| author | |
| committer | |
| log | 5d4439cc3e9dc9196fc109552f36594ad97542c5 |
| tree | b0ed2b36b213c5c47cd373327bb91cbf9e6d2205 |
| parent | 9ddfacd8e62abd80b25619dd852ee811dad5f7b6 |
release/17.x branch, commit 8f4dd44097c9ae25dd203d5ac87f3b48f854bba8
This adds the flag `-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL`. A future
enhancement could possibly pass something different if there is a
compelling parallel implementation. That libdispatch one might be worth
looking into.959 files changed, 48526 insertions(+), 24061 deletions(-)
lib/libcxx/include/__algorithm/adjacent_find.h+5| ... | ... | @@ -20,6 +20,9 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | _LIBCPP_PUSH_MACROS | |
| 24 | #include <__undef_macros> | |
| 25 | ||
| 23 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 27 | |
| 25 | 28 | template <class _Iter, class _Sent, class _BinaryPredicate> |
| ... | ... | @@ -50,4 +53,6 @@ adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { |
| 50 | 53 | |
| 51 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 55 | |
| 56 | _LIBCPP_POP_MACROS | |
| 57 | ||
| 53 | 58 | #endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H |
lib/libcxx/include/__algorithm/all_of.h+1-1| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _InputIterator, class _Predicate> |
| 22 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 22 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 23 | 23 | all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { |
| 24 | 24 | for (; __first != __last; ++__first) |
| 25 | 25 | if (!__pred(*__first)) |
lib/libcxx/include/__algorithm/binary_search.h+1-2| ... | ... | @@ -37,8 +37,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 37 | 37 | bool |
| 38 | 38 | binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) |
| 39 | 39 | { |
| 40 | return std::binary_search(__first, __last, __value, | |
| 41 | __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); | |
| 40 | return std::binary_search(__first, __last, __value, __less<>()); | |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/clamp.h+3-3| ... | ... | @@ -19,14 +19,14 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | template<class _Tp, class _Compare> |
| 24 | 24 | _LIBCPP_NODISCARD_EXT inline |
| 25 | 25 | _LIBCPP_INLINE_VISIBILITY constexpr |
| 26 | 26 | const _Tp& |
| 27 | 27 | clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) |
| 28 | 28 | { |
| 29 | _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); | |
| 29 | _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); | |
| 30 | 30 | return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; |
| 31 | 31 | |
| 32 | 32 | } |
| ... | ... | @@ -37,7 +37,7 @@ _LIBCPP_INLINE_VISIBILITY constexpr |
| 37 | 37 | const _Tp& |
| 38 | 38 | clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) |
| 39 | 39 | { |
| 40 | return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); | |
| 40 | return _VSTD::clamp(__v, __lo, __hi, __less<>()); | |
| 41 | 41 | } |
| 42 | 42 | #endif |
| 43 | 43 |
lib/libcxx/include/__algorithm/comp.h+14-33| ... | ... | @@ -10,6 +10,8 @@ |
| 10 | 10 | #define _LIBCPP___ALGORITHM_COMP_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <__type_traits/integral_constant.h> | |
| 14 | #include <__type_traits/predicate_traits.h> | |
| 13 | 15 | |
| 14 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 15 | 17 | # pragma GCC system_header |
| ... | ... | @@ -24,41 +26,20 @@ struct __equal_to { |
| 24 | 26 | } |
| 25 | 27 | }; |
| 26 | 28 | |
| 27 | template <class _T1, class _T2 = _T1> | |
| 28 | struct __less | |
| 29 | { | |
| 30 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 31 | bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} | |
| 29 | template <class _Lhs, class _Rhs> | |
| 30 | struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {}; | |
| 32 | 31 | |
| 33 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 34 | bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} | |
| 32 | // The definition is required because __less is part of the ABI, but it's empty | |
| 33 | // because all comparisons should be transparent. | |
| 34 | template <class _T1 = void, class _T2 = _T1> | |
| 35 | struct __less {}; | |
| 35 | 36 | |
| 36 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 37 | bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} | |
| 38 | ||
| 39 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 40 | bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} | |
| 41 | }; | |
| 42 | ||
| 43 | template <class _T1> | |
| 44 | struct __less<_T1, _T1> | |
| 45 | { | |
| 46 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 47 | bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} | |
| 48 | }; | |
| 49 | ||
| 50 | template <class _T1> | |
| 51 | struct __less<const _T1, _T1> | |
| 52 | { | |
| 53 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 54 | bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} | |
| 55 | }; | |
| 56 | ||
| 57 | template <class _T1> | |
| 58 | struct __less<_T1, const _T1> | |
| 59 | { | |
| 60 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 61 | bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} | |
| 37 | template <> | |
| 38 | struct __less<void, void> { | |
| 39 | template <class _Tp, class _Up> | |
| 40 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const { | |
| 41 | return __lhs < __rhs; | |
| 42 | } | |
| 62 | 43 | }; |
| 63 | 44 | |
| 64 | 45 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/comp_ref_type.h+6-7| ... | ... | @@ -9,8 +9,8 @@ |
| 9 | 9 | #ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H |
| 10 | 10 | #define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H |
| 11 | 11 | |
| 12 | #include <__assert> | |
| 12 | 13 | #include <__config> |
| 13 | #include <__debug> | |
| 14 | 14 | #include <__utility/declval.h> |
| 15 | 15 | |
| 16 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -23,11 +23,10 @@ template <class _Compare> |
| 23 | 23 | struct __debug_less |
| 24 | 24 | { |
| 25 | 25 | _Compare &__comp_; |
| 26 | _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 27 | __debug_less(_Compare& __c) : __comp_(__c) {} | |
| 26 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} | |
| 28 | 27 | |
| 29 | 28 | template <class _Tp, class _Up> |
| 30 | _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 29 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI | |
| 31 | 30 | bool operator()(const _Tp& __x, const _Up& __y) |
| 32 | 31 | { |
| 33 | 32 | bool __r = __comp_(__x, __y); |
| ... | ... | @@ -37,7 +36,7 @@ struct __debug_less |
| 37 | 36 | } |
| 38 | 37 | |
| 39 | 38 | template <class _Tp, class _Up> |
| 40 | _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 39 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI | |
| 41 | 40 | bool operator()(_Tp& __x, _Up& __y) |
| 42 | 41 | { |
| 43 | 42 | bool __r = __comp_(__x, __y); |
| ... | ... | @@ -52,7 +51,7 @@ struct __debug_less |
| 52 | 51 | decltype((void)std::declval<_Compare&>()( |
| 53 | 52 | std::declval<_LHS &>(), std::declval<_RHS &>())) |
| 54 | 53 | __do_compare_assert(int, _LHS & __l, _RHS & __r) { |
| 55 | _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r), | |
| 54 | _LIBCPP_ASSERT_UNCATEGORIZED(!__comp_(__l, __r), | |
| 56 | 55 | "Comparator does not induce a strict weak ordering"); |
| 57 | 56 | (void)__l; |
| 58 | 57 | (void)__r; |
| ... | ... | @@ -66,7 +65,7 @@ struct __debug_less |
| 66 | 65 | |
| 67 | 66 | // Pass the comparator by lvalue reference. Or in debug mode, using a |
| 68 | 67 | // debugging wrapper that stores a reference. |
| 69 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 68 | #if _LIBCPP_ENABLE_DEBUG_MODE | |
| 70 | 69 | template <class _Comp> |
| 71 | 70 | using __comp_ref_type = __debug_less<_Comp>; |
| 72 | 71 | #else |
lib/libcxx/include/__algorithm/copy.h+19-21| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #define _LIBCPP___ALGORITHM_COPY_H |
| 11 | 11 | |
| 12 | 12 | #include <__algorithm/copy_move_common.h> |
| 13 | #include <__algorithm/for_each_segment.h> | |
| 13 | 14 | #include <__algorithm/iterator_operations.h> |
| 14 | 15 | #include <__algorithm/min.h> |
| 15 | 16 | #include <__config> |
| ... | ... | @@ -44,36 +45,34 @@ struct __copy_loop { |
| 44 | 45 | return std::make_pair(std::move(__first), std::move(__result)); |
| 45 | 46 | } |
| 46 | 47 | |
| 47 | template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> | |
| 48 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> | |
| 49 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 48 | template <class _InIter, class _OutIter> | |
| 49 | struct _CopySegment { | |
| 50 | 50 | using _Traits = __segmented_iterator_traits<_InIter>; |
| 51 | auto __sfirst = _Traits::__segment(__first); | |
| 52 | auto __slast = _Traits::__segment(__last); | |
| 53 | if (__sfirst == __slast) { | |
| 54 | auto __iters = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); | |
| 55 | return std::make_pair(__last, std::move(__iters.second)); | |
| 56 | } | |
| 57 | 51 | |
| 58 | __result = std::__copy<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; | |
| 59 | ++__sfirst; | |
| 60 | while (__sfirst != __slast) { | |
| 61 | __result = | |
| 62 | std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; | |
| 63 | ++__sfirst; | |
| 52 | _OutIter& __result_; | |
| 53 | ||
| 54 | _LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {} | |
| 55 | ||
| 56 | _LIBCPP_HIDE_FROM_ABI void | |
| 57 | operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) { | |
| 58 | __result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second; | |
| 64 | 59 | } |
| 65 | __result = | |
| 66 | std::__copy<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; | |
| 60 | }; | |
| 61 | ||
| 62 | template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> | |
| 63 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> | |
| 64 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 65 | std::__for_each_segment(__first, __last, _CopySegment<_InIter, _OutIter>(__result)); | |
| 67 | 66 | return std::make_pair(__last, std::move(__result)); |
| 68 | 67 | } |
| 69 | 68 | |
| 70 | 69 | template <class _InIter, |
| 71 | 70 | class _OutIter, |
| 72 | __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value && | |
| 71 | __enable_if_t<__has_random_access_iterator_category<_InIter>::value && | |
| 73 | 72 | !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, |
| 74 | 73 | int> = 0> |
| 75 | 74 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> |
| 76 | operator()(_InIter __first, _InIter __last, _OutIter __result) { | |
| 75 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 77 | 76 | using _Traits = __segmented_iterator_traits<_OutIter>; |
| 78 | 77 | using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; |
| 79 | 78 | |
| ... | ... | @@ -98,8 +97,7 @@ struct __copy_loop { |
| 98 | 97 | |
| 99 | 98 | struct __copy_trivial { |
| 100 | 99 | // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. |
| 101 | template <class _In, class _Out, | |
| 102 | __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0> | |
| 100 | template <class _In, class _Out, __enable_if_t<__can_lower_copy_assignment_to_memmove<_In, _Out>::value, int> = 0> | |
| 103 | 101 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> |
| 104 | 102 | operator()(_In* __first, _In* __last, _Out* __result) const { |
| 105 | 103 | return std::__copy_trivial_impl(__first, __last, __result); |
lib/libcxx/include/__algorithm/copy_backward.h+2-2| ... | ... | @@ -76,11 +76,11 @@ struct __copy_backward_loop { |
| 76 | 76 | |
| 77 | 77 | template <class _InIter, |
| 78 | 78 | class _OutIter, |
| 79 | __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value && | |
| 79 | __enable_if_t<__has_random_access_iterator_category<_InIter>::value && | |
| 80 | 80 | !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, |
| 81 | 81 | int> = 0> |
| 82 | 82 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> |
| 83 | operator()(_InIter __first, _InIter __last, _OutIter __result) { | |
| 83 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 84 | 84 | using _Traits = __segmented_iterator_traits<_OutIter>; |
| 85 | 85 | auto __orig_last = __last; |
| 86 | 86 | auto __segment_iterator = _Traits::__segment(__result); |
lib/libcxx/include/__algorithm/copy_move_common.h+4-29| ... | ... | @@ -15,6 +15,7 @@ |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__iterator/iterator_traits.h> |
| 17 | 17 | #include <__memory/pointer_traits.h> |
| 18 | #include <__string/constexpr_c_functions.h> | |
| 18 | 19 | #include <__type_traits/enable_if.h> |
| 19 | 20 | #include <__type_traits/is_always_bitcastable.h> |
| 20 | 21 | #include <__type_traits/is_constant_evaluated.h> |
| ... | ... | @@ -61,7 +62,8 @@ template <class _In, class _Out> |
| 61 | 62 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> |
| 62 | 63 | __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { |
| 63 | 64 | const size_t __n = static_cast<size_t>(__last - __first); |
| 64 | ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); | |
| 65 | ||
| 66 | std::__constexpr_memmove(__result, __first, __element_count(__n)); | |
| 65 | 67 | |
| 66 | 68 | return std::make_pair(__last, __result + __n); |
| 67 | 69 | } |
| ... | ... | @@ -72,7 +74,7 @@ __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) { |
| 72 | 74 | const size_t __n = static_cast<size_t>(__last - __first); |
| 73 | 75 | __result -= __n; |
| 74 | 76 | |
| 75 | ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); | |
| 77 | std::__constexpr_memmove(__result, __first, __element_count(__n)); | |
| 76 | 78 | |
| 77 | 79 | return std::make_pair(__last, __result); |
| 78 | 80 | } |
| ... | ... | @@ -119,16 +121,6 @@ __unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { |
| 119 | 121 | return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first)); |
| 120 | 122 | } |
| 121 | 123 | |
| 122 | template <class _IterOps, class _InValue, class _OutIter, class = void> | |
| 123 | struct __can_copy_without_conversion : false_type {}; | |
| 124 | ||
| 125 | template <class _IterOps, class _InValue, class _OutIter> | |
| 126 | struct __can_copy_without_conversion< | |
| 127 | _IterOps, | |
| 128 | _InValue, | |
| 129 | _OutIter, | |
| 130 | __enable_if_t<is_same<_InValue, typename _IterOps::template __value_type<_OutIter> >::value> > : true_type {}; | |
| 131 | ||
| 132 | 124 | template <class _AlgPolicy, |
| 133 | 125 | class _NaiveAlgorithm, |
| 134 | 126 | class _OptimizedAlgorithm, |
| ... | ... | @@ -137,23 +129,6 @@ template <class _AlgPolicy, |
| 137 | 129 | class _OutIter> |
| 138 | 130 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> |
| 139 | 131 | __dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { |
| 140 | #ifdef _LIBCPP_COMPILER_GCC | |
| 141 | // GCC doesn't support `__builtin_memmove` during constant evaluation. | |
| 142 | if (__libcpp_is_constant_evaluated()) { | |
| 143 | return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); | |
| 144 | } | |
| 145 | #else | |
| 146 | // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is | |
| 147 | // insufficient). Also, conversions are not supported. | |
| 148 | if (__libcpp_is_constant_evaluated()) { | |
| 149 | using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>; | |
| 150 | if (!is_trivially_copyable<_InValue>::value || | |
| 151 | !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) { | |
| 152 | return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); | |
| 153 | } | |
| 154 | } | |
| 155 | #endif // _LIBCPP_COMPILER_GCC | |
| 156 | ||
| 157 | 132 | using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>; |
| 158 | 133 | return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); |
| 159 | 134 | } |
lib/libcxx/include/__algorithm/copy_n.h+4-4| ... | ... | @@ -12,8 +12,8 @@ |
| 12 | 12 | #include <__algorithm/copy.h> |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__iterator/iterator_traits.h> |
| 15 | #include <__type_traits/enable_if.h> | |
| 15 | 16 | #include <__utility/convert_to_integral.h> |
| 16 | #include <type_traits> | |
| 17 | 17 | |
| 18 | 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 19 | # pragma GCC system_header |
| ... | ... | @@ -25,8 +25,8 @@ template<class _InputIterator, class _Size, class _OutputIterator> |
| 25 | 25 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 26 | 26 | typename enable_if |
| 27 | 27 | < |
| 28 | __is_cpp17_input_iterator<_InputIterator>::value && | |
| 29 | !__is_cpp17_random_access_iterator<_InputIterator>::value, | |
| 28 | __has_input_iterator_category<_InputIterator>::value && | |
| 29 | !__has_random_access_iterator_category<_InputIterator>::value, | |
| 30 | 30 | _OutputIterator |
| 31 | 31 | >::type |
| 32 | 32 | copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) |
| ... | ... | @@ -51,7 +51,7 @@ template<class _InputIterator, class _Size, class _OutputIterator> |
| 51 | 51 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 52 | 52 | typename enable_if |
| 53 | 53 | < |
| 54 | __is_cpp17_random_access_iterator<_InputIterator>::value, | |
| 54 | __has_random_access_iterator_category<_InputIterator>::value, | |
| 55 | 55 | _OutputIterator |
| 56 | 56 | >::type |
| 57 | 57 | copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) |
lib/libcxx/include/__algorithm/equal.h+73-10| ... | ... | @@ -11,9 +11,20 @@ |
| 11 | 11 | #define _LIBCPP___ALGORITHM_EQUAL_H |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/comp.h> |
| 14 | #include <__algorithm/unwrap_iter.h> | |
| 14 | 15 | #include <__config> |
| 16 | #include <__functional/identity.h> | |
| 17 | #include <__functional/invoke.h> | |
| 15 | 18 | #include <__iterator/distance.h> |
| 16 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | #include <__string/constexpr_c_functions.h> | |
| 21 | #include <__type_traits/enable_if.h> | |
| 22 | #include <__type_traits/integral_constant.h> | |
| 23 | #include <__type_traits/is_constant_evaluated.h> | |
| 24 | #include <__type_traits/is_equality_comparable.h> | |
| 25 | #include <__type_traits/is_volatile.h> | |
| 26 | #include <__type_traits/predicate_traits.h> | |
| 27 | #include <__utility/move.h> | |
| 17 | 28 | |
| 18 | 29 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 30 | # pragma GCC system_header |
| ... | ... | @@ -22,23 +33,42 @@ |
| 22 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 34 | |
| 24 | 35 | template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> |
| 25 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 26 | equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { | |
| 36 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl( | |
| 37 | _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate& __pred) { | |
| 27 | 38 | for (; __first1 != __last1; ++__first1, (void)++__first2) |
| 28 | 39 | if (!__pred(*__first1, *__first2)) |
| 29 | 40 | return false; |
| 30 | 41 | return true; |
| 31 | 42 | } |
| 32 | 43 | |
| 44 | template < | |
| 45 | class _Tp, | |
| 46 | class _Up, | |
| 47 | class _BinaryPredicate, | |
| 48 | __enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value && | |
| 49 | !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, | |
| 50 | int> = 0> | |
| 51 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 52 | __equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) { | |
| 53 | return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1)); | |
| 54 | } | |
| 55 | ||
| 56 | template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> | |
| 57 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 58 | equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { | |
| 59 | return std::__equal_iter_impl( | |
| 60 | std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred); | |
| 61 | } | |
| 62 | ||
| 33 | 63 | template <class _InputIterator1, class _InputIterator2> |
| 34 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 64 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 35 | 65 | equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { |
| 36 | 66 | return std::equal(__first1, __last1, __first2, __equal_to()); |
| 37 | 67 | } |
| 38 | 68 | |
| 39 | #if _LIBCPP_STD_VER > 11 | |
| 69 | #if _LIBCPP_STD_VER >= 14 | |
| 40 | 70 | template <class _BinaryPredicate, class _InputIterator1, class _InputIterator2> |
| 41 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 71 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 42 | 72 | __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, |
| 43 | 73 | _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { |
| 44 | 74 | for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) |
| ... | ... | @@ -47,19 +77,52 @@ __equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fir |
| 47 | 77 | return __first1 == __last1 && __first2 == __last2; |
| 48 | 78 | } |
| 49 | 79 | |
| 80 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2> | |
| 81 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl( | |
| 82 | _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) { | |
| 83 | while (__first1 != __last1 && __first2 != __last2) { | |
| 84 | if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) | |
| 85 | return false; | |
| 86 | ++__first1; | |
| 87 | ++__first2; | |
| 88 | } | |
| 89 | return __first1 == __last1 && __first2 == __last2; | |
| 90 | } | |
| 91 | ||
| 92 | template <class _Tp, | |
| 93 | class _Up, | |
| 94 | class _Pred, | |
| 95 | class _Proj1, | |
| 96 | class _Proj2, | |
| 97 | __enable_if_t<__is_trivial_equality_predicate<_Pred, _Tp, _Up>::value && __is_identity<_Proj1>::value && | |
| 98 | __is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value && | |
| 99 | __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, | |
| 100 | int> = 0> | |
| 101 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl( | |
| 102 | _Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) { | |
| 103 | return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1)); | |
| 104 | } | |
| 105 | ||
| 50 | 106 | template <class _BinaryPredicate, class _RandomAccessIterator1, class _RandomAccessIterator2> |
| 51 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 107 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 52 | 108 | __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, |
| 53 | 109 | _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, |
| 54 | 110 | random_access_iterator_tag) { |
| 55 | 111 | if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) |
| 56 | 112 | return false; |
| 57 | return _VSTD::equal<_RandomAccessIterator1, _RandomAccessIterator2, | |
| 58 | _BinaryPredicate&>(__first1, __last1, __first2, __pred); | |
| 113 | __identity __proj; | |
| 114 | return std::__equal_impl( | |
| 115 | std::__unwrap_iter(__first1), | |
| 116 | std::__unwrap_iter(__last1), | |
| 117 | std::__unwrap_iter(__first2), | |
| 118 | std::__unwrap_iter(__last2), | |
| 119 | __pred, | |
| 120 | __proj, | |
| 121 | __proj); | |
| 59 | 122 | } |
| 60 | 123 | |
| 61 | 124 | template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> |
| 62 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 125 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 63 | 126 | equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, |
| 64 | 127 | _BinaryPredicate __pred) { |
| 65 | 128 | return _VSTD::__equal<_BinaryPredicate&>( |
| ... | ... | @@ -68,7 +131,7 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first |
| 68 | 131 | } |
| 69 | 132 | |
| 70 | 133 | template <class _InputIterator1, class _InputIterator2> |
| 71 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 134 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 72 | 135 | equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { |
| 73 | 136 | return std::__equal( |
| 74 | 137 | __first1, |
lib/libcxx/include/__algorithm/equal_range.h+2-6| ... | ... | @@ -50,7 +50,7 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp |
| 50 | 50 | } else { |
| 51 | 51 | _Iter __mp1 = __mid; |
| 52 | 52 | return pair<_Iter, _Iter>( |
| 53 | std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj), | |
| 53 | std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj), | |
| 54 | 54 | std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); |
| 55 | 55 | } |
| 56 | 56 | } |
| ... | ... | @@ -75,11 +75,7 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu |
| 75 | 75 | template <class _ForwardIterator, class _Tp> |
| 76 | 76 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> |
| 77 | 77 | equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { |
| 78 | return std::equal_range( | |
| 79 | std::move(__first), | |
| 80 | std::move(__last), | |
| 81 | __value, | |
| 82 | __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); | |
| 78 | return std::equal_range(std::move(__first), std::move(__last), __value, __less<>()); | |
| 83 | 79 | } |
| 84 | 80 | |
| 85 | 81 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/fill.h-1| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <__algorithm/fill_n.h> |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__iterator/iterator_traits.h> |
| 15 | #include <type_traits> | |
| 16 | 15 | |
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/fill_n.h-1| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__iterator/iterator_traits.h> |
| 14 | 14 | #include <__utility/convert_to_integral.h> |
| 15 | #include <type_traits> | |
| 16 | 15 | |
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/find.h+49-4| ... | ... | @@ -10,7 +10,16 @@ |
| 10 | 10 | #ifndef _LIBCPP___ALGORITHM_FIND_H |
| 11 | 11 | #define _LIBCPP___ALGORITHM_FIND_H |
| 12 | 12 | |
| 13 | #include <__algorithm/unwrap_iter.h> | |
| 13 | 14 | #include <__config> |
| 15 | #include <__functional/identity.h> | |
| 16 | #include <__functional/invoke.h> | |
| 17 | #include <__string/constexpr_c_functions.h> | |
| 18 | #include <__type_traits/is_same.h> | |
| 19 | ||
| 20 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 21 | # include <cwchar> | |
| 22 | #endif | |
| 14 | 23 | |
| 15 | 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 16 | 25 | # pragma GCC system_header |
| ... | ... | @@ -18,15 +27,51 @@ |
| 18 | 27 | |
| 19 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 29 | |
| 21 | template <class _InputIterator, class _Tp> | |
| 22 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator | |
| 23 | find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { | |
| 30 | template <class _Iter, class _Sent, class _Tp, class _Proj> | |
| 31 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter | |
| 32 | __find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) { | |
| 24 | 33 | for (; __first != __last; ++__first) |
| 25 | if (*__first == __value) | |
| 34 | if (std::__invoke(__proj, *__first) == __value) | |
| 26 | 35 | break; |
| 27 | 36 | return __first; |
| 28 | 37 | } |
| 29 | 38 | |
| 39 | template <class _Tp, | |
| 40 | class _Up, | |
| 41 | class _Proj, | |
| 42 | __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value && | |
| 43 | sizeof(_Tp) == 1, | |
| 44 | int> = 0> | |
| 45 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* | |
| 46 | __find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { | |
| 47 | if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first)) | |
| 48 | return __ret; | |
| 49 | return __last; | |
| 50 | } | |
| 51 | ||
| 52 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 53 | template <class _Tp, | |
| 54 | class _Up, | |
| 55 | class _Proj, | |
| 56 | __enable_if_t<__is_identity<_Proj>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value && | |
| 57 | sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t), | |
| 58 | int> = 0> | |
| 59 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* | |
| 60 | __find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { | |
| 61 | if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first)) | |
| 62 | return __ret; | |
| 63 | return __last; | |
| 64 | } | |
| 65 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 66 | ||
| 67 | template <class _InputIterator, class _Tp> | |
| 68 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator | |
| 69 | find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { | |
| 70 | __identity __proj; | |
| 71 | return std::__rewrap_iter( | |
| 72 | __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj)); | |
| 73 | } | |
| 74 | ||
| 30 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 31 | 76 | |
| 32 | 77 | #endif // _LIBCPP___ALGORITHM_FIND_H |
lib/libcxx/include/__algorithm/find_end.h+1-1| ... | ... | @@ -15,12 +15,12 @@ |
| 15 | 15 | #include <__algorithm/search.h> |
| 16 | 16 | #include <__config> |
| 17 | 17 | #include <__functional/identity.h> |
| 18 | #include <__functional/invoke.h> | |
| 18 | 19 | #include <__iterator/advance.h> |
| 19 | 20 | #include <__iterator/iterator_traits.h> |
| 20 | 21 | #include <__iterator/next.h> |
| 21 | 22 | #include <__iterator/reverse_iterator.h> |
| 22 | 23 | #include <__utility/pair.h> |
| 23 | #include <type_traits> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/for_each_n.h+1-2| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__utility/convert_to_integral.h> |
| 15 | #include <type_traits> | |
| 16 | 15 | |
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
| ... | ... | @@ -20,7 +19,7 @@ |
| 20 | 19 | |
| 21 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 21 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 23 | |
| 25 | 24 | template <class _InputIterator, class _Size, class _Function> |
| 26 | 25 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, |
lib/libcxx/include/__algorithm/for_each_segment.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H | |
| 10 | #define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__iterator/segmented_iterator.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | // __for_each_segment is a utility function for optimizing iterating over segmented iterators linearly. | |
| 22 | // __first and __last are expected to be a segmented range. __func is expected to take a range of local iterators. | |
| 23 | // Anything that is returned from __func is ignored. | |
| 24 | ||
| 25 | template <class _SegmentedIterator, class _Functor> | |
| 26 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void | |
| 27 | __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Functor __func) { | |
| 28 | using _Traits = __segmented_iterator_traits<_SegmentedIterator>; | |
| 29 | ||
| 30 | auto __sfirst = _Traits::__segment(__first); | |
| 31 | auto __slast = _Traits::__segment(__last); | |
| 32 | ||
| 33 | // We are in a single segment, so we might not be at the beginning or end | |
| 34 | if (__sfirst == __slast) { | |
| 35 | __func(_Traits::__local(__first), _Traits::__local(__last)); | |
| 36 | return; | |
| 37 | } | |
| 38 | ||
| 39 | // We have more than one segment. Iterate over the first segment, since we might not start at the beginning | |
| 40 | __func(_Traits::__local(__first), _Traits::__end(__sfirst)); | |
| 41 | ++__sfirst; | |
| 42 | // iterate over the segments which are guaranteed to be completely in the range | |
| 43 | while (__sfirst != __slast) { | |
| 44 | __func(_Traits::__begin(__sfirst), _Traits::__end(__sfirst)); | |
| 45 | ++__sfirst; | |
| 46 | } | |
| 47 | // iterate over the last segment | |
| 48 | __func(_Traits::__begin(__sfirst), _Traits::__local(__last)); | |
| 49 | } | |
| 50 | ||
| 51 | _LIBCPP_END_NAMESPACE_STD | |
| 52 | ||
| 53 | #endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H |
lib/libcxx/include/__algorithm/generate_n.h-1| ... | ... | @@ -11,7 +11,6 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__utility/convert_to_integral.h> |
| 14 | #include <type_traits> | |
| 15 | 14 | |
| 16 | 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 16 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/half_positive.h+3-1| ... | ... | @@ -10,7 +10,9 @@ |
| 10 | 10 | #define _LIBCPP___ALGORITHM_HALF_POSITIVE_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <type_traits> | |
| 13 | #include <__type_traits/enable_if.h> | |
| 14 | #include <__type_traits/is_integral.h> | |
| 15 | #include <__type_traits/make_unsigned.h> | |
| 14 | 16 | |
| 15 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 16 | 18 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/in_found_result.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -44,6 +44,6 @@ struct in_found_result { |
| 44 | 44 | |
| 45 | 45 | _LIBCPP_END_NAMESPACE_STD |
| 46 | 46 | |
| 47 | #endif // _LIBCPP_STD_VER > 17 | |
| 47 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | 48 | |
| 49 | 49 | #endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H |
lib/libcxx/include/__algorithm/in_fun_result.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | namespace ranges { |
| 26 | 26 | template <class _InIter1, class _Func1> |
| ... | ... | @@ -42,7 +42,7 @@ struct in_fun_result { |
| 42 | 42 | }; |
| 43 | 43 | } // namespace ranges |
| 44 | 44 | |
| 45 | #endif // _LIBCPP_STD_VER > 17 | |
| 45 | #endif // _LIBCPP_STD_VER >= 20 | |
| 46 | 46 | |
| 47 | 47 | _LIBCPP_END_NAMESPACE_STD |
| 48 | 48 |
lib/libcxx/include/__algorithm/in_in_out_result.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | namespace ranges { |
| 26 | 26 | |
| ... | ... | @@ -49,7 +49,7 @@ struct in_in_out_result { |
| 49 | 49 | |
| 50 | 50 | } // namespace ranges |
| 51 | 51 | |
| 52 | #endif // _LIBCPP_STD_VER > 17 | |
| 52 | #endif // _LIBCPP_STD_VER >= 20 | |
| 53 | 53 | |
| 54 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 55 | 55 |
lib/libcxx/include/__algorithm/in_in_result.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | namespace ranges { |
| 26 | 26 | |
| ... | ... | @@ -46,7 +46,7 @@ struct in_in_result { |
| 46 | 46 | |
| 47 | 47 | } // namespace ranges |
| 48 | 48 | |
| 49 | #endif // _LIBCPP_STD_VER > 17 | |
| 49 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | 50 | |
| 51 | 51 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 52 |
lib/libcxx/include/__algorithm/in_out_out_result.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | namespace ranges { |
| 26 | 26 | template <class _InIter1, class _OutIter1, class _OutIter2> |
| ... | ... | @@ -47,7 +47,7 @@ struct in_out_out_result { |
| 47 | 47 | }; |
| 48 | 48 | } // namespace ranges |
| 49 | 49 | |
| 50 | #endif // _LIBCPP_STD_VER > 17 | |
| 50 | #endif // _LIBCPP_STD_VER >= 20 | |
| 51 | 51 | |
| 52 | 52 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 53 |
lib/libcxx/include/__algorithm/in_out_result.h+7-2| ... | ... | @@ -18,9 +18,12 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | _LIBCPP_PUSH_MACROS | |
| 22 | #include <__undef_macros> | |
| 23 | ||
| 21 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 25 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 27 | |
| 25 | 28 | namespace ranges { |
| 26 | 29 | |
| ... | ... | @@ -46,8 +49,10 @@ struct in_out_result { |
| 46 | 49 | |
| 47 | 50 | } // namespace ranges |
| 48 | 51 | |
| 49 | #endif // _LIBCPP_STD_VER > 17 | |
| 52 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | 53 | |
| 51 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 55 | |
| 56 | _LIBCPP_POP_MACROS | |
| 57 | ||
| 53 | 58 | #endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H |
lib/libcxx/include/__algorithm/includes.h+1-7| ... | ... | @@ -61,13 +61,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 61 | 61 | template <class _InputIterator1, class _InputIterator2> |
| 62 | 62 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool |
| 63 | 63 | includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { |
| 64 | return std::includes( | |
| 65 | std::move(__first1), | |
| 66 | std::move(__last1), | |
| 67 | std::move(__first2), | |
| 68 | std::move(__last2), | |
| 69 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 70 | typename iterator_traits<_InputIterator2>::value_type>()); | |
| 64 | return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>()); | |
| 71 | 65 | } |
| 72 | 66 | |
| 73 | 67 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/inplace_merge.h+1-2| ... | ... | @@ -246,8 +246,7 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 246 | 246 | void |
| 247 | 247 | inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) |
| 248 | 248 | { |
| 249 | std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), | |
| 250 | __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); | |
| 249 | std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>()); | |
| 251 | 250 | } |
| 252 | 251 | |
| 253 | 252 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/is_heap.h+1-1| ... | ... | @@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 36 | 36 | bool |
| 37 | 37 | is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) |
| 38 | 38 | { |
| 39 | return _VSTD::is_heap(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 39 | return _VSTD::is_heap(__first, __last, __less<>()); | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/is_heap_until.h+1-1| ... | ... | @@ -58,7 +58,7 @@ template<class _RandomAccessIterator> |
| 58 | 58 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator |
| 59 | 59 | is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) |
| 60 | 60 | { |
| 61 | return _VSTD::__is_heap_until(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 61 | return _VSTD::__is_heap_until(__first, __last, __less<>()); | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/is_permutation.h+10-5| ... | ... | @@ -19,19 +19,22 @@ |
| 19 | 19 | #include <__iterator/distance.h> |
| 20 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | 21 | #include <__iterator/next.h> |
| 22 | #include <__type_traits/is_callable.h> | |
| 22 | 23 | #include <__utility/move.h> |
| 23 | #include <type_traits> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | _LIBCPP_PUSH_MACROS | |
| 30 | #include <__undef_macros> | |
| 31 | ||
| 29 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 33 | |
| 31 | 34 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class = void> |
| 32 | 35 | struct _ConstTimeDistance : false_type {}; |
| 33 | 36 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 38 | |
| 36 | 39 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2> |
| 37 | 40 | struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< |
| ... | ... | @@ -47,7 +50,7 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< |
| 47 | 50 | is_same<typename iterator_traits<_Iter2>::iterator_category, random_access_iterator_tag>::value |
| 48 | 51 | > > : true_type {}; |
| 49 | 52 | |
| 50 | #endif // _LIBCPP_STD_VER > 17 | |
| 53 | #endif // _LIBCPP_STD_VER >= 20 | |
| 51 | 54 | |
| 52 | 55 | // Internal functions |
| 53 | 56 | |
| ... | ... | @@ -202,7 +205,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt |
| 202 | 205 | return std::is_permutation(__first1, __last1, __first2, __equal_to()); |
| 203 | 206 | } |
| 204 | 207 | |
| 205 | #if _LIBCPP_STD_VER > 11 | |
| 208 | #if _LIBCPP_STD_VER >= 14 | |
| 206 | 209 | |
| 207 | 210 | // 2+2 iterators |
| 208 | 211 | template <class _ForwardIterator1, class _ForwardIterator2> |
| ... | ... | @@ -231,8 +234,10 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt |
| 231 | 234 | __pred, __identity(), __identity()); |
| 232 | 235 | } |
| 233 | 236 | |
| 234 | #endif // _LIBCPP_STD_VER > 11 | |
| 237 | #endif // _LIBCPP_STD_VER >= 14 | |
| 235 | 238 | |
| 236 | 239 | _LIBCPP_END_NAMESPACE_STD |
| 237 | 240 | |
| 241 | _LIBCPP_POP_MACROS | |
| 242 | ||
| 238 | 243 | #endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H |
lib/libcxx/include/__algorithm/is_sorted.h+1-1| ... | ... | @@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 36 | 36 | bool |
| 37 | 37 | is_sorted(_ForwardIterator __first, _ForwardIterator __last) |
| 38 | 38 | { |
| 39 | return _VSTD::is_sorted(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 39 | return _VSTD::is_sorted(__first, __last, __less<>()); | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/is_sorted_until.h+1-1| ... | ... | @@ -48,7 +48,7 @@ template<class _ForwardIterator> |
| 48 | 48 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator |
| 49 | 49 | is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) |
| 50 | 50 | { |
| 51 | return _VSTD::is_sorted_until(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 51 | return _VSTD::is_sorted_until(__first, __last, __less<>()); | |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/iterator_operations.h+6-1| ... | ... | @@ -33,11 +33,14 @@ |
| 33 | 33 | # pragma GCC system_header |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | _LIBCPP_PUSH_MACROS | |
| 37 | #include <__undef_macros> | |
| 38 | ||
| 36 | 39 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 40 | |
| 38 | 41 | template <class _AlgPolicy> struct _IterOps; |
| 39 | 42 | |
| 40 | #if _LIBCPP_STD_VER > 17 | |
| 43 | #if _LIBCPP_STD_VER >= 20 | |
| 41 | 44 | struct _RangeAlgPolicy {}; |
| 42 | 45 | |
| 43 | 46 | template <> |
| ... | ... | @@ -172,4 +175,6 @@ struct _IterOps<_ClassicAlgPolicy> { |
| 172 | 175 | |
| 173 | 176 | _LIBCPP_END_NAMESPACE_STD |
| 174 | 177 | |
| 178 | _LIBCPP_POP_MACROS | |
| 179 | ||
| 175 | 180 | #endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H |
lib/libcxx/include/__algorithm/lexicographical_compare.h+1-3| ... | ... | @@ -52,9 +52,7 @@ bool |
| 52 | 52 | lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, |
| 53 | 53 | _InputIterator2 __first2, _InputIterator2 __last2) |
| 54 | 54 | { |
| 55 | return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, | |
| 56 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 57 | typename iterator_traits<_InputIterator2>::value_type>()); | |
| 55 | return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); | |
| 58 | 56 | } |
| 59 | 57 | |
| 60 | 58 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/lexicographical_compare_three_way.h created+125| ... | ... | @@ -0,0 +1,125 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H | |
| 10 | #define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H | |
| 11 | ||
| 12 | #include <__algorithm/min.h> | |
| 13 | #include <__algorithm/three_way_comp_ref_type.h> | |
| 14 | #include <__compare/compare_three_way.h> | |
| 15 | #include <__compare/ordering.h> | |
| 16 | #include <__concepts/arithmetic.h> | |
| 17 | #include <__config> | |
| 18 | #include <__iterator/iterator_traits.h> | |
| 19 | #include <__type_traits/common_type.h> | |
| 20 | #include <__type_traits/is_copy_constructible.h> | |
| 21 | #include <__utility/move.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_PUSH_MACROS | |
| 28 | #include <__undef_macros> | |
| 29 | ||
| 30 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 31 | ||
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | ||
| 34 | // Fast path for random access iterators which computes the number of loop iterations up-front and | |
| 35 | // then skips the iterator comparisons inside the loop. | |
| 36 | template <class _InputIterator1, class _InputIterator2, class _Cmp> | |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_fast_path( | |
| 38 | _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp) | |
| 39 | -> decltype(__comp(*__first1, *__first2)) { | |
| 40 | static_assert( | |
| 41 | signed_integral<__iter_diff_t<_InputIterator1>>, "Using a non-integral difference_type is undefined behavior."); | |
| 42 | static_assert( | |
| 43 | signed_integral<__iter_diff_t<_InputIterator2>>, "Using a non-integral difference_type is undefined behavior."); | |
| 44 | ||
| 45 | using _Len1 = __iter_diff_t<_InputIterator1>; | |
| 46 | using _Len2 = __iter_diff_t<_InputIterator2>; | |
| 47 | using _Common = common_type_t<_Len1, _Len2>; | |
| 48 | ||
| 49 | _Len1 __len1 = __last1 - __first1; | |
| 50 | _Len2 __len2 = __last2 - __first2; | |
| 51 | _Common __min_len = std::min<_Common>(__len1, __len2); | |
| 52 | ||
| 53 | for (_Common __i = 0; __i < __min_len; ++__i) { | |
| 54 | auto __c = __comp(*__first1, *__first2); | |
| 55 | if (__c != 0) { | |
| 56 | return __c; | |
| 57 | } | |
| 58 | ++__first1; | |
| 59 | ++__first2; | |
| 60 | } | |
| 61 | ||
| 62 | return __len1 <=> __len2; | |
| 63 | } | |
| 64 | ||
| 65 | // Unoptimized implementation which compares the iterators against the end in every loop iteration | |
| 66 | template <class _InputIterator1, class _InputIterator2, class _Cmp> | |
| 67 | _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_path( | |
| 68 | _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp& __comp) | |
| 69 | -> decltype(__comp(*__first1, *__first2)) { | |
| 70 | while (true) { | |
| 71 | bool __exhausted1 = __first1 == __last1; | |
| 72 | bool __exhausted2 = __first2 == __last2; | |
| 73 | ||
| 74 | if (__exhausted1 || __exhausted2) { | |
| 75 | if (!__exhausted1) | |
| 76 | return strong_ordering::greater; | |
| 77 | if (!__exhausted2) | |
| 78 | return strong_ordering::less; | |
| 79 | return strong_ordering::equal; | |
| 80 | } | |
| 81 | ||
| 82 | auto __c = __comp(*__first1, *__first2); | |
| 83 | if (__c != 0) { | |
| 84 | return __c; | |
| 85 | } | |
| 86 | ||
| 87 | ++__first1; | |
| 88 | ++__first2; | |
| 89 | } | |
| 90 | } | |
| 91 | ||
| 92 | template <class _InputIterator1, class _InputIterator2, class _Cmp> | |
| 93 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( | |
| 94 | _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp) | |
| 95 | -> decltype(__comp(*__first1, *__first2)) { | |
| 96 | static_assert(__comparison_category<decltype(__comp(*__first1, *__first2))>, | |
| 97 | "The comparator passed to lexicographical_compare_three_way must return a comparison category type."); | |
| 98 | static_assert(std::is_copy_constructible_v<_InputIterator1>, "Iterators must be copy constructible."); | |
| 99 | static_assert(std::is_copy_constructible_v<_InputIterator2>, "Iterators must be copy constructible."); | |
| 100 | __three_way_comp_ref_type<_Cmp> __wrapped_comp_ref(__comp); | |
| 101 | if constexpr (__has_random_access_iterator_category<_InputIterator1>::value && | |
| 102 | __has_random_access_iterator_category<_InputIterator2>::value) { | |
| 103 | return std::__lexicographical_compare_three_way_fast_path( | |
| 104 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref); | |
| 105 | } else { | |
| 106 | // Unoptimized implementation which compares the iterators against the end in every loop iteration | |
| 107 | return std::__lexicographical_compare_three_way_slow_path( | |
| 108 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __wrapped_comp_ref); | |
| 109 | } | |
| 110 | } | |
| 111 | ||
| 112 | template <class _InputIterator1, class _InputIterator2> | |
| 113 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( | |
| 114 | _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { | |
| 115 | return std::lexicographical_compare_three_way( | |
| 116 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way()); | |
| 117 | } | |
| 118 | ||
| 119 | #endif // _LIBCPP_STD_VER >= 20 | |
| 120 | ||
| 121 | _LIBCPP_END_NAMESPACE_STD | |
| 122 | ||
| 123 | _LIBCPP_POP_MACROS | |
| 124 | ||
| 125 | #endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H |
lib/libcxx/include/__algorithm/lower_bound.h+3-5| ... | ... | @@ -20,7 +20,6 @@ |
| 20 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | 21 | #include <__type_traits/is_callable.h> |
| 22 | 22 | #include <__type_traits/remove_reference.h> |
| 23 | #include <type_traits> | |
| 24 | 23 | |
| 25 | 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 25 | # pragma GCC system_header |
| ... | ... | @@ -30,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 29 | |
| 31 | 30 | template <class _AlgPolicy, class _Iter, class _Sent, class _Type, class _Proj, class _Comp> |
| 32 | 31 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 33 | _Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { | |
| 32 | _Iter __lower_bound(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { | |
| 34 | 33 | auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); |
| 35 | 34 | |
| 36 | 35 | while (__len != 0) { |
| ... | ... | @@ -53,14 +52,13 @@ _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, |
| 53 | 52 | static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, |
| 54 | 53 | "The comparator has to be callable"); |
| 55 | 54 | auto __proj = std::__identity(); |
| 56 | return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 55 | return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 57 | 56 | } |
| 58 | 57 | |
| 59 | 58 | template <class _ForwardIterator, class _Tp> |
| 60 | 59 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 61 | 60 | _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { |
| 62 | return std::lower_bound(__first, __last, __value, | |
| 63 | __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>()); | |
| 61 | return std::lower_bound(__first, __last, __value, __less<>()); | |
| 64 | 62 | } |
| 65 | 63 | |
| 66 | 64 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/make_heap.h+6-2| ... | ... | @@ -21,6 +21,9 @@ |
| 21 | 21 | # pragma GCC system_header |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | _LIBCPP_PUSH_MACROS | |
| 25 | #include <__undef_macros> | |
| 26 | ||
| 24 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 28 | |
| 26 | 29 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| ... | ... | @@ -47,10 +50,11 @@ void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com |
| 47 | 50 | template <class _RandomAccessIterator> |
| 48 | 51 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 49 | 52 | void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 50 | std::make_heap(std::move(__first), std::move(__last), | |
| 51 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 53 | std::make_heap(std::move(__first), std::move(__last), __less<>()); | |
| 52 | 54 | } |
| 53 | 55 | |
| 54 | 56 | _LIBCPP_END_NAMESPACE_STD |
| 55 | 57 | |
| 58 | _LIBCPP_POP_MACROS | |
| 59 | ||
| 56 | 60 | #endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H |
lib/libcxx/include/__algorithm/make_projected.h+20-33| ... | ... | @@ -32,13 +32,14 @@ struct _ProjectedPred { |
| 32 | 32 | _Pred& __pred; // Can be a unary or a binary predicate. |
| 33 | 33 | _Proj& __proj; |
| 34 | 34 | |
| 35 | _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {} | |
| 35 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) | |
| 36 | : __pred(__pred_arg), __proj(__proj_arg) {} | |
| 36 | 37 | |
| 37 | 38 | template <class _Tp> |
| 38 | 39 | typename __invoke_of<_Pred&, |
| 39 | 40 | decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) |
| 40 | 41 | >::type |
| 41 | _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const { | |
| 42 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const { | |
| 42 | 43 | return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); |
| 43 | 44 | } |
| 44 | 45 | |
| ... | ... | @@ -47,7 +48,7 @@ struct _ProjectedPred { |
| 47 | 48 | decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), |
| 48 | 49 | decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) |
| 49 | 50 | >::type |
| 50 | _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const { | |
| 51 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const { | |
| 51 | 52 | return std::__invoke(__pred, |
| 52 | 53 | std::__invoke(__proj, std::forward<_T1>(__lhs)), |
| 53 | 54 | std::__invoke(__proj, std::forward<_T2>(__rhs))); |
| ... | ... | @@ -55,25 +56,12 @@ struct _ProjectedPred { |
| 55 | 56 | |
| 56 | 57 | }; |
| 57 | 58 | |
| 58 | template <class _Pred, class _Proj, class = void> | |
| 59 | struct __can_use_pristine_comp : false_type {}; | |
| 60 | ||
| 61 | template <class _Pred, class _Proj> | |
| 62 | struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t< | |
| 63 | !is_member_pointer<typename decay<_Pred>::type>::value && ( | |
| 64 | #if _LIBCPP_STD_VER > 17 | |
| 65 | is_same<typename decay<_Proj>::type, identity>::value || | |
| 66 | #endif | |
| 67 | is_same<typename decay<_Proj>::type, __identity>::value | |
| 68 | ) | |
| 69 | > > : true_type {}; | |
| 70 | ||
| 71 | template <class _Pred, class _Proj> | |
| 72 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static | |
| 73 | __enable_if_t< | |
| 74 | !__can_use_pristine_comp<_Pred, _Proj>::value, | |
| 75 | _ProjectedPred<_Pred, _Proj> | |
| 76 | > | |
| 59 | template <class _Pred, | |
| 60 | class _Proj, | |
| 61 | __enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value && | |
| 62 | __is_identity<__decay_t<_Proj> >::value), | |
| 63 | int> = 0> | |
| 64 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> | |
| 77 | 65 | __make_projected(_Pred& __pred, _Proj& __proj) { |
| 78 | 66 | return _ProjectedPred<_Pred, _Proj>(__pred, __proj); |
| 79 | 67 | } |
| ... | ... | @@ -81,28 +69,27 @@ __make_projected(_Pred& __pred, _Proj& __proj) { |
| 81 | 69 | // Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable |
| 82 | 70 | // optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in |
| 83 | 71 | // the call stack when the comparator is invoked, even in an unoptimized build. |
| 84 | template <class _Pred, class _Proj> | |
| 85 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static | |
| 86 | __enable_if_t< | |
| 87 | __can_use_pristine_comp<_Pred, _Proj>::value, | |
| 88 | _Pred& | |
| 89 | > | |
| 90 | __make_projected(_Pred& __pred, _Proj&) { | |
| 72 | template <class _Pred, | |
| 73 | class _Proj, | |
| 74 | __enable_if_t<!is_member_pointer<__decay_t<_Pred> >::value && | |
| 75 | __is_identity<__decay_t<_Proj> >::value, | |
| 76 | int> = 0> | |
| 77 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) { | |
| 91 | 78 | return __pred; |
| 92 | 79 | } |
| 93 | 80 | |
| 94 | 81 | _LIBCPP_END_NAMESPACE_STD |
| 95 | 82 | |
| 96 | #if _LIBCPP_STD_VER > 17 | |
| 83 | #if _LIBCPP_STD_VER >= 20 | |
| 97 | 84 | |
| 98 | 85 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 99 | 86 | |
| 100 | 87 | namespace ranges { |
| 101 | 88 | |
| 102 | 89 | template <class _Comp, class _Proj1, class _Proj2> |
| 103 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 90 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 104 | 91 | decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { |
| 105 | if constexpr (same_as<decay_t<_Proj1>, identity> && same_as<decay_t<_Proj2>, identity> && | |
| 92 | if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value && | |
| 106 | 93 | !is_member_pointer_v<decay_t<_Comp>>) { |
| 107 | 94 | // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable |
| 108 | 95 | // optimizations that rely on the type of the comparator. |
| ... | ... | @@ -121,6 +108,6 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p |
| 121 | 108 | |
| 122 | 109 | _LIBCPP_END_NAMESPACE_STD |
| 123 | 110 | |
| 124 | #endif // _LIBCPP_STD_VER > 17 | |
| 111 | #endif // _LIBCPP_STD_VER >= 20 | |
| 125 | 112 | |
| 126 | 113 | #endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H |
lib/libcxx/include/__algorithm/max.h+4-4| ... | ... | @@ -28,7 +28,7 @@ template <class _Tp, class _Compare> |
| 28 | 28 | _LIBCPP_NODISCARD_EXT inline |
| 29 | 29 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 30 | 30 | const _Tp& |
| 31 | max(const _Tp& __a, const _Tp& __b, _Compare __comp) | |
| 31 | max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) | |
| 32 | 32 | { |
| 33 | 33 | return __comp(__a, __b) ? __b : __a; |
| 34 | 34 | } |
| ... | ... | @@ -37,9 +37,9 @@ template <class _Tp> |
| 37 | 37 | _LIBCPP_NODISCARD_EXT inline |
| 38 | 38 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 39 | 39 | const _Tp& |
| 40 | max(const _Tp& __a, const _Tp& __b) | |
| 40 | max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) | |
| 41 | 41 | { |
| 42 | return _VSTD::max(__a, __b, __less<_Tp>()); | |
| 42 | return _VSTD::max(__a, __b, __less<>()); | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 59 | 59 | _Tp |
| 60 | 60 | max(initializer_list<_Tp> __t) |
| 61 | 61 | { |
| 62 | return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); | |
| 62 | return *_VSTD::max_element(__t.begin(), __t.end(), __less<>()); | |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__algorithm/max_element.h+2-3| ... | ... | @@ -24,7 +24,7 @@ template <class _Compare, class _ForwardIterator> |
| 24 | 24 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator |
| 25 | 25 | __max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) |
| 26 | 26 | { |
| 27 | static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 27 | static_assert(__has_forward_iterator_category<_ForwardIterator>::value, | |
| 28 | 28 | "std::max_element requires a ForwardIterator"); |
| 29 | 29 | if (__first != __last) |
| 30 | 30 | { |
| ... | ... | @@ -48,8 +48,7 @@ template <class _ForwardIterator> |
| 48 | 48 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator |
| 49 | 49 | max_element(_ForwardIterator __first, _ForwardIterator __last) |
| 50 | 50 | { |
| 51 | return _VSTD::max_element(__first, __last, | |
| 52 | __less<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 51 | return _VSTD::max_element(__first, __last, __less<>()); | |
| 53 | 52 | } |
| 54 | 53 | |
| 55 | 54 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/merge.h+1-3| ... | ... | @@ -60,9 +60,7 @@ _OutputIterator |
| 60 | 60 | merge(_InputIterator1 __first1, _InputIterator1 __last1, |
| 61 | 61 | _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) |
| 62 | 62 | { |
| 63 | typedef typename iterator_traits<_InputIterator1>::value_type __v1; | |
| 64 | typedef typename iterator_traits<_InputIterator2>::value_type __v2; | |
| 65 | return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); | |
| 63 | return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<>()); | |
| 66 | 64 | } |
| 67 | 65 | |
| 68 | 66 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/min.h+4-4| ... | ... | @@ -28,7 +28,7 @@ template <class _Tp, class _Compare> |
| 28 | 28 | _LIBCPP_NODISCARD_EXT inline |
| 29 | 29 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 30 | 30 | const _Tp& |
| 31 | min(const _Tp& __a, const _Tp& __b, _Compare __comp) | |
| 31 | min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) | |
| 32 | 32 | { |
| 33 | 33 | return __comp(__b, __a) ? __b : __a; |
| 34 | 34 | } |
| ... | ... | @@ -37,9 +37,9 @@ template <class _Tp> |
| 37 | 37 | _LIBCPP_NODISCARD_EXT inline |
| 38 | 38 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 39 | 39 | const _Tp& |
| 40 | min(const _Tp& __a, const _Tp& __b) | |
| 40 | min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) | |
| 41 | 41 | { |
| 42 | return _VSTD::min(__a, __b, __less<_Tp>()); | |
| 42 | return _VSTD::min(__a, __b, __less<>()); | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 59 | 59 | _Tp |
| 60 | 60 | min(initializer_list<_Tp> __t) |
| 61 | 61 | { |
| 62 | return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); | |
| 62 | return *_VSTD::min_element(__t.begin(), __t.end(), __less<>()); | |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__algorithm/min_element.h+7-3| ... | ... | @@ -22,6 +22,9 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | _LIBCPP_PUSH_MACROS | |
| 26 | #include <__undef_macros> | |
| 27 | ||
| 25 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 29 | |
| 27 | 30 | template <class _Comp, class _Iter, class _Sent, class _Proj> |
| ... | ... | @@ -49,7 +52,7 @@ template <class _ForwardIterator, class _Compare> |
| 49 | 52 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator |
| 50 | 53 | min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) |
| 51 | 54 | { |
| 52 | static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 55 | static_assert(__has_forward_iterator_category<_ForwardIterator>::value, | |
| 53 | 56 | "std::min_element requires a ForwardIterator"); |
| 54 | 57 | static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, |
| 55 | 58 | "The comparator has to be callable"); |
| ... | ... | @@ -61,10 +64,11 @@ template <class _ForwardIterator> |
| 61 | 64 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator |
| 62 | 65 | min_element(_ForwardIterator __first, _ForwardIterator __last) |
| 63 | 66 | { |
| 64 | return _VSTD::min_element(__first, __last, | |
| 65 | __less<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 67 | return _VSTD::min_element(__first, __last, __less<>()); | |
| 66 | 68 | } |
| 67 | 69 | |
| 68 | 70 | _LIBCPP_END_NAMESPACE_STD |
| 69 | 71 | |
| 72 | _LIBCPP_POP_MACROS | |
| 73 | ||
| 70 | 74 | #endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H |
lib/libcxx/include/__algorithm/min_max_result.h+2-2| ... | ... | @@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | namespace ranges { |
| 29 | 29 | |
| ... | ... | @@ -47,7 +47,7 @@ struct min_max_result { |
| 47 | 47 | |
| 48 | 48 | } // namespace ranges |
| 49 | 49 | |
| 50 | #endif // _LIBCPP_STD_VER > 17 | |
| 50 | #endif // _LIBCPP_STD_VER >= 20 | |
| 51 | 51 | |
| 52 | 52 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 53 |
lib/libcxx/include/__algorithm/minmax.h+4-4| ... | ... | @@ -27,7 +27,7 @@ template<class _Tp, class _Compare> |
| 27 | 27 | _LIBCPP_NODISCARD_EXT inline |
| 28 | 28 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 29 | 29 | pair<const _Tp&, const _Tp&> |
| 30 | minmax(const _Tp& __a, const _Tp& __b, _Compare __comp) | |
| 30 | minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) | |
| 31 | 31 | { |
| 32 | 32 | return __comp(__b, __a) ? pair<const _Tp&, const _Tp&>(__b, __a) : |
| 33 | 33 | pair<const _Tp&, const _Tp&>(__a, __b); |
| ... | ... | @@ -37,9 +37,9 @@ template<class _Tp> |
| 37 | 37 | _LIBCPP_NODISCARD_EXT inline |
| 38 | 38 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 39 | 39 | pair<const _Tp&, const _Tp&> |
| 40 | minmax(const _Tp& __a, const _Tp& __b) | |
| 40 | minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) | |
| 41 | 41 | { |
| 42 | return std::minmax(__a, __b, __less<_Tp>()); | |
| 42 | return std::minmax(__a, __b, __less<>()); | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -59,7 +59,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 59 | 59 | pair<_Tp, _Tp> |
| 60 | 60 | minmax(initializer_list<_Tp> __t) |
| 61 | 61 | { |
| 62 | return std::minmax(__t, __less<_Tp>()); | |
| 62 | return std::minmax(__t, __less<>()); | |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | 65 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__algorithm/minmax_element.h+4-3| ... | ... | @@ -12,9 +12,10 @@ |
| 12 | 12 | #include <__algorithm/comp.h> |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/identity.h> |
| 15 | #include <__functional/invoke.h> | |
| 15 | 16 | #include <__iterator/iterator_traits.h> |
| 17 | #include <__type_traits/is_callable.h> | |
| 16 | 18 | #include <__utility/pair.h> |
| 17 | #include <type_traits> | |
| 18 | 19 | |
| 19 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 21 | # pragma GCC system_header |
| ... | ... | @@ -82,7 +83,7 @@ template <class _ForwardIterator, class _Compare> |
| 82 | 83 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 83 | 84 | pair<_ForwardIterator, _ForwardIterator> |
| 84 | 85 | minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { |
| 85 | static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 86 | static_assert(__has_forward_iterator_category<_ForwardIterator>::value, | |
| 86 | 87 | "std::minmax_element requires a ForwardIterator"); |
| 87 | 88 | static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, |
| 88 | 89 | "The comparator has to be callable"); |
| ... | ... | @@ -93,7 +94,7 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __com |
| 93 | 94 | template <class _ForwardIterator> |
| 94 | 95 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 95 | 96 | pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { |
| 96 | return std::minmax_element(__first, __last, __less<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 97 | return std::minmax_element(__first, __last, __less<>()); | |
| 97 | 98 | } |
| 98 | 99 | |
| 99 | 100 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/mismatch.h+1-1| ... | ... | @@ -38,7 +38,7 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY |
| 38 | 38 | return std::mismatch(__first1, __last1, __first2, __equal_to()); |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | #if _LIBCPP_STD_VER > 11 | |
| 41 | #if _LIBCPP_STD_VER >= 14 | |
| 42 | 42 | template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate> |
| 43 | 43 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY |
| 44 | 44 | _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> |
lib/libcxx/include/__algorithm/move.h+18-19| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #define _LIBCPP___ALGORITHM_MOVE_H |
| 11 | 11 | |
| 12 | 12 | #include <__algorithm/copy_move_common.h> |
| 13 | #include <__algorithm/for_each_segment.h> | |
| 13 | 14 | #include <__algorithm/iterator_operations.h> |
| 14 | 15 | #include <__algorithm/min.h> |
| 15 | 16 | #include <__config> |
| ... | ... | @@ -45,36 +46,34 @@ struct __move_loop { |
| 45 | 46 | return std::make_pair(std::move(__first), std::move(__result)); |
| 46 | 47 | } |
| 47 | 48 | |
| 48 | template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> | |
| 49 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> | |
| 50 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 49 | template <class _InIter, class _OutIter> | |
| 50 | struct _MoveSegment { | |
| 51 | 51 | using _Traits = __segmented_iterator_traits<_InIter>; |
| 52 | auto __sfirst = _Traits::__segment(__first); | |
| 53 | auto __slast = _Traits::__segment(__last); | |
| 54 | if (__sfirst == __slast) { | |
| 55 | auto __iters = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__local(__last), std::move(__result)); | |
| 56 | return std::make_pair(__last, std::move(__iters.second)); | |
| 57 | } | |
| 58 | 52 | |
| 59 | __result = std::__move<_AlgPolicy>(_Traits::__local(__first), _Traits::__end(__sfirst), std::move(__result)).second; | |
| 60 | ++__sfirst; | |
| 61 | while (__sfirst != __slast) { | |
| 62 | __result = | |
| 63 | std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), std::move(__result)).second; | |
| 64 | ++__sfirst; | |
| 53 | _OutIter& __result_; | |
| 54 | ||
| 55 | _LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {} | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI void | |
| 58 | operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) { | |
| 59 | __result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second; | |
| 65 | 60 | } |
| 66 | __result = | |
| 67 | std::__move<_AlgPolicy>(_Traits::__begin(__sfirst), _Traits::__local(__last), std::move(__result)).second; | |
| 61 | }; | |
| 62 | ||
| 63 | template <class _InIter, class _OutIter, __enable_if_t<__is_segmented_iterator<_InIter>::value, int> = 0> | |
| 64 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> | |
| 65 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 66 | std::__for_each_segment(__first, __last, _MoveSegment<_InIter, _OutIter>(__result)); | |
| 68 | 67 | return std::make_pair(__last, std::move(__result)); |
| 69 | 68 | } |
| 70 | 69 | |
| 71 | 70 | template <class _InIter, |
| 72 | 71 | class _OutIter, |
| 73 | __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value && | |
| 72 | __enable_if_t<__has_random_access_iterator_category<_InIter>::value && | |
| 74 | 73 | !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, |
| 75 | 74 | int> = 0> |
| 76 | 75 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> |
| 77 | operator()(_InIter __first, _InIter __last, _OutIter __result) { | |
| 76 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 78 | 77 | using _Traits = __segmented_iterator_traits<_OutIter>; |
| 79 | 78 | using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; |
| 80 | 79 |
lib/libcxx/include/__algorithm/move_backward.h+2-2| ... | ... | @@ -76,11 +76,11 @@ struct __move_backward_loop { |
| 76 | 76 | |
| 77 | 77 | template <class _InIter, |
| 78 | 78 | class _OutIter, |
| 79 | __enable_if_t<__is_cpp17_random_access_iterator<_InIter>::value && | |
| 79 | __enable_if_t<__has_random_access_iterator_category<_InIter>::value && | |
| 80 | 80 | !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, |
| 81 | 81 | int> = 0> |
| 82 | 82 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> |
| 83 | operator()(_InIter __first, _InIter __last, _OutIter __result) { | |
| 83 | operator()(_InIter __first, _InIter __last, _OutIter __result) const { | |
| 84 | 84 | using _Traits = __segmented_iterator_traits<_OutIter>; |
| 85 | 85 | using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; |
| 86 | 86 |
lib/libcxx/include/__algorithm/next_permutation.h+1-2| ... | ... | @@ -69,8 +69,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 69 | 69 | bool |
| 70 | 70 | next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) |
| 71 | 71 | { |
| 72 | return _VSTD::next_permutation(__first, __last, | |
| 73 | __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); | |
| 72 | return _VSTD::next_permutation(__first, __last, __less<>()); | |
| 74 | 73 | } |
| 75 | 74 | |
| 76 | 75 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/nth_element.h+1-3| ... | ... | @@ -14,7 +14,6 @@ |
| 14 | 14 | #include <__algorithm/iterator_operations.h> |
| 15 | 15 | #include <__algorithm/sort.h> |
| 16 | 16 | #include <__config> |
| 17 | #include <__debug> | |
| 18 | 17 | #include <__debug_utils/randomize_range.h> |
| 19 | 18 | #include <__iterator/iterator_traits.h> |
| 20 | 19 | #include <__utility/move.h> |
| ... | ... | @@ -249,8 +248,7 @@ void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _Ra |
| 249 | 248 | template <class _RandomAccessIterator> |
| 250 | 249 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 251 | 250 | void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { |
| 252 | std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<typename | |
| 253 | iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 251 | std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>()); | |
| 254 | 252 | } |
| 255 | 253 | |
| 256 | 254 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/partial_sort.h+3-4| ... | ... | @@ -16,11 +16,11 @@ |
| 16 | 16 | #include <__algorithm/sift_down.h> |
| 17 | 17 | #include <__algorithm/sort_heap.h> |
| 18 | 18 | #include <__config> |
| 19 | #include <__debug> | |
| 20 | 19 | #include <__debug_utils/randomize_range.h> |
| 21 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | #include <__type_traits/is_copy_assignable.h> | |
| 22 | #include <__type_traits/is_copy_constructible.h> | |
| 22 | 23 | #include <__utility/move.h> |
| 23 | #include <type_traits> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
| ... | ... | @@ -87,8 +87,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 87 | 87 | void |
| 88 | 88 | partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) |
| 89 | 89 | { |
| 90 | _VSTD::partial_sort(__first, __middle, __last, | |
| 91 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 90 | _VSTD::partial_sort(__first, __middle, __last, __less<>()); | |
| 92 | 91 | } |
| 93 | 92 | |
| 94 | 93 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/partial_sort_copy.h+1-2| ... | ... | @@ -79,8 +79,7 @@ _RandomAccessIterator |
| 79 | 79 | partial_sort_copy(_InputIterator __first, _InputIterator __last, |
| 80 | 80 | _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) |
| 81 | 81 | { |
| 82 | return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, | |
| 83 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 82 | return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>()); | |
| 84 | 83 | } |
| 85 | 84 | |
| 86 | 85 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/partition.h-1| ... | ... | @@ -14,7 +14,6 @@ |
| 14 | 14 | #include <__iterator/iterator_traits.h> |
| 15 | 15 | #include <__utility/move.h> |
| 16 | 16 | #include <__utility/pair.h> |
| 17 | #include <type_traits> | |
| 18 | 17 | |
| 19 | 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 19 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/pop_heap.h+9-4| ... | ... | @@ -17,20 +17,24 @@ |
| 17 | 17 | #include <__assert> |
| 18 | 18 | #include <__config> |
| 19 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | #include <__type_traits/is_copy_assignable.h> | |
| 21 | #include <__type_traits/is_copy_constructible.h> | |
| 20 | 22 | #include <__utility/move.h> |
| 21 | #include <type_traits> | |
| 22 | 23 | |
| 23 | 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 25 | # pragma GCC system_header |
| 25 | 26 | #endif |
| 26 | 27 | |
| 28 | _LIBCPP_PUSH_MACROS | |
| 29 | #include <__undef_macros> | |
| 30 | ||
| 27 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 32 | |
| 29 | 33 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| 30 | 34 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 31 | 35 | void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, |
| 32 | 36 | typename iterator_traits<_RandomAccessIterator>::difference_type __len) { |
| 33 | _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty"); | |
| 37 | _LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty"); | |
| 34 | 38 | |
| 35 | 39 | __comp_ref_type<_Compare> __comp_ref = __comp; |
| 36 | 40 | |
| ... | ... | @@ -64,10 +68,11 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp |
| 64 | 68 | template <class _RandomAccessIterator> |
| 65 | 69 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 66 | 70 | void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 67 | std::pop_heap(std::move(__first), std::move(__last), | |
| 68 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 71 | std::pop_heap(std::move(__first), std::move(__last), __less<>()); | |
| 69 | 72 | } |
| 70 | 73 | |
| 71 | 74 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 75 | |
| 76 | _LIBCPP_POP_MACROS | |
| 77 | ||
| 73 | 78 | #endif // _LIBCPP___ALGORITHM_POP_HEAP_H |
lib/libcxx/include/__algorithm/prev_permutation.h+1-2| ... | ... | @@ -70,8 +70,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 70 | 70 | bool |
| 71 | 71 | prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) |
| 72 | 72 | { |
| 73 | return _VSTD::prev_permutation(__first, __last, | |
| 74 | __less<typename iterator_traits<_BidirectionalIterator>::value_type>()); | |
| 73 | return _VSTD::prev_permutation(__first, __last, __less<>()); | |
| 75 | 74 | } |
| 76 | 75 | |
| 77 | 76 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/pstl_any_all_none_of.h created+100| ... | ... | @@ -0,0 +1,100 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_find.h> | |
| 13 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 16 | #include <__iterator/iterator_traits.h> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_execution_policy.h> | |
| 19 | #include <__type_traits/remove_cvref.h> | |
| 20 | #include <__utility/move.h> | |
| 21 | #include <__utility/terminate_on_exception.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | template <class> | |
| 32 | void __pstl_any_of(); // declaration needed for the frontend dispatch below | |
| 33 | ||
| 34 | template <class _ExecutionPolicy, | |
| 35 | class _ForwardIterator, | |
| 36 | class _Predicate, | |
| 37 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 38 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 39 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool | |
| 40 | any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 41 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 42 | return std::__pstl_frontend_dispatch( | |
| 43 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of), | |
| 44 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { | |
| 45 | return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last; | |
| 46 | }, | |
| 47 | std::move(__first), | |
| 48 | std::move(__last), | |
| 49 | std::move(__pred)); | |
| 50 | } | |
| 51 | ||
| 52 | template <class> | |
| 53 | void __pstl_all_of(); // declaration needed for the frontend dispatch below | |
| 54 | ||
| 55 | template <class _ExecutionPolicy, | |
| 56 | class _ForwardIterator, | |
| 57 | class _Pred, | |
| 58 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 59 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool | |
| 61 | all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { | |
| 62 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 63 | return std::__pstl_frontend_dispatch( | |
| 64 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of), | |
| 65 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) { | |
| 66 | return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) { | |
| 67 | return !__g_pred(__value); | |
| 68 | }); | |
| 69 | }, | |
| 70 | std::move(__first), | |
| 71 | std::move(__last), | |
| 72 | std::move(__pred)); | |
| 73 | } | |
| 74 | ||
| 75 | template <class> | |
| 76 | void __pstl_none_of(); // declaration needed for the frontend dispatch below | |
| 77 | ||
| 78 | template <class _ExecutionPolicy, | |
| 79 | class _ForwardIterator, | |
| 80 | class _Pred, | |
| 81 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 82 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 83 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool | |
| 84 | none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { | |
| 85 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 86 | return std::__pstl_frontend_dispatch( | |
| 87 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of), | |
| 88 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) { | |
| 89 | return !std::any_of(__policy, __g_first, __g_last, __g_pred); | |
| 90 | }, | |
| 91 | std::move(__first), | |
| 92 | std::move(__last), | |
| 93 | std::move(__pred)); | |
| 94 | } | |
| 95 | ||
| 96 | _LIBCPP_END_NAMESPACE_STD | |
| 97 | ||
| 98 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 99 | ||
| 100 | #endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H |
lib/libcxx/include/__algorithm/pstl_backend.h created+198| ... | ... | @@ -0,0 +1,198 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKEND_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backends/cpu_backend.h> | |
| 13 | #include <__config> | |
| 14 | #include <execution> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | /* | |
| 25 | TODO: Documentation of how backends work | |
| 26 | ||
| 27 | A PSTL parallel backend is a tag type to which the following functions are associated, at minimum: | |
| 28 | ||
| 29 | template <class _ExecutionPolicy, class _Iterator, class _Func> | |
| 30 | void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f); | |
| 31 | ||
| 32 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 33 | _Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); | |
| 34 | ||
| 35 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp> | |
| 36 | void __pstl_stable_sort(_Backend, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp); | |
| 37 | ||
| 38 | template <class _ExecutionPolicy, class _InIterator, class _OutIterator, class _UnaryOperation> | |
| 39 | _OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op); | |
| 40 | ||
| 41 | template <class _ExecutionPolicy, class _InIterator1, class _InIterator2, class _OutIterator, class _BinaryOperation> | |
| 42 | _OutIterator __pstl_transform(_InIterator1 __first1, | |
| 43 | _InIterator1 __last1, | |
| 44 | _InIterator2 __first2, | |
| 45 | _OutIterator __result, | |
| 46 | _BinaryOperation __op); | |
| 47 | ||
| 48 | template <class _ExecutionPolicy, | |
| 49 | class _Iterator1, | |
| 50 | class _Iterator2, | |
| 51 | class _Tp, | |
| 52 | class _BinaryOperation1, | |
| 53 | class _BinaryOperation2> | |
| 54 | _Tp __pstl_transform_reduce(_Backend, | |
| 55 | _Iterator1 __first1, | |
| 56 | _Iterator1 __last1, | |
| 57 | _Iterator2 __first2, | |
| 58 | _Iterator2 __last2, | |
| 59 | _Tp __init, | |
| 60 | _BinaryOperation1 __reduce, | |
| 61 | _BinaryOperation2 __transform); | |
| 62 | ||
| 63 | template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation, class _UnaryOperation> | |
| 64 | _Tp __pstl_transform_reduce(_Backend, | |
| 65 | _Iterator __first, | |
| 66 | _Iterator __last, | |
| 67 | _Tp __init, | |
| 68 | _BinaryOperation __reduce, | |
| 69 | _UnaryOperation __transform); | |
| 70 | ||
| 71 | // TODO: Complete this list | |
| 72 | ||
| 73 | The following functions are optional but can be provided. If provided, they are used by the corresponding | |
| 74 | algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are | |
| 75 | implemented, all the algorithms will eventually forward to the basis algorithms listed above: | |
| 76 | ||
| 77 | template <class _ExecutionPolicy, class _Iterator, class _Size, class _Func> | |
| 78 | void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f); | |
| 79 | ||
| 80 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 81 | bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); | |
| 82 | ||
| 83 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 84 | bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); | |
| 85 | ||
| 86 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 87 | bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); | |
| 88 | ||
| 89 | template <class _ExecutionPolicy, class _Iterator, class _Tp> | |
| 90 | _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); | |
| 91 | ||
| 92 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 93 | _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); | |
| 94 | ||
| 95 | template <class _ExecutionPolicy, class _Iterator, class _Tp> | |
| 96 | void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); | |
| 97 | ||
| 98 | template <class _ExecutionPolicy, class _Iterator, class _SizeT, class _Tp> | |
| 99 | void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value); | |
| 100 | ||
| 101 | template <class _ExecutionPolicy, class _Iterator, class _Generator> | |
| 102 | void __pstl_generate(_Backend, _Iterator __first, _Iterator __last, _Generator __gen); | |
| 103 | ||
| 104 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 105 | void __pstl_is_partitioned(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); | |
| 106 | ||
| 107 | template <class _ExecutionPolicy, class _Iterator, class _Size, class _Generator> | |
| 108 | void __pstl_generator_n(_Backend, _Iterator __first, _Size __n, _Generator __gen); | |
| 109 | ||
| 110 | template <class _ExecutionPolicy, class _terator1, class _Iterator2, class _OutIterator, class _Comp> | |
| 111 | _OutIterator __pstl_merge(_Backend, | |
| 112 | _Iterator1 __first1, | |
| 113 | _Iterator1 __last1, | |
| 114 | _Iterator2 __first2, | |
| 115 | _Iterator2 __last2, | |
| 116 | _OutIterator __result, | |
| 117 | _Comp __comp); | |
| 118 | ||
| 119 | template <class _ExecutionPolicy, class _Iterator, class _Tp, class _BinaryOperation> | |
| 120 | _Tp __pstl_reduce(_Backend, _Iterator __first, _Iterator __last, _Tp __init, _BinaryOperation __op); | |
| 121 | ||
| 122 | temlate <class _ExecutionPolicy, class _Iterator> | |
| 123 | __iter_value_type<_Iterator> __pstl_reduce(_Backend, _Iterator __first, _Iterator __last); | |
| 124 | ||
| 125 | template <class _ExecuitonPolicy, class _Iterator, class _Tp> | |
| 126 | __iter_diff_t<_Iterator> __pstl_count(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); | |
| 127 | ||
| 128 | template <class _ExecutionPolicy, class _Iterator, class _Predicate> | |
| 129 | __iter_diff_t<_Iterator> __pstl_count_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); | |
| 130 | ||
| 131 | template <class _ExecutionPolicy, class _Iterator, class _Tp> | |
| 132 | void __pstl_replace(_Backend, _Iterator __first, _Iterator __last, const _Tp& __old_value, const _Tp& __new_value); | |
| 133 | ||
| 134 | template <class _ExecutionPolicy, class _Iterator, class _Pred, class _Tp> | |
| 135 | void __pstl_replace_if(_Backend, _Iterator __first, _Iterator __last, _Pred __pred, const _Tp& __new_value); | |
| 136 | ||
| 137 | template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Tp> | |
| 138 | void __pstl_replace_copy(_Backend, | |
| 139 | _Iterator __first, | |
| 140 | _Iterator __last, | |
| 141 | _OutIterator __result, | |
| 142 | const _Tp& __old_value, | |
| 143 | const _Tp& __new_value); | |
| 144 | ||
| 145 | template <class _ExecutionPolicy, class _Iterator, class _OutIterator, class _Pred, class _Tp> | |
| 146 | void __pstl_replace_copy_if(_Backend, | |
| 147 | _Iterator __first, | |
| 148 | _Iterator __last, | |
| 149 | _OutIterator __result, | |
| 150 | _Pred __pred, | |
| 151 | const _Tp& __new_value); | |
| 152 | ||
| 153 | template <class _ExecutionPolicy, class _Iterator, class _Comp> | |
| 154 | void __pstl_sort(_Backend, _Iterator __first, _Iterator __last, _Comp __comp); | |
| 155 | ||
| 156 | // TODO: Complete this list | |
| 157 | ||
| 158 | */ | |
| 159 | ||
| 160 | template <class _ExecutionPolicy> | |
| 161 | struct __select_backend; | |
| 162 | ||
| 163 | template <> | |
| 164 | struct __select_backend<std::execution::sequenced_policy> { | |
| 165 | using type = __cpu_backend_tag; | |
| 166 | }; | |
| 167 | ||
| 168 | # if _LIBCPP_STD_VER >= 20 | |
| 169 | template <> | |
| 170 | struct __select_backend<std::execution::unsequenced_policy> { | |
| 171 | using type = __cpu_backend_tag; | |
| 172 | }; | |
| 173 | # endif | |
| 174 | ||
| 175 | # if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) || \ | |
| 176 | defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH) | |
| 177 | template <> | |
| 178 | struct __select_backend<std::execution::parallel_policy> { | |
| 179 | using type = __cpu_backend_tag; | |
| 180 | }; | |
| 181 | ||
| 182 | template <> | |
| 183 | struct __select_backend<std::execution::parallel_unsequenced_policy> { | |
| 184 | using type = __cpu_backend_tag; | |
| 185 | }; | |
| 186 | ||
| 187 | # else | |
| 188 | ||
| 189 | // ...New vendors can add parallel backends here... | |
| 190 | ||
| 191 | # error "Invalid choice of a PSTL parallel backend" | |
| 192 | # endif | |
| 193 | ||
| 194 | _LIBCPP_END_NAMESPACE_STD | |
| 195 | ||
| 196 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 197 | ||
| 198 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backend.h created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | /* | |
| 15 | ||
| 16 | // _Functor takes a subrange for [__first, __last) that should be executed in serial | |
| 17 | template <class _RandomAccessIterator, class _Functor> | |
| 18 | void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func); | |
| 19 | ||
| 20 | template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction> | |
| 21 | _Tp __parallel_transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction); | |
| 22 | ||
| 23 | // Cancel the execution of other jobs - they aren't needed anymore | |
| 24 | void __cancel_execution(); | |
| 25 | ||
| 26 | template <class _RandomAccessIterator1, | |
| 27 | class _RandomAccessIterator2, | |
| 28 | class _RandomAccessIterator3, | |
| 29 | class _Compare, | |
| 30 | class _LeafMerge> | |
| 31 | void __parallel_merge( | |
| 32 | _RandomAccessIterator1 __first1, | |
| 33 | _RandomAccessIterator1 __last1, | |
| 34 | _RandomAccessIterator2 __first2, | |
| 35 | _RandomAccessIterator2 __last2, | |
| 36 | _RandomAccessIterator3 __outit, | |
| 37 | _Compare __comp, | |
| 38 | _LeafMerge __leaf_merge); | |
| 39 | ||
| 40 | template <class _RandomAccessIterator, class _Comp, class _LeafSort> | |
| 41 | void __parallel_stable_sort(_RandomAccessIterator __first, | |
| 42 | _RandomAccessIterator __last, | |
| 43 | _Comp __comp, | |
| 44 | _LeafSort __leaf_sort); | |
| 45 | ||
| 46 | TODO: Document the parallel backend | |
| 47 | */ | |
| 48 | ||
| 49 | #include <__algorithm/pstl_backends/cpu_backends/any_of.h> | |
| 50 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 51 | #include <__algorithm/pstl_backends/cpu_backends/fill.h> | |
| 52 | #include <__algorithm/pstl_backends/cpu_backends/find_if.h> | |
| 53 | #include <__algorithm/pstl_backends/cpu_backends/for_each.h> | |
| 54 | #include <__algorithm/pstl_backends/cpu_backends/merge.h> | |
| 55 | #include <__algorithm/pstl_backends/cpu_backends/stable_sort.h> | |
| 56 | #include <__algorithm/pstl_backends/cpu_backends/transform.h> | |
| 57 | #include <__algorithm/pstl_backends/cpu_backends/transform_reduce.h> | |
| 58 | ||
| 59 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/any_of.h created+90| ... | ... | @@ -0,0 +1,90 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H | |
| 11 | ||
| 12 | #include <__algorithm/any_of.h> | |
| 13 | #include <__algorithm/find_if.h> | |
| 14 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 15 | #include <__atomic/atomic.h> | |
| 16 | #include <__atomic/memory_order.h> | |
| 17 | #include <__config> | |
| 18 | #include <__functional/operations.h> | |
| 19 | #include <__iterator/iterator_traits.h> | |
| 20 | #include <__type_traits/is_execution_policy.h> | |
| 21 | #include <__utility/pair.h> | |
| 22 | #include <__utility/terminate_on_exception.h> | |
| 23 | #include <cstdint> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Index, class _Brick> | |
| 30 | _LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) { | |
| 31 | std::atomic<bool> __found(false); | |
| 32 | __par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) { | |
| 33 | if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) { | |
| 34 | __found.store(true, std::memory_order_relaxed); | |
| 35 | __par_backend::__cancel_execution(); | |
| 36 | } | |
| 37 | }); | |
| 38 | return __found; | |
| 39 | } | |
| 40 | ||
| 41 | // TODO: check whether __simd_first() can be used here | |
| 42 | template <class _Index, class _DifferenceType, class _Pred> | |
| 43 | _LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept { | |
| 44 | _DifferenceType __block_size = 4 < __n ? 4 : __n; | |
| 45 | const _Index __last = __first + __n; | |
| 46 | while (__last != __first) { | |
| 47 | int32_t __flag = 1; | |
| 48 | _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag) | |
| 49 | for (_DifferenceType __i = 0; __i < __block_size; ++__i) | |
| 50 | if (__pred(*(__first + __i))) | |
| 51 | __flag = 0; | |
| 52 | if (!__flag) | |
| 53 | return true; | |
| 54 | ||
| 55 | __first += __block_size; | |
| 56 | if (__last - __first >= __block_size << 1) { | |
| 57 | // Double the block _Size. Any unnecessary iterations can be amortized against work done so far. | |
| 58 | __block_size <<= 1; | |
| 59 | } else { | |
| 60 | __block_size = __last - __first; | |
| 61 | } | |
| 62 | } | |
| 63 | return false; | |
| 64 | } | |
| 65 | ||
| 66 | template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 67 | _LIBCPP_HIDE_FROM_ABI bool | |
| 68 | __pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 69 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 70 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 71 | return std::__terminate_on_exception([&] { | |
| 72 | return std::__parallel_or( | |
| 73 | __first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { | |
| 74 | return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 75 | __cpu_backend_tag{}, __brick_first, __brick_last, __pred); | |
| 76 | }); | |
| 77 | }); | |
| 78 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 79 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 80 | return std::__simd_or(__first, __last - __first, __pred); | |
| 81 | } else { | |
| 82 | return std::any_of(__first, __last, __pred); | |
| 83 | } | |
| 84 | } | |
| 85 | ||
| 86 | _LIBCPP_END_NAMESPACE_STD | |
| 87 | ||
| 88 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 89 | ||
| 90 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <cstddef> | |
| 14 | ||
| 15 | #if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) | |
| 16 | # include <__algorithm/pstl_backends/cpu_backends/serial.h> | |
| 17 | #elif defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) | |
| 18 | # include <__algorithm/pstl_backends/cpu_backends/thread.h> | |
| 19 | #elif defined(_LIBCPP_PSTL_CPU_BACKEND_LIBDISPATCH) | |
| 20 | # include <__algorithm/pstl_backends/cpu_backends/libdispatch.h> | |
| 21 | #else | |
| 22 | # error "Invalid CPU backend choice" | |
| 23 | #endif | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | ||
| 31 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 32 | ||
| 33 | struct __cpu_backend_tag {}; | |
| 34 | ||
| 35 | inline constexpr size_t __lane_size = 64; | |
| 36 | ||
| 37 | _LIBCPP_END_NAMESPACE_STD | |
| 38 | ||
| 39 | #endif // _LIBCPP_STD_VER >= 17 | |
| 40 | ||
| 41 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_BACKEND_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/fill.h created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H | |
| 11 | ||
| 12 | #include <__algorithm/fill.h> | |
| 13 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/is_execution_policy.h> | |
| 17 | #include <__utility/terminate_on_exception.h> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | template <class _Index, class _DifferenceType, class _Tp> | |
| 28 | _LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept { | |
| 29 | _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED | |
| 30 | _PSTL_PRAGMA_SIMD | |
| 31 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 32 | __first[__i] = __value; | |
| 33 | return __first + __n; | |
| 34 | } | |
| 35 | ||
| 36 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 37 | _LIBCPP_HIDE_FROM_ABI void | |
| 38 | __pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 39 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 40 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 41 | std::__terminate_on_exception([&] { | |
| 42 | __par_backend::__parallel_for( | |
| 43 | __first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { | |
| 44 | std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 45 | __cpu_backend_tag{}, __brick_first, __brick_last, __value); | |
| 46 | }); | |
| 47 | }); | |
| 48 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 49 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 50 | std::__simd_fill_n(__first, __last - __first, __value); | |
| 51 | } else { | |
| 52 | std::fill(__first, __last, __value); | |
| 53 | } | |
| 54 | } | |
| 55 | ||
| 56 | _LIBCPP_END_NAMESPACE_STD | |
| 57 | ||
| 58 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 59 | ||
| 60 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/find_if.h created+123| ... | ... | @@ -0,0 +1,123 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H | |
| 11 | ||
| 12 | #include <__algorithm/find_if.h> | |
| 13 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 14 | #include <__atomic/atomic.h> | |
| 15 | #include <__config> | |
| 16 | #include <__functional/operations.h> | |
| 17 | #include <__iterator/iterator_traits.h> | |
| 18 | #include <__type_traits/is_execution_policy.h> | |
| 19 | #include <__utility/pair.h> | |
| 20 | #include <__utility/terminate_on_exception.h> | |
| 21 | #include <cstddef> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | template <class _Index, class _Brick, class _Compare> | |
| 32 | _LIBCPP_HIDE_FROM_ABI _Index | |
| 33 | __parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) { | |
| 34 | typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType; | |
| 35 | const _DifferenceType __n = __last - __first; | |
| 36 | _DifferenceType __initial_dist = __b_first ? __n : -1; | |
| 37 | std::atomic<_DifferenceType> __extremum(__initial_dist); | |
| 38 | // TODO: find out what is better here: parallel_for or parallel_reduce | |
| 39 | __par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) { | |
| 40 | // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of | |
| 41 | // why using a shared variable scales fairly well in this situation. | |
| 42 | if (__comp(__i - __first, __extremum)) { | |
| 43 | _Index __res = __f(__i, __j); | |
| 44 | // If not '__last' returned then we found what we want so put this to extremum | |
| 45 | if (__res != __j) { | |
| 46 | const _DifferenceType __k = __res - __first; | |
| 47 | for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) { | |
| 48 | __extremum.compare_exchange_weak(__old, __k); | |
| 49 | } | |
| 50 | } | |
| 51 | } | |
| 52 | }); | |
| 53 | return __extremum != __initial_dist ? __first + __extremum : __last; | |
| 54 | } | |
| 55 | ||
| 56 | template <class _Index, class _DifferenceType, class _Compare> | |
| 57 | _LIBCPP_HIDE_FROM_ABI _Index | |
| 58 | __simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept { | |
| 59 | // Experiments show good block sizes like this | |
| 60 | const _DifferenceType __block_size = 8; | |
| 61 | alignas(__lane_size) _DifferenceType __lane[__block_size] = {0}; | |
| 62 | while (__end - __begin >= __block_size) { | |
| 63 | _DifferenceType __found = 0; | |
| 64 | _PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) { | |
| 65 | const _DifferenceType __t = __comp(__first, __i); | |
| 66 | __lane[__i - __begin] = __t; | |
| 67 | __found |= __t; | |
| 68 | } | |
| 69 | if (__found) { | |
| 70 | _DifferenceType __i; | |
| 71 | // This will vectorize | |
| 72 | for (__i = 0; __i < __block_size; ++__i) { | |
| 73 | if (__lane[__i]) { | |
| 74 | break; | |
| 75 | } | |
| 76 | } | |
| 77 | return __first + __begin + __i; | |
| 78 | } | |
| 79 | __begin += __block_size; | |
| 80 | } | |
| 81 | ||
| 82 | // Keep remainder scalar | |
| 83 | while (__begin != __end) { | |
| 84 | if (__comp(__first, __begin)) { | |
| 85 | return __first + __begin; | |
| 86 | } | |
| 87 | ++__begin; | |
| 88 | } | |
| 89 | return __first + __end; | |
| 90 | } | |
| 91 | ||
| 92 | template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 93 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 94 | __pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 95 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 96 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 97 | return std::__terminate_on_exception([&] { | |
| 98 | return std::__parallel_find( | |
| 99 | __first, | |
| 100 | __last, | |
| 101 | [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { | |
| 102 | return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 103 | __cpu_backend_tag{}, __brick_first, __brick_last, __pred); | |
| 104 | }, | |
| 105 | less<>{}, | |
| 106 | true); | |
| 107 | }); | |
| 108 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 109 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 110 | using __diff_t = __iter_diff_t<_ForwardIterator>; | |
| 111 | return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) { | |
| 112 | return __pred(__iter[__i]); | |
| 113 | }); | |
| 114 | } else { | |
| 115 | return std::find_if(__first, __last, __pred); | |
| 116 | } | |
| 117 | } | |
| 118 | ||
| 119 | _LIBCPP_END_NAMESPACE_STD | |
| 120 | ||
| 121 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 122 | ||
| 123 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/for_each.h created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H | |
| 11 | ||
| 12 | #include <__algorithm/for_each.h> | |
| 13 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/is_execution_policy.h> | |
| 17 | #include <__utility/terminate_on_exception.h> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | template <class _Iterator, class _DifferenceType, class _Function> | |
| 28 | _LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept { | |
| 29 | _PSTL_PRAGMA_SIMD | |
| 30 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 31 | __f(__first[__i]); | |
| 32 | ||
| 33 | return __first + __n; | |
| 34 | } | |
| 35 | ||
| 36 | template <class _ExecutionPolicy, class _ForwardIterator, class _Functor> | |
| 37 | _LIBCPP_HIDE_FROM_ABI void | |
| 38 | __pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) { | |
| 39 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 40 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 41 | std::__terminate_on_exception([&] { | |
| 42 | std::__par_backend::__parallel_for( | |
| 43 | __first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { | |
| 44 | std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 45 | __cpu_backend_tag{}, __brick_first, __brick_last, __func); | |
| 46 | }); | |
| 47 | }); | |
| 48 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 49 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 50 | std::__simd_walk_1(__first, __last - __first, __func); | |
| 51 | } else { | |
| 52 | std::for_each(__first, __last, __func); | |
| 53 | } | |
| 54 | } | |
| 55 | ||
| 56 | _LIBCPP_END_NAMESPACE_STD | |
| 57 | ||
| 58 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 59 | ||
| 60 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/libdispatch.h created+241| ... | ... | @@ -0,0 +1,241 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H | |
| 11 | ||
| 12 | #include <__algorithm/lower_bound.h> | |
| 13 | #include <__algorithm/max.h> | |
| 14 | #include <__algorithm/upper_bound.h> | |
| 15 | #include <__atomic/atomic.h> | |
| 16 | #include <__config> | |
| 17 | #include <__exception/terminate.h> | |
| 18 | #include <__iterator/iterator_traits.h> | |
| 19 | #include <__iterator/move_iterator.h> | |
| 20 | #include <__memory/allocator.h> | |
| 21 | #include <__memory/construct_at.h> | |
| 22 | #include <__memory/unique_ptr.h> | |
| 23 | #include <__numeric/reduce.h> | |
| 24 | #include <__utility/exception_guard.h> | |
| 25 | #include <__utility/move.h> | |
| 26 | #include <__utility/pair.h> | |
| 27 | #include <__utility/terminate_on_exception.h> | |
| 28 | #include <cstddef> | |
| 29 | #include <new> | |
| 30 | ||
| 31 | _LIBCPP_PUSH_MACROS | |
| 32 | #include <__undef_macros> | |
| 33 | ||
| 34 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 35 | ||
| 36 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 37 | ||
| 38 | namespace __par_backend { | |
| 39 | inline namespace __libdispatch { | |
| 40 | ||
| 41 | // ::dispatch_apply is marked as __attribute__((nothrow)) because it doesn't let exceptions propagate, and neither do | |
| 42 | // we. | |
| 43 | // TODO: Do we want to add [[_Clang::__callback__(__func, __context, __)]]? | |
| 44 | _LIBCPP_EXPORTED_FROM_ABI void | |
| 45 | __dispatch_apply(size_t __chunk_count, void* __context, void (*__func)(void* __context, size_t __chunk)) noexcept; | |
| 46 | ||
| 47 | template <class _Func> | |
| 48 | _LIBCPP_HIDE_FROM_ABI void __dispatch_apply(size_t __chunk_count, _Func __func) noexcept { | |
| 49 | __libdispatch::__dispatch_apply(__chunk_count, &__func, [](void* __context, size_t __chunk) { | |
| 50 | (*static_cast<_Func*>(__context))(__chunk); | |
| 51 | }); | |
| 52 | } | |
| 53 | ||
| 54 | struct __chunk_partitions { | |
| 55 | ptrdiff_t __chunk_count_; // includes the first chunk | |
| 56 | ptrdiff_t __chunk_size_; | |
| 57 | ptrdiff_t __first_chunk_size_; | |
| 58 | }; | |
| 59 | ||
| 60 | [[__gnu__::__const__]] _LIBCPP_EXPORTED_FROM_ABI __chunk_partitions __partition_chunks(ptrdiff_t __size); | |
| 61 | ||
| 62 | template <class _RandomAccessIterator, class _Functor> | |
| 63 | _LIBCPP_HIDE_FROM_ABI void | |
| 64 | __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func) { | |
| 65 | auto __partitions = __libdispatch::__partition_chunks(__last - __first); | |
| 66 | ||
| 67 | // Perform the chunked execution. | |
| 68 | __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) { | |
| 69 | auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_; | |
| 70 | auto __index = | |
| 71 | __chunk == 0 | |
| 72 | ? 0 | |
| 73 | : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_); | |
| 74 | __func(__first + __index, __first + __index + __this_chunk_size); | |
| 75 | }); | |
| 76 | } | |
| 77 | ||
| 78 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIteratorOut> | |
| 79 | struct __merge_range { | |
| 80 | __merge_range(_RandomAccessIterator1 __mid1, _RandomAccessIterator2 __mid2, _RandomAccessIteratorOut __result) | |
| 81 | : __mid1_(__mid1), __mid2_(__mid2), __result_(__result) {} | |
| 82 | ||
| 83 | _RandomAccessIterator1 __mid1_; | |
| 84 | _RandomAccessIterator2 __mid2_; | |
| 85 | _RandomAccessIteratorOut __result_; | |
| 86 | }; | |
| 87 | ||
| 88 | template <typename _RandomAccessIterator1, | |
| 89 | typename _RandomAccessIterator2, | |
| 90 | typename _RandomAccessIterator3, | |
| 91 | typename _Compare, | |
| 92 | typename _LeafMerge> | |
| 93 | _LIBCPP_HIDE_FROM_ABI void __parallel_merge( | |
| 94 | _RandomAccessIterator1 __first1, | |
| 95 | _RandomAccessIterator1 __last1, | |
| 96 | _RandomAccessIterator2 __first2, | |
| 97 | _RandomAccessIterator2 __last2, | |
| 98 | _RandomAccessIterator3 __result, | |
| 99 | _Compare __comp, | |
| 100 | _LeafMerge __leaf_merge) { | |
| 101 | __chunk_partitions __partitions = | |
| 102 | __libdispatch::__partition_chunks(std::max<ptrdiff_t>(__last1 - __first1, __last2 - __first2)); | |
| 103 | ||
| 104 | if (__partitions.__chunk_count_ == 0) | |
| 105 | return; | |
| 106 | ||
| 107 | if (__partitions.__chunk_count_ == 1) { | |
| 108 | __leaf_merge(__first1, __last1, __first2, __last2, __result, __comp); | |
| 109 | return; | |
| 110 | } | |
| 111 | ||
| 112 | using __merge_range_t = __merge_range<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3>; | |
| 113 | auto const __n_ranges = __partitions.__chunk_count_ + 1; | |
| 114 | ||
| 115 | // TODO: use __uninitialized_buffer | |
| 116 | auto __destroy = [=](__merge_range_t* __ptr) { | |
| 117 | std::destroy_n(__ptr, __n_ranges); | |
| 118 | std::allocator<__merge_range_t>().deallocate(__ptr, __n_ranges); | |
| 119 | }; | |
| 120 | unique_ptr<__merge_range_t[], decltype(__destroy)> __ranges( | |
| 121 | std::allocator<__merge_range_t>().allocate(__n_ranges), __destroy); | |
| 122 | ||
| 123 | // TODO: Improve the case where the smaller range is merged into just a few (or even one) chunks of the larger case | |
| 124 | std::__terminate_on_exception([&] { | |
| 125 | __merge_range_t* __r = __ranges.get(); | |
| 126 | std::__construct_at(__r++, __first1, __first2, __result); | |
| 127 | ||
| 128 | bool __iterate_first_range = __last1 - __first1 > __last2 - __first2; | |
| 129 | ||
| 130 | auto __compute_chunk = [&](size_t __chunk_size) -> __merge_range_t { | |
| 131 | auto [__mid1, __mid2] = [&] { | |
| 132 | if (__iterate_first_range) { | |
| 133 | auto __m1 = __first1 + __chunk_size; | |
| 134 | auto __m2 = std::lower_bound(__first2, __last2, __m1[-1], __comp); | |
| 135 | return std::make_pair(__m1, __m2); | |
| 136 | } else { | |
| 137 | auto __m2 = __first2 + __chunk_size; | |
| 138 | auto __m1 = std::lower_bound(__first1, __last1, __m2[-1], __comp); | |
| 139 | return std::make_pair(__m1, __m2); | |
| 140 | } | |
| 141 | }(); | |
| 142 | ||
| 143 | __result += (__mid1 - __first1) + (__mid2 - __first2); | |
| 144 | __first1 = __mid1; | |
| 145 | __first2 = __mid2; | |
| 146 | return {std::move(__mid1), std::move(__mid2), __result}; | |
| 147 | }; | |
| 148 | ||
| 149 | // handle first chunk | |
| 150 | std::__construct_at(__r++, __compute_chunk(__partitions.__first_chunk_size_)); | |
| 151 | ||
| 152 | // handle 2 -> N - 1 chunks | |
| 153 | for (ptrdiff_t __i = 0; __i != __partitions.__chunk_count_ - 2; ++__i) | |
| 154 | std::__construct_at(__r++, __compute_chunk(__partitions.__chunk_size_)); | |
| 155 | ||
| 156 | // handle last chunk | |
| 157 | std::__construct_at(__r, __last1, __last2, __result); | |
| 158 | ||
| 159 | __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __index) { | |
| 160 | auto __first_iters = __ranges[__index]; | |
| 161 | auto __last_iters = __ranges[__index + 1]; | |
| 162 | __leaf_merge( | |
| 163 | __first_iters.__mid1_, | |
| 164 | __last_iters.__mid1_, | |
| 165 | __first_iters.__mid2_, | |
| 166 | __last_iters.__mid2_, | |
| 167 | __first_iters.__result_, | |
| 168 | __comp); | |
| 169 | }); | |
| 170 | }); | |
| 171 | } | |
| 172 | ||
| 173 | template <class _RandomAccessIterator, class _Transform, class _Value, class _Combiner, class _Reduction> | |
| 174 | _LIBCPP_HIDE_FROM_ABI _Value __parallel_transform_reduce( | |
| 175 | _RandomAccessIterator __first, | |
| 176 | _RandomAccessIterator __last, | |
| 177 | _Transform __transform, | |
| 178 | _Value __init, | |
| 179 | _Combiner __combiner, | |
| 180 | _Reduction __reduction) { | |
| 181 | if (__first == __last) | |
| 182 | return __init; | |
| 183 | ||
| 184 | auto __partitions = __libdispatch::__partition_chunks(__last - __first); | |
| 185 | ||
| 186 | auto __destroy = [__count = __partitions.__chunk_count_](_Value* __ptr) { | |
| 187 | std::destroy_n(__ptr, __count); | |
| 188 | std::allocator<_Value>().deallocate(__ptr, __count); | |
| 189 | }; | |
| 190 | ||
| 191 | // TODO: use __uninitialized_buffer | |
| 192 | // TODO: allocate one element per worker instead of one element per chunk | |
| 193 | unique_ptr<_Value[], decltype(__destroy)> __values( | |
| 194 | std::allocator<_Value>().allocate(__partitions.__chunk_count_), __destroy); | |
| 195 | ||
| 196 | // __dispatch_apply is noexcept | |
| 197 | __libdispatch::__dispatch_apply(__partitions.__chunk_count_, [&](size_t __chunk) { | |
| 198 | auto __this_chunk_size = __chunk == 0 ? __partitions.__first_chunk_size_ : __partitions.__chunk_size_; | |
| 199 | auto __index = | |
| 200 | __chunk == 0 | |
| 201 | ? 0 | |
| 202 | : (__chunk * __partitions.__chunk_size_) + (__partitions.__first_chunk_size_ - __partitions.__chunk_size_); | |
| 203 | if (__this_chunk_size != 1) { | |
| 204 | std::__construct_at( | |
| 205 | __values.get() + __chunk, | |
| 206 | __reduction(__first + __index + 2, | |
| 207 | __first + __index + __this_chunk_size, | |
| 208 | __combiner(__transform(__first + __index), __transform(__first + __index + 1)))); | |
| 209 | } else { | |
| 210 | std::__construct_at(__values.get() + __chunk, __transform(__first + __index)); | |
| 211 | } | |
| 212 | }); | |
| 213 | ||
| 214 | return std::__terminate_on_exception([&] { | |
| 215 | return std::reduce( | |
| 216 | std::make_move_iterator(__values.get()), | |
| 217 | std::make_move_iterator(__values.get() + __partitions.__chunk_count_), | |
| 218 | std::move(__init), | |
| 219 | __combiner); | |
| 220 | }); | |
| 221 | } | |
| 222 | ||
| 223 | // TODO: parallelize this | |
| 224 | template <class _RandomAccessIterator, class _Comp, class _LeafSort> | |
| 225 | _LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort( | |
| 226 | _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp, _LeafSort __leaf_sort) { | |
| 227 | __leaf_sort(__first, __last, __comp); | |
| 228 | } | |
| 229 | ||
| 230 | _LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {} | |
| 231 | ||
| 232 | } // namespace __libdispatch | |
| 233 | } // namespace __par_backend | |
| 234 | ||
| 235 | _LIBCPP_END_NAMESPACE_STD | |
| 236 | ||
| 237 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 238 | ||
| 239 | _LIBCPP_POP_MACROS | |
| 240 | ||
| 241 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_LIBDISPATCH_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/merge.h created+79| ... | ... | @@ -0,0 +1,79 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H | |
| 11 | ||
| 12 | #include <__algorithm/merge.h> | |
| 13 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/is_execution_policy.h> | |
| 17 | #include <__utility/move.h> | |
| 18 | #include <__utility/terminate_on_exception.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | template <class _ExecutionPolicy, | |
| 29 | class _ForwardIterator1, | |
| 30 | class _ForwardIterator2, | |
| 31 | class _ForwardOutIterator, | |
| 32 | class _Comp> | |
| 33 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge( | |
| 34 | __cpu_backend_tag, | |
| 35 | _ForwardIterator1 __first1, | |
| 36 | _ForwardIterator1 __last1, | |
| 37 | _ForwardIterator2 __first2, | |
| 38 | _ForwardIterator2 __last2, | |
| 39 | _ForwardOutIterator __result, | |
| 40 | _Comp __comp) { | |
| 41 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 42 | __has_random_access_iterator_category<_ForwardIterator1>::value && | |
| 43 | __has_random_access_iterator_category<_ForwardIterator2>::value && | |
| 44 | __has_random_access_iterator_category<_ForwardOutIterator>::value) { | |
| 45 | return std::__terminate_on_exception([&] { | |
| 46 | __par_backend::__parallel_merge( | |
| 47 | __first1, | |
| 48 | __last1, | |
| 49 | __first2, | |
| 50 | __last2, | |
| 51 | __result, | |
| 52 | __comp, | |
| 53 | [](_ForwardIterator1 __g_first1, | |
| 54 | _ForwardIterator1 __g_last1, | |
| 55 | _ForwardIterator2 __g_first2, | |
| 56 | _ForwardIterator2 __g_last2, | |
| 57 | _ForwardOutIterator __g_result, | |
| 58 | _Comp __g_comp) { | |
| 59 | return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 60 | __cpu_backend_tag{}, | |
| 61 | std::move(__g_first1), | |
| 62 | std::move(__g_last1), | |
| 63 | std::move(__g_first2), | |
| 64 | std::move(__g_last2), | |
| 65 | std::move(__g_result), | |
| 66 | std::move(__g_comp)); | |
| 67 | }); | |
| 68 | return __result + (__last1 - __first1) + (__last2 - __first2); | |
| 69 | }); | |
| 70 | } else { | |
| 71 | return std::merge(__first1, __last1, __first2, __last2, __result, __comp); | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | _LIBCPP_END_NAMESPACE_STD | |
| 76 | ||
| 77 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 78 | ||
| 79 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/serial.h created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H | |
| 11 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__utility/move.h> | |
| 15 | #include <cstddef> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | namespace __par_backend { | |
| 26 | inline namespace __serial_cpu_backend { | |
| 27 | ||
| 28 | template <class _RandomAccessIterator, class _Fp> | |
| 29 | _LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) { | |
| 30 | __f(__first, __last); | |
| 31 | } | |
| 32 | ||
| 33 | template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce> | |
| 34 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 35 | __parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) { | |
| 36 | return __reduce(std::move(__first), std::move(__last), std::move(__init)); | |
| 37 | } | |
| 38 | ||
| 39 | template <class _RandomAccessIterator, class _Compare, class _LeafSort> | |
| 40 | _LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort( | |
| 41 | _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) { | |
| 42 | __leaf_sort(__first, __last, __comp); | |
| 43 | } | |
| 44 | ||
| 45 | _LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {} | |
| 46 | ||
| 47 | template <class _RandomAccessIterator1, | |
| 48 | class _RandomAccessIterator2, | |
| 49 | class _RandomAccessIterator3, | |
| 50 | class _Compare, | |
| 51 | class _LeafMerge> | |
| 52 | _LIBCPP_HIDE_FROM_ABI void __parallel_merge( | |
| 53 | _RandomAccessIterator1 __first1, | |
| 54 | _RandomAccessIterator1 __last1, | |
| 55 | _RandomAccessIterator2 __first2, | |
| 56 | _RandomAccessIterator2 __last2, | |
| 57 | _RandomAccessIterator3 __outit, | |
| 58 | _Compare __comp, | |
| 59 | _LeafMerge __leaf_merge) { | |
| 60 | __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); | |
| 61 | } | |
| 62 | ||
| 63 | // TODO: Complete this list | |
| 64 | ||
| 65 | } // namespace __serial_cpu_backend | |
| 66 | } // namespace __par_backend | |
| 67 | ||
| 68 | _LIBCPP_END_NAMESPACE_STD | |
| 69 | ||
| 70 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17 | |
| 71 | ||
| 72 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/stable_sort.h created+45| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 13 | #include <__algorithm/stable_sort.h> | |
| 14 | #include <__config> | |
| 15 | #include <__type_traits/is_execution_policy.h> | |
| 16 | #include <__utility/terminate_on_exception.h> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Comp> | |
| 27 | _LIBCPP_HIDE_FROM_ABI void | |
| 28 | __pstl_stable_sort(__cpu_backend_tag, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { | |
| 29 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy>) { | |
| 30 | std::__terminate_on_exception([&] { | |
| 31 | __par_backend::__parallel_stable_sort( | |
| 32 | __first, __last, __comp, [](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) { | |
| 33 | std::stable_sort(__g_first, __g_last, __g_comp); | |
| 34 | }); | |
| 35 | }); | |
| 36 | } else { | |
| 37 | std::stable_sort(__first, __last, __comp); | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | _LIBCPP_END_NAMESPACE_STD | |
| 42 | ||
| 43 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 44 | ||
| 45 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_STABLE_SORT_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/thread.h created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H | |
| 11 | ||
| 12 | #include <__assert> | |
| 13 | #include <__config> | |
| 14 | #include <__utility/move.h> | |
| 15 | #include <cstddef> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_PUSH_MACROS | |
| 22 | #include <__undef_macros> | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 25 | ||
| 26 | // This backend implementation is for testing purposes only and not meant for production use. This will be replaced | |
| 27 | // by a proper implementation once the PSTL implementation is somewhat stable. | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | namespace __par_backend { | |
| 32 | inline namespace __thread_cpu_backend { | |
| 33 | ||
| 34 | template <class _RandomAccessIterator, class _Fp> | |
| 35 | _LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) { | |
| 36 | __f(__first, __last); | |
| 37 | } | |
| 38 | ||
| 39 | template <class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce> | |
| 40 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 41 | __parallel_transform_reduce(_Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce) { | |
| 42 | return __reduce(std::move(__first), std::move(__last), std::move(__init)); | |
| 43 | } | |
| 44 | ||
| 45 | template <class _RandomAccessIterator, class _Compare, class _LeafSort> | |
| 46 | _LIBCPP_HIDE_FROM_ABI void __parallel_stable_sort( | |
| 47 | _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort) { | |
| 48 | __leaf_sort(__first, __last, __comp); | |
| 49 | } | |
| 50 | ||
| 51 | _LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {} | |
| 52 | ||
| 53 | template <class _RandomAccessIterator1, | |
| 54 | class _RandomAccessIterator2, | |
| 55 | class _RandomAccessIterator3, | |
| 56 | class _Compare, | |
| 57 | class _LeafMerge> | |
| 58 | _LIBCPP_HIDE_FROM_ABI void __parallel_merge( | |
| 59 | _RandomAccessIterator1 __first1, | |
| 60 | _RandomAccessIterator1 __last1, | |
| 61 | _RandomAccessIterator2 __first2, | |
| 62 | _RandomAccessIterator2 __last2, | |
| 63 | _RandomAccessIterator3 __outit, | |
| 64 | _Compare __comp, | |
| 65 | _LeafMerge __leaf_merge) { | |
| 66 | __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); | |
| 67 | } | |
| 68 | ||
| 69 | } // namespace __thread_cpu_backend | |
| 70 | } // namespace __par_backend | |
| 71 | ||
| 72 | _LIBCPP_END_NAMESPACE_STD | |
| 73 | ||
| 74 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17 | |
| 75 | ||
| 76 | _LIBCPP_POP_MACROS | |
| 77 | ||
| 78 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform.h created+132| ... | ... | @@ -0,0 +1,132 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 13 | #include <__algorithm/transform.h> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/enable_if.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <__utility/terminate_on_exception.h> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function> | |
| 30 | _LIBCPP_HIDE_FROM_ABI _Iterator2 | |
| 31 | __simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept { | |
| 32 | _PSTL_PRAGMA_SIMD | |
| 33 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 34 | __f(__first1[__i], __first2[__i]); | |
| 35 | return __first2 + __n; | |
| 36 | } | |
| 37 | ||
| 38 | template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardOutIterator, class _UnaryOperation> | |
| 39 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform( | |
| 40 | __cpu_backend_tag, | |
| 41 | _ForwardIterator __first, | |
| 42 | _ForwardIterator __last, | |
| 43 | _ForwardOutIterator __result, | |
| 44 | _UnaryOperation __op) { | |
| 45 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 46 | __has_random_access_iterator_category<_ForwardIterator>::value && | |
| 47 | __has_random_access_iterator_category<_ForwardOutIterator>::value) { | |
| 48 | std::__terminate_on_exception([&] { | |
| 49 | std::__par_backend::__parallel_for( | |
| 50 | __first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { | |
| 51 | return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 52 | __cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op); | |
| 53 | }); | |
| 54 | }); | |
| 55 | return __result + (__last - __first); | |
| 56 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 57 | __has_random_access_iterator_category<_ForwardIterator>::value && | |
| 58 | __has_random_access_iterator_category<_ForwardOutIterator>::value) { | |
| 59 | return std::__simd_walk_2( | |
| 60 | __first, | |
| 61 | __last - __first, | |
| 62 | __result, | |
| 63 | [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) { | |
| 64 | __out_value = __op(__in_value); | |
| 65 | }); | |
| 66 | } else { | |
| 67 | return std::transform(__first, __last, __result, __op); | |
| 68 | } | |
| 69 | } | |
| 70 | ||
| 71 | template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function> | |
| 72 | _LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3( | |
| 73 | _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept { | |
| 74 | _PSTL_PRAGMA_SIMD | |
| 75 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 76 | __f(__first1[__i], __first2[__i], __first3[__i]); | |
| 77 | return __first3 + __n; | |
| 78 | } | |
| 79 | template <class _ExecutionPolicy, | |
| 80 | class _ForwardIterator1, | |
| 81 | class _ForwardIterator2, | |
| 82 | class _ForwardOutIterator, | |
| 83 | class _BinaryOperation, | |
| 84 | enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> | |
| 85 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform( | |
| 86 | __cpu_backend_tag, | |
| 87 | _ForwardIterator1 __first1, | |
| 88 | _ForwardIterator1 __last1, | |
| 89 | _ForwardIterator2 __first2, | |
| 90 | _ForwardOutIterator __result, | |
| 91 | _BinaryOperation __op) { | |
| 92 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 93 | __has_random_access_iterator_category<_ForwardIterator1>::value && | |
| 94 | __has_random_access_iterator_category<_ForwardIterator2>::value && | |
| 95 | __has_random_access_iterator_category<_ForwardOutIterator>::value) { | |
| 96 | std::__terminate_on_exception([&] { | |
| 97 | std::__par_backend::__parallel_for( | |
| 98 | __first1, | |
| 99 | __last1, | |
| 100 | [__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) { | |
| 101 | return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 102 | __cpu_backend_tag{}, | |
| 103 | __brick_first, | |
| 104 | __brick_last, | |
| 105 | __first2 + (__brick_first - __first1), | |
| 106 | __result + (__brick_first - __first1), | |
| 107 | __op); | |
| 108 | }); | |
| 109 | }); | |
| 110 | return __result + (__last1 - __first1); | |
| 111 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 112 | __has_random_access_iterator_category<_ForwardIterator1>::value && | |
| 113 | __has_random_access_iterator_category<_ForwardIterator2>::value && | |
| 114 | __has_random_access_iterator_category<_ForwardOutIterator>::value) { | |
| 115 | return std::__simd_walk_3( | |
| 116 | __first1, | |
| 117 | __last1 - __first1, | |
| 118 | __first2, | |
| 119 | __result, | |
| 120 | [&](__iter_reference<_ForwardIterator1> __in1, | |
| 121 | __iter_reference<_ForwardIterator2> __in2, | |
| 122 | __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); }); | |
| 123 | } else { | |
| 124 | return std::transform(__first1, __last1, __first2, __result, __op); | |
| 125 | } | |
| 126 | } | |
| 127 | ||
| 128 | _LIBCPP_END_NAMESPACE_STD | |
| 129 | ||
| 130 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 131 | ||
| 132 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H |
lib/libcxx/include/__algorithm/pstl_backends/cpu_backends/transform_reduce.h created+194| ... | ... | @@ -0,0 +1,194 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backends/cpu_backends/backend.h> | |
| 13 | #include <__config> | |
| 14 | #include <__iterator/iterator_traits.h> | |
| 15 | #include <__numeric/transform_reduce.h> | |
| 16 | #include <__type_traits/is_arithmetic.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | #include <__type_traits/operation_traits.h> | |
| 19 | #include <__utility/move.h> | |
| 20 | #include <__utility/terminate_on_exception.h> | |
| 21 | #include <new> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | template < | |
| 32 | typename _DifferenceType, | |
| 33 | typename _Tp, | |
| 34 | typename _BinaryOperation, | |
| 35 | typename _UnaryOperation, | |
| 36 | __enable_if_t<__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>, int> = 0> | |
| 37 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 38 | __simd_transform_reduce(_DifferenceType __n, _Tp __init, _BinaryOperation, _UnaryOperation __f) noexcept { | |
| 39 | _PSTL_PRAGMA_SIMD_REDUCTION(+ : __init) | |
| 40 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 41 | __init += __f(__i); | |
| 42 | return __init; | |
| 43 | } | |
| 44 | ||
| 45 | template < | |
| 46 | typename _Size, | |
| 47 | typename _Tp, | |
| 48 | typename _BinaryOperation, | |
| 49 | typename _UnaryOperation, | |
| 50 | __enable_if_t<!(__is_trivial_plus_operation<_BinaryOperation, _Tp, _Tp>::value && is_arithmetic_v<_Tp>), int> = 0> | |
| 51 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 52 | __simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _UnaryOperation __f) noexcept { | |
| 53 | const _Size __block_size = __lane_size / sizeof(_Tp); | |
| 54 | if (__n > 2 * __block_size && __block_size > 1) { | |
| 55 | alignas(__lane_size) char __lane_buffer[__lane_size]; | |
| 56 | _Tp* __lane = reinterpret_cast<_Tp*>(__lane_buffer); | |
| 57 | ||
| 58 | // initializer | |
| 59 | _PSTL_PRAGMA_SIMD | |
| 60 | for (_Size __i = 0; __i < __block_size; ++__i) { | |
| 61 | ::new (__lane + __i) _Tp(__binary_op(__f(__i), __f(__block_size + __i))); | |
| 62 | } | |
| 63 | // main loop | |
| 64 | _Size __i = 2 * __block_size; | |
| 65 | const _Size __last_iteration = __block_size * (__n / __block_size); | |
| 66 | for (; __i < __last_iteration; __i += __block_size) { | |
| 67 | _PSTL_PRAGMA_SIMD | |
| 68 | for (_Size __j = 0; __j < __block_size; ++__j) { | |
| 69 | __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__i + __j)); | |
| 70 | } | |
| 71 | } | |
| 72 | // remainder | |
| 73 | _PSTL_PRAGMA_SIMD | |
| 74 | for (_Size __j = 0; __j < __n - __last_iteration; ++__j) { | |
| 75 | __lane[__j] = __binary_op(std::move(__lane[__j]), __f(__last_iteration + __j)); | |
| 76 | } | |
| 77 | // combiner | |
| 78 | for (_Size __j = 0; __j < __block_size; ++__j) { | |
| 79 | __init = __binary_op(std::move(__init), std::move(__lane[__j])); | |
| 80 | } | |
| 81 | // destroyer | |
| 82 | _PSTL_PRAGMA_SIMD | |
| 83 | for (_Size __j = 0; __j < __block_size; ++__j) { | |
| 84 | __lane[__j].~_Tp(); | |
| 85 | } | |
| 86 | } else { | |
| 87 | for (_Size __i = 0; __i < __n; ++__i) { | |
| 88 | __init = __binary_op(std::move(__init), __f(__i)); | |
| 89 | } | |
| 90 | } | |
| 91 | return __init; | |
| 92 | } | |
| 93 | ||
| 94 | template <class _ExecutionPolicy, | |
| 95 | class _ForwardIterator1, | |
| 96 | class _ForwardIterator2, | |
| 97 | class _Tp, | |
| 98 | class _BinaryOperation1, | |
| 99 | class _BinaryOperation2> | |
| 100 | _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce( | |
| 101 | __cpu_backend_tag, | |
| 102 | _ForwardIterator1 __first1, | |
| 103 | _ForwardIterator1 __last1, | |
| 104 | _ForwardIterator2 __first2, | |
| 105 | _Tp __init, | |
| 106 | _BinaryOperation1 __reduce, | |
| 107 | _BinaryOperation2 __transform) { | |
| 108 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 109 | __has_random_access_iterator_category<_ForwardIterator1>::value && | |
| 110 | __has_random_access_iterator_category<_ForwardIterator2>::value) { | |
| 111 | return std::__terminate_on_exception([&] { | |
| 112 | return __par_backend::__parallel_transform_reduce( | |
| 113 | __first1, | |
| 114 | std::move(__last1), | |
| 115 | [__first1, __first2, __transform](_ForwardIterator1 __iter) { | |
| 116 | return __transform(*__iter, *(__first2 + (__iter - __first1))); | |
| 117 | }, | |
| 118 | std::move(__init), | |
| 119 | std::move(__reduce), | |
| 120 | [__first1, __first2, __reduce, __transform]( | |
| 121 | _ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last, _Tp __brick_init) { | |
| 122 | return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 123 | __cpu_backend_tag{}, | |
| 124 | __brick_first, | |
| 125 | std::move(__brick_last), | |
| 126 | __first2 + (__brick_first - __first1), | |
| 127 | std::move(__brick_init), | |
| 128 | std::move(__reduce), | |
| 129 | std::move(__transform)); | |
| 130 | }); | |
| 131 | }); | |
| 132 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 133 | __has_random_access_iterator_category<_ForwardIterator1>::value && | |
| 134 | __has_random_access_iterator_category<_ForwardIterator2>::value) { | |
| 135 | return std::__simd_transform_reduce( | |
| 136 | __last1 - __first1, std::move(__init), std::move(__reduce), [&](__iter_diff_t<_ForwardIterator1> __i) { | |
| 137 | return __transform(__first1[__i], __first2[__i]); | |
| 138 | }); | |
| 139 | } else { | |
| 140 | return std::transform_reduce( | |
| 141 | std::move(__first1), | |
| 142 | std::move(__last1), | |
| 143 | std::move(__first2), | |
| 144 | std::move(__init), | |
| 145 | std::move(__reduce), | |
| 146 | std::move(__transform)); | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation> | |
| 151 | _LIBCPP_HIDE_FROM_ABI _Tp __pstl_transform_reduce( | |
| 152 | __cpu_backend_tag, | |
| 153 | _ForwardIterator __first, | |
| 154 | _ForwardIterator __last, | |
| 155 | _Tp __init, | |
| 156 | _BinaryOperation __reduce, | |
| 157 | _UnaryOperation __transform) { | |
| 158 | if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && | |
| 159 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 160 | return std::__terminate_on_exception([&] { | |
| 161 | return __par_backend::__parallel_transform_reduce( | |
| 162 | std::move(__first), | |
| 163 | std::move(__last), | |
| 164 | [__transform](_ForwardIterator __iter) { return __transform(*__iter); }, | |
| 165 | std::move(__init), | |
| 166 | __reduce, | |
| 167 | [__transform, __reduce](auto __brick_first, auto __brick_last, _Tp __brick_init) { | |
| 168 | return std::__pstl_transform_reduce<__remove_parallel_policy_t<_ExecutionPolicy>>( | |
| 169 | __cpu_backend_tag{}, | |
| 170 | std::move(__brick_first), | |
| 171 | std::move(__brick_last), | |
| 172 | std::move(__brick_init), | |
| 173 | std::move(__reduce), | |
| 174 | std::move(__transform)); | |
| 175 | }); | |
| 176 | }); | |
| 177 | } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && | |
| 178 | __has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 179 | return std::__simd_transform_reduce( | |
| 180 | __last - __first, | |
| 181 | std::move(__init), | |
| 182 | std::move(__reduce), | |
| 183 | [=, &__transform](__iter_diff_t<_ForwardIterator> __i) { return __transform(__first[__i]); }); | |
| 184 | } else { | |
| 185 | return std::transform_reduce( | |
| 186 | std::move(__first), std::move(__last), std::move(__init), std::move(__reduce), std::move(__transform)); | |
| 187 | } | |
| 188 | } | |
| 189 | ||
| 190 | _LIBCPP_END_NAMESPACE_STD | |
| 191 | ||
| 192 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 193 | ||
| 194 | #endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_REDUCE_H |
lib/libcxx/include/__algorithm/pstl_copy.h created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_COPY_H | |
| 11 | ||
| 12 | #include <__algorithm/copy_n.h> | |
| 13 | #include <__algorithm/pstl_transform.h> | |
| 14 | #include <__config> | |
| 15 | #include <__functional/identity.h> | |
| 16 | #include <__iterator/iterator_traits.h> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_constant_evaluated.h> | |
| 19 | #include <__type_traits/is_execution_policy.h> | |
| 20 | #include <__type_traits/is_trivially_copyable.h> | |
| 21 | #include <__type_traits/remove_cvref.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | // TODO: Use the std::copy/move shenanigans to forward to std::memmove | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _ForwardIterator, | |
| 35 | class _ForwardOutIterator, | |
| 36 | enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> | |
| 37 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator | |
| 38 | copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) { | |
| 39 | return std::transform(__policy, __first, __last, __result, __identity()); | |
| 40 | } | |
| 41 | ||
| 42 | template <class _ExecutionPolicy, | |
| 43 | class _ForwardIterator, | |
| 44 | class _ForwardOutIterator, | |
| 45 | class _Size, | |
| 46 | enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> | |
| 47 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator | |
| 48 | copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) { | |
| 49 | if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) | |
| 50 | return std::copy(__policy, __first, __first + __n, __result); | |
| 51 | else | |
| 52 | return std::copy_n(__first, __n, __result); | |
| 53 | } | |
| 54 | ||
| 55 | _LIBCPP_END_NAMESPACE_STD | |
| 56 | ||
| 57 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 58 | ||
| 59 | #endif // _LIBCPP___ALGORITHM_PSTL_COPY_H |
lib/libcxx/include/__algorithm/pstl_count.h created+89| ... | ... | @@ -0,0 +1,89 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_COUNT_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_COUNT_H | |
| 11 | ||
| 12 | #include <__algorithm/count.h> | |
| 13 | #include <__algorithm/for_each.h> | |
| 14 | #include <__algorithm/pstl_backend.h> | |
| 15 | #include <__algorithm/pstl_for_each.h> | |
| 16 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 17 | #include <__atomic/atomic.h> | |
| 18 | #include <__config> | |
| 19 | #include <__functional/operations.h> | |
| 20 | #include <__iterator/iterator_traits.h> | |
| 21 | #include <__numeric/pstl_transform_reduce.h> | |
| 22 | #include <__type_traits/enable_if.h> | |
| 23 | #include <__type_traits/is_execution_policy.h> | |
| 24 | #include <__type_traits/remove_cvref.h> | |
| 25 | #include <__utility/move.h> | |
| 26 | #include <__utility/terminate_on_exception.h> | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 29 | # pragma GCC system_header | |
| 30 | #endif | |
| 31 | ||
| 32 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 33 | ||
| 34 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 35 | ||
| 36 | template <class> | |
| 37 | void __pstl_count_if(); // declaration needed for the frontend dispatch below | |
| 38 | ||
| 39 | template <class _ExecutionPolicy, | |
| 40 | class _ForwardIterator, | |
| 41 | class _Predicate, | |
| 42 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 43 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 44 | _LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator> | |
| 45 | count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 46 | using __diff_t = __iter_diff_t<_ForwardIterator>; | |
| 47 | return std::__pstl_frontend_dispatch( | |
| 48 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count_if), | |
| 49 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { | |
| 50 | return std::transform_reduce( | |
| 51 | __policy, | |
| 52 | std::move(__g_first), | |
| 53 | std::move(__g_last), | |
| 54 | __diff_t(), | |
| 55 | std::plus{}, | |
| 56 | [&](__iter_reference<_ForwardIterator> __element) -> bool { return __g_pred(__element); }); | |
| 57 | }, | |
| 58 | std::move(__first), | |
| 59 | std::move(__last), | |
| 60 | std::move(__pred)); | |
| 61 | } | |
| 62 | ||
| 63 | template <class> | |
| 64 | void __pstl_count(); // declaration needed for the frontend dispatch below | |
| 65 | ||
| 66 | template <class _ExecutionPolicy, | |
| 67 | class _ForwardIterator, | |
| 68 | class _Tp, | |
| 69 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 70 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 71 | _LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator> | |
| 72 | count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 73 | return std::__pstl_frontend_dispatch( | |
| 74 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_count), | |
| 75 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { | |
| 76 | return std::count_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __v) { | |
| 77 | return __v == __g_value; | |
| 78 | }); | |
| 79 | }, | |
| 80 | std::move(__first), | |
| 81 | std::move(__last), | |
| 82 | __value); | |
| 83 | } | |
| 84 | ||
| 85 | _LIBCPP_END_NAMESPACE_STD | |
| 86 | ||
| 87 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 88 | ||
| 89 | #endif // _LIBCPP___ALGORITHM_PSTL_COUNT_H |
lib/libcxx/include/__algorithm/pstl_fill.h created+84| ... | ... | @@ -0,0 +1,84 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_FILL_H | |
| 11 | ||
| 12 | #include <__algorithm/fill_n.h> | |
| 13 | #include <__algorithm/pstl_for_each.h> | |
| 14 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 15 | #include <__config> | |
| 16 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 17 | #include <__iterator/iterator_traits.h> | |
| 18 | #include <__type_traits/enable_if.h> | |
| 19 | #include <__type_traits/is_execution_policy.h> | |
| 20 | #include <__type_traits/remove_cvref.h> | |
| 21 | #include <__utility/move.h> | |
| 22 | #include <__utility/terminate_on_exception.h> | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 25 | # pragma GCC system_header | |
| 26 | #endif | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 29 | ||
| 30 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 31 | ||
| 32 | template <class> | |
| 33 | void __pstl_fill(); // declaration needed for the frontend dispatch below | |
| 34 | ||
| 35 | template <class _ExecutionPolicy, | |
| 36 | class _ForwardIterator, | |
| 37 | class _Tp, | |
| 38 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 39 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 40 | _LIBCPP_HIDE_FROM_ABI void | |
| 41 | fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 42 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 43 | std::__pstl_frontend_dispatch( | |
| 44 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill), | |
| 45 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { | |
| 46 | std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { | |
| 47 | __element = __g_value; | |
| 48 | }); | |
| 49 | }, | |
| 50 | std::move(__first), | |
| 51 | std::move(__last), | |
| 52 | __value); | |
| 53 | } | |
| 54 | ||
| 55 | template <class> | |
| 56 | void __pstl_fill_n(); // declaration needed for the frontend dispatch below | |
| 57 | ||
| 58 | template <class _ExecutionPolicy, | |
| 59 | class _ForwardIterator, | |
| 60 | class _SizeT, | |
| 61 | class _Tp, | |
| 62 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 63 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 64 | _LIBCPP_HIDE_FROM_ABI void | |
| 65 | fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) { | |
| 66 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 67 | std::__pstl_frontend_dispatch( | |
| 68 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n), | |
| 69 | [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) { | |
| 70 | if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) | |
| 71 | std::fill(__policy, __g_first, __g_first + __g_n, __g_value); | |
| 72 | else | |
| 73 | std::fill_n(__g_first, __g_n, __g_value); | |
| 74 | }, | |
| 75 | std::move(__first), | |
| 76 | __n, | |
| 77 | __value); | |
| 78 | } | |
| 79 | ||
| 80 | _LIBCPP_END_NAMESPACE_STD | |
| 81 | ||
| 82 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 83 | ||
| 84 | #endif // _LIBCPP___ALGORITHM_PSTL_FILL_H |
lib/libcxx/include/__algorithm/pstl_find.h created+95| ... | ... | @@ -0,0 +1,95 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_FIND_H | |
| 11 | ||
| 12 | #include <__algorithm/comp.h> | |
| 13 | #include <__algorithm/find.h> | |
| 14 | #include <__algorithm/pstl_backend.h> | |
| 15 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 16 | #include <__config> | |
| 17 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 18 | #include <__iterator/iterator_traits.h> | |
| 19 | #include <__type_traits/enable_if.h> | |
| 20 | #include <__type_traits/is_execution_policy.h> | |
| 21 | #include <__type_traits/remove_cvref.h> | |
| 22 | #include <__utility/move.h> | |
| 23 | #include <__utility/terminate_on_exception.h> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 30 | ||
| 31 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _ForwardIterator, | |
| 35 | class _Predicate, | |
| 36 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 37 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 38 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 39 | find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 40 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 41 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 42 | return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred)); | |
| 43 | } | |
| 44 | ||
| 45 | template <class> | |
| 46 | void __pstl_find_if_not(); | |
| 47 | ||
| 48 | template <class _ExecutionPolicy, | |
| 49 | class _ForwardIterator, | |
| 50 | class _Predicate, | |
| 51 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 52 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 53 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 54 | find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 55 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 56 | return std::__pstl_frontend_dispatch( | |
| 57 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not), | |
| 58 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { | |
| 59 | return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) { | |
| 60 | return !__g_pred(__value); | |
| 61 | }); | |
| 62 | }, | |
| 63 | std::move(__first), | |
| 64 | std::move(__last), | |
| 65 | std::move(__pred)); | |
| 66 | } | |
| 67 | ||
| 68 | template <class> | |
| 69 | void __pstl_find(); | |
| 70 | ||
| 71 | template <class _ExecutionPolicy, | |
| 72 | class _ForwardIterator, | |
| 73 | class _Tp, | |
| 74 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 75 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 76 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 77 | find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 78 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 79 | return std::__pstl_frontend_dispatch( | |
| 80 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find), | |
| 81 | [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { | |
| 82 | return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { | |
| 83 | return __element == __g_value; | |
| 84 | }); | |
| 85 | }, | |
| 86 | std::move(__first), | |
| 87 | std::move(__last), | |
| 88 | __value); | |
| 89 | } | |
| 90 | ||
| 91 | _LIBCPP_END_NAMESPACE_STD | |
| 92 | ||
| 93 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 94 | ||
| 95 | #endif // _LIBCPP___ALGORITHM_PSTL_FIND_H |
lib/libcxx/include/__algorithm/pstl_for_each.h created+76| ... | ... | @@ -0,0 +1,76 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H | |
| 11 | ||
| 12 | #include <__algorithm/for_each.h> | |
| 13 | #include <__algorithm/for_each_n.h> | |
| 14 | #include <__algorithm/pstl_backend.h> | |
| 15 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 16 | #include <__config> | |
| 17 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 18 | #include <__iterator/iterator_traits.h> | |
| 19 | #include <__type_traits/enable_if.h> | |
| 20 | #include <__type_traits/is_execution_policy.h> | |
| 21 | #include <__type_traits/remove_cvref.h> | |
| 22 | #include <__type_traits/void_t.h> | |
| 23 | #include <__utility/move.h> | |
| 24 | #include <__utility/terminate_on_exception.h> | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 27 | # pragma GCC system_header | |
| 28 | #endif | |
| 29 | ||
| 30 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 31 | ||
| 32 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 33 | ||
| 34 | template <class _ExecutionPolicy, | |
| 35 | class _ForwardIterator, | |
| 36 | class _Function, | |
| 37 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 38 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 39 | _LIBCPP_HIDE_FROM_ABI void | |
| 40 | for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) { | |
| 41 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 42 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 43 | std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func)); | |
| 44 | } | |
| 45 | ||
| 46 | template <class> | |
| 47 | void __pstl_for_each_n(); // declaration needed for the frontend dispatch below | |
| 48 | ||
| 49 | template <class _ExecutionPolicy, | |
| 50 | class _ForwardIterator, | |
| 51 | class _Size, | |
| 52 | class _Function, | |
| 53 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 54 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 55 | _LIBCPP_HIDE_FROM_ABI void | |
| 56 | for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) { | |
| 57 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 58 | return std::__pstl_frontend_dispatch( | |
| 59 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n), | |
| 60 | [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) { | |
| 61 | if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 62 | std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func)); | |
| 63 | } else { | |
| 64 | std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func)); | |
| 65 | } | |
| 66 | }, | |
| 67 | __first, | |
| 68 | __size, | |
| 69 | std::move(__func)); | |
| 70 | } | |
| 71 | ||
| 72 | _LIBCPP_END_NAMESPACE_STD | |
| 73 | ||
| 74 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 75 | ||
| 76 | #endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H |
lib/libcxx/include/__algorithm/pstl_frontend_dispatch.h created+45| ... | ... | @@ -0,0 +1,45 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/is_callable.h> | |
| 14 | #include <__utility/forward.h> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #if _LIBCPP_STD_VER >= 17 | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | # define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name) \ | |
| 25 | [](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{}, \ | |
| 26 | std::forward<decltype(__args)>(__args)...)) { \ | |
| 27 | return std::name<_RawPolicy>( \ | |
| 28 | typename __select_backend<_RawPolicy>::type{}, std::forward<decltype(__args)>(__args)...); \ | |
| 29 | } | |
| 30 | ||
| 31 | template <class _SpecializedImpl, class _GenericImpl, class... _Args> | |
| 32 | _LIBCPP_HIDE_FROM_ABI decltype(auto) | |
| 33 | __pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) { | |
| 34 | if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) { | |
| 35 | return __specialized_impl(std::forward<_Args>(__args)...); | |
| 36 | } else { | |
| 37 | return __generic_impl(std::forward<_Args>(__args)...); | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | _LIBCPP_END_NAMESPACE_STD | |
| 42 | ||
| 43 | #endif // _LIBCPP_STD_VER >= 17 | |
| 44 | ||
| 45 | #endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH |
lib/libcxx/include/__algorithm/pstl_generate.h created+82| ... | ... | @@ -0,0 +1,82 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_GENERATE_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_GENERATE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__algorithm/pstl_for_each.h> | |
| 14 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 15 | #include <__config> | |
| 16 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_execution_policy.h> | |
| 19 | #include <__type_traits/remove_cvref.h> | |
| 20 | #include <__utility/move.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | template <class> | |
| 31 | void __pstl_generate(); | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _ForwardIterator, | |
| 35 | class _Generator, | |
| 36 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 37 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 38 | _LIBCPP_HIDE_FROM_ABI void | |
| 39 | generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { | |
| 40 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 41 | std::__pstl_frontend_dispatch( | |
| 42 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate), | |
| 43 | [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Generator __g_gen) { | |
| 44 | std::for_each( | |
| 45 | __policy, std::move(__g_first), std::move(__g_last), [&](__iter_reference<_ForwardIterator> __element) { | |
| 46 | __element = __g_gen(); | |
| 47 | }); | |
| 48 | }, | |
| 49 | std::move(__first), | |
| 50 | std::move(__last), | |
| 51 | std::move(__gen)); | |
| 52 | } | |
| 53 | ||
| 54 | template <class> | |
| 55 | void __pstl_generate_n(); | |
| 56 | ||
| 57 | template <class _ExecutionPolicy, | |
| 58 | class _ForwardIterator, | |
| 59 | class _Size, | |
| 60 | class _Generator, | |
| 61 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 62 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 63 | _LIBCPP_HIDE_FROM_ABI void | |
| 64 | generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) { | |
| 65 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 66 | std::__pstl_frontend_dispatch( | |
| 67 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_generate_n), | |
| 68 | [&__policy](_ForwardIterator __g_first, _Size __g_n, _Generator __g_gen) { | |
| 69 | std::for_each_n(__policy, std::move(__g_first), __g_n, [&](__iter_reference<_ForwardIterator> __element) { | |
| 70 | __element = __g_gen(); | |
| 71 | }); | |
| 72 | }, | |
| 73 | std::move(__first), | |
| 74 | __n, | |
| 75 | std::move(__gen)); | |
| 76 | } | |
| 77 | ||
| 78 | _LIBCPP_END_NAMESPACE_STD | |
| 79 | ||
| 80 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 81 | ||
| 82 | #endif // _LIBCPP___ALGORITHM_PSTL_GENERATE_H |
lib/libcxx/include/__algorithm/pstl_is_partitioned.h created+58| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED | |
| 11 | ||
| 12 | #include <__algorithm/pstl_any_all_none_of.h> | |
| 13 | #include <__algorithm/pstl_backend.h> | |
| 14 | #include <__algorithm/pstl_find.h> | |
| 15 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 16 | #include <__config> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_execution_policy.h> | |
| 19 | #include <__type_traits/remove_cvref.h> | |
| 20 | #include <__utility/move.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | template <class> | |
| 31 | void __pstl_is_partitioned(); | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _ForwardIterator, | |
| 35 | class _Predicate, | |
| 36 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 37 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool | |
| 39 | is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 40 | return std::__pstl_frontend_dispatch( | |
| 41 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_is_partitioned), | |
| 42 | [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { | |
| 43 | __g_first = std::find_if_not(__policy, __g_first, __g_last, __g_pred); | |
| 44 | if (__g_first == __g_last) | |
| 45 | return true; | |
| 46 | ++__g_first; | |
| 47 | return std::none_of(__policy, __g_first, __g_last, __g_pred); | |
| 48 | }, | |
| 49 | std::move(__first), | |
| 50 | std::move(__last), | |
| 51 | std::move(__pred)); | |
| 52 | } | |
| 53 | ||
| 54 | _LIBCPP_END_NAMESPACE_STD | |
| 55 | ||
| 56 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 57 | ||
| 58 | #endif // _LIBCPP___ALGORITHM_PSTL_IS_PARITTIONED |
lib/libcxx/include/__algorithm/pstl_merge.h created+58| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_MERGE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__config> | |
| 14 | #include <__functional/operations.h> | |
| 15 | #include <__type_traits/enable_if.h> | |
| 16 | #include <__type_traits/is_execution_policy.h> | |
| 17 | #include <__type_traits/remove_cvref.h> | |
| 18 | #include <__utility/move.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | template <class _ExecutionPolicy, | |
| 29 | class _ForwardIterator1, | |
| 30 | class _ForwardIterator2, | |
| 31 | class _ForwardOutIterator, | |
| 32 | class _Comp = std::less<>, | |
| 33 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 34 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 35 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator | |
| 36 | merge(_ExecutionPolicy&&, | |
| 37 | _ForwardIterator1 __first1, | |
| 38 | _ForwardIterator1 __last1, | |
| 39 | _ForwardIterator2 __first2, | |
| 40 | _ForwardIterator2 __last2, | |
| 41 | _ForwardOutIterator __result, | |
| 42 | _Comp __comp = {}) { | |
| 43 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 44 | return std::__pstl_merge<_RawPolicy>( | |
| 45 | _Backend{}, | |
| 46 | std::move(__first1), | |
| 47 | std::move(__last1), | |
| 48 | std::move(__first2), | |
| 49 | std::move(__last2), | |
| 50 | std::move(__result), | |
| 51 | std::move(__comp)); | |
| 52 | } | |
| 53 | ||
| 54 | _LIBCPP_END_NAMESPACE_STD | |
| 55 | ||
| 56 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 57 | ||
| 58 | #endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H |
lib/libcxx/include/__algorithm/pstl_replace.h created+167| ... | ... | @@ -0,0 +1,167 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_REPLACE_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_REPLACE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__algorithm/pstl_for_each.h> | |
| 14 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 15 | #include <__algorithm/pstl_transform.h> | |
| 16 | #include <__config> | |
| 17 | #include <__iterator/iterator_traits.h> | |
| 18 | #include <__type_traits/enable_if.h> | |
| 19 | #include <__type_traits/remove_cvref.h> | |
| 20 | #include <__utility/move.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | template <class> | |
| 31 | void __pstl_replace_if(); | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _ForwardIterator, | |
| 35 | class _Pred, | |
| 36 | class _Tp, | |
| 37 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 38 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 39 | _LIBCPP_HIDE_FROM_ABI void | |
| 40 | replace_if(_ExecutionPolicy&& __policy, | |
| 41 | _ForwardIterator __first, | |
| 42 | _ForwardIterator __last, | |
| 43 | _Pred __pred, | |
| 44 | const _Tp& __new_value) { | |
| 45 | std::__pstl_frontend_dispatch( | |
| 46 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_if), | |
| 47 | [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred, const _Tp& __g_new_value) { | |
| 48 | std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { | |
| 49 | if (__g_pred(__element)) | |
| 50 | __element = __g_new_value; | |
| 51 | }); | |
| 52 | }, | |
| 53 | std::move(__first), | |
| 54 | std::move(__last), | |
| 55 | std::move(__pred), | |
| 56 | __new_value); | |
| 57 | } | |
| 58 | ||
| 59 | template <class> | |
| 60 | void __pstl_replace(); | |
| 61 | ||
| 62 | template <class _ExecutionPolicy, | |
| 63 | class _ForwardIterator, | |
| 64 | class _Tp, | |
| 65 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 66 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 67 | _LIBCPP_HIDE_FROM_ABI void | |
| 68 | replace(_ExecutionPolicy&& __policy, | |
| 69 | _ForwardIterator __first, | |
| 70 | _ForwardIterator __last, | |
| 71 | const _Tp& __old_value, | |
| 72 | const _Tp& __new_value) { | |
| 73 | std::__pstl_frontend_dispatch( | |
| 74 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace), | |
| 75 | [&__policy]( | |
| 76 | _ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_old_value, const _Tp& __g_new_value) { | |
| 77 | std::replace_if( | |
| 78 | __policy, | |
| 79 | std::move(__g_first), | |
| 80 | std::move(__g_last), | |
| 81 | [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, | |
| 82 | __g_new_value); | |
| 83 | }, | |
| 84 | std::move(__first), | |
| 85 | std::move(__last), | |
| 86 | __old_value, | |
| 87 | __new_value); | |
| 88 | } | |
| 89 | ||
| 90 | template <class> | |
| 91 | void __pstl_replace_copy_if(); | |
| 92 | ||
| 93 | template <class _ExecutionPolicy, | |
| 94 | class _ForwardIterator, | |
| 95 | class _ForwardOutIterator, | |
| 96 | class _Pred, | |
| 97 | class _Tp, | |
| 98 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 99 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 100 | _LIBCPP_HIDE_FROM_ABI void replace_copy_if( | |
| 101 | _ExecutionPolicy&& __policy, | |
| 102 | _ForwardIterator __first, | |
| 103 | _ForwardIterator __last, | |
| 104 | _ForwardOutIterator __result, | |
| 105 | _Pred __pred, | |
| 106 | const _Tp& __new_value) { | |
| 107 | std::__pstl_frontend_dispatch( | |
| 108 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy_if), | |
| 109 | [&__policy](_ForwardIterator __g_first, | |
| 110 | _ForwardIterator __g_last, | |
| 111 | _ForwardOutIterator __g_result, | |
| 112 | _Pred __g_pred, | |
| 113 | const _Tp& __g_new_value) { | |
| 114 | std::transform(__policy, __g_first, __g_last, __g_result, [&](__iter_reference<_ForwardIterator> __element) { | |
| 115 | return __g_pred(__element) ? __g_new_value : __element; | |
| 116 | }); | |
| 117 | }, | |
| 118 | std::move(__first), | |
| 119 | std::move(__last), | |
| 120 | std::move(__result), | |
| 121 | std::move(__pred), | |
| 122 | __new_value); | |
| 123 | } | |
| 124 | ||
| 125 | template <class> | |
| 126 | void __pstl_replace_copy(); | |
| 127 | ||
| 128 | template <class _ExecutionPolicy, | |
| 129 | class _ForwardIterator, | |
| 130 | class _ForwardOutIterator, | |
| 131 | class _Tp, | |
| 132 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 133 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 134 | _LIBCPP_HIDE_FROM_ABI void replace_copy( | |
| 135 | _ExecutionPolicy&& __policy, | |
| 136 | _ForwardIterator __first, | |
| 137 | _ForwardIterator __last, | |
| 138 | _ForwardOutIterator __result, | |
| 139 | const _Tp& __old_value, | |
| 140 | const _Tp& __new_value) { | |
| 141 | std::__pstl_frontend_dispatch( | |
| 142 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_replace_copy), | |
| 143 | [&__policy](_ForwardIterator __g_first, | |
| 144 | _ForwardIterator __g_last, | |
| 145 | _ForwardOutIterator __g_result, | |
| 146 | const _Tp& __g_old_value, | |
| 147 | const _Tp& __g_new_value) { | |
| 148 | return std::replace_copy_if( | |
| 149 | __policy, | |
| 150 | std::move(__g_first), | |
| 151 | std::move(__g_last), | |
| 152 | std::move(__g_result), | |
| 153 | [&](__iter_reference<_ForwardIterator> __element) { return __element == __g_old_value; }, | |
| 154 | __g_new_value); | |
| 155 | }, | |
| 156 | std::move(__first), | |
| 157 | std::move(__last), | |
| 158 | std::move(__result), | |
| 159 | __old_value, | |
| 160 | __new_value); | |
| 161 | } | |
| 162 | ||
| 163 | _LIBCPP_END_NAMESPACE_STD | |
| 164 | ||
| 165 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 166 | ||
| 167 | #endif // _LIBCPP___ALGORITHM_PSTL_REPLACE_H |
lib/libcxx/include/__algorithm/pstl_sort.h created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_SORT_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_SORT_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 14 | #include <__algorithm/pstl_stable_sort.h> | |
| 15 | #include <__config> | |
| 16 | #include <__functional/operations.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <__utility/forward.h> | |
| 20 | #include <__utility/move.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | template <class> | |
| 31 | void __pstl_sort(); | |
| 32 | ||
| 33 | template <class _ExecutionPolicy, | |
| 34 | class _RandomAccessIterator, | |
| 35 | class _Comp, | |
| 36 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 37 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 38 | _LIBCPP_HIDE_FROM_ABI void | |
| 39 | sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { | |
| 40 | std::__pstl_frontend_dispatch( | |
| 41 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_sort), | |
| 42 | [&__policy](_RandomAccessIterator __g_first, _RandomAccessIterator __g_last, _Comp __g_comp) { | |
| 43 | std::stable_sort(__policy, std::move(__g_first), std::move(__g_last), std::move(__g_comp)); | |
| 44 | }, | |
| 45 | std::move(__first), | |
| 46 | std::move(__last), | |
| 47 | std::move(__comp)); | |
| 48 | } | |
| 49 | ||
| 50 | template <class _ExecutionPolicy, | |
| 51 | class _RandomAccessIterator, | |
| 52 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 53 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 54 | _LIBCPP_HIDE_FROM_ABI void | |
| 55 | sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) { | |
| 56 | std::sort(std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{}); | |
| 57 | } | |
| 58 | ||
| 59 | _LIBCPP_END_NAMESPACE_STD | |
| 60 | ||
| 61 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 62 | ||
| 63 | #endif // _LIBCPP___ALGORITHM_PSTL_SORT_H |
lib/libcxx/include/__algorithm/pstl_stable_sort.h created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__config> | |
| 14 | #include <__functional/operations.h> | |
| 15 | #include <__type_traits/enable_if.h> | |
| 16 | #include <__type_traits/is_execution_policy.h> | |
| 17 | #include <__type_traits/remove_cvref.h> | |
| 18 | #include <__utility/move.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | template <class _ExecutionPolicy, | |
| 29 | class _RandomAccessIterator, | |
| 30 | class _Comp = less<>, | |
| 31 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 32 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 33 | _LIBCPP_HIDE_FROM_ABI void | |
| 34 | stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp = {}) { | |
| 35 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 36 | std::__pstl_stable_sort<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__comp)); | |
| 37 | } | |
| 38 | ||
| 39 | _LIBCPP_END_NAMESPACE_STD | |
| 40 | ||
| 41 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 42 | ||
| 43 | #endif // _LIBCPP___ALGORITHM_PSTL_STABLE_SORT_H |
lib/libcxx/include/__algorithm/pstl_transform.h created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H | |
| 10 | #define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__config> | |
| 14 | #include <__iterator/cpp17_iterator_concepts.h> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/enable_if.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <__utility/move.h> | |
| 20 | #include <__utility/terminate_on_exception.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | template <class _ExecutionPolicy, | |
| 31 | class _ForwardIterator, | |
| 32 | class _ForwardOutIterator, | |
| 33 | class _UnaryOperation, | |
| 34 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 35 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 36 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( | |
| 37 | _ExecutionPolicy&&, | |
| 38 | _ForwardIterator __first, | |
| 39 | _ForwardIterator __last, | |
| 40 | _ForwardOutIterator __result, | |
| 41 | _UnaryOperation __op) { | |
| 42 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator); | |
| 43 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator); | |
| 44 | _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first))); | |
| 45 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 46 | return std::__pstl_transform<_RawPolicy>( | |
| 47 | _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op)); | |
| 48 | } | |
| 49 | ||
| 50 | template <class _ExecutionPolicy, | |
| 51 | class _ForwardIterator1, | |
| 52 | class _ForwardIterator2, | |
| 53 | class _ForwardOutIterator, | |
| 54 | class _BinaryOperation, | |
| 55 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 56 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 57 | _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( | |
| 58 | _ExecutionPolicy&&, | |
| 59 | _ForwardIterator1 __first1, | |
| 60 | _ForwardIterator1 __last1, | |
| 61 | _ForwardIterator2 __first2, | |
| 62 | _ForwardOutIterator __result, | |
| 63 | _BinaryOperation __op) { | |
| 64 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1); | |
| 65 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2); | |
| 66 | _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator); | |
| 67 | _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(__op(*__first1, *__first2))); | |
| 68 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 69 | return std::__pstl_transform<_RawPolicy>( | |
| 70 | _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op)); | |
| 71 | } | |
| 72 | ||
| 73 | _LIBCPP_END_NAMESPACE_STD | |
| 74 | ||
| 75 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 76 | ||
| 77 | #endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H |
lib/libcxx/include/__algorithm/push_heap.h+8-3| ... | ... | @@ -14,13 +14,17 @@ |
| 14 | 14 | #include <__algorithm/iterator_operations.h> |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__iterator/iterator_traits.h> |
| 17 | #include <__type_traits/is_copy_assignable.h> | |
| 18 | #include <__type_traits/is_copy_constructible.h> | |
| 17 | 19 | #include <__utility/move.h> |
| 18 | #include <type_traits> | |
| 19 | 20 | |
| 20 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 22 | # pragma GCC system_header |
| 22 | 23 | #endif |
| 23 | 24 | |
| 25 | _LIBCPP_PUSH_MACROS | |
| 26 | #include <__undef_macros> | |
| 27 | ||
| 24 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 29 | |
| 26 | 30 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| ... | ... | @@ -68,10 +72,11 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com |
| 68 | 72 | template <class _RandomAccessIterator> |
| 69 | 73 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 70 | 74 | void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 71 | std::push_heap(std::move(__first), std::move(__last), | |
| 72 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 75 | std::push_heap(std::move(__first), std::move(__last), __less<>()); | |
| 73 | 76 | } |
| 74 | 77 | |
| 75 | 78 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 79 | |
| 80 | _LIBCPP_POP_MACROS | |
| 81 | ||
| 77 | 82 | #endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H |
lib/libcxx/include/__algorithm/ranges_adjacent_find.h+14-14| ... | ... | @@ -24,17 +24,16 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | namespace __adjacent_find { |
| 33 | 33 | struct __fn { |
| 34 | ||
| 35 | 34 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 37 | _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 36 | __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 38 | 37 | if (__first == __last) |
| 39 | 38 | return __first; |
| 40 | 39 | |
| ... | ... | @@ -47,32 +46,33 @@ struct __fn { |
| 47 | 46 | return __i; |
| 48 | 47 | } |
| 49 | 48 | |
| 50 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 51 | class _Proj = identity, | |
| 49 | template <forward_iterator _Iter, | |
| 50 | sentinel_for<_Iter> _Sent, | |
| 51 | class _Proj = identity, | |
| 52 | 52 | indirect_binary_predicate<projected<_Iter, _Proj>, projected<_Iter, _Proj>> _Pred = ranges::equal_to> |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 54 | _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 54 | operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 55 | 55 | return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | template <forward_range _Range, |
| 59 | 59 | class _Proj = identity, |
| 60 | indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, | |
| 61 | projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to> | |
| 62 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 63 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 60 | indirect_binary_predicate<projected<iterator_t<_Range>, _Proj>, projected<iterator_t<_Range>, _Proj>> | |
| 61 | _Pred = ranges::equal_to> | |
| 62 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 63 | operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 64 | 64 | return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 65 | 65 | } |
| 66 | 66 | }; |
| 67 | 67 | } // namespace __adjacent_find |
| 68 | 68 | |
| 69 | 69 | inline namespace __cpo { |
| 70 | inline constexpr auto adjacent_find = __adjacent_find::__fn{}; | |
| 70 | inline constexpr auto adjacent_find = __adjacent_find::__fn{}; | |
| 71 | 71 | } // namespace __cpo |
| 72 | 72 | } // namespace ranges |
| 73 | 73 | |
| 74 | 74 | _LIBCPP_END_NAMESPACE_STD |
| 75 | 75 | |
| 76 | #endif // _LIBCPP_STD_VER > 17 | |
| 76 | #endif // _LIBCPP_STD_VER >= 20 | |
| 77 | 77 | |
| 78 | 78 | #endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H |
lib/libcxx/include/__algorithm/ranges_all_of.h+13-12| ... | ... | @@ -22,17 +22,15 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | namespace ranges { |
| 30 | 30 | namespace __all_of { |
| 31 | 31 | struct __fn { |
| 32 | ||
| 33 | 32 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 35 | bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 36 | 34 | for (; __first != __last; ++__first) { |
| 37 | 35 | if (!std::invoke(__pred, std::invoke(__proj, *__first))) |
| 38 | 36 | return false; |
| ... | ... | @@ -40,29 +38,32 @@ struct __fn { |
| 40 | 38 | return true; |
| 41 | 39 | } |
| 42 | 40 | |
| 43 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 41 | template <input_iterator _Iter, | |
| 42 | sentinel_for<_Iter> _Sent, | |
| 43 | class _Proj = identity, | |
| 44 | 44 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 46 | bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 46 | operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 47 | 47 | return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | template <input_range _Range, class _Proj = identity, | |
| 50 | template <input_range _Range, | |
| 51 | class _Proj = identity, | |
| 51 | 52 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 53 | bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 54 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 54 | 55 | return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 55 | 56 | } |
| 56 | 57 | }; |
| 57 | 58 | } // namespace __all_of |
| 58 | 59 | |
| 59 | 60 | inline namespace __cpo { |
| 60 | inline constexpr auto all_of = __all_of::__fn{}; | |
| 61 | inline constexpr auto all_of = __all_of::__fn{}; | |
| 61 | 62 | } // namespace __cpo |
| 62 | 63 | } // namespace ranges |
| 63 | 64 | |
| 64 | 65 | _LIBCPP_END_NAMESPACE_STD |
| 65 | 66 | |
| 66 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 67 | 68 | |
| 68 | 69 | #endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H |
lib/libcxx/include/__algorithm/ranges_any_of.h+13-12| ... | ... | @@ -22,17 +22,15 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | namespace ranges { |
| 30 | 30 | namespace __any_of { |
| 31 | 31 | struct __fn { |
| 32 | ||
| 33 | 32 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 35 | bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 36 | 34 | for (; __first != __last; ++__first) { |
| 37 | 35 | if (std::invoke(__pred, std::invoke(__proj, *__first))) |
| 38 | 36 | return true; |
| ... | ... | @@ -40,29 +38,32 @@ struct __fn { |
| 40 | 38 | return false; |
| 41 | 39 | } |
| 42 | 40 | |
| 43 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 41 | template <input_iterator _Iter, | |
| 42 | sentinel_for<_Iter> _Sent, | |
| 43 | class _Proj = identity, | |
| 44 | 44 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 46 | bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 46 | operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 47 | 47 | return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | template <input_range _Range, class _Proj = identity, | |
| 50 | template <input_range _Range, | |
| 51 | class _Proj = identity, | |
| 51 | 52 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 53 | bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 54 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 54 | 55 | return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 55 | 56 | } |
| 56 | 57 | }; |
| 57 | 58 | } // namespace __any_of |
| 58 | 59 | |
| 59 | 60 | inline namespace __cpo { |
| 60 | inline constexpr auto any_of = __any_of::__fn{}; | |
| 61 | inline constexpr auto any_of = __any_of::__fn{}; | |
| 61 | 62 | } // namespace __cpo |
| 62 | 63 | } // namespace ranges |
| 63 | 64 | |
| 64 | 65 | _LIBCPP_END_NAMESPACE_STD |
| 65 | 66 | |
| 66 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 67 | 68 | |
| 68 | 69 | #endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H |
lib/libcxx/include/__algorithm/ranges_binary_search.h+17-12| ... | ... | @@ -24,40 +24,45 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | namespace __binary_search { |
| 33 | 33 | struct __fn { |
| 34 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity, | |
| 34 | template <forward_iterator _Iter, | |
| 35 | sentinel_for<_Iter> _Sent, | |
| 36 | class _Type, | |
| 37 | class _Proj = identity, | |
| 35 | 38 | indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less> |
| 36 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 37 | bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 38 | auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 39 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 40 | operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 41 | auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 39 | 42 | return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); |
| 40 | 43 | } |
| 41 | 44 | |
| 42 | template <forward_range _Range, class _Type, class _Proj = identity, | |
| 45 | template <forward_range _Range, | |
| 46 | class _Type, | |
| 47 | class _Proj = identity, | |
| 43 | 48 | indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 44 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 45 | bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 49 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 50 | operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 46 | 51 | auto __first = ranges::begin(__r); |
| 47 | auto __last = ranges::end(__r); | |
| 48 | auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 52 | auto __last = ranges::end(__r); | |
| 53 | auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 49 | 54 | return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); |
| 50 | 55 | } |
| 51 | 56 | }; |
| 52 | 57 | } // namespace __binary_search |
| 53 | 58 | |
| 54 | 59 | inline namespace __cpo { |
| 55 | inline constexpr auto binary_search = __binary_search::__fn{}; | |
| 60 | inline constexpr auto binary_search = __binary_search::__fn{}; | |
| 56 | 61 | } // namespace __cpo |
| 57 | 62 | } // namespace ranges |
| 58 | 63 | |
| 59 | 64 | _LIBCPP_END_NAMESPACE_STD |
| 60 | 65 | |
| 61 | #endif // _LIBCPP_STD_VER > 17 | |
| 66 | #endif // _LIBCPP_STD_VER >= 20 | |
| 62 | 67 | |
| 63 | 68 | #endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H |
lib/libcxx/include/__algorithm/ranges_clamp.h+8-14| ... | ... | @@ -22,25 +22,20 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | namespace ranges { |
| 30 | 30 | namespace __clamp { |
| 31 | 31 | struct __fn { |
| 32 | ||
| 33 | 32 | template <class _Type, |
| 34 | class _Proj = identity, | |
| 33 | class _Proj = identity, | |
| 35 | 34 | indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> |
| 36 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 37 | const _Type& operator()(const _Type& __value, | |
| 38 | const _Type& __low, | |
| 39 | const _Type& __high, | |
| 40 | _Comp __comp = {}, | |
| 41 | _Proj __proj = {}) const { | |
| 42 | _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), | |
| 43 | "Bad bounds passed to std::ranges::clamp"); | |
| 35 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( | |
| 36 | const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 37 | _LIBCPP_ASSERT_UNCATEGORIZED(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), | |
| 38 | "Bad bounds passed to std::ranges::clamp"); | |
| 44 | 39 | |
| 45 | 40 | if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low))) |
| 46 | 41 | return __low; |
| ... | ... | @@ -49,17 +44,16 @@ struct __fn { |
| 49 | 44 | else |
| 50 | 45 | return __value; |
| 51 | 46 | } |
| 52 | ||
| 53 | 47 | }; |
| 54 | 48 | } // namespace __clamp |
| 55 | 49 | |
| 56 | 50 | inline namespace __cpo { |
| 57 | inline constexpr auto clamp = __clamp::__fn{}; | |
| 51 | inline constexpr auto clamp = __clamp::__fn{}; | |
| 58 | 52 | } // namespace __cpo |
| 59 | 53 | } // namespace ranges |
| 60 | 54 | |
| 61 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 62 | 56 | |
| 63 | #endif // _LIBCPP_STD_VER > 17 | |
| 57 | #endif // _LIBCPP_STD_VER >= 20 | |
| 64 | 58 | |
| 65 | 59 | #endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H |
lib/libcxx/include/__algorithm/ranges_copy.h+7-8| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -36,19 +36,18 @@ using copy_result = in_out_result<_InIter, _OutIter>; |
| 36 | 36 | |
| 37 | 37 | namespace __copy { |
| 38 | 38 | struct __fn { |
| 39 | ||
| 40 | 39 | template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter> |
| 41 | 40 | requires indirectly_copyable<_InIter, _OutIter> |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 43 | copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter> | |
| 42 | operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 44 | 43 | auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); |
| 45 | 44 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | 47 | template <input_range _Range, weakly_incrementable _OutIter> |
| 49 | 48 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __r, _OutIter __result) const { | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 50 | operator()(_Range&& __r, _OutIter __result) const { | |
| 52 | 51 | auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); |
| 53 | 52 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 54 | 53 | } |
| ... | ... | @@ -56,12 +55,12 @@ struct __fn { |
| 56 | 55 | } // namespace __copy |
| 57 | 56 | |
| 58 | 57 | inline namespace __cpo { |
| 59 | inline constexpr auto copy = __copy::__fn{}; | |
| 58 | inline constexpr auto copy = __copy::__fn{}; | |
| 60 | 59 | } // namespace __cpo |
| 61 | 60 | } // namespace ranges |
| 62 | 61 | |
| 63 | 62 | _LIBCPP_END_NAMESPACE_STD |
| 64 | 63 | |
| 65 | #endif // _LIBCPP_STD_VER > 17 | |
| 64 | #endif // _LIBCPP_STD_VER >= 20 | |
| 66 | 65 | |
| 67 | 66 | #endif // _LIBCPP___ALGORITHM_RANGES_COPY_H |
lib/libcxx/include/__algorithm/ranges_copy_backward.h+8-9| ... | ... | @@ -23,30 +23,29 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | namespace ranges { |
| 31 | 31 | |
| 32 | template<class _Ip, class _Op> | |
| 32 | template <class _Ip, class _Op> | |
| 33 | 33 | using copy_backward_result = in_out_result<_Ip, _Op>; |
| 34 | 34 | |
| 35 | 35 | namespace __copy_backward { |
| 36 | 36 | struct __fn { |
| 37 | ||
| 38 | 37 | template <bidirectional_iterator _InIter1, sentinel_for<_InIter1> _Sent1, bidirectional_iterator _InIter2> |
| 39 | 38 | requires indirectly_copyable<_InIter1, _InIter2> |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 41 | copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2> | |
| 40 | operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { | |
| 42 | 41 | auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); |
| 43 | 42 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 44 | 43 | } |
| 45 | 44 | |
| 46 | 45 | template <bidirectional_range _Range, bidirectional_iterator _Iter> |
| 47 | 46 | requires indirectly_copyable<iterator_t<_Range>, _Iter> |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 49 | copy_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __r, _Iter __result) const { | |
| 47 | _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter> | |
| 48 | operator()(_Range&& __r, _Iter __result) const { | |
| 50 | 49 | auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); |
| 51 | 50 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 52 | 51 | } |
| ... | ... | @@ -54,12 +53,12 @@ struct __fn { |
| 54 | 53 | } // namespace __copy_backward |
| 55 | 54 | |
| 56 | 55 | inline namespace __cpo { |
| 57 | inline constexpr auto copy_backward = __copy_backward::__fn{}; | |
| 56 | inline constexpr auto copy_backward = __copy_backward::__fn{}; | |
| 58 | 57 | } // namespace __cpo |
| 59 | 58 | } // namespace ranges |
| 60 | 59 | |
| 61 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 62 | 61 | |
| 63 | #endif // _LIBCPP_STD_VER > 17 | |
| 62 | #endif // _LIBCPP_STD_VER >= 20 | |
| 64 | 63 | |
| 65 | 64 | #endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H |
lib/libcxx/include/__algorithm/ranges_copy_if.h+14-13| ... | ... | @@ -24,21 +24,19 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | |
| 33 | template<class _Ip, class _Op> | |
| 33 | template <class _Ip, class _Op> | |
| 34 | 34 | using copy_if_result = in_out_result<_Ip, _Op>; |
| 35 | 35 | |
| 36 | 36 | namespace __copy_if { |
| 37 | 37 | struct __fn { |
| 38 | ||
| 39 | 38 | template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred> |
| 40 | _LIBCPP_HIDE_FROM_ABI static constexpr | |
| 41 | copy_if_result <_InIter, _OutIter> | |
| 39 | _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter> | |
| 42 | 40 | __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { |
| 43 | 41 | for (; __first != __last; ++__first) { |
| 44 | 42 | if (std::invoke(__pred, std::invoke(__proj, *__first))) { |
| ... | ... | @@ -49,20 +47,23 @@ struct __fn { |
| 49 | 47 | return {std::move(__first), std::move(__result)}; |
| 50 | 48 | } |
| 51 | 49 | |
| 52 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Proj = identity, | |
| 50 | template <input_iterator _Iter, | |
| 51 | sentinel_for<_Iter> _Sent, | |
| 52 | weakly_incrementable _OutIter, | |
| 53 | class _Proj = identity, | |
| 53 | 54 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 54 | 55 | requires indirectly_copyable<_Iter, _OutIter> |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 56 | copy_if_result<_Iter, _OutIter> | |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter> | |
| 57 | 57 | operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { |
| 58 | 58 | return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | template <input_range _Range, weakly_incrementable _OutIter, class _Proj = identity, | |
| 61 | template <input_range _Range, | |
| 62 | weakly_incrementable _OutIter, | |
| 63 | class _Proj = identity, | |
| 62 | 64 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 63 | 65 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 65 | copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 66 | _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 66 | 67 | operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { |
| 67 | 68 | return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj); |
| 68 | 69 | } |
| ... | ... | @@ -70,12 +71,12 @@ struct __fn { |
| 70 | 71 | } // namespace __copy_if |
| 71 | 72 | |
| 72 | 73 | inline namespace __cpo { |
| 73 | inline constexpr auto copy_if = __copy_if::__fn{}; | |
| 74 | inline constexpr auto copy_if = __copy_if::__fn{}; | |
| 74 | 75 | } // namespace __cpo |
| 75 | 76 | } // namespace ranges |
| 76 | 77 | |
| 77 | 78 | _LIBCPP_END_NAMESPACE_STD |
| 78 | 79 | |
| 79 | #endif // _LIBCPP_STD_VER > 17 | |
| 80 | #endif // _LIBCPP_STD_VER >= 20 | |
| 80 | 81 | |
| 81 | 82 | #endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H |
lib/libcxx/include/__algorithm/ranges_copy_n.h+9-10| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | |
| ... | ... | @@ -36,10 +36,9 @@ using copy_n_result = in_out_result<_Ip, _Op>; |
| 36 | 36 | |
| 37 | 37 | namespace __copy_n { |
| 38 | 38 | struct __fn { |
| 39 | ||
| 40 | 39 | template <class _InIter, class _DiffType, class _OutIter> |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 42 | copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> | |
| 41 | __go(_InIter __first, _DiffType __n, _OutIter __result) { | |
| 43 | 42 | while (__n != 0) { |
| 44 | 43 | *__result = *__first; |
| 45 | 44 | ++__first; |
| ... | ... | @@ -50,27 +49,27 @@ struct __fn { |
| 50 | 49 | } |
| 51 | 50 | |
| 52 | 51 | template <random_access_iterator _InIter, class _DiffType, random_access_iterator _OutIter> |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 54 | copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> | |
| 53 | __go(_InIter __first, _DiffType __n, _OutIter __result) { | |
| 55 | 54 | auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result); |
| 56 | 55 | return {__ret.first, __ret.second}; |
| 57 | 56 | } |
| 58 | 57 | |
| 59 | 58 | template <input_iterator _Ip, weakly_incrementable _Op> |
| 60 | 59 | requires indirectly_copyable<_Ip, _Op> |
| 61 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 62 | copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { | |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op> | |
| 61 | operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { | |
| 63 | 62 | return __go(std::move(__first), __n, std::move(__result)); |
| 64 | 63 | } |
| 65 | 64 | }; |
| 66 | 65 | } // namespace __copy_n |
| 67 | 66 | |
| 68 | 67 | inline namespace __cpo { |
| 69 | inline constexpr auto copy_n = __copy_n::__fn{}; | |
| 68 | inline constexpr auto copy_n = __copy_n::__fn{}; | |
| 70 | 69 | } // namespace __cpo |
| 71 | 70 | } // namespace ranges |
| 72 | 71 | |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 72 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 73 | |
| 75 | 74 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 75 |
lib/libcxx/include/__algorithm/ranges_count.h+7-7| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -34,16 +34,16 @@ namespace __count { |
| 34 | 34 | struct __fn { |
| 35 | 35 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity> |
| 36 | 36 | requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*> |
| 37 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 38 | iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { | |
| 37 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> | |
| 38 | operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { | |
| 39 | 39 | auto __pred = [&](auto&& __e) { return __e == __value; }; |
| 40 | 40 | return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | 43 | template <input_range _Range, class _Type, class _Proj = identity> |
| 44 | 44 | requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*> |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 46 | range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { | |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> | |
| 46 | operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { | |
| 47 | 47 | auto __pred = [&](auto&& __e) { return __e == __value; }; |
| 48 | 48 | return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); |
| 49 | 49 | } |
| ... | ... | @@ -51,12 +51,12 @@ struct __fn { |
| 51 | 51 | } // namespace __count |
| 52 | 52 | |
| 53 | 53 | inline namespace __cpo { |
| 54 | inline constexpr auto count = __count::__fn{}; | |
| 54 | inline constexpr auto count = __count::__fn{}; | |
| 55 | 55 | } // namespace __cpo |
| 56 | 56 | } // namespace ranges |
| 57 | 57 | |
| 58 | 58 | _LIBCPP_END_NAMESPACE_STD |
| 59 | 59 | |
| 60 | #endif // _LIBCPP_STD_VER > 17 | |
| 60 | #endif // _LIBCPP_STD_VER >= 20 | |
| 61 | 61 | |
| 62 | 62 | #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H |
lib/libcxx/include/__algorithm/ranges_count_if.h+14-12| ... | ... | @@ -25,15 +25,14 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 35 | iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, | |
| 36 | _Pred& __pred, _Proj& __proj) { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> | |
| 35 | __count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 37 | 36 | iter_difference_t<_Iter> __counter(0); |
| 38 | 37 | for (; __first != __last; ++__first) { |
| 39 | 38 | if (std::invoke(__pred, std::invoke(__proj, *__first))) |
| ... | ... | @@ -44,29 +43,32 @@ iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, |
| 44 | 43 | |
| 45 | 44 | namespace __count_if { |
| 46 | 45 | struct __fn { |
| 47 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 46 | template <input_iterator _Iter, | |
| 47 | sentinel_for<_Iter> _Sent, | |
| 48 | class _Proj = identity, | |
| 48 | 49 | indirect_unary_predicate<projected<_Iter, _Proj>> _Predicate> |
| 49 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 50 | iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { | |
| 50 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> | |
| 51 | operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { | |
| 51 | 52 | return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 52 | 53 | } |
| 53 | 54 | |
| 54 | template <input_range _Range, class _Proj = identity, | |
| 55 | template <input_range _Range, | |
| 56 | class _Proj = identity, | |
| 55 | 57 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Predicate> |
| 56 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 57 | range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { | |
| 58 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> | |
| 59 | operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { | |
| 58 | 60 | return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); |
| 59 | 61 | } |
| 60 | 62 | }; |
| 61 | 63 | } // namespace __count_if |
| 62 | 64 | |
| 63 | 65 | inline namespace __cpo { |
| 64 | inline constexpr auto count_if = __count_if::__fn{}; | |
| 66 | inline constexpr auto count_if = __count_if::__fn{}; | |
| 65 | 67 | } // namespace __cpo |
| 66 | 68 | } // namespace ranges |
| 67 | 69 | |
| 68 | 70 | _LIBCPP_END_NAMESPACE_STD |
| 69 | 71 | |
| 70 | #endif // _LIBCPP_STD_VER > 17 | |
| 72 | #endif // _LIBCPP_STD_VER >= 20 | |
| 71 | 73 | |
| 72 | 74 | #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H |
lib/libcxx/include/__algorithm/ranges_equal.h+41-52| ... | ... | @@ -9,6 +9,8 @@ |
| 9 | 9 | #ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H |
| 10 | 10 | #define _LIBCPP___ALGORITHM_RANGES_EQUAL_H |
| 11 | 11 | |
| 12 | #include <__algorithm/equal.h> | |
| 13 | #include <__algorithm/unwrap_range.h> | |
| 12 | 14 | #include <__config> |
| 13 | 15 | #include <__functional/identity.h> |
| 14 | 16 | #include <__functional/invoke.h> |
| ... | ... | @@ -24,92 +26,79 @@ |
| 24 | 26 | # pragma GCC system_header |
| 25 | 27 | #endif |
| 26 | 28 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 30 | |
| 29 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 32 | |
| 31 | 33 | namespace ranges { |
| 32 | 34 | namespace __equal { |
| 33 | 35 | struct __fn { |
| 34 | private: | |
| 35 | template <class _Iter1, class _Sent1, | |
| 36 | class _Iter2, class _Sent2, | |
| 37 | class _Pred, | |
| 38 | class _Proj1, | |
| 39 | class _Proj2> | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 41 | bool __equal_impl(_Iter1 __first1, _Sent1 __last1, | |
| 42 | _Iter2 __first2, _Sent2 __last2, | |
| 43 | _Pred& __pred, | |
| 44 | _Proj1& __proj1, | |
| 45 | _Proj2& __proj2) { | |
| 46 | while (__first1 != __last1 && __first2 != __last2) { | |
| 47 | if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) | |
| 48 | return false; | |
| 49 | ++__first1; | |
| 50 | ++__first2; | |
| 51 | } | |
| 52 | return __first1 == __last1 && __first2 == __last2; | |
| 53 | } | |
| 54 | ||
| 55 | public: | |
| 56 | ||
| 57 | template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 58 | input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 59 | class _Pred = ranges::equal_to, | |
| 36 | template <input_iterator _Iter1, | |
| 37 | sentinel_for<_Iter1> _Sent1, | |
| 38 | input_iterator _Iter2, | |
| 39 | sentinel_for<_Iter2> _Sent2, | |
| 40 | class _Pred = ranges::equal_to, | |
| 60 | 41 | class _Proj1 = identity, |
| 61 | 42 | class _Proj2 = identity> |
| 62 | 43 | requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> |
| 63 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 64 | bool operator()(_Iter1 __first1, _Sent1 __last1, | |
| 65 | _Iter2 __first2, _Sent2 __last2, | |
| 66 | _Pred __pred = {}, | |
| 67 | _Proj1 __proj1 = {}, | |
| 68 | _Proj2 __proj2 = {}) const { | |
| 44 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 45 | _Iter1 __first1, | |
| 46 | _Sent1 __last1, | |
| 47 | _Iter2 __first2, | |
| 48 | _Sent2 __last2, | |
| 49 | _Pred __pred = {}, | |
| 50 | _Proj1 __proj1 = {}, | |
| 51 | _Proj2 __proj2 = {}) const { | |
| 69 | 52 | if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) { |
| 70 | 53 | if (__last1 - __first1 != __last2 - __first2) |
| 71 | 54 | return false; |
| 72 | 55 | } |
| 73 | return __equal_impl(std::move(__first1), std::move(__last1), | |
| 74 | std::move(__first2), std::move(__last2), | |
| 75 | __pred, | |
| 76 | __proj1, | |
| 77 | __proj2); | |
| 56 | auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1)); | |
| 57 | auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2)); | |
| 58 | return std::__equal_impl( | |
| 59 | std::move(__unwrapped1.first), | |
| 60 | std::move(__unwrapped1.second), | |
| 61 | std::move(__unwrapped2.first), | |
| 62 | std::move(__unwrapped2.second), | |
| 63 | __pred, | |
| 64 | __proj1, | |
| 65 | __proj2); | |
| 78 | 66 | } |
| 79 | 67 | |
| 80 | 68 | template <input_range _Range1, |
| 81 | 69 | input_range _Range2, |
| 82 | class _Pred = ranges::equal_to, | |
| 70 | class _Pred = ranges::equal_to, | |
| 83 | 71 | class _Proj1 = identity, |
| 84 | 72 | class _Proj2 = identity> |
| 85 | 73 | requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> |
| 86 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 87 | bool operator()(_Range1&& __range1, | |
| 88 | _Range2&& __range2, | |
| 89 | _Pred __pred = {}, | |
| 90 | _Proj1 __proj1 = {}, | |
| 91 | _Proj2 __proj2 = {}) const { | |
| 74 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 75 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 92 | 76 | if constexpr (sized_range<_Range1> && sized_range<_Range2>) { |
| 93 | 77 | if (ranges::distance(__range1) != ranges::distance(__range2)) |
| 94 | 78 | return false; |
| 95 | 79 | } |
| 96 | return __equal_impl(ranges::begin(__range1), ranges::end(__range1), | |
| 97 | ranges::begin(__range2), ranges::end(__range2), | |
| 98 | __pred, | |
| 99 | __proj1, | |
| 100 | __proj2); | |
| 80 | auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1)); | |
| 81 | auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2)); | |
| 82 | return std::__equal_impl( | |
| 83 | std::move(__unwrapped1.first), | |
| 84 | std::move(__unwrapped1.second), | |
| 85 | std::move(__unwrapped2.first), | |
| 86 | std::move(__unwrapped2.second), | |
| 87 | __pred, | |
| 88 | __proj1, | |
| 89 | __proj2); | |
| 101 | 90 | return false; |
| 102 | 91 | } |
| 103 | 92 | }; |
| 104 | 93 | } // namespace __equal |
| 105 | 94 | |
| 106 | 95 | inline namespace __cpo { |
| 107 | inline constexpr auto equal = __equal::__fn{}; | |
| 96 | inline constexpr auto equal = __equal::__fn{}; | |
| 108 | 97 | } // namespace __cpo |
| 109 | 98 | } // namespace ranges |
| 110 | 99 | |
| 111 | 100 | _LIBCPP_END_NAMESPACE_STD |
| 112 | 101 | |
| 113 | #endif // _LIBCPP_STD_VER > 17 | |
| 102 | #endif // _LIBCPP_STD_VER >= 20 | |
| 114 | 103 | |
| 115 | 104 | #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H |
lib/libcxx/include/__algorithm/ranges_equal_range.h+15-18| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | # pragma GCC system_header |
| 31 | 31 | #endif |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 36 | |
| ... | ... | @@ -38,28 +38,25 @@ namespace ranges { |
| 38 | 38 | namespace __equal_range { |
| 39 | 39 | |
| 40 | 40 | struct __fn { |
| 41 | template < | |
| 42 | forward_iterator _Iter, | |
| 43 | sentinel_for<_Iter> _Sent, | |
| 44 | class _Tp, | |
| 45 | class _Proj = identity, | |
| 46 | indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less> | |
| 41 | template <forward_iterator _Iter, | |
| 42 | sentinel_for<_Iter> _Sent, | |
| 43 | class _Tp, | |
| 44 | class _Proj = identity, | |
| 45 | indirect_strict_weak_order<const _Tp*, projected<_Iter, _Proj>> _Comp = ranges::less> | |
| 47 | 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> |
| 48 | 47 | operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { |
| 49 | auto __ret = std::__equal_range<_RangeAlgPolicy>( | |
| 50 | std::move(__first), std::move(__last), __value, __comp, __proj); | |
| 48 | auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj); | |
| 51 | 49 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 52 | 50 | } |
| 53 | 51 | |
| 54 | template < | |
| 55 | forward_range _Range, | |
| 56 | class _Tp, | |
| 57 | class _Proj = identity, | |
| 58 | indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> | |
| 52 | template <forward_range _Range, | |
| 53 | class _Tp, | |
| 54 | class _Proj = identity, | |
| 55 | indirect_strict_weak_order<const _Tp*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> | |
| 59 | 56 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> |
| 60 | 57 | operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { |
| 61 | auto __ret = std::__equal_range<_RangeAlgPolicy>( | |
| 62 | ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); | |
| 58 | auto __ret = | |
| 59 | std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); | |
| 63 | 60 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 64 | 61 | } |
| 65 | 62 | }; |
| ... | ... | @@ -67,12 +64,12 @@ struct __fn { |
| 67 | 64 | } // namespace __equal_range |
| 68 | 65 | |
| 69 | 66 | inline namespace __cpo { |
| 70 | inline constexpr auto equal_range = __equal_range::__fn{}; | |
| 67 | inline constexpr auto equal_range = __equal_range::__fn{}; | |
| 71 | 68 | } // namespace __cpo |
| 72 | 69 | } // namespace ranges |
| 73 | 70 | |
| 74 | 71 | _LIBCPP_END_NAMESPACE_STD |
| 75 | 72 | |
| 76 | #endif // _LIBCPP_STD_VER > 17 | |
| 73 | #endif // _LIBCPP_STD_VER >= 20 | |
| 77 | 74 | |
| 78 | 75 | #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H |
lib/libcxx/include/__algorithm/ranges_fill.h+6-8| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| ... | ... | @@ -28,9 +28,8 @@ namespace ranges { |
| 28 | 28 | namespace __fill { |
| 29 | 29 | struct __fn { |
| 30 | 30 | template <class _Type, output_iterator<const _Type&> _Iter, sentinel_for<_Iter> _Sent> |
| 31 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 32 | _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { | |
| 33 | if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { | |
| 31 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { | |
| 32 | if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { | |
| 34 | 33 | return ranges::fill_n(__first, __last - __first, __value); |
| 35 | 34 | } else { |
| 36 | 35 | for (; __first != __last; ++__first) |
| ... | ... | @@ -40,20 +39,19 @@ struct __fn { |
| 40 | 39 | } |
| 41 | 40 | |
| 42 | 41 | template <class _Type, output_range<const _Type&> _Range> |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 44 | borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { | |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { | |
| 45 | 43 | return (*this)(ranges::begin(__range), ranges::end(__range), __value); |
| 46 | 44 | } |
| 47 | 45 | }; |
| 48 | 46 | } // namespace __fill |
| 49 | 47 | |
| 50 | 48 | inline namespace __cpo { |
| 51 | inline constexpr auto fill = __fill::__fn{}; | |
| 49 | inline constexpr auto fill = __fill::__fn{}; | |
| 52 | 50 | } // namespace __cpo |
| 53 | 51 | } // namespace ranges |
| 54 | 52 | |
| 55 | 53 | _LIBCPP_END_NAMESPACE_STD |
| 56 | 54 | |
| 57 | #endif // _LIBCPP_STD_VER > 17 | |
| 55 | #endif // _LIBCPP_STD_VER >= 20 | |
| 58 | 56 | |
| 59 | 57 | #endif // _LIBCPP___ALGORITHM_RANGES_FILL_H |
lib/libcxx/include/__algorithm/ranges_fill_n.h+5-5| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | #if _LIBCPP_STD_VER > 17 | |
| 20 | #if _LIBCPP_STD_VER >= 20 | |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| ... | ... | @@ -25,8 +25,8 @@ namespace ranges { |
| 25 | 25 | namespace __fill_n { |
| 26 | 26 | struct __fn { |
| 27 | 27 | template <class _Type, output_iterator<const _Type&> _Iter> |
| 28 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 29 | _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { | |
| 28 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 29 | operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { | |
| 30 | 30 | for (; __n != 0; --__n) { |
| 31 | 31 | *__first = __value; |
| 32 | 32 | ++__first; |
| ... | ... | @@ -37,12 +37,12 @@ struct __fn { |
| 37 | 37 | } // namespace __fill_n |
| 38 | 38 | |
| 39 | 39 | inline namespace __cpo { |
| 40 | inline constexpr auto fill_n = __fill_n::__fn{}; | |
| 40 | inline constexpr auto fill_n = __fill_n::__fn{}; | |
| 41 | 41 | } // namespace __cpo |
| 42 | 42 | } // namespace ranges |
| 43 | 43 | |
| 44 | 44 | _LIBCPP_END_NAMESPACE_STD |
| 45 | 45 | |
| 46 | #endif // _LIBCPP_STD_VER > 17 | |
| 46 | #endif // _LIBCPP_STD_VER >= 20 | |
| 47 | 47 | |
| 48 | 48 | #endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H |
lib/libcxx/include/__algorithm/ranges_find.h+23-11| ... | ... | @@ -9,7 +9,9 @@ |
| 9 | 9 | #ifndef _LIBCPP___ALGORITHM_RANGES_FIND_H |
| 10 | 10 | #define _LIBCPP___ALGORITHM_RANGES_FIND_H |
| 11 | 11 | |
| 12 | #include <__algorithm/find.h> | |
| 12 | 13 | #include <__algorithm/ranges_find_if.h> |
| 14 | #include <__algorithm/unwrap_range.h> | |
| 13 | 15 | #include <__config> |
| 14 | 16 | #include <__functional/identity.h> |
| 15 | 17 | #include <__functional/invoke.h> |
| ... | ... | @@ -26,38 +28,48 @@ |
| 26 | 28 | # pragma GCC system_header |
| 27 | 29 | #endif |
| 28 | 30 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 32 | |
| 31 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 34 | |
| 33 | 35 | namespace ranges { |
| 34 | 36 | namespace __find { |
| 35 | 37 | struct __fn { |
| 38 | template <class _Iter, class _Sent, class _Tp, class _Proj> | |
| 39 | _LIBCPP_HIDE_FROM_ABI static constexpr _Iter | |
| 40 | __find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) { | |
| 41 | if constexpr (forward_iterator<_Iter>) { | |
| 42 | auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last)); | |
| 43 | return std::__rewrap_range<_Sent>( | |
| 44 | std::move(__first), std::__find_impl(std::move(__first_un), std::move(__last_un), __value, __proj)); | |
| 45 | } else { | |
| 46 | return std::__find_impl(std::move(__first), std::move(__last), __value, __proj); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 36 | 50 | template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Tp, class _Proj = identity> |
| 37 | 51 | requires indirect_binary_predicate<ranges::equal_to, projected<_Ip, _Proj>, const _Tp*> |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 39 | _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { | |
| 40 | auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; }; | |
| 41 | return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); | |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip | |
| 53 | operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { | |
| 54 | return __find_unwrap(std::move(__first), std::move(__last), __value, __proj); | |
| 42 | 55 | } |
| 43 | 56 | |
| 44 | 57 | template <input_range _Rp, class _Tp, class _Proj = identity> |
| 45 | 58 | requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Rp>, _Proj>, const _Tp*> |
| 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 47 | borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { | |
| 48 | auto __pred = [&](auto&& __e) { return std::forward<decltype(__e)>(__e) == __value; }; | |
| 49 | return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); | |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> | |
| 60 | operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { | |
| 61 | return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj); | |
| 50 | 62 | } |
| 51 | 63 | }; |
| 52 | 64 | } // namespace __find |
| 53 | 65 | |
| 54 | 66 | inline namespace __cpo { |
| 55 | inline constexpr auto find = __find::__fn{}; | |
| 67 | inline constexpr auto find = __find::__fn{}; | |
| 56 | 68 | } // namespace __cpo |
| 57 | 69 | } // namespace ranges |
| 58 | 70 | |
| 59 | 71 | _LIBCPP_END_NAMESPACE_STD |
| 60 | 72 | |
| 61 | #endif // _LIBCPP_STD_VER > 17 | |
| 73 | #endif // _LIBCPP_STD_VER >= 20 | |
| 62 | 74 | |
| 63 | 75 | #endif // _LIBCPP___ALGORITHM_RANGES_FIND_H |
lib/libcxx/include/__algorithm/ranges_find_end.h+19-19| ... | ... | @@ -27,25 +27,29 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| 34 | 34 | namespace ranges { |
| 35 | 35 | namespace __find_end { |
| 36 | 36 | struct __fn { |
| 37 | template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 38 | forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 39 | class _Pred = ranges::equal_to, | |
| 37 | template <forward_iterator _Iter1, | |
| 38 | sentinel_for<_Iter1> _Sent1, | |
| 39 | forward_iterator _Iter2, | |
| 40 | sentinel_for<_Iter2> _Sent2, | |
| 41 | class _Pred = ranges::equal_to, | |
| 40 | 42 | class _Proj1 = identity, |
| 41 | 43 | class _Proj2 = identity> |
| 42 | 44 | requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> |
| 43 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 44 | subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, | |
| 45 | _Iter2 __first2, _Sent2 __last2, | |
| 46 | _Pred __pred = {}, | |
| 47 | _Proj1 __proj1 = {}, | |
| 48 | _Proj2 __proj2 = {}) const { | |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( | |
| 46 | _Iter1 __first1, | |
| 47 | _Sent1 __last1, | |
| 48 | _Iter2 __first2, | |
| 49 | _Sent2 __last2, | |
| 50 | _Pred __pred = {}, | |
| 51 | _Proj1 __proj1 = {}, | |
| 52 | _Proj2 __proj2 = {}) const { | |
| 49 | 53 | auto __ret = std::__find_end_impl<_RangeAlgPolicy>( |
| 50 | 54 | __first1, |
| 51 | 55 | __last1, |
| ... | ... | @@ -61,16 +65,12 @@ struct __fn { |
| 61 | 65 | |
| 62 | 66 | template <forward_range _Range1, |
| 63 | 67 | forward_range _Range2, |
| 64 | class _Pred = ranges::equal_to, | |
| 68 | class _Pred = ranges::equal_to, | |
| 65 | 69 | class _Proj1 = identity, |
| 66 | 70 | class _Proj2 = identity> |
| 67 | 71 | requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> |
| 68 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 69 | borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, | |
| 70 | _Range2&& __range2, | |
| 71 | _Pred __pred = {}, | |
| 72 | _Proj1 __proj1 = {}, | |
| 73 | _Proj2 __proj2 = {}) const { | |
| 72 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( | |
| 73 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 74 | 74 | auto __ret = std::__find_end_impl<_RangeAlgPolicy>( |
| 75 | 75 | ranges::begin(__range1), |
| 76 | 76 | ranges::end(__range1), |
| ... | ... | @@ -87,12 +87,12 @@ struct __fn { |
| 87 | 87 | } // namespace __find_end |
| 88 | 88 | |
| 89 | 89 | inline namespace __cpo { |
| 90 | inline constexpr auto find_end = __find_end::__fn{}; | |
| 90 | inline constexpr auto find_end = __find_end::__fn{}; | |
| 91 | 91 | } // namespace __cpo |
| 92 | 92 | } // namespace ranges |
| 93 | 93 | |
| 94 | 94 | _LIBCPP_END_NAMESPACE_STD |
| 95 | 95 | |
| 96 | #endif // _LIBCPP_STD_VER > 17 | |
| 96 | #endif // _LIBCPP_STD_VER >= 20 | |
| 97 | 97 | |
| 98 | 98 | #endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H |
lib/libcxx/include/__algorithm/ranges_find_first_of.h+37-37| ... | ... | @@ -24,21 +24,22 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | namespace __find_first_of { |
| 33 | 33 | struct __fn { |
| 34 | ||
| 35 | 34 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2> |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 37 | _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1, | |
| 38 | _Iter2 __first2, _Sent2 __last2, | |
| 39 | _Pred& __pred, | |
| 40 | _Proj1& __proj1, | |
| 41 | _Proj2& __proj2) { | |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl( | |
| 36 | _Iter1 __first1, | |
| 37 | _Sent1 __last1, | |
| 38 | _Iter2 __first2, | |
| 39 | _Sent2 __last2, | |
| 40 | _Pred& __pred, | |
| 41 | _Proj1& __proj1, | |
| 42 | _Proj2& __proj2) { | |
| 42 | 43 | for (; __first1 != __last1; ++__first1) { |
| 43 | 44 | for (auto __j = __first2; __j != __last2; ++__j) { |
| 44 | 45 | if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j))) |
| ... | ... | @@ -48,54 +49,53 @@ struct __fn { |
| 48 | 49 | return __first1; |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 52 | forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 53 | class _Pred = ranges::equal_to, | |
| 52 | template <input_iterator _Iter1, | |
| 53 | sentinel_for<_Iter1> _Sent1, | |
| 54 | forward_iterator _Iter2, | |
| 55 | sentinel_for<_Iter2> _Sent2, | |
| 56 | class _Pred = ranges::equal_to, | |
| 54 | 57 | class _Proj1 = identity, |
| 55 | 58 | class _Proj2 = identity> |
| 56 | 59 | requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | _Iter1 operator()(_Iter1 __first1, _Sent1 __last1, | |
| 59 | _Iter2 __first2, _Sent2 __last2, | |
| 60 | _Pred __pred = {}, | |
| 61 | _Proj1 __proj1 = {}, | |
| 62 | _Proj2 __proj2 = {}) const { | |
| 63 | return __find_first_of_impl(std::move(__first1), std::move(__last1), | |
| 64 | std::move(__first2), std::move(__last2), | |
| 65 | __pred, | |
| 66 | __proj1, | |
| 67 | __proj2); | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( | |
| 61 | _Iter1 __first1, | |
| 62 | _Sent1 __last1, | |
| 63 | _Iter2 __first2, | |
| 64 | _Sent2 __last2, | |
| 65 | _Pred __pred = {}, | |
| 66 | _Proj1 __proj1 = {}, | |
| 67 | _Proj2 __proj2 = {}) const { | |
| 68 | return __find_first_of_impl( | |
| 69 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); | |
| 68 | 70 | } |
| 69 | 71 | |
| 70 | 72 | template <input_range _Range1, |
| 71 | 73 | forward_range _Range2, |
| 72 | class _Pred = ranges::equal_to, | |
| 74 | class _Pred = ranges::equal_to, | |
| 73 | 75 | class _Proj1 = identity, |
| 74 | 76 | class _Proj2 = identity> |
| 75 | 77 | requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> |
| 76 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 77 | borrowed_iterator_t<_Range1> operator()(_Range1&& __range1, | |
| 78 | _Range2&& __range2, | |
| 79 | _Pred __pred = {}, | |
| 80 | _Proj1 __proj1 = {}, | |
| 81 | _Proj2 __proj2 = {}) const { | |
| 82 | return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1), | |
| 83 | ranges::begin(__range2), ranges::end(__range2), | |
| 84 | __pred, | |
| 85 | __proj1, | |
| 86 | __proj2); | |
| 78 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( | |
| 79 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 80 | return __find_first_of_impl( | |
| 81 | ranges::begin(__range1), | |
| 82 | ranges::end(__range1), | |
| 83 | ranges::begin(__range2), | |
| 84 | ranges::end(__range2), | |
| 85 | __pred, | |
| 86 | __proj1, | |
| 87 | __proj2); | |
| 87 | 88 | } |
| 88 | ||
| 89 | 89 | }; |
| 90 | 90 | } // namespace __find_first_of |
| 91 | 91 | |
| 92 | 92 | inline namespace __cpo { |
| 93 | inline constexpr auto find_first_of = __find_first_of::__fn{}; | |
| 93 | inline constexpr auto find_first_of = __find_first_of::__fn{}; | |
| 94 | 94 | } // namespace __cpo |
| 95 | 95 | } // namespace ranges |
| 96 | 96 | |
| 97 | 97 | _LIBCPP_END_NAMESPACE_STD |
| 98 | 98 | |
| 99 | #endif // _LIBCPP_STD_VER > 17 | |
| 99 | #endif // _LIBCPP_STD_VER >= 20 | |
| 100 | 100 | |
| 101 | 101 | #endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H |
lib/libcxx/include/__algorithm/ranges_find_if.h+12-13| ... | ... | @@ -24,15 +24,14 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | |
| 33 | 33 | template <class _Ip, class _Sp, class _Pred, class _Proj> |
| 34 | _LIBCPP_HIDE_FROM_ABI static constexpr | |
| 35 | _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { | |
| 36 | 35 | for (; __first != __last; ++__first) { |
| 37 | 36 | if (std::invoke(__pred, std::invoke(__proj, *__first))) |
| 38 | 37 | break; |
| ... | ... | @@ -42,30 +41,30 @@ _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { |
| 42 | 41 | |
| 43 | 42 | namespace __find_if { |
| 44 | 43 | struct __fn { |
| 45 | ||
| 46 | template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, | |
| 44 | template <input_iterator _Ip, | |
| 45 | sentinel_for<_Ip> _Sp, | |
| 46 | class _Proj = identity, | |
| 47 | 47 | indirect_unary_predicate<projected<_Ip, _Proj>> _Pred> |
| 48 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 49 | _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { | |
| 48 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip | |
| 49 | operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { | |
| 50 | 50 | return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | template <input_range _Rp, class _Proj = identity, | |
| 54 | indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> | |
| 55 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 56 | borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { | |
| 53 | template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> | |
| 54 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> | |
| 55 | operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { | |
| 57 | 56 | return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); |
| 58 | 57 | } |
| 59 | 58 | }; |
| 60 | 59 | } // namespace __find_if |
| 61 | 60 | |
| 62 | 61 | inline namespace __cpo { |
| 63 | inline constexpr auto find_if = __find_if::__fn{}; | |
| 62 | inline constexpr auto find_if = __find_if::__fn{}; | |
| 64 | 63 | } // namespace __cpo |
| 65 | 64 | } // namespace ranges |
| 66 | 65 | |
| 67 | 66 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 67 | |
| 69 | #endif // _LIBCPP_STD_VER > 17 | |
| 68 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 69 | |
| 71 | 70 | #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H |
lib/libcxx/include/__algorithm/ranges_find_if_not.h+11-10| ... | ... | @@ -26,25 +26,26 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | 33 | namespace ranges { |
| 34 | 34 | namespace __find_if_not { |
| 35 | 35 | struct __fn { |
| 36 | template <input_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, | |
| 36 | template <input_iterator _Ip, | |
| 37 | sentinel_for<_Ip> _Sp, | |
| 38 | class _Proj = identity, | |
| 37 | 39 | indirect_unary_predicate<projected<_Ip, _Proj>> _Pred> |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 39 | _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { | |
| 40 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip | |
| 41 | operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { | |
| 40 | 42 | auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); }; |
| 41 | 43 | return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj); |
| 42 | 44 | } |
| 43 | 45 | |
| 44 | template <input_range _Rp, class _Proj = identity, | |
| 45 | indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> | |
| 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 47 | borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { | |
| 46 | template <input_range _Rp, class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Rp>, _Proj>> _Pred> | |
| 47 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> | |
| 48 | operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { | |
| 48 | 49 | auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward<decltype(__e)>(__e)); }; |
| 49 | 50 | return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); |
| 50 | 51 | } |
| ... | ... | @@ -52,12 +53,12 @@ struct __fn { |
| 52 | 53 | } // namespace __find_if_not |
| 53 | 54 | |
| 54 | 55 | inline namespace __cpo { |
| 55 | inline constexpr auto find_if_not = __find_if_not::__fn{}; | |
| 56 | inline constexpr auto find_if_not = __find_if_not::__fn{}; | |
| 56 | 57 | } // namespace __cpo |
| 57 | 58 | } // namespace ranges |
| 58 | 59 | |
| 59 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 60 | 61 | |
| 61 | #endif // _LIBCPP_STD_VER > 17 | |
| 62 | #endif // _LIBCPP_STD_VER >= 20 | |
| 62 | 63 | |
| 63 | 64 | #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H |
lib/libcxx/include/__algorithm/ranges_for_each.h+11-13| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -37,42 +37,40 @@ namespace __for_each { |
| 37 | 37 | struct __fn { |
| 38 | 38 | private: |
| 39 | 39 | template <class _Iter, class _Sent, class _Proj, class _Func> |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 41 | for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func> | |
| 41 | __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { | |
| 42 | 42 | for (; __first != __last; ++__first) |
| 43 | 43 | std::invoke(__func, std::invoke(__proj, *__first)); |
| 44 | 44 | return {std::move(__first), std::move(__func)}; |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | public: |
| 48 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 48 | template <input_iterator _Iter, | |
| 49 | sentinel_for<_Iter> _Sent, | |
| 49 | 50 | class _Proj = identity, |
| 50 | 51 | indirectly_unary_invocable<projected<_Iter, _Proj>> _Func> |
| 51 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 52 | for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<_Iter, _Func> | |
| 53 | operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { | |
| 53 | 54 | return __for_each_impl(std::move(__first), std::move(__last), __func, __proj); |
| 54 | 55 | } |
| 55 | 56 | |
| 56 | 57 | template <input_range _Range, |
| 57 | 58 | class _Proj = identity, |
| 58 | 59 | indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>> _Func> |
| 59 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 60 | for_each_result<borrowed_iterator_t<_Range>, _Func> operator()(_Range&& __range, | |
| 61 | _Func __func, | |
| 62 | _Proj __proj = {}) const { | |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<borrowed_iterator_t<_Range>, _Func> | |
| 61 | operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const { | |
| 63 | 62 | return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj); |
| 64 | 63 | } |
| 65 | ||
| 66 | 64 | }; |
| 67 | 65 | } // namespace __for_each |
| 68 | 66 | |
| 69 | 67 | inline namespace __cpo { |
| 70 | inline constexpr auto for_each = __for_each::__fn{}; | |
| 68 | inline constexpr auto for_each = __for_each::__fn{}; | |
| 71 | 69 | } // namespace __cpo |
| 72 | 70 | } // namespace ranges |
| 73 | 71 | |
| 74 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 75 | 73 | |
| 76 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 77 | 75 | |
| 78 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H |
lib/libcxx/include/__algorithm/ranges_for_each_n.h+6-13| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -35,32 +35,25 @@ using for_each_n_result = in_fun_result<_Iter, _Func>; |
| 35 | 35 | |
| 36 | 36 | namespace __for_each_n { |
| 37 | 37 | struct __fn { |
| 38 | ||
| 39 | template <input_iterator _Iter, | |
| 40 | class _Proj = identity, | |
| 41 | indirectly_unary_invocable<projected<_Iter, _Proj>> _Func> | |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 43 | for_each_n_result<_Iter, _Func> operator()(_Iter __first, | |
| 44 | iter_difference_t<_Iter> __count, | |
| 45 | _Func __func, | |
| 46 | _Proj __proj = {}) const { | |
| 38 | template <input_iterator _Iter, class _Proj = identity, indirectly_unary_invocable<projected<_Iter, _Proj>> _Func> | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr for_each_n_result<_Iter, _Func> | |
| 40 | operator()(_Iter __first, iter_difference_t<_Iter> __count, _Func __func, _Proj __proj = {}) const { | |
| 47 | 41 | while (__count-- > 0) { |
| 48 | 42 | std::invoke(__func, std::invoke(__proj, *__first)); |
| 49 | 43 | ++__first; |
| 50 | 44 | } |
| 51 | 45 | return {std::move(__first), std::move(__func)}; |
| 52 | 46 | } |
| 53 | ||
| 54 | 47 | }; |
| 55 | 48 | } // namespace __for_each_n |
| 56 | 49 | |
| 57 | 50 | inline namespace __cpo { |
| 58 | inline constexpr auto for_each_n = __for_each_n::__fn{}; | |
| 51 | inline constexpr auto for_each_n = __for_each_n::__fn{}; | |
| 59 | 52 | } // namespace __cpo |
| 60 | 53 | } // namespace ranges |
| 61 | 54 | |
| 62 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 63 | 56 | |
| 64 | #endif // _LIBCPP_STD_VER > 17 | |
| 57 | #endif // _LIBCPP_STD_VER >= 20 | |
| 65 | 58 | |
| 66 | 59 | #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H |
lib/libcxx/include/__algorithm/ranges_generate.h+8-13| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -32,10 +32,8 @@ namespace ranges { |
| 32 | 32 | namespace __generate { |
| 33 | 33 | |
| 34 | 34 | struct __fn { |
| 35 | ||
| 36 | 35 | template <class _OutIter, class _Sent, class _Func> |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 38 | static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { | |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { | |
| 39 | 37 | for (; __first != __last; ++__first) { |
| 40 | 38 | *__first = __gen(); |
| 41 | 39 | } |
| ... | ... | @@ -44,30 +42,27 @@ struct __fn { |
| 44 | 42 | } |
| 45 | 43 | |
| 46 | 44 | template <input_or_output_iterator _OutIter, sentinel_for<_OutIter> _Sent, copy_constructible _Func> |
| 47 | requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 49 | _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { | |
| 45 | requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> | |
| 46 | _LIBCPP_HIDE_FROM_ABI constexpr _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { | |
| 50 | 47 | return __generate_fn_impl(std::move(__first), std::move(__last), __gen); |
| 51 | 48 | } |
| 52 | 49 | |
| 53 | 50 | template <class _Range, copy_constructible _Func> |
| 54 | requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 56 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { | |
| 51 | requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { | |
| 57 | 53 | return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen); |
| 58 | 54 | } |
| 59 | ||
| 60 | 55 | }; |
| 61 | 56 | |
| 62 | 57 | } // namespace __generate |
| 63 | 58 | |
| 64 | 59 | inline namespace __cpo { |
| 65 | inline constexpr auto generate = __generate::__fn{}; | |
| 60 | inline constexpr auto generate = __generate::__fn{}; | |
| 66 | 61 | } // namespace __cpo |
| 67 | 62 | } // namespace ranges |
| 68 | 63 | |
| 69 | 64 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 65 | |
| 71 | #endif // _LIBCPP_STD_VER > 17 | |
| 66 | #endif // _LIBCPP_STD_VER >= 20 | |
| 72 | 67 | |
| 73 | 68 | #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H |
lib/libcxx/include/__algorithm/ranges_generate_n.h+6-8| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -33,11 +33,10 @@ namespace ranges { |
| 33 | 33 | namespace __generate_n { |
| 34 | 34 | |
| 35 | 35 | struct __fn { |
| 36 | ||
| 37 | 36 | template <input_or_output_iterator _OutIter, copy_constructible _Func> |
| 38 | requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 40 | _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { | |
| 37 | requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr _OutIter | |
| 39 | operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { | |
| 41 | 40 | for (; __n > 0; --__n) { |
| 42 | 41 | *__first = __gen(); |
| 43 | 42 | ++__first; |
| ... | ... | @@ -45,18 +44,17 @@ struct __fn { |
| 45 | 44 | |
| 46 | 45 | return __first; |
| 47 | 46 | } |
| 48 | ||
| 49 | 47 | }; |
| 50 | 48 | |
| 51 | 49 | } // namespace __generate_n |
| 52 | 50 | |
| 53 | 51 | inline namespace __cpo { |
| 54 | inline constexpr auto generate_n = __generate_n::__fn{}; | |
| 52 | inline constexpr auto generate_n = __generate_n::__fn{}; | |
| 55 | 53 | } // namespace __cpo |
| 56 | 54 | } // namespace ranges |
| 57 | 55 | |
| 58 | 56 | _LIBCPP_END_NAMESPACE_STD |
| 59 | 57 | |
| 60 | #endif // _LIBCPP_STD_VER > 17 | |
| 58 | #endif // _LIBCPP_STD_VER >= 20 | |
| 61 | 59 | |
| 62 | 60 | #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H |
lib/libcxx/include/__algorithm/ranges_includes.h+16-18| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -35,14 +35,13 @@ namespace ranges { |
| 35 | 35 | namespace __includes { |
| 36 | 36 | |
| 37 | 37 | struct __fn { |
| 38 | template < | |
| 39 | input_iterator _Iter1, | |
| 40 | sentinel_for<_Iter1> _Sent1, | |
| 41 | input_iterator _Iter2, | |
| 42 | sentinel_for<_Iter2> _Sent2, | |
| 43 | class _Proj1 = identity, | |
| 44 | class _Proj2 = identity, | |
| 45 | indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less> | |
| 38 | template <input_iterator _Iter1, | |
| 39 | sentinel_for<_Iter1> _Sent1, | |
| 40 | input_iterator _Iter2, | |
| 41 | sentinel_for<_Iter2> _Sent2, | |
| 42 | class _Proj1 = identity, | |
| 43 | class _Proj2 = identity, | |
| 44 | indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less> | |
| 46 | 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( |
| 47 | 46 | _Iter1 __first1, |
| 48 | 47 | _Sent1 __last1, |
| ... | ... | @@ -61,13 +60,12 @@ struct __fn { |
| 61 | 60 | std::move(__proj2)); |
| 62 | 61 | } |
| 63 | 62 | |
| 64 | template < | |
| 65 | input_range _Range1, | |
| 66 | input_range _Range2, | |
| 67 | class _Proj1 = identity, | |
| 68 | class _Proj2 = identity, | |
| 69 | indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> | |
| 70 | _Comp = ranges::less> | |
| 63 | template <input_range _Range1, | |
| 64 | input_range _Range2, | |
| 65 | class _Proj1 = identity, | |
| 66 | class _Proj2 = identity, | |
| 67 | indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> | |
| 68 | _Comp = ranges::less> | |
| 71 | 69 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( |
| 72 | 70 | _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { |
| 73 | 71 | return std::__includes( |
| ... | ... | @@ -84,12 +82,12 @@ struct __fn { |
| 84 | 82 | } // namespace __includes |
| 85 | 83 | |
| 86 | 84 | inline namespace __cpo { |
| 87 | inline constexpr auto includes = __includes::__fn{}; | |
| 85 | inline constexpr auto includes = __includes::__fn{}; | |
| 88 | 86 | } // namespace __cpo |
| 89 | 87 | } // namespace ranges |
| 90 | 88 | |
| 91 | 89 | _LIBCPP_END_NAMESPACE_STD |
| 92 | 90 | |
| 93 | #endif // _LIBCPP_STD_VER > 17 | |
| 91 | #endif // _LIBCPP_STD_VER >= 20 | |
| 94 | 92 | |
| 95 | 93 | #endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H |
lib/libcxx/include/__algorithm/ranges_inplace_merge.h+27-33| ... | ... | @@ -31,55 +31,49 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| 38 | 38 | namespace ranges { |
| 39 | 39 | namespace __inplace_merge { |
| 40 | 40 | |
| 41 | struct __fn { | |
| 42 | template <class _Iter, class _Sent, class _Comp, class _Proj> | |
| 43 | _LIBCPP_HIDE_FROM_ABI static constexpr auto | |
| 44 | __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { | |
| 45 | auto __last_iter = ranges::next(__middle, __last); | |
| 46 | std::__inplace_merge<_RangeAlgPolicy>( | |
| 47 | std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); | |
| 48 | return __last_iter; | |
| 49 | } | |
| 41 | struct __fn { | |
| 42 | template <class _Iter, class _Sent, class _Comp, class _Proj> | |
| 43 | _LIBCPP_HIDE_FROM_ABI static constexpr auto | |
| 44 | __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { | |
| 45 | auto __last_iter = ranges::next(__middle, __last); | |
| 46 | std::__inplace_merge<_RangeAlgPolicy>( | |
| 47 | std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); | |
| 48 | return __last_iter; | |
| 49 | } | |
| 50 | 50 | |
| 51 | template < | |
| 52 | bidirectional_iterator _Iter, | |
| 53 | sentinel_for<_Iter> _Sent, | |
| 54 | class _Comp = ranges::less, | |
| 55 | class _Proj = identity> | |
| 56 | requires sortable<_Iter, _Comp, _Proj> | |
| 57 | _LIBCPP_HIDE_FROM_ABI _Iter | |
| 58 | operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | return __inplace_merge_impl( | |
| 60 | std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); | |
| 61 | } | |
| 51 | template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> | |
| 52 | requires sortable<_Iter, _Comp, _Proj> | |
| 53 | _LIBCPP_HIDE_FROM_ABI _Iter | |
| 54 | operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 55 | return __inplace_merge_impl( | |
| 56 | std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); | |
| 57 | } | |
| 62 | 58 | |
| 63 | template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity> | |
| 64 | requires sortable< | |
| 65 | iterator_t<_Range>, | |
| 66 | _Comp, | |
| 67 | _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> | |
| 68 | operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 69 | return __inplace_merge_impl( | |
| 70 | ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); | |
| 71 | } | |
| 72 | }; | |
| 59 | template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity> | |
| 60 | requires sortable<iterator_t<_Range>, _Comp, _Proj> | |
| 61 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> | |
| 62 | operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 63 | return __inplace_merge_impl( | |
| 64 | ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); | |
| 65 | } | |
| 66 | }; | |
| 73 | 67 | |
| 74 | 68 | } // namespace __inplace_merge |
| 75 | 69 | |
| 76 | 70 | inline namespace __cpo { |
| 77 | inline constexpr auto inplace_merge = __inplace_merge::__fn{}; | |
| 71 | inline constexpr auto inplace_merge = __inplace_merge::__fn{}; | |
| 78 | 72 | } // namespace __cpo |
| 79 | 73 | } // namespace ranges |
| 80 | 74 | |
| 81 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 82 | 76 | |
| 83 | #endif // _LIBCPP_STD_VER > 17 | |
| 77 | #endif // _LIBCPP_STD_VER >= 20 | |
| 84 | 78 | |
| 85 | 79 | #endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H |
lib/libcxx/include/__algorithm/ranges_is_heap.h+15-13| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| ... | ... | @@ -34,28 +34,30 @@ namespace ranges { |
| 34 | 34 | namespace __is_heap { |
| 35 | 35 | |
| 36 | 36 | struct __fn { |
| 37 | ||
| 38 | 37 | template <class _Iter, class _Sent, class _Proj, class _Comp> |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 40 | static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 41 | auto __last_iter = ranges::next(__first, __last); | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr static bool | |
| 39 | __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 40 | auto __last_iter = ranges::next(__first, __last); | |
| 42 | 41 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| 43 | 42 | |
| 44 | 43 | auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); |
| 45 | 44 | return __result == __last; |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 47 | template <random_access_iterator _Iter, | |
| 48 | sentinel_for<_Iter> _Sent, | |
| 49 | class _Proj = identity, | |
| 49 | 50 | indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less> |
| 50 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 51 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 52 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 52 | 53 | return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 53 | 54 | } |
| 54 | 55 | |
| 55 | template <random_access_range _Range, class _Proj = identity, | |
| 56 | template <random_access_range _Range, | |
| 57 | class _Proj = identity, | |
| 56 | 58 | indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 60 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | 61 | return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); |
| 60 | 62 | } |
| 61 | 63 | }; |
| ... | ... | @@ -63,12 +65,12 @@ struct __fn { |
| 63 | 65 | } // namespace __is_heap |
| 64 | 66 | |
| 65 | 67 | inline namespace __cpo { |
| 66 | inline constexpr auto is_heap = __is_heap::__fn{}; | |
| 68 | inline constexpr auto is_heap = __is_heap::__fn{}; | |
| 67 | 69 | } // namespace __cpo |
| 68 | 70 | } // namespace ranges |
| 69 | 71 | |
| 70 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 71 | 73 | |
| 72 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 73 | 75 | |
| 74 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H |
lib/libcxx/include/__algorithm/ranges_is_heap_until.h+15-14| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -35,41 +35,42 @@ namespace ranges { |
| 35 | 35 | namespace __is_heap_until { |
| 36 | 36 | |
| 37 | 37 | struct __fn { |
| 38 | ||
| 39 | 38 | template <class _Iter, class _Sent, class _Proj, class _Comp> |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 41 | static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 42 | auto __last_iter = ranges::next(__first, __last); | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 40 | __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 41 | auto __last_iter = ranges::next(__first, __last); | |
| 43 | 42 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| 44 | 43 | |
| 45 | 44 | return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); |
| 46 | 45 | } |
| 47 | 46 | |
| 48 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 47 | template <random_access_iterator _Iter, | |
| 48 | sentinel_for<_Iter> _Sent, | |
| 49 | class _Proj = identity, | |
| 49 | 50 | indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less> |
| 50 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 51 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 52 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 52 | 53 | return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 53 | 54 | } |
| 54 | 55 | |
| 55 | template <random_access_range _Range, class _Proj = identity, | |
| 56 | template <random_access_range _Range, | |
| 57 | class _Proj = identity, | |
| 56 | 58 | indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 60 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | 61 | return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); |
| 60 | 62 | } |
| 61 | ||
| 62 | 63 | }; |
| 63 | 64 | |
| 64 | 65 | } // namespace __is_heap_until |
| 65 | 66 | |
| 66 | 67 | inline namespace __cpo { |
| 67 | inline constexpr auto is_heap_until = __is_heap_until::__fn{}; | |
| 68 | inline constexpr auto is_heap_until = __is_heap_until::__fn{}; | |
| 68 | 69 | } // namespace __cpo |
| 69 | 70 | } // namespace ranges |
| 70 | 71 | |
| 71 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 73 | |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 75 | |
| 75 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H |
lib/libcxx/include/__algorithm/ranges_is_partitioned.h+13-13| ... | ... | @@ -23,17 +23,16 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | namespace ranges { |
| 31 | 31 | namespace __is_partitioned { |
| 32 | 32 | struct __fn { |
| 33 | ||
| 34 | 33 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 36 | bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr static bool | |
| 35 | __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 37 | 36 | for (; __first != __last; ++__first) { |
| 38 | 37 | if (!std::invoke(__pred, std::invoke(__proj, *__first))) |
| 39 | 38 | break; |
| ... | ... | @@ -51,31 +50,32 @@ struct __fn { |
| 51 | 50 | return true; |
| 52 | 51 | } |
| 53 | 52 | |
| 54 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 53 | template <input_iterator _Iter, | |
| 54 | sentinel_for<_Iter> _Sent, | |
| 55 | 55 | class _Proj = identity, |
| 56 | 56 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 59 | return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj); | |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 58 | operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 59 | return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | template <input_range _Range, |
| 63 | 63 | class _Proj = identity, |
| 64 | 64 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 65 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 66 | bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 67 | return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); | |
| 65 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 66 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 67 | return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); | |
| 68 | 68 | } |
| 69 | 69 | }; |
| 70 | 70 | } // namespace __is_partitioned |
| 71 | 71 | |
| 72 | 72 | inline namespace __cpo { |
| 73 | inline constexpr auto is_partitioned = __is_partitioned::__fn{}; | |
| 73 | inline constexpr auto is_partitioned = __is_partitioned::__fn{}; | |
| 74 | 74 | } // namespace __cpo |
| 75 | 75 | } // namespace ranges |
| 76 | 76 | |
| 77 | 77 | _LIBCPP_END_NAMESPACE_STD |
| 78 | 78 | |
| 79 | #endif // _LIBCPP_STD_VER > 17 | |
| 79 | #endif // _LIBCPP_STD_VER >= 20 | |
| 80 | 80 | |
| 81 | 81 | #endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H |
lib/libcxx/include/__algorithm/ranges_is_permutation.h+43-30| ... | ... | @@ -25,65 +25,78 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | namespace __is_permutation { |
| 34 | 34 | struct __fn { |
| 35 | ||
| 36 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, | |
| 37 | class _Proj1, class _Proj2, class _Pred> | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 39 | bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, | |
| 40 | _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { | |
| 35 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Pred> | |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl( | |
| 37 | _Iter1 __first1, | |
| 38 | _Sent1 __last1, | |
| 39 | _Iter2 __first2, | |
| 40 | _Sent2 __last2, | |
| 41 | _Pred& __pred, | |
| 42 | _Proj1& __proj1, | |
| 43 | _Proj2& __proj2) { | |
| 41 | 44 | return std::__is_permutation<_RangeAlgPolicy>( |
| 42 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), | |
| 43 | __pred, __proj1, __proj2); | |
| 45 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); | |
| 44 | 46 | } |
| 45 | 47 | |
| 46 | template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 47 | forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 48 | class _Proj1 = identity, | |
| 49 | class _Proj2 = identity, | |
| 50 | indirect_equivalence_relation<projected<_Iter1, _Proj1>, | |
| 51 | projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> | |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 53 | bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, | |
| 54 | _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 48 | template < | |
| 49 | forward_iterator _Iter1, | |
| 50 | sentinel_for<_Iter1> _Sent1, | |
| 51 | forward_iterator _Iter2, | |
| 52 | sentinel_for<_Iter2> _Sent2, | |
| 53 | class _Proj1 = identity, | |
| 54 | class _Proj2 = identity, | |
| 55 | indirect_equivalence_relation<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> | |
| 56 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 57 | _Iter1 __first1, | |
| 58 | _Sent1 __last1, | |
| 59 | _Iter2 __first2, | |
| 60 | _Sent2 __last2, | |
| 61 | _Pred __pred = {}, | |
| 62 | _Proj1 __proj1 = {}, | |
| 63 | _Proj2 __proj2 = {}) const { | |
| 55 | 64 | return __is_permutation_func_impl( |
| 56 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), | |
| 57 | __pred, __proj1, __proj2); | |
| 65 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); | |
| 58 | 66 | } |
| 59 | 67 | |
| 60 | 68 | template <forward_range _Range1, |
| 61 | 69 | forward_range _Range2, |
| 62 | class _Proj1 = identity, | |
| 63 | class _Proj2 = identity, | |
| 64 | indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to> | |
| 65 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 66 | bool operator()(_Range1&& __range1, _Range2&& __range2, | |
| 67 | _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 70 | class _Proj1 = identity, | |
| 71 | class _Proj2 = identity, | |
| 72 | indirect_equivalence_relation<projected<iterator_t<_Range1>, _Proj1>, | |
| 73 | projected<iterator_t<_Range2>, _Proj2>> _Pred = ranges::equal_to> | |
| 74 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 75 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 68 | 76 | if constexpr (sized_range<_Range1> && sized_range<_Range2>) { |
| 69 | 77 | if (ranges::distance(__range1) != ranges::distance(__range2)) |
| 70 | 78 | return false; |
| 71 | 79 | } |
| 72 | 80 | |
| 73 | 81 | return __is_permutation_func_impl( |
| 74 | ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2), | |
| 75 | __pred, __proj1, __proj2); | |
| 82 | ranges::begin(__range1), | |
| 83 | ranges::end(__range1), | |
| 84 | ranges::begin(__range2), | |
| 85 | ranges::end(__range2), | |
| 86 | __pred, | |
| 87 | __proj1, | |
| 88 | __proj2); | |
| 76 | 89 | } |
| 77 | 90 | }; |
| 78 | 91 | } // namespace __is_permutation |
| 79 | 92 | |
| 80 | 93 | inline namespace __cpo { |
| 81 | inline constexpr auto is_permutation = __is_permutation::__fn{}; | |
| 94 | inline constexpr auto is_permutation = __is_permutation::__fn{}; | |
| 82 | 95 | } // namespace __cpo |
| 83 | 96 | } // namespace ranges |
| 84 | 97 | |
| 85 | 98 | _LIBCPP_END_NAMESPACE_STD |
| 86 | 99 | |
| 87 | #endif // _LIBCPP_STD_VER > 17 | |
| 100 | #endif // _LIBCPP_STD_VER >= 20 | |
| 88 | 101 | |
| 89 | 102 | #endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H |
lib/libcxx/include/__algorithm/ranges_is_sorted.h+11-10| ... | ... | @@ -23,26 +23,27 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | namespace ranges { |
| 31 | 31 | namespace __is_sorted { |
| 32 | 32 | struct __fn { |
| 33 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 34 | class _Proj = identity, | |
| 33 | template <forward_iterator _Iter, | |
| 34 | sentinel_for<_Iter> _Sent, | |
| 35 | class _Proj = identity, | |
| 35 | 36 | indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less> |
| 36 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 37 | bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 37 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 38 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 38 | 39 | return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; |
| 39 | 40 | } |
| 40 | 41 | |
| 41 | 42 | template <forward_range _Range, |
| 42 | class _Proj = identity, | |
| 43 | class _Proj = identity, | |
| 43 | 44 | indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 44 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 45 | bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 46 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 46 | 47 | auto __last = ranges::end(__range); |
| 47 | 48 | return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; |
| 48 | 49 | } |
| ... | ... | @@ -50,12 +51,12 @@ struct __fn { |
| 50 | 51 | } // namespace __is_sorted |
| 51 | 52 | |
| 52 | 53 | inline namespace __cpo { |
| 53 | inline constexpr auto is_sorted = __is_sorted::__fn{}; | |
| 54 | inline constexpr auto is_sorted = __is_sorted::__fn{}; | |
| 54 | 55 | } // namespace __cpo |
| 55 | 56 | } // namespace ranges |
| 56 | 57 | |
| 57 | 58 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 59 | |
| 59 | #endif // _LIBCPP_STD_VER > 17 | |
| 60 | #endif // _LIBCPP_STD_VER >= 20 | |
| 60 | 61 | |
| 61 | 62 | #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H |
lib/libcxx/include/__algorithm/ranges_is_sorted_until.h+13-12| ... | ... | @@ -24,15 +24,15 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | |
| 33 | 33 | template <class _Iter, class _Sent, class _Proj, class _Comp> |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 35 | _Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 35 | __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 36 | 36 | if (__first == __last) |
| 37 | 37 | return __first; |
| 38 | 38 | auto __i = __first; |
| ... | ... | @@ -46,31 +46,32 @@ _Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& |
| 46 | 46 | |
| 47 | 47 | namespace __is_sorted_until { |
| 48 | 48 | struct __fn { |
| 49 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 50 | class _Proj = identity, | |
| 49 | template <forward_iterator _Iter, | |
| 50 | sentinel_for<_Iter> _Sent, | |
| 51 | class _Proj = identity, | |
| 51 | 52 | indirect_strict_weak_order<projected<_Iter, _Proj>> _Comp = ranges::less> |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 53 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 54 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 54 | 55 | return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 55 | 56 | } |
| 56 | 57 | |
| 57 | 58 | template <forward_range _Range, |
| 58 | class _Proj = identity, | |
| 59 | class _Proj = identity, | |
| 59 | 60 | indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 61 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 61 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 62 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 62 | 63 | return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); |
| 63 | 64 | } |
| 64 | 65 | }; |
| 65 | 66 | } // namespace __is_sorted_until |
| 66 | 67 | |
| 67 | 68 | inline namespace __cpo { |
| 68 | inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; | |
| 69 | inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; | |
| 69 | 70 | } // namespace __cpo |
| 70 | 71 | } // namespace ranges |
| 71 | 72 | |
| 72 | 73 | _LIBCPP_END_NAMESPACE_STD |
| 73 | 74 | |
| 74 | #endif // _LIBCPP_STD_VER > 17 | |
| 75 | #endif // _LIBCPP_STD_VER >= 20 | |
| 75 | 76 | |
| 76 | 77 | #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H |
lib/libcxx/include/__algorithm/ranges_iterator_concept.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -46,6 +46,6 @@ using __iterator_concept = decltype(__get_iterator_concept<_Iter>()); |
| 46 | 46 | } // namespace ranges |
| 47 | 47 | _LIBCPP_END_NAMESPACE_STD |
| 48 | 48 | |
| 49 | #endif // _LIBCPP_STD_VER > 17 | |
| 49 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | 50 | |
| 51 | 51 | #endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H |
lib/libcxx/include/__algorithm/ranges_lexicographical_compare.h+40-37| ... | ... | @@ -23,24 +23,24 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | namespace ranges { |
| 31 | 31 | namespace __lexicographical_compare { |
| 32 | 32 | struct __fn { |
| 33 | ||
| 34 | 33 | template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp> |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 36 | bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1, | |
| 37 | _Iter2 __first2, _Sent2 __last2, | |
| 38 | _Comp& __comp, | |
| 39 | _Proj1& __proj1, | |
| 40 | _Proj2& __proj2) { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr static bool __lexicographical_compare_impl( | |
| 35 | _Iter1 __first1, | |
| 36 | _Sent1 __last1, | |
| 37 | _Iter2 __first2, | |
| 38 | _Sent2 __last2, | |
| 39 | _Comp& __comp, | |
| 40 | _Proj1& __proj1, | |
| 41 | _Proj2& __proj2) { | |
| 41 | 42 | while (__first2 != __last2) { |
| 42 | if (__first1 == __last1 | |
| 43 | || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) | |
| 43 | if (__first1 == __last1 || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) | |
| 44 | 44 | return true; |
| 45 | 45 | if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) |
| 46 | 46 | return false; |
| ... | ... | @@ -50,49 +50,52 @@ struct __fn { |
| 50 | 50 | return false; |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 54 | input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 55 | class _Proj1 = identity, | |
| 56 | class _Proj2 = identity, | |
| 53 | template <input_iterator _Iter1, | |
| 54 | sentinel_for<_Iter1> _Sent1, | |
| 55 | input_iterator _Iter2, | |
| 56 | sentinel_for<_Iter2> _Sent2, | |
| 57 | class _Proj1 = identity, | |
| 58 | class _Proj2 = identity, | |
| 57 | 59 | indirect_strict_weak_order<projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> _Comp = ranges::less> |
| 58 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 59 | bool operator()(_Iter1 __first1, _Sent1 __last1, | |
| 60 | _Iter2 __first2, _Sent2 __last2, | |
| 61 | _Comp __comp = {}, | |
| 62 | _Proj1 __proj1 = {}, | |
| 63 | _Proj2 __proj2 = {}) const { | |
| 64 | return __lexicographical_compare_impl(std::move(__first1), std::move(__last1), | |
| 65 | std::move(__first2), std::move(__last2), | |
| 66 | __comp, | |
| 67 | __proj1, | |
| 68 | __proj2); | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 61 | _Iter1 __first1, | |
| 62 | _Sent1 __last1, | |
| 63 | _Iter2 __first2, | |
| 64 | _Sent2 __last2, | |
| 65 | _Comp __comp = {}, | |
| 66 | _Proj1 __proj1 = {}, | |
| 67 | _Proj2 __proj2 = {}) const { | |
| 68 | return __lexicographical_compare_impl( | |
| 69 | std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __comp, __proj1, __proj2); | |
| 69 | 70 | } |
| 70 | 71 | |
| 71 | 72 | template <input_range _Range1, |
| 72 | 73 | input_range _Range2, |
| 73 | 74 | class _Proj1 = identity, |
| 74 | 75 | class _Proj2 = identity, |
| 75 | indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, | |
| 76 | projected<iterator_t<_Range2>, _Proj2>> _Comp = ranges::less> | |
| 77 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 78 | bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 79 | return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1), | |
| 80 | ranges::begin(__range2), ranges::end(__range2), | |
| 81 | __comp, | |
| 82 | __proj1, | |
| 83 | __proj2); | |
| 76 | indirect_strict_weak_order<projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>> | |
| 77 | _Comp = ranges::less> | |
| 78 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 79 | _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 80 | return __lexicographical_compare_impl( | |
| 81 | ranges::begin(__range1), | |
| 82 | ranges::end(__range1), | |
| 83 | ranges::begin(__range2), | |
| 84 | ranges::end(__range2), | |
| 85 | __comp, | |
| 86 | __proj1, | |
| 87 | __proj2); | |
| 84 | 88 | } |
| 85 | ||
| 86 | 89 | }; |
| 87 | 90 | } // namespace __lexicographical_compare |
| 88 | 91 | |
| 89 | 92 | inline namespace __cpo { |
| 90 | inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; | |
| 93 | inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; | |
| 91 | 94 | } // namespace __cpo |
| 92 | 95 | } // namespace ranges |
| 93 | 96 | |
| 94 | 97 | _LIBCPP_END_NAMESPACE_STD |
| 95 | 98 | |
| 96 | #endif // _LIBCPP_STD_VER > 17 | |
| 99 | #endif // _LIBCPP_STD_VER >= 20 | |
| 97 | 100 | |
| 98 | 101 | #endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H |
lib/libcxx/include/__algorithm/ranges_lower_bound.h+16-14| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -35,32 +35,34 @@ namespace ranges { |
| 35 | 35 | |
| 36 | 36 | namespace __lower_bound { |
| 37 | 37 | struct __fn { |
| 38 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity, | |
| 38 | template <forward_iterator _Iter, | |
| 39 | sentinel_for<_Iter> _Sent, | |
| 40 | class _Type, | |
| 41 | class _Proj = identity, | |
| 39 | 42 | indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less> |
| 40 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 41 | _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 42 | return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 43 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 44 | operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 45 | return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); | |
| 43 | 46 | } |
| 44 | 47 | |
| 45 | template <forward_range _Range, class _Type, class _Proj = identity, | |
| 48 | template <forward_range _Range, | |
| 49 | class _Type, | |
| 50 | class _Proj = identity, | |
| 46 | 51 | indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 47 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 48 | borrowed_iterator_t<_Range> operator()(_Range&& __r, | |
| 49 | const _Type& __value, | |
| 50 | _Comp __comp = {}, | |
| 51 | _Proj __proj = {}) const { | |
| 52 | return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); | |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 53 | operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 54 | return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); | |
| 53 | 55 | } |
| 54 | 56 | }; |
| 55 | 57 | } // namespace __lower_bound |
| 56 | 58 | |
| 57 | 59 | inline namespace __cpo { |
| 58 | inline constexpr auto lower_bound = __lower_bound::__fn{}; | |
| 60 | inline constexpr auto lower_bound = __lower_bound::__fn{}; | |
| 59 | 61 | } // namespace __cpo |
| 60 | 62 | } // namespace ranges |
| 61 | 63 | |
| 62 | 64 | _LIBCPP_END_NAMESPACE_STD |
| 63 | 65 | |
| 64 | #endif // _LIBCPP_STD_VER > 17 | |
| 66 | #endif // _LIBCPP_STD_VER >= 20 | |
| 65 | 67 | |
| 66 | 68 | #endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H |
lib/libcxx/include/__algorithm/ranges_make_heap.h+9-9| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | # pragma GCC system_header |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 38 | |
| ... | ... | @@ -41,8 +41,8 @@ namespace __make_heap { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | 43 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 45 | _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 45 | __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 46 | 46 | auto __last_iter = ranges::next(__first, __last); |
| 47 | 47 | |
| 48 | 48 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -53,15 +53,15 @@ struct __fn { |
| 53 | 53 | |
| 54 | 54 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 55 | 55 | requires sortable<_Iter, _Comp, _Proj> |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 57 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 57 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 58 | 58 | return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 62 | 62 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 64 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 64 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 65 | 65 | return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 66 | 66 | } |
| 67 | 67 | }; |
| ... | ... | @@ -69,12 +69,12 @@ struct __fn { |
| 69 | 69 | } // namespace __make_heap |
| 70 | 70 | |
| 71 | 71 | inline namespace __cpo { |
| 72 | inline constexpr auto make_heap = __make_heap::__fn{}; | |
| 72 | inline constexpr auto make_heap = __make_heap::__fn{}; | |
| 73 | 73 | } // namespace __cpo |
| 74 | 74 | } // namespace ranges |
| 75 | 75 | |
| 76 | 76 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 77 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 78 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 79 | |
| 80 | 80 | #endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H |
lib/libcxx/include/__algorithm/ranges_max.h+24-17| ... | ... | @@ -20,6 +20,7 @@ |
| 20 | 20 | #include <__iterator/projected.h> |
| 21 | 21 | #include <__ranges/access.h> |
| 22 | 22 | #include <__ranges/concepts.h> |
| 23 | #include <__type_traits/is_trivially_copyable.h> | |
| 23 | 24 | #include <__utility/move.h> |
| 24 | 25 | #include <initializer_list> |
| 25 | 26 | |
| ... | ... | @@ -27,44 +28,50 @@ |
| 27 | 28 | # pragma GCC system_header |
| 28 | 29 | #endif |
| 29 | 30 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 32 | |
| 32 | 33 | _LIBCPP_PUSH_MACROS |
| 33 | #include <__undef_macros> | |
| 34 | # include <__undef_macros> | |
| 34 | 35 | |
| 35 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 37 | |
| 37 | 38 | namespace ranges { |
| 38 | 39 | namespace __max { |
| 39 | 40 | struct __fn { |
| 40 | template <class _Tp, class _Proj = identity, | |
| 41 | template <class _Tp, | |
| 42 | class _Proj = identity, | |
| 41 | 43 | indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less> |
| 42 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 43 | const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 44 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& | |
| 45 | operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, | |
| 46 | _LIBCPP_LIFETIMEBOUND const _Tp& __b, | |
| 47 | _Comp __comp = {}, | |
| 48 | _Proj __proj = {}) const { | |
| 44 | 49 | return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a; |
| 45 | 50 | } |
| 46 | 51 | |
| 47 | template <copyable _Tp, class _Proj = identity, | |
| 52 | template <copyable _Tp, | |
| 53 | class _Proj = identity, | |
| 48 | 54 | indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less> |
| 49 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 50 | _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 51 | _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); | |
| 55 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp | |
| 56 | operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 57 | _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element"); | |
| 52 | 58 | |
| 53 | 59 | auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; |
| 54 | 60 | return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj); |
| 55 | 61 | } |
| 56 | 62 | |
| 57 | template <input_range _Rp, class _Proj = identity, | |
| 63 | template <input_range _Rp, | |
| 64 | class _Proj = identity, | |
| 58 | 65 | indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> |
| 59 | 66 | requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*> |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 61 | range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 67 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> | |
| 68 | operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 62 | 69 | auto __first = ranges::begin(__r); |
| 63 | auto __last = ranges::end(__r); | |
| 70 | auto __last = ranges::end(__r); | |
| 64 | 71 | |
| 65 | _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); | |
| 72 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element"); | |
| 66 | 73 | |
| 67 | if constexpr (forward_range<_Rp>) { | |
| 74 | if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) { | |
| 68 | 75 | auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; |
| 69 | 76 | return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj); |
| 70 | 77 | } else { |
| ... | ... | @@ -80,7 +87,7 @@ struct __fn { |
| 80 | 87 | } // namespace __max |
| 81 | 88 | |
| 82 | 89 | inline namespace __cpo { |
| 83 | inline constexpr auto max = __max::__fn{}; | |
| 90 | inline constexpr auto max = __max::__fn{}; | |
| 84 | 91 | } // namespace __cpo |
| 85 | 92 | } // namespace ranges |
| 86 | 93 | |
| ... | ... | @@ -88,6 +95,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 88 | 95 | |
| 89 | 96 | _LIBCPP_POP_MACROS |
| 90 | 97 | |
| 91 | #endif // _LIBCPP_STD_VER > 17 && | |
| 98 | #endif // _LIBCPP_STD_VER >= 20 && | |
| 92 | 99 | |
| 93 | 100 | #endif // _LIBCPP___ALGORITHM_RANGES_MAX_H |
lib/libcxx/include/__algorithm/ranges_max_element.h+12-9| ... | ... | @@ -24,25 +24,28 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | namespace __max_element { |
| 33 | 33 | struct __fn { |
| 34 | template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, | |
| 34 | template <forward_iterator _Ip, | |
| 35 | sentinel_for<_Ip> _Sp, | |
| 36 | class _Proj = identity, | |
| 35 | 37 | indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less> |
| 36 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 37 | _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip | |
| 39 | operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 38 | 40 | auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; |
| 39 | 41 | return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); |
| 40 | 42 | } |
| 41 | 43 | |
| 42 | template <forward_range _Rp, class _Proj = identity, | |
| 44 | template <forward_range _Rp, | |
| 45 | class _Proj = identity, | |
| 43 | 46 | indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> |
| 44 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 45 | borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 47 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> | |
| 48 | operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 46 | 49 | auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; |
| 47 | 50 | return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); |
| 48 | 51 | } |
| ... | ... | @@ -50,12 +53,12 @@ struct __fn { |
| 50 | 53 | } // namespace __max_element |
| 51 | 54 | |
| 52 | 55 | inline namespace __cpo { |
| 53 | inline constexpr auto max_element = __max_element::__fn{}; | |
| 56 | inline constexpr auto max_element = __max_element::__fn{}; | |
| 54 | 57 | } // namespace __cpo |
| 55 | 58 | } // namespace ranges |
| 56 | 59 | |
| 57 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 61 | |
| 59 | #endif // _LIBCPP_STD_VER > 17 | |
| 62 | #endif // _LIBCPP_STD_VER >= 20 | |
| 60 | 63 | |
| 61 | 64 | #endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H |
lib/libcxx/include/__algorithm/ranges_merge.h+44-53| ... | ... | @@ -20,14 +20,14 @@ |
| 20 | 20 | #include <__ranges/access.h> |
| 21 | 21 | #include <__ranges/concepts.h> |
| 22 | 22 | #include <__ranges/dangling.h> |
| 23 | #include <__type_traits/remove_cvref.h> | |
| 23 | 24 | #include <__utility/move.h> |
| 24 | #include <type_traits> | |
| 25 | 25 | |
| 26 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -38,25 +38,25 @@ using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; |
| 38 | 38 | |
| 39 | 39 | namespace __merge { |
| 40 | 40 | |
| 41 | template < | |
| 42 | class _InIter1, | |
| 43 | class _Sent1, | |
| 44 | class _InIter2, | |
| 45 | class _Sent2, | |
| 46 | class _OutIter, | |
| 47 | class _Comp, | |
| 48 | class _Proj1, | |
| 49 | class _Proj2> | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>> | |
| 51 | __merge_impl( | |
| 52 | _InIter1&& __first1, | |
| 53 | _Sent1&& __last1, | |
| 54 | _InIter2&& __first2, | |
| 55 | _Sent2&& __last2, | |
| 56 | _OutIter&& __result, | |
| 57 | _Comp&& __comp, | |
| 58 | _Proj1&& __proj1, | |
| 59 | _Proj2&& __proj2) { | |
| 41 | template < class _InIter1, | |
| 42 | class _Sent1, | |
| 43 | class _InIter2, | |
| 44 | class _Sent2, | |
| 45 | class _OutIter, | |
| 46 | class _Comp, | |
| 47 | class _Proj1, | |
| 48 | class _Proj2> | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, | |
| 50 | __remove_cvref_t<_InIter2>, | |
| 51 | __remove_cvref_t<_OutIter>> | |
| 52 | __merge_impl(_InIter1&& __first1, | |
| 53 | _Sent1&& __last1, | |
| 54 | _InIter2&& __first2, | |
| 55 | _Sent2&& __last2, | |
| 56 | _OutIter&& __result, | |
| 57 | _Comp&& __comp, | |
| 58 | _Proj1&& __proj1, | |
| 59 | _Proj2&& __proj2) { | |
| 60 | 60 | for (; __first1 != __last1 && __first2 != __last2; ++__result) { |
| 61 | 61 | if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) { |
| 62 | 62 | *__result = *__first2; |
| ... | ... | @@ -72,15 +72,14 @@ __merge_impl( |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | struct __fn { |
| 75 | template < | |
| 76 | input_iterator _InIter1, | |
| 77 | sentinel_for<_InIter1> _Sent1, | |
| 78 | input_iterator _InIter2, | |
| 79 | sentinel_for<_InIter2> _Sent2, | |
| 80 | weakly_incrementable _OutIter, | |
| 81 | class _Comp = less, | |
| 82 | class _Proj1 = identity, | |
| 83 | class _Proj2 = identity> | |
| 75 | template <input_iterator _InIter1, | |
| 76 | sentinel_for<_InIter1> _Sent1, | |
| 77 | input_iterator _InIter2, | |
| 78 | sentinel_for<_InIter2> _Sent2, | |
| 79 | weakly_incrementable _OutIter, | |
| 80 | class _Comp = less, | |
| 81 | class _Proj1 = identity, | |
| 82 | class _Proj2 = identity> | |
| 84 | 83 | requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> |
| 85 | 84 | _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()( |
| 86 | 85 | _InIter1 __first1, |
| ... | ... | @@ -94,28 +93,20 @@ struct __fn { |
| 94 | 93 | return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2); |
| 95 | 94 | } |
| 96 | 95 | |
| 97 | template < | |
| 98 | input_range _Range1, | |
| 99 | input_range _Range2, | |
| 100 | weakly_incrementable _OutIter, | |
| 101 | class _Comp = less, | |
| 102 | class _Proj1 = identity, | |
| 103 | class _Proj2 = identity> | |
| 104 | requires mergeable< | |
| 105 | iterator_t<_Range1>, | |
| 106 | iterator_t<_Range2>, | |
| 107 | _OutIter, | |
| 108 | _Comp, | |
| 109 | _Proj1, | |
| 110 | _Proj2> | |
| 96 | template <input_range _Range1, | |
| 97 | input_range _Range2, | |
| 98 | weakly_incrementable _OutIter, | |
| 99 | class _Comp = less, | |
| 100 | class _Proj1 = identity, | |
| 101 | class _Proj2 = identity> | |
| 102 | requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> | |
| 111 | 103 | _LIBCPP_HIDE_FROM_ABI constexpr merge_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter> |
| 112 | operator()( | |
| 113 | _Range1&& __range1, | |
| 114 | _Range2&& __range2, | |
| 115 | _OutIter __result, | |
| 116 | _Comp __comp = {}, | |
| 117 | _Proj1 __proj1 = {}, | |
| 118 | _Proj2 __proj2 = {}) const { | |
| 104 | operator()(_Range1&& __range1, | |
| 105 | _Range2&& __range2, | |
| 106 | _OutIter __result, | |
| 107 | _Comp __comp = {}, | |
| 108 | _Proj1 __proj1 = {}, | |
| 109 | _Proj2 __proj2 = {}) const { | |
| 119 | 110 | return __merge::__merge_impl( |
| 120 | 111 | ranges::begin(__range1), |
| 121 | 112 | ranges::end(__range1), |
| ... | ... | @@ -131,12 +122,12 @@ struct __fn { |
| 131 | 122 | } // namespace __merge |
| 132 | 123 | |
| 133 | 124 | inline namespace __cpo { |
| 134 | inline constexpr auto merge = __merge::__fn{}; | |
| 125 | inline constexpr auto merge = __merge::__fn{}; | |
| 135 | 126 | } // namespace __cpo |
| 136 | 127 | } // namespace ranges |
| 137 | 128 | |
| 138 | 129 | _LIBCPP_END_NAMESPACE_STD |
| 139 | 130 | |
| 140 | #endif // _LIBCPP_STD_VER > 17 | |
| 131 | #endif // _LIBCPP_STD_VER >= 20 | |
| 141 | 132 | |
| 142 | 133 | #endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H |
lib/libcxx/include/__algorithm/ranges_min.h+24-19| ... | ... | @@ -20,48 +20,53 @@ |
| 20 | 20 | #include <__iterator/projected.h> |
| 21 | 21 | #include <__ranges/access.h> |
| 22 | 22 | #include <__ranges/concepts.h> |
| 23 | #include <__type_traits/is_trivially_copyable.h> | |
| 23 | 24 | #include <initializer_list> |
| 24 | 25 | |
| 25 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 27 | # pragma GCC system_header |
| 27 | 28 | #endif |
| 28 | 29 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 31 | |
| 31 | 32 | _LIBCPP_PUSH_MACROS |
| 32 | #include <__undef_macros> | |
| 33 | # include <__undef_macros> | |
| 33 | 34 | |
| 34 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 36 | |
| 36 | 37 | namespace ranges { |
| 37 | 38 | namespace __min { |
| 38 | 39 | struct __fn { |
| 39 | template <class _Tp, class _Proj = identity, | |
| 40 | template <class _Tp, | |
| 41 | class _Proj = identity, | |
| 40 | 42 | indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less> |
| 41 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 42 | const _Tp& operator()(const _Tp& __a, const _Tp& __b, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 43 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& | |
| 44 | operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, | |
| 45 | _LIBCPP_LIFETIMEBOUND const _Tp& __b, | |
| 46 | _Comp __comp = {}, | |
| 47 | _Proj __proj = {}) const { | |
| 43 | 48 | return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a; |
| 44 | 49 | } |
| 45 | 50 | |
| 46 | template <copyable _Tp, class _Proj = identity, | |
| 51 | template <copyable _Tp, | |
| 52 | class _Proj = identity, | |
| 47 | 53 | indirect_strict_weak_order<projected<const _Tp*, _Proj>> _Comp = ranges::less> |
| 48 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 49 | _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 50 | _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); | |
| 54 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp | |
| 55 | operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 56 | _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list must contain at least one element"); | |
| 51 | 57 | return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj); |
| 52 | 58 | } |
| 53 | 59 | |
| 54 | template <input_range _Rp, class _Proj = identity, | |
| 60 | template <input_range _Rp, | |
| 61 | class _Proj = identity, | |
| 55 | 62 | indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> |
| 56 | 63 | requires indirectly_copyable_storable<iterator_t<_Rp>, range_value_t<_Rp>*> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 64 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> | |
| 65 | operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | 66 | auto __first = ranges::begin(__r); |
| 60 | auto __last = ranges::end(__r); | |
| 61 | ||
| 62 | _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); | |
| 63 | ||
| 64 | if constexpr (forward_range<_Rp>) { | |
| 67 | auto __last = ranges::end(__r); | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range must contain at least one element"); | |
| 69 | if constexpr (forward_range<_Rp> && !__is_cheap_to_copy<range_value_t<_Rp>>) { | |
| 65 | 70 | return *ranges::__min_element_impl(__first, __last, __comp, __proj); |
| 66 | 71 | } else { |
| 67 | 72 | range_value_t<_Rp> __result = *__first; |
| ... | ... | @@ -76,7 +81,7 @@ struct __fn { |
| 76 | 81 | } // namespace __min |
| 77 | 82 | |
| 78 | 83 | inline namespace __cpo { |
| 79 | inline constexpr auto min = __min::__fn{}; | |
| 84 | inline constexpr auto min = __min::__fn{}; | |
| 80 | 85 | } // namespace __cpo |
| 81 | 86 | } // namespace ranges |
| 82 | 87 | |
| ... | ... | @@ -84,6 +89,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 84 | 89 | |
| 85 | 90 | _LIBCPP_POP_MACROS |
| 86 | 91 | |
| 87 | #endif // _LIBCPP_STD_VER > 17 && | |
| 92 | #endif // _LIBCPP_STD_VER >= 20 && | |
| 88 | 93 | |
| 89 | 94 | #endif // _LIBCPP___ALGORITHM_RANGES_MIN_H |
lib/libcxx/include/__algorithm/ranges_min_element.h+13-11| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -32,8 +32,7 @@ namespace ranges { |
| 32 | 32 | |
| 33 | 33 | // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. |
| 34 | 34 | template <class _Ip, class _Sp, class _Proj, class _Comp> |
| 35 | _LIBCPP_HIDE_FROM_ABI static constexpr | |
| 36 | _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { | |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { | |
| 37 | 36 | if (__first == __last) |
| 38 | 37 | return __first; |
| 39 | 38 | |
| ... | ... | @@ -46,29 +45,32 @@ _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { |
| 46 | 45 | |
| 47 | 46 | namespace __min_element { |
| 48 | 47 | struct __fn { |
| 49 | template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, | |
| 48 | template <forward_iterator _Ip, | |
| 49 | sentinel_for<_Ip> _Sp, | |
| 50 | class _Proj = identity, | |
| 50 | 51 | indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less> |
| 51 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 52 | _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Ip | |
| 53 | operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 53 | 54 | return ranges::__min_element_impl(__first, __last, __comp, __proj); |
| 54 | 55 | } |
| 55 | 56 | |
| 56 | template <forward_range _Rp, class _Proj = identity, | |
| 57 | template <forward_range _Rp, | |
| 58 | class _Proj = identity, | |
| 57 | 59 | indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> |
| 58 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 59 | borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> | |
| 61 | operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 60 | 62 | return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 61 | 63 | } |
| 62 | 64 | }; |
| 63 | 65 | } // namespace __min_element |
| 64 | 66 | |
| 65 | 67 | inline namespace __cpo { |
| 66 | inline constexpr auto min_element = __min_element::__fn{}; | |
| 68 | inline constexpr auto min_element = __min_element::__fn{}; | |
| 67 | 69 | } // namespace __cpo |
| 68 | 70 | } // namespace ranges |
| 69 | 71 | |
| 70 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 71 | 73 | |
| 72 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 73 | 75 | |
| 74 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H |
lib/libcxx/include/__algorithm/ranges_minmax.h+44-19| ... | ... | @@ -13,14 +13,18 @@ |
| 13 | 13 | #include <__algorithm/minmax_element.h> |
| 14 | 14 | #include <__assert> |
| 15 | 15 | #include <__concepts/copyable.h> |
| 16 | #include <__concepts/same_as.h> | |
| 16 | 17 | #include <__config> |
| 17 | 18 | #include <__functional/identity.h> |
| 18 | 19 | #include <__functional/invoke.h> |
| 19 | 20 | #include <__functional/ranges_operations.h> |
| 20 | 21 | #include <__iterator/concepts.h> |
| 22 | #include <__iterator/next.h> | |
| 21 | 23 | #include <__iterator/projected.h> |
| 22 | 24 | #include <__ranges/access.h> |
| 23 | 25 | #include <__ranges/concepts.h> |
| 26 | #include <__type_traits/is_reference.h> | |
| 27 | #include <__type_traits/remove_cvref.h> | |
| 24 | 28 | #include <__utility/forward.h> |
| 25 | 29 | #include <__utility/move.h> |
| 26 | 30 | #include <__utility/pair.h> |
| ... | ... | @@ -30,10 +34,10 @@ |
| 30 | 34 | # pragma GCC system_header |
| 31 | 35 | #endif |
| 32 | 36 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 38 | |
| 35 | 39 | _LIBCPP_PUSH_MACROS |
| 36 | #include <__undef_macros> | |
| 40 | # include <__undef_macros> | |
| 37 | 41 | |
| 38 | 42 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 43 | |
| ... | ... | @@ -43,46 +47,67 @@ using minmax_result = min_max_result<_T1>; |
| 43 | 47 | |
| 44 | 48 | namespace __minmax { |
| 45 | 49 | struct __fn { |
| 46 | template <class _Type, class _Proj = identity, | |
| 50 | template <class _Type, | |
| 51 | class _Proj = identity, | |
| 47 | 52 | indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> |
| 48 | 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<const _Type&> |
| 49 | operator()(const _Type& __a, const _Type& __b, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 54 | operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a, | |
| 55 | _LIBCPP_LIFETIMEBOUND const _Type& __b, | |
| 56 | _Comp __comp = {}, | |
| 57 | _Proj __proj = {}) const { | |
| 50 | 58 | if (std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a))) |
| 51 | 59 | return {__b, __a}; |
| 52 | 60 | return {__a, __b}; |
| 53 | 61 | } |
| 54 | 62 | |
| 55 | template <copyable _Type, class _Proj = identity, | |
| 63 | template <copyable _Type, | |
| 64 | class _Proj = identity, | |
| 56 | 65 | indirect_strict_weak_order<projected<const _Type*, _Proj>> _Comp = ranges::less> |
| 57 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); | |
| 66 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> | |
| 67 | operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); | |
| 60 | 69 | auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj); |
| 61 | return ranges::minmax_result<_Type> { *__iters.first, *__iters.second }; | |
| 70 | return ranges::minmax_result<_Type>{*__iters.first, *__iters.second}; | |
| 62 | 71 | } |
| 63 | 72 | |
| 64 | template <input_range _Range, class _Proj = identity, | |
| 73 | template <input_range _Range, | |
| 74 | class _Proj = identity, | |
| 65 | 75 | indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 66 | 76 | requires indirectly_copyable_storable<iterator_t<_Range>, range_value_t<_Range>*> |
| 67 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 68 | ranges::minmax_result<range_value_t<_Range>> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 69 | auto __first = ranges::begin(__r); | |
| 70 | auto __last = ranges::end(__r); | |
| 77 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<range_value_t<_Range>> | |
| 78 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 79 | auto __first = ranges::begin(__r); | |
| 80 | auto __last = ranges::end(__r); | |
| 71 | 81 | using _ValueT = range_value_t<_Range>; |
| 72 | 82 | |
| 73 | _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element"); | |
| 83 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range has to contain at least one element"); | |
| 74 | 84 | |
| 75 | 85 | if constexpr (forward_range<_Range>) { |
| 86 | // Special-case the one element case. Avoid repeatedly initializing objects from the result of an iterator | |
| 87 | // dereference when doing so might not be idempotent. The `if constexpr` avoids the extra branch in cases where | |
| 88 | // it's not needed. | |
| 89 | if constexpr (!same_as<remove_cvref_t<range_reference_t<_Range>>, _ValueT> || | |
| 90 | is_rvalue_reference_v<range_reference_t<_Range>>) { | |
| 91 | if (ranges::next(__first) == __last) { | |
| 92 | // During initialization, members are allowed to refer to already initialized members | |
| 93 | // (see http://eel.is/c++draft/dcl.init.aggr#6) | |
| 94 | minmax_result<_ValueT> __result = {*__first, __result.min}; | |
| 95 | return __result; | |
| 96 | } | |
| 97 | } | |
| 76 | 98 | auto __result = std::__minmax_element_impl(__first, __last, __comp, __proj); |
| 77 | 99 | return {*__result.first, *__result.second}; |
| 78 | 100 | } else { |
| 79 | 101 | // input_iterators can't be copied, so the implementation for input_iterators has to store |
| 80 | 102 | // the values instead of a pointer to the correct values |
| 81 | 103 | auto __less = [&](auto&& __a, auto&& __b) -> bool { |
| 82 | return std::invoke(__comp, std::invoke(__proj, std::forward<decltype(__a)>(__a)), | |
| 83 | std::invoke(__proj, std::forward<decltype(__b)>(__b))); | |
| 104 | return std::invoke(__comp, | |
| 105 | std::invoke(__proj, std::forward<decltype(__a)>(__a)), | |
| 106 | std::invoke(__proj, std::forward<decltype(__b)>(__b))); | |
| 84 | 107 | }; |
| 85 | 108 | |
| 109 | // During initialization, members are allowed to refer to already initialized members | |
| 110 | // (see http://eel.is/c++draft/dcl.init.aggr#6) | |
| 86 | 111 | ranges::minmax_result<_ValueT> __result = {*__first, __result.min}; |
| 87 | 112 | if (__first == __last || ++__first == __last) |
| 88 | 113 | return __result; |
| ... | ... | @@ -121,7 +146,7 @@ struct __fn { |
| 121 | 146 | } // namespace __minmax |
| 122 | 147 | |
| 123 | 148 | inline namespace __cpo { |
| 124 | inline constexpr auto minmax = __minmax::__fn{}; | |
| 149 | inline constexpr auto minmax = __minmax::__fn{}; | |
| 125 | 150 | } // namespace __cpo |
| 126 | 151 | } // namespace ranges |
| 127 | 152 | |
| ... | ... | @@ -129,6 +154,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 129 | 154 | |
| 130 | 155 | _LIBCPP_POP_MACROS |
| 131 | 156 | |
| 132 | #endif // _LIBCPP_STD_VER > 17 | |
| 157 | #endif // _LIBCPP_STD_VER >= 20 | |
| 133 | 158 | |
| 134 | 159 | #endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H |
lib/libcxx/include/__algorithm/ranges_minmax_element.h+11-10| ... | ... | @@ -23,13 +23,12 @@ |
| 23 | 23 | #include <__utility/forward.h> |
| 24 | 24 | #include <__utility/move.h> |
| 25 | 25 | #include <__utility/pair.h> |
| 26 | #include <type_traits> | |
| 27 | 26 | |
| 28 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 29 | 28 | # pragma GCC system_header |
| 30 | 29 | #endif |
| 31 | 30 | |
| 32 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | 32 | |
| 34 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 34 | |
| ... | ... | @@ -40,18 +39,20 @@ using minmax_element_result = min_max_result<_T1>; |
| 40 | 39 | |
| 41 | 40 | namespace __minmax_element { |
| 42 | 41 | struct __fn { |
| 43 | template <forward_iterator _Ip, sentinel_for<_Ip> _Sp, class _Proj = identity, | |
| 42 | template <forward_iterator _Ip, | |
| 43 | sentinel_for<_Ip> _Sp, | |
| 44 | class _Proj = identity, | |
| 44 | 45 | indirect_strict_weak_order<projected<_Ip, _Proj>> _Comp = ranges::less> |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 46 | ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> | |
| 47 | operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 47 | 48 | auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 48 | 49 | return {__ret.first, __ret.second}; |
| 49 | 50 | } |
| 50 | 51 | |
| 51 | template <forward_range _Rp, class _Proj = identity, | |
| 52 | template <forward_range _Rp, | |
| 53 | class _Proj = identity, | |
| 52 | 54 | indirect_strict_weak_order<projected<iterator_t<_Rp>, _Proj>> _Comp = ranges::less> |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 54 | ranges::minmax_element_result<borrowed_iterator_t<_Rp>> | |
| 55 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<borrowed_iterator_t<_Rp>> | |
| 55 | 56 | operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { |
| 56 | 57 | auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 57 | 58 | return {__ret.first, __ret.second}; |
| ... | ... | @@ -60,13 +61,13 @@ struct __fn { |
| 60 | 61 | } // namespace __minmax_element |
| 61 | 62 | |
| 62 | 63 | inline namespace __cpo { |
| 63 | inline constexpr auto minmax_element = __minmax_element::__fn{}; | |
| 64 | inline constexpr auto minmax_element = __minmax_element::__fn{}; | |
| 64 | 65 | } // namespace __cpo |
| 65 | 66 | |
| 66 | 67 | } // namespace ranges |
| 67 | 68 | |
| 68 | 69 | _LIBCPP_END_NAMESPACE_STD |
| 69 | 70 | |
| 70 | #endif // _LIBCPP_STD_VER > 17 | |
| 71 | #endif // _LIBCPP_STD_VER >= 20 | |
| 71 | 72 | |
| 72 | 73 | #endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H |
lib/libcxx/include/__algorithm/ranges_mismatch.h+25-21| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | |
| ... | ... | @@ -36,12 +36,9 @@ using mismatch_result = in_in_result<_I1, _I2>; |
| 36 | 36 | |
| 37 | 37 | namespace __mismatch { |
| 38 | 38 | struct __fn { |
| 39 | template <class _I1, class _S1, class _I2, class _S2, | |
| 40 | class _Pred, class _Proj1, class _Proj2> | |
| 41 | static _LIBCPP_HIDE_FROM_ABI constexpr | |
| 42 | mismatch_result<_I1, _I2> | |
| 43 | __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, | |
| 44 | _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { | |
| 39 | template <class _I1, class _S1, class _I2, class _S2, class _Pred, class _Proj1, class _Proj2> | |
| 40 | static _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> | |
| 41 | __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { | |
| 45 | 42 | while (__first1 != __last1 && __first2 != __last2) { |
| 46 | 43 | if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) |
| 47 | 44 | break; |
| ... | ... | @@ -51,34 +48,41 @@ struct __fn { |
| 51 | 48 | return {std::move(__first1), std::move(__first2)}; |
| 52 | 49 | } |
| 53 | 50 | |
| 54 | template <input_iterator _I1, sentinel_for<_I1> _S1, | |
| 55 | input_iterator _I2, sentinel_for<_I2> _S2, | |
| 56 | class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> | |
| 51 | template <input_iterator _I1, | |
| 52 | sentinel_for<_I1> _S1, | |
| 53 | input_iterator _I2, | |
| 54 | sentinel_for<_I2> _S2, | |
| 55 | class _Pred = ranges::equal_to, | |
| 56 | class _Proj1 = identity, | |
| 57 | class _Proj2 = identity> | |
| 57 | 58 | requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> |
| 58 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 59 | mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, | |
| 60 | _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( | |
| 60 | _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) | |
| 61 | const { | |
| 61 | 62 | return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); |
| 62 | 63 | } |
| 63 | 64 | |
| 64 | template <input_range _R1, input_range _R2, | |
| 65 | class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> | |
| 65 | template <input_range _R1, | |
| 66 | input_range _R2, | |
| 67 | class _Pred = ranges::equal_to, | |
| 68 | class _Proj1 = identity, | |
| 69 | class _Proj2 = identity> | |
| 66 | 70 | requires indirectly_comparable<iterator_t<_R1>, iterator_t<_R2>, _Pred, _Proj1, _Proj2> |
| 67 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 68 | mismatch_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>> | |
| 71 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<borrowed_iterator_t<_R1>, | |
| 72 | borrowed_iterator_t<_R2>> | |
| 69 | 73 | operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { |
| 70 | return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), | |
| 71 | __pred, __proj1, __proj2); | |
| 74 | return __go( | |
| 75 | ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), __pred, __proj1, __proj2); | |
| 72 | 76 | } |
| 73 | 77 | }; |
| 74 | 78 | } // namespace __mismatch |
| 75 | 79 | |
| 76 | 80 | inline namespace __cpo { |
| 77 | constexpr inline auto mismatch = __mismatch::__fn{}; | |
| 81 | constexpr inline auto mismatch = __mismatch::__fn{}; | |
| 78 | 82 | } // namespace __cpo |
| 79 | 83 | } // namespace ranges |
| 80 | 84 | |
| 81 | #endif // _LIBCPP_STD_VER > 17 | |
| 85 | #endif // _LIBCPP_STD_VER >= 20 | |
| 82 | 86 | |
| 83 | 87 | _LIBCPP_END_NAMESPACE_STD |
| 84 | 88 |
lib/libcxx/include/__algorithm/ranges_move.h+9-11| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| ... | ... | @@ -34,38 +34,36 @@ using move_result = in_out_result<_InIter, _OutIter>; |
| 34 | 34 | |
| 35 | 35 | namespace __move { |
| 36 | 36 | struct __fn { |
| 37 | ||
| 38 | 37 | template <class _InIter, class _Sent, class _OutIter> |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 40 | move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) { | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr static move_result<_InIter, _OutIter> | |
| 39 | __move_impl(_InIter __first, _Sent __last, _OutIter __result) { | |
| 41 | 40 | auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); |
| 42 | 41 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 43 | 42 | } |
| 44 | 43 | |
| 45 | 44 | template <input_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter> |
| 46 | 45 | requires indirectly_movable<_InIter, _OutIter> |
| 47 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 48 | move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 46 | _LIBCPP_HIDE_FROM_ABI constexpr move_result<_InIter, _OutIter> | |
| 47 | operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 49 | 48 | return __move_impl(std::move(__first), std::move(__last), std::move(__result)); |
| 50 | 49 | } |
| 51 | 50 | |
| 52 | 51 | template <input_range _Range, weakly_incrementable _OutIter> |
| 53 | 52 | requires indirectly_movable<iterator_t<_Range>, _OutIter> |
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 55 | move_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const { | |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr move_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 54 | operator()(_Range&& __range, _OutIter __result) const { | |
| 56 | 55 | return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); |
| 57 | 56 | } |
| 58 | ||
| 59 | 57 | }; |
| 60 | 58 | } // namespace __move |
| 61 | 59 | |
| 62 | 60 | inline namespace __cpo { |
| 63 | inline constexpr auto move = __move::__fn{}; | |
| 61 | inline constexpr auto move = __move::__fn{}; | |
| 64 | 62 | } // namespace __cpo |
| 65 | 63 | } // namespace ranges |
| 66 | 64 | |
| 67 | 65 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 66 | |
| 69 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 68 | |
| 71 | 69 | #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H |
lib/libcxx/include/__algorithm/ranges_move_backward.h+9-11| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -36,38 +36,36 @@ using move_backward_result = in_out_result<_InIter, _OutIter>; |
| 36 | 36 | |
| 37 | 37 | namespace __move_backward { |
| 38 | 38 | struct __fn { |
| 39 | ||
| 40 | 39 | template <class _InIter, class _Sent, class _OutIter> |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 42 | move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static move_backward_result<_InIter, _OutIter> | |
| 41 | __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { | |
| 43 | 42 | auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); |
| 44 | 43 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 45 | 44 | } |
| 46 | 45 | |
| 47 | 46 | template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, bidirectional_iterator _OutIter> |
| 48 | 47 | requires indirectly_movable<_InIter, _OutIter> |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 50 | move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<_InIter, _OutIter> | |
| 49 | operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 51 | 50 | return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result)); |
| 52 | 51 | } |
| 53 | 52 | |
| 54 | 53 | template <bidirectional_range _Range, bidirectional_iterator _Iter> |
| 55 | 54 | requires indirectly_movable<iterator_t<_Range>, _Iter> |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 57 | move_backward_result<borrowed_iterator_t<_Range>, _Iter> operator()(_Range&& __range, _Iter __result) const { | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter> | |
| 56 | operator()(_Range&& __range, _Iter __result) const { | |
| 58 | 57 | return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); |
| 59 | 58 | } |
| 60 | ||
| 61 | 59 | }; |
| 62 | 60 | } // namespace __move_backward |
| 63 | 61 | |
| 64 | 62 | inline namespace __cpo { |
| 65 | inline constexpr auto move_backward = __move_backward::__fn{}; | |
| 63 | inline constexpr auto move_backward = __move_backward::__fn{}; | |
| 66 | 64 | } // namespace __cpo |
| 67 | 65 | } // namespace ranges |
| 68 | 66 | |
| 69 | 67 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 68 | |
| 71 | #endif // _LIBCPP_STD_VER > 17 | |
| 69 | #endif // _LIBCPP_STD_VER >= 20 | |
| 72 | 70 | |
| 73 | 71 | #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H |
lib/libcxx/include/__algorithm/ranges_next_permutation.h+2-2| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 34 | |
| ... | ... | @@ -68,6 +68,6 @@ constexpr inline auto next_permutation = __next_permutation::__fn{}; |
| 68 | 68 | |
| 69 | 69 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 70 | |
| 71 | #endif // _LIBCPP_STD_VER > 17 | |
| 71 | #endif // _LIBCPP_STD_VER >= 20 | |
| 72 | 72 | |
| 73 | 73 | #endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H |
lib/libcxx/include/__algorithm/ranges_none_of.h+14-12| ... | ... | @@ -22,17 +22,16 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | namespace ranges { |
| 30 | 30 | namespace __none_of { |
| 31 | 31 | struct __fn { |
| 32 | ||
| 33 | 32 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 35 | bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr static bool | |
| 34 | __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 36 | 35 | for (; __first != __last; ++__first) { |
| 37 | 36 | if (std::invoke(__pred, std::invoke(__proj, *__first))) |
| 38 | 37 | return false; |
| ... | ... | @@ -40,29 +39,32 @@ struct __fn { |
| 40 | 39 | return true; |
| 41 | 40 | } |
| 42 | 41 | |
| 43 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 42 | template <input_iterator _Iter, | |
| 43 | sentinel_for<_Iter> _Sent, | |
| 44 | class _Proj = identity, | |
| 44 | 45 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 45 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 46 | bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 47 | operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { | |
| 47 | 48 | return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 48 | 49 | } |
| 49 | 50 | |
| 50 | template <input_range _Range, class _Proj = identity, | |
| 51 | template <input_range _Range, | |
| 52 | class _Proj = identity, | |
| 51 | 53 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 52 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 53 | bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 54 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 55 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 54 | 56 | return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 55 | 57 | } |
| 56 | 58 | }; |
| 57 | 59 | } // namespace __none_of |
| 58 | 60 | |
| 59 | 61 | inline namespace __cpo { |
| 60 | inline constexpr auto none_of = __none_of::__fn{}; | |
| 62 | inline constexpr auto none_of = __none_of::__fn{}; | |
| 61 | 63 | } // namespace __cpo |
| 62 | 64 | } // namespace ranges |
| 63 | 65 | |
| 64 | 66 | _LIBCPP_END_NAMESPACE_STD |
| 65 | 67 | |
| 66 | #endif // _LIBCPP_STD_VER > 17 | |
| 68 | #endif // _LIBCPP_STD_VER >= 20 | |
| 67 | 69 | |
| 68 | 70 | #endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H |
lib/libcxx/include/__algorithm/ranges_nth_element.h+9-10| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| ... | ... | @@ -40,8 +40,8 @@ namespace __nth_element { |
| 40 | 40 | |
| 41 | 41 | struct __fn { |
| 42 | 42 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 44 | _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 44 | __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 45 | 45 | auto __last_iter = ranges::next(__first, __last); |
| 46 | 46 | |
| 47 | 47 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -52,16 +52,15 @@ struct __fn { |
| 52 | 52 | |
| 53 | 53 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 54 | 54 | requires sortable<_Iter, _Comp, _Proj> |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 56 | _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 56 | operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 57 | 57 | return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 61 | 61 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 63 | borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, | |
| 64 | _Proj __proj = {}) const { | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 63 | operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 65 | 64 | return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj); |
| 66 | 65 | } |
| 67 | 66 | }; |
| ... | ... | @@ -69,12 +68,12 @@ struct __fn { |
| 69 | 68 | } // namespace __nth_element |
| 70 | 69 | |
| 71 | 70 | inline namespace __cpo { |
| 72 | inline constexpr auto nth_element = __nth_element::__fn{}; | |
| 71 | inline constexpr auto nth_element = __nth_element::__fn{}; | |
| 73 | 72 | } // namespace __cpo |
| 74 | 73 | } // namespace ranges |
| 75 | 74 | |
| 76 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 76 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 77 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 78 | |
| 80 | 79 | #endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H |
lib/libcxx/include/__algorithm/ranges_partial_sort.h+9-10| ... | ... | @@ -33,7 +33,7 @@ |
| 33 | 33 | # pragma GCC system_header |
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 39 | |
| ... | ... | @@ -42,24 +42,23 @@ namespace __partial_sort { |
| 42 | 42 | |
| 43 | 43 | struct __fn { |
| 44 | 44 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 45 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 46 | _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 45 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 46 | __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 47 | 47 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| 48 | 48 | return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 52 | 52 | requires sortable<_Iter, _Comp, _Proj> |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 54 | _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 54 | operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 55 | 55 | return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj); |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 59 | 59 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 61 | borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, | |
| 62 | _Proj __proj = {}) const { | |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 61 | operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 63 | 62 | return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj); |
| 64 | 63 | } |
| 65 | 64 | }; |
| ... | ... | @@ -67,12 +66,12 @@ struct __fn { |
| 67 | 66 | } // namespace __partial_sort |
| 68 | 67 | |
| 69 | 68 | inline namespace __cpo { |
| 70 | inline constexpr auto partial_sort = __partial_sort::__fn{}; | |
| 69 | inline constexpr auto partial_sort = __partial_sort::__fn{}; | |
| 71 | 70 | } // namespace __cpo |
| 72 | 71 | } // namespace ranges |
| 73 | 72 | |
| 74 | 73 | _LIBCPP_END_NAMESPACE_STD |
| 75 | 74 | |
| 76 | #endif // _LIBCPP_STD_VER > 17 | |
| 75 | #endif // _LIBCPP_STD_VER >= 20 | |
| 77 | 76 | |
| 78 | 77 | #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H |
lib/libcxx/include/__algorithm/ranges_partial_sort_copy.h+47-30| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | # pragma GCC system_header |
| 31 | 31 | #endif |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 36 | |
| ... | ... | @@ -42,51 +42,68 @@ using partial_sort_copy_result = in_out_result<_InIter, _OutIter>; |
| 42 | 42 | namespace __partial_sort_copy { |
| 43 | 43 | |
| 44 | 44 | struct __fn { |
| 45 | ||
| 46 | template <input_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 47 | random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 48 | class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> | |
| 49 | requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && | |
| 50 | indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> | |
| 51 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 52 | partial_sort_copy_result<_Iter1, _Iter2> | |
| 53 | operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last, | |
| 54 | _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 45 | template <input_iterator _Iter1, | |
| 46 | sentinel_for<_Iter1> _Sent1, | |
| 47 | random_access_iterator _Iter2, | |
| 48 | sentinel_for<_Iter2> _Sent2, | |
| 49 | class _Comp = ranges::less, | |
| 50 | class _Proj1 = identity, | |
| 51 | class _Proj2 = identity> | |
| 52 | requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && | |
| 53 | indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> | |
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<_Iter1, _Iter2> operator()( | |
| 55 | _Iter1 __first, | |
| 56 | _Sent1 __last, | |
| 57 | _Iter2 __result_first, | |
| 58 | _Sent2 __result_last, | |
| 59 | _Comp __comp = {}, | |
| 60 | _Proj1 __proj1 = {}, | |
| 61 | _Proj2 __proj2 = {}) const { | |
| 55 | 62 | auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( |
| 56 | std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last), | |
| 57 | __comp, __proj1, __proj2 | |
| 58 | ); | |
| 63 | std::move(__first), | |
| 64 | std::move(__last), | |
| 65 | std::move(__result_first), | |
| 66 | std::move(__result_last), | |
| 67 | __comp, | |
| 68 | __proj1, | |
| 69 | __proj2); | |
| 59 | 70 | return {std::move(__result.first), std::move(__result.second)}; |
| 60 | 71 | } |
| 61 | 72 | |
| 62 | template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less, | |
| 63 | class _Proj1 = identity, class _Proj2 = identity> | |
| 64 | requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> && | |
| 65 | sortable<iterator_t<_Range2>, _Comp, _Proj2> && | |
| 66 | indirect_strict_weak_order<_Comp, projected<iterator_t<_Range1>, _Proj1>, | |
| 67 | projected<iterator_t<_Range2>, _Proj2>> | |
| 68 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 69 | partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>> | |
| 70 | operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, | |
| 71 | _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 73 | template <input_range _Range1, | |
| 74 | random_access_range _Range2, | |
| 75 | class _Comp = ranges::less, | |
| 76 | class _Proj1 = identity, | |
| 77 | class _Proj2 = identity> | |
| 78 | requires indirectly_copyable<iterator_t<_Range1>, iterator_t<_Range2>> && | |
| 79 | sortable<iterator_t<_Range2>, _Comp, _Proj2> && | |
| 80 | indirect_strict_weak_order<_Comp, | |
| 81 | projected<iterator_t<_Range1>, _Proj1>, | |
| 82 | projected<iterator_t<_Range2>, _Proj2>> | |
| 83 | _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>> | |
| 84 | operator()( | |
| 85 | _Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 72 | 86 | auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( |
| 73 | ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range), | |
| 74 | __comp, __proj1, __proj2 | |
| 75 | ); | |
| 87 | ranges::begin(__range), | |
| 88 | ranges::end(__range), | |
| 89 | ranges::begin(__result_range), | |
| 90 | ranges::end(__result_range), | |
| 91 | __comp, | |
| 92 | __proj1, | |
| 93 | __proj2); | |
| 76 | 94 | return {std::move(__result.first), std::move(__result.second)}; |
| 77 | 95 | } |
| 78 | ||
| 79 | 96 | }; |
| 80 | 97 | |
| 81 | 98 | } // namespace __partial_sort_copy |
| 82 | 99 | |
| 83 | 100 | inline namespace __cpo { |
| 84 | inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; | |
| 101 | inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; | |
| 85 | 102 | } // namespace __cpo |
| 86 | 103 | } // namespace ranges |
| 87 | 104 | |
| 88 | 105 | _LIBCPP_END_NAMESPACE_STD |
| 89 | 106 | |
| 90 | #endif // _LIBCPP_STD_VER > 17 | |
| 107 | #endif // _LIBCPP_STD_VER >= 20 | |
| 91 | 108 | |
| 92 | 109 | #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H |
lib/libcxx/include/__algorithm/ranges_partition.h+16-16| ... | ... | @@ -27,13 +27,12 @@ |
| 27 | 27 | #include <__utility/forward.h> |
| 28 | 28 | #include <__utility/move.h> |
| 29 | 29 | #include <__utility/pair.h> |
| 30 | #include <type_traits> | |
| 31 | 30 | |
| 32 | 31 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 33 | 32 | # pragma GCC system_header |
| 34 | 33 | #endif |
| 35 | 34 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 36 | |
| 38 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 38 | |
| ... | ... | @@ -41,43 +40,44 @@ namespace ranges { |
| 41 | 40 | namespace __partition { |
| 42 | 41 | |
| 43 | 42 | struct __fn { |
| 44 | ||
| 45 | 43 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 46 | _LIBCPP_HIDE_FROM_ABI static constexpr | |
| 47 | subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { | |
| 44 | _LIBCPP_HIDE_FROM_ABI static constexpr subrange<__remove_cvref_t<_Iter>> | |
| 45 | __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { | |
| 48 | 46 | auto&& __projected_pred = std::__make_projected(__pred, __proj); |
| 49 | auto __result = std::__partition<_RangeAlgPolicy>( | |
| 47 | auto __result = std::__partition<_RangeAlgPolicy>( | |
| 50 | 48 | std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>()); |
| 51 | 49 | |
| 52 | 50 | return {std::move(__result.first), std::move(__result.second)}; |
| 53 | 51 | } |
| 54 | 52 | |
| 55 | template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 53 | template <permutable _Iter, | |
| 54 | sentinel_for<_Iter> _Sent, | |
| 55 | class _Proj = identity, | |
| 56 | 56 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 58 | operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 59 | 59 | return __partition_fn_impl(__first, __last, __pred, __proj); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | template <forward_range _Range, class _Proj = identity, | |
| 62 | template <forward_range _Range, | |
| 63 | class _Proj = identity, | |
| 63 | 64 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 64 | requires permutable<iterator_t<_Range>> | |
| 65 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 66 | borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 65 | requires permutable<iterator_t<_Range>> | |
| 66 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 67 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 67 | 68 | return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 68 | 69 | } |
| 69 | ||
| 70 | 70 | }; |
| 71 | 71 | |
| 72 | 72 | } // namespace __partition |
| 73 | 73 | |
| 74 | 74 | inline namespace __cpo { |
| 75 | inline constexpr auto partition = __partition::__fn{}; | |
| 75 | inline constexpr auto partition = __partition::__fn{}; | |
| 76 | 76 | } // namespace __cpo |
| 77 | 77 | } // namespace ranges |
| 78 | 78 | |
| 79 | 79 | _LIBCPP_END_NAMESPACE_STD |
| 80 | 80 | |
| 81 | #endif // _LIBCPP_STD_VER > 17 | |
| 81 | #endif // _LIBCPP_STD_VER >= 20 | |
| 82 | 82 | |
| 83 | 83 | #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H |
lib/libcxx/include/__algorithm/ranges_partition_copy.h+31-24| ... | ... | @@ -19,14 +19,14 @@ |
| 19 | 19 | #include <__ranges/access.h> |
| 20 | 20 | #include <__ranges/concepts.h> |
| 21 | 21 | #include <__ranges/dangling.h> |
| 22 | #include <__type_traits/remove_cvref.h> | |
| 22 | 23 | #include <__utility/move.h> |
| 23 | #include <type_traits> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| ... | ... | @@ -38,14 +38,18 @@ using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>; |
| 38 | 38 | namespace __partition_copy { |
| 39 | 39 | |
| 40 | 40 | struct __fn { |
| 41 | ||
| 42 | 41 | // TODO(ranges): delegate to the classic algorithm. |
| 43 | 42 | template <class _InIter, class _Sent, class _OutIter1, class _OutIter2, class _Proj, class _Pred> |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 45 | static partition_copy_result< | |
| 46 | __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2> | |
| 47 | > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false, | |
| 48 | _Pred& __pred, _Proj& __proj) { | |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>, | |
| 44 | __remove_cvref_t<_OutIter1>, | |
| 45 | __remove_cvref_t<_OutIter2> > | |
| 46 | __partition_copy_fn_impl( | |
| 47 | _InIter&& __first, | |
| 48 | _Sent&& __last, | |
| 49 | _OutIter1&& __out_true, | |
| 50 | _OutIter2&& __out_false, | |
| 51 | _Pred& __pred, | |
| 52 | _Proj& __proj) { | |
| 49 | 53 | for (; __first != __last; ++__first) { |
| 50 | 54 | if (std::invoke(__pred, std::invoke(__proj, *__first))) { |
| 51 | 55 | *__out_true = *__first; |
| ... | ... | @@ -60,39 +64,42 @@ struct __fn { |
| 60 | 64 | return {std::move(__first), std::move(__out_true), std::move(__out_false)}; |
| 61 | 65 | } |
| 62 | 66 | |
| 63 | template <input_iterator _InIter, sentinel_for<_InIter> _Sent, | |
| 64 | weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, | |
| 65 | class _Proj = identity, indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 66 | requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> | |
| 67 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 68 | partition_copy_result<_InIter, _OutIter1, _OutIter2> | |
| 69 | operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, | |
| 70 | _Pred __pred, _Proj __proj = {}) const { | |
| 67 | template <input_iterator _InIter, | |
| 68 | sentinel_for<_InIter> _Sent, | |
| 69 | weakly_incrementable _OutIter1, | |
| 70 | weakly_incrementable _OutIter2, | |
| 71 | class _Proj = identity, | |
| 72 | indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 73 | requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> | |
| 74 | _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()( | |
| 75 | _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) | |
| 76 | const { | |
| 71 | 77 | return __partition_copy_fn_impl( |
| 72 | 78 | std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj); |
| 73 | 79 | } |
| 74 | 80 | |
| 75 | template <input_range _Range, weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, | |
| 76 | class _Proj = identity, indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 77 | requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2> | |
| 78 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 79 | partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2> | |
| 81 | template <input_range _Range, | |
| 82 | weakly_incrementable _OutIter1, | |
| 83 | weakly_incrementable _OutIter2, | |
| 84 | class _Proj = identity, | |
| 85 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 86 | requires indirectly_copyable<iterator_t<_Range>, _OutIter1> && indirectly_copyable<iterator_t<_Range>, _OutIter2> | |
| 87 | _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<borrowed_iterator_t<_Range>, _OutIter1, _OutIter2> | |
| 80 | 88 | operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const { |
| 81 | 89 | return __partition_copy_fn_impl( |
| 82 | 90 | ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj); |
| 83 | 91 | } |
| 84 | ||
| 85 | 92 | }; |
| 86 | 93 | |
| 87 | 94 | } // namespace __partition_copy |
| 88 | 95 | |
| 89 | 96 | inline namespace __cpo { |
| 90 | inline constexpr auto partition_copy = __partition_copy::__fn{}; | |
| 97 | inline constexpr auto partition_copy = __partition_copy::__fn{}; | |
| 91 | 98 | } // namespace __cpo |
| 92 | 99 | } // namespace ranges |
| 93 | 100 | |
| 94 | 101 | _LIBCPP_END_NAMESPACE_STD |
| 95 | 102 | |
| 96 | #endif // _LIBCPP_STD_VER > 17 | |
| 103 | #endif // _LIBCPP_STD_VER >= 20 | |
| 97 | 104 | |
| 98 | 105 | #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H |
lib/libcxx/include/__algorithm/ranges_partition_point.h+14-14| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -35,16 +35,15 @@ namespace ranges { |
| 35 | 35 | namespace __partition_point { |
| 36 | 36 | |
| 37 | 37 | struct __fn { |
| 38 | ||
| 39 | 38 | // TODO(ranges): delegate to the classic algorithm. |
| 40 | 39 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 42 | static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 41 | __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { | |
| 43 | 42 | auto __len = ranges::distance(__first, __last); |
| 44 | 43 | |
| 45 | 44 | while (__len != 0) { |
| 46 | 45 | auto __half_len = std::__half_positive(__len); |
| 47 | auto __mid = ranges::next(__first, __half_len); | |
| 46 | auto __mid = ranges::next(__first, __half_len); | |
| 48 | 47 | |
| 49 | 48 | if (std::invoke(__pred, std::invoke(__proj, *__mid))) { |
| 50 | 49 | __first = ++__mid; |
| ... | ... | @@ -58,31 +57,32 @@ struct __fn { |
| 58 | 57 | return __first; |
| 59 | 58 | } |
| 60 | 59 | |
| 61 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 60 | template <forward_iterator _Iter, | |
| 61 | sentinel_for<_Iter> _Sent, | |
| 62 | class _Proj = identity, | |
| 62 | 63 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 64 | _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 65 | 65 | return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | template <forward_range _Range, class _Proj = identity, | |
| 68 | template <forward_range _Range, | |
| 69 | class _Proj = identity, | |
| 69 | 70 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 70 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 71 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 71 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 72 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 72 | 73 | return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 73 | 74 | } |
| 74 | ||
| 75 | 75 | }; |
| 76 | 76 | |
| 77 | 77 | } // namespace __partition_point |
| 78 | 78 | |
| 79 | 79 | inline namespace __cpo { |
| 80 | inline constexpr auto partition_point = __partition_point::__fn{}; | |
| 80 | inline constexpr auto partition_point = __partition_point::__fn{}; | |
| 81 | 81 | } // namespace __cpo |
| 82 | 82 | } // namespace ranges |
| 83 | 83 | |
| 84 | 84 | _LIBCPP_END_NAMESPACE_STD |
| 85 | 85 | |
| 86 | #endif // _LIBCPP_STD_VER > 17 | |
| 86 | #endif // _LIBCPP_STD_VER >= 20 | |
| 87 | 87 | |
| 88 | 88 | #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H |
lib/libcxx/include/__algorithm/ranges_pop_heap.h+10-10| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | # pragma GCC system_header |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 38 | |
| ... | ... | @@ -41,10 +41,10 @@ namespace __pop_heap { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | 43 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 45 | _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 45 | __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 46 | 46 | auto __last_iter = ranges::next(__first, __last); |
| 47 | auto __len = __last_iter - __first; | |
| 47 | auto __len = __last_iter - __first; | |
| 48 | 48 | |
| 49 | 49 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| 50 | 50 | std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len); |
| ... | ... | @@ -54,15 +54,15 @@ struct __fn { |
| 54 | 54 | |
| 55 | 55 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 56 | 56 | requires sortable<_Iter, _Comp, _Proj> |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 58 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 58 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 59 | 59 | return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 63 | 63 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 65 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 65 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 66 | 66 | return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 67 | 67 | } |
| 68 | 68 | }; |
| ... | ... | @@ -70,12 +70,12 @@ struct __fn { |
| 70 | 70 | } // namespace __pop_heap |
| 71 | 71 | |
| 72 | 72 | inline namespace __cpo { |
| 73 | inline constexpr auto pop_heap = __pop_heap::__fn{}; | |
| 73 | inline constexpr auto pop_heap = __pop_heap::__fn{}; | |
| 74 | 74 | } // namespace __cpo |
| 75 | 75 | } // namespace ranges |
| 76 | 76 | |
| 77 | 77 | _LIBCPP_END_NAMESPACE_STD |
| 78 | 78 | |
| 79 | #endif // _LIBCPP_STD_VER > 17 | |
| 79 | #endif // _LIBCPP_STD_VER >= 20 | |
| 80 | 80 | |
| 81 | 81 | #endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H |
lib/libcxx/include/__algorithm/ranges_prev_permutation.h+4-8| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 34 | |
| ... | ... | @@ -40,9 +40,7 @@ using prev_permutation_result = in_found_result<_InIter>; |
| 40 | 40 | namespace __prev_permutation { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | ||
| 44 | template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 45 | class _Comp = ranges::less, class _Proj = identity> | |
| 43 | template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> | |
| 46 | 44 | requires sortable<_Iter, _Comp, _Proj> |
| 47 | 45 | _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter> |
| 48 | 46 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { |
| ... | ... | @@ -51,8 +49,7 @@ struct __fn { |
| 51 | 49 | return {std::move(__result.first), std::move(__result.second)}; |
| 52 | 50 | } |
| 53 | 51 | |
| 54 | template <bidirectional_range _Range, | |
| 55 | class _Comp = ranges::less, class _Proj = identity> | |
| 52 | template <bidirectional_range _Range, class _Comp = ranges::less, class _Proj = identity> | |
| 56 | 53 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 57 | 54 | _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<borrowed_iterator_t<_Range>> |
| 58 | 55 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { |
| ... | ... | @@ -60,7 +57,6 @@ struct __fn { |
| 60 | 57 | ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); |
| 61 | 58 | return {std::move(__result.first), std::move(__result.second)}; |
| 62 | 59 | } |
| 63 | ||
| 64 | 60 | }; |
| 65 | 61 | |
| 66 | 62 | } // namespace __prev_permutation |
| ... | ... | @@ -72,6 +68,6 @@ constexpr inline auto prev_permutation = __prev_permutation::__fn{}; |
| 72 | 68 | |
| 73 | 69 | _LIBCPP_END_NAMESPACE_STD |
| 74 | 70 | |
| 75 | #endif // _LIBCPP_STD_VER > 17 | |
| 71 | #endif // _LIBCPP_STD_VER >= 20 | |
| 76 | 72 | |
| 77 | 73 | #endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H |
lib/libcxx/include/__algorithm/ranges_push_heap.h+9-9| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | # pragma GCC system_header |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 38 | |
| ... | ... | @@ -41,8 +41,8 @@ namespace __push_heap { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | 43 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 45 | _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 45 | __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 46 | 46 | auto __last_iter = ranges::next(__first, __last); |
| 47 | 47 | |
| 48 | 48 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -53,15 +53,15 @@ struct __fn { |
| 53 | 53 | |
| 54 | 54 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 55 | 55 | requires sortable<_Iter, _Comp, _Proj> |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 57 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 57 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 58 | 58 | return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 62 | 62 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 64 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 64 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 65 | 65 | return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 66 | 66 | } |
| 67 | 67 | }; |
| ... | ... | @@ -69,12 +69,12 @@ struct __fn { |
| 69 | 69 | } // namespace __push_heap |
| 70 | 70 | |
| 71 | 71 | inline namespace __cpo { |
| 72 | inline constexpr auto push_heap = __push_heap::__fn{}; | |
| 72 | inline constexpr auto push_heap = __push_heap::__fn{}; | |
| 73 | 73 | } // namespace __cpo |
| 74 | 74 | } // namespace ranges |
| 75 | 75 | |
| 76 | 76 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 77 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 78 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 79 | |
| 80 | 80 | #endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H |
lib/libcxx/include/__algorithm/ranges_remove.h+9-10| ... | ... | @@ -25,27 +25,26 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | namespace __remove { |
| 34 | 34 | struct __fn { |
| 35 | ||
| 36 | 35 | template <permutable _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity> |
| 37 | 36 | requires indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type*> |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 39 | subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { | |
| 37 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 38 | operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { | |
| 40 | 39 | auto __pred = [&](auto&& __other) { return __value == __other; }; |
| 41 | 40 | return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | 43 | template <forward_range _Range, class _Type, class _Proj = identity> |
| 45 | requires permutable<iterator_t<_Range>> | |
| 46 | && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*> | |
| 47 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 48 | borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { | |
| 44 | requires permutable<iterator_t<_Range>> && | |
| 45 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*> | |
| 46 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 47 | operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { | |
| 49 | 48 | auto __pred = [&](auto&& __other) { return __value == __other; }; |
| 50 | 49 | return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 51 | 50 | } |
| ... | ... | @@ -53,12 +52,12 @@ struct __fn { |
| 53 | 52 | } // namespace __remove |
| 54 | 53 | |
| 55 | 54 | inline namespace __cpo { |
| 56 | inline constexpr auto remove = __remove::__fn{}; | |
| 55 | inline constexpr auto remove = __remove::__fn{}; | |
| 57 | 56 | } // namespace __cpo |
| 58 | 57 | } // namespace ranges |
| 59 | 58 | |
| 60 | 59 | _LIBCPP_END_NAMESPACE_STD |
| 61 | 60 | |
| 62 | #endif // _LIBCPP_STD_VER > 17 | |
| 61 | #endif // _LIBCPP_STD_VER >= 20 | |
| 63 | 62 | |
| 64 | 63 | #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H |
lib/libcxx/include/__algorithm/ranges_remove_copy.h+26-26| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| ... | ... | @@ -37,40 +37,40 @@ using remove_copy_result = in_out_result<_InIter, _OutIter>; |
| 37 | 37 | |
| 38 | 38 | namespace __remove_copy { |
| 39 | 39 | |
| 40 | struct __fn { | |
| 41 | template <input_iterator _InIter, | |
| 42 | sentinel_for<_InIter> _Sent, | |
| 43 | weakly_incrementable _OutIter, | |
| 44 | class _Type, | |
| 45 | class _Proj = identity> | |
| 46 | requires indirectly_copyable<_InIter, _OutIter> && | |
| 47 | indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*> | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> | |
| 49 | operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { | |
| 50 | auto __pred = [&](auto&& __val) { return __value == __val; }; | |
| 51 | return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); | |
| 52 | } | |
| 40 | struct __fn { | |
| 41 | template <input_iterator _InIter, | |
| 42 | sentinel_for<_InIter> _Sent, | |
| 43 | weakly_incrementable _OutIter, | |
| 44 | class _Type, | |
| 45 | class _Proj = identity> | |
| 46 | requires indirectly_copyable<_InIter, _OutIter> && | |
| 47 | indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _Type*> | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> | |
| 49 | operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { | |
| 50 | auto __pred = [&](auto&& __val) { return __value == __val; }; | |
| 51 | return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); | |
| 52 | } | |
| 53 | 53 | |
| 54 | template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity> | |
| 55 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> && | |
| 56 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*> | |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 58 | operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { | |
| 59 | auto __pred = [&](auto&& __val) { return __value == __val; }; | |
| 60 | return ranges::__remove_copy_if_impl( | |
| 61 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); | |
| 62 | } | |
| 63 | }; | |
| 54 | template <input_range _Range, weakly_incrementable _OutIter, class _Type, class _Proj = identity> | |
| 55 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> && | |
| 56 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type*> | |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 58 | operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { | |
| 59 | auto __pred = [&](auto&& __val) { return __value == __val; }; | |
| 60 | return ranges::__remove_copy_if_impl( | |
| 61 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); | |
| 62 | } | |
| 63 | }; | |
| 64 | 64 | |
| 65 | 65 | } // namespace __remove_copy |
| 66 | 66 | |
| 67 | 67 | inline namespace __cpo { |
| 68 | inline constexpr auto remove_copy = __remove_copy::__fn{}; | |
| 68 | inline constexpr auto remove_copy = __remove_copy::__fn{}; | |
| 69 | 69 | } // namespace __cpo |
| 70 | 70 | } // namespace ranges |
| 71 | 71 | |
| 72 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 73 | 73 | |
| 74 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 75 | 75 | |
| 76 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H |
lib/libcxx/include/__algorithm/ranges_remove_copy_if.h+25-25| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | # pragma GCC system_header |
| 30 | 30 | #endif |
| 31 | 31 | |
| 32 | #if _LIBCPP_STD_VER > 17 | |
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | 33 | |
| 34 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 35 | |
| ... | ... | @@ -52,39 +52,39 @@ __remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& _ |
| 52 | 52 | |
| 53 | 53 | namespace __remove_copy_if { |
| 54 | 54 | |
| 55 | struct __fn { | |
| 56 | template <input_iterator _InIter, | |
| 57 | sentinel_for<_InIter> _Sent, | |
| 58 | weakly_incrementable _OutIter, | |
| 59 | class _Proj = identity, | |
| 60 | indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 61 | requires indirectly_copyable<_InIter, _OutIter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> | |
| 63 | operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { | |
| 64 | return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); | |
| 65 | } | |
| 55 | struct __fn { | |
| 56 | template <input_iterator _InIter, | |
| 57 | sentinel_for<_InIter> _Sent, | |
| 58 | weakly_incrementable _OutIter, | |
| 59 | class _Proj = identity, | |
| 60 | indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 61 | requires indirectly_copyable<_InIter, _OutIter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> | |
| 63 | operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { | |
| 64 | return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); | |
| 65 | } | |
| 66 | 66 | |
| 67 | template <input_range _Range, | |
| 68 | weakly_incrementable _OutIter, | |
| 69 | class _Proj = identity, | |
| 70 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 71 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> | |
| 72 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 73 | operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { | |
| 74 | return ranges::__remove_copy_if_impl( | |
| 75 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); | |
| 76 | } | |
| 77 | }; | |
| 67 | template <input_range _Range, | |
| 68 | weakly_incrementable _OutIter, | |
| 69 | class _Proj = identity, | |
| 70 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 71 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> | |
| 72 | _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 73 | operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { | |
| 74 | return ranges::__remove_copy_if_impl( | |
| 75 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); | |
| 76 | } | |
| 77 | }; | |
| 78 | 78 | |
| 79 | 79 | } // namespace __remove_copy_if |
| 80 | 80 | |
| 81 | 81 | inline namespace __cpo { |
| 82 | inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; | |
| 82 | inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; | |
| 83 | 83 | } // namespace __cpo |
| 84 | 84 | } // namespace ranges |
| 85 | 85 | |
| 86 | 86 | _LIBCPP_END_NAMESPACE_STD |
| 87 | 87 | |
| 88 | #endif // _LIBCPP_STD_VER > 17 | |
| 88 | #endif // _LIBCPP_STD_VER >= 20 | |
| 89 | 89 | |
| 90 | 90 | #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H |
lib/libcxx/include/__algorithm/ranges_remove_if.h+11-12| ... | ... | @@ -27,15 +27,15 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| 34 | 34 | namespace ranges { |
| 35 | 35 | |
| 36 | 36 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 38 | subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 38 | __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { | |
| 39 | 39 | auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj); |
| 40 | 40 | if (__new_end == __last) |
| 41 | 41 | return {__new_end, __new_end}; |
| ... | ... | @@ -52,12 +52,12 @@ subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Pr |
| 52 | 52 | |
| 53 | 53 | namespace __remove_if { |
| 54 | 54 | struct __fn { |
| 55 | ||
| 56 | template <permutable _Iter, sentinel_for<_Iter> _Sent, | |
| 55 | template <permutable _Iter, | |
| 56 | sentinel_for<_Iter> _Sent, | |
| 57 | 57 | class _Proj = identity, |
| 58 | 58 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 60 | subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 59 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 60 | operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 61 | 61 | return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); |
| 62 | 62 | } |
| 63 | 63 | |
| ... | ... | @@ -65,21 +65,20 @@ struct __fn { |
| 65 | 65 | class _Proj = identity, |
| 66 | 66 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 67 | 67 | requires permutable<iterator_t<_Range>> |
| 68 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 69 | borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 68 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 69 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 70 | 70 | return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 71 | 71 | } |
| 72 | ||
| 73 | 72 | }; |
| 74 | 73 | } // namespace __remove_if |
| 75 | 74 | |
| 76 | 75 | inline namespace __cpo { |
| 77 | inline constexpr auto remove_if = __remove_if::__fn{}; | |
| 76 | inline constexpr auto remove_if = __remove_if::__fn{}; | |
| 78 | 77 | } // namespace __cpo |
| 79 | 78 | } // namespace ranges |
| 80 | 79 | |
| 81 | 80 | _LIBCPP_END_NAMESPACE_STD |
| 82 | 81 | |
| 83 | #endif // _LIBCPP_STD_VER > 17 | |
| 82 | #endif // _LIBCPP_STD_VER >= 20 | |
| 84 | 83 | |
| 85 | 84 | #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H |
lib/libcxx/include/__algorithm/ranges_replace.h+11-22| ... | ... | @@ -24,51 +24,40 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | 31 | namespace ranges { |
| 32 | 32 | namespace __replace { |
| 33 | 33 | struct __fn { |
| 34 | ||
| 35 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 36 | class _Type1, | |
| 37 | class _Type2, | |
| 38 | class _Proj = identity> | |
| 39 | requires indirectly_writable<_Iter, const _Type2&> | |
| 40 | && indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*> | |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 42 | _Iter operator()(_Iter __first, _Sent __last, | |
| 43 | const _Type1& __old_value, | |
| 44 | const _Type2& __new_value, | |
| 45 | _Proj __proj = {}) const { | |
| 34 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type1, class _Type2, class _Proj = identity> | |
| 35 | requires indirectly_writable<_Iter, const _Type2&> && | |
| 36 | indirect_binary_predicate<ranges::equal_to, projected<_Iter, _Proj>, const _Type1*> | |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()( | |
| 38 | _Iter __first, _Sent __last, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { | |
| 46 | 39 | auto __pred = [&](const auto& __val) { return __val == __old_value; }; |
| 47 | 40 | return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); |
| 48 | 41 | } |
| 49 | 42 | |
| 50 | template <input_range _Range, | |
| 51 | class _Type1, | |
| 52 | class _Type2, | |
| 53 | class _Proj = identity> | |
| 54 | requires indirectly_writable<iterator_t<_Range>, const _Type2&> | |
| 55 | && indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*> | |
| 43 | template <input_range _Range, class _Type1, class _Type2, class _Proj = identity> | |
| 44 | requires indirectly_writable<iterator_t<_Range>, const _Type2&> && | |
| 45 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _Type1*> | |
| 56 | 46 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> |
| 57 | 47 | operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { |
| 58 | 48 | auto __pred = [&](auto&& __val) { return __val == __old_value; }; |
| 59 | 49 | return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); |
| 60 | 50 | } |
| 61 | ||
| 62 | 51 | }; |
| 63 | 52 | } // namespace __replace |
| 64 | 53 | |
| 65 | 54 | inline namespace __cpo { |
| 66 | inline constexpr auto replace = __replace::__fn{}; | |
| 55 | inline constexpr auto replace = __replace::__fn{}; | |
| 67 | 56 | } // namespace __cpo |
| 68 | 57 | } // namespace ranges |
| 69 | 58 | |
| 70 | 59 | _LIBCPP_END_NAMESPACE_STD |
| 71 | 60 | |
| 72 | #endif // _LIBCPP_STD_VER > 17 | |
| 61 | #endif // _LIBCPP_STD_VER >= 20 | |
| 73 | 62 | |
| 74 | 63 | #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H |
lib/libcxx/include/__algorithm/ranges_replace_copy.h+38-41| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| ... | ... | @@ -37,55 +37,52 @@ using replace_copy_result = in_out_result<_InIter, _OutIter>; |
| 37 | 37 | |
| 38 | 38 | namespace __replace_copy { |
| 39 | 39 | |
| 40 | struct __fn { | |
| 41 | template <input_iterator _InIter, | |
| 42 | sentinel_for<_InIter> _Sent, | |
| 43 | class _OldType, | |
| 44 | class _NewType, | |
| 45 | output_iterator<const _NewType&> _OutIter, | |
| 46 | class _Proj = identity> | |
| 47 | requires indirectly_copyable<_InIter, _OutIter> && | |
| 48 | indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*> | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> | |
| 50 | operator()(_InIter __first, | |
| 51 | _Sent __last, | |
| 52 | _OutIter __result, | |
| 53 | const _OldType& __old_value, | |
| 54 | const _NewType& __new_value, | |
| 55 | _Proj __proj = {}) const { | |
| 56 | auto __pred = [&](const auto& __value) { return __value == __old_value; }; | |
| 57 | return ranges::__replace_copy_if_impl( | |
| 58 | std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); | |
| 59 | } | |
| 40 | struct __fn { | |
| 41 | template <input_iterator _InIter, | |
| 42 | sentinel_for<_InIter> _Sent, | |
| 43 | class _OldType, | |
| 44 | class _NewType, | |
| 45 | output_iterator<const _NewType&> _OutIter, | |
| 46 | class _Proj = identity> | |
| 47 | requires indirectly_copyable<_InIter, _OutIter> && | |
| 48 | indirect_binary_predicate<ranges::equal_to, projected<_InIter, _Proj>, const _OldType*> | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> | |
| 50 | operator()(_InIter __first, | |
| 51 | _Sent __last, | |
| 52 | _OutIter __result, | |
| 53 | const _OldType& __old_value, | |
| 54 | const _NewType& __new_value, | |
| 55 | _Proj __proj = {}) const { | |
| 56 | auto __pred = [&](const auto& __value) { return __value == __old_value; }; | |
| 57 | return ranges::__replace_copy_if_impl( | |
| 58 | std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); | |
| 59 | } | |
| 60 | 60 | |
| 61 | template <input_range _Range, | |
| 62 | class _OldType, | |
| 63 | class _NewType, | |
| 64 | output_iterator<const _NewType&> _OutIter, | |
| 65 | class _Proj = identity> | |
| 66 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> && | |
| 67 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*> | |
| 68 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 69 | operator()(_Range&& __range, | |
| 70 | _OutIter __result, | |
| 71 | const _OldType& __old_value, | |
| 72 | const _NewType& __new_value, | |
| 73 | _Proj __proj = {}) const { | |
| 74 | auto __pred = [&](const auto& __value) { return __value == __old_value; }; | |
| 75 | return ranges::__replace_copy_if_impl( | |
| 76 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); | |
| 77 | } | |
| 78 | }; | |
| 61 | template <input_range _Range, | |
| 62 | class _OldType, | |
| 63 | class _NewType, | |
| 64 | output_iterator<const _NewType&> _OutIter, | |
| 65 | class _Proj = identity> | |
| 66 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> && | |
| 67 | indirect_binary_predicate<ranges::equal_to, projected<iterator_t<_Range>, _Proj>, const _OldType*> | |
| 68 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()( | |
| 69 | _Range&& __range, _OutIter __result, const _OldType& __old_value, const _NewType& __new_value, _Proj __proj = {}) | |
| 70 | const { | |
| 71 | auto __pred = [&](const auto& __value) { return __value == __old_value; }; | |
| 72 | return ranges::__replace_copy_if_impl( | |
| 73 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); | |
| 74 | } | |
| 75 | }; | |
| 79 | 76 | |
| 80 | 77 | } // namespace __replace_copy |
| 81 | 78 | |
| 82 | 79 | inline namespace __cpo { |
| 83 | inline constexpr auto replace_copy = __replace_copy::__fn{}; | |
| 80 | inline constexpr auto replace_copy = __replace_copy::__fn{}; | |
| 84 | 81 | } // namespace __cpo |
| 85 | 82 | } // namespace ranges |
| 86 | 83 | |
| 87 | 84 | _LIBCPP_END_NAMESPACE_STD |
| 88 | 85 | |
| 89 | #endif // _LIBCPP_STD_VER > 17 | |
| 86 | #endif // _LIBCPP_STD_VER >= 20 | |
| 90 | 87 | |
| 91 | 88 | #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H |
lib/libcxx/include/__algorithm/ranges_replace_copy_if.h+30-30| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -51,43 +51,43 @@ _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __repl |
| 51 | 51 | |
| 52 | 52 | namespace __replace_copy_if { |
| 53 | 53 | |
| 54 | struct __fn { | |
| 55 | template <input_iterator _InIter, | |
| 56 | sentinel_for<_InIter> _Sent, | |
| 57 | class _Type, | |
| 58 | output_iterator<const _Type&> _OutIter, | |
| 59 | class _Proj = identity, | |
| 60 | indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 61 | requires indirectly_copyable<_InIter, _OutIter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( | |
| 63 | _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) | |
| 64 | const { | |
| 65 | return ranges::__replace_copy_if_impl( | |
| 66 | std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); | |
| 67 | } | |
| 68 | ||
| 69 | template <input_range _Range, | |
| 70 | class _Type, | |
| 71 | output_iterator<const _Type&> _OutIter, | |
| 72 | class _Proj = identity, | |
| 73 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 74 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> | |
| 75 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 76 | operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { | |
| 77 | return ranges::__replace_copy_if_impl( | |
| 78 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); | |
| 79 | } | |
| 80 | }; | |
| 54 | struct __fn { | |
| 55 | template <input_iterator _InIter, | |
| 56 | sentinel_for<_InIter> _Sent, | |
| 57 | class _Type, | |
| 58 | output_iterator<const _Type&> _OutIter, | |
| 59 | class _Proj = identity, | |
| 60 | indirect_unary_predicate<projected<_InIter, _Proj>> _Pred> | |
| 61 | requires indirectly_copyable<_InIter, _OutIter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( | |
| 63 | _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) | |
| 64 | const { | |
| 65 | return ranges::__replace_copy_if_impl( | |
| 66 | std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); | |
| 67 | } | |
| 68 | ||
| 69 | template <input_range _Range, | |
| 70 | class _Type, | |
| 71 | output_iterator<const _Type&> _OutIter, | |
| 72 | class _Proj = identity, | |
| 73 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> | |
| 74 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> | |
| 75 | _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 76 | operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { | |
| 77 | return ranges::__replace_copy_if_impl( | |
| 78 | ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); | |
| 79 | } | |
| 80 | }; | |
| 81 | 81 | |
| 82 | 82 | } // namespace __replace_copy_if |
| 83 | 83 | |
| 84 | 84 | inline namespace __cpo { |
| 85 | inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; | |
| 85 | inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; | |
| 86 | 86 | } // namespace __cpo |
| 87 | 87 | } // namespace ranges |
| 88 | 88 | |
| 89 | 89 | _LIBCPP_END_NAMESPACE_STD |
| 90 | 90 | |
| 91 | #endif // _LIBCPP_STD_VER > 17 | |
| 91 | #endif // _LIBCPP_STD_VER >= 20 | |
| 92 | 92 | |
| 93 | 93 | #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H |
lib/libcxx/include/__algorithm/ranges_replace_if.h+9-10| ... | ... | @@ -23,15 +23,15 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | namespace ranges { |
| 31 | 31 | |
| 32 | 32 | template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred> |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 34 | _Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { | |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 34 | __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { | |
| 35 | 35 | for (; __first != __last; ++__first) { |
| 36 | 36 | if (std::invoke(__pred, std::invoke(__proj, *__first))) |
| 37 | 37 | *__first = __new_value; |
| ... | ... | @@ -41,14 +41,14 @@ _Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& |
| 41 | 41 | |
| 42 | 42 | namespace __replace_if { |
| 43 | 43 | struct __fn { |
| 44 | ||
| 45 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 44 | template <input_iterator _Iter, | |
| 45 | sentinel_for<_Iter> _Sent, | |
| 46 | 46 | class _Type, |
| 47 | 47 | class _Proj = identity, |
| 48 | 48 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 49 | 49 | requires indirectly_writable<_Iter, const _Type&> |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 51 | operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { | |
| 52 | 52 | return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); |
| 53 | 53 | } |
| 54 | 54 | |
| ... | ... | @@ -61,17 +61,16 @@ struct __fn { |
| 61 | 61 | operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { |
| 62 | 62 | return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); |
| 63 | 63 | } |
| 64 | ||
| 65 | 64 | }; |
| 66 | 65 | } // namespace __replace_if |
| 67 | 66 | |
| 68 | 67 | inline namespace __cpo { |
| 69 | inline constexpr auto replace_if = __replace_if::__fn{}; | |
| 68 | inline constexpr auto replace_if = __replace_if::__fn{}; | |
| 70 | 69 | } // namespace __cpo |
| 71 | 70 | } // namespace ranges |
| 72 | 71 | |
| 73 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 74 | 73 | |
| 75 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 76 | 75 | |
| 77 | 76 | #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H |
lib/libcxx/include/__algorithm/ranges_reverse.h+5-9| ... | ... | @@ -22,18 +22,16 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | namespace ranges { |
| 30 | 30 | namespace __reverse { |
| 31 | 31 | struct __fn { |
| 32 | ||
| 33 | 32 | template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent> |
| 34 | 33 | requires permutable<_Iter> |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 36 | _Iter operator()(_Iter __first, _Sent __last) const { | |
| 34 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const { | |
| 37 | 35 | if constexpr (random_access_iterator<_Iter>) { |
| 38 | 36 | if (__first == __last) |
| 39 | 37 | return __first; |
| ... | ... | @@ -63,21 +61,19 @@ struct __fn { |
| 63 | 61 | |
| 64 | 62 | template <bidirectional_range _Range> |
| 65 | 63 | requires permutable<iterator_t<_Range>> |
| 66 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 67 | borrowed_iterator_t<_Range> operator()(_Range&& __range) const { | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const { | |
| 68 | 65 | return (*this)(ranges::begin(__range), ranges::end(__range)); |
| 69 | 66 | } |
| 70 | ||
| 71 | 67 | }; |
| 72 | 68 | } // namespace __reverse |
| 73 | 69 | |
| 74 | 70 | inline namespace __cpo { |
| 75 | inline constexpr auto reverse = __reverse::__fn{}; | |
| 71 | inline constexpr auto reverse = __reverse::__fn{}; | |
| 76 | 72 | } // namespace __cpo |
| 77 | 73 | } // namespace ranges |
| 78 | 74 | |
| 79 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 80 | 76 | |
| 81 | #endif // _LIBCPP_STD_VER > 17 | |
| 77 | #endif // _LIBCPP_STD_VER >= 20 | |
| 82 | 78 | |
| 83 | 79 | #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H |
lib/libcxx/include/__algorithm/ranges_reverse_copy.h+7-9| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -36,32 +36,30 @@ using reverse_copy_result = in_out_result<_InIter, _OutIter>; |
| 36 | 36 | |
| 37 | 37 | namespace __reverse_copy { |
| 38 | 38 | struct __fn { |
| 39 | ||
| 40 | 39 | template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter> |
| 41 | 40 | requires indirectly_copyable<_InIter, _OutIter> |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 43 | reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<_InIter, _OutIter> | |
| 42 | operator()(_InIter __first, _Sent __last, _OutIter __result) const { | |
| 44 | 43 | return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result)); |
| 45 | 44 | } |
| 46 | 45 | |
| 47 | 46 | template <bidirectional_range _Range, weakly_incrementable _OutIter> |
| 48 | 47 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 50 | reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, _OutIter __result) const { | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 49 | operator()(_Range&& __range, _OutIter __result) const { | |
| 51 | 50 | auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result)); |
| 52 | 51 | return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)}; |
| 53 | 52 | } |
| 54 | ||
| 55 | 53 | }; |
| 56 | 54 | } // namespace __reverse_copy |
| 57 | 55 | |
| 58 | 56 | inline namespace __cpo { |
| 59 | inline constexpr auto reverse_copy = __reverse_copy::__fn{}; | |
| 57 | inline constexpr auto reverse_copy = __reverse_copy::__fn{}; | |
| 60 | 58 | } // namespace __cpo |
| 61 | 59 | } // namespace ranges |
| 62 | 60 | |
| 63 | 61 | _LIBCPP_END_NAMESPACE_STD |
| 64 | 62 | |
| 65 | #endif // _LIBCPP_STD_VER > 17 | |
| 63 | #endif // _LIBCPP_STD_VER >= 20 | |
| 66 | 64 | |
| 67 | 65 | #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H |
lib/libcxx/include/__algorithm/ranges_rotate.h+9-14| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| ... | ... | @@ -33,39 +33,34 @@ namespace ranges { |
| 33 | 33 | namespace __rotate { |
| 34 | 34 | |
| 35 | 35 | struct __fn { |
| 36 | ||
| 37 | 36 | template <class _Iter, class _Sent> |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 39 | static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { | |
| 40 | auto __ret = std::__rotate<_RangeAlgPolicy>( | |
| 41 | std::move(__first), std::move(__middle), std::move(__last)); | |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { | |
| 38 | auto __ret = std::__rotate<_RangeAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)); | |
| 42 | 39 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 43 | 40 | } |
| 44 | 41 | |
| 45 | 42 | template <permutable _Iter, sentinel_for<_Iter> _Sent> |
| 46 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 47 | subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { | |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { | |
| 48 | 44 | return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last)); |
| 49 | 45 | } |
| 50 | 46 | |
| 51 | 47 | template <forward_range _Range> |
| 52 | requires permutable<iterator_t<_Range>> | |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 54 | borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const { | |
| 48 | requires permutable<iterator_t<_Range>> | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 50 | operator()(_Range&& __range, iterator_t<_Range> __middle) const { | |
| 55 | 51 | return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range)); |
| 56 | 52 | } |
| 57 | ||
| 58 | 53 | }; |
| 59 | 54 | |
| 60 | 55 | } // namespace __rotate |
| 61 | 56 | |
| 62 | 57 | inline namespace __cpo { |
| 63 | inline constexpr auto rotate = __rotate::__fn{}; | |
| 58 | inline constexpr auto rotate = __rotate::__fn{}; | |
| 64 | 59 | } // namespace __cpo |
| 65 | 60 | } // namespace ranges |
| 66 | 61 | |
| 67 | 62 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 63 | |
| 69 | #endif // _LIBCPP_STD_VER > 17 | |
| 64 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 65 | |
| 71 | 66 | #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H |
lib/libcxx/include/__algorithm/ranges_rotate_copy.h+5-9| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| ... | ... | @@ -34,11 +34,9 @@ using rotate_copy_result = in_out_result<_InIter, _OutIter>; |
| 34 | 34 | |
| 35 | 35 | namespace __rotate_copy { |
| 36 | 36 | struct __fn { |
| 37 | ||
| 38 | 37 | template <bidirectional_iterator _InIter, sentinel_for<_InIter> _Sent, weakly_incrementable _OutIter> |
| 39 | 38 | requires indirectly_copyable<_InIter, _OutIter> |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 41 | rotate_copy_result<_InIter, _OutIter> | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<_InIter, _OutIter> | |
| 42 | 40 | operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const { |
| 43 | 41 | auto __res1 = ranges::copy(__middle, __last, std::move(__result)); |
| 44 | 42 | auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out)); |
| ... | ... | @@ -47,22 +45,20 @@ struct __fn { |
| 47 | 45 | |
| 48 | 46 | template <bidirectional_range _Range, weakly_incrementable _OutIter> |
| 49 | 47 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 52 | 49 | operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const { |
| 53 | 50 | return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result)); |
| 54 | 51 | } |
| 55 | ||
| 56 | 52 | }; |
| 57 | 53 | } // namespace __rotate_copy |
| 58 | 54 | |
| 59 | 55 | inline namespace __cpo { |
| 60 | inline constexpr auto rotate_copy = __rotate_copy::__fn{}; | |
| 56 | inline constexpr auto rotate_copy = __rotate_copy::__fn{}; | |
| 61 | 57 | } // namespace __cpo |
| 62 | 58 | } // namespace ranges |
| 63 | 59 | |
| 64 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 65 | 61 | |
| 66 | #endif // _LIBCPP_STD_VER > 17 | |
| 62 | #endif // _LIBCPP_STD_VER >= 20 | |
| 67 | 63 | |
| 68 | 64 | #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H |
lib/libcxx/include/__algorithm/ranges_sample.h+14-19| ... | ... | @@ -19,15 +19,15 @@ |
| 19 | 19 | #include <__random/uniform_random_bit_generator.h> |
| 20 | 20 | #include <__ranges/access.h> |
| 21 | 21 | #include <__ranges/concepts.h> |
| 22 | #include <__type_traits/remove_reference.h> | |
| 22 | 23 | #include <__utility/forward.h> |
| 23 | 24 | #include <__utility/move.h> |
| 24 | #include <type_traits> | |
| 25 | 25 | |
| 26 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -35,40 +35,35 @@ namespace ranges { |
| 35 | 35 | namespace __sample { |
| 36 | 36 | |
| 37 | 37 | struct __fn { |
| 38 | ||
| 39 | 38 | template <input_iterator _Iter, sentinel_for<_Iter> _Sent, weakly_incrementable _OutIter, class _Gen> |
| 40 | requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) && | |
| 41 | indirectly_copyable<_Iter, _OutIter> && | |
| 42 | uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 43 | _LIBCPP_HIDE_FROM_ABI | |
| 44 | _OutIter operator()(_Iter __first, _Sent __last, | |
| 45 | _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { | |
| 39 | requires(forward_iterator<_Iter> || random_access_iterator<_OutIter>) && indirectly_copyable<_Iter, _OutIter> && | |
| 40 | uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 41 | _LIBCPP_HIDE_FROM_ABI _OutIter | |
| 42 | operator()(_Iter __first, _Sent __last, _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { | |
| 46 | 43 | _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); |
| 47 | 44 | return std::__sample<_RangeAlgPolicy>( |
| 48 | 45 | std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen); |
| 49 | 46 | } |
| 50 | 47 | |
| 51 | 48 | template <input_range _Range, weakly_incrementable _OutIter, class _Gen> |
| 52 | requires (forward_range<_Range> || random_access_iterator<_OutIter>) && | |
| 53 | indirectly_copyable<iterator_t<_Range>, _OutIter> && | |
| 54 | uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 55 | _LIBCPP_HIDE_FROM_ABI | |
| 56 | _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { | |
| 57 | return (*this)(ranges::begin(__range), ranges::end(__range), | |
| 58 | std::move(__out_first), __n, std::forward<_Gen>(__gen)); | |
| 49 | requires(forward_range<_Range> || random_access_iterator<_OutIter>) && | |
| 50 | indirectly_copyable<iterator_t<_Range>, _OutIter> && uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 51 | _LIBCPP_HIDE_FROM_ABI _OutIter | |
| 52 | operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { | |
| 53 | return (*this)( | |
| 54 | ranges::begin(__range), ranges::end(__range), std::move(__out_first), __n, std::forward<_Gen>(__gen)); | |
| 59 | 55 | } |
| 60 | ||
| 61 | 56 | }; |
| 62 | 57 | |
| 63 | 58 | } // namespace __sample |
| 64 | 59 | |
| 65 | 60 | inline namespace __cpo { |
| 66 | inline constexpr auto sample = __sample::__fn{}; | |
| 61 | inline constexpr auto sample = __sample::__fn{}; | |
| 67 | 62 | } // namespace __cpo |
| 68 | 63 | } // namespace ranges |
| 69 | 64 | |
| 70 | 65 | _LIBCPP_END_NAMESPACE_STD |
| 71 | 66 | |
| 72 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 73 | 68 | |
| 74 | 69 | #endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H |
lib/libcxx/include/__algorithm/ranges_search.h+19-20| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 34 | |
| ... | ... | @@ -69,33 +69,33 @@ struct __fn { |
| 69 | 69 | return {__ret.first, __ret.second}; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | template <forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1, | |
| 73 | forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, | |
| 74 | class _Pred = ranges::equal_to, | |
| 72 | template <forward_iterator _Iter1, | |
| 73 | sentinel_for<_Iter1> _Sent1, | |
| 74 | forward_iterator _Iter2, | |
| 75 | sentinel_for<_Iter2> _Sent2, | |
| 76 | class _Pred = ranges::equal_to, | |
| 75 | 77 | class _Proj1 = identity, |
| 76 | 78 | class _Proj2 = identity> |
| 77 | 79 | requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> |
| 78 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 79 | subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, | |
| 80 | _Iter2 __first2, _Sent2 __last2, | |
| 81 | _Pred __pred = {}, | |
| 82 | _Proj1 __proj1 = {}, | |
| 83 | _Proj2 __proj2 = {}) const { | |
| 80 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( | |
| 81 | _Iter1 __first1, | |
| 82 | _Sent1 __last1, | |
| 83 | _Iter2 __first2, | |
| 84 | _Sent2 __last2, | |
| 85 | _Pred __pred = {}, | |
| 86 | _Proj1 __proj1 = {}, | |
| 87 | _Proj2 __proj2 = {}) const { | |
| 84 | 88 | return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); |
| 85 | 89 | } |
| 86 | 90 | |
| 87 | 91 | template <forward_range _Range1, |
| 88 | 92 | forward_range _Range2, |
| 89 | class _Pred = ranges::equal_to, | |
| 93 | class _Pred = ranges::equal_to, | |
| 90 | 94 | class _Proj1 = identity, |
| 91 | 95 | class _Proj2 = identity> |
| 92 | 96 | requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> |
| 93 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 94 | borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, | |
| 95 | _Range2&& __range2, | |
| 96 | _Pred __pred = {}, | |
| 97 | _Proj1 __proj1 = {}, | |
| 98 | _Proj2 __proj2 = {}) const { | |
| 97 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( | |
| 98 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 99 | 99 | auto __first1 = ranges::begin(__range1); |
| 100 | 100 | if constexpr (sized_range<_Range2>) { |
| 101 | 101 | auto __size2 = ranges::size(__range2); |
| ... | ... | @@ -119,17 +119,16 @@ struct __fn { |
| 119 | 119 | __proj1, |
| 120 | 120 | __proj2); |
| 121 | 121 | } |
| 122 | ||
| 123 | 122 | }; |
| 124 | 123 | } // namespace __search |
| 125 | 124 | |
| 126 | 125 | inline namespace __cpo { |
| 127 | inline constexpr auto search = __search::__fn{}; | |
| 126 | inline constexpr auto search = __search::__fn{}; | |
| 128 | 127 | } // namespace __cpo |
| 129 | 128 | } // namespace ranges |
| 130 | 129 | |
| 131 | 130 | _LIBCPP_END_NAMESPACE_STD |
| 132 | 131 | |
| 133 | #endif // _LIBCPP_STD_VER > 17 | |
| 132 | #endif // _LIBCPP_STD_VER >= 20 | |
| 134 | 133 | |
| 135 | 134 | #endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H |
lib/libcxx/include/__algorithm/ranges_search_n.h+16-22| ... | ... | @@ -31,14 +31,13 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| 38 | 38 | namespace ranges { |
| 39 | 39 | namespace __search_n { |
| 40 | 40 | struct __fn { |
| 41 | ||
| 42 | 41 | template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj> |
| 43 | 42 | _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl( |
| 44 | 43 | _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { |
| ... | ... | @@ -59,36 +58,31 @@ struct __fn { |
| 59 | 58 | } |
| 60 | 59 | } |
| 61 | 60 | |
| 62 | auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, | |
| 63 | __count, | |
| 64 | __value, | |
| 65 | __pred, | |
| 66 | __proj); | |
| 61 | auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, __count, __value, __pred, __proj); | |
| 67 | 62 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 68 | 63 | } |
| 69 | 64 | |
| 70 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, | |
| 65 | template <forward_iterator _Iter, | |
| 66 | sentinel_for<_Iter> _Sent, | |
| 71 | 67 | class _Type, |
| 72 | 68 | class _Pred = ranges::equal_to, |
| 73 | 69 | class _Proj = identity> |
| 74 | 70 | requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> |
| 75 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 76 | subrange<_Iter> operator()(_Iter __first, _Sent __last, | |
| 77 | iter_difference_t<_Iter> __count, | |
| 78 | const _Type& __value, | |
| 79 | _Pred __pred = {}, | |
| 80 | _Proj __proj = _Proj{}) const { | |
| 71 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 72 | operator()(_Iter __first, | |
| 73 | _Sent __last, | |
| 74 | iter_difference_t<_Iter> __count, | |
| 75 | const _Type& __value, | |
| 76 | _Pred __pred = {}, | |
| 77 | _Proj __proj = _Proj{}) const { | |
| 81 | 78 | return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj); |
| 82 | 79 | } |
| 83 | 80 | |
| 84 | 81 | template <forward_range _Range, class _Type, class _Pred = ranges::equal_to, class _Proj = identity> |
| 85 | 82 | requires indirectly_comparable<iterator_t<_Range>, const _Type*, _Pred, _Proj> |
| 86 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 87 | borrowed_subrange_t<_Range> operator()(_Range&& __range, | |
| 88 | range_difference_t<_Range> __count, | |
| 89 | const _Type& __value, | |
| 90 | _Pred __pred = {}, | |
| 91 | _Proj __proj = {}) const { | |
| 83 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( | |
| 84 | _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {}) | |
| 85 | const { | |
| 92 | 86 | auto __first = ranges::begin(__range); |
| 93 | 87 | if (__count <= 0) |
| 94 | 88 | return {__first, __first}; |
| ... | ... | @@ -106,12 +100,12 @@ struct __fn { |
| 106 | 100 | } // namespace __search_n |
| 107 | 101 | |
| 108 | 102 | inline namespace __cpo { |
| 109 | inline constexpr auto search_n = __search_n::__fn{}; | |
| 103 | inline constexpr auto search_n = __search_n::__fn{}; | |
| 110 | 104 | } // namespace __cpo |
| 111 | 105 | } // namespace ranges |
| 112 | 106 | |
| 113 | 107 | _LIBCPP_END_NAMESPACE_STD |
| 114 | 108 | |
| 115 | #endif // _LIBCPP_STD_VER > 17 | |
| 109 | #endif // _LIBCPP_STD_VER >= 20 | |
| 116 | 110 | |
| 117 | 111 | #endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H |
lib/libcxx/include/__algorithm/ranges_set_difference.h+23-26| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | # pragma GCC system_header |
| 31 | 31 | #endif |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 36 | |
| ... | ... | @@ -42,15 +42,14 @@ using set_difference_result = in_out_result<_InIter, _OutIter>; |
| 42 | 42 | namespace __set_difference { |
| 43 | 43 | |
| 44 | 44 | struct __fn { |
| 45 | template < | |
| 46 | input_iterator _InIter1, | |
| 47 | sentinel_for<_InIter1> _Sent1, | |
| 48 | input_iterator _InIter2, | |
| 49 | sentinel_for<_InIter2> _Sent2, | |
| 50 | weakly_incrementable _OutIter, | |
| 51 | class _Comp = less, | |
| 52 | class _Proj1 = identity, | |
| 53 | class _Proj2 = identity> | |
| 45 | template <input_iterator _InIter1, | |
| 46 | sentinel_for<_InIter1> _Sent1, | |
| 47 | input_iterator _InIter2, | |
| 48 | sentinel_for<_InIter2> _Sent2, | |
| 49 | weakly_incrementable _OutIter, | |
| 50 | class _Comp = less, | |
| 51 | class _Proj1 = identity, | |
| 52 | class _Proj2 = identity> | |
| 54 | 53 | requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> |
| 55 | 54 | _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()( |
| 56 | 55 | _InIter1 __first1, |
| ... | ... | @@ -66,22 +65,20 @@ struct __fn { |
| 66 | 65 | return {std::move(__ret.first), std::move(__ret.second)}; |
| 67 | 66 | } |
| 68 | 67 | |
| 69 | template < | |
| 70 | input_range _Range1, | |
| 71 | input_range _Range2, | |
| 72 | weakly_incrementable _OutIter, | |
| 73 | class _Comp = less, | |
| 74 | class _Proj1 = identity, | |
| 75 | class _Proj2 = identity> | |
| 68 | template <input_range _Range1, | |
| 69 | input_range _Range2, | |
| 70 | weakly_incrementable _OutIter, | |
| 71 | class _Comp = less, | |
| 72 | class _Proj1 = identity, | |
| 73 | class _Proj2 = identity> | |
| 76 | 74 | requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> |
| 77 | 75 | _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<borrowed_iterator_t<_Range1>, _OutIter> |
| 78 | operator()( | |
| 79 | _Range1&& __range1, | |
| 80 | _Range2&& __range2, | |
| 81 | _OutIter __result, | |
| 82 | _Comp __comp = {}, | |
| 83 | _Proj1 __proj1 = {}, | |
| 84 | _Proj2 __proj2 = {}) const { | |
| 76 | operator()(_Range1&& __range1, | |
| 77 | _Range2&& __range2, | |
| 78 | _OutIter __result, | |
| 79 | _Comp __comp = {}, | |
| 80 | _Proj1 __proj1 = {}, | |
| 81 | _Proj2 __proj2 = {}) const { | |
| 85 | 82 | auto __ret = std::__set_difference<_RangeAlgPolicy>( |
| 86 | 83 | ranges::begin(__range1), |
| 87 | 84 | ranges::end(__range1), |
| ... | ... | @@ -96,11 +93,11 @@ struct __fn { |
| 96 | 93 | } // namespace __set_difference |
| 97 | 94 | |
| 98 | 95 | inline namespace __cpo { |
| 99 | inline constexpr auto set_difference = __set_difference::__fn{}; | |
| 96 | inline constexpr auto set_difference = __set_difference::__fn{}; | |
| 100 | 97 | } // namespace __cpo |
| 101 | 98 | } // namespace ranges |
| 102 | 99 | |
| 103 | 100 | _LIBCPP_END_NAMESPACE_STD |
| 104 | 101 | |
| 105 | #endif // _LIBCPP_STD_VER > 17 | |
| 102 | #endif // _LIBCPP_STD_VER >= 20 | |
| 106 | 103 | #endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H |
lib/libcxx/include/__algorithm/ranges_set_intersection.h+27-36| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 34 | |
| ... | ... | @@ -40,15 +40,14 @@ using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; |
| 40 | 40 | namespace __set_intersection { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | template < | |
| 44 | input_iterator _InIter1, | |
| 45 | sentinel_for<_InIter1> _Sent1, | |
| 46 | input_iterator _InIter2, | |
| 47 | sentinel_for<_InIter2> _Sent2, | |
| 48 | weakly_incrementable _OutIter, | |
| 49 | class _Comp = less, | |
| 50 | class _Proj1 = identity, | |
| 51 | class _Proj2 = identity> | |
| 43 | template <input_iterator _InIter1, | |
| 44 | sentinel_for<_InIter1> _Sent1, | |
| 45 | input_iterator _InIter2, | |
| 46 | sentinel_for<_InIter2> _Sent2, | |
| 47 | weakly_incrementable _OutIter, | |
| 48 | class _Comp = less, | |
| 49 | class _Proj1 = identity, | |
| 50 | class _Proj2 = identity> | |
| 52 | 51 | requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> |
| 53 | 52 | _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()( |
| 54 | 53 | _InIter1 __first1, |
| ... | ... | @@ -69,30 +68,22 @@ struct __fn { |
| 69 | 68 | return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; |
| 70 | 69 | } |
| 71 | 70 | |
| 72 | template < | |
| 73 | input_range _Range1, | |
| 74 | input_range _Range2, | |
| 75 | weakly_incrementable _OutIter, | |
| 76 | class _Comp = less, | |
| 77 | class _Proj1 = identity, | |
| 78 | class _Proj2 = identity> | |
| 79 | requires mergeable< | |
| 80 | iterator_t<_Range1>, | |
| 81 | iterator_t<_Range2>, | |
| 82 | _OutIter, | |
| 83 | _Comp, | |
| 84 | _Proj1, | |
| 85 | _Proj2> | |
| 86 | _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>, | |
| 87 | borrowed_iterator_t<_Range2>, | |
| 88 | _OutIter> | |
| 89 | operator()( | |
| 90 | _Range1&& __range1, | |
| 91 | _Range2&& __range2, | |
| 92 | _OutIter __result, | |
| 93 | _Comp __comp = {}, | |
| 94 | _Proj1 __proj1 = {}, | |
| 95 | _Proj2 __proj2 = {}) const { | |
| 71 | template <input_range _Range1, | |
| 72 | input_range _Range2, | |
| 73 | weakly_incrementable _OutIter, | |
| 74 | class _Comp = less, | |
| 75 | class _Proj1 = identity, | |
| 76 | class _Proj2 = identity> | |
| 77 | requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> | |
| 78 | _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<borrowed_iterator_t<_Range1>, | |
| 79 | borrowed_iterator_t<_Range2>, | |
| 80 | _OutIter> | |
| 81 | operator()(_Range1&& __range1, | |
| 82 | _Range2&& __range2, | |
| 83 | _OutIter __result, | |
| 84 | _Comp __comp = {}, | |
| 85 | _Proj1 __proj1 = {}, | |
| 86 | _Proj2 __proj2 = {}) const { | |
| 96 | 87 | auto __ret = std::__set_intersection<_RangeAlgPolicy>( |
| 97 | 88 | ranges::begin(__range1), |
| 98 | 89 | ranges::end(__range1), |
| ... | ... | @@ -107,11 +98,11 @@ struct __fn { |
| 107 | 98 | } // namespace __set_intersection |
| 108 | 99 | |
| 109 | 100 | inline namespace __cpo { |
| 110 | inline constexpr auto set_intersection = __set_intersection::__fn{}; | |
| 101 | inline constexpr auto set_intersection = __set_intersection::__fn{}; | |
| 111 | 102 | } // namespace __cpo |
| 112 | 103 | } // namespace ranges |
| 113 | 104 | |
| 114 | 105 | _LIBCPP_END_NAMESPACE_STD |
| 115 | 106 | |
| 116 | #endif // _LIBCPP_STD_VER > 17 | |
| 107 | #endif // _LIBCPP_STD_VER >= 20 | |
| 117 | 108 | #endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H |
lib/libcxx/include/__algorithm/ranges_set_symmetric_difference.h+24-33| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 34 | |
| ... | ... | @@ -40,15 +40,14 @@ using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _Ou |
| 40 | 40 | namespace __set_symmetric_difference { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | template < | |
| 44 | input_iterator _InIter1, | |
| 45 | sentinel_for<_InIter1> _Sent1, | |
| 46 | input_iterator _InIter2, | |
| 47 | sentinel_for<_InIter2> _Sent2, | |
| 48 | weakly_incrementable _OutIter, | |
| 49 | class _Comp = ranges::less, | |
| 50 | class _Proj1 = identity, | |
| 51 | class _Proj2 = identity> | |
| 43 | template <input_iterator _InIter1, | |
| 44 | sentinel_for<_InIter1> _Sent1, | |
| 45 | input_iterator _InIter2, | |
| 46 | sentinel_for<_InIter2> _Sent2, | |
| 47 | weakly_incrementable _OutIter, | |
| 48 | class _Comp = ranges::less, | |
| 49 | class _Proj1 = identity, | |
| 50 | class _Proj2 = identity> | |
| 52 | 51 | requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> |
| 53 | 52 | _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()( |
| 54 | 53 | _InIter1 __first1, |
| ... | ... | @@ -69,30 +68,22 @@ struct __fn { |
| 69 | 68 | return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; |
| 70 | 69 | } |
| 71 | 70 | |
| 72 | template < | |
| 73 | input_range _Range1, | |
| 74 | input_range _Range2, | |
| 75 | weakly_incrementable _OutIter, | |
| 76 | class _Comp = ranges::less, | |
| 77 | class _Proj1 = identity, | |
| 78 | class _Proj2 = identity> | |
| 79 | requires mergeable< | |
| 80 | iterator_t<_Range1>, | |
| 81 | iterator_t<_Range2>, | |
| 82 | _OutIter, | |
| 83 | _Comp, | |
| 84 | _Proj1, | |
| 85 | _Proj2> | |
| 71 | template <input_range _Range1, | |
| 72 | input_range _Range2, | |
| 73 | weakly_incrementable _OutIter, | |
| 74 | class _Comp = ranges::less, | |
| 75 | class _Proj1 = identity, | |
| 76 | class _Proj2 = identity> | |
| 77 | requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> | |
| 86 | 78 | _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>, |
| 87 | 79 | borrowed_iterator_t<_Range2>, |
| 88 | 80 | _OutIter> |
| 89 | operator()( | |
| 90 | _Range1&& __range1, | |
| 91 | _Range2&& __range2, | |
| 92 | _OutIter __result, | |
| 93 | _Comp __comp = {}, | |
| 94 | _Proj1 __proj1 = {}, | |
| 95 | _Proj2 __proj2 = {}) const { | |
| 81 | operator()(_Range1&& __range1, | |
| 82 | _Range2&& __range2, | |
| 83 | _OutIter __result, | |
| 84 | _Comp __comp = {}, | |
| 85 | _Proj1 __proj1 = {}, | |
| 86 | _Proj2 __proj2 = {}) const { | |
| 96 | 87 | auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( |
| 97 | 88 | ranges::begin(__range1), |
| 98 | 89 | ranges::end(__range1), |
| ... | ... | @@ -107,11 +98,11 @@ struct __fn { |
| 107 | 98 | } // namespace __set_symmetric_difference |
| 108 | 99 | |
| 109 | 100 | inline namespace __cpo { |
| 110 | inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; | |
| 101 | inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; | |
| 111 | 102 | } // namespace __cpo |
| 112 | 103 | } // namespace ranges |
| 113 | 104 | |
| 114 | 105 | _LIBCPP_END_NAMESPACE_STD |
| 115 | 106 | |
| 116 | #endif // _LIBCPP_STD_VER > 17 | |
| 107 | #endif // _LIBCPP_STD_VER >= 20 | |
| 117 | 108 | #endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H |
lib/libcxx/include/__algorithm/ranges_set_union.h+25-36| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| ... | ... | @@ -43,15 +43,14 @@ using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; |
| 43 | 43 | namespace __set_union { |
| 44 | 44 | |
| 45 | 45 | struct __fn { |
| 46 | template < | |
| 47 | input_iterator _InIter1, | |
| 48 | sentinel_for<_InIter1> _Sent1, | |
| 49 | input_iterator _InIter2, | |
| 50 | sentinel_for<_InIter2> _Sent2, | |
| 51 | weakly_incrementable _OutIter, | |
| 52 | class _Comp = ranges::less, | |
| 53 | class _Proj1 = identity, | |
| 54 | class _Proj2 = identity> | |
| 46 | template <input_iterator _InIter1, | |
| 47 | sentinel_for<_InIter1> _Sent1, | |
| 48 | input_iterator _InIter2, | |
| 49 | sentinel_for<_InIter2> _Sent2, | |
| 50 | weakly_incrementable _OutIter, | |
| 51 | class _Comp = ranges::less, | |
| 52 | class _Proj1 = identity, | |
| 53 | class _Proj2 = identity> | |
| 55 | 54 | requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> |
| 56 | 55 | _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()( |
| 57 | 56 | _InIter1 __first1, |
| ... | ... | @@ -72,30 +71,20 @@ struct __fn { |
| 72 | 71 | return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; |
| 73 | 72 | } |
| 74 | 73 | |
| 75 | template < | |
| 76 | input_range _Range1, | |
| 77 | input_range _Range2, | |
| 78 | weakly_incrementable _OutIter, | |
| 79 | class _Comp = ranges::less, | |
| 80 | class _Proj1 = identity, | |
| 81 | class _Proj2 = identity> | |
| 82 | requires mergeable< | |
| 83 | iterator_t<_Range1>, | |
| 84 | iterator_t<_Range2>, | |
| 85 | _OutIter, | |
| 86 | _Comp, | |
| 87 | _Proj1, | |
| 88 | _Proj2> | |
| 89 | _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>, | |
| 90 | borrowed_iterator_t<_Range2>, | |
| 91 | _OutIter> | |
| 92 | operator()( | |
| 93 | _Range1&& __range1, | |
| 94 | _Range2&& __range2, | |
| 95 | _OutIter __result, | |
| 96 | _Comp __comp = {}, | |
| 97 | _Proj1 __proj1 = {}, | |
| 98 | _Proj2 __proj2 = {}) const { | |
| 74 | template <input_range _Range1, | |
| 75 | input_range _Range2, | |
| 76 | weakly_incrementable _OutIter, | |
| 77 | class _Comp = ranges::less, | |
| 78 | class _Proj1 = identity, | |
| 79 | class _Proj2 = identity> | |
| 80 | requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> | |
| 81 | _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter> | |
| 82 | operator()(_Range1&& __range1, | |
| 83 | _Range2&& __range2, | |
| 84 | _OutIter __result, | |
| 85 | _Comp __comp = {}, | |
| 86 | _Proj1 __proj1 = {}, | |
| 87 | _Proj2 __proj2 = {}) const { | |
| 99 | 88 | auto __ret = std::__set_union<_RangeAlgPolicy>( |
| 100 | 89 | ranges::begin(__range1), |
| 101 | 90 | ranges::end(__range1), |
| ... | ... | @@ -110,12 +99,12 @@ struct __fn { |
| 110 | 99 | } // namespace __set_union |
| 111 | 100 | |
| 112 | 101 | inline namespace __cpo { |
| 113 | inline constexpr auto set_union = __set_union::__fn{}; | |
| 102 | inline constexpr auto set_union = __set_union::__fn{}; | |
| 114 | 103 | } // namespace __cpo |
| 115 | 104 | } // namespace ranges |
| 116 | 105 | |
| 117 | 106 | _LIBCPP_END_NAMESPACE_STD |
| 118 | 107 | |
| 119 | #endif // _LIBCPP_STD_VER > 17 | |
| 108 | #endif // _LIBCPP_STD_VER >= 20 | |
| 120 | 109 | |
| 121 | 110 | #endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H |
lib/libcxx/include/__algorithm/ranges_shuffle.h+9-13| ... | ... | @@ -23,15 +23,15 @@ |
| 23 | 23 | #include <__ranges/access.h> |
| 24 | 24 | #include <__ranges/concepts.h> |
| 25 | 25 | #include <__ranges/dangling.h> |
| 26 | #include <__type_traits/remove_reference.h> | |
| 26 | 27 | #include <__utility/forward.h> |
| 27 | 28 | #include <__utility/move.h> |
| 28 | #include <type_traits> | |
| 29 | 29 | |
| 30 | 30 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| ... | ... | @@ -39,33 +39,29 @@ namespace ranges { |
| 39 | 39 | namespace __shuffle { |
| 40 | 40 | |
| 41 | 41 | struct __fn { |
| 42 | ||
| 43 | 42 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Gen> |
| 44 | requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 45 | _LIBCPP_HIDE_FROM_ABI | |
| 46 | _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { | |
| 43 | requires permutable<_Iter> && uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 44 | _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { | |
| 47 | 45 | _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); |
| 48 | 46 | return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen); |
| 49 | 47 | } |
| 50 | 48 | |
| 51 | template<random_access_range _Range, class _Gen> | |
| 52 | requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 53 | _LIBCPP_HIDE_FROM_ABI | |
| 54 | borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { | |
| 49 | template <random_access_range _Range, class _Gen> | |
| 50 | requires permutable<iterator_t<_Range>> && uniform_random_bit_generator<remove_reference_t<_Gen>> | |
| 51 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { | |
| 55 | 52 | return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen)); |
| 56 | 53 | } |
| 57 | ||
| 58 | 54 | }; |
| 59 | 55 | |
| 60 | 56 | } // namespace __shuffle |
| 61 | 57 | |
| 62 | 58 | inline namespace __cpo { |
| 63 | inline constexpr auto shuffle = __shuffle::__fn{}; | |
| 59 | inline constexpr auto shuffle = __shuffle::__fn{}; | |
| 64 | 60 | } // namespace __cpo |
| 65 | 61 | } // namespace ranges |
| 66 | 62 | |
| 67 | 63 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 64 | |
| 69 | #endif // _LIBCPP_STD_VER > 17 | |
| 65 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 66 | |
| 71 | 67 | #endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H |
lib/libcxx/include/__algorithm/ranges_sort.h+9-9| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| ... | ... | @@ -40,8 +40,8 @@ namespace __sort { |
| 40 | 40 | |
| 41 | 41 | struct __fn { |
| 42 | 42 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 44 | _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 44 | __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 45 | 45 | auto __last_iter = ranges::next(__first, __last); |
| 46 | 46 | |
| 47 | 47 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -52,15 +52,15 @@ struct __fn { |
| 52 | 52 | |
| 53 | 53 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 54 | 54 | requires sortable<_Iter, _Comp, _Proj> |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 56 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 56 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 57 | 57 | return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 61 | 61 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 63 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 63 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 64 | 64 | return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 65 | 65 | } |
| 66 | 66 | }; |
| ... | ... | @@ -68,12 +68,12 @@ struct __fn { |
| 68 | 68 | } // namespace __sort |
| 69 | 69 | |
| 70 | 70 | inline namespace __cpo { |
| 71 | inline constexpr auto sort = __sort::__fn{}; | |
| 71 | inline constexpr auto sort = __sort::__fn{}; | |
| 72 | 72 | } // namespace __cpo |
| 73 | 73 | } // namespace ranges |
| 74 | 74 | |
| 75 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 76 | |
| 77 | #endif // _LIBCPP_STD_VER > 17 | |
| 77 | #endif // _LIBCPP_STD_VER >= 20 | |
| 78 | 78 | |
| 79 | 79 | #endif // _LIBCPP___ALGORITHM_RANGES_SORT_H |
lib/libcxx/include/__algorithm/ranges_sort_heap.h+9-9| ... | ... | @@ -32,7 +32,7 @@ |
| 32 | 32 | # pragma GCC system_header |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 38 | |
| ... | ... | @@ -41,8 +41,8 @@ namespace __sort_heap { |
| 41 | 41 | |
| 42 | 42 | struct __fn { |
| 43 | 43 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static | |
| 45 | _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr static _Iter | |
| 45 | __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 46 | 46 | auto __last_iter = ranges::next(__first, __last); |
| 47 | 47 | |
| 48 | 48 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -53,15 +53,15 @@ struct __fn { |
| 53 | 53 | |
| 54 | 54 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 55 | 55 | requires sortable<_Iter, _Comp, _Proj> |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 57 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 56 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 57 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 58 | 58 | return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 62 | 62 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 64 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 63 | _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 64 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 65 | 65 | return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 66 | 66 | } |
| 67 | 67 | }; |
| ... | ... | @@ -69,12 +69,12 @@ struct __fn { |
| 69 | 69 | } // namespace __sort_heap |
| 70 | 70 | |
| 71 | 71 | inline namespace __cpo { |
| 72 | inline constexpr auto sort_heap = __sort_heap::__fn{}; | |
| 72 | inline constexpr auto sort_heap = __sort_heap::__fn{}; | |
| 73 | 73 | } // namespace __cpo |
| 74 | 74 | } // namespace ranges |
| 75 | 75 | |
| 76 | 76 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 77 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 78 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 79 | |
| 80 | 80 | #endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H |
lib/libcxx/include/__algorithm/ranges_stable_partition.h+17-18| ... | ... | @@ -26,15 +26,15 @@ |
| 26 | 26 | #include <__ranges/concepts.h> |
| 27 | 27 | #include <__ranges/dangling.h> |
| 28 | 28 | #include <__ranges/subrange.h> |
| 29 | #include <__type_traits/remove_cvref.h> | |
| 29 | 30 | #include <__utility/forward.h> |
| 30 | 31 | #include <__utility/move.h> |
| 31 | #include <type_traits> | |
| 32 | 32 | |
| 33 | 33 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 34 | 34 | # pragma GCC system_header |
| 35 | 35 | #endif |
| 36 | 36 | |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 40 | 40 | |
| ... | ... | @@ -42,47 +42,46 @@ namespace ranges { |
| 42 | 42 | namespace __stable_partition { |
| 43 | 43 | |
| 44 | 44 | struct __fn { |
| 45 | ||
| 46 | 45 | template <class _Iter, class _Sent, class _Proj, class _Pred> |
| 47 | _LIBCPP_HIDE_FROM_ABI static | |
| 48 | subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl( | |
| 49 | _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { | |
| 46 | _LIBCPP_HIDE_FROM_ABI static subrange<__remove_cvref_t<_Iter>> | |
| 47 | __stable_partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { | |
| 50 | 48 | auto __last_iter = ranges::next(__first, __last); |
| 51 | 49 | |
| 52 | 50 | auto&& __projected_pred = std::__make_projected(__pred, __proj); |
| 53 | auto __result = std::__stable_partition<_RangeAlgPolicy>( | |
| 51 | auto __result = std::__stable_partition<_RangeAlgPolicy>( | |
| 54 | 52 | std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>()); |
| 55 | 53 | |
| 56 | 54 | return {std::move(__result), std::move(__last_iter)}; |
| 57 | 55 | } |
| 58 | 56 | |
| 59 | template <bidirectional_iterator _Iter, sentinel_for<_Iter> _Sent, class _Proj = identity, | |
| 57 | template <bidirectional_iterator _Iter, | |
| 58 | sentinel_for<_Iter> _Sent, | |
| 59 | class _Proj = identity, | |
| 60 | 60 | indirect_unary_predicate<projected<_Iter, _Proj>> _Pred> |
| 61 | requires permutable<_Iter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI | |
| 63 | subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 61 | requires permutable<_Iter> | |
| 62 | _LIBCPP_HIDE_FROM_ABI subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { | |
| 64 | 63 | return __stable_partition_fn_impl(__first, __last, __pred, __proj); |
| 65 | 64 | } |
| 66 | 65 | |
| 67 | template <bidirectional_range _Range, class _Proj = identity, | |
| 66 | template <bidirectional_range _Range, | |
| 67 | class _Proj = identity, | |
| 68 | 68 | indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>> _Pred> |
| 69 | requires permutable<iterator_t<_Range>> | |
| 70 | _LIBCPP_HIDE_FROM_ABI | |
| 71 | borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 69 | requires permutable<iterator_t<_Range>> | |
| 70 | _LIBCPP_HIDE_FROM_ABI borrowed_subrange_t<_Range> | |
| 71 | operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { | |
| 72 | 72 | return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); |
| 73 | 73 | } |
| 74 | ||
| 75 | 74 | }; |
| 76 | 75 | |
| 77 | 76 | } // namespace __stable_partition |
| 78 | 77 | |
| 79 | 78 | inline namespace __cpo { |
| 80 | inline constexpr auto stable_partition = __stable_partition::__fn{}; | |
| 79 | inline constexpr auto stable_partition = __stable_partition::__fn{}; | |
| 81 | 80 | } // namespace __cpo |
| 82 | 81 | } // namespace ranges |
| 83 | 82 | |
| 84 | 83 | _LIBCPP_END_NAMESPACE_STD |
| 85 | 84 | |
| 86 | #endif // _LIBCPP_STD_VER > 17 | |
| 85 | #endif // _LIBCPP_STD_VER >= 20 | |
| 87 | 86 | |
| 88 | 87 | #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H |
lib/libcxx/include/__algorithm/ranges_stable_sort.h+7-9| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 37 | |
| ... | ... | @@ -40,8 +40,7 @@ namespace __stable_sort { |
| 40 | 40 | |
| 41 | 41 | struct __fn { |
| 42 | 42 | template <class _Iter, class _Sent, class _Comp, class _Proj> |
| 43 | _LIBCPP_HIDE_FROM_ABI | |
| 44 | static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 43 | _LIBCPP_HIDE_FROM_ABI static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { | |
| 45 | 44 | auto __last_iter = ranges::next(__first, __last); |
| 46 | 45 | |
| 47 | 46 | auto&& __projected_comp = std::__make_projected(__comp, __proj); |
| ... | ... | @@ -52,15 +51,14 @@ struct __fn { |
| 52 | 51 | |
| 53 | 52 | template <random_access_iterator _Iter, sentinel_for<_Iter> _Sent, class _Comp = ranges::less, class _Proj = identity> |
| 54 | 53 | requires sortable<_Iter, _Comp, _Proj> |
| 55 | _LIBCPP_HIDE_FROM_ABI | |
| 56 | _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 54 | _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 57 | 55 | return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); |
| 58 | 56 | } |
| 59 | 57 | |
| 60 | 58 | template <random_access_range _Range, class _Comp = ranges::less, class _Proj = identity> |
| 61 | 59 | requires sortable<iterator_t<_Range>, _Comp, _Proj> |
| 62 | _LIBCPP_HIDE_FROM_ABI | |
| 63 | borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 60 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> | |
| 61 | operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 64 | 62 | return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); |
| 65 | 63 | } |
| 66 | 64 | }; |
| ... | ... | @@ -68,12 +66,12 @@ struct __fn { |
| 68 | 66 | } // namespace __stable_sort |
| 69 | 67 | |
| 70 | 68 | inline namespace __cpo { |
| 71 | inline constexpr auto stable_sort = __stable_sort::__fn{}; | |
| 69 | inline constexpr auto stable_sort = __stable_sort::__fn{}; | |
| 72 | 70 | } // namespace __cpo |
| 73 | 71 | } // namespace ranges |
| 74 | 72 | |
| 75 | 73 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 74 | |
| 77 | #endif // _LIBCPP_STD_VER > 17 | |
| 75 | #endif // _LIBCPP_STD_VER >= 20 | |
| 78 | 76 | |
| 79 | 77 | #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H |
lib/libcxx/include/__algorithm/ranges_starts_with.h created+90| ... | ... | @@ -0,0 +1,90 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H | |
| 10 | #define _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H | |
| 11 | ||
| 12 | #include <__algorithm/in_in_result.h> | |
| 13 | #include <__algorithm/ranges_mismatch.h> | |
| 14 | #include <__config> | |
| 15 | #include <__functional/identity.h> | |
| 16 | #include <__functional/ranges_operations.h> | |
| 17 | #include <__iterator/concepts.h> | |
| 18 | #include <__iterator/indirectly_comparable.h> | |
| 19 | #include <__ranges/access.h> | |
| 20 | #include <__ranges/concepts.h> | |
| 21 | #include <__utility/move.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | #if _LIBCPP_STD_VER >= 23 | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | namespace ranges { | |
| 32 | namespace __starts_with { | |
| 33 | struct __fn { | |
| 34 | template <input_iterator _Iter1, | |
| 35 | sentinel_for<_Iter1> _Sent1, | |
| 36 | input_iterator _Iter2, | |
| 37 | sentinel_for<_Iter2> _Sent2, | |
| 38 | class _Pred = ranges::equal_to, | |
| 39 | class _Proj1 = identity, | |
| 40 | class _Proj2 = identity> | |
| 41 | requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> | |
| 42 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 43 | _Iter1 __first1, | |
| 44 | _Sent1 __last1, | |
| 45 | _Iter2 __first2, | |
| 46 | _Sent2 __last2, | |
| 47 | _Pred __pred = {}, | |
| 48 | _Proj1 __proj1 = {}, | |
| 49 | _Proj2 __proj2 = {}) const { | |
| 50 | return __mismatch::__fn::__go( | |
| 51 | std::move(__first1), | |
| 52 | std::move(__last1), | |
| 53 | std::move(__first2), | |
| 54 | std::move(__last2), | |
| 55 | __pred, | |
| 56 | __proj1, | |
| 57 | __proj2) | |
| 58 | .in2 == __last2; | |
| 59 | } | |
| 60 | ||
| 61 | template <input_range _Range1, | |
| 62 | input_range _Range2, | |
| 63 | class _Pred = ranges::equal_to, | |
| 64 | class _Proj1 = identity, | |
| 65 | class _Proj2 = identity> | |
| 66 | requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> | |
| 67 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( | |
| 68 | _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { | |
| 69 | return __mismatch::__fn::__go( | |
| 70 | ranges::begin(__range1), | |
| 71 | ranges::end(__range1), | |
| 72 | ranges::begin(__range2), | |
| 73 | ranges::end(__range2), | |
| 74 | __pred, | |
| 75 | __proj1, | |
| 76 | __proj2) | |
| 77 | .in2 == ranges::end(__range2); | |
| 78 | } | |
| 79 | }; | |
| 80 | } // namespace __starts_with | |
| 81 | inline namespace __cpo { | |
| 82 | inline constexpr auto starts_with = __starts_with::__fn{}; | |
| 83 | } // namespace __cpo | |
| 84 | } // namespace ranges | |
| 85 | ||
| 86 | _LIBCPP_END_NAMESPACE_STD | |
| 87 | ||
| 88 | #endif // _LIBCPP_STD_VER >= 23 | |
| 89 | ||
| 90 | #endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H |
lib/libcxx/include/__algorithm/ranges_swap_ranges.h+6-9| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | # pragma GCC system_header |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| ... | ... | @@ -35,8 +35,7 @@ using swap_ranges_result = in_in_result<_I1, _I2>; |
| 35 | 35 | |
| 36 | 36 | namespace __swap_ranges { |
| 37 | 37 | struct __fn { |
| 38 | template <input_iterator _I1, sentinel_for<_I1> _S1, | |
| 39 | input_iterator _I2, sentinel_for<_I2> _S2> | |
| 38 | template <input_iterator _I1, sentinel_for<_I1> _S1, input_iterator _I2, sentinel_for<_I2> _S2> | |
| 40 | 39 | requires indirectly_swappable<_I1, _I2> |
| 41 | 40 | _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2> |
| 42 | 41 | operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const { |
| ... | ... | @@ -47,22 +46,20 @@ struct __fn { |
| 47 | 46 | |
| 48 | 47 | template <input_range _R1, input_range _R2> |
| 49 | 48 | requires indirectly_swappable<iterator_t<_R1>, iterator_t<_R2>> |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 51 | swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>> | |
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<borrowed_iterator_t<_R1>, borrowed_iterator_t<_R2>> | |
| 52 | 50 | operator()(_R1&& __r1, _R2&& __r2) const { |
| 53 | return operator()(ranges::begin(__r1), ranges::end(__r1), | |
| 54 | ranges::begin(__r2), ranges::end(__r2)); | |
| 51 | return operator()(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2)); | |
| 55 | 52 | } |
| 56 | 53 | }; |
| 57 | 54 | } // namespace __swap_ranges |
| 58 | 55 | |
| 59 | 56 | inline namespace __cpo { |
| 60 | inline constexpr auto swap_ranges = __swap_ranges::__fn{}; | |
| 57 | inline constexpr auto swap_ranges = __swap_ranges::__fn{}; | |
| 61 | 58 | } // namespace __cpo |
| 62 | 59 | } // namespace ranges |
| 63 | 60 | |
| 64 | 61 | _LIBCPP_END_NAMESPACE_STD |
| 65 | 62 | |
| 66 | #endif // _LIBCPP_STD_VER > 17 | |
| 63 | #endif // _LIBCPP_STD_VER >= 20 | |
| 67 | 64 | |
| 68 | 65 | #endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H |
lib/libcxx/include/__algorithm/ranges_transform.h+63-61| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| ... | ... | @@ -41,15 +41,9 @@ using binary_transform_result = in_in_out_result<_I1, _I2, _O1>; |
| 41 | 41 | namespace __transform { |
| 42 | 42 | struct __fn { |
| 43 | 43 | private: |
| 44 | template <class _InIter, class _Sent, | |
| 45 | class _OutIter, | |
| 46 | class _Func, | |
| 47 | class _Proj> | |
| 48 | _LIBCPP_HIDE_FROM_ABI static constexpr | |
| 49 | unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last, | |
| 50 | _OutIter __result, | |
| 51 | _Func& __operation, | |
| 52 | _Proj& __projection) { | |
| 44 | template <class _InIter, class _Sent, class _OutIter, class _Func, class _Proj> | |
| 45 | _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter> | |
| 46 | __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) { | |
| 53 | 47 | while (__first != __last) { |
| 54 | 48 | *__result = std::invoke(__operation, std::invoke(__projection, *__first)); |
| 55 | 49 | ++__first; |
| ... | ... | @@ -59,76 +53,80 @@ private: |
| 59 | 53 | return {std::move(__first), std::move(__result)}; |
| 60 | 54 | } |
| 61 | 55 | |
| 62 | template <class _InIter1, class _Sent1, | |
| 63 | class _InIter2, class _Sent2, | |
| 56 | template <class _InIter1, | |
| 57 | class _Sent1, | |
| 58 | class _InIter2, | |
| 59 | class _Sent2, | |
| 64 | 60 | class _OutIter, |
| 65 | 61 | class _Func, |
| 66 | 62 | class _Proj1, |
| 67 | 63 | class _Proj2> |
| 68 | 64 | _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> |
| 69 | __binary(_InIter1 __first1, _Sent1 __last1, | |
| 70 | _InIter2 __first2, _Sent2 __last2, | |
| 65 | __binary(_InIter1 __first1, | |
| 66 | _Sent1 __last1, | |
| 67 | _InIter2 __first2, | |
| 68 | _Sent2 __last2, | |
| 71 | 69 | _OutIter __result, |
| 72 | 70 | _Func& __binary_operation, |
| 73 | 71 | _Proj1& __projection1, |
| 74 | 72 | _Proj2& __projection2) { |
| 75 | 73 | while (__first1 != __last1 && __first2 != __last2) { |
| 76 | *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1), | |
| 77 | std::invoke(__projection2, *__first2)); | |
| 74 | *__result = | |
| 75 | std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2)); | |
| 78 | 76 | ++__first1; |
| 79 | 77 | ++__first2; |
| 80 | 78 | ++__result; |
| 81 | 79 | } |
| 82 | 80 | return {std::move(__first1), std::move(__first2), std::move(__result)}; |
| 83 | 81 | } |
| 82 | ||
| 84 | 83 | public: |
| 85 | template <input_iterator _InIter, sentinel_for<_InIter> _Sent, | |
| 84 | template <input_iterator _InIter, | |
| 85 | sentinel_for<_InIter> _Sent, | |
| 86 | 86 | weakly_incrementable _OutIter, |
| 87 | 87 | copy_constructible _Func, |
| 88 | 88 | class _Proj = identity> |
| 89 | 89 | requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>> |
| 90 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 91 | unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, | |
| 92 | _OutIter __result, | |
| 93 | _Func __operation, | |
| 94 | _Proj __proj = {}) const { | |
| 90 | _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<_InIter, _OutIter> | |
| 91 | operator()(_InIter __first, _Sent __last, _OutIter __result, _Func __operation, _Proj __proj = {}) const { | |
| 95 | 92 | return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj); |
| 96 | 93 | } |
| 97 | 94 | |
| 98 | template <input_range _Range, | |
| 99 | weakly_incrementable _OutIter, | |
| 100 | copy_constructible _Func, | |
| 101 | class _Proj = identity> | |
| 95 | template <input_range _Range, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj = identity> | |
| 102 | 96 | requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected<iterator_t<_Range>, _Proj>>> |
| 103 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 104 | unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> operator()(_Range&& __range, | |
| 105 | _OutIter __result, | |
| 106 | _Func __operation, | |
| 107 | _Proj __projection = {}) const { | |
| 97 | _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<borrowed_iterator_t<_Range>, _OutIter> | |
| 98 | operator()(_Range&& __range, _OutIter __result, _Func __operation, _Proj __projection = {}) const { | |
| 108 | 99 | return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection); |
| 109 | 100 | } |
| 110 | 101 | |
| 111 | template <input_iterator _InIter1, sentinel_for<_InIter1> _Sent1, | |
| 112 | input_iterator _InIter2, sentinel_for<_InIter2> _Sent2, | |
| 102 | template <input_iterator _InIter1, | |
| 103 | sentinel_for<_InIter1> _Sent1, | |
| 104 | input_iterator _InIter2, | |
| 105 | sentinel_for<_InIter2> _Sent2, | |
| 113 | 106 | weakly_incrementable _OutIter, |
| 114 | 107 | copy_constructible _Func, |
| 115 | 108 | class _Proj1 = identity, |
| 116 | 109 | class _Proj2 = identity> |
| 117 | requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>, | |
| 118 | projected<_InIter2, _Proj2>>> | |
| 119 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 120 | binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1, | |
| 121 | _InIter2 __first2, _Sent2 __last2, | |
| 122 | _OutIter __result, | |
| 123 | _Func __binary_operation, | |
| 124 | _Proj1 __projection1 = {}, | |
| 125 | _Proj2 __projection2 = {}) const { | |
| 126 | return __binary(std::move(__first1), std::move(__last1), | |
| 127 | std::move(__first2), std::move(__last2), | |
| 128 | std::move(__result), | |
| 129 | __binary_operation, | |
| 130 | __projection1, | |
| 131 | __projection2); | |
| 110 | requires indirectly_writable<_OutIter, | |
| 111 | indirect_result_t<_Func&, projected<_InIter1, _Proj1>, projected<_InIter2, _Proj2>>> | |
| 112 | _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> operator()( | |
| 113 | _InIter1 __first1, | |
| 114 | _Sent1 __last1, | |
| 115 | _InIter2 __first2, | |
| 116 | _Sent2 __last2, | |
| 117 | _OutIter __result, | |
| 118 | _Func __binary_operation, | |
| 119 | _Proj1 __projection1 = {}, | |
| 120 | _Proj2 __projection2 = {}) const { | |
| 121 | return __binary( | |
| 122 | std::move(__first1), | |
| 123 | std::move(__last1), | |
| 124 | std::move(__first2), | |
| 125 | std::move(__last2), | |
| 126 | std::move(__result), | |
| 127 | __binary_operation, | |
| 128 | __projection1, | |
| 129 | __projection2); | |
| 132 | 130 | } |
| 133 | 131 | |
| 134 | 132 | template <input_range _Range1, |
| ... | ... | @@ -137,34 +135,38 @@ public: |
| 137 | 135 | copy_constructible _Func, |
| 138 | 136 | class _Proj1 = identity, |
| 139 | 137 | class _Proj2 = identity> |
| 140 | requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>, | |
| 141 | projected<iterator_t<_Range2>, _Proj2>>> | |
| 142 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 143 | binary_transform_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>, _OutIter> | |
| 138 | requires indirectly_writable< | |
| 139 | _OutIter, | |
| 140 | indirect_result_t<_Func&, projected<iterator_t<_Range1>, _Proj1>, projected<iterator_t<_Range2>, _Proj2>>> | |
| 141 | _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<borrowed_iterator_t<_Range1>, | |
| 142 | borrowed_iterator_t<_Range2>, | |
| 143 | _OutIter> | |
| 144 | 144 | operator()(_Range1&& __range1, |
| 145 | 145 | _Range2&& __range2, |
| 146 | 146 | _OutIter __result, |
| 147 | 147 | _Func __binary_operation, |
| 148 | 148 | _Proj1 __projection1 = {}, |
| 149 | 149 | _Proj2 __projection2 = {}) const { |
| 150 | return __binary(ranges::begin(__range1), ranges::end(__range1), | |
| 151 | ranges::begin(__range2), ranges::end(__range2), | |
| 152 | std::move(__result), | |
| 153 | __binary_operation, | |
| 154 | __projection1, | |
| 155 | __projection2); | |
| 150 | return __binary( | |
| 151 | ranges::begin(__range1), | |
| 152 | ranges::end(__range1), | |
| 153 | ranges::begin(__range2), | |
| 154 | ranges::end(__range2), | |
| 155 | std::move(__result), | |
| 156 | __binary_operation, | |
| 157 | __projection1, | |
| 158 | __projection2); | |
| 156 | 159 | } |
| 157 | ||
| 158 | 160 | }; |
| 159 | 161 | } // namespace __transform |
| 160 | 162 | |
| 161 | 163 | inline namespace __cpo { |
| 162 | inline constexpr auto transform = __transform::__fn{}; | |
| 164 | inline constexpr auto transform = __transform::__fn{}; | |
| 163 | 165 | } // namespace __cpo |
| 164 | 166 | } // namespace ranges |
| 165 | 167 | |
| 166 | 168 | _LIBCPP_END_NAMESPACE_STD |
| 167 | 169 | |
| 168 | #endif // _LIBCPP_STD_VER > 17 | |
| 170 | #endif // _LIBCPP_STD_VER >= 20 | |
| 169 | 171 | |
| 170 | 172 | #endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H |
lib/libcxx/include/__algorithm/ranges_unique.h+25-27| ... | ... | @@ -32,48 +32,46 @@ |
| 32 | 32 | # pragma GCC system_header |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 38 | |
| 39 | 39 | namespace ranges { |
| 40 | 40 | namespace __unique { |
| 41 | 41 | |
| 42 | struct __fn { | |
| 43 | template < | |
| 44 | permutable _Iter, | |
| 45 | sentinel_for<_Iter> _Sent, | |
| 46 | class _Proj = identity, | |
| 47 | indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to> | |
| 48 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 49 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 50 | auto __ret = std::__unique<_RangeAlgPolicy>( | |
| 51 | std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); | |
| 52 | return {std::move(__ret.first), std::move(__ret.second)}; | |
| 53 | } | |
| 42 | struct __fn { | |
| 43 | template <permutable _Iter, | |
| 44 | sentinel_for<_Iter> _Sent, | |
| 45 | class _Proj = identity, | |
| 46 | indirect_equivalence_relation<projected<_Iter, _Proj>> _Comp = ranges::equal_to> | |
| 47 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> | |
| 48 | operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 49 | auto __ret = | |
| 50 | std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); | |
| 51 | return {std::move(__ret.first), std::move(__ret.second)}; | |
| 52 | } | |
| 54 | 53 | |
| 55 | template < | |
| 56 | forward_range _Range, | |
| 57 | class _Proj = identity, | |
| 58 | indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to> | |
| 59 | requires permutable<iterator_t<_Range>> | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 61 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 62 | auto __ret = std::__unique<_RangeAlgPolicy>( | |
| 63 | ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); | |
| 64 | return {std::move(__ret.first), std::move(__ret.second)}; | |
| 65 | } | |
| 66 | }; | |
| 54 | template <forward_range _Range, | |
| 55 | class _Proj = identity, | |
| 56 | indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to> | |
| 57 | requires permutable<iterator_t<_Range>> | |
| 58 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> | |
| 59 | operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 60 | auto __ret = std::__unique<_RangeAlgPolicy>( | |
| 61 | ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); | |
| 62 | return {std::move(__ret.first), std::move(__ret.second)}; | |
| 63 | } | |
| 64 | }; | |
| 67 | 65 | |
| 68 | 66 | } // namespace __unique |
| 69 | 67 | |
| 70 | 68 | inline namespace __cpo { |
| 71 | inline constexpr auto unique = __unique::__fn{}; | |
| 69 | inline constexpr auto unique = __unique::__fn{}; | |
| 72 | 70 | } // namespace __cpo |
| 73 | 71 | } // namespace ranges |
| 74 | 72 | |
| 75 | 73 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 74 | |
| 77 | #endif // _LIBCPP_STD_VER > 17 | |
| 75 | #endif // _LIBCPP_STD_VER >= 20 | |
| 78 | 76 | |
| 79 | 77 | #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H |
lib/libcxx/include/__algorithm/ranges_unique_copy.h+5-6| ... | ... | @@ -21,7 +21,6 @@ |
| 21 | 21 | #include <__iterator/concepts.h> |
| 22 | 22 | #include <__iterator/iterator_traits.h> |
| 23 | 23 | #include <__iterator/projected.h> |
| 24 | #include <__iterator/readable_traits.h> | |
| 25 | 24 | #include <__ranges/access.h> |
| 26 | 25 | #include <__ranges/concepts.h> |
| 27 | 26 | #include <__ranges/dangling.h> |
| ... | ... | @@ -33,7 +32,7 @@ |
| 33 | 32 | # pragma GCC system_header |
| 34 | 33 | #endif |
| 35 | 34 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 36 | |
| 38 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 38 | |
| ... | ... | @@ -87,9 +86,9 @@ struct __fn { |
| 87 | 86 | class _Proj = identity, |
| 88 | 87 | indirect_equivalence_relation<projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to> |
| 89 | 88 | requires indirectly_copyable<iterator_t<_Range>, _OutIter> && |
| 90 | (forward_iterator<iterator_t<_Range>> || | |
| 91 | (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) || | |
| 92 | indirectly_copyable_storable<iterator_t<_Range>, _OutIter>) | |
| 89 | (forward_iterator<iterator_t<_Range>> || | |
| 90 | (input_iterator<_OutIter> && same_as<range_value_t<_Range>, iter_value_t<_OutIter>>) || | |
| 91 | indirectly_copyable_storable<iterator_t<_Range>, _OutIter>) | |
| 93 | 92 | _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result<borrowed_iterator_t<_Range>, _OutIter> |
| 94 | 93 | operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { |
| 95 | 94 | auto __ret = std::__unique_copy<_RangeAlgPolicy>( |
| ... | ... | @@ -111,6 +110,6 @@ inline constexpr auto unique_copy = __unique_copy::__fn{}; |
| 111 | 110 | |
| 112 | 111 | _LIBCPP_END_NAMESPACE_STD |
| 113 | 112 | |
| 114 | #endif // _LIBCPP_STD_VER > 17 | |
| 113 | #endif // _LIBCPP_STD_VER >= 20 | |
| 115 | 114 | |
| 116 | 115 | #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H |
lib/libcxx/include/__algorithm/ranges_upper_bound.h+17-18| ... | ... | @@ -25,51 +25,50 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| 32 | 32 | namespace ranges { |
| 33 | 33 | namespace __upper_bound { |
| 34 | 34 | struct __fn { |
| 35 | template <forward_iterator _Iter, sentinel_for<_Iter> _Sent, class _Type, class _Proj = identity, | |
| 35 | template <forward_iterator _Iter, | |
| 36 | sentinel_for<_Iter> _Sent, | |
| 37 | class _Type, | |
| 38 | class _Proj = identity, | |
| 36 | 39 | indirect_strict_weak_order<const _Type*, projected<_Iter, _Proj>> _Comp = ranges::less> |
| 37 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 38 | _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 40 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Iter | |
| 41 | operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 39 | 42 | auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { |
| 40 | 43 | return !std::invoke(__comp, __rhs, __lhs); |
| 41 | 44 | }; |
| 42 | 45 | |
| 43 | return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); | |
| 46 | return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); | |
| 44 | 47 | } |
| 45 | 48 | |
| 46 | template <forward_range _Range, class _Type, class _Proj = identity, | |
| 49 | template <forward_range _Range, | |
| 50 | class _Type, | |
| 51 | class _Proj = identity, | |
| 47 | 52 | indirect_strict_weak_order<const _Type*, projected<iterator_t<_Range>, _Proj>> _Comp = ranges::less> |
| 48 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr | |
| 49 | borrowed_iterator_t<_Range> operator()(_Range&& __r, | |
| 50 | const _Type& __value, | |
| 51 | _Comp __comp = {}, | |
| 52 | _Proj __proj = {}) const { | |
| 53 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> | |
| 54 | operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { | |
| 53 | 55 | auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { |
| 54 | 56 | return !std::invoke(__comp, __rhs, __lhs); |
| 55 | 57 | }; |
| 56 | 58 | |
| 57 | return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), | |
| 58 | ranges::end(__r), | |
| 59 | __value, | |
| 60 | __comp_lhs_rhs_swapped, | |
| 61 | __proj); | |
| 59 | return std::__lower_bound<_RangeAlgPolicy>( | |
| 60 | ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj); | |
| 62 | 61 | } |
| 63 | 62 | }; |
| 64 | 63 | } // namespace __upper_bound |
| 65 | 64 | |
| 66 | 65 | inline namespace __cpo { |
| 67 | inline constexpr auto upper_bound = __upper_bound::__fn{}; | |
| 66 | inline constexpr auto upper_bound = __upper_bound::__fn{}; | |
| 68 | 67 | } // namespace __cpo |
| 69 | 68 | } // namespace ranges |
| 70 | 69 | |
| 71 | 70 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 71 | |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 72 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 73 | |
| 75 | 74 | #endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H |
lib/libcxx/include/__algorithm/rotate.h+1-1| ... | ... | @@ -15,9 +15,9 @@ |
| 15 | 15 | #include <__algorithm/swap_ranges.h> |
| 16 | 16 | #include <__config> |
| 17 | 17 | #include <__iterator/iterator_traits.h> |
| 18 | #include <__type_traits/is_trivially_move_assignable.h> | |
| 18 | 19 | #include <__utility/move.h> |
| 19 | 20 | #include <__utility/pair.h> |
| 20 | #include <type_traits> | |
| 21 | 21 | |
| 22 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 23 | 23 | # pragma GCC system_header |
lib/libcxx/include/__algorithm/sample.h+6-6| ... | ... | @@ -16,8 +16,8 @@ |
| 16 | 16 | #include <__iterator/distance.h> |
| 17 | 17 | #include <__iterator/iterator_traits.h> |
| 18 | 18 | #include <__random/uniform_int_distribution.h> |
| 19 | #include <__type_traits/common_type.h> | |
| 19 | 20 | #include <__utility/move.h> |
| 20 | #include <type_traits> | |
| 21 | 21 | |
| 22 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 23 | 23 | # pragma GCC system_header |
| ... | ... | @@ -77,7 +77,7 @@ _LIBCPP_INLINE_VISIBILITY |
| 77 | 77 | _SampleIterator __sample(_PopulationIterator __first, |
| 78 | 78 | _PopulationSentinel __last, _SampleIterator __output_iter, |
| 79 | 79 | _Distance __n, _UniformRandomNumberGenerator& __g) { |
| 80 | _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); | |
| 80 | _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number."); | |
| 81 | 81 | |
| 82 | 82 | using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; |
| 83 | 83 | using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; |
| ... | ... | @@ -88,22 +88,22 @@ _SampleIterator __sample(_PopulationIterator __first, |
| 88 | 88 | __g, _PopIterCategory()); |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | #if _LIBCPP_STD_VER > 14 | |
| 91 | #if _LIBCPP_STD_VER >= 17 | |
| 92 | 92 | template <class _PopulationIterator, class _SampleIterator, class _Distance, |
| 93 | 93 | class _UniformRandomNumberGenerator> |
| 94 | 94 | inline _LIBCPP_INLINE_VISIBILITY |
| 95 | 95 | _SampleIterator sample(_PopulationIterator __first, |
| 96 | 96 | _PopulationIterator __last, _SampleIterator __output_iter, |
| 97 | 97 | _Distance __n, _UniformRandomNumberGenerator&& __g) { |
| 98 | static_assert(__is_cpp17_forward_iterator<_PopulationIterator>::value || | |
| 99 | __is_cpp17_random_access_iterator<_SampleIterator>::value, | |
| 98 | static_assert(__has_forward_iterator_category<_PopulationIterator>::value || | |
| 99 | __has_random_access_iterator_category<_SampleIterator>::value, | |
| 100 | 100 | "SampleIterator must meet the requirements of RandomAccessIterator"); |
| 101 | 101 | |
| 102 | 102 | return std::__sample<_ClassicAlgPolicy>( |
| 103 | 103 | std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); |
| 104 | 104 | } |
| 105 | 105 | |
| 106 | #endif // _LIBCPP_STD_VER > 14 | |
| 106 | #endif // _LIBCPP_STD_VER >= 17 | |
| 107 | 107 | |
| 108 | 108 | _LIBCPP_END_NAMESPACE_STD |
| 109 | 109 |
lib/libcxx/include/__algorithm/search.h+9-8| ... | ... | @@ -14,12 +14,13 @@ |
| 14 | 14 | #include <__algorithm/iterator_operations.h> |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__functional/identity.h> |
| 17 | #include <__functional/invoke.h> | |
| 17 | 18 | #include <__iterator/advance.h> |
| 18 | 19 | #include <__iterator/concepts.h> |
| 19 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | #include <__type_traits/enable_if.h> | |
| 20 | 22 | #include <__type_traits/is_callable.h> |
| 21 | 23 | #include <__utility/pair.h> |
| 22 | #include <type_traits> | |
| 23 | 24 | |
| 24 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 25 | 26 | # pragma GCC system_header |
| ... | ... | @@ -126,8 +127,8 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, |
| 126 | 127 | _Pred& __pred, |
| 127 | 128 | _Proj1& __proj1, |
| 128 | 129 | _Proj2& __proj2, |
| 129 | __enable_if_t<__is_cpp17_random_access_iterator<_Iter1>::value | |
| 130 | && __is_cpp17_random_access_iterator<_Iter2>::value>* = nullptr) { | |
| 130 | __enable_if_t<__has_random_access_iterator_category<_Iter1>::value | |
| 131 | && __has_random_access_iterator_category<_Iter2>::value>* = nullptr) { | |
| 131 | 132 | |
| 132 | 133 | auto __size2 = __last2 - __first2; |
| 133 | 134 | if (__size2 == 0) |
| ... | ... | @@ -158,10 +159,10 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, |
| 158 | 159 | _Pred& __pred, |
| 159 | 160 | _Proj1& __proj1, |
| 160 | 161 | _Proj2& __proj2, |
| 161 | __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value | |
| 162 | && __is_cpp17_forward_iterator<_Iter2>::value | |
| 163 | && !(__is_cpp17_random_access_iterator<_Iter1>::value | |
| 164 | && __is_cpp17_random_access_iterator<_Iter2>::value)>* = nullptr) { | |
| 162 | __enable_if_t<__has_forward_iterator_category<_Iter1>::value | |
| 163 | && __has_forward_iterator_category<_Iter2>::value | |
| 164 | && !(__has_random_access_iterator_category<_Iter1>::value | |
| 165 | && __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) { | |
| 165 | 166 | return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, |
| 166 | 167 | __first2, __last2, |
| 167 | 168 | __pred, |
| ... | ... | @@ -187,7 +188,7 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, |
| 187 | 188 | return std::search(__first1, __last1, __first2, __last2, __equal_to()); |
| 188 | 189 | } |
| 189 | 190 | |
| 190 | #if _LIBCPP_STD_VER > 14 | |
| 191 | #if _LIBCPP_STD_VER >= 17 | |
| 191 | 192 | template <class _ForwardIterator, class _Searcher> |
| 192 | 193 | _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator |
| 193 | 194 | search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { |
lib/libcxx/include/__algorithm/search_n.h+5-4| ... | ... | @@ -14,14 +14,15 @@ |
| 14 | 14 | #include <__algorithm/iterator_operations.h> |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__functional/identity.h> |
| 17 | #include <__functional/invoke.h> | |
| 17 | 18 | #include <__iterator/advance.h> |
| 18 | 19 | #include <__iterator/concepts.h> |
| 19 | 20 | #include <__iterator/distance.h> |
| 20 | 21 | #include <__iterator/iterator_traits.h> |
| 21 | 22 | #include <__ranges/concepts.h> |
| 23 | #include <__type_traits/is_callable.h> | |
| 22 | 24 | #include <__utility/convert_to_integral.h> |
| 23 | 25 | #include <__utility/pair.h> |
| 24 | #include <type_traits> // __convert_to_integral | |
| 25 | 26 | |
| 26 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 28 | # pragma GCC system_header |
| ... | ... | @@ -129,7 +130,7 @@ pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, |
| 129 | 130 | const _Type& __value, |
| 130 | 131 | _Pred& __pred, |
| 131 | 132 | _Proj& __proj, |
| 132 | __enable_if_t<__is_cpp17_random_access_iterator<_Iter>::value>* = nullptr) { | |
| 133 | __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) { | |
| 133 | 134 | return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last, |
| 134 | 135 | __count, |
| 135 | 136 | __value, |
| ... | ... | @@ -149,8 +150,8 @@ pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, |
| 149 | 150 | const _Type& __value, |
| 150 | 151 | _Pred& __pred, |
| 151 | 152 | _Proj& __proj, |
| 152 | __enable_if_t<__is_cpp17_forward_iterator<_Iter1>::value | |
| 153 | && !__is_cpp17_random_access_iterator<_Iter1>::value>* = nullptr) { | |
| 153 | __enable_if_t<__has_forward_iterator_category<_Iter1>::value | |
| 154 | && !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) { | |
| 154 | 155 | return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, |
| 155 | 156 | __count, |
| 156 | 157 | __value, |
lib/libcxx/include/__algorithm/set_difference.h+2-9| ... | ... | @@ -17,9 +17,9 @@ |
| 17 | 17 | #include <__functional/identity.h> |
| 18 | 18 | #include <__functional/invoke.h> |
| 19 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | #include <__type_traits/remove_cvref.h> | |
| 20 | 21 | #include <__utility/move.h> |
| 21 | 22 | #include <__utility/pair.h> |
| 22 | #include <type_traits> | |
| 23 | 23 | |
| 24 | 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 25 | 25 | # pragma GCC system_header |
| ... | ... | @@ -66,14 +66,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d |
| 66 | 66 | _InputIterator2 __first2, |
| 67 | 67 | _InputIterator2 __last2, |
| 68 | 68 | _OutputIterator __result) { |
| 69 | return std::__set_difference<_ClassicAlgPolicy>( | |
| 70 | __first1, | |
| 71 | __last1, | |
| 72 | __first2, | |
| 73 | __last2, | |
| 74 | __result, | |
| 75 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 76 | typename iterator_traits<_InputIterator2>::value_type>()).second; | |
| 69 | return std::__set_difference<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __result, __less<>()).second; | |
| 77 | 70 | } |
| 78 | 71 | |
| 79 | 72 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/set_intersection.h+1-2| ... | ... | @@ -89,8 +89,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_i |
| 89 | 89 | std::move(__first2), |
| 90 | 90 | std::move(__last2), |
| 91 | 91 | std::move(__result), |
| 92 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 93 | typename iterator_traits<_InputIterator2>::value_type>()) | |
| 92 | __less<>()) | |
| 94 | 93 | .__out_; |
| 95 | 94 | } |
| 96 | 95 |
lib/libcxx/include/__algorithm/set_symmetric_difference.h+1-2| ... | ... | @@ -96,8 +96,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri |
| 96 | 96 | std::move(__first2), |
| 97 | 97 | std::move(__last2), |
| 98 | 98 | std::move(__result), |
| 99 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 100 | typename iterator_traits<_InputIterator2>::value_type>()); | |
| 99 | __less<>()); | |
| 101 | 100 | } |
| 102 | 101 | |
| 103 | 102 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/set_union.h+1-2| ... | ... | @@ -92,8 +92,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( |
| 92 | 92 | std::move(__first2), |
| 93 | 93 | std::move(__last2), |
| 94 | 94 | std::move(__result), |
| 95 | __less<typename iterator_traits<_InputIterator1>::value_type, | |
| 96 | typename iterator_traits<_InputIterator2>::value_type>()); | |
| 95 | __less<>()); | |
| 97 | 96 | } |
| 98 | 97 | |
| 99 | 98 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/shift_left.h+3-4| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <__algorithm/move.h> |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__iterator/iterator_traits.h> |
| 15 | #include <type_traits> | |
| 16 | 15 | |
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
| ... | ... | @@ -20,7 +19,7 @@ |
| 20 | 19 | |
| 21 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 21 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 23 | |
| 25 | 24 | template <class _ForwardIterator> |
| 26 | 25 | inline _LIBCPP_INLINE_VISIBILITY constexpr |
| ... | ... | @@ -33,7 +32,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last, |
| 33 | 32 | } |
| 34 | 33 | |
| 35 | 34 | _ForwardIterator __m = __first; |
| 36 | if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { | |
| 35 | if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 37 | 36 | if (__n >= __last - __first) { |
| 38 | 37 | return __first; |
| 39 | 38 | } |
| ... | ... | @@ -49,7 +48,7 @@ shift_left(_ForwardIterator __first, _ForwardIterator __last, |
| 49 | 48 | return _VSTD::move(__m, __last, __first); |
| 50 | 49 | } |
| 51 | 50 | |
| 52 | #endif // _LIBCPP_STD_VER > 17 | |
| 51 | #endif // _LIBCPP_STD_VER >= 20 | |
| 53 | 52 | |
| 54 | 53 | _LIBCPP_END_NAMESPACE_STD |
| 55 | 54 |
lib/libcxx/include/__algorithm/shift_right.h+4-5| ... | ... | @@ -15,7 +15,6 @@ |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__iterator/iterator_traits.h> |
| 17 | 17 | #include <__utility/swap.h> |
| 18 | #include <type_traits> | |
| 19 | 18 | |
| 20 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 20 | # pragma GCC system_header |
| ... | ... | @@ -23,7 +22,7 @@ |
| 23 | 22 | |
| 24 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 24 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 26 | |
| 28 | 27 | template <class _ForwardIterator> |
| 29 | 28 | inline _LIBCPP_INLINE_VISIBILITY constexpr |
| ... | ... | @@ -35,14 +34,14 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last, |
| 35 | 34 | return __first; |
| 36 | 35 | } |
| 37 | 36 | |
| 38 | if constexpr (__is_cpp17_random_access_iterator<_ForwardIterator>::value) { | |
| 37 | if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { | |
| 39 | 38 | decltype(__n) __d = __last - __first; |
| 40 | 39 | if (__n >= __d) { |
| 41 | 40 | return __last; |
| 42 | 41 | } |
| 43 | 42 | _ForwardIterator __m = __first + (__d - __n); |
| 44 | 43 | return _VSTD::move_backward(__first, __m, __last); |
| 45 | } else if constexpr (__is_cpp17_bidirectional_iterator<_ForwardIterator>::value) { | |
| 44 | } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) { | |
| 46 | 45 | _ForwardIterator __m = __last; |
| 47 | 46 | for (; __n > 0; --__n) { |
| 48 | 47 | if (__m == __first) { |
| ... | ... | @@ -95,7 +94,7 @@ shift_right(_ForwardIterator __first, _ForwardIterator __last, |
| 95 | 94 | } |
| 96 | 95 | } |
| 97 | 96 | |
| 98 | #endif // _LIBCPP_STD_VER > 17 | |
| 97 | #endif // _LIBCPP_STD_VER >= 20 | |
| 99 | 98 | |
| 100 | 99 | _LIBCPP_END_NAMESPACE_STD |
| 101 | 100 |
lib/libcxx/include/__algorithm/shuffle.h+9-10| ... | ... | @@ -11,7 +11,6 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__algorithm/iterator_operations.h> |
| 13 | 13 | #include <__config> |
| 14 | #include <__debug> | |
| 15 | 14 | #include <__iterator/iterator_traits.h> |
| 16 | 15 | #include <__random/uniform_int_distribution.h> |
| 17 | 16 | #include <__utility/forward.h> |
| ... | ... | @@ -29,9 +28,9 @@ _LIBCPP_PUSH_MACROS |
| 29 | 28 | |
| 30 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 30 | |
| 32 | class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer { | |
| 31 | class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer { | |
| 33 | 32 | public: |
| 34 | __libcpp_debug_randomizer() { | |
| 33 | _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() { | |
| 35 | 34 | __state_ = __seed(); |
| 36 | 35 | __inc_ = __state_ + 0xda3e39cb94b95bdbULL; |
| 37 | 36 | __inc_ = (__inc_ << 1) | 1; |
| ... | ... | @@ -65,11 +64,11 @@ private: |
| 65 | 64 | |
| 66 | 65 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ |
| 67 | 66 | || defined(_LIBCPP_BUILDING_LIBRARY) |
| 68 | class _LIBCPP_TYPE_VIS __rs_default; | |
| 67 | class _LIBCPP_EXPORTED_FROM_ABI __rs_default; | |
| 69 | 68 | |
| 70 | _LIBCPP_FUNC_VIS __rs_default __rs_get(); | |
| 69 | _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); | |
| 71 | 70 | |
| 72 | class _LIBCPP_TYPE_VIS __rs_default | |
| 71 | class _LIBCPP_EXPORTED_FROM_ABI __rs_default | |
| 73 | 72 | { |
| 74 | 73 | static unsigned __c_; |
| 75 | 74 | |
| ... | ... | @@ -85,13 +84,13 @@ public: |
| 85 | 84 | |
| 86 | 85 | result_type operator()(); |
| 87 | 86 | |
| 88 | static _LIBCPP_CONSTEXPR result_type min() {return _Min;} | |
| 89 | static _LIBCPP_CONSTEXPR result_type max() {return _Max;} | |
| 87 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;} | |
| 88 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;} | |
| 90 | 89 | |
| 91 | friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); | |
| 90 | friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); | |
| 92 | 91 | }; |
| 93 | 92 | |
| 94 | _LIBCPP_FUNC_VIS __rs_default __rs_get(); | |
| 93 | _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); | |
| 95 | 94 | |
| 96 | 95 | template <class _RandomAccessIterator> |
| 97 | 96 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void |
lib/libcxx/include/__algorithm/sift_down.h+6-1| ... | ... | @@ -19,6 +19,9 @@ |
| 19 | 19 | # pragma GCC system_header |
| 20 | 20 | #endif |
| 21 | 21 | |
| 22 | _LIBCPP_PUSH_MACROS | |
| 23 | #include <__undef_macros> | |
| 24 | ||
| 22 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 26 | |
| 24 | 27 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| ... | ... | @@ -83,7 +86,7 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, |
| 83 | 86 | typename iterator_traits<_RandomAccessIterator>::difference_type __len) |
| 84 | 87 | { |
| 85 | 88 | using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; |
| 86 | _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2"); | |
| 89 | _LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2"); | |
| 87 | 90 | |
| 88 | 91 | _RandomAccessIterator __hole = __first; |
| 89 | 92 | _RandomAccessIterator __child_i = __first; |
| ... | ... | @@ -111,4 +114,6 @@ __floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, |
| 111 | 114 | |
| 112 | 115 | _LIBCPP_END_NAMESPACE_STD |
| 113 | 116 | |
| 117 | _LIBCPP_POP_MACROS | |
| 118 | ||
| 114 | 119 | #endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H |
lib/libcxx/include/__algorithm/sort.h+575-327| ... | ... | @@ -11,23 +11,27 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__algorithm/comp.h> |
| 13 | 13 | #include <__algorithm/comp_ref_type.h> |
| 14 | #include <__algorithm/iter_swap.h> | |
| 14 | 15 | #include <__algorithm/iterator_operations.h> |
| 15 | 16 | #include <__algorithm/min_element.h> |
| 16 | 17 | #include <__algorithm/partial_sort.h> |
| 17 | 18 | #include <__algorithm/unwrap_iter.h> |
| 19 | #include <__assert> | |
| 20 | #include <__bit/blsr.h> | |
| 21 | #include <__bit/countl.h> | |
| 22 | #include <__bit/countr.h> | |
| 18 | 23 | #include <__config> |
| 19 | #include <__debug> | |
| 20 | 24 | #include <__debug_utils/randomize_range.h> |
| 25 | #include <__debug_utils/strict_weak_ordering_check.h> | |
| 21 | 26 | #include <__functional/operations.h> |
| 22 | 27 | #include <__functional/ranges_operations.h> |
| 23 | 28 | #include <__iterator/iterator_traits.h> |
| 24 | #include <__memory/destruct_n.h> | |
| 25 | #include <__memory/unique_ptr.h> | |
| 29 | #include <__type_traits/conditional.h> | |
| 30 | #include <__type_traits/disjunction.h> | |
| 26 | 31 | #include <__type_traits/is_arithmetic.h> |
| 27 | #include <__type_traits/is_trivially_copy_assignable.h> | |
| 28 | #include <__type_traits/is_trivially_copy_constructible.h> | |
| 32 | #include <__type_traits/is_constant_evaluated.h> | |
| 29 | 33 | #include <__utility/move.h> |
| 30 | #include <bit> | |
| 34 | #include <__utility/pair.h> | |
| 31 | 35 | #include <climits> |
| 32 | 36 | #include <cstdint> |
| 33 | 37 | |
| ... | ... | @@ -37,52 +41,6 @@ |
| 37 | 41 | |
| 38 | 42 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 43 | |
| 40 | // Wraps an algorithm policy tag and a comparator in a single struct, used to pass the policy tag around without | |
| 41 | // changing the number of template arguments (to keep the ABI stable). This is only used for the "range" policy tag. | |
| 42 | // | |
| 43 | // To create an object of this type, use `_WrapAlgPolicy<T, C>::type` -- see the specialization below for the rationale. | |
| 44 | template <class _PolicyT, class _CompT, class = void> | |
| 45 | struct _WrapAlgPolicy { | |
| 46 | using type = _WrapAlgPolicy; | |
| 47 | ||
| 48 | using _AlgPolicy = _PolicyT; | |
| 49 | using _Comp = _CompT; | |
| 50 | _Comp& __comp; | |
| 51 | ||
| 52 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 53 | _WrapAlgPolicy(_Comp& __c) : __comp(__c) {} | |
| 54 | }; | |
| 55 | ||
| 56 | // Specialization for the "classic" policy tag that avoids creating a struct and simply defines an alias for the | |
| 57 | // comparator. When unwrapping, a pristine comparator is always considered to have the "classic" tag attached. Passing | |
| 58 | // the pristine comparator where possible allows using template instantiations from the dylib. | |
| 59 | template <class _PolicyT, class _CompT> | |
| 60 | struct _WrapAlgPolicy<_PolicyT, _CompT, __enable_if_t<std::is_same<_PolicyT, _ClassicAlgPolicy>::value> > { | |
| 61 | using type = _CompT; | |
| 62 | }; | |
| 63 | ||
| 64 | // Unwraps a pristine functor (e.g. `std::less`) as if it were wrapped using `_WrapAlgPolicy`. The policy tag is always | |
| 65 | // set to "classic". | |
| 66 | template <class _CompT> | |
| 67 | struct _UnwrapAlgPolicy { | |
| 68 | using _AlgPolicy = _ClassicAlgPolicy; | |
| 69 | using _Comp = _CompT; | |
| 70 | ||
| 71 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static | |
| 72 | _Comp __get_comp(_Comp __comp) { return __comp; } | |
| 73 | }; | |
| 74 | ||
| 75 | // Unwraps a `_WrapAlgPolicy` struct. | |
| 76 | template <class... _Ts> | |
| 77 | struct _UnwrapAlgPolicy<_WrapAlgPolicy<_Ts...> > { | |
| 78 | using _Wrapped = _WrapAlgPolicy<_Ts...>; | |
| 79 | using _AlgPolicy = typename _Wrapped::_AlgPolicy; | |
| 80 | using _Comp = typename _Wrapped::_Comp; | |
| 81 | ||
| 82 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static | |
| 83 | _Comp __get_comp(_Wrapped& __w) { return __w.__comp; } | |
| 84 | }; | |
| 85 | ||
| 86 | 44 | // stable, 2-3 compares, 0-2 swaps |
| 87 | 45 | |
| 88 | 46 | template <class _AlgPolicy, class _Compare, class _ForwardIterator> |
| ... | ... | @@ -126,78 +84,53 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIte |
| 126 | 84 | |
| 127 | 85 | template <class _AlgPolicy, class _Compare, class _ForwardIterator> |
| 128 | 86 | _LIBCPP_HIDE_FROM_ABI |
| 129 | unsigned __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, | |
| 87 | void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, | |
| 130 | 88 | _Compare __c) { |
| 131 | using _Ops = _IterOps<_AlgPolicy>; | |
| 132 | ||
| 133 | unsigned __r = std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); | |
| 89 | using _Ops = _IterOps<_AlgPolicy>; | |
| 90 | std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); | |
| 134 | 91 | if (__c(*__x4, *__x3)) { |
| 135 | 92 | _Ops::iter_swap(__x3, __x4); |
| 136 | ++__r; | |
| 137 | 93 | if (__c(*__x3, *__x2)) { |
| 138 | 94 | _Ops::iter_swap(__x2, __x3); |
| 139 | ++__r; | |
| 140 | 95 | if (__c(*__x2, *__x1)) { |
| 141 | 96 | _Ops::iter_swap(__x1, __x2); |
| 142 | ++__r; | |
| 143 | 97 | } |
| 144 | 98 | } |
| 145 | 99 | } |
| 146 | return __r; | |
| 147 | 100 | } |
| 148 | 101 | |
| 149 | 102 | // stable, 4-10 compares, 0-9 swaps |
| 150 | 103 | |
| 151 | template <class _WrappedComp, class _ForwardIterator> | |
| 152 | _LIBCPP_HIDDEN unsigned __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, | |
| 153 | _ForwardIterator __x4, _ForwardIterator __x5, _WrappedComp __wrapped_comp) { | |
| 154 | using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; | |
| 155 | using _AlgPolicy = typename _Unwrap::_AlgPolicy; | |
| 104 | template <class _AlgPolicy, class _Comp, class _ForwardIterator> | |
| 105 | _LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, | |
| 106 | _ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) { | |
| 156 | 107 | using _Ops = _IterOps<_AlgPolicy>; |
| 157 | 108 | |
| 158 | using _Compare = typename _Unwrap::_Comp; | |
| 159 | _Compare __c = _Unwrap::__get_comp(__wrapped_comp); | |
| 160 | ||
| 161 | unsigned __r = std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); | |
| 162 | if (__c(*__x5, *__x4)) { | |
| 109 | std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp); | |
| 110 | if (__comp(*__x5, *__x4)) { | |
| 163 | 111 | _Ops::iter_swap(__x4, __x5); |
| 164 | ++__r; | |
| 165 | if (__c(*__x4, *__x3)) { | |
| 112 | if (__comp(*__x4, *__x3)) { | |
| 166 | 113 | _Ops::iter_swap(__x3, __x4); |
| 167 | ++__r; | |
| 168 | if (__c(*__x3, *__x2)) { | |
| 114 | if (__comp(*__x3, *__x2)) { | |
| 169 | 115 | _Ops::iter_swap(__x2, __x3); |
| 170 | ++__r; | |
| 171 | if (__c(*__x2, *__x1)) { | |
| 116 | if (__comp(*__x2, *__x1)) { | |
| 172 | 117 | _Ops::iter_swap(__x1, __x2); |
| 173 | ++__r; | |
| 174 | 118 | } |
| 175 | 119 | } |
| 176 | 120 | } |
| 177 | 121 | } |
| 178 | return __r; | |
| 179 | } | |
| 180 | ||
| 181 | template <class _AlgPolicy, class _Compare, class _ForwardIterator> | |
| 182 | _LIBCPP_HIDE_FROM_ABI unsigned __sort5_wrap_policy( | |
| 183 | _ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _ForwardIterator __x5, | |
| 184 | _Compare __c) { | |
| 185 | using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; | |
| 186 | _WrappedComp __wrapped_comp(__c); | |
| 187 | return std::__sort5<_WrappedComp>( | |
| 188 | std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __wrapped_comp); | |
| 189 | 122 | } |
| 190 | 123 | |
| 191 | 124 | // The comparator being simple is a prerequisite for using the branchless optimization. |
| 192 | 125 | template <class _Tp> |
| 193 | 126 | struct __is_simple_comparator : false_type {}; |
| 194 | template <class _Tp> | |
| 195 | struct __is_simple_comparator<__less<_Tp>&> : true_type {}; | |
| 127 | template <> | |
| 128 | struct __is_simple_comparator<__less<>&> : true_type {}; | |
| 196 | 129 | template <class _Tp> |
| 197 | 130 | struct __is_simple_comparator<less<_Tp>&> : true_type {}; |
| 198 | 131 | template <class _Tp> |
| 199 | 132 | struct __is_simple_comparator<greater<_Tp>&> : true_type {}; |
| 200 | #if _LIBCPP_STD_VER > 17 | |
| 133 | #if _LIBCPP_STD_VER >= 20 | |
| 201 | 134 | template <> |
| 202 | 135 | struct __is_simple_comparator<ranges::less&> : true_type {}; |
| 203 | 136 | template <> |
| ... | ... | @@ -206,9 +139,16 @@ struct __is_simple_comparator<ranges::greater&> : true_type {}; |
| 206 | 139 | |
| 207 | 140 | template <class _Compare, class _Iter, class _Tp = typename iterator_traits<_Iter>::value_type> |
| 208 | 141 | using __use_branchless_sort = |
| 209 | integral_constant<bool, __is_cpp17_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) && | |
| 142 | integral_constant<bool, __libcpp_is_contiguous_iterator<_Iter>::value && sizeof(_Tp) <= sizeof(void*) && | |
| 210 | 143 | is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; |
| 211 | 144 | |
| 145 | namespace __detail { | |
| 146 | ||
| 147 | // Size in bits for the bitset in use. | |
| 148 | enum { __block_size = sizeof(uint64_t) * 8 }; | |
| 149 | ||
| 150 | } // namespace __detail | |
| 151 | ||
| 212 | 152 | // Ensures that __c(*__x, *__y) is true by swapping *__x and *__y if necessary. |
| 213 | 153 | template <class _Compare, class _RandomAccessIterator> |
| 214 | 154 | inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { |
| ... | ... | @@ -268,10 +208,15 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, |
| 268 | 208 | std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); |
| 269 | 209 | } |
| 270 | 210 | |
| 271 | template <class, class _Compare, class _RandomAccessIterator> | |
| 211 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> | |
| 272 | 212 | inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> |
| 273 | __sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, | |
| 274 | _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { | |
| 213 | __sort5_maybe_branchless( | |
| 214 | _RandomAccessIterator __x1, | |
| 215 | _RandomAccessIterator __x2, | |
| 216 | _RandomAccessIterator __x3, | |
| 217 | _RandomAccessIterator __x4, | |
| 218 | _RandomAccessIterator __x5, | |
| 219 | _Compare __c) { | |
| 275 | 220 | std::__cond_swap<_Compare>(__x1, __x2, __c); |
| 276 | 221 | std::__cond_swap<_Compare>(__x4, __x5, __c); |
| 277 | 222 | std::__partially_sorted_swap<_Compare>(__x3, __x4, __x5, __c); |
| ... | ... | @@ -284,7 +229,8 @@ template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| 284 | 229 | inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> |
| 285 | 230 | __sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, |
| 286 | 231 | _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { |
| 287 | std::__sort5_wrap_policy<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __x5, __c); | |
| 232 | std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>( | |
| 233 | std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c); | |
| 288 | 234 | } |
| 289 | 235 | |
| 290 | 236 | // Assumes size > 0 |
| ... | ... | @@ -300,34 +246,49 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir |
| 300 | 246 | } |
| 301 | 247 | } |
| 302 | 248 | |
| 249 | // Sort the iterator range [__first, __last) using the comparator __comp using | |
| 250 | // the insertion sort algorithm. | |
| 303 | 251 | template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> |
| 304 | 252 | _LIBCPP_HIDE_FROM_ABI |
| 305 | 253 | void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { |
| 306 | 254 | using _Ops = _IterOps<_AlgPolicy>; |
| 307 | 255 | |
| 308 | 256 | typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; |
| 309 | if (__first != __last) { | |
| 310 | _BidirectionalIterator __i = __first; | |
| 311 | for (++__i; __i != __last; ++__i) { | |
| 312 | _BidirectionalIterator __j = __i; | |
| 313 | value_type __t(_Ops::__iter_move(__j)); | |
| 314 | for (_BidirectionalIterator __k = __i; __k != __first && __comp(__t, *--__k); --__j) | |
| 257 | if (__first == __last) | |
| 258 | return; | |
| 259 | _BidirectionalIterator __i = __first; | |
| 260 | for (++__i; __i != __last; ++__i) { | |
| 261 | _BidirectionalIterator __j = __i; | |
| 262 | --__j; | |
| 263 | if (__comp(*__i, *__j)) { | |
| 264 | value_type __t(_Ops::__iter_move(__i)); | |
| 265 | _BidirectionalIterator __k = __j; | |
| 266 | __j = __i; | |
| 267 | do { | |
| 315 | 268 | *__j = _Ops::__iter_move(__k); |
| 269 | __j = __k; | |
| 270 | } while (__j != __first && __comp(__t, *--__k)); | |
| 316 | 271 | *__j = std::move(__t); |
| 317 | 272 | } |
| 318 | 273 | } |
| 319 | 274 | } |
| 320 | 275 | |
| 276 | // Sort the iterator range [__first, __last) using the comparator __comp using | |
| 277 | // the insertion sort algorithm. Insertion sort has two loops, outer and inner. | |
| 278 | // The implementation below has no bounds check (unguarded) for the inner loop. | |
| 279 | // Assumes that there is an element in the position (__first - 1) and that each | |
| 280 | // element in the input range is greater or equal to the element at __first - 1. | |
| 321 | 281 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| 322 | _LIBCPP_HIDE_FROM_ABI | |
| 323 | void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 282 | _LIBCPP_HIDE_FROM_ABI void | |
| 283 | __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 324 | 284 | using _Ops = _IterOps<_AlgPolicy>; |
| 325 | ||
| 326 | 285 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; |
| 327 | 286 | typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; |
| 328 | _RandomAccessIterator __j = __first + difference_type(2); | |
| 329 | std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); | |
| 330 | for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { | |
| 287 | if (__first == __last) | |
| 288 | return; | |
| 289 | const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled | |
| 290 | for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) { | |
| 291 | _RandomAccessIterator __j = __i - difference_type(1); | |
| 331 | 292 | if (__comp(*__i, *__j)) { |
| 332 | 293 | value_type __t(_Ops::__iter_move(__i)); |
| 333 | 294 | _RandomAccessIterator __k = __j; |
| ... | ... | @@ -335,23 +296,20 @@ void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __l |
| 335 | 296 | do { |
| 336 | 297 | *__j = _Ops::__iter_move(__k); |
| 337 | 298 | __j = __k; |
| 338 | } while (__j != __first && __comp(__t, *--__k)); | |
| 299 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 300 | __k != __leftmost, | |
| 301 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 302 | } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above. | |
| 339 | 303 | *__j = std::move(__t); |
| 340 | 304 | } |
| 341 | __j = __i; | |
| 342 | 305 | } |
| 343 | 306 | } |
| 344 | 307 | |
| 345 | template <class _WrappedComp, class _RandomAccessIterator> | |
| 346 | _LIBCPP_HIDDEN bool __insertion_sort_incomplete( | |
| 347 | _RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { | |
| 348 | using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; | |
| 349 | using _AlgPolicy = typename _Unwrap::_AlgPolicy; | |
| 308 | template <class _AlgPolicy, class _Comp, class _RandomAccessIterator> | |
| 309 | _LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( | |
| 310 | _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { | |
| 350 | 311 | using _Ops = _IterOps<_AlgPolicy>; |
| 351 | 312 | |
| 352 | using _Compare = typename _Unwrap::_Comp; | |
| 353 | _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); | |
| 354 | ||
| 355 | 313 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; |
| 356 | 314 | switch (__last - __first) { |
| 357 | 315 | case 0: |
| ... | ... | @@ -359,24 +317,24 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete( |
| 359 | 317 | return true; |
| 360 | 318 | case 2: |
| 361 | 319 | if (__comp(*--__last, *__first)) |
| 362 | _IterOps<_AlgPolicy>::iter_swap(__first, __last); | |
| 320 | _Ops::iter_swap(__first, __last); | |
| 363 | 321 | return true; |
| 364 | 322 | case 3: |
| 365 | std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); | |
| 323 | std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), --__last, __comp); | |
| 366 | 324 | return true; |
| 367 | 325 | case 4: |
| 368 | std::__sort4_maybe_branchless<_AlgPolicy, _Compare>( | |
| 326 | std::__sort4_maybe_branchless<_AlgPolicy, _Comp>( | |
| 369 | 327 | __first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); |
| 370 | 328 | return true; |
| 371 | 329 | case 5: |
| 372 | std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( | |
| 330 | std::__sort5_maybe_branchless<_AlgPolicy, _Comp>( | |
| 373 | 331 | __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), |
| 374 | 332 | --__last, __comp); |
| 375 | 333 | return true; |
| 376 | 334 | } |
| 377 | 335 | typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; |
| 378 | 336 | _RandomAccessIterator __j = __first + difference_type(2); |
| 379 | std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), __j, __comp); | |
| 337 | std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp); | |
| 380 | 338 | const unsigned __limit = 8; |
| 381 | 339 | unsigned __count = 0; |
| 382 | 340 | for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { |
| ... | ... | @@ -397,48 +355,380 @@ _LIBCPP_HIDDEN bool __insertion_sort_incomplete( |
| 397 | 355 | return true; |
| 398 | 356 | } |
| 399 | 357 | |
| 400 | template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> | |
| 401 | _LIBCPP_HIDE_FROM_ABI | |
| 402 | void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, | |
| 403 | typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { | |
| 358 | template <class _AlgPolicy, class _RandomAccessIterator> | |
| 359 | inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos( | |
| 360 | _RandomAccessIterator __first, _RandomAccessIterator __last, uint64_t& __left_bitset, uint64_t& __right_bitset) { | |
| 404 | 361 | using _Ops = _IterOps<_AlgPolicy>; |
| 362 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 363 | // Swap one pair on each iteration as long as both bitsets have at least one | |
| 364 | // element for swapping. | |
| 365 | while (__left_bitset != 0 && __right_bitset != 0) { | |
| 366 | difference_type __tz_left = __libcpp_ctz(__left_bitset); | |
| 367 | __left_bitset = __libcpp_blsr(__left_bitset); | |
| 368 | difference_type __tz_right = __libcpp_ctz(__right_bitset); | |
| 369 | __right_bitset = __libcpp_blsr(__right_bitset); | |
| 370 | _Ops::iter_swap(__first + __tz_left, __last - __tz_right); | |
| 371 | } | |
| 372 | } | |
| 405 | 373 | |
| 406 | typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; | |
| 407 | if (__first1 != __last1) { | |
| 408 | __destruct_n __d(0); | |
| 409 | unique_ptr<value_type, __destruct_n&> __h(__first2, __d); | |
| 410 | value_type* __last2 = __first2; | |
| 411 | ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1)); | |
| 412 | __d.template __incr<value_type>(); | |
| 413 | for (++__last2; ++__first1 != __last1; ++__last2) { | |
| 414 | value_type* __j2 = __last2; | |
| 415 | value_type* __i2 = __j2; | |
| 416 | if (__comp(*__first1, *--__i2)) { | |
| 417 | ::new ((void*)__j2) value_type(std::move(*__i2)); | |
| 418 | __d.template __incr<value_type>(); | |
| 419 | for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) | |
| 420 | *__j2 = std::move(*__i2); | |
| 421 | *__j2 = _Ops::__iter_move(__first1); | |
| 422 | } else { | |
| 423 | ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1)); | |
| 424 | __d.template __incr<value_type>(); | |
| 374 | template <class _Compare, | |
| 375 | class _RandomAccessIterator, | |
| 376 | class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type> | |
| 377 | inline _LIBCPP_HIDE_FROM_ABI void | |
| 378 | __populate_left_bitset(_RandomAccessIterator __first, _Compare __comp, _ValueType& __pivot, uint64_t& __left_bitset) { | |
| 379 | // Possible vectorization. With a proper "-march" flag, the following loop | |
| 380 | // will be compiled into a set of SIMD instructions. | |
| 381 | _RandomAccessIterator __iter = __first; | |
| 382 | for (int __j = 0; __j < __detail::__block_size;) { | |
| 383 | bool __comp_result = !__comp(*__iter, __pivot); | |
| 384 | __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j); | |
| 385 | __j++; | |
| 386 | ++__iter; | |
| 387 | } | |
| 388 | } | |
| 389 | ||
| 390 | template <class _Compare, | |
| 391 | class _RandomAccessIterator, | |
| 392 | class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type> | |
| 393 | inline _LIBCPP_HIDE_FROM_ABI void | |
| 394 | __populate_right_bitset(_RandomAccessIterator __lm1, _Compare __comp, _ValueType& __pivot, uint64_t& __right_bitset) { | |
| 395 | // Possible vectorization. With a proper "-march" flag, the following loop | |
| 396 | // will be compiled into a set of SIMD instructions. | |
| 397 | _RandomAccessIterator __iter = __lm1; | |
| 398 | for (int __j = 0; __j < __detail::__block_size;) { | |
| 399 | bool __comp_result = __comp(*__iter, __pivot); | |
| 400 | __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j); | |
| 401 | __j++; | |
| 402 | --__iter; | |
| 403 | } | |
| 404 | } | |
| 405 | ||
| 406 | template <class _AlgPolicy, | |
| 407 | class _Compare, | |
| 408 | class _RandomAccessIterator, | |
| 409 | class _ValueType = typename iterator_traits<_RandomAccessIterator>::value_type> | |
| 410 | inline _LIBCPP_HIDE_FROM_ABI void __bitset_partition_partial_blocks( | |
| 411 | _RandomAccessIterator& __first, | |
| 412 | _RandomAccessIterator& __lm1, | |
| 413 | _Compare __comp, | |
| 414 | _ValueType& __pivot, | |
| 415 | uint64_t& __left_bitset, | |
| 416 | uint64_t& __right_bitset) { | |
| 417 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 418 | difference_type __remaining_len = __lm1 - __first + 1; | |
| 419 | difference_type __l_size; | |
| 420 | difference_type __r_size; | |
| 421 | if (__left_bitset == 0 && __right_bitset == 0) { | |
| 422 | __l_size = __remaining_len / 2; | |
| 423 | __r_size = __remaining_len - __l_size; | |
| 424 | } else if (__left_bitset == 0) { | |
| 425 | // We know at least one side is a full block. | |
| 426 | __l_size = __remaining_len - __detail::__block_size; | |
| 427 | __r_size = __detail::__block_size; | |
| 428 | } else { // if (__right_bitset == 0) | |
| 429 | __l_size = __detail::__block_size; | |
| 430 | __r_size = __remaining_len - __detail::__block_size; | |
| 431 | } | |
| 432 | // Record the comparison outcomes for the elements currently on the left side. | |
| 433 | if (__left_bitset == 0) { | |
| 434 | _RandomAccessIterator __iter = __first; | |
| 435 | for (int __j = 0; __j < __l_size; __j++) { | |
| 436 | bool __comp_result = !__comp(*__iter, __pivot); | |
| 437 | __left_bitset |= (static_cast<uint64_t>(__comp_result) << __j); | |
| 438 | ++__iter; | |
| 439 | } | |
| 440 | } | |
| 441 | // Record the comparison outcomes for the elements currently on the right | |
| 442 | // side. | |
| 443 | if (__right_bitset == 0) { | |
| 444 | _RandomAccessIterator __iter = __lm1; | |
| 445 | for (int __j = 0; __j < __r_size; __j++) { | |
| 446 | bool __comp_result = __comp(*__iter, __pivot); | |
| 447 | __right_bitset |= (static_cast<uint64_t>(__comp_result) << __j); | |
| 448 | --__iter; | |
| 449 | } | |
| 450 | } | |
| 451 | std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset); | |
| 452 | __first += (__left_bitset == 0) ? __l_size : 0; | |
| 453 | __lm1 -= (__right_bitset == 0) ? __r_size : 0; | |
| 454 | } | |
| 455 | ||
| 456 | template <class _AlgPolicy, class _RandomAccessIterator> | |
| 457 | inline _LIBCPP_HIDE_FROM_ABI void __swap_bitmap_pos_within( | |
| 458 | _RandomAccessIterator& __first, _RandomAccessIterator& __lm1, uint64_t& __left_bitset, uint64_t& __right_bitset) { | |
| 459 | using _Ops = _IterOps<_AlgPolicy>; | |
| 460 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 461 | if (__left_bitset) { | |
| 462 | // Swap within the left side. Need to find set positions in the reverse | |
| 463 | // order. | |
| 464 | while (__left_bitset != 0) { | |
| 465 | difference_type __tz_left = __detail::__block_size - 1 - __libcpp_clz(__left_bitset); | |
| 466 | __left_bitset &= (static_cast<uint64_t>(1) << __tz_left) - 1; | |
| 467 | _RandomAccessIterator __it = __first + __tz_left; | |
| 468 | if (__it != __lm1) { | |
| 469 | _Ops::iter_swap(__it, __lm1); | |
| 425 | 470 | } |
| 471 | --__lm1; | |
| 472 | } | |
| 473 | __first = __lm1 + difference_type(1); | |
| 474 | } else if (__right_bitset) { | |
| 475 | // Swap within the right side. Need to find set positions in the reverse | |
| 476 | // order. | |
| 477 | while (__right_bitset != 0) { | |
| 478 | difference_type __tz_right = __detail::__block_size - 1 - __libcpp_clz(__right_bitset); | |
| 479 | __right_bitset &= (static_cast<uint64_t>(1) << __tz_right) - 1; | |
| 480 | _RandomAccessIterator __it = __lm1 - __tz_right; | |
| 481 | if (__it != __first) { | |
| 482 | _Ops::iter_swap(__it, __first); | |
| 483 | } | |
| 484 | ++__first; | |
| 426 | 485 | } |
| 427 | __h.release(); | |
| 428 | 486 | } |
| 429 | 487 | } |
| 430 | 488 | |
| 431 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> | |
| 432 | void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, | |
| 433 | typename iterator_traits<_RandomAccessIterator>::difference_type __depth) { | |
| 489 | // Partition [__first, __last) using the comparator __comp. *__first has the | |
| 490 | // chosen pivot. Elements that are equivalent are kept to the left of the | |
| 491 | // pivot. Returns the iterator for the pivot and a bool value which is true if | |
| 492 | // the provided range is already sorted, false otherwise. We assume that the | |
| 493 | // length of the range is at least three elements. | |
| 494 | // | |
| 495 | // __bitset_partition uses bitsets for storing outcomes of the comparisons | |
| 496 | // between the pivot and other elements. | |
| 497 | template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> | |
| 498 | _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool> | |
| 499 | __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 434 | 500 | using _Ops = _IterOps<_AlgPolicy>; |
| 501 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; | |
| 502 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 503 | _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); | |
| 504 | const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around | |
| 505 | const _RandomAccessIterator __end = __last; (void)__end; // | |
| 506 | ||
| 507 | value_type __pivot(_Ops::__iter_move(__first)); | |
| 508 | // Find the first element greater than the pivot. | |
| 509 | if (__comp(__pivot, *(__last - difference_type(1)))) { | |
| 510 | // Not guarded since we know the last element is greater than the pivot. | |
| 511 | do { | |
| 512 | ++__first; | |
| 513 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 514 | __first != __end, | |
| 515 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 516 | } while (!__comp(__pivot, *__first)); | |
| 517 | } else { | |
| 518 | while (++__first < __last && !__comp(__pivot, *__first)) { | |
| 519 | } | |
| 520 | } | |
| 521 | // Find the last element less than or equal to the pivot. | |
| 522 | if (__first < __last) { | |
| 523 | // It will be always guarded because __introsort will do the median-of-three | |
| 524 | // before calling this. | |
| 525 | do { | |
| 526 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 527 | __last != __begin, | |
| 528 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 529 | --__last; | |
| 530 | } while (__comp(__pivot, *__last)); | |
| 531 | } | |
| 532 | // If the first element greater than the pivot is at or after the | |
| 533 | // last element less than or equal to the pivot, then we have covered the | |
| 534 | // entire range without swapping elements. This implies the range is already | |
| 535 | // partitioned. | |
| 536 | bool __already_partitioned = __first >= __last; | |
| 537 | if (!__already_partitioned) { | |
| 538 | _Ops::iter_swap(__first, __last); | |
| 539 | ++__first; | |
| 540 | } | |
| 435 | 541 | |
| 542 | // In [__first, __last) __last is not inclusive. From now on, it uses last | |
| 543 | // minus one to be inclusive on both sides. | |
| 544 | _RandomAccessIterator __lm1 = __last - difference_type(1); | |
| 545 | uint64_t __left_bitset = 0; | |
| 546 | uint64_t __right_bitset = 0; | |
| 547 | ||
| 548 | // Reminder: length = __lm1 - __first + 1. | |
| 549 | while (__lm1 - __first >= 2 * __detail::__block_size - 1) { | |
| 550 | // Record the comparison outcomes for the elements currently on the left | |
| 551 | // side. | |
| 552 | if (__left_bitset == 0) | |
| 553 | std::__populate_left_bitset<_Compare>(__first, __comp, __pivot, __left_bitset); | |
| 554 | // Record the comparison outcomes for the elements currently on the right | |
| 555 | // side. | |
| 556 | if (__right_bitset == 0) | |
| 557 | std::__populate_right_bitset<_Compare>(__lm1, __comp, __pivot, __right_bitset); | |
| 558 | // Swap the elements recorded to be the candidates for swapping in the | |
| 559 | // bitsets. | |
| 560 | std::__swap_bitmap_pos<_AlgPolicy, _RandomAccessIterator>(__first, __lm1, __left_bitset, __right_bitset); | |
| 561 | // Only advance the iterator if all the elements that need to be moved to | |
| 562 | // other side were moved. | |
| 563 | __first += (__left_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0); | |
| 564 | __lm1 -= (__right_bitset == 0) ? difference_type(__detail::__block_size) : difference_type(0); | |
| 565 | } | |
| 566 | // Now, we have a less-than a block worth of elements on at least one of the | |
| 567 | // sides. | |
| 568 | std::__bitset_partition_partial_blocks<_AlgPolicy, _Compare>( | |
| 569 | __first, __lm1, __comp, __pivot, __left_bitset, __right_bitset); | |
| 570 | // At least one the bitsets would be empty. For the non-empty one, we need to | |
| 571 | // properly partition the elements that appear within that bitset. | |
| 572 | std::__swap_bitmap_pos_within<_AlgPolicy>(__first, __lm1, __left_bitset, __right_bitset); | |
| 573 | ||
| 574 | // Move the pivot to its correct position. | |
| 575 | _RandomAccessIterator __pivot_pos = __first - difference_type(1); | |
| 576 | if (__begin != __pivot_pos) { | |
| 577 | *__begin = _Ops::__iter_move(__pivot_pos); | |
| 578 | } | |
| 579 | *__pivot_pos = std::move(__pivot); | |
| 580 | return std::make_pair(__pivot_pos, __already_partitioned); | |
| 581 | } | |
| 582 | ||
| 583 | // Partition [__first, __last) using the comparator __comp. *__first has the | |
| 584 | // chosen pivot. Elements that are equivalent are kept to the right of the | |
| 585 | // pivot. Returns the iterator for the pivot and a bool value which is true if | |
| 586 | // the provided range is already sorted, false otherwise. We assume that the | |
| 587 | // length of the range is at least three elements. | |
| 588 | template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> | |
| 589 | _LIBCPP_HIDE_FROM_ABI std::pair<_RandomAccessIterator, bool> | |
| 590 | __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 591 | using _Ops = _IterOps<_AlgPolicy>; | |
| 436 | 592 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; |
| 437 | typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; | |
| 438 | const difference_type __limit = | |
| 439 | is_trivially_copy_constructible<value_type>::value && is_trivially_copy_assignable<value_type>::value ? 30 : 6; | |
| 593 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; | |
| 594 | _LIBCPP_ASSERT_UNCATEGORIZED(__last - __first >= difference_type(3), ""); | |
| 595 | const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around | |
| 596 | const _RandomAccessIterator __end = __last; (void)__end; // | |
| 597 | value_type __pivot(_Ops::__iter_move(__first)); | |
| 598 | // Find the first element greater or equal to the pivot. It will be always | |
| 599 | // guarded because __introsort will do the median-of-three before calling | |
| 600 | // this. | |
| 601 | do { | |
| 602 | ++__first; | |
| 603 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 604 | __first != __end, | |
| 605 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 606 | } while (__comp(*__first, __pivot)); | |
| 607 | ||
| 608 | // Find the last element less than the pivot. | |
| 609 | if (__begin == __first - difference_type(1)) { | |
| 610 | while (__first < __last && !__comp(*--__last, __pivot)) | |
| 611 | ; | |
| 612 | } else { | |
| 613 | // Guarded. | |
| 614 | do { | |
| 615 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 616 | __last != __begin, | |
| 617 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 618 | --__last; | |
| 619 | } while (!__comp(*__last, __pivot)); | |
| 620 | } | |
| 621 | ||
| 622 | // If the first element greater than or equal to the pivot is at or after the | |
| 623 | // last element less than the pivot, then we have covered the entire range | |
| 624 | // without swapping elements. This implies the range is already partitioned. | |
| 625 | bool __already_partitioned = __first >= __last; | |
| 626 | // Go through the remaining elements. Swap pairs of elements (one to the | |
| 627 | // right of the pivot and the other to left of the pivot) that are not on the | |
| 628 | // correct side of the pivot. | |
| 629 | while (__first < __last) { | |
| 630 | _Ops::iter_swap(__first, __last); | |
| 631 | do { | |
| 632 | ++__first; | |
| 633 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 634 | __first != __end, | |
| 635 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 636 | } while (__comp(*__first, __pivot)); | |
| 637 | do { | |
| 638 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 639 | __last != __begin, | |
| 640 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 641 | --__last; | |
| 642 | } while (!__comp(*__last, __pivot)); | |
| 643 | } | |
| 644 | // Move the pivot to its correct position. | |
| 645 | _RandomAccessIterator __pivot_pos = __first - difference_type(1); | |
| 646 | if (__begin != __pivot_pos) { | |
| 647 | *__begin = _Ops::__iter_move(__pivot_pos); | |
| 648 | } | |
| 649 | *__pivot_pos = std::move(__pivot); | |
| 650 | return std::make_pair(__pivot_pos, __already_partitioned); | |
| 651 | } | |
| 652 | ||
| 653 | // Similar to the above function. Elements equivalent to the pivot are put to | |
| 654 | // the left of the pivot. Returns the iterator to the pivot element. | |
| 655 | template <class _AlgPolicy, class _RandomAccessIterator, class _Compare> | |
| 656 | _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator | |
| 657 | __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 658 | using _Ops = _IterOps<_AlgPolicy>; | |
| 659 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 660 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; | |
| 661 | // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748 | |
| 662 | _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around | |
| 663 | const _RandomAccessIterator __end = __last; (void)__end; // | |
| 664 | value_type __pivot(_Ops::__iter_move(__first)); | |
| 665 | if (__comp(__pivot, *(__last - difference_type(1)))) { | |
| 666 | // Guarded. | |
| 667 | do { | |
| 668 | ++__first; | |
| 669 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 670 | __first != __end, | |
| 671 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 672 | } while (!__comp(__pivot, *__first)); | |
| 673 | } else { | |
| 674 | while (++__first < __last && !__comp(__pivot, *__first)) { | |
| 675 | } | |
| 676 | } | |
| 677 | ||
| 678 | if (__first < __last) { | |
| 679 | // It will be always guarded because __introsort will do the | |
| 680 | // median-of-three before calling this. | |
| 681 | do { | |
| 682 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 683 | __last != __begin, | |
| 684 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 685 | --__last; | |
| 686 | } while (__comp(__pivot, *__last)); | |
| 687 | } | |
| 688 | while (__first < __last) { | |
| 689 | _Ops::iter_swap(__first, __last); | |
| 690 | do { | |
| 691 | ++__first; | |
| 692 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 693 | __first != __end, | |
| 694 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 695 | } while (!__comp(__pivot, *__first)); | |
| 696 | do { | |
| 697 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 698 | __last != __begin, | |
| 699 | "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); | |
| 700 | --__last; | |
| 701 | } while (__comp(__pivot, *__last)); | |
| 702 | } | |
| 703 | _RandomAccessIterator __pivot_pos = __first - difference_type(1); | |
| 704 | if (__begin != __pivot_pos) { | |
| 705 | *__begin = _Ops::__iter_move(__pivot_pos); | |
| 706 | } | |
| 707 | *__pivot_pos = std::move(__pivot); | |
| 708 | return __first; | |
| 709 | } | |
| 710 | ||
| 711 | // The main sorting function. Implements introsort combined with other ideas: | |
| 712 | // - option of using block quick sort for partitioning, | |
| 713 | // - guarded and unguarded insertion sort for small lengths, | |
| 714 | // - Tuckey's ninther technique for computing the pivot, | |
| 715 | // - check on whether partition was not required. | |
| 716 | // The implementation is partly based on Orson Peters' pattern-defeating | |
| 717 | // quicksort, published at: <https://github.com/orlp/pdqsort>. | |
| 718 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, bool _UseBitSetPartition> | |
| 719 | void __introsort(_RandomAccessIterator __first, | |
| 720 | _RandomAccessIterator __last, | |
| 721 | _Compare __comp, | |
| 722 | typename iterator_traits<_RandomAccessIterator>::difference_type __depth, | |
| 723 | bool __leftmost = true) { | |
| 724 | using _Ops = _IterOps<_AlgPolicy>; | |
| 725 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; | |
| 726 | using _Comp_ref = __comp_ref_type<_Compare>; | |
| 727 | // Upper bound for using insertion sort for sorting. | |
| 728 | _LIBCPP_CONSTEXPR difference_type __limit = 24; | |
| 729 | // Lower bound for using Tuckey's ninther technique for median computation. | |
| 730 | _LIBCPP_CONSTEXPR difference_type __ninther_threshold = 128; | |
| 440 | 731 | while (true) { |
| 441 | __restart: | |
| 442 | 732 | difference_type __len = __last - __first; |
| 443 | 733 | switch (__len) { |
| 444 | 734 | case 0: |
| ... | ... | @@ -446,7 +736,7 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C |
| 446 | 736 | return; |
| 447 | 737 | case 2: |
| 448 | 738 | if (__comp(*--__last, *__first)) |
| 449 | _IterOps<_AlgPolicy>::iter_swap(__first, __last); | |
| 739 | _Ops::iter_swap(__first, __last); | |
| 450 | 740 | return; |
| 451 | 741 | case 3: |
| 452 | 742 | std::__sort3_maybe_branchless<_AlgPolicy, _Compare>(__first, __first + difference_type(1), --__last, __comp); |
| ... | ... | @@ -461,131 +751,62 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C |
| 461 | 751 | --__last, __comp); |
| 462 | 752 | return; |
| 463 | 753 | } |
| 464 | if (__len <= __limit) { | |
| 465 | std::__insertion_sort_3<_AlgPolicy, _Compare>(__first, __last, __comp); | |
| 754 | // Use insertion sort if the length of the range is below the specified limit. | |
| 755 | if (__len < __limit) { | |
| 756 | if (__leftmost) { | |
| 757 | std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); | |
| 758 | } else { | |
| 759 | std::__insertion_sort_unguarded<_AlgPolicy, _Compare>(__first, __last, __comp); | |
| 760 | } | |
| 466 | 761 | return; |
| 467 | 762 | } |
| 468 | // __len > 5 | |
| 469 | 763 | if (__depth == 0) { |
| 470 | 764 | // Fallback to heap sort as Introsort suggests. |
| 471 | 765 | std::__partial_sort<_AlgPolicy, _Compare>(__first, __last, __last, __comp); |
| 472 | 766 | return; |
| 473 | 767 | } |
| 474 | 768 | --__depth; |
| 475 | _RandomAccessIterator __m = __first; | |
| 476 | _RandomAccessIterator __lm1 = __last; | |
| 477 | --__lm1; | |
| 478 | unsigned __n_swaps; | |
| 479 | 769 | { |
| 480 | difference_type __delta; | |
| 481 | if (__len >= 1000) { | |
| 482 | __delta = __len / 2; | |
| 483 | __m += __delta; | |
| 484 | __delta /= 2; | |
| 485 | __n_swaps = std::__sort5_wrap_policy<_AlgPolicy, _Compare>( | |
| 486 | __first, __first + __delta, __m, __m + __delta, __lm1, __comp); | |
| 770 | difference_type __half_len = __len / 2; | |
| 771 | // Use Tuckey's ninther technique or median of 3 for pivot selection | |
| 772 | // depending on the length of the range being sorted. | |
| 773 | if (__len > __ninther_threshold) { | |
| 774 | std::__sort3<_AlgPolicy, _Compare>(__first, __first + __half_len, __last - difference_type(1), __comp); | |
| 775 | std::__sort3<_AlgPolicy, _Compare>( | |
| 776 | __first + difference_type(1), __first + (__half_len - 1), __last - difference_type(2), __comp); | |
| 777 | std::__sort3<_AlgPolicy, _Compare>( | |
| 778 | __first + difference_type(2), __first + (__half_len + 1), __last - difference_type(3), __comp); | |
| 779 | std::__sort3<_AlgPolicy, _Compare>( | |
| 780 | __first + (__half_len - 1), __first + __half_len, __first + (__half_len + 1), __comp); | |
| 781 | _Ops::iter_swap(__first, __first + __half_len); | |
| 487 | 782 | } else { |
| 488 | __delta = __len / 2; | |
| 489 | __m += __delta; | |
| 490 | __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, __lm1, __comp); | |
| 491 | } | |
| 492 | } | |
| 493 | // *__m is median | |
| 494 | // partition [__first, __m) < *__m and *__m <= [__m, __last) | |
| 495 | // (this inhibits tossing elements equivalent to __m around unnecessarily) | |
| 496 | _RandomAccessIterator __i = __first; | |
| 497 | _RandomAccessIterator __j = __lm1; | |
| 498 | // j points beyond range to be tested, *__m is known to be <= *__lm1 | |
| 499 | // The search going up is known to be guarded but the search coming down isn't. | |
| 500 | // Prime the downward search with a guard. | |
| 501 | if (!__comp(*__i, *__m)) // if *__first == *__m | |
| 502 | { | |
| 503 | // *__first == *__m, *__first doesn't go in first part | |
| 504 | // manually guard downward moving __j against __i | |
| 505 | while (true) { | |
| 506 | if (__i == --__j) { | |
| 507 | // *__first == *__m, *__m <= all other elements | |
| 508 | // Parition instead into [__first, __i) == *__first and *__first < [__i, __last) | |
| 509 | ++__i; // __first + 1 | |
| 510 | __j = __last; | |
| 511 | if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1) | |
| 512 | { | |
| 513 | while (true) { | |
| 514 | if (__i == __j) | |
| 515 | return; // [__first, __last) all equivalent elements | |
| 516 | if (__comp(*__first, *__i)) { | |
| 517 | _Ops::iter_swap(__i, __j); | |
| 518 | ++__n_swaps; | |
| 519 | ++__i; | |
| 520 | break; | |
| 521 | } | |
| 522 | ++__i; | |
| 523 | } | |
| 524 | } | |
| 525 | // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 | |
| 526 | if (__i == __j) | |
| 527 | return; | |
| 528 | while (true) { | |
| 529 | while (!__comp(*__first, *__i)) | |
| 530 | ++__i; | |
| 531 | while (__comp(*__first, *--__j)) | |
| 532 | ; | |
| 533 | if (__i >= __j) | |
| 534 | break; | |
| 535 | _Ops::iter_swap(__i, __j); | |
| 536 | ++__n_swaps; | |
| 537 | ++__i; | |
| 538 | } | |
| 539 | // [__first, __i) == *__first and *__first < [__i, __last) | |
| 540 | // The first part is sorted, sort the second part | |
| 541 | // std::__sort<_Compare>(__i, __last, __comp); | |
| 542 | __first = __i; | |
| 543 | goto __restart; | |
| 544 | } | |
| 545 | if (__comp(*__j, *__m)) { | |
| 546 | _Ops::iter_swap(__i, __j); | |
| 547 | ++__n_swaps; | |
| 548 | break; // found guard for downward moving __j, now use unguarded partition | |
| 549 | } | |
| 550 | } | |
| 551 | } | |
| 552 | // It is known that *__i < *__m | |
| 553 | ++__i; | |
| 554 | // j points beyond range to be tested, *__m is known to be <= *__lm1 | |
| 555 | // if not yet partitioned... | |
| 556 | if (__i < __j) { | |
| 557 | // known that *(__i - 1) < *__m | |
| 558 | // known that __i <= __m | |
| 559 | while (true) { | |
| 560 | // __m still guards upward moving __i | |
| 561 | while (__comp(*__i, *__m)) | |
| 562 | ++__i; | |
| 563 | // It is now known that a guard exists for downward moving __j | |
| 564 | while (!__comp(*--__j, *__m)) | |
| 565 | ; | |
| 566 | if (__i > __j) | |
| 567 | break; | |
| 568 | _Ops::iter_swap(__i, __j); | |
| 569 | ++__n_swaps; | |
| 570 | // It is known that __m != __j | |
| 571 | // If __m just moved, follow it | |
| 572 | if (__m == __i) | |
| 573 | __m = __j; | |
| 574 | ++__i; | |
| 783 | std::__sort3<_AlgPolicy, _Compare>(__first + __half_len, __first, __last - difference_type(1), __comp); | |
| 575 | 784 | } |
| 576 | 785 | } |
| 577 | // [__first, __i) < *__m and *__m <= [__i, __last) | |
| 578 | if (__i != __m && __comp(*__m, *__i)) { | |
| 579 | _Ops::iter_swap(__i, __m); | |
| 580 | ++__n_swaps; | |
| 786 | // The elements to the left of the current iterator range are already | |
| 787 | // sorted. If the current iterator range to be sorted is not the | |
| 788 | // leftmost part of the entire iterator range and the pivot is same as | |
| 789 | // the highest element in the range to the left, then we know that all | |
| 790 | // the elements in the range [first, pivot] would be equal to the pivot, | |
| 791 | // assuming the equal elements are put on the left side when | |
| 792 | // partitioned. This also means that we do not need to sort the left | |
| 793 | // side of the partition. | |
| 794 | if (!__leftmost && !__comp(*(__first - difference_type(1)), *__first)) { | |
| 795 | __first = std::__partition_with_equals_on_left<_AlgPolicy, _RandomAccessIterator, _Comp_ref>( | |
| 796 | __first, __last, _Comp_ref(__comp)); | |
| 797 | continue; | |
| 581 | 798 | } |
| 799 | // Use bitset partition only if asked for. | |
| 800 | auto __ret = | |
| 801 | _UseBitSetPartition | |
| 802 | ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) | |
| 803 | : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp); | |
| 804 | _RandomAccessIterator __i = __ret.first; | |
| 582 | 805 | // [__first, __i) < *__i and *__i <= [__i+1, __last) |
| 583 | 806 | // If we were given a perfect partition, see if insertion sort is quick... |
| 584 | if (__n_swaps == 0) { | |
| 585 | using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Compare>::type; | |
| 586 | _WrappedComp __wrapped_comp(__comp); | |
| 587 | bool __fs = std::__insertion_sort_incomplete<_WrappedComp>(__first, __i, __wrapped_comp); | |
| 588 | if (std::__insertion_sort_incomplete<_WrappedComp>(__i + difference_type(1), __last, __wrapped_comp)) { | |
| 807 | if (__ret.second) { | |
| 808 | bool __fs = std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__first, __i, __comp); | |
| 809 | if (std::__insertion_sort_incomplete<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp)) { | |
| 589 | 810 | if (__fs) |
| 590 | 811 | return; |
| 591 | 812 | __last = __i; |
| ... | ... | @@ -597,14 +818,11 @@ void __introsort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C |
| 597 | 818 | } |
| 598 | 819 | } |
| 599 | 820 | } |
| 600 | // sort smaller range with recursive call and larger with tail recursion elimination | |
| 601 | if (__i - __first < __last - __i) { | |
| 602 | std::__introsort<_AlgPolicy, _Compare>(__first, __i, __comp, __depth); | |
| 603 | __first = ++__i; | |
| 604 | } else { | |
| 605 | std::__introsort<_AlgPolicy, _Compare>(__i + difference_type(1), __last, __comp, __depth); | |
| 606 | __last = __i; | |
| 607 | } | |
| 821 | // Sort the left partiton recursively and the right partition with tail recursion elimination. | |
| 822 | std::__introsort<_AlgPolicy, _Compare, _RandomAccessIterator, _UseBitSetPartition>( | |
| 823 | __first, __i, __comp, __depth, __leftmost); | |
| 824 | __leftmost = false; | |
| 825 | __first = ++__i; | |
| 608 | 826 | } |
| 609 | 827 | } |
| 610 | 828 | |
| ... | ... | @@ -627,77 +845,107 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { |
| 627 | 845 | return __log2; |
| 628 | 846 | } |
| 629 | 847 | |
| 630 | template <class _WrappedComp, class _RandomAccessIterator> | |
| 631 | _LIBCPP_HIDDEN void __sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _WrappedComp __wrapped_comp) { | |
| 848 | template <class _Comp, class _RandomAccessIterator> | |
| 849 | void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp); | |
| 850 | ||
| 851 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<char>&, char*>(char*, char*, __less<char>&); | |
| 852 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 853 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
| 854 | #endif | |
| 855 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
| 856 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
| 857 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<short>&, short*>(short*, short*, __less<short>&); | |
| 858 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
| 859 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<int>&, int*>(int*, int*, __less<int>&); | |
| 860 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
| 861 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long>&, long*>(long*, long*, __less<long>&); | |
| 862 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
| 863 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
| 864 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
| 865 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<float>&, float*>(float*, float*, __less<float>&); | |
| 866 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<double>&, double*>(double*, double*, __less<double>&); | |
| 867 | extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
| 868 | ||
| 869 | template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> | |
| 870 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void | |
| 871 | __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { | |
| 632 | 872 | typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; |
| 633 | 873 | difference_type __depth_limit = 2 * std::__log2i(__last - __first); |
| 634 | 874 | |
| 635 | using _Unwrap = _UnwrapAlgPolicy<_WrappedComp>; | |
| 636 | using _AlgPolicy = typename _Unwrap::_AlgPolicy; | |
| 637 | using _Compare = typename _Unwrap::_Comp; | |
| 638 | _Compare __comp = _Unwrap::__get_comp(__wrapped_comp); | |
| 639 | std::__introsort<_AlgPolicy, _Compare>(__first, __last, __comp, __depth_limit); | |
| 875 | // Only use bitset partitioning for arithmetic types. We should also check | |
| 876 | // that the default comparator is in use so that we are sure that there are no | |
| 877 | // branches in the comparator. | |
| 878 | std::__introsort<_AlgPolicy, | |
| 879 | _Comp&, | |
| 880 | _RandomAccessIterator, | |
| 881 | __use_branchless_sort<_Comp, _RandomAccessIterator>::value>( | |
| 882 | __first, __last, __comp, __depth_limit); | |
| 640 | 883 | } |
| 641 | 884 | |
| 642 | template <class _Compare, class _Tp> | |
| 643 | inline _LIBCPP_INLINE_VISIBILITY void __sort(_Tp** __first, _Tp** __last, __less<_Tp*>&) { | |
| 644 | __less<uintptr_t> __comp; | |
| 645 | std::__sort<__less<uintptr_t>&, uintptr_t*>((uintptr_t*)__first, (uintptr_t*)__last, __comp); | |
| 646 | } | |
| 885 | template <class _Type, class... _Options> | |
| 886 | using __is_any_of = _Or<is_same<_Type, _Options>...>; | |
| 647 | 887 | |
| 648 | extern template _LIBCPP_FUNC_VIS void __sort<__less<char>&, char*>(char*, char*, __less<char>&); | |
| 888 | template <class _Type> | |
| 889 | using __sort_is_specialized_in_library = __is_any_of< | |
| 890 | _Type, | |
| 891 | char, | |
| 649 | 892 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 650 | extern template _LIBCPP_FUNC_VIS void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
| 893 | wchar_t, | |
| 651 | 894 | #endif |
| 652 | extern template _LIBCPP_FUNC_VIS void __sort<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
| 653 | extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
| 654 | extern template _LIBCPP_FUNC_VIS void __sort<__less<short>&, short*>(short*, short*, __less<short>&); | |
| 655 | extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
| 656 | extern template _LIBCPP_FUNC_VIS void __sort<__less<int>&, int*>(int*, int*, __less<int>&); | |
| 657 | extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
| 658 | extern template _LIBCPP_FUNC_VIS void __sort<__less<long>&, long*>(long*, long*, __less<long>&); | |
| 659 | extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
| 660 | extern template _LIBCPP_FUNC_VIS void __sort<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
| 661 | extern template _LIBCPP_FUNC_VIS void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
| 662 | extern template _LIBCPP_FUNC_VIS void __sort<__less<float>&, float*>(float*, float*, __less<float>&); | |
| 663 | extern template _LIBCPP_FUNC_VIS void __sort<__less<double>&, double*>(double*, double*, __less<double>&); | |
| 664 | extern template _LIBCPP_FUNC_VIS void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
| 665 | ||
| 666 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&); | |
| 667 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 668 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
| 895 | signed char, | |
| 896 | unsigned char, | |
| 897 | short, | |
| 898 | unsigned short, | |
| 899 | int, | |
| 900 | unsigned int, | |
| 901 | long, | |
| 902 | unsigned long, | |
| 903 | long long, | |
| 904 | unsigned long long, | |
| 905 | float, | |
| 906 | double, | |
| 907 | long double>; | |
| 908 | ||
| 909 | template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0> | |
| 910 | _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) { | |
| 911 | __less<_Type> __comp; | |
| 912 | std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp); | |
| 913 | } | |
| 914 | ||
| 915 | template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0> | |
| 916 | _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<_Type>&) { | |
| 917 | __less<_Type> __comp; | |
| 918 | std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp); | |
| 919 | } | |
| 920 | ||
| 921 | #if _LIBCPP_STD_VER >= 14 | |
| 922 | template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0> | |
| 923 | _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, less<>&) { | |
| 924 | __less<_Type> __comp; | |
| 925 | std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp); | |
| 926 | } | |
| 927 | #endif | |
| 928 | ||
| 929 | #if _LIBCPP_STD_VER >= 20 | |
| 930 | template <class _AlgPolicy, class _Type, __enable_if_t<__sort_is_specialized_in_library<_Type>::value, int> = 0> | |
| 931 | _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges::less&) { | |
| 932 | __less<_Type> __comp; | |
| 933 | std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp); | |
| 934 | } | |
| 669 | 935 | #endif |
| 670 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
| 671 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
| 672 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&); | |
| 673 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
| 674 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&); | |
| 675 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
| 676 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&); | |
| 677 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
| 678 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
| 679 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
| 680 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&); | |
| 681 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&); | |
| 682 | extern template _LIBCPP_FUNC_VIS bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
| 683 | ||
| 684 | extern template _LIBCPP_FUNC_VIS unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); | |
| 685 | 936 | |
| 686 | 937 | template <class _AlgPolicy, class _RandomAccessIterator, class _Comp> |
| 687 | 938 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 688 | 939 | void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { |
| 689 | 940 | std::__debug_randomize_range<_AlgPolicy>(__first, __last); |
| 690 | 941 | |
| 691 | using _Comp_ref = __comp_ref_type<_Comp>; | |
| 692 | 942 | if (__libcpp_is_constant_evaluated()) { |
| 693 | std::__partial_sort<_AlgPolicy>(__first, __last, __last, __comp); | |
| 694 | ||
| 943 | std::__partial_sort<_AlgPolicy>( | |
| 944 | std::__unwrap_iter(__first), std::__unwrap_iter(__last), std::__unwrap_iter(__last), __comp); | |
| 695 | 945 | } else { |
| 696 | using _WrappedComp = typename _WrapAlgPolicy<_AlgPolicy, _Comp_ref>::type; | |
| 697 | _Comp_ref __comp_ref(__comp); | |
| 698 | _WrappedComp __wrapped_comp(__comp_ref); | |
| 699 | std::__sort<_WrappedComp>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __wrapped_comp); | |
| 946 | std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp); | |
| 700 | 947 | } |
| 948 | std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp); | |
| 701 | 949 | } |
| 702 | 950 | |
| 703 | 951 | template <class _RandomAccessIterator, class _Comp> |
| ... | ... | @@ -709,7 +957,7 @@ void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __c |
| 709 | 957 | template <class _RandomAccessIterator> |
| 710 | 958 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 711 | 959 | void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 712 | std::sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 960 | std::sort(__first, __last, __less<>()); | |
| 713 | 961 | } |
| 714 | 962 | |
| 715 | 963 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/sort_heap.h+6-3| ... | ... | @@ -14,9 +14,11 @@ |
| 14 | 14 | #include <__algorithm/iterator_operations.h> |
| 15 | 15 | #include <__algorithm/pop_heap.h> |
| 16 | 16 | #include <__config> |
| 17 | #include <__debug_utils/strict_weak_ordering_check.h> | |
| 17 | 18 | #include <__iterator/iterator_traits.h> |
| 19 | #include <__type_traits/is_copy_assignable.h> | |
| 20 | #include <__type_traits/is_copy_constructible.h> | |
| 18 | 21 | #include <__utility/move.h> |
| 19 | #include <type_traits> | |
| 20 | 22 | |
| 21 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 24 | # pragma GCC system_header |
| ... | ... | @@ -27,11 +29,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 29 | template <class _AlgPolicy, class _Compare, class _RandomAccessIterator> |
| 28 | 30 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 29 | 31 | void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { |
| 32 | _RandomAccessIterator __saved_last = __last; | |
| 30 | 33 | __comp_ref_type<_Compare> __comp_ref = __comp; |
| 31 | 34 | |
| 32 | 35 | using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; |
| 33 | 36 | for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) |
| 34 | 37 | std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); |
| 38 | std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref); | |
| 35 | 39 | } |
| 36 | 40 | |
| 37 | 41 | template <class _RandomAccessIterator, class _Compare> |
| ... | ... | @@ -46,8 +50,7 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com |
| 46 | 50 | template <class _RandomAccessIterator> |
| 47 | 51 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 48 | 52 | void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 49 | std::sort_heap(std::move(__first), std::move(__last), | |
| 50 | __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 53 | std::sort_heap(std::move(__first), std::move(__last), __less<>()); | |
| 51 | 54 | } |
| 52 | 55 | |
| 53 | 56 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/stable_partition.h+4-4| ... | ... | @@ -21,7 +21,6 @@ |
| 21 | 21 | #include <__utility/move.h> |
| 22 | 22 | #include <__utility/pair.h> |
| 23 | 23 | #include <new> |
| 24 | #include <type_traits> | |
| 25 | 24 | |
| 26 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 26 | # pragma GCC system_header |
| ... | ... | @@ -123,7 +122,10 @@ _LIBCPP_HIDE_FROM_ABI _ForwardIterator |
| 123 | 122 | __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, |
| 124 | 123 | forward_iterator_tag) |
| 125 | 124 | { |
| 126 | const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment | |
| 125 | typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; | |
| 126 | typedef typename iterator_traits<_ForwardIterator>::value_type value_type; | |
| 127 | ||
| 128 | const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment | |
| 127 | 129 | // Either prove all true and return __first or point to first false |
| 128 | 130 | while (true) |
| 129 | 131 | { |
| ... | ... | @@ -135,8 +137,6 @@ __stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Pred |
| 135 | 137 | } |
| 136 | 138 | // We now have a reduced range [__first, __last) |
| 137 | 139 | // *__first is known to be false |
| 138 | typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; | |
| 139 | typedef typename iterator_traits<_ForwardIterator>::value_type value_type; | |
| 140 | 140 | difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); |
| 141 | 141 | pair<value_type*, ptrdiff_t> __p(0, 0); |
| 142 | 142 | unique_ptr<value_type, __return_temporary_buffer> __h; |
lib/libcxx/include/__algorithm/stable_sort.h+35-2| ... | ... | @@ -15,14 +15,15 @@ |
| 15 | 15 | #include <__algorithm/iterator_operations.h> |
| 16 | 16 | #include <__algorithm/sort.h> |
| 17 | 17 | #include <__config> |
| 18 | #include <__debug_utils/strict_weak_ordering_check.h> | |
| 18 | 19 | #include <__iterator/iterator_traits.h> |
| 19 | 20 | #include <__memory/destruct_n.h> |
| 20 | 21 | #include <__memory/temporary_buffer.h> |
| 21 | 22 | #include <__memory/unique_ptr.h> |
| 23 | #include <__type_traits/is_trivially_copy_assignable.h> | |
| 22 | 24 | #include <__utility/move.h> |
| 23 | 25 | #include <__utility/pair.h> |
| 24 | 26 | #include <new> |
| 25 | #include <type_traits> | |
| 26 | 27 | |
| 27 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 28 | 29 | # pragma GCC system_header |
| ... | ... | @@ -30,6 +31,37 @@ |
| 30 | 31 | |
| 31 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 33 | |
| 34 | template <class _AlgPolicy, class _Compare, class _BidirectionalIterator> | |
| 35 | _LIBCPP_HIDE_FROM_ABI | |
| 36 | void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, | |
| 37 | typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { | |
| 38 | using _Ops = _IterOps<_AlgPolicy>; | |
| 39 | ||
| 40 | typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; | |
| 41 | if (__first1 != __last1) { | |
| 42 | __destruct_n __d(0); | |
| 43 | unique_ptr<value_type, __destruct_n&> __h(__first2, __d); | |
| 44 | value_type* __last2 = __first2; | |
| 45 | ::new ((void*)__last2) value_type(_Ops::__iter_move(__first1)); | |
| 46 | __d.template __incr<value_type>(); | |
| 47 | for (++__last2; ++__first1 != __last1; ++__last2) { | |
| 48 | value_type* __j2 = __last2; | |
| 49 | value_type* __i2 = __j2; | |
| 50 | if (__comp(*__first1, *--__i2)) { | |
| 51 | ::new ((void*)__j2) value_type(std::move(*__i2)); | |
| 52 | __d.template __incr<value_type>(); | |
| 53 | for (--__j2; __i2 != __first2 && __comp(*__first1, *--__i2); --__j2) | |
| 54 | *__j2 = std::move(*__i2); | |
| 55 | *__j2 = _Ops::__iter_move(__first1); | |
| 56 | } else { | |
| 57 | ::new ((void*)__j2) value_type(_Ops::__iter_move(__first1)); | |
| 58 | __d.template __incr<value_type>(); | |
| 59 | } | |
| 60 | } | |
| 61 | __h.release(); | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 33 | 65 | template <class _AlgPolicy, class _Compare, class _InputIterator1, class _InputIterator2> |
| 34 | 66 | _LIBCPP_HIDE_FROM_ABI void |
| 35 | 67 | __merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, |
| ... | ... | @@ -228,6 +260,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 228 | 260 | } |
| 229 | 261 | |
| 230 | 262 | std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); |
| 263 | std::__check_strict_weak_ordering_sorted(__first, __last, __comp); | |
| 231 | 264 | } |
| 232 | 265 | |
| 233 | 266 | template <class _RandomAccessIterator, class _Compare> |
| ... | ... | @@ -239,7 +272,7 @@ void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _C |
| 239 | 272 | template <class _RandomAccessIterator> |
| 240 | 273 | inline _LIBCPP_HIDE_FROM_ABI |
| 241 | 274 | void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { |
| 242 | std::stable_sort(__first, __last, __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); | |
| 275 | std::stable_sort(__first, __last, __less<>()); | |
| 243 | 276 | } |
| 244 | 277 | |
| 245 | 278 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__algorithm/three_way_comp_ref_type.h created+73| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H | |
| 10 | #define _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H | |
| 11 | ||
| 12 | #include <__compare/ordering.h> | |
| 13 | #include <__config> | |
| 14 | #include <__utility/declval.h> | |
| 15 | #include <__utility/forward.h> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | ||
| 25 | template <class _Comp> | |
| 26 | struct __debug_three_way_comp { | |
| 27 | _Comp& __comp_; | |
| 28 | _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {} | |
| 29 | ||
| 30 | template <class _Tp, class _Up> | |
| 31 | _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) { | |
| 32 | auto __r = __comp_(__x, __y); | |
| 33 | if constexpr (__comparison_category<decltype(__comp_(__x, __y))>) | |
| 34 | __do_compare_assert(__y, __x, __r); | |
| 35 | return __r; | |
| 36 | } | |
| 37 | ||
| 38 | template <class _Tp, class _Up> | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) { | |
| 40 | auto __r = __comp_(__x, __y); | |
| 41 | if constexpr (__comparison_category<decltype(__comp_(__x, __y))>) | |
| 42 | __do_compare_assert(__y, __x, __r); | |
| 43 | return __r; | |
| 44 | } | |
| 45 | ||
| 46 | template <class _LHS, class _RHS, class _Order> | |
| 47 | _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) { | |
| 48 | _Order __expected = __o; | |
| 49 | if (__o == _Order::less) | |
| 50 | __expected = _Order::greater; | |
| 51 | if (__o == _Order::greater) | |
| 52 | __expected = _Order::less; | |
| 53 | _LIBCPP_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); | |
| 54 | (void)__l; | |
| 55 | (void)__r; | |
| 56 | } | |
| 57 | }; | |
| 58 | ||
| 59 | // Pass the comparator by lvalue reference. Or in debug mode, using a | |
| 60 | // debugging wrapper that stores a reference. | |
| 61 | # if _LIBCPP_ENABLE_DEBUG_MODE | |
| 62 | template <class _Comp> | |
| 63 | using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>; | |
| 64 | # else | |
| 65 | template <class _Comp> | |
| 66 | using __three_way_comp_ref_type = _Comp&; | |
| 67 | # endif | |
| 68 | ||
| 69 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | ||
| 71 | _LIBCPP_END_NAMESPACE_STD | |
| 72 | ||
| 73 | #endif // _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H |
lib/libcxx/include/__algorithm/uniform_random_bit_generator_adaptor.h+3-3| ... | ... | @@ -11,13 +11,13 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__functional/invoke.h> |
| 14 | #include <type_traits> | |
| 14 | #include <__type_traits/remove_cvref.h> | |
| 15 | 15 | |
| 16 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | #if _LIBCPP_STD_VER > 17 | |
| 20 | #if _LIBCPP_STD_VER >= 20 | |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_PUSH_MACROS |
| 23 | 23 | #include <__undef_macros> |
| ... | ... | @@ -57,6 +57,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 57 | 57 | |
| 58 | 58 | _LIBCPP_POP_MACROS |
| 59 | 59 | |
| 60 | #endif // _LIBCPP_STD_VER > 17 | |
| 60 | #endif // _LIBCPP_STD_VER >= 20 | |
| 61 | 61 | |
| 62 | 62 | #endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H |
lib/libcxx/include/__algorithm/unwrap_iter.h+16-5| ... | ... | @@ -21,24 +21,27 @@ |
| 21 | 21 | # pragma GCC system_header |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | _LIBCPP_PUSH_MACROS | |
| 25 | #include <__undef_macros> | |
| 26 | ||
| 24 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 28 | |
| 26 | 29 | // TODO: Change the name of __unwrap_iter_impl to something more appropriate |
| 27 | 30 | // The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter), |
| 28 | 31 | // to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy. |
| 29 | // In debug mode, we don't do this. | |
| 30 | 32 | // |
| 31 | 33 | // Some algorithms (e.g. std::copy, but not std::sort) need to convert an |
| 32 | 34 | // "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter. |
| 33 | 35 | |
| 34 | 36 | // Default case - we can't unwrap anything |
| 35 | template <class _Iter, bool = __is_cpp17_contiguous_iterator<_Iter>::value> | |
| 37 | template <class _Iter, bool = __libcpp_is_contiguous_iterator<_Iter>::value> | |
| 36 | 38 | struct __unwrap_iter_impl { |
| 37 | 39 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap(_Iter, _Iter __iter) { return __iter; } |
| 38 | 40 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; } |
| 39 | 41 | }; |
| 40 | 42 | |
| 41 | #ifndef _LIBCPP_ENABLE_DEBUG_MODE | |
| 43 | // TODO(hardening): make sure that the following unwrapping doesn't unexpectedly turn hardened iterators into raw | |
| 44 | // pointers. | |
| 42 | 45 | |
| 43 | 46 | // It's a contiguous iterator, so we can use a raw pointer instead |
| 44 | 47 | template <class _Iter> |
| ... | ... | @@ -54,8 +57,6 @@ struct __unwrap_iter_impl<_Iter, true> { |
| 54 | 57 | } |
| 55 | 58 | }; |
| 56 | 59 | |
| 57 | #endif // !_LIBCPP_ENABLE_DEBUG_MODE | |
| 58 | ||
| 59 | 60 | template<class _Iter, |
| 60 | 61 | class _Impl = __unwrap_iter_impl<_Iter>, |
| 61 | 62 | __enable_if_t<is_copy_constructible<_Iter>::value, int> = 0> |
| ... | ... | @@ -64,6 +65,14 @@ decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXC |
| 64 | 65 | return _Impl::__unwrap(__i); |
| 65 | 66 | } |
| 66 | 67 | |
| 68 | // Allow input_iterators to be passed to __unwrap_iter (but not __rewrap_iter) | |
| 69 | #if _LIBCPP_STD_VER >= 20 | |
| 70 | template <class _Iter, __enable_if_t<!is_copy_constructible<_Iter>::value, int> = 0> | |
| 71 | inline _LIBCPP_HIDE_FROM_ABI constexpr _Iter __unwrap_iter(_Iter __i) noexcept { | |
| 72 | return __i; | |
| 73 | } | |
| 74 | #endif | |
| 75 | ||
| 67 | 76 | template <class _OrigIter, class _Iter, class _Impl = __unwrap_iter_impl<_OrigIter> > |
| 68 | 77 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig_iter, _Iter __iter) _NOEXCEPT { |
| 69 | 78 | return _Impl::__rewrap(std::move(__orig_iter), std::move(__iter)); |
| ... | ... | @@ -71,4 +80,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig |
| 71 | 80 | |
| 72 | 81 | _LIBCPP_END_NAMESPACE_STD |
| 73 | 82 | |
| 83 | _LIBCPP_PUSH_MACROS | |
| 84 | ||
| 74 | 85 | #endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H |
lib/libcxx/include/__algorithm/unwrap_range.h+4-4| ... | ... | @@ -28,7 +28,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | // __unwrap_iter and __rewrap_iter don't work for this, because they assume that the iterator and sentinel have |
| 29 | 29 | // the same type. __unwrap_range tries to get two iterators and then forward to __unwrap_iter. |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | template <class _Iter, class _Sent> |
| 33 | 33 | struct __unwrap_range_impl { |
| 34 | 34 | _LIBCPP_HIDE_FROM_ABI static constexpr auto __unwrap(_Iter __first, _Sent __sent) |
| ... | ... | @@ -43,7 +43,7 @@ struct __unwrap_range_impl { |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | _LIBCPP_HIDE_FROM_ABI static constexpr auto |
| 46 | __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(__orig_iter)) __iter) | |
| 46 | __rewrap(_Iter __orig_iter, decltype(std::__unwrap_iter(std::move(__orig_iter))) __iter) | |
| 47 | 47 | requires random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter> |
| 48 | 48 | { |
| 49 | 49 | return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); |
| ... | ... | @@ -80,7 +80,7 @@ template < |
| 80 | 80 | _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { |
| 81 | 81 | return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter)); |
| 82 | 82 | } |
| 83 | #else // _LIBCPP_STD_VER > 17 | |
| 83 | #else // _LIBCPP_STD_VER >= 20 | |
| 84 | 84 | template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declval<_Iter>()))> |
| 85 | 85 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_range(_Iter __first, _Iter __last) { |
| 86 | 86 | return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))); |
| ... | ... | @@ -90,7 +90,7 @@ template <class _Iter, class _Unwrapped = decltype(std::__unwrap_iter(std::declv |
| 90 | 90 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { |
| 91 | 91 | return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); |
| 92 | 92 | } |
| 93 | #endif // _LIBCPP_STD_VER > 17 | |
| 93 | #endif // _LIBCPP_STD_VER >= 20 | |
| 94 | 94 | |
| 95 | 95 | _LIBCPP_END_NAMESPACE_STD |
| 96 | 96 |
lib/libcxx/include/__algorithm/upper_bound.h+7-7| ... | ... | @@ -25,6 +25,9 @@ |
| 25 | 25 | # pragma GCC system_header |
| 26 | 26 | #endif |
| 27 | 27 | |
| 28 | _LIBCPP_PUSH_MACROS | |
| 29 | #include <__undef_macros> | |
| 30 | ||
| 28 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 32 | |
| 30 | 33 | template <class _AlgPolicy, class _Compare, class _Iter, class _Sent, class _Tp, class _Proj> |
| ... | ... | @@ -47,8 +50,7 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp |
| 47 | 50 | template <class _ForwardIterator, class _Tp, class _Compare> |
| 48 | 51 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator |
| 49 | 52 | upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { |
| 50 | static_assert(is_copy_constructible<_ForwardIterator>::value, | |
| 51 | "Iterator has to be copy constructible"); | |
| 53 | static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); | |
| 52 | 54 | return std::__upper_bound<_ClassicAlgPolicy>( |
| 53 | 55 | std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity()); |
| 54 | 56 | } |
| ... | ... | @@ -56,13 +58,11 @@ upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu |
| 56 | 58 | template <class _ForwardIterator, class _Tp> |
| 57 | 59 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator |
| 58 | 60 | upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { |
| 59 | return std::upper_bound( | |
| 60 | std::move(__first), | |
| 61 | std::move(__last), | |
| 62 | __value, | |
| 63 | __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 61 | return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>()); | |
| 64 | 62 | } |
| 65 | 63 | |
| 66 | 64 | _LIBCPP_END_NAMESPACE_STD |
| 67 | 65 | |
| 66 | _LIBCPP_POP_MACROS | |
| 67 | ||
| 68 | 68 | #endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H |
lib/libcxx/include/__assert+14-32| ... | ... | @@ -17,39 +17,21 @@ |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | // TODO: Remove in LLVM 17. | |
| 21 | #if defined(_LIBCPP_DEBUG) | |
| 22 | # error "Defining _LIBCPP_DEBUG is not supported anymore. Please use _LIBCPP_ENABLE_DEBUG_MODE instead." | |
| 23 | #endif | |
| 24 | ||
| 25 | // Automatically enable assertions when the debug mode is enabled. | |
| 26 | #if defined(_LIBCPP_ENABLE_DEBUG_MODE) | |
| 27 | # ifndef _LIBCPP_ENABLE_ASSERTIONS | |
| 28 | # define _LIBCPP_ENABLE_ASSERTIONS 1 | |
| 29 | # endif | |
| 30 | #endif | |
| 31 | ||
| 32 | #ifndef _LIBCPP_ENABLE_ASSERTIONS | |
| 33 | # define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT | |
| 34 | #endif | |
| 35 | ||
| 36 | #if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 | |
| 37 | # error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" | |
| 38 | #endif | |
| 39 | ||
| 40 | #if _LIBCPP_ENABLE_ASSERTIONS | |
| 41 | # define _LIBCPP_ASSERT(expression, message) \ | |
| 42 | (__builtin_expect(static_cast<bool>(expression), 1) ? \ | |
| 43 | (void)0 : \ | |
| 44 | _LIBCPP_VERBOSE_ABORT("%s:%d: assertion %s failed: %s", __FILE__, __LINE__, #expression, message)) | |
| 45 | #elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume) | |
| 46 | # define _LIBCPP_ASSERT(expression, message) \ | |
| 47 | (_LIBCPP_DIAGNOSTIC_PUSH \ | |
| 48 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ | |
| 49 | __builtin_assume(static_cast<bool>(expression)) \ | |
| 50 | _LIBCPP_DIAGNOSTIC_POP) | |
| 20 | #define _LIBCPP_ASSERT(expression, message) \ | |
| 21 | (__builtin_expect(static_cast<bool>(expression), 1) \ | |
| 22 | ? (void)0 \ | |
| 23 | : _LIBCPP_VERBOSE_ABORT( \ | |
| 24 | "%s:%d: assertion %s failed: %s\n", __builtin_FILE(), __builtin_LINE(), #expression, message)) | |
| 25 | ||
| 26 | // TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add | |
| 27 | // assumptions without a clear optimization intent, disable that to avoid worsening the code generation. | |
| 28 | // See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion. | |
| 29 | #if 0 && __has_builtin(__builtin_assume) | |
| 30 | # define _LIBCPP_ASSUME(expression) \ | |
| 31 | (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ | |
| 32 | __builtin_assume(static_cast<bool>(expression)) _LIBCPP_DIAGNOSTIC_POP) | |
| 51 | 33 | #else |
| 52 | # define _LIBCPP_ASSERT(expression, message) ((void)0) | |
| 34 | # define _LIBCPP_ASSUME(expression) ((void)0) | |
| 53 | 35 | #endif |
| 54 | 36 | |
| 55 | 37 | #endif // _LIBCPP___ASSERT |
lib/libcxx/include/__atomic/aliases.h created+116| ... | ... | @@ -0,0 +1,116 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ALIASES_H | |
| 10 | #define _LIBCPP___ATOMIC_ALIASES_H | |
| 11 | ||
| 12 | #include <__atomic/atomic.h> | |
| 13 | #include <__atomic/atomic_lock_free.h> | |
| 14 | #include <__atomic/contention_t.h> | |
| 15 | #include <__atomic/is_always_lock_free.h> | |
| 16 | #include <__config> | |
| 17 | #include <__type_traits/conditional.h> | |
| 18 | #include <cstddef> | |
| 19 | #include <cstdint> | |
| 20 | #include <cstdlib> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | using atomic_bool = atomic<bool>; | |
| 29 | using atomic_char = atomic<char>; | |
| 30 | using atomic_schar = atomic<signed char>; | |
| 31 | using atomic_uchar = atomic<unsigned char>; | |
| 32 | using atomic_short = atomic<short>; | |
| 33 | using atomic_ushort = atomic<unsigned short>; | |
| 34 | using atomic_int = atomic<int>; | |
| 35 | using atomic_uint = atomic<unsigned int>; | |
| 36 | using atomic_long = atomic<long>; | |
| 37 | using atomic_ulong = atomic<unsigned long>; | |
| 38 | using atomic_llong = atomic<long long>; | |
| 39 | using atomic_ullong = atomic<unsigned long long>; | |
| 40 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 41 | using atomic_char8_t = atomic<char8_t>; | |
| 42 | #endif | |
| 43 | using atomic_char16_t = atomic<char16_t>; | |
| 44 | using atomic_char32_t = atomic<char32_t>; | |
| 45 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 46 | using atomic_wchar_t = atomic<wchar_t>; | |
| 47 | #endif | |
| 48 | ||
| 49 | using atomic_int_least8_t = atomic<int_least8_t>; | |
| 50 | using atomic_uint_least8_t = atomic<uint_least8_t>; | |
| 51 | using atomic_int_least16_t = atomic<int_least16_t>; | |
| 52 | using atomic_uint_least16_t = atomic<uint_least16_t>; | |
| 53 | using atomic_int_least32_t = atomic<int_least32_t>; | |
| 54 | using atomic_uint_least32_t = atomic<uint_least32_t>; | |
| 55 | using atomic_int_least64_t = atomic<int_least64_t>; | |
| 56 | using atomic_uint_least64_t = atomic<uint_least64_t>; | |
| 57 | ||
| 58 | using atomic_int_fast8_t = atomic<int_fast8_t>; | |
| 59 | using atomic_uint_fast8_t = atomic<uint_fast8_t>; | |
| 60 | using atomic_int_fast16_t = atomic<int_fast16_t>; | |
| 61 | using atomic_uint_fast16_t = atomic<uint_fast16_t>; | |
| 62 | using atomic_int_fast32_t = atomic<int_fast32_t>; | |
| 63 | using atomic_uint_fast32_t = atomic<uint_fast32_t>; | |
| 64 | using atomic_int_fast64_t = atomic<int_fast64_t>; | |
| 65 | using atomic_uint_fast64_t = atomic<uint_fast64_t>; | |
| 66 | ||
| 67 | using atomic_int8_t = atomic< int8_t>; | |
| 68 | using atomic_uint8_t = atomic<uint8_t>; | |
| 69 | using atomic_int16_t = atomic< int16_t>; | |
| 70 | using atomic_uint16_t = atomic<uint16_t>; | |
| 71 | using atomic_int32_t = atomic< int32_t>; | |
| 72 | using atomic_uint32_t = atomic<uint32_t>; | |
| 73 | using atomic_int64_t = atomic< int64_t>; | |
| 74 | using atomic_uint64_t = atomic<uint64_t>; | |
| 75 | ||
| 76 | using atomic_intptr_t = atomic<intptr_t>; | |
| 77 | using atomic_uintptr_t = atomic<uintptr_t>; | |
| 78 | using atomic_size_t = atomic<size_t>; | |
| 79 | using atomic_ptrdiff_t = atomic<ptrdiff_t>; | |
| 80 | using atomic_intmax_t = atomic<intmax_t>; | |
| 81 | using atomic_uintmax_t = atomic<uintmax_t>; | |
| 82 | ||
| 83 | // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type | |
| 84 | ||
| 85 | #if _LIBCPP_STD_VER >= 17 | |
| 86 | # define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value | |
| 87 | #else | |
| 88 | # define _LIBCPP_CONTENTION_LOCK_FREE false | |
| 89 | #endif | |
| 90 | ||
| 91 | #if ATOMIC_LLONG_LOCK_FREE == 2 | |
| 92 | using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>; | |
| 93 | using __libcpp_unsigned_lock_free = | |
| 94 | __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>; | |
| 95 | #elif ATOMIC_INT_LOCK_FREE == 2 | |
| 96 | using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>; | |
| 97 | using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>; | |
| 98 | #elif ATOMIC_SHORT_LOCK_FREE == 2 | |
| 99 | using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>; | |
| 100 | using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>; | |
| 101 | #elif ATOMIC_CHAR_LOCK_FREE == 2 | |
| 102 | using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>; | |
| 103 | using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>; | |
| 104 | #else | |
| 105 | // No signed/unsigned lock-free types | |
| 106 | # define _LIBCPP_NO_LOCK_FREE_TYPES | |
| 107 | #endif | |
| 108 | ||
| 109 | #if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) | |
| 110 | using atomic_signed_lock_free = atomic<__libcpp_signed_lock_free>; | |
| 111 | using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>; | |
| 112 | #endif | |
| 113 | ||
| 114 | _LIBCPP_END_NAMESPACE_STD | |
| 115 | ||
| 116 | #endif // _LIBCPP___ATOMIC_ALIASES_H |
lib/libcxx/include/__atomic/atomic.h created+664| ... | ... | @@ -0,0 +1,664 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_H | |
| 11 | ||
| 12 | #include <__atomic/atomic_base.h> | |
| 13 | #include <__atomic/check_memory_order.h> | |
| 14 | #include <__atomic/cxx_atomic_impl.h> | |
| 15 | #include <__atomic/memory_order.h> | |
| 16 | #include <__config> | |
| 17 | #include <__memory/addressof.h> | |
| 18 | #include <__type_traits/is_function.h> | |
| 19 | #include <__type_traits/is_same.h> | |
| 20 | #include <__type_traits/remove_pointer.h> | |
| 21 | #include <cstddef> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct atomic | |
| 31 | : public __atomic_base<_Tp> | |
| 32 | { | |
| 33 | using __base = __atomic_base<_Tp>; | |
| 34 | using value_type = _Tp; | |
| 35 | using difference_type = value_type; | |
| 36 | ||
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | _LIBCPP_HIDE_FROM_ABI | |
| 39 | atomic() = default; | |
| 40 | #else | |
| 41 | _LIBCPP_HIDE_FROM_ABI | |
| 42 | atomic() _NOEXCEPT = default; | |
| 43 | #endif | |
| 44 | ||
| 45 | _LIBCPP_HIDE_FROM_ABI | |
| 46 | _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI | |
| 49 | _Tp operator=(_Tp __d) volatile _NOEXCEPT | |
| 50 | {__base::store(__d); return __d;} | |
| 51 | _LIBCPP_HIDE_FROM_ABI | |
| 52 | _Tp operator=(_Tp __d) _NOEXCEPT | |
| 53 | {__base::store(__d); return __d;} | |
| 54 | ||
| 55 | atomic& operator=(const atomic&) = delete; | |
| 56 | atomic& operator=(const atomic&) volatile = delete; | |
| 57 | }; | |
| 58 | ||
| 59 | // atomic<T*> | |
| 60 | ||
| 61 | template <class _Tp> | |
| 62 | struct atomic<_Tp*> | |
| 63 | : public __atomic_base<_Tp*> | |
| 64 | { | |
| 65 | using __base = __atomic_base<_Tp*>; | |
| 66 | using value_type = _Tp*; | |
| 67 | using difference_type = ptrdiff_t; | |
| 68 | ||
| 69 | _LIBCPP_HIDE_FROM_ABI | |
| 70 | atomic() _NOEXCEPT = default; | |
| 71 | ||
| 72 | _LIBCPP_HIDE_FROM_ABI | |
| 73 | _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} | |
| 74 | ||
| 75 | _LIBCPP_HIDE_FROM_ABI | |
| 76 | _Tp* operator=(_Tp* __d) volatile _NOEXCEPT | |
| 77 | {__base::store(__d); return __d;} | |
| 78 | _LIBCPP_HIDE_FROM_ABI | |
| 79 | _Tp* operator=(_Tp* __d) _NOEXCEPT | |
| 80 | {__base::store(__d); return __d;} | |
| 81 | ||
| 82 | _LIBCPP_HIDE_FROM_ABI | |
| 83 | _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 84 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 85 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 86 | return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); | |
| 87 | } | |
| 88 | ||
| 89 | _LIBCPP_HIDE_FROM_ABI | |
| 90 | _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 91 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 92 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 93 | return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); | |
| 94 | } | |
| 95 | ||
| 96 | _LIBCPP_HIDE_FROM_ABI | |
| 97 | _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 98 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 99 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 100 | return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); | |
| 101 | } | |
| 102 | ||
| 103 | _LIBCPP_HIDE_FROM_ABI | |
| 104 | _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 105 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 106 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 107 | return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); | |
| 108 | } | |
| 109 | ||
| 110 | _LIBCPP_HIDE_FROM_ABI | |
| 111 | _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} | |
| 112 | _LIBCPP_HIDE_FROM_ABI | |
| 113 | _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} | |
| 114 | _LIBCPP_HIDE_FROM_ABI | |
| 115 | _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} | |
| 116 | _LIBCPP_HIDE_FROM_ABI | |
| 117 | _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} | |
| 118 | _LIBCPP_HIDE_FROM_ABI | |
| 119 | _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} | |
| 120 | _LIBCPP_HIDE_FROM_ABI | |
| 121 | _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} | |
| 122 | _LIBCPP_HIDE_FROM_ABI | |
| 123 | _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} | |
| 124 | _LIBCPP_HIDE_FROM_ABI | |
| 125 | _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} | |
| 126 | _LIBCPP_HIDE_FROM_ABI | |
| 127 | _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 128 | _LIBCPP_HIDE_FROM_ABI | |
| 129 | _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 130 | _LIBCPP_HIDE_FROM_ABI | |
| 131 | _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 132 | _LIBCPP_HIDE_FROM_ABI | |
| 133 | _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 134 | ||
| 135 | atomic& operator=(const atomic&) = delete; | |
| 136 | atomic& operator=(const atomic&) volatile = delete; | |
| 137 | }; | |
| 138 | ||
| 139 | // atomic_is_lock_free | |
| 140 | ||
| 141 | template <class _Tp> | |
| 142 | _LIBCPP_HIDE_FROM_ABI | |
| 143 | bool | |
| 144 | atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 145 | { | |
| 146 | return __o->is_lock_free(); | |
| 147 | } | |
| 148 | ||
| 149 | template <class _Tp> | |
| 150 | _LIBCPP_HIDE_FROM_ABI | |
| 151 | bool | |
| 152 | atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT | |
| 153 | { | |
| 154 | return __o->is_lock_free(); | |
| 155 | } | |
| 156 | ||
| 157 | // atomic_init | |
| 158 | ||
| 159 | template <class _Tp> | |
| 160 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 161 | void | |
| 162 | atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 163 | { | |
| 164 | std::__cxx_atomic_init(std::addressof(__o->__a_), __d); | |
| 165 | } | |
| 166 | ||
| 167 | template <class _Tp> | |
| 168 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 169 | void | |
| 170 | atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 171 | { | |
| 172 | std::__cxx_atomic_init(std::addressof(__o->__a_), __d); | |
| 173 | } | |
| 174 | ||
| 175 | // atomic_store | |
| 176 | ||
| 177 | template <class _Tp> | |
| 178 | _LIBCPP_HIDE_FROM_ABI | |
| 179 | void | |
| 180 | atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 181 | { | |
| 182 | __o->store(__d); | |
| 183 | } | |
| 184 | ||
| 185 | template <class _Tp> | |
| 186 | _LIBCPP_HIDE_FROM_ABI | |
| 187 | void | |
| 188 | atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 189 | { | |
| 190 | __o->store(__d); | |
| 191 | } | |
| 192 | ||
| 193 | // atomic_store_explicit | |
| 194 | ||
| 195 | template <class _Tp> | |
| 196 | _LIBCPP_HIDE_FROM_ABI | |
| 197 | void | |
| 198 | atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 199 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 200 | { | |
| 201 | __o->store(__d, __m); | |
| 202 | } | |
| 203 | ||
| 204 | template <class _Tp> | |
| 205 | _LIBCPP_HIDE_FROM_ABI | |
| 206 | void | |
| 207 | atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 208 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 209 | { | |
| 210 | __o->store(__d, __m); | |
| 211 | } | |
| 212 | ||
| 213 | // atomic_load | |
| 214 | ||
| 215 | template <class _Tp> | |
| 216 | _LIBCPP_HIDE_FROM_ABI | |
| 217 | _Tp | |
| 218 | atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 219 | { | |
| 220 | return __o->load(); | |
| 221 | } | |
| 222 | ||
| 223 | template <class _Tp> | |
| 224 | _LIBCPP_HIDE_FROM_ABI | |
| 225 | _Tp | |
| 226 | atomic_load(const atomic<_Tp>* __o) _NOEXCEPT | |
| 227 | { | |
| 228 | return __o->load(); | |
| 229 | } | |
| 230 | ||
| 231 | // atomic_load_explicit | |
| 232 | ||
| 233 | template <class _Tp> | |
| 234 | _LIBCPP_HIDE_FROM_ABI | |
| 235 | _Tp | |
| 236 | atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT | |
| 237 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 238 | { | |
| 239 | return __o->load(__m); | |
| 240 | } | |
| 241 | ||
| 242 | template <class _Tp> | |
| 243 | _LIBCPP_HIDE_FROM_ABI | |
| 244 | _Tp | |
| 245 | atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT | |
| 246 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 247 | { | |
| 248 | return __o->load(__m); | |
| 249 | } | |
| 250 | ||
| 251 | // atomic_exchange | |
| 252 | ||
| 253 | template <class _Tp> | |
| 254 | _LIBCPP_HIDE_FROM_ABI | |
| 255 | _Tp | |
| 256 | atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 257 | { | |
| 258 | return __o->exchange(__d); | |
| 259 | } | |
| 260 | ||
| 261 | template <class _Tp> | |
| 262 | _LIBCPP_HIDE_FROM_ABI | |
| 263 | _Tp | |
| 264 | atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 265 | { | |
| 266 | return __o->exchange(__d); | |
| 267 | } | |
| 268 | ||
| 269 | // atomic_exchange_explicit | |
| 270 | ||
| 271 | template <class _Tp> | |
| 272 | _LIBCPP_HIDE_FROM_ABI | |
| 273 | _Tp | |
| 274 | atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 275 | { | |
| 276 | return __o->exchange(__d, __m); | |
| 277 | } | |
| 278 | ||
| 279 | template <class _Tp> | |
| 280 | _LIBCPP_HIDE_FROM_ABI | |
| 281 | _Tp | |
| 282 | atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 283 | { | |
| 284 | return __o->exchange(__d, __m); | |
| 285 | } | |
| 286 | ||
| 287 | // atomic_compare_exchange_weak | |
| 288 | ||
| 289 | template <class _Tp> | |
| 290 | _LIBCPP_HIDE_FROM_ABI | |
| 291 | bool | |
| 292 | atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 293 | { | |
| 294 | return __o->compare_exchange_weak(*__e, __d); | |
| 295 | } | |
| 296 | ||
| 297 | template <class _Tp> | |
| 298 | _LIBCPP_HIDE_FROM_ABI | |
| 299 | bool | |
| 300 | atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 301 | { | |
| 302 | return __o->compare_exchange_weak(*__e, __d); | |
| 303 | } | |
| 304 | ||
| 305 | // atomic_compare_exchange_strong | |
| 306 | ||
| 307 | template <class _Tp> | |
| 308 | _LIBCPP_HIDE_FROM_ABI | |
| 309 | bool | |
| 310 | atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 311 | { | |
| 312 | return __o->compare_exchange_strong(*__e, __d); | |
| 313 | } | |
| 314 | ||
| 315 | template <class _Tp> | |
| 316 | _LIBCPP_HIDE_FROM_ABI | |
| 317 | bool | |
| 318 | atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 319 | { | |
| 320 | return __o->compare_exchange_strong(*__e, __d); | |
| 321 | } | |
| 322 | ||
| 323 | // atomic_compare_exchange_weak_explicit | |
| 324 | ||
| 325 | template <class _Tp> | |
| 326 | _LIBCPP_HIDE_FROM_ABI | |
| 327 | bool | |
| 328 | atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, | |
| 329 | typename atomic<_Tp>::value_type __d, | |
| 330 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 331 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 332 | { | |
| 333 | return __o->compare_exchange_weak(*__e, __d, __s, __f); | |
| 334 | } | |
| 335 | ||
| 336 | template <class _Tp> | |
| 337 | _LIBCPP_HIDE_FROM_ABI | |
| 338 | bool | |
| 339 | atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, | |
| 340 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 341 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 342 | { | |
| 343 | return __o->compare_exchange_weak(*__e, __d, __s, __f); | |
| 344 | } | |
| 345 | ||
| 346 | // atomic_compare_exchange_strong_explicit | |
| 347 | ||
| 348 | template <class _Tp> | |
| 349 | _LIBCPP_HIDE_FROM_ABI | |
| 350 | bool | |
| 351 | atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, | |
| 352 | typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, | |
| 353 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 354 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 355 | { | |
| 356 | return __o->compare_exchange_strong(*__e, __d, __s, __f); | |
| 357 | } | |
| 358 | ||
| 359 | template <class _Tp> | |
| 360 | _LIBCPP_HIDE_FROM_ABI | |
| 361 | bool | |
| 362 | atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, | |
| 363 | typename atomic<_Tp>::value_type __d, | |
| 364 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 365 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 366 | { | |
| 367 | return __o->compare_exchange_strong(*__e, __d, __s, __f); | |
| 368 | } | |
| 369 | ||
| 370 | // atomic_wait | |
| 371 | ||
| 372 | template <class _Tp> | |
| 373 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 374 | void atomic_wait(const volatile atomic<_Tp>* __o, | |
| 375 | typename atomic<_Tp>::value_type __v) _NOEXCEPT | |
| 376 | { | |
| 377 | return __o->wait(__v); | |
| 378 | } | |
| 379 | ||
| 380 | template <class _Tp> | |
| 381 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 382 | void atomic_wait(const atomic<_Tp>* __o, | |
| 383 | typename atomic<_Tp>::value_type __v) _NOEXCEPT | |
| 384 | { | |
| 385 | return __o->wait(__v); | |
| 386 | } | |
| 387 | ||
| 388 | // atomic_wait_explicit | |
| 389 | ||
| 390 | template <class _Tp> | |
| 391 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 392 | void atomic_wait_explicit(const volatile atomic<_Tp>* __o, | |
| 393 | typename atomic<_Tp>::value_type __v, | |
| 394 | memory_order __m) _NOEXCEPT | |
| 395 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 396 | { | |
| 397 | return __o->wait(__v, __m); | |
| 398 | } | |
| 399 | ||
| 400 | template <class _Tp> | |
| 401 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 402 | void atomic_wait_explicit(const atomic<_Tp>* __o, | |
| 403 | typename atomic<_Tp>::value_type __v, | |
| 404 | memory_order __m) _NOEXCEPT | |
| 405 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 406 | { | |
| 407 | return __o->wait(__v, __m); | |
| 408 | } | |
| 409 | ||
| 410 | // atomic_notify_one | |
| 411 | ||
| 412 | template <class _Tp> | |
| 413 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 414 | void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 415 | { | |
| 416 | __o->notify_one(); | |
| 417 | } | |
| 418 | template <class _Tp> | |
| 419 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 420 | void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT | |
| 421 | { | |
| 422 | __o->notify_one(); | |
| 423 | } | |
| 424 | ||
| 425 | // atomic_notify_all | |
| 426 | ||
| 427 | template <class _Tp> | |
| 428 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 429 | void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 430 | { | |
| 431 | __o->notify_all(); | |
| 432 | } | |
| 433 | template <class _Tp> | |
| 434 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 435 | void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT | |
| 436 | { | |
| 437 | __o->notify_all(); | |
| 438 | } | |
| 439 | ||
| 440 | // atomic_fetch_add | |
| 441 | ||
| 442 | template <class _Tp> | |
| 443 | _LIBCPP_HIDE_FROM_ABI | |
| 444 | _Tp | |
| 445 | atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 446 | { | |
| 447 | return __o->fetch_add(__op); | |
| 448 | } | |
| 449 | ||
| 450 | template <class _Tp> | |
| 451 | _LIBCPP_HIDE_FROM_ABI | |
| 452 | _Tp | |
| 453 | atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 454 | { | |
| 455 | return __o->fetch_add(__op); | |
| 456 | } | |
| 457 | ||
| 458 | // atomic_fetch_add_explicit | |
| 459 | ||
| 460 | template <class _Tp> | |
| 461 | _LIBCPP_HIDE_FROM_ABI | |
| 462 | _Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 463 | { | |
| 464 | return __o->fetch_add(__op, __m); | |
| 465 | } | |
| 466 | ||
| 467 | template <class _Tp> | |
| 468 | _LIBCPP_HIDE_FROM_ABI | |
| 469 | _Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 470 | { | |
| 471 | return __o->fetch_add(__op, __m); | |
| 472 | } | |
| 473 | ||
| 474 | // atomic_fetch_sub | |
| 475 | ||
| 476 | template <class _Tp> | |
| 477 | _LIBCPP_HIDE_FROM_ABI | |
| 478 | _Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 479 | { | |
| 480 | return __o->fetch_sub(__op); | |
| 481 | } | |
| 482 | ||
| 483 | template <class _Tp> | |
| 484 | _LIBCPP_HIDE_FROM_ABI | |
| 485 | _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 486 | { | |
| 487 | return __o->fetch_sub(__op); | |
| 488 | } | |
| 489 | ||
| 490 | // atomic_fetch_sub_explicit | |
| 491 | ||
| 492 | template <class _Tp> | |
| 493 | _LIBCPP_HIDE_FROM_ABI | |
| 494 | _Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 495 | { | |
| 496 | return __o->fetch_sub(__op, __m); | |
| 497 | } | |
| 498 | ||
| 499 | template <class _Tp> | |
| 500 | _LIBCPP_HIDE_FROM_ABI | |
| 501 | _Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 502 | { | |
| 503 | return __o->fetch_sub(__op, __m); | |
| 504 | } | |
| 505 | ||
| 506 | // atomic_fetch_and | |
| 507 | ||
| 508 | template <class _Tp> | |
| 509 | _LIBCPP_HIDE_FROM_ABI | |
| 510 | typename enable_if | |
| 511 | < | |
| 512 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 513 | _Tp | |
| 514 | >::type | |
| 515 | atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 516 | { | |
| 517 | return __o->fetch_and(__op); | |
| 518 | } | |
| 519 | ||
| 520 | template <class _Tp> | |
| 521 | _LIBCPP_HIDE_FROM_ABI | |
| 522 | typename enable_if | |
| 523 | < | |
| 524 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 525 | _Tp | |
| 526 | >::type | |
| 527 | atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 528 | { | |
| 529 | return __o->fetch_and(__op); | |
| 530 | } | |
| 531 | ||
| 532 | // atomic_fetch_and_explicit | |
| 533 | ||
| 534 | template <class _Tp> | |
| 535 | _LIBCPP_HIDE_FROM_ABI | |
| 536 | typename enable_if | |
| 537 | < | |
| 538 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 539 | _Tp | |
| 540 | >::type | |
| 541 | atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 542 | { | |
| 543 | return __o->fetch_and(__op, __m); | |
| 544 | } | |
| 545 | ||
| 546 | template <class _Tp> | |
| 547 | _LIBCPP_HIDE_FROM_ABI | |
| 548 | typename enable_if | |
| 549 | < | |
| 550 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 551 | _Tp | |
| 552 | >::type | |
| 553 | atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 554 | { | |
| 555 | return __o->fetch_and(__op, __m); | |
| 556 | } | |
| 557 | ||
| 558 | // atomic_fetch_or | |
| 559 | ||
| 560 | template <class _Tp> | |
| 561 | _LIBCPP_HIDE_FROM_ABI | |
| 562 | typename enable_if | |
| 563 | < | |
| 564 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 565 | _Tp | |
| 566 | >::type | |
| 567 | atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 568 | { | |
| 569 | return __o->fetch_or(__op); | |
| 570 | } | |
| 571 | ||
| 572 | template <class _Tp> | |
| 573 | _LIBCPP_HIDE_FROM_ABI | |
| 574 | typename enable_if | |
| 575 | < | |
| 576 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 577 | _Tp | |
| 578 | >::type | |
| 579 | atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 580 | { | |
| 581 | return __o->fetch_or(__op); | |
| 582 | } | |
| 583 | ||
| 584 | // atomic_fetch_or_explicit | |
| 585 | ||
| 586 | template <class _Tp> | |
| 587 | _LIBCPP_HIDE_FROM_ABI | |
| 588 | typename enable_if | |
| 589 | < | |
| 590 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 591 | _Tp | |
| 592 | >::type | |
| 593 | atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 594 | { | |
| 595 | return __o->fetch_or(__op, __m); | |
| 596 | } | |
| 597 | ||
| 598 | template <class _Tp> | |
| 599 | _LIBCPP_HIDE_FROM_ABI | |
| 600 | typename enable_if | |
| 601 | < | |
| 602 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 603 | _Tp | |
| 604 | >::type | |
| 605 | atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 606 | { | |
| 607 | return __o->fetch_or(__op, __m); | |
| 608 | } | |
| 609 | ||
| 610 | // atomic_fetch_xor | |
| 611 | ||
| 612 | template <class _Tp> | |
| 613 | _LIBCPP_HIDE_FROM_ABI | |
| 614 | typename enable_if | |
| 615 | < | |
| 616 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 617 | _Tp | |
| 618 | >::type | |
| 619 | atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 620 | { | |
| 621 | return __o->fetch_xor(__op); | |
| 622 | } | |
| 623 | ||
| 624 | template <class _Tp> | |
| 625 | _LIBCPP_HIDE_FROM_ABI | |
| 626 | typename enable_if | |
| 627 | < | |
| 628 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 629 | _Tp | |
| 630 | >::type | |
| 631 | atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 632 | { | |
| 633 | return __o->fetch_xor(__op); | |
| 634 | } | |
| 635 | ||
| 636 | // atomic_fetch_xor_explicit | |
| 637 | ||
| 638 | template <class _Tp> | |
| 639 | _LIBCPP_HIDE_FROM_ABI | |
| 640 | typename enable_if | |
| 641 | < | |
| 642 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 643 | _Tp | |
| 644 | >::type | |
| 645 | atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 646 | { | |
| 647 | return __o->fetch_xor(__op, __m); | |
| 648 | } | |
| 649 | ||
| 650 | template <class _Tp> | |
| 651 | _LIBCPP_HIDE_FROM_ABI | |
| 652 | typename enable_if | |
| 653 | < | |
| 654 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 655 | _Tp | |
| 656 | >::type | |
| 657 | atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 658 | { | |
| 659 | return __o->fetch_xor(__op, __m); | |
| 660 | } | |
| 661 | ||
| 662 | _LIBCPP_END_NAMESPACE_STD | |
| 663 | ||
| 664 | #endif // _LIBCPP___ATOMIC_ATOMIC_H |
lib/libcxx/include/__atomic/atomic_base.h created+232| ... | ... | @@ -0,0 +1,232 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_BASE_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_BASE_H | |
| 11 | ||
| 12 | #include <__atomic/atomic_sync.h> | |
| 13 | #include <__atomic/check_memory_order.h> | |
| 14 | #include <__atomic/cxx_atomic_impl.h> | |
| 15 | #include <__atomic/is_always_lock_free.h> | |
| 16 | #include <__atomic/memory_order.h> | |
| 17 | #include <__availability> | |
| 18 | #include <__config> | |
| 19 | #include <__memory/addressof.h> | |
| 20 | #include <__type_traits/is_integral.h> | |
| 21 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 22 | #include <__type_traits/is_same.h> | |
| 23 | #include <version> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> | |
| 32 | struct __atomic_base // false | |
| 33 | { | |
| 34 | mutable __cxx_atomic_impl<_Tp> __a_; | |
| 35 | ||
| 36 | #if _LIBCPP_STD_VER >= 17 | |
| 37 | static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; | |
| 38 | #endif | |
| 39 | ||
| 40 | _LIBCPP_HIDE_FROM_ABI | |
| 41 | bool is_lock_free() const volatile _NOEXCEPT | |
| 42 | {return __cxx_atomic_is_lock_free(sizeof(_Tp));} | |
| 43 | _LIBCPP_HIDE_FROM_ABI | |
| 44 | bool is_lock_free() const _NOEXCEPT | |
| 45 | {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} | |
| 46 | _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 47 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { | |
| 48 | std::__cxx_atomic_store(std::addressof(__a_), __d, __m); | |
| 49 | } | |
| 50 | _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 51 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { | |
| 52 | std::__cxx_atomic_store(std::addressof(__a_), __d, __m); | |
| 53 | } | |
| 54 | _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 55 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { | |
| 56 | return std::__cxx_atomic_load(std::addressof(__a_), __m); | |
| 57 | } | |
| 58 | _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 59 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { | |
| 60 | return std::__cxx_atomic_load(std::addressof(__a_), __m); | |
| 61 | } | |
| 62 | _LIBCPP_HIDE_FROM_ABI | |
| 63 | operator _Tp() const volatile _NOEXCEPT {return load();} | |
| 64 | _LIBCPP_HIDE_FROM_ABI | |
| 65 | operator _Tp() const _NOEXCEPT {return load();} | |
| 66 | _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 67 | return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); | |
| 68 | } | |
| 69 | _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 70 | return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); | |
| 71 | } | |
| 72 | _LIBCPP_HIDE_FROM_ABI bool | |
| 73 | compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT | |
| 74 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { | |
| 75 | return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); | |
| 76 | } | |
| 77 | _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT | |
| 78 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { | |
| 79 | return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); | |
| 80 | } | |
| 81 | _LIBCPP_HIDE_FROM_ABI bool | |
| 82 | compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT | |
| 83 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { | |
| 84 | return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); | |
| 85 | } | |
| 86 | _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT | |
| 87 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { | |
| 88 | return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); | |
| 89 | } | |
| 90 | _LIBCPP_HIDE_FROM_ABI bool | |
| 91 | compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 92 | return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); | |
| 93 | } | |
| 94 | _LIBCPP_HIDE_FROM_ABI bool | |
| 95 | compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 96 | return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); | |
| 97 | } | |
| 98 | _LIBCPP_HIDE_FROM_ABI bool | |
| 99 | compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 100 | return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); | |
| 101 | } | |
| 102 | _LIBCPP_HIDE_FROM_ABI bool | |
| 103 | compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 104 | return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); | |
| 105 | } | |
| 106 | ||
| 107 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const | |
| 108 | volatile _NOEXCEPT { | |
| 109 | std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); | |
| 110 | } | |
| 111 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void | |
| 112 | wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { | |
| 113 | std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); | |
| 114 | } | |
| 115 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { | |
| 116 | std::__cxx_atomic_notify_one(std::addressof(__a_)); | |
| 117 | } | |
| 118 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { | |
| 119 | std::__cxx_atomic_notify_one(std::addressof(__a_)); | |
| 120 | } | |
| 121 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { | |
| 122 | std::__cxx_atomic_notify_all(std::addressof(__a_)); | |
| 123 | } | |
| 124 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { | |
| 125 | std::__cxx_atomic_notify_all(std::addressof(__a_)); | |
| 126 | } | |
| 127 | ||
| 128 | #if _LIBCPP_STD_VER >= 20 | |
| 129 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 130 | __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} | |
| 131 | #else | |
| 132 | _LIBCPP_HIDE_FROM_ABI | |
| 133 | __atomic_base() _NOEXCEPT = default; | |
| 134 | #endif | |
| 135 | ||
| 136 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 137 | __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} | |
| 138 | ||
| 139 | __atomic_base(const __atomic_base&) = delete; | |
| 140 | }; | |
| 141 | ||
| 142 | #if _LIBCPP_STD_VER >= 17 | |
| 143 | template <class _Tp, bool __b> | |
| 144 | _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; | |
| 145 | #endif | |
| 146 | ||
| 147 | // atomic<Integral> | |
| 148 | ||
| 149 | template <class _Tp> | |
| 150 | struct __atomic_base<_Tp, true> | |
| 151 | : public __atomic_base<_Tp, false> | |
| 152 | { | |
| 153 | using __base = __atomic_base<_Tp, false>; | |
| 154 | ||
| 155 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 156 | __atomic_base() _NOEXCEPT = default; | |
| 157 | ||
| 158 | _LIBCPP_HIDE_FROM_ABI | |
| 159 | _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} | |
| 160 | ||
| 161 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 162 | return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); | |
| 163 | } | |
| 164 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 165 | return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); | |
| 166 | } | |
| 167 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 168 | return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); | |
| 169 | } | |
| 170 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 171 | return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); | |
| 172 | } | |
| 173 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 174 | return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); | |
| 175 | } | |
| 176 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 177 | return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); | |
| 178 | } | |
| 179 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 180 | return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); | |
| 181 | } | |
| 182 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 183 | return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); | |
| 184 | } | |
| 185 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 186 | return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); | |
| 187 | } | |
| 188 | _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 189 | return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); | |
| 190 | } | |
| 191 | ||
| 192 | _LIBCPP_HIDE_FROM_ABI | |
| 193 | _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} | |
| 194 | _LIBCPP_HIDE_FROM_ABI | |
| 195 | _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} | |
| 196 | _LIBCPP_HIDE_FROM_ABI | |
| 197 | _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} | |
| 198 | _LIBCPP_HIDE_FROM_ABI | |
| 199 | _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} | |
| 200 | _LIBCPP_HIDE_FROM_ABI | |
| 201 | _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} | |
| 202 | _LIBCPP_HIDE_FROM_ABI | |
| 203 | _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} | |
| 204 | _LIBCPP_HIDE_FROM_ABI | |
| 205 | _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} | |
| 206 | _LIBCPP_HIDE_FROM_ABI | |
| 207 | _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} | |
| 208 | _LIBCPP_HIDE_FROM_ABI | |
| 209 | _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 210 | _LIBCPP_HIDE_FROM_ABI | |
| 211 | _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 212 | _LIBCPP_HIDE_FROM_ABI | |
| 213 | _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 214 | _LIBCPP_HIDE_FROM_ABI | |
| 215 | _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 216 | _LIBCPP_HIDE_FROM_ABI | |
| 217 | _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} | |
| 218 | _LIBCPP_HIDE_FROM_ABI | |
| 219 | _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} | |
| 220 | _LIBCPP_HIDE_FROM_ABI | |
| 221 | _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} | |
| 222 | _LIBCPP_HIDE_FROM_ABI | |
| 223 | _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} | |
| 224 | _LIBCPP_HIDE_FROM_ABI | |
| 225 | _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} | |
| 226 | _LIBCPP_HIDE_FROM_ABI | |
| 227 | _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} | |
| 228 | }; | |
| 229 | ||
| 230 | _LIBCPP_END_NAMESPACE_STD | |
| 231 | ||
| 232 | #endif // _LIBCPP___ATOMIC_ATOMIC_BASE_H |
lib/libcxx/include/__atomic/atomic_flag.h created+230| ... | ... | @@ -0,0 +1,230 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_FLAG_H | |
| 11 | ||
| 12 | #include <__atomic/atomic_sync.h> | |
| 13 | #include <__atomic/contention_t.h> | |
| 14 | #include <__atomic/cxx_atomic_impl.h> | |
| 15 | #include <__atomic/memory_order.h> | |
| 16 | #include <__chrono/duration.h> | |
| 17 | #include <__config> | |
| 18 | #include <__threading_support> | |
| 19 | #include <cstdint> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | struct atomic_flag | |
| 28 | { | |
| 29 | __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; | |
| 30 | ||
| 31 | _LIBCPP_HIDE_FROM_ABI | |
| 32 | bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 33 | {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} | |
| 34 | _LIBCPP_HIDE_FROM_ABI | |
| 35 | bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 36 | {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} | |
| 37 | ||
| 38 | _LIBCPP_HIDE_FROM_ABI | |
| 39 | bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 40 | {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} | |
| 41 | _LIBCPP_HIDE_FROM_ABI | |
| 42 | bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 43 | {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} | |
| 44 | _LIBCPP_HIDE_FROM_ABI | |
| 45 | void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 46 | {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} | |
| 47 | _LIBCPP_HIDE_FROM_ABI | |
| 48 | void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 49 | {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} | |
| 50 | ||
| 51 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 52 | void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 53 | {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} | |
| 54 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 55 | void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 56 | {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} | |
| 57 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 58 | void notify_one() volatile _NOEXCEPT | |
| 59 | {__cxx_atomic_notify_one(&__a_);} | |
| 60 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 61 | void notify_one() _NOEXCEPT | |
| 62 | {__cxx_atomic_notify_one(&__a_);} | |
| 63 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 64 | void notify_all() volatile _NOEXCEPT | |
| 65 | {__cxx_atomic_notify_all(&__a_);} | |
| 66 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI | |
| 67 | void notify_all() _NOEXCEPT | |
| 68 | {__cxx_atomic_notify_all(&__a_);} | |
| 69 | ||
| 70 | #if _LIBCPP_STD_VER >= 20 | |
| 71 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 72 | atomic_flag() _NOEXCEPT : __a_(false) {} | |
| 73 | #else | |
| 74 | atomic_flag() _NOEXCEPT = default; | |
| 75 | #endif | |
| 76 | ||
| 77 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 78 | atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION | |
| 79 | ||
| 80 | atomic_flag(const atomic_flag&) = delete; | |
| 81 | atomic_flag& operator=(const atomic_flag&) = delete; | |
| 82 | atomic_flag& operator=(const atomic_flag&) volatile = delete; | |
| 83 | ||
| 84 | }; | |
| 85 | ||
| 86 | inline _LIBCPP_HIDE_FROM_ABI | |
| 87 | bool | |
| 88 | atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT | |
| 89 | { | |
| 90 | return __o->test(); | |
| 91 | } | |
| 92 | ||
| 93 | inline _LIBCPP_HIDE_FROM_ABI | |
| 94 | bool | |
| 95 | atomic_flag_test(const atomic_flag* __o) _NOEXCEPT | |
| 96 | { | |
| 97 | return __o->test(); | |
| 98 | } | |
| 99 | ||
| 100 | inline _LIBCPP_HIDE_FROM_ABI | |
| 101 | bool | |
| 102 | atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 103 | { | |
| 104 | return __o->test(__m); | |
| 105 | } | |
| 106 | ||
| 107 | inline _LIBCPP_HIDE_FROM_ABI | |
| 108 | bool | |
| 109 | atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 110 | { | |
| 111 | return __o->test(__m); | |
| 112 | } | |
| 113 | ||
| 114 | inline _LIBCPP_HIDE_FROM_ABI | |
| 115 | bool | |
| 116 | atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT | |
| 117 | { | |
| 118 | return __o->test_and_set(); | |
| 119 | } | |
| 120 | ||
| 121 | inline _LIBCPP_HIDE_FROM_ABI | |
| 122 | bool | |
| 123 | atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT | |
| 124 | { | |
| 125 | return __o->test_and_set(); | |
| 126 | } | |
| 127 | ||
| 128 | inline _LIBCPP_HIDE_FROM_ABI | |
| 129 | bool | |
| 130 | atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 131 | { | |
| 132 | return __o->test_and_set(__m); | |
| 133 | } | |
| 134 | ||
| 135 | inline _LIBCPP_HIDE_FROM_ABI | |
| 136 | bool | |
| 137 | atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 138 | { | |
| 139 | return __o->test_and_set(__m); | |
| 140 | } | |
| 141 | ||
| 142 | inline _LIBCPP_HIDE_FROM_ABI | |
| 143 | void | |
| 144 | atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT | |
| 145 | { | |
| 146 | __o->clear(); | |
| 147 | } | |
| 148 | ||
| 149 | inline _LIBCPP_HIDE_FROM_ABI | |
| 150 | void | |
| 151 | atomic_flag_clear(atomic_flag* __o) _NOEXCEPT | |
| 152 | { | |
| 153 | __o->clear(); | |
| 154 | } | |
| 155 | ||
| 156 | inline _LIBCPP_HIDE_FROM_ABI | |
| 157 | void | |
| 158 | atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 159 | { | |
| 160 | __o->clear(__m); | |
| 161 | } | |
| 162 | ||
| 163 | inline _LIBCPP_HIDE_FROM_ABI | |
| 164 | void | |
| 165 | atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 166 | { | |
| 167 | __o->clear(__m); | |
| 168 | } | |
| 169 | ||
| 170 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 171 | void | |
| 172 | atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT | |
| 173 | { | |
| 174 | __o->wait(__v); | |
| 175 | } | |
| 176 | ||
| 177 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 178 | void | |
| 179 | atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT | |
| 180 | { | |
| 181 | __o->wait(__v); | |
| 182 | } | |
| 183 | ||
| 184 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 185 | void | |
| 186 | atomic_flag_wait_explicit(const volatile atomic_flag* __o, | |
| 187 | bool __v, memory_order __m) _NOEXCEPT | |
| 188 | { | |
| 189 | __o->wait(__v, __m); | |
| 190 | } | |
| 191 | ||
| 192 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 193 | void | |
| 194 | atomic_flag_wait_explicit(const atomic_flag* __o, | |
| 195 | bool __v, memory_order __m) _NOEXCEPT | |
| 196 | { | |
| 197 | __o->wait(__v, __m); | |
| 198 | } | |
| 199 | ||
| 200 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 201 | void | |
| 202 | atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT | |
| 203 | { | |
| 204 | __o->notify_one(); | |
| 205 | } | |
| 206 | ||
| 207 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 208 | void | |
| 209 | atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT | |
| 210 | { | |
| 211 | __o->notify_one(); | |
| 212 | } | |
| 213 | ||
| 214 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 215 | void | |
| 216 | atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT | |
| 217 | { | |
| 218 | __o->notify_all(); | |
| 219 | } | |
| 220 | ||
| 221 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC | |
| 222 | void | |
| 223 | atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT | |
| 224 | { | |
| 225 | __o->notify_all(); | |
| 226 | } | |
| 227 | ||
| 228 | _LIBCPP_END_NAMESPACE_STD | |
| 229 | ||
| 230 | #endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H |
lib/libcxx/include/__atomic/atomic_init.h created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_INIT_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_INIT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | #define ATOMIC_FLAG_INIT {false} | |
| 19 | #define ATOMIC_VAR_INIT(__v) {__v} | |
| 20 | ||
| 21 | #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) | |
| 22 | # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400 | |
| 23 | # pragma clang deprecated(ATOMIC_VAR_INIT) | |
| 24 | # endif | |
| 25 | #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) | |
| 26 | ||
| 27 | #endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H |
lib/libcxx/include/__atomic/atomic_lock_free.h created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) | |
| 19 | # define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE | |
| 20 | # define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE | |
| 21 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 22 | # define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE | |
| 23 | #endif | |
| 24 | # define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE | |
| 25 | # define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE | |
| 26 | # define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE | |
| 27 | # define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE | |
| 28 | # define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE | |
| 29 | # define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE | |
| 30 | # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE | |
| 31 | # define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE | |
| 32 | #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) | |
| 33 | # define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE | |
| 34 | # define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE | |
| 35 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 36 | # define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE | |
| 37 | #endif | |
| 38 | # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE | |
| 39 | # define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE | |
| 40 | # define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE | |
| 41 | # define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE | |
| 42 | # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE | |
| 43 | # define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE | |
| 44 | # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE | |
| 45 | # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE | |
| 46 | #endif | |
| 47 | ||
| 48 | #endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H |
lib/libcxx/include/__atomic/atomic_sync.h created+112| ... | ... | @@ -0,0 +1,112 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H | |
| 10 | #define _LIBCPP___ATOMIC_ATOMIC_SYNC_H | |
| 11 | ||
| 12 | #include <__atomic/contention_t.h> | |
| 13 | #include <__atomic/cxx_atomic_impl.h> | |
| 14 | #include <__atomic/memory_order.h> | |
| 15 | #include <__availability> | |
| 16 | #include <__chrono/duration.h> | |
| 17 | #include <__config> | |
| 18 | #include <__memory/addressof.h> | |
| 19 | #include <__thread/poll_with_backoff.h> | |
| 20 | #include <__threading_support> | |
| 21 | #include <__type_traits/decay.h> | |
| 22 | #include <cstring> | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 25 | # pragma GCC system_header | |
| 26 | #endif | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 31 | ||
| 32 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); | |
| 33 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); | |
| 34 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); | |
| 35 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); | |
| 36 | ||
| 37 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); | |
| 38 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); | |
| 39 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); | |
| 40 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); | |
| 41 | ||
| 42 | template <class _Atp, class _Fn> | |
| 43 | struct __libcpp_atomic_wait_backoff_impl { | |
| 44 | _Atp* __a; | |
| 45 | _Fn __test_fn; | |
| 46 | _LIBCPP_AVAILABILITY_SYNC | |
| 47 | _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const | |
| 48 | { | |
| 49 | if(__elapsed > chrono::microseconds(64)) | |
| 50 | { | |
| 51 | auto const __monitor = std::__libcpp_atomic_monitor(__a); | |
| 52 | if(__test_fn()) | |
| 53 | return true; | |
| 54 | std::__libcpp_atomic_wait(__a, __monitor); | |
| 55 | } | |
| 56 | else if(__elapsed > chrono::microseconds(4)) | |
| 57 | __libcpp_thread_yield(); | |
| 58 | else | |
| 59 | {} // poll | |
| 60 | return false; | |
| 61 | } | |
| 62 | }; | |
| 63 | ||
| 64 | template <class _Atp, class _Fn> | |
| 65 | _LIBCPP_AVAILABILITY_SYNC | |
| 66 | _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) | |
| 67 | { | |
| 68 | __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn}; | |
| 69 | return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); | |
| 70 | } | |
| 71 | ||
| 72 | #else // _LIBCPP_HAS_NO_THREADS | |
| 73 | ||
| 74 | template <class _Tp> | |
| 75 | _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } | |
| 76 | template <class _Tp> | |
| 77 | _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } | |
| 78 | template <class _Atp, class _Fn> | |
| 79 | _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) | |
| 80 | { | |
| 81 | return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); | |
| 82 | } | |
| 83 | ||
| 84 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 85 | ||
| 86 | template <typename _Tp> _LIBCPP_HIDE_FROM_ABI | |
| 87 | bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { | |
| 88 | return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; | |
| 89 | } | |
| 90 | ||
| 91 | template <class _Atp, class _Tp> | |
| 92 | struct __cxx_atomic_wait_test_fn_impl { | |
| 93 | _Atp* __a; | |
| 94 | _Tp __val; | |
| 95 | memory_order __order; | |
| 96 | _LIBCPP_HIDE_FROM_ABI bool operator()() const | |
| 97 | { | |
| 98 | return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); | |
| 99 | } | |
| 100 | }; | |
| 101 | ||
| 102 | template <class _Atp, class _Tp> | |
| 103 | _LIBCPP_AVAILABILITY_SYNC | |
| 104 | _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) | |
| 105 | { | |
| 106 | __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; | |
| 107 | return std::__cxx_atomic_wait(__a, __test_fn); | |
| 108 | } | |
| 109 | ||
| 110 | _LIBCPP_END_NAMESPACE_STD | |
| 111 | ||
| 112 | #endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_H |
lib/libcxx/include/__atomic/check_memory_order.h created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H | |
| 10 | #define _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ | |
| 19 | _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ | |
| 20 | __m == memory_order_acquire || \ | |
| 21 | __m == memory_order_acq_rel, \ | |
| 22 | "memory order argument to atomic operation is invalid") | |
| 23 | ||
| 24 | #define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ | |
| 25 | _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ | |
| 26 | __m == memory_order_acq_rel, \ | |
| 27 | "memory order argument to atomic operation is invalid") | |
| 28 | ||
| 29 | #define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ | |
| 30 | _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ | |
| 31 | __f == memory_order_acq_rel, \ | |
| 32 | "memory order argument to atomic operation is invalid") | |
| 33 | ||
| 34 | #endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H |
lib/libcxx/include/__atomic/contention_t.h created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_CONTENTION_T_H | |
| 10 | #define _LIBCPP___ATOMIC_CONTENTION_T_H | |
| 11 | ||
| 12 | #include <__atomic/cxx_atomic_impl.h> | |
| 13 | #include <__config> | |
| 14 | #include <cstdint> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) | |
| 23 | using __cxx_contention_t = int32_t; | |
| 24 | #else | |
| 25 | using __cxx_contention_t = int64_t; | |
| 26 | #endif // __linux__ || (_AIX && !__64BIT__) | |
| 27 | ||
| 28 | using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; | |
| 29 | ||
| 30 | _LIBCPP_END_NAMESPACE_STD | |
| 31 | ||
| 32 | #endif // _LIBCPP___ATOMIC_CONTENTION_T_H |
lib/libcxx/include/__atomic/cxx_atomic_impl.h created+831| ... | ... | @@ -0,0 +1,831 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H | |
| 10 | #define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H | |
| 11 | ||
| 12 | #include <__atomic/is_always_lock_free.h> | |
| 13 | #include <__atomic/memory_order.h> | |
| 14 | #include <__config> | |
| 15 | #include <__memory/addressof.h> | |
| 16 | #include <__type_traits/conditional.h> | |
| 17 | #include <__type_traits/is_assignable.h> | |
| 18 | #include <__type_traits/is_trivially_copyable.h> | |
| 19 | #include <__type_traits/remove_const.h> | |
| 20 | #include <cstddef> | |
| 21 | #include <cstring> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ | |
| 30 | defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) | |
| 31 | ||
| 32 | // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because | |
| 33 | // the default operator= in an object is not volatile, a byte-by-byte copy | |
| 34 | // is required. | |
| 35 | template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI | |
| 36 | typename enable_if<is_assignable<_Tp&, _Tv>::value>::type | |
| 37 | __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { | |
| 38 | __a_value = __val; | |
| 39 | } | |
| 40 | template <typename _Tp, typename _Tv> _LIBCPP_HIDE_FROM_ABI | |
| 41 | typename enable_if<is_assignable<_Tp&, _Tv>::value>::type | |
| 42 | __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { | |
| 43 | volatile char* __to = reinterpret_cast<volatile char*>(std::addressof(__a_value)); | |
| 44 | volatile char* __end = __to + sizeof(_Tp); | |
| 45 | volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val)); | |
| 46 | while (__to != __end) | |
| 47 | *__to++ = *__from++; | |
| 48 | } | |
| 49 | ||
| 50 | #endif | |
| 51 | ||
| 52 | #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) | |
| 53 | ||
| 54 | template <typename _Tp> | |
| 55 | struct __cxx_atomic_base_impl { | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI | |
| 58 | #ifndef _LIBCPP_CXX03_LANG | |
| 59 | __cxx_atomic_base_impl() _NOEXCEPT = default; | |
| 60 | #else | |
| 61 | __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} | |
| 62 | #endif // _LIBCPP_CXX03_LANG | |
| 63 | _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT | |
| 64 | : __a_value(value) {} | |
| 65 | _Tp __a_value; | |
| 66 | }; | |
| 67 | ||
| 68 | _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { | |
| 69 | // Avoid switch statement to make this a constexpr. | |
| 70 | return __order == memory_order_relaxed ? __ATOMIC_RELAXED: | |
| 71 | (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: | |
| 72 | (__order == memory_order_release ? __ATOMIC_RELEASE: | |
| 73 | (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: | |
| 74 | (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: | |
| 75 | __ATOMIC_CONSUME)))); | |
| 76 | } | |
| 77 | ||
| 78 | _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { | |
| 79 | // Avoid switch statement to make this a constexpr. | |
| 80 | return __order == memory_order_relaxed ? __ATOMIC_RELAXED: | |
| 81 | (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: | |
| 82 | (__order == memory_order_release ? __ATOMIC_RELAXED: | |
| 83 | (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: | |
| 84 | (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: | |
| 85 | __ATOMIC_CONSUME)))); | |
| 86 | } | |
| 87 | ||
| 88 | template <typename _Tp> | |
| 89 | _LIBCPP_HIDE_FROM_ABI | |
| 90 | void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { | |
| 91 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 92 | } | |
| 93 | ||
| 94 | template <typename _Tp> | |
| 95 | _LIBCPP_HIDE_FROM_ABI | |
| 96 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { | |
| 97 | __a->__a_value = __val; | |
| 98 | } | |
| 99 | ||
| 100 | _LIBCPP_HIDE_FROM_ABI inline | |
| 101 | void __cxx_atomic_thread_fence(memory_order __order) { | |
| 102 | __atomic_thread_fence(__to_gcc_order(__order)); | |
| 103 | } | |
| 104 | ||
| 105 | _LIBCPP_HIDE_FROM_ABI inline | |
| 106 | void __cxx_atomic_signal_fence(memory_order __order) { | |
| 107 | __atomic_signal_fence(__to_gcc_order(__order)); | |
| 108 | } | |
| 109 | ||
| 110 | template <typename _Tp> | |
| 111 | _LIBCPP_HIDE_FROM_ABI | |
| 112 | void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, | |
| 113 | memory_order __order) { | |
| 114 | __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); | |
| 115 | } | |
| 116 | ||
| 117 | template <typename _Tp> | |
| 118 | _LIBCPP_HIDE_FROM_ABI | |
| 119 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, | |
| 120 | memory_order __order) { | |
| 121 | __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); | |
| 122 | } | |
| 123 | ||
| 124 | template <typename _Tp> | |
| 125 | _LIBCPP_HIDE_FROM_ABI | |
| 126 | _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 127 | memory_order __order) { | |
| 128 | _Tp __ret; | |
| 129 | __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); | |
| 130 | return __ret; | |
| 131 | } | |
| 132 | ||
| 133 | template <typename _Tp> | |
| 134 | _LIBCPP_HIDE_FROM_ABI | |
| 135 | _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { | |
| 136 | _Tp __ret; | |
| 137 | __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); | |
| 138 | return __ret; | |
| 139 | } | |
| 140 | ||
| 141 | template <typename _Tp> | |
| 142 | _LIBCPP_HIDE_FROM_ABI | |
| 143 | _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 144 | _Tp __value, memory_order __order) { | |
| 145 | _Tp __ret; | |
| 146 | __atomic_exchange( | |
| 147 | std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); | |
| 148 | return __ret; | |
| 149 | } | |
| 150 | ||
| 151 | template <typename _Tp> | |
| 152 | _LIBCPP_HIDE_FROM_ABI | |
| 153 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, | |
| 154 | memory_order __order) { | |
| 155 | _Tp __ret; | |
| 156 | __atomic_exchange( | |
| 157 | std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); | |
| 158 | return __ret; | |
| 159 | } | |
| 160 | ||
| 161 | template <typename _Tp> | |
| 162 | _LIBCPP_HIDE_FROM_ABI | |
| 163 | bool __cxx_atomic_compare_exchange_strong( | |
| 164 | volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, | |
| 165 | memory_order __success, memory_order __failure) { | |
| 166 | return __atomic_compare_exchange( | |
| 167 | std::addressof(__a->__a_value), | |
| 168 | __expected, | |
| 169 | std::addressof(__value), | |
| 170 | false, | |
| 171 | __to_gcc_order(__success), | |
| 172 | __to_gcc_failure_order(__failure)); | |
| 173 | } | |
| 174 | ||
| 175 | template <typename _Tp> | |
| 176 | _LIBCPP_HIDE_FROM_ABI | |
| 177 | bool __cxx_atomic_compare_exchange_strong( | |
| 178 | __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, | |
| 179 | memory_order __failure) { | |
| 180 | return __atomic_compare_exchange( | |
| 181 | std::addressof(__a->__a_value), | |
| 182 | __expected, | |
| 183 | std::addressof(__value), | |
| 184 | false, | |
| 185 | __to_gcc_order(__success), | |
| 186 | __to_gcc_failure_order(__failure)); | |
| 187 | } | |
| 188 | ||
| 189 | template <typename _Tp> | |
| 190 | _LIBCPP_HIDE_FROM_ABI | |
| 191 | bool __cxx_atomic_compare_exchange_weak( | |
| 192 | volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, | |
| 193 | memory_order __success, memory_order __failure) { | |
| 194 | return __atomic_compare_exchange( | |
| 195 | std::addressof(__a->__a_value), | |
| 196 | __expected, | |
| 197 | std::addressof(__value), | |
| 198 | true, | |
| 199 | __to_gcc_order(__success), | |
| 200 | __to_gcc_failure_order(__failure)); | |
| 201 | } | |
| 202 | ||
| 203 | template <typename _Tp> | |
| 204 | _LIBCPP_HIDE_FROM_ABI | |
| 205 | bool __cxx_atomic_compare_exchange_weak( | |
| 206 | __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, | |
| 207 | memory_order __failure) { | |
| 208 | return __atomic_compare_exchange( | |
| 209 | std::addressof(__a->__a_value), | |
| 210 | __expected, | |
| 211 | std::addressof(__value), | |
| 212 | true, | |
| 213 | __to_gcc_order(__success), | |
| 214 | __to_gcc_failure_order(__failure)); | |
| 215 | } | |
| 216 | ||
| 217 | template <typename _Tp> | |
| 218 | struct __skip_amt { enum {value = 1}; }; | |
| 219 | ||
| 220 | template <typename _Tp> | |
| 221 | struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; | |
| 222 | ||
| 223 | // FIXME: Haven't figured out what the spec says about using arrays with | |
| 224 | // atomic_fetch_add. Force a failure rather than creating bad behavior. | |
| 225 | template <typename _Tp> | |
| 226 | struct __skip_amt<_Tp[]> { }; | |
| 227 | template <typename _Tp, int n> | |
| 228 | struct __skip_amt<_Tp[n]> { }; | |
| 229 | ||
| 230 | template <typename _Tp, typename _Td> | |
| 231 | _LIBCPP_HIDE_FROM_ABI | |
| 232 | _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 233 | _Td __delta, memory_order __order) { | |
| 234 | return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); | |
| 235 | } | |
| 236 | ||
| 237 | template <typename _Tp, typename _Td> | |
| 238 | _LIBCPP_HIDE_FROM_ABI | |
| 239 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, | |
| 240 | memory_order __order) { | |
| 241 | return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); | |
| 242 | } | |
| 243 | ||
| 244 | template <typename _Tp, typename _Td> | |
| 245 | _LIBCPP_HIDE_FROM_ABI | |
| 246 | _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 247 | _Td __delta, memory_order __order) { | |
| 248 | return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); | |
| 249 | } | |
| 250 | ||
| 251 | template <typename _Tp, typename _Td> | |
| 252 | _LIBCPP_HIDE_FROM_ABI | |
| 253 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, | |
| 254 | memory_order __order) { | |
| 255 | return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); | |
| 256 | } | |
| 257 | ||
| 258 | template <typename _Tp> | |
| 259 | _LIBCPP_HIDE_FROM_ABI | |
| 260 | _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 261 | _Tp __pattern, memory_order __order) { | |
| 262 | return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 263 | } | |
| 264 | ||
| 265 | template <typename _Tp> | |
| 266 | _LIBCPP_HIDE_FROM_ABI | |
| 267 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, | |
| 268 | _Tp __pattern, memory_order __order) { | |
| 269 | return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 270 | } | |
| 271 | ||
| 272 | template <typename _Tp> | |
| 273 | _LIBCPP_HIDE_FROM_ABI | |
| 274 | _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 275 | _Tp __pattern, memory_order __order) { | |
| 276 | return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 277 | } | |
| 278 | ||
| 279 | template <typename _Tp> | |
| 280 | _LIBCPP_HIDE_FROM_ABI | |
| 281 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, | |
| 282 | memory_order __order) { | |
| 283 | return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 284 | } | |
| 285 | ||
| 286 | template <typename _Tp> | |
| 287 | _LIBCPP_HIDE_FROM_ABI | |
| 288 | _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 289 | _Tp __pattern, memory_order __order) { | |
| 290 | return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 291 | } | |
| 292 | ||
| 293 | template <typename _Tp> | |
| 294 | _LIBCPP_HIDE_FROM_ABI | |
| 295 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, | |
| 296 | memory_order __order) { | |
| 297 | return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); | |
| 298 | } | |
| 299 | ||
| 300 | #define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) | |
| 301 | ||
| 302 | #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) | |
| 303 | ||
| 304 | template <typename _Tp> | |
| 305 | struct __cxx_atomic_base_impl { | |
| 306 | ||
| 307 | _LIBCPP_HIDE_FROM_ABI | |
| 308 | #ifndef _LIBCPP_CXX03_LANG | |
| 309 | __cxx_atomic_base_impl() _NOEXCEPT = default; | |
| 310 | #else | |
| 311 | __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} | |
| 312 | #endif // _LIBCPP_CXX03_LANG | |
| 313 | _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT | |
| 314 | : __a_value(__value) {} | |
| 315 | _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; | |
| 316 | }; | |
| 317 | ||
| 318 | #define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) | |
| 319 | ||
| 320 | _LIBCPP_HIDE_FROM_ABI inline | |
| 321 | void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { | |
| 322 | __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); | |
| 323 | } | |
| 324 | ||
| 325 | _LIBCPP_HIDE_FROM_ABI inline | |
| 326 | void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { | |
| 327 | __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); | |
| 328 | } | |
| 329 | ||
| 330 | template<class _Tp> | |
| 331 | _LIBCPP_HIDE_FROM_ABI | |
| 332 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { | |
| 333 | __c11_atomic_init(std::addressof(__a->__a_value), __val); | |
| 334 | } | |
| 335 | template<class _Tp> | |
| 336 | _LIBCPP_HIDE_FROM_ABI | |
| 337 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { | |
| 338 | __c11_atomic_init(std::addressof(__a->__a_value), __val); | |
| 339 | } | |
| 340 | ||
| 341 | template<class _Tp> | |
| 342 | _LIBCPP_HIDE_FROM_ABI | |
| 343 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { | |
| 344 | __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); | |
| 345 | } | |
| 346 | template<class _Tp> | |
| 347 | _LIBCPP_HIDE_FROM_ABI | |
| 348 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { | |
| 349 | __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); | |
| 350 | } | |
| 351 | ||
| 352 | template<class _Tp> | |
| 353 | _LIBCPP_HIDE_FROM_ABI | |
| 354 | _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { | |
| 355 | using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; | |
| 356 | return __c11_atomic_load( | |
| 357 | const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); | |
| 358 | } | |
| 359 | template<class _Tp> | |
| 360 | _LIBCPP_HIDE_FROM_ABI | |
| 361 | _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { | |
| 362 | using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; | |
| 363 | return __c11_atomic_load( | |
| 364 | const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); | |
| 365 | } | |
| 366 | ||
| 367 | template<class _Tp> | |
| 368 | _LIBCPP_HIDE_FROM_ABI | |
| 369 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { | |
| 370 | return __c11_atomic_exchange( | |
| 371 | std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); | |
| 372 | } | |
| 373 | template<class _Tp> | |
| 374 | _LIBCPP_HIDE_FROM_ABI | |
| 375 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { | |
| 376 | return __c11_atomic_exchange( | |
| 377 | std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); | |
| 378 | } | |
| 379 | ||
| 380 | _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) { | |
| 381 | // Avoid switch statement to make this a constexpr. | |
| 382 | return __order == memory_order_release ? memory_order_relaxed: | |
| 383 | (__order == memory_order_acq_rel ? memory_order_acquire: | |
| 384 | __order); | |
| 385 | } | |
| 386 | ||
| 387 | template<class _Tp> | |
| 388 | _LIBCPP_HIDE_FROM_ABI | |
| 389 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 390 | return __c11_atomic_compare_exchange_strong( | |
| 391 | std::addressof(__a->__a_value), | |
| 392 | __expected, | |
| 393 | __value, | |
| 394 | static_cast<__memory_order_underlying_t>(__success), | |
| 395 | static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 396 | } | |
| 397 | template<class _Tp> | |
| 398 | _LIBCPP_HIDE_FROM_ABI | |
| 399 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 400 | return __c11_atomic_compare_exchange_strong( | |
| 401 | std::addressof(__a->__a_value), | |
| 402 | __expected, | |
| 403 | __value, | |
| 404 | static_cast<__memory_order_underlying_t>(__success), | |
| 405 | static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 406 | } | |
| 407 | ||
| 408 | template<class _Tp> | |
| 409 | _LIBCPP_HIDE_FROM_ABI | |
| 410 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 411 | return __c11_atomic_compare_exchange_weak( | |
| 412 | std::addressof(__a->__a_value), | |
| 413 | __expected, | |
| 414 | __value, | |
| 415 | static_cast<__memory_order_underlying_t>(__success), | |
| 416 | static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 417 | } | |
| 418 | template<class _Tp> | |
| 419 | _LIBCPP_HIDE_FROM_ABI | |
| 420 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 421 | return __c11_atomic_compare_exchange_weak( | |
| 422 | std::addressof(__a->__a_value), | |
| 423 | __expected, | |
| 424 | __value, | |
| 425 | static_cast<__memory_order_underlying_t>(__success), | |
| 426 | static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 427 | } | |
| 428 | ||
| 429 | template<class _Tp> | |
| 430 | _LIBCPP_HIDE_FROM_ABI | |
| 431 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 432 | return __c11_atomic_fetch_add( | |
| 433 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 434 | } | |
| 435 | template<class _Tp> | |
| 436 | _LIBCPP_HIDE_FROM_ABI | |
| 437 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 438 | return __c11_atomic_fetch_add( | |
| 439 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 440 | } | |
| 441 | ||
| 442 | template<class _Tp> | |
| 443 | _LIBCPP_HIDE_FROM_ABI | |
| 444 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 445 | return __c11_atomic_fetch_add( | |
| 446 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 447 | } | |
| 448 | template<class _Tp> | |
| 449 | _LIBCPP_HIDE_FROM_ABI | |
| 450 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 451 | return __c11_atomic_fetch_add( | |
| 452 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 453 | } | |
| 454 | ||
| 455 | template<class _Tp> | |
| 456 | _LIBCPP_HIDE_FROM_ABI | |
| 457 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 458 | return __c11_atomic_fetch_sub( | |
| 459 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 460 | } | |
| 461 | template<class _Tp> | |
| 462 | _LIBCPP_HIDE_FROM_ABI | |
| 463 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 464 | return __c11_atomic_fetch_sub( | |
| 465 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 466 | } | |
| 467 | template<class _Tp> | |
| 468 | _LIBCPP_HIDE_FROM_ABI | |
| 469 | _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 470 | return __c11_atomic_fetch_sub( | |
| 471 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 472 | } | |
| 473 | template<class _Tp> | |
| 474 | _LIBCPP_HIDE_FROM_ABI | |
| 475 | _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 476 | return __c11_atomic_fetch_sub( | |
| 477 | std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 478 | } | |
| 479 | ||
| 480 | template<class _Tp> | |
| 481 | _LIBCPP_HIDE_FROM_ABI | |
| 482 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 483 | return __c11_atomic_fetch_and( | |
| 484 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 485 | } | |
| 486 | template<class _Tp> | |
| 487 | _LIBCPP_HIDE_FROM_ABI | |
| 488 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 489 | return __c11_atomic_fetch_and( | |
| 490 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 491 | } | |
| 492 | ||
| 493 | template<class _Tp> | |
| 494 | _LIBCPP_HIDE_FROM_ABI | |
| 495 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 496 | return __c11_atomic_fetch_or( | |
| 497 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 498 | } | |
| 499 | template<class _Tp> | |
| 500 | _LIBCPP_HIDE_FROM_ABI | |
| 501 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 502 | return __c11_atomic_fetch_or( | |
| 503 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 504 | } | |
| 505 | ||
| 506 | template<class _Tp> | |
| 507 | _LIBCPP_HIDE_FROM_ABI | |
| 508 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 509 | return __c11_atomic_fetch_xor( | |
| 510 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 511 | } | |
| 512 | template<class _Tp> | |
| 513 | _LIBCPP_HIDE_FROM_ABI | |
| 514 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 515 | return __c11_atomic_fetch_xor( | |
| 516 | std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 517 | } | |
| 518 | ||
| 519 | #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP | |
| 520 | ||
| 521 | #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS | |
| 522 | ||
| 523 | template<typename _Tp> | |
| 524 | struct __cxx_atomic_lock_impl { | |
| 525 | ||
| 526 | _LIBCPP_HIDE_FROM_ABI | |
| 527 | __cxx_atomic_lock_impl() _NOEXCEPT | |
| 528 | : __a_value(), __a_lock(0) {} | |
| 529 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit | |
| 530 | __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT | |
| 531 | : __a_value(value), __a_lock(0) {} | |
| 532 | ||
| 533 | _Tp __a_value; | |
| 534 | mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; | |
| 535 | ||
| 536 | _LIBCPP_HIDE_FROM_ABI void __lock() const volatile { | |
| 537 | while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) | |
| 538 | /*spin*/; | |
| 539 | } | |
| 540 | _LIBCPP_HIDE_FROM_ABI void __lock() const { | |
| 541 | while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) | |
| 542 | /*spin*/; | |
| 543 | } | |
| 544 | _LIBCPP_HIDE_FROM_ABI void __unlock() const volatile { | |
| 545 | __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); | |
| 546 | } | |
| 547 | _LIBCPP_HIDE_FROM_ABI void __unlock() const { | |
| 548 | __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); | |
| 549 | } | |
| 550 | _LIBCPP_HIDE_FROM_ABI _Tp __read() const volatile { | |
| 551 | __lock(); | |
| 552 | _Tp __old; | |
| 553 | __cxx_atomic_assign_volatile(__old, __a_value); | |
| 554 | __unlock(); | |
| 555 | return __old; | |
| 556 | } | |
| 557 | _LIBCPP_HIDE_FROM_ABI _Tp __read() const { | |
| 558 | __lock(); | |
| 559 | _Tp __old = __a_value; | |
| 560 | __unlock(); | |
| 561 | return __old; | |
| 562 | } | |
| 563 | }; | |
| 564 | ||
| 565 | template <typename _Tp> | |
| 566 | _LIBCPP_HIDE_FROM_ABI | |
| 567 | void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { | |
| 568 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 569 | } | |
| 570 | template <typename _Tp> | |
| 571 | _LIBCPP_HIDE_FROM_ABI | |
| 572 | void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { | |
| 573 | __a->__a_value = __val; | |
| 574 | } | |
| 575 | ||
| 576 | template <typename _Tp> | |
| 577 | _LIBCPP_HIDE_FROM_ABI | |
| 578 | void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { | |
| 579 | __a->__lock(); | |
| 580 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 581 | __a->__unlock(); | |
| 582 | } | |
| 583 | template <typename _Tp> | |
| 584 | _LIBCPP_HIDE_FROM_ABI | |
| 585 | void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { | |
| 586 | __a->__lock(); | |
| 587 | __a->__a_value = __val; | |
| 588 | __a->__unlock(); | |
| 589 | } | |
| 590 | ||
| 591 | template <typename _Tp> | |
| 592 | _LIBCPP_HIDE_FROM_ABI | |
| 593 | _Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { | |
| 594 | return __a->__read(); | |
| 595 | } | |
| 596 | template <typename _Tp> | |
| 597 | _LIBCPP_HIDE_FROM_ABI | |
| 598 | _Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { | |
| 599 | return __a->__read(); | |
| 600 | } | |
| 601 | ||
| 602 | template <typename _Tp> | |
| 603 | _LIBCPP_HIDE_FROM_ABI | |
| 604 | _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { | |
| 605 | __a->__lock(); | |
| 606 | _Tp __old; | |
| 607 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 608 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 609 | __a->__unlock(); | |
| 610 | return __old; | |
| 611 | } | |
| 612 | template <typename _Tp> | |
| 613 | _LIBCPP_HIDE_FROM_ABI | |
| 614 | _Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { | |
| 615 | __a->__lock(); | |
| 616 | _Tp __old = __a->__a_value; | |
| 617 | __a->__a_value = __value; | |
| 618 | __a->__unlock(); | |
| 619 | return __old; | |
| 620 | } | |
| 621 | ||
| 622 | template <typename _Tp> | |
| 623 | _LIBCPP_HIDE_FROM_ABI | |
| 624 | bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 625 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 626 | _Tp __temp; | |
| 627 | __a->__lock(); | |
| 628 | __cxx_atomic_assign_volatile(__temp, __a->__a_value); | |
| 629 | bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); | |
| 630 | if(__ret) | |
| 631 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 632 | else | |
| 633 | __cxx_atomic_assign_volatile(*__expected, __a->__a_value); | |
| 634 | __a->__unlock(); | |
| 635 | return __ret; | |
| 636 | } | |
| 637 | template <typename _Tp> | |
| 638 | _LIBCPP_HIDE_FROM_ABI | |
| 639 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 640 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 641 | __a->__lock(); | |
| 642 | bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); | |
| 643 | if(__ret) | |
| 644 | std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); | |
| 645 | else | |
| 646 | std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); | |
| 647 | __a->__unlock(); | |
| 648 | return __ret; | |
| 649 | } | |
| 650 | ||
| 651 | template <typename _Tp> | |
| 652 | _LIBCPP_HIDE_FROM_ABI | |
| 653 | bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 654 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 655 | _Tp __temp; | |
| 656 | __a->__lock(); | |
| 657 | __cxx_atomic_assign_volatile(__temp, __a->__a_value); | |
| 658 | bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); | |
| 659 | if(__ret) | |
| 660 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 661 | else | |
| 662 | __cxx_atomic_assign_volatile(*__expected, __a->__a_value); | |
| 663 | __a->__unlock(); | |
| 664 | return __ret; | |
| 665 | } | |
| 666 | template <typename _Tp> | |
| 667 | _LIBCPP_HIDE_FROM_ABI | |
| 668 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 669 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 670 | __a->__lock(); | |
| 671 | bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); | |
| 672 | if(__ret) | |
| 673 | std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); | |
| 674 | else | |
| 675 | std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); | |
| 676 | __a->__unlock(); | |
| 677 | return __ret; | |
| 678 | } | |
| 679 | ||
| 680 | template <typename _Tp, typename _Td> | |
| 681 | _LIBCPP_HIDE_FROM_ABI | |
| 682 | _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 683 | _Td __delta, memory_order) { | |
| 684 | __a->__lock(); | |
| 685 | _Tp __old; | |
| 686 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 687 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta)); | |
| 688 | __a->__unlock(); | |
| 689 | return __old; | |
| 690 | } | |
| 691 | template <typename _Tp, typename _Td> | |
| 692 | _LIBCPP_HIDE_FROM_ABI | |
| 693 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 694 | _Td __delta, memory_order) { | |
| 695 | __a->__lock(); | |
| 696 | _Tp __old = __a->__a_value; | |
| 697 | __a->__a_value += __delta; | |
| 698 | __a->__unlock(); | |
| 699 | return __old; | |
| 700 | } | |
| 701 | ||
| 702 | template <typename _Tp, typename _Td> | |
| 703 | _LIBCPP_HIDE_FROM_ABI | |
| 704 | _Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, | |
| 705 | ptrdiff_t __delta, memory_order) { | |
| 706 | __a->__lock(); | |
| 707 | _Tp* __old; | |
| 708 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 709 | __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta); | |
| 710 | __a->__unlock(); | |
| 711 | return __old; | |
| 712 | } | |
| 713 | template <typename _Tp, typename _Td> | |
| 714 | _LIBCPP_HIDE_FROM_ABI | |
| 715 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, | |
| 716 | ptrdiff_t __delta, memory_order) { | |
| 717 | __a->__lock(); | |
| 718 | _Tp* __old = __a->__a_value; | |
| 719 | __a->__a_value += __delta; | |
| 720 | __a->__unlock(); | |
| 721 | return __old; | |
| 722 | } | |
| 723 | ||
| 724 | template <typename _Tp, typename _Td> | |
| 725 | _LIBCPP_HIDE_FROM_ABI | |
| 726 | _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 727 | _Td __delta, memory_order) { | |
| 728 | __a->__lock(); | |
| 729 | _Tp __old; | |
| 730 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 731 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta)); | |
| 732 | __a->__unlock(); | |
| 733 | return __old; | |
| 734 | } | |
| 735 | template <typename _Tp, typename _Td> | |
| 736 | _LIBCPP_HIDE_FROM_ABI | |
| 737 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 738 | _Td __delta, memory_order) { | |
| 739 | __a->__lock(); | |
| 740 | _Tp __old = __a->__a_value; | |
| 741 | __a->__a_value -= __delta; | |
| 742 | __a->__unlock(); | |
| 743 | return __old; | |
| 744 | } | |
| 745 | ||
| 746 | template <typename _Tp> | |
| 747 | _LIBCPP_HIDE_FROM_ABI | |
| 748 | _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 749 | _Tp __pattern, memory_order) { | |
| 750 | __a->__lock(); | |
| 751 | _Tp __old; | |
| 752 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 753 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern)); | |
| 754 | __a->__unlock(); | |
| 755 | return __old; | |
| 756 | } | |
| 757 | template <typename _Tp> | |
| 758 | _LIBCPP_HIDE_FROM_ABI | |
| 759 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 760 | _Tp __pattern, memory_order) { | |
| 761 | __a->__lock(); | |
| 762 | _Tp __old = __a->__a_value; | |
| 763 | __a->__a_value &= __pattern; | |
| 764 | __a->__unlock(); | |
| 765 | return __old; | |
| 766 | } | |
| 767 | ||
| 768 | template <typename _Tp> | |
| 769 | _LIBCPP_HIDE_FROM_ABI | |
| 770 | _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 771 | _Tp __pattern, memory_order) { | |
| 772 | __a->__lock(); | |
| 773 | _Tp __old; | |
| 774 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 775 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern)); | |
| 776 | __a->__unlock(); | |
| 777 | return __old; | |
| 778 | } | |
| 779 | template <typename _Tp> | |
| 780 | _LIBCPP_HIDE_FROM_ABI | |
| 781 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 782 | _Tp __pattern, memory_order) { | |
| 783 | __a->__lock(); | |
| 784 | _Tp __old = __a->__a_value; | |
| 785 | __a->__a_value |= __pattern; | |
| 786 | __a->__unlock(); | |
| 787 | return __old; | |
| 788 | } | |
| 789 | ||
| 790 | template <typename _Tp> | |
| 791 | _LIBCPP_HIDE_FROM_ABI | |
| 792 | _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 793 | _Tp __pattern, memory_order) { | |
| 794 | __a->__lock(); | |
| 795 | _Tp __old; | |
| 796 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 797 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern)); | |
| 798 | __a->__unlock(); | |
| 799 | return __old; | |
| 800 | } | |
| 801 | template <typename _Tp> | |
| 802 | _LIBCPP_HIDE_FROM_ABI | |
| 803 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 804 | _Tp __pattern, memory_order) { | |
| 805 | __a->__lock(); | |
| 806 | _Tp __old = __a->__a_value; | |
| 807 | __a->__a_value ^= __pattern; | |
| 808 | __a->__unlock(); | |
| 809 | return __old; | |
| 810 | } | |
| 811 | ||
| 812 | template <typename _Tp, | |
| 813 | typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value, | |
| 814 | __cxx_atomic_base_impl<_Tp>, | |
| 815 | __cxx_atomic_lock_impl<_Tp> >::type> | |
| 816 | #else | |
| 817 | template <typename _Tp, | |
| 818 | typename _Base = __cxx_atomic_base_impl<_Tp> > | |
| 819 | #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS | |
| 820 | struct __cxx_atomic_impl : public _Base { | |
| 821 | static_assert(is_trivially_copyable<_Tp>::value, | |
| 822 | "std::atomic<T> requires that 'T' be a trivially copyable type"); | |
| 823 | ||
| 824 | _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; | |
| 825 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT | |
| 826 | : _Base(__value) {} | |
| 827 | }; | |
| 828 | ||
| 829 | _LIBCPP_END_NAMESPACE_STD | |
| 830 | ||
| 831 | #endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H |
lib/libcxx/include/__atomic/fence.h created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_FENCE_H | |
| 10 | #define _LIBCPP___ATOMIC_FENCE_H | |
| 11 | ||
| 12 | #include <__atomic/cxx_atomic_impl.h> | |
| 13 | #include <__atomic/memory_order.h> | |
| 14 | #include <__config> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | inline _LIBCPP_HIDE_FROM_ABI | |
| 23 | void | |
| 24 | atomic_thread_fence(memory_order __m) _NOEXCEPT | |
| 25 | { | |
| 26 | __cxx_atomic_thread_fence(__m); | |
| 27 | } | |
| 28 | ||
| 29 | inline _LIBCPP_HIDE_FROM_ABI | |
| 30 | void | |
| 31 | atomic_signal_fence(memory_order __m) _NOEXCEPT | |
| 32 | { | |
| 33 | __cxx_atomic_signal_fence(__m); | |
| 34 | } | |
| 35 | ||
| 36 | _LIBCPP_END_NAMESPACE_STD | |
| 37 | ||
| 38 | #endif // _LIBCPP___ATOMIC_FENCE_H |
lib/libcxx/include/__atomic/is_always_lock_free.h created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H | |
| 10 | #define _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 19 | ||
| 20 | template <class _Tp> | |
| 21 | struct __libcpp_is_always_lock_free { | |
| 22 | // __atomic_always_lock_free is available in all Standard modes | |
| 23 | static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); | |
| 24 | }; | |
| 25 | ||
| 26 | _LIBCPP_END_NAMESPACE_STD | |
| 27 | ||
| 28 | #endif // _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H |
lib/libcxx/include/__atomic/kill_dependency.h created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_KILL_DEPENDENCY_H | |
| 10 | #define _LIBCPP___ATOMIC_KILL_DEPENDENCY_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 19 | ||
| 20 | template <class _Tp> | |
| 21 | _LIBCPP_HIDE_FROM_ABI | |
| 22 | _Tp kill_dependency(_Tp __y) _NOEXCEPT | |
| 23 | { | |
| 24 | return __y; | |
| 25 | } | |
| 26 | ||
| 27 | _LIBCPP_END_NAMESPACE_STD | |
| 28 | ||
| 29 | #endif // _LIBCPP___ATOMIC_KILL_DEPENDENCY_H |
lib/libcxx/include/__atomic/memory_order.h created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ATOMIC_MEMORY_ORDER_H | |
| 10 | #define _LIBCPP___ATOMIC_MEMORY_ORDER_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/is_same.h> | |
| 14 | #include <__type_traits/underlying_type.h> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | // Figure out what the underlying type for `memory_order` would be if it were | |
| 23 | // declared as an unscoped enum (accounting for -fshort-enums). Use this result | |
| 24 | // to pin the underlying type in C++20. | |
| 25 | enum __legacy_memory_order { | |
| 26 | __mo_relaxed, | |
| 27 | __mo_consume, | |
| 28 | __mo_acquire, | |
| 29 | __mo_release, | |
| 30 | __mo_acq_rel, | |
| 31 | __mo_seq_cst | |
| 32 | }; | |
| 33 | ||
| 34 | using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type; | |
| 35 | ||
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | ||
| 38 | enum class memory_order : __memory_order_underlying_t { | |
| 39 | relaxed = __mo_relaxed, | |
| 40 | consume = __mo_consume, | |
| 41 | acquire = __mo_acquire, | |
| 42 | release = __mo_release, | |
| 43 | acq_rel = __mo_acq_rel, | |
| 44 | seq_cst = __mo_seq_cst | |
| 45 | }; | |
| 46 | ||
| 47 | static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value), | |
| 48 | "unexpected underlying type for std::memory_order"); | |
| 49 | ||
| 50 | inline constexpr auto memory_order_relaxed = memory_order::relaxed; | |
| 51 | inline constexpr auto memory_order_consume = memory_order::consume; | |
| 52 | inline constexpr auto memory_order_acquire = memory_order::acquire; | |
| 53 | inline constexpr auto memory_order_release = memory_order::release; | |
| 54 | inline constexpr auto memory_order_acq_rel = memory_order::acq_rel; | |
| 55 | inline constexpr auto memory_order_seq_cst = memory_order::seq_cst; | |
| 56 | ||
| 57 | #else | |
| 58 | ||
| 59 | enum memory_order { | |
| 60 | memory_order_relaxed = __mo_relaxed, | |
| 61 | memory_order_consume = __mo_consume, | |
| 62 | memory_order_acquire = __mo_acquire, | |
| 63 | memory_order_release = __mo_release, | |
| 64 | memory_order_acq_rel = __mo_acq_rel, | |
| 65 | memory_order_seq_cst = __mo_seq_cst, | |
| 66 | }; | |
| 67 | ||
| 68 | #endif // _LIBCPP_STD_VER >= 20 | |
| 69 | ||
| 70 | _LIBCPP_END_NAMESPACE_STD | |
| 71 | ||
| 72 | #endif // _LIBCPP___ATOMIC_MEMORY_ORDER_H |
lib/libcxx/include/__availability+144-58| ... | ... | @@ -39,17 +39,23 @@ |
| 39 | 39 | // |
| 40 | 40 | // This mechanism is general in nature, and any vendor can add their markup to |
| 41 | 41 | // the library (see below). Whenever a new feature is added that requires support |
| 42 | // in the shared library, a macro should be added below to mark this feature | |
| 43 | // as unavailable. When vendors decide to ship the feature as part of their | |
| 44 | // shared library, they can update the markup appropriately. | |
| 42 | // in the shared library, two macros are added below to allow marking the feature | |
| 43 | // as unavailable: | |
| 44 | // 1. A macro named `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` which must be defined | |
| 45 | // exactly when compiling for a target that doesn't support the feature. | |
| 46 | // 2. A macro named `_LIBCPP_AVAILABILITY_<feature>`, which must always be defined | |
| 47 | // and must expand to the proper availability attribute for the platform. | |
| 48 | // | |
| 49 | // When vendors decide to ship the feature as part of their shared library, they | |
| 50 | // can update these macros appropriately for their platform, and the library will | |
| 51 | // use those to provide an optimal user experience. | |
| 45 | 52 | // |
| 46 | 53 | // Furthermore, many features in the standard library have corresponding |
| 47 | // feature-test macros. When a feature is made unavailable on some deployment | |
| 48 | // target, a macro should be defined to signal that it is unavailable. That | |
| 49 | // macro can then be picked up when feature-test macros are generated (see | |
| 50 | // generate_feature_test_macro_components.py) to make sure that feature-test | |
| 51 | // macros don't announce a feature as being implemented if it has been marked | |
| 52 | // as unavailable. | |
| 54 | // feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_NO_<feature>` macros | |
| 55 | // are checked by the corresponding feature-test macros generated by | |
| 56 | // generate_feature_test_macro_components.py to ensure that the library | |
| 57 | // doesn't announce a feature as being implemented if it is unavailable on | |
| 58 | // the deployment target. | |
| 53 | 59 | // |
| 54 | 60 | // Note that this mechanism is disabled by default in the "upstream" libc++. |
| 55 | 61 | // Availability annotations are only meaningful when shipping libc++ inside |
| ... | ... | @@ -83,9 +89,8 @@ |
| 83 | 89 | |
| 84 | 90 | // This controls the availability of std::shared_mutex and std::shared_timed_mutex, |
| 85 | 91 | // which were added to the dylib later. |
| 92 | // # define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX | |
| 86 | 93 | # define _LIBCPP_AVAILABILITY_SHARED_MUTEX |
| 87 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex | |
| 88 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex | |
| 89 | 94 | |
| 90 | 95 | // These macros control the availability of std::bad_optional_access and |
| 91 | 96 | // other exception types. These were put in the shared library to prevent |
| ... | ... | @@ -95,16 +100,23 @@ |
| 95 | 100 | // Note that when exceptions are disabled, the methods that normally throw |
| 96 | 101 | // these exceptions can be used even on older deployment targets, but those |
| 97 | 102 | // methods will abort instead of throwing. |
| 103 | // # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS | |
| 98 | 104 | # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS |
| 105 | ||
| 106 | // # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS | |
| 99 | 107 | # define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS |
| 108 | ||
| 109 | // # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST | |
| 100 | 110 | # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST |
| 101 | 111 | |
| 102 | 112 | // This controls the availability of std::uncaught_exceptions(). |
| 113 | // # define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS | |
| 103 | 114 | # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS |
| 104 | 115 | |
| 105 | 116 | // This controls the availability of the sized version of ::operator delete, |
| 106 | 117 | // ::operator delete[], and their align_val_t variants, which were all added |
| 107 | 118 | // in C++17, and hence not present in early dylibs. |
| 119 | // # define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE | |
| 108 | 120 | # define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE |
| 109 | 121 | |
| 110 | 122 | // This controls the availability of the std::future_error exception. |
| ... | ... | @@ -112,73 +124,83 @@ |
| 112 | 124 | // Note that when exceptions are disabled, the methods that normally throw |
| 113 | 125 | // std::future_error can be used even on older deployment targets, but those |
| 114 | 126 | // methods will abort instead of throwing. |
| 127 | // # define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR | |
| 115 | 128 | # define _LIBCPP_AVAILABILITY_FUTURE_ERROR |
| 116 | 129 | |
| 117 | 130 | // This controls the availability of std::type_info's vtable. |
| 118 | 131 | // I can't imagine how using std::type_info can work at all if |
| 119 | 132 | // this isn't supported. |
| 133 | // # define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE | |
| 120 | 134 | # define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE |
| 121 | 135 | |
| 122 | 136 | // This controls the availability of std::locale::category members |
| 123 | 137 | // (e.g. std::locale::collate), which are defined in the dylib. |
| 138 | // # define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY | |
| 124 | 139 | # define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY |
| 125 | 140 | |
| 126 | 141 | // This controls the availability of atomic operations on std::shared_ptr |
| 127 | 142 | // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared |
| 128 | 143 | // lock table located in the dylib. |
| 144 | // # define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR | |
| 129 | 145 | # define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
| 130 | 146 | |
| 131 | 147 | // These macros control the availability of all parts of <filesystem> that |
| 132 | 148 | // depend on something in the dylib. |
| 133 | # define _LIBCPP_AVAILABILITY_FILESYSTEM | |
| 134 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 135 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 136 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem | |
| 149 | // # define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY | |
| 150 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 151 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 152 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 137 | 153 | |
| 138 | 154 | // This controls the availability of floating-point std::to_chars functions. |
| 139 | 155 | // These overloads were added later than the integer overloads. |
| 156 | // # define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT | |
| 140 | 157 | # define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT |
| 141 | 158 | |
| 142 | 159 | // This controls the availability of the C++20 synchronization library, |
| 143 | 160 | // which requires shared library support for various operations |
| 144 | 161 | // (see libcxx/src/atomic.cpp). This includes <barier>, <latch>, |
| 145 | 162 | // <semaphore>, and notification functions on std::atomic. |
| 163 | // # define _LIBCPP_AVAILABILITY_HAS_NO_SYNC | |
| 146 | 164 | # define _LIBCPP_AVAILABILITY_SYNC |
| 147 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait | |
| 148 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier | |
| 149 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch | |
| 150 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore | |
| 151 | ||
| 152 | // This controls the availability of the C++20 format library. | |
| 153 | // The library is in development and not ABI stable yet. P2216 is | |
| 154 | // retroactively accepted in C++20. This paper contains ABI breaking | |
| 155 | // changes. | |
| 156 | # define _LIBCPP_AVAILABILITY_FORMAT | |
| 157 | // # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format | |
| 158 | 165 | |
| 159 | 166 | // This controls whether the library claims to provide a default verbose |
| 160 | 167 | // termination function, and consequently whether the headers will try |
| 161 | 168 | // to use it when the mechanism isn't overriden at compile-time. |
| 162 | // # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY | |
| 169 | // # define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT | |
| 170 | # define _LIBCPP_AVAILABILITY_VERBOSE_ABORT | |
| 171 | ||
| 172 | // This controls the availability of the C++17 std::pmr library, | |
| 173 | // which is implemented in large part in the built library. | |
| 174 | // # define _LIBCPP_AVAILABILITY_HAS_NO_PMR | |
| 175 | # define _LIBCPP_AVAILABILITY_PMR | |
| 163 | 176 | |
| 164 | 177 | #elif defined(__APPLE__) |
| 165 | 178 | |
| 166 | # define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ | |
| 167 | __attribute__((availability(macos,strict,introduced=10.12))) \ | |
| 168 | __attribute__((availability(ios,strict,introduced=10.0))) \ | |
| 169 | __attribute__((availability(tvos,strict,introduced=10.0))) \ | |
| 170 | __attribute__((availability(watchos,strict,introduced=3.0))) | |
| 179 | // shared_mutex and shared_timed_mutex | |
| 171 | 180 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ |
| 172 | 181 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ |
| 173 | 182 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ |
| 174 | 183 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) |
| 175 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex | |
| 176 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex | |
| 184 | # define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX | |
| 177 | 185 | # endif |
| 186 | # define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ | |
| 187 | __attribute__((availability(macos,strict,introduced=10.12))) \ | |
| 188 | __attribute__((availability(ios,strict,introduced=10.0))) \ | |
| 189 | __attribute__((availability(tvos,strict,introduced=10.0))) \ | |
| 190 | __attribute__((availability(watchos,strict,introduced=3.0))) | |
| 178 | 191 | |
| 192 | // bad_optional_access, bad_variant_access and bad_any_cast | |
| 179 | 193 | // Note: bad_optional_access & friends were not introduced in the matching |
| 180 | 194 | // macOS and iOS versions, so the version mismatch between macOS and others |
| 181 | 195 | // is intended. |
| 196 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) || \ | |
| 197 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ | |
| 198 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000) || \ | |
| 199 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) | |
| 200 | # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS | |
| 201 | # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS | |
| 202 | # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST | |
| 203 | # endif | |
| 182 | 204 | # define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ |
| 183 | 205 | __attribute__((availability(macos,strict,introduced=10.13))) \ |
| 184 | 206 | __attribute__((availability(ios,strict,introduced=12.0))) \ |
| ... | ... | @@ -189,78 +211,142 @@ |
| 189 | 211 | # define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ |
| 190 | 212 | _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS |
| 191 | 213 | |
| 214 | // uncaught_exceptions | |
| 215 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ | |
| 216 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 217 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 218 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) | |
| 219 | # define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS | |
| 220 | # endif | |
| 192 | 221 | # define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ |
| 193 | 222 | __attribute__((availability(macos,strict,introduced=10.12))) \ |
| 194 | 223 | __attribute__((availability(ios,strict,introduced=10.0))) \ |
| 195 | 224 | __attribute__((availability(tvos,strict,introduced=10.0))) \ |
| 196 | 225 | __attribute__((availability(watchos,strict,introduced=3.0))) |
| 197 | 226 | |
| 227 | // sized operator new and sized operator delete | |
| 228 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ | |
| 229 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 230 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 231 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) | |
| 232 | # define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE | |
| 233 | # endif | |
| 198 | 234 | # define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ |
| 199 | 235 | __attribute__((availability(macos,strict,introduced=10.12))) \ |
| 200 | 236 | __attribute__((availability(ios,strict,introduced=10.0))) \ |
| 201 | 237 | __attribute__((availability(tvos,strict,introduced=10.0))) \ |
| 202 | 238 | __attribute__((availability(watchos,strict,introduced=3.0))) |
| 203 | 239 | |
| 240 | // future_error | |
| 241 | # if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 60000) | |
| 242 | # define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR | |
| 243 | # endif | |
| 204 | 244 | # define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ |
| 205 | 245 | __attribute__((availability(ios,strict,introduced=6.0))) |
| 206 | 246 | |
| 247 | // type_info's vtable | |
| 248 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ | |
| 249 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) | |
| 250 | # define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE | |
| 251 | # endif | |
| 207 | 252 | # define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ |
| 208 | 253 | __attribute__((availability(macos,strict,introduced=10.9))) \ |
| 209 | 254 | __attribute__((availability(ios,strict,introduced=7.0))) |
| 210 | 255 | |
| 256 | // locale::category | |
| 257 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ | |
| 258 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) | |
| 259 | # define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY | |
| 260 | # endif | |
| 211 | 261 | # define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ |
| 212 | 262 | __attribute__((availability(macos,strict,introduced=10.9))) \ |
| 213 | 263 | __attribute__((availability(ios,strict,introduced=7.0))) |
| 214 | 264 | |
| 265 | // atomic operations on shared_ptr | |
| 266 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ | |
| 267 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) | |
| 268 | # define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR | |
| 269 | # endif | |
| 215 | 270 | # define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ |
| 216 | 271 | __attribute__((availability(macos,strict,introduced=10.9))) \ |
| 217 | 272 | __attribute__((availability(ios,strict,introduced=7.0))) |
| 218 | 273 | |
| 219 | # define _LIBCPP_AVAILABILITY_FILESYSTEM \ | |
| 274 | // <filesystem> | |
| 275 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ | |
| 276 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ | |
| 277 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \ | |
| 278 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) | |
| 279 | # define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY | |
| 280 | # endif | |
| 281 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY \ | |
| 220 | 282 | __attribute__((availability(macos,strict,introduced=10.15))) \ |
| 221 | 283 | __attribute__((availability(ios,strict,introduced=13.0))) \ |
| 222 | 284 | __attribute__((availability(tvos,strict,introduced=13.0))) \ |
| 223 | 285 | __attribute__((availability(watchos,strict,introduced=6.0))) |
| 224 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ | |
| 286 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH \ | |
| 225 | 287 | _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ |
| 226 | 288 | _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ |
| 227 | 289 | _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ |
| 228 | 290 | _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") |
| 229 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ | |
| 291 | # define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP \ | |
| 230 | 292 | _Pragma("clang attribute pop") \ |
| 231 | 293 | _Pragma("clang attribute pop") \ |
| 232 | 294 | _Pragma("clang attribute pop") \ |
| 233 | 295 | _Pragma("clang attribute pop") |
| 234 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ | |
| 235 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ | |
| 236 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \ | |
| 237 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) | |
| 238 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem | |
| 239 | # endif | |
| 240 | 296 | |
| 297 | // std::to_chars(floating-point) | |
| 298 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) || \ | |
| 299 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \ | |
| 300 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) || \ | |
| 301 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300) | |
| 302 | # define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT | |
| 303 | # endif | |
| 241 | 304 | # define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ |
| 242 | __attribute__((unavailable)) | |
| 305 | __attribute__((availability(macos,strict,introduced=13.3))) \ | |
| 306 | __attribute__((availability(ios,strict,introduced=16.3))) \ | |
| 307 | __attribute__((availability(tvos,strict,introduced=16.3))) \ | |
| 308 | __attribute__((availability(watchos,strict,introduced=9.3))) | |
| 243 | 309 | |
| 244 | # define _LIBCPP_AVAILABILITY_SYNC \ | |
| 245 | __attribute__((availability(macos,strict,introduced=11.0))) \ | |
| 246 | __attribute__((availability(ios,strict,introduced=14.0))) \ | |
| 247 | __attribute__((availability(tvos,strict,introduced=14.0))) \ | |
| 248 | __attribute__((availability(watchos,strict,introduced=7.0))) | |
| 310 | // c++20 synchronization library | |
| 249 | 311 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ |
| 250 | 312 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ |
| 251 | 313 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \ |
| 252 | 314 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000) |
| 253 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait | |
| 254 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier | |
| 255 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch | |
| 256 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore | |
| 315 | # define _LIBCPP_AVAILABILITY_HAS_NO_SYNC | |
| 257 | 316 | # endif |
| 317 | # define _LIBCPP_AVAILABILITY_SYNC \ | |
| 318 | __attribute__((availability(macos,strict,introduced=11.0))) \ | |
| 319 | __attribute__((availability(ios,strict,introduced=14.0))) \ | |
| 320 | __attribute__((availability(tvos,strict,introduced=14.0))) \ | |
| 321 | __attribute__((availability(watchos,strict,introduced=7.0))) | |
| 258 | 322 | |
| 259 | # define _LIBCPP_AVAILABILITY_FORMAT \ | |
| 323 | // __libcpp_verbose_abort | |
| 324 | # if 1 // TODO: Update once this is released | |
| 325 | # define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT | |
| 326 | # endif | |
| 327 | # define _LIBCPP_AVAILABILITY_VERBOSE_ABORT \ | |
| 260 | 328 | __attribute__((unavailable)) |
| 261 | # define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format | |
| 262 | 329 | |
| 263 | # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY | |
| 330 | // std::pmr | |
| 331 | # if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) || \ | |
| 332 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \ | |
| 333 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) || \ | |
| 334 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000) | |
| 335 | # define _LIBCPP_AVAILABILITY_HAS_NO_PMR | |
| 336 | # endif | |
| 337 | // TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed | |
| 338 | // Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support | |
| 339 | // 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 | |
| 340 | // use availability annotations until that bug has been fixed. | |
| 341 | # if 0 | |
| 342 | # define _LIBCPP_AVAILABILITY_PMR \ | |
| 343 | __attribute__((availability(macos, strict, introduced = 14.0))) \ | |
| 344 | __attribute__((availability(ios, strict, introduced = 17.0))) \ | |
| 345 | __attribute__((availability(tvos, strict, introduced = 17.0))) \ | |
| 346 | __attribute__((availability(watchos, strict, introduced = 10.0))) | |
| 347 | # else | |
| 348 | # define _LIBCPP_AVAILABILITY_PMR | |
| 349 | # endif | |
| 264 | 350 | |
| 265 | 351 | #else |
| 266 | 352 | |
| ... | ... | @@ -270,10 +356,10 @@ |
| 270 | 356 | |
| 271 | 357 | #endif |
| 272 | 358 | |
| 273 | // Define availability attributes that depend on _LIBCPP_NO_EXCEPTIONS. | |
| 359 | // Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS. | |
| 274 | 360 | // Those are defined in terms of the availability attributes above, and |
| 275 | 361 | // should not be vendor-specific. |
| 276 | #if defined(_LIBCPP_NO_EXCEPTIONS) | |
| 362 | #if defined(_LIBCPP_HAS_NO_EXCEPTIONS) | |
| 277 | 363 | # define _LIBCPP_AVAILABILITY_FUTURE |
| 278 | 364 | # define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
| 279 | 365 | # define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS |
lib/libcxx/include/__bit/bit_cast.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | template <class _ToType, class _FromType> |
| 25 | 25 | requires(sizeof(_ToType) == sizeof(_FromType) && |
| ... | ... | @@ -29,7 +29,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _Fr |
| 29 | 29 | return __builtin_bit_cast(_ToType, __from); |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | #endif // _LIBCPP_STD_VER > 17 | |
| 32 | #endif // _LIBCPP_STD_VER >= 20 | |
| 33 | 33 | |
| 34 | 34 | _LIBCPP_END_NAMESPACE_STD |
| 35 | 35 |
lib/libcxx/include/__bit/bit_ceil.h+4-4| ... | ... | @@ -24,18 +24,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | #if _LIBCPP_STD_VER >= 20 |
| 25 | 25 | |
| 26 | 26 | template <__libcpp_unsigned_integer _Tp> |
| 27 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { | |
| 27 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { | |
| 28 | 28 | if (__t < 2) |
| 29 | 29 | return 1; |
| 30 | 30 | const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u)); |
| 31 | _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); | |
| 31 | _LIBCPP_ASSERT_UNCATEGORIZED(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); | |
| 32 | 32 | |
| 33 | 33 | if constexpr (sizeof(_Tp) >= sizeof(unsigned)) |
| 34 | 34 | return _Tp{1} << __n; |
| 35 | 35 | else { |
| 36 | 36 | const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits; |
| 37 | const unsigned __retVal = 1u << (__n + __extra); | |
| 38 | return (_Tp)(__retVal >> __extra); | |
| 37 | const unsigned __ret_val = 1u << (__n + __extra); | |
| 38 | return (_Tp)(__ret_val >> __extra); | |
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 |
lib/libcxx/include/__bit/bit_floor.h+1-1| ... | ... | @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | #if _LIBCPP_STD_VER >= 20 |
| 24 | 24 | |
| 25 | 25 | template <__libcpp_unsigned_integer _Tp> |
| 26 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { | |
| 26 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { | |
| 27 | 27 | return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); |
| 28 | 28 | } |
| 29 | 29 |
lib/libcxx/include/__bit/bit_width.h+1-1| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | 24 | template <__libcpp_unsigned_integer _Tp> |
| 25 | _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { | |
| 25 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { | |
| 26 | 26 | return __t == 0 ? 0 : std::__bit_log2(__t) + 1; |
| 27 | 27 | } |
| 28 | 28 |
lib/libcxx/include/__bit/byteswap.h+3-4| ... | ... | @@ -13,7 +13,6 @@ |
| 13 | 13 | #include <__concepts/arithmetic.h> |
| 14 | 14 | #include <__config> |
| 15 | 15 | #include <cstdint> |
| 16 | #include <cstdlib> | |
| 17 | 16 | |
| 18 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 18 | # pragma GCC system_header |
| ... | ... | @@ -21,10 +20,10 @@ |
| 21 | 20 | |
| 22 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 22 | |
| 24 | #if _LIBCPP_STD_VER > 20 | |
| 23 | #if _LIBCPP_STD_VER >= 23 | |
| 25 | 24 | |
| 26 | 25 | template <integral _Tp> |
| 27 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { | |
| 26 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { | |
| 28 | 27 | |
| 29 | 28 | if constexpr (sizeof(_Tp) == 1) { |
| 30 | 29 | return __val; |
| ... | ... | @@ -48,7 +47,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { |
| 48 | 47 | } |
| 49 | 48 | } |
| 50 | 49 | |
| 51 | #endif // _LIBCPP_STD_VER > 20 | |
| 50 | #endif // _LIBCPP_STD_VER >= 23 | |
| 52 | 51 | |
| 53 | 52 | _LIBCPP_END_NAMESPACE_STD |
| 54 | 53 |
lib/libcxx/include/__bit/countl.h+5-5| ... | ... | @@ -24,13 +24,13 @@ _LIBCPP_PUSH_MACROS |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 27 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 28 | 28 | int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } |
| 29 | 29 | |
| 30 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 30 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 31 | 31 | int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } |
| 32 | 32 | |
| 33 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 33 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 34 | 34 | int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } |
| 35 | 35 | |
| 36 | 36 | # ifndef _LIBCPP_HAS_NO_INT128 |
| ... | ... | @@ -86,12 +86,12 @@ int __countl_zero(_Tp __t) _NOEXCEPT |
| 86 | 86 | #if _LIBCPP_STD_VER >= 20 |
| 87 | 87 | |
| 88 | 88 | template <__libcpp_unsigned_integer _Tp> |
| 89 | _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { | |
| 89 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { | |
| 90 | 90 | return std::__countl_zero(__t); |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | template <__libcpp_unsigned_integer _Tp> |
| 94 | _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { | |
| 94 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { | |
| 95 | 95 | return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; |
| 96 | 96 | } |
| 97 | 97 |
lib/libcxx/include/__bit/countr.h+5-5| ... | ... | @@ -23,19 +23,19 @@ _LIBCPP_PUSH_MACROS |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 26 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 27 | 27 | int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } |
| 28 | 28 | |
| 29 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 29 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 30 | 30 | int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } |
| 31 | 31 | |
| 32 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 32 | _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 33 | 33 | int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } |
| 34 | 34 | |
| 35 | 35 | #if _LIBCPP_STD_VER >= 20 |
| 36 | 36 | |
| 37 | 37 | template <__libcpp_unsigned_integer _Tp> |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { | |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { | |
| 39 | 39 | if (__t == 0) |
| 40 | 40 | return numeric_limits<_Tp>::digits; |
| 41 | 41 | |
| ... | ... | @@ -57,7 +57,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | 59 | template <__libcpp_unsigned_integer _Tp> |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { | |
| 60 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { | |
| 61 | 61 | return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; |
| 62 | 62 | } |
| 63 | 63 |
lib/libcxx/include/__bit/has_single_bit.h+1-1| ... | ... | @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | 26 | template <__libcpp_unsigned_integer _Tp> |
| 27 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { | |
| 27 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { | |
| 28 | 28 | return __t != 0 && (((__t & (__t - 1)) == 0)); |
| 29 | 29 | } |
| 30 | 30 |
lib/libcxx/include/__bit/popcount.h+1-1| ... | ... | @@ -35,7 +35,7 @@ int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popco |
| 35 | 35 | #if _LIBCPP_STD_VER >= 20 |
| 36 | 36 | |
| 37 | 37 | template <__libcpp_unsigned_integer _Tp> |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { | |
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { | |
| 39 | 39 | if (sizeof(_Tp) <= sizeof(unsigned int)) |
| 40 | 40 | return std::__libcpp_popcount(static_cast<unsigned int>(__t)); |
| 41 | 41 | else if (sizeof(_Tp) <= sizeof(unsigned long)) |
lib/libcxx/include/__bit/rotate.h+2-2| ... | ... | @@ -34,7 +34,7 @@ _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT |
| 34 | 34 | #if _LIBCPP_STD_VER >= 20 |
| 35 | 35 | |
| 36 | 36 | template <__libcpp_unsigned_integer _Tp> |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { | |
| 37 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { | |
| 38 | 38 | const unsigned int __dig = numeric_limits<_Tp>::digits; |
| 39 | 39 | if ((__cnt % __dig) == 0) |
| 40 | 40 | return __t; |
| ... | ... | @@ -42,7 +42,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | 44 | template <__libcpp_unsigned_integer _Tp> |
| 45 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { | |
| 45 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { | |
| 46 | 46 | return std::__rotr(__t, __cnt); |
| 47 | 47 | } |
| 48 | 48 |
lib/libcxx/include/__bit_reference+29-26| ... | ... | @@ -19,8 +19,9 @@ |
| 19 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | 20 | #include <__memory/construct_at.h> |
| 21 | 21 | #include <__memory/pointer_traits.h> |
| 22 | #include <__type_traits/conditional.h> | |
| 23 | #include <__utility/swap.h> | |
| 22 | 24 | #include <cstring> |
| 23 | #include <type_traits> | |
| 24 | 25 | |
| 25 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 27 | # pragma GCC system_header |
| ... | ... | @@ -75,7 +76,7 @@ public: |
| 75 | 76 | return *this; |
| 76 | 77 | } |
| 77 | 78 | |
| 78 | #if _LIBCPP_STD_VER > 20 | |
| 79 | #if _LIBCPP_STD_VER >= 23 | |
| 79 | 80 | _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { |
| 80 | 81 | if (__x) |
| 81 | 82 | *__seg_ |= __mask_; |
| ... | ... | @@ -155,6 +156,8 @@ class __bit_const_reference |
| 155 | 156 | friend typename _Cp::__self; |
| 156 | 157 | friend class __bit_iterator<_Cp, true>; |
| 157 | 158 | public: |
| 159 | using __container = typename _Cp::__self; | |
| 160 | ||
| 158 | 161 | _LIBCPP_INLINE_VISIBILITY |
| 159 | 162 | __bit_const_reference(const __bit_const_reference&) = default; |
| 160 | 163 | |
| ... | ... | @@ -728,12 +731,12 @@ move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsCons |
| 728 | 731 | |
| 729 | 732 | // swap_ranges |
| 730 | 733 | |
| 731 | template <class __C1, class __C2> | |
| 732 | _LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> | |
| 733 | __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, | |
| 734 | __bit_iterator<__C2, false> __result) | |
| 734 | template <class _Cl, class _Cr> | |
| 735 | _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> | |
| 736 | __swap_ranges_aligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, | |
| 737 | __bit_iterator<_Cr, false> __result) | |
| 735 | 738 | { |
| 736 | typedef __bit_iterator<__C1, false> _I1; | |
| 739 | typedef __bit_iterator<_Cl, false> _I1; | |
| 737 | 740 | typedef typename _I1::difference_type difference_type; |
| 738 | 741 | typedef typename _I1::__storage_type __storage_type; |
| 739 | 742 | const int __bits_per_word = _I1::__bits_per_word; |
| ... | ... | @@ -778,12 +781,12 @@ __swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, |
| 778 | 781 | return __result; |
| 779 | 782 | } |
| 780 | 783 | |
| 781 | template <class __C1, class __C2> | |
| 782 | _LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> | |
| 783 | __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, | |
| 784 | __bit_iterator<__C2, false> __result) | |
| 784 | template <class _Cl, class _Cr> | |
| 785 | _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> | |
| 786 | __swap_ranges_unaligned(__bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, | |
| 787 | __bit_iterator<_Cr, false> __result) | |
| 785 | 788 | { |
| 786 | typedef __bit_iterator<__C1, false> _I1; | |
| 789 | typedef __bit_iterator<_Cl, false> _I1; | |
| 787 | 790 | typedef typename _I1::difference_type difference_type; |
| 788 | 791 | typedef typename _I1::__storage_type __storage_type; |
| 789 | 792 | const int __bits_per_word = _I1::__bits_per_word; |
| ... | ... | @@ -878,11 +881,11 @@ __swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1 |
| 878 | 881 | return __result; |
| 879 | 882 | } |
| 880 | 883 | |
| 881 | template <class __C1, class __C2> | |
| 884 | template <class _Cl, class _Cr> | |
| 882 | 885 | inline _LIBCPP_INLINE_VISIBILITY |
| 883 | __bit_iterator<__C2, false> | |
| 884 | swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, | |
| 885 | __bit_iterator<__C2, false> __first2) | |
| 886 | __bit_iterator<_Cr, false> | |
| 887 | swap_ranges(__bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, | |
| 888 | __bit_iterator<_Cr, false> __first2) | |
| 886 | 889 | { |
| 887 | 890 | if (__first1.__ctz_ == __first2.__ctz_) |
| 888 | 891 | return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); |
| ... | ... | @@ -1135,7 +1138,7 @@ private: |
| 1135 | 1138 | |
| 1136 | 1139 | public: |
| 1137 | 1140 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT |
| 1138 | #if _LIBCPP_STD_VER > 11 | |
| 1141 | #if _LIBCPP_STD_VER >= 14 | |
| 1139 | 1142 | : __seg_(nullptr), __ctz_(0) |
| 1140 | 1143 | #endif |
| 1141 | 1144 | {} |
| ... | ... | @@ -1311,15 +1314,15 @@ private: |
| 1311 | 1314 | friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, |
| 1312 | 1315 | __bit_iterator<_Dp, _IC> __last, |
| 1313 | 1316 | __bit_iterator<_Dp, false> __result); |
| 1314 | template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, | |
| 1315 | __bit_iterator<__C1, false>, | |
| 1316 | __bit_iterator<__C2, false>); | |
| 1317 | template <class __C1, class __C2>friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, | |
| 1318 | __bit_iterator<__C1, false>, | |
| 1319 | __bit_iterator<__C2, false>); | |
| 1320 | template <class __C1, class __C2>friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, | |
| 1321 | __bit_iterator<__C1, false>, | |
| 1322 | __bit_iterator<__C2, false>); | |
| 1317 | template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_aligned(__bit_iterator<_Cl, false>, | |
| 1318 | __bit_iterator<_Cl, false>, | |
| 1319 | __bit_iterator<_Cr, false>); | |
| 1320 | template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> __swap_ranges_unaligned(__bit_iterator<_Cl, false>, | |
| 1321 | __bit_iterator<_Cl, false>, | |
| 1322 | __bit_iterator<_Cr, false>); | |
| 1323 | template <class _Cl, class _Cr>friend __bit_iterator<_Cr, false> swap_ranges(__bit_iterator<_Cl, false>, | |
| 1324 | __bit_iterator<_Cl, false>, | |
| 1325 | __bit_iterator<_Cr, false>); | |
| 1323 | 1326 | template <class _Dp> |
| 1324 | 1327 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1325 | 1328 | friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, |
lib/libcxx/include/__bsd_locale_defaults.h deleted-36| ... | ... | @@ -1,36 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // The BSDs have lots of *_l functions. We don't want to define those symbols | |
| 10 | // on other platforms though, for fear of conflicts with user code. So here, | |
| 11 | // we will define the mapping from an internal macro to the real BSD symbol. | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #ifndef _LIBCPP___BSD_LOCALE_DEFAULTS_H | |
| 15 | #define _LIBCPP___BSD_LOCALE_DEFAULTS_H | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | #define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) | |
| 22 | #define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) | |
| 23 | #define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) | |
| 24 | #define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) | |
| 25 | #define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) | |
| 26 | #define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) | |
| 27 | #define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) | |
| 28 | #define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) | |
| 29 | #define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) | |
| 30 | #define __libcpp_localeconv_l(l) localeconv_l(l) | |
| 31 | #define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) | |
| 32 | #define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) | |
| 33 | #define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) | |
| 34 | #define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) | |
| 35 | ||
| 36 | #endif // _LIBCPP___BSD_LOCALE_DEFAULTS_H |
lib/libcxx/include/__bsd_locale_fallbacks.h deleted-142| ... | ... | @@ -1,142 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // The BSDs have lots of *_l functions. This file provides reimplementations | |
| 10 | // of those functions for non-BSD platforms. | |
| 11 | //===----------------------------------------------------------------------===// | |
| 12 | ||
| 13 | #ifndef _LIBCPP___BSD_LOCALE_FALLBACKS_H | |
| 14 | #define _LIBCPP___BSD_LOCALE_FALLBACKS_H | |
| 15 | ||
| 16 | #include <stdarg.h> | |
| 17 | #include <stdlib.h> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | inline _LIBCPP_INLINE_VISIBILITY | |
| 26 | decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) | |
| 27 | { | |
| 28 | __libcpp_locale_guard __current(__l); | |
| 29 | return MB_CUR_MAX; | |
| 30 | } | |
| 31 | ||
| 32 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 33 | inline _LIBCPP_INLINE_VISIBILITY | |
| 34 | wint_t __libcpp_btowc_l(int __c, locale_t __l) | |
| 35 | { | |
| 36 | __libcpp_locale_guard __current(__l); | |
| 37 | return btowc(__c); | |
| 38 | } | |
| 39 | ||
| 40 | inline _LIBCPP_INLINE_VISIBILITY | |
| 41 | int __libcpp_wctob_l(wint_t __c, locale_t __l) | |
| 42 | { | |
| 43 | __libcpp_locale_guard __current(__l); | |
| 44 | return wctob(__c); | |
| 45 | } | |
| 46 | ||
| 47 | inline _LIBCPP_INLINE_VISIBILITY | |
| 48 | size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, | |
| 49 | size_t __len, mbstate_t *__ps, locale_t __l) | |
| 50 | { | |
| 51 | __libcpp_locale_guard __current(__l); | |
| 52 | return wcsnrtombs(__dest, __src, __nwc, __len, __ps); | |
| 53 | } | |
| 54 | ||
| 55 | inline _LIBCPP_INLINE_VISIBILITY | |
| 56 | size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) | |
| 57 | { | |
| 58 | __libcpp_locale_guard __current(__l); | |
| 59 | return wcrtomb(__s, __wc, __ps); | |
| 60 | } | |
| 61 | ||
| 62 | inline _LIBCPP_INLINE_VISIBILITY | |
| 63 | size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, | |
| 64 | size_t __len, mbstate_t *__ps, locale_t __l) | |
| 65 | { | |
| 66 | __libcpp_locale_guard __current(__l); | |
| 67 | return mbsnrtowcs(__dest, __src, __nms, __len, __ps); | |
| 68 | } | |
| 69 | ||
| 70 | inline _LIBCPP_INLINE_VISIBILITY | |
| 71 | size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, | |
| 72 | mbstate_t *__ps, locale_t __l) | |
| 73 | { | |
| 74 | __libcpp_locale_guard __current(__l); | |
| 75 | return mbrtowc(__pwc, __s, __n, __ps); | |
| 76 | } | |
| 77 | ||
| 78 | inline _LIBCPP_INLINE_VISIBILITY | |
| 79 | int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) | |
| 80 | { | |
| 81 | __libcpp_locale_guard __current(__l); | |
| 82 | return mbtowc(__pwc, __pmb, __max); | |
| 83 | } | |
| 84 | ||
| 85 | inline _LIBCPP_INLINE_VISIBILITY | |
| 86 | size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) | |
| 87 | { | |
| 88 | __libcpp_locale_guard __current(__l); | |
| 89 | return mbrlen(__s, __n, __ps); | |
| 90 | } | |
| 91 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 92 | ||
| 93 | inline _LIBCPP_INLINE_VISIBILITY | |
| 94 | lconv *__libcpp_localeconv_l(locale_t __l) | |
| 95 | { | |
| 96 | __libcpp_locale_guard __current(__l); | |
| 97 | return localeconv(); | |
| 98 | } | |
| 99 | ||
| 100 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 101 | inline _LIBCPP_INLINE_VISIBILITY | |
| 102 | size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, | |
| 103 | mbstate_t *__ps, locale_t __l) | |
| 104 | { | |
| 105 | __libcpp_locale_guard __current(__l); | |
| 106 | return mbsrtowcs(__dest, __src, __len, __ps); | |
| 107 | } | |
| 108 | #endif | |
| 109 | ||
| 110 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) | |
| 111 | int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { | |
| 112 | va_list __va; | |
| 113 | va_start(__va, __format); | |
| 114 | __libcpp_locale_guard __current(__l); | |
| 115 | int __res = vsnprintf(__s, __n, __format, __va); | |
| 116 | va_end(__va); | |
| 117 | return __res; | |
| 118 | } | |
| 119 | ||
| 120 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 121 | int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { | |
| 122 | va_list __va; | |
| 123 | va_start(__va, __format); | |
| 124 | __libcpp_locale_guard __current(__l); | |
| 125 | int __res = vasprintf(__s, __format, __va); | |
| 126 | va_end(__va); | |
| 127 | return __res; | |
| 128 | } | |
| 129 | ||
| 130 | inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) | |
| 131 | int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { | |
| 132 | va_list __va; | |
| 133 | va_start(__va, __format); | |
| 134 | __libcpp_locale_guard __current(__l); | |
| 135 | int __res = vsscanf(__s, __format, __va); | |
| 136 | va_end(__va); | |
| 137 | return __res; | |
| 138 | } | |
| 139 | ||
| 140 | _LIBCPP_END_NAMESPACE_STD | |
| 141 | ||
| 142 | #endif // _LIBCPP___BSD_LOCALE_FALLBACKS_H |
lib/libcxx/include/__charconv/chars_format.h+16-29| ... | ... | @@ -19,58 +19,45 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 23 | ||
| 24 | enum class _LIBCPP_ENUM_VIS chars_format | |
| 25 | { | |
| 26 | scientific = 0x1, | |
| 27 | fixed = 0x2, | |
| 28 | hex = 0x4, | |
| 29 | general = fixed | scientific | |
| 30 | }; | |
| 31 | ||
| 32 | inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format | |
| 33 | operator~(chars_format __x) { | |
| 34 | return chars_format(~_VSTD::__to_underlying(__x)); | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | ||
| 24 | enum class _LIBCPP_ENUM_VIS chars_format { scientific = 0x1, fixed = 0x2, hex = 0x4, general = fixed | scientific }; | |
| 25 | ||
| 26 | inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator~(chars_format __x) { | |
| 27 | return chars_format(~std::__to_underlying(__x)); | |
| 35 | 28 | } |
| 36 | 29 | |
| 37 | inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format | |
| 38 | operator&(chars_format __x, chars_format __y) { | |
| 39 | return chars_format(_VSTD::__to_underlying(__x) & | |
| 40 | _VSTD::__to_underlying(__y)); | |
| 30 | inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator&(chars_format __x, chars_format __y) { | |
| 31 | return chars_format(std::__to_underlying(__x) & std::__to_underlying(__y)); | |
| 41 | 32 | } |
| 42 | 33 | |
| 43 | inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format | |
| 44 | operator|(chars_format __x, chars_format __y) { | |
| 45 | return chars_format(_VSTD::__to_underlying(__x) | | |
| 46 | _VSTD::__to_underlying(__y)); | |
| 34 | inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator|(chars_format __x, chars_format __y) { | |
| 35 | return chars_format(std::__to_underlying(__x) | std::__to_underlying(__y)); | |
| 47 | 36 | } |
| 48 | 37 | |
| 49 | inline _LIBCPP_INLINE_VISIBILITY constexpr chars_format | |
| 50 | operator^(chars_format __x, chars_format __y) { | |
| 51 | return chars_format(_VSTD::__to_underlying(__x) ^ | |
| 52 | _VSTD::__to_underlying(__y)); | |
| 38 | inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator^(chars_format __x, chars_format __y) { | |
| 39 | return chars_format(std::__to_underlying(__x) ^ std::__to_underlying(__y)); | |
| 53 | 40 | } |
| 54 | 41 | |
| 55 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 42 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 56 | 43 | operator&=(chars_format& __x, chars_format __y) { |
| 57 | 44 | __x = __x & __y; |
| 58 | 45 | return __x; |
| 59 | 46 | } |
| 60 | 47 | |
| 61 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 48 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 62 | 49 | operator|=(chars_format& __x, chars_format __y) { |
| 63 | 50 | __x = __x | __y; |
| 64 | 51 | return __x; |
| 65 | 52 | } |
| 66 | 53 | |
| 67 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 54 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& | |
| 68 | 55 | operator^=(chars_format& __x, chars_format __y) { |
| 69 | 56 | __x = __x ^ __y; |
| 70 | 57 | return __x; |
| 71 | 58 | } |
| 72 | 59 | |
| 73 | #endif // _LIBCPP_STD_VER > 14 | |
| 60 | #endif // _LIBCPP_STD_VER >= 17 | |
| 74 | 61 | |
| 75 | 62 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 63 |
lib/libcxx/include/__charconv/from_chars_integral.h created+239| ... | ... | @@ -0,0 +1,239 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H | |
| 11 | #define _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H | |
| 12 | ||
| 13 | #include <__algorithm/copy_n.h> | |
| 14 | #include <__charconv/from_chars_result.h> | |
| 15 | #include <__charconv/traits.h> | |
| 16 | #include <__config> | |
| 17 | #include <__memory/addressof.h> | |
| 18 | #include <__system_error/errc.h> | |
| 19 | #include <__type_traits/enable_if.h> | |
| 20 | #include <__type_traits/integral_constant.h> | |
| 21 | #include <__type_traits/is_integral.h> | |
| 22 | #include <__type_traits/is_unsigned.h> | |
| 23 | #include <__type_traits/make_unsigned.h> | |
| 24 | #include <limits> | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 27 | # pragma GCC system_header | |
| 28 | #endif | |
| 29 | ||
| 30 | _LIBCPP_PUSH_MACROS | |
| 31 | #include <__undef_macros> | |
| 32 | ||
| 33 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 34 | ||
| 35 | #if _LIBCPP_STD_VER >= 17 | |
| 36 | ||
| 37 | from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete; | |
| 38 | ||
| 39 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> | |
| 40 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 41 | __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) { | |
| 42 | using __tl = numeric_limits<_Tp>; | |
| 43 | decltype(std::__to_unsigned_like(__value)) __x; | |
| 44 | ||
| 45 | bool __neg = (__first != __last && *__first == '-'); | |
| 46 | auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...); | |
| 47 | switch (__r.ec) { | |
| 48 | case errc::invalid_argument: | |
| 49 | return {__first, __r.ec}; | |
| 50 | case errc::result_out_of_range: | |
| 51 | return __r; | |
| 52 | default: | |
| 53 | break; | |
| 54 | } | |
| 55 | ||
| 56 | if (__neg) { | |
| 57 | if (__x <= std::__complement(std::__to_unsigned_like(__tl::min()))) { | |
| 58 | __x = std::__complement(__x); | |
| 59 | std::copy_n(std::addressof(__x), 1, std::addressof(__value)); | |
| 60 | return __r; | |
| 61 | } | |
| 62 | } else { | |
| 63 | if (__x <= std::__to_unsigned_like(__tl::max())) { | |
| 64 | __value = __x; | |
| 65 | return __r; | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 69 | return {__r.ptr, errc::result_out_of_range}; | |
| 70 | } | |
| 71 | ||
| 72 | template <typename _Tp> | |
| 73 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __in_pattern(_Tp __c) { | |
| 74 | return '0' <= __c && __c <= '9'; | |
| 75 | } | |
| 76 | ||
| 77 | struct _LIBCPP_HIDDEN __in_pattern_result { | |
| 78 | bool __ok; | |
| 79 | int __val; | |
| 80 | ||
| 81 | explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; } | |
| 82 | }; | |
| 83 | ||
| 84 | template <typename _Tp> | |
| 85 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result __in_pattern(_Tp __c, int __base) { | |
| 86 | if (__base <= 10) | |
| 87 | return {'0' <= __c && __c < '0' + __base, __c - '0'}; | |
| 88 | else if (std::__in_pattern(__c)) | |
| 89 | return {true, __c - '0'}; | |
| 90 | else if ('a' <= __c && __c < 'a' + __base - 10) | |
| 91 | return {true, __c - 'a' + 10}; | |
| 92 | else | |
| 93 | return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; | |
| 94 | } | |
| 95 | ||
| 96 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> | |
| 97 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 98 | __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) { | |
| 99 | auto __find_non_zero = [](_It __firstit, _It __lastit) { | |
| 100 | for (; __firstit != __lastit; ++__firstit) | |
| 101 | if (*__firstit != '0') | |
| 102 | break; | |
| 103 | return __firstit; | |
| 104 | }; | |
| 105 | ||
| 106 | auto __p = __find_non_zero(__first, __last); | |
| 107 | if (__p == __last || !std::__in_pattern(*__p, __args...)) { | |
| 108 | if (__p == __first) | |
| 109 | return {__first, errc::invalid_argument}; | |
| 110 | else { | |
| 111 | __value = 0; | |
| 112 | return {__p, {}}; | |
| 113 | } | |
| 114 | } | |
| 115 | ||
| 116 | auto __r = __f(__p, __last, __value, __args...); | |
| 117 | if (__r.ec == errc::result_out_of_range) { | |
| 118 | for (; __r.ptr != __last; ++__r.ptr) { | |
| 119 | if (!std::__in_pattern(*__r.ptr, __args...)) | |
| 120 | break; | |
| 121 | } | |
| 122 | } | |
| 123 | ||
| 124 | return __r; | |
| 125 | } | |
| 126 | ||
| 127 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> | |
| 128 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 129 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) { | |
| 130 | using __tx = __itoa::__traits<_Tp>; | |
| 131 | using __output_type = typename __tx::type; | |
| 132 | ||
| 133 | return std::__subject_seq_combinator( | |
| 134 | __first, __last, __value, [](const char* __f, const char* __l, _Tp& __val) -> from_chars_result { | |
| 135 | __output_type __a, __b; | |
| 136 | auto __p = __tx::__read(__f, __l, __a, __b); | |
| 137 | if (__p == __l || !std::__in_pattern(*__p)) { | |
| 138 | __output_type __m = numeric_limits<_Tp>::max(); | |
| 139 | if (__m >= __a && __m - __a >= __b) { | |
| 140 | __val = __a + __b; | |
| 141 | return {__p, {}}; | |
| 142 | } | |
| 143 | } | |
| 144 | return {__p, errc::result_out_of_range}; | |
| 145 | }); | |
| 146 | } | |
| 147 | ||
| 148 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> | |
| 149 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 150 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) { | |
| 151 | using __t = decltype(std::__to_unsigned_like(__value)); | |
| 152 | return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); | |
| 153 | } | |
| 154 | ||
| 155 | /* | |
| 156 | // Code used to generate __from_chars_log2f_lut. | |
| 157 | #include <cmath> | |
| 158 | #include <format> | |
| 159 | #include <iostream> | |
| 160 | ||
| 161 | int main() { | |
| 162 | for (int i = 2; i <= 36; ++i) | |
| 163 | std::cout << std::format("{},\n", log2f(i)); | |
| 164 | } | |
| 165 | */ | |
| 166 | /// log2f table for bases [2, 36]. | |
| 167 | inline constexpr float __from_chars_log2f_lut[35] = { | |
| 168 | 1, 1.5849625, 2, 2.321928, 2.5849626, 2.807355, 3, 3.169925, 3.321928, | |
| 169 | 3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4, 4.087463, 4.169925, 4.2479277, | |
| 170 | 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355, | |
| 171 | 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925}; | |
| 172 | ||
| 173 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> | |
| 174 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 175 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) { | |
| 176 | if (__base == 10) | |
| 177 | return std::__from_chars_atoi(__first, __last, __value); | |
| 178 | ||
| 179 | return std::__subject_seq_combinator( | |
| 180 | __first, | |
| 181 | __last, | |
| 182 | __value, | |
| 183 | [](const char* __p, const char* __lastp, _Tp& __val, int __b) -> from_chars_result { | |
| 184 | using __tl = numeric_limits<_Tp>; | |
| 185 | // __base is always between 2 and 36 inclusive. | |
| 186 | auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2]; | |
| 187 | _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0; | |
| 188 | ||
| 189 | for (int __i = 1; __p != __lastp; ++__i, ++__p) { | |
| 190 | if (auto __c = __in_pattern(*__p, __b)) { | |
| 191 | if (__i < __digits - 1) | |
| 192 | __x = __x * __b + __c.__val; | |
| 193 | else { | |
| 194 | if (!__itoa::__mul_overflowed(__x, __b, __x)) | |
| 195 | ++__p; | |
| 196 | __y = __c.__val; | |
| 197 | break; | |
| 198 | } | |
| 199 | } else | |
| 200 | break; | |
| 201 | } | |
| 202 | ||
| 203 | if (__p == __lastp || !__in_pattern(*__p, __b)) { | |
| 204 | if (__tl::max() - __x >= __y) { | |
| 205 | __val = __x + __y; | |
| 206 | return {__p, {}}; | |
| 207 | } | |
| 208 | } | |
| 209 | return {__p, errc::result_out_of_range}; | |
| 210 | }, | |
| 211 | __base); | |
| 212 | } | |
| 213 | ||
| 214 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> | |
| 215 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 216 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) { | |
| 217 | using __t = decltype(std::__to_unsigned_like(__value)); | |
| 218 | return std::__sign_combinator(__first, __last, __value, __from_chars_integral<__t>, __base); | |
| 219 | } | |
| 220 | ||
| 221 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 222 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 223 | from_chars(const char* __first, const char* __last, _Tp& __value) { | |
| 224 | return std::__from_chars_atoi(__first, __last, __value); | |
| 225 | } | |
| 226 | ||
| 227 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 228 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 229 | from_chars(const char* __first, const char* __last, _Tp& __value, int __base) { | |
| 230 | _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]"); | |
| 231 | return std::__from_chars_integral(__first, __last, __value, __base); | |
| 232 | } | |
| 233 | #endif // _LIBCPP_STD_VER >= 17 | |
| 234 | ||
| 235 | _LIBCPP_END_NAMESPACE_STD | |
| 236 | ||
| 237 | _LIBCPP_POP_MACROS | |
| 238 | ||
| 239 | #endif // _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H |
lib/libcxx/include/__charconv/from_chars_result.h+8-9| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__errc> | |
| 14 | #include <__system_error/errc.h> | |
| 15 | 15 | |
| 16 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 17 | # pragma GCC system_header |
| ... | ... | @@ -19,18 +19,17 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | |
| 24 | struct _LIBCPP_TYPE_VIS from_chars_result | |
| 25 | { | |
| 26 | const char* ptr; | |
| 27 | errc ec; | |
| 28 | # if _LIBCPP_STD_VER > 17 | |
| 29 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; | |
| 24 | struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result { | |
| 25 | const char* ptr; | |
| 26 | errc ec; | |
| 27 | # if _LIBCPP_STD_VER >= 20 | |
| 28 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; | |
| 30 | 29 | # endif |
| 31 | 30 | }; |
| 32 | 31 | |
| 33 | #endif // _LIBCPP_STD_VER > 14 | |
| 32 | #endif // _LIBCPP_STD_VER >= 17 | |
| 34 | 33 | |
| 35 | 34 | _LIBCPP_END_NAMESPACE_STD |
| 36 | 35 |
lib/libcxx/include/__charconv/tables.h+35-26| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | |
| 24 | 24 | namespace __itoa { |
| 25 | 25 | |
| ... | ... | @@ -62,32 +62,41 @@ inline constexpr char __base_16_lut[512] = { |
| 62 | 62 | 'f', 'd', 'f', 'e', 'f', 'f'}; |
| 63 | 63 | |
| 64 | 64 | inline constexpr uint32_t __pow10_32[10] = { |
| 65 | UINT32_C(0), UINT32_C(10), UINT32_C(100), UINT32_C(1000), UINT32_C(10000), | |
| 66 | UINT32_C(100000), UINT32_C(1000000), UINT32_C(10000000), UINT32_C(100000000), UINT32_C(1000000000)}; | |
| 67 | ||
| 68 | inline constexpr uint64_t __pow10_64[20] = {UINT64_C(0), | |
| 69 | UINT64_C(10), | |
| 70 | UINT64_C(100), | |
| 71 | UINT64_C(1000), | |
| 72 | UINT64_C(10000), | |
| 73 | UINT64_C(100000), | |
| 74 | UINT64_C(1000000), | |
| 75 | UINT64_C(10000000), | |
| 76 | UINT64_C(100000000), | |
| 77 | UINT64_C(1000000000), | |
| 78 | UINT64_C(10000000000), | |
| 79 | UINT64_C(100000000000), | |
| 80 | UINT64_C(1000000000000), | |
| 81 | UINT64_C(10000000000000), | |
| 82 | UINT64_C(100000000000000), | |
| 83 | UINT64_C(1000000000000000), | |
| 84 | UINT64_C(10000000000000000), | |
| 85 | UINT64_C(100000000000000000), | |
| 86 | UINT64_C(1000000000000000000), | |
| 87 | UINT64_C(10000000000000000000)}; | |
| 65 | UINT32_C(0), | |
| 66 | UINT32_C(10), | |
| 67 | UINT32_C(100), | |
| 68 | UINT32_C(1000), | |
| 69 | UINT32_C(10000), | |
| 70 | UINT32_C(100000), | |
| 71 | UINT32_C(1000000), | |
| 72 | UINT32_C(10000000), | |
| 73 | UINT32_C(100000000), | |
| 74 | UINT32_C(1000000000)}; | |
| 75 | ||
| 76 | inline constexpr uint64_t __pow10_64[20] = { | |
| 77 | UINT64_C(0), | |
| 78 | UINT64_C(10), | |
| 79 | UINT64_C(100), | |
| 80 | UINT64_C(1000), | |
| 81 | UINT64_C(10000), | |
| 82 | UINT64_C(100000), | |
| 83 | UINT64_C(1000000), | |
| 84 | UINT64_C(10000000), | |
| 85 | UINT64_C(100000000), | |
| 86 | UINT64_C(1000000000), | |
| 87 | UINT64_C(10000000000), | |
| 88 | UINT64_C(100000000000), | |
| 89 | UINT64_C(1000000000000), | |
| 90 | UINT64_C(10000000000000), | |
| 91 | UINT64_C(100000000000000), | |
| 92 | UINT64_C(1000000000000000), | |
| 93 | UINT64_C(10000000000000000), | |
| 94 | UINT64_C(100000000000000000), | |
| 95 | UINT64_C(1000000000000000000), | |
| 96 | UINT64_C(10000000000000000000)}; | |
| 88 | 97 | |
| 89 | 98 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 90 | inline constexpr int __pow10_128_offset = 0; | |
| 99 | inline constexpr int __pow10_128_offset = 0; | |
| 91 | 100 | inline constexpr __uint128_t __pow10_128[40] = { |
| 92 | 101 | UINT64_C(0), |
| 93 | 102 | UINT64_C(10), |
| ... | ... | @@ -147,7 +156,7 @@ inline constexpr char __digits_base_10[200] = { |
| 147 | 156 | |
| 148 | 157 | } // namespace __itoa |
| 149 | 158 | |
| 150 | #endif // _LIBCPP_STD_VER > 14 | |
| 159 | #endif // _LIBCPP_STD_VER >= 17 | |
| 151 | 160 | |
| 152 | 161 | _LIBCPP_END_NAMESPACE_STD |
| 153 | 162 |
lib/libcxx/include/__charconv/to_chars.h created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHARCONV_TO_CHARS | |
| 11 | #define _LIBCPP___CHARCONV_TO_CHARS | |
| 12 | ||
| 13 | #include <__charconv/to_chars_floating_point.h> | |
| 14 | #include <__charconv/to_chars_integral.h> | |
| 15 | #include <__config> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | _LIBCPP_END_NAMESPACE_STD | |
| 24 | ||
| 25 | #endif // _LIBCPP___CHARCONV_TO_CHARS |
lib/libcxx/include/__charconv/to_chars_base_10.h+11-9| ... | ... | @@ -25,7 +25,7 @@ _LIBCPP_PUSH_MACROS |
| 25 | 25 | |
| 26 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 28 | #if _LIBCPP_STD_VER >= 17 | |
| 29 | 29 | |
| 30 | 30 | namespace __itoa { |
| 31 | 31 | |
| ... | ... | @@ -72,7 +72,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __append10(char* __fir |
| 72 | 72 | static_cast<uint32_t>(__value % 100000000)); |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(char* __first, uint32_t __value) noexcept { | |
| 75 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* | |
| 76 | __base_10_u32(char* __first, uint32_t __value) noexcept { | |
| 76 | 77 | if (__value < 1000000) { |
| 77 | 78 | if (__value < 10000) { |
| 78 | 79 | if (__value < 100) { |
| ... | ... | @@ -107,7 +108,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u32(c |
| 107 | 108 | return __itoa::__append10(__first, __value); |
| 108 | 109 | } |
| 109 | 110 | |
| 110 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(char* __buffer, uint64_t __value) noexcept { | |
| 111 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* | |
| 112 | __base_10_u64(char* __buffer, uint64_t __value) noexcept { | |
| 111 | 113 | if (__value <= UINT32_MAX) |
| 112 | 114 | return __itoa::__base_10_u32(__buffer, static_cast<uint32_t>(__value)); |
| 113 | 115 | |
| ... | ... | @@ -130,12 +132,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u64(c |
| 130 | 132 | /// range that can be used. However the range is sufficient for |
| 131 | 133 | /// \ref __base_10_u128. |
| 132 | 134 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept { |
| 133 | _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds"); | |
| 135 | _LIBCPP_ASSERT_UNCATEGORIZED(__exp >= __pow10_128_offset, "Index out of bounds"); | |
| 134 | 136 | return __pow10_128[__exp - __pow10_128_offset]; |
| 135 | 137 | } |
| 136 | 138 | |
| 137 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept { | |
| 138 | _LIBCPP_ASSERT( | |
| 139 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* | |
| 140 | __base_10_u128(char* __buffer, __uint128_t __value) noexcept { | |
| 141 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 139 | 142 | __value > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true."); |
| 140 | 143 | |
| 141 | 144 | // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be |
| ... | ... | @@ -159,8 +162,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128( |
| 159 | 162 | __value %= __itoa::__pow_10(29); |
| 160 | 163 | __buffer = __itoa::__append10(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19))); |
| 161 | 164 | __value %= __itoa::__pow_10(19); |
| 162 | } | |
| 163 | else { | |
| 165 | } else { | |
| 164 | 166 | // step 2 |
| 165 | 167 | // This version needs to determine the position of the leading non-zero digit. |
| 166 | 168 | __buffer = __base_10_u64(__buffer, static_cast<uint64_t>(__value / __itoa::__pow_10(19))); |
| ... | ... | @@ -176,7 +178,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128( |
| 176 | 178 | # endif |
| 177 | 179 | } // namespace __itoa |
| 178 | 180 | |
| 179 | #endif // _LIBCPP_STD_VER > 14 | |
| 181 | #endif // _LIBCPP_STD_VER >= 17 | |
| 180 | 182 | |
| 181 | 183 | _LIBCPP_END_NAMESPACE_STD |
| 182 | 184 |
lib/libcxx/include/__charconv/to_chars_floating_point.h created+56| ... | ... | @@ -0,0 +1,56 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H | |
| 11 | #define _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H | |
| 12 | ||
| 13 | #include <__availability> | |
| 14 | #include <__charconv/chars_format.h> | |
| 15 | #include <__charconv/to_chars_result.h> | |
| 16 | #include <__config> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | ||
| 26 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 27 | to_chars(char* __first, char* __last, float __value); | |
| 28 | ||
| 29 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 30 | to_chars(char* __first, char* __last, double __value); | |
| 31 | ||
| 32 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 33 | to_chars(char* __first, char* __last, long double __value); | |
| 34 | ||
| 35 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 36 | to_chars(char* __first, char* __last, float __value, chars_format __fmt); | |
| 37 | ||
| 38 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 39 | to_chars(char* __first, char* __last, double __value, chars_format __fmt); | |
| 40 | ||
| 41 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 42 | to_chars(char* __first, char* __last, long double __value, chars_format __fmt); | |
| 43 | ||
| 44 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 45 | to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision); | |
| 46 | ||
| 47 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 48 | to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision); | |
| 49 | ||
| 50 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result | |
| 51 | to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision); | |
| 52 | #endif // _LIBCPP_STD_VER >= 17 | |
| 53 | ||
| 54 | _LIBCPP_END_NAMESPACE_STD | |
| 55 | ||
| 56 | #endif // _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H |
lib/libcxx/include/__charconv/to_chars_integral.h created+326| ... | ... | @@ -0,0 +1,326 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H | |
| 11 | #define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H | |
| 12 | ||
| 13 | #include <__algorithm/copy_n.h> | |
| 14 | #include <__bit/countl.h> | |
| 15 | #include <__charconv/tables.h> | |
| 16 | #include <__charconv/to_chars_base_10.h> | |
| 17 | #include <__charconv/to_chars_result.h> | |
| 18 | #include <__charconv/traits.h> | |
| 19 | #include <__config> | |
| 20 | #include <__system_error/errc.h> | |
| 21 | #include <__type_traits/enable_if.h> | |
| 22 | #include <__type_traits/integral_constant.h> | |
| 23 | #include <__type_traits/is_same.h> | |
| 24 | #include <__type_traits/make_32_64_or_128_bit.h> | |
| 25 | #include <__type_traits/make_unsigned.h> | |
| 26 | #include <__utility/unreachable.h> | |
| 27 | #include <cstddef> | |
| 28 | #include <cstdint> | |
| 29 | #include <limits> | |
| 30 | ||
| 31 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 32 | # pragma GCC system_header | |
| 33 | #endif | |
| 34 | ||
| 35 | _LIBCPP_PUSH_MACROS | |
| 36 | #include <__undef_macros> | |
| 37 | ||
| 38 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 39 | ||
| 40 | #if _LIBCPP_STD_VER >= 17 | |
| 41 | ||
| 42 | to_chars_result to_chars(char*, char*, bool, int = 10) = delete; | |
| 43 | ||
| 44 | template <typename _Tp> | |
| 45 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 46 | __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type); | |
| 47 | ||
| 48 | template <typename _Tp> | |
| 49 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 50 | __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) { | |
| 51 | auto __x = std::__to_unsigned_like(__value); | |
| 52 | if (__value < 0 && __first != __last) { | |
| 53 | *__first++ = '-'; | |
| 54 | __x = std::__complement(__x); | |
| 55 | } | |
| 56 | ||
| 57 | return std::__to_chars_itoa(__first, __last, __x, false_type()); | |
| 58 | } | |
| 59 | ||
| 60 | template <typename _Tp> | |
| 61 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 62 | __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) { | |
| 63 | using __tx = __itoa::__traits<_Tp>; | |
| 64 | auto __diff = __last - __first; | |
| 65 | ||
| 66 | if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) | |
| 67 | return {__tx::__convert(__first, __value), errc(0)}; | |
| 68 | else | |
| 69 | return {__last, errc::value_too_large}; | |
| 70 | } | |
| 71 | ||
| 72 | # ifndef _LIBCPP_HAS_NO_INT128 | |
| 73 | template <> | |
| 74 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 75 | __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) { | |
| 76 | // When the value fits in 64-bits use the 64-bit code path. This reduces | |
| 77 | // the number of expensive calculations on 128-bit values. | |
| 78 | // | |
| 79 | // NOTE the 128-bit code path requires this optimization. | |
| 80 | if (__value <= numeric_limits<uint64_t>::max()) | |
| 81 | return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type()); | |
| 82 | ||
| 83 | using __tx = __itoa::__traits<__uint128_t>; | |
| 84 | auto __diff = __last - __first; | |
| 85 | ||
| 86 | if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) | |
| 87 | return {__tx::__convert(__first, __value), errc(0)}; | |
| 88 | else | |
| 89 | return {__last, errc::value_too_large}; | |
| 90 | } | |
| 91 | # endif | |
| 92 | ||
| 93 | template <class _Tp> | |
| 94 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 95 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type); | |
| 96 | ||
| 97 | template <typename _Tp> | |
| 98 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 99 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, true_type) { | |
| 100 | auto __x = std::__to_unsigned_like(__value); | |
| 101 | if (__value < 0 && __first != __last) { | |
| 102 | *__first++ = '-'; | |
| 103 | __x = std::__complement(__x); | |
| 104 | } | |
| 105 | ||
| 106 | return std::__to_chars_integral(__first, __last, __x, __base, false_type()); | |
| 107 | } | |
| 108 | ||
| 109 | namespace __itoa { | |
| 110 | ||
| 111 | template <unsigned _Base> | |
| 112 | struct _LIBCPP_HIDDEN __integral; | |
| 113 | ||
| 114 | template <> | |
| 115 | struct _LIBCPP_HIDDEN __integral<2> { | |
| 116 | template <typename _Tp> | |
| 117 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 118 | // If value == 0 still need one digit. If the value != this has no | |
| 119 | // effect since the code scans for the most significant bit set. (Note | |
| 120 | // that __libcpp_clz doesn't work for 0.) | |
| 121 | return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1); | |
| 122 | } | |
| 123 | ||
| 124 | template <typename _Tp> | |
| 125 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result | |
| 126 | __to_chars(char* __first, char* __last, _Tp __value) { | |
| 127 | ptrdiff_t __cap = __last - __first; | |
| 128 | int __n = __width(__value); | |
| 129 | if (__n > __cap) | |
| 130 | return {__last, errc::value_too_large}; | |
| 131 | ||
| 132 | __last = __first + __n; | |
| 133 | char* __p = __last; | |
| 134 | const unsigned __divisor = 16; | |
| 135 | while (__value > __divisor) { | |
| 136 | unsigned __c = __value % __divisor; | |
| 137 | __value /= __divisor; | |
| 138 | __p -= 4; | |
| 139 | std::copy_n(&__base_2_lut[4 * __c], 4, __p); | |
| 140 | } | |
| 141 | do { | |
| 142 | unsigned __c = __value % 2; | |
| 143 | __value /= 2; | |
| 144 | *--__p = "01"[__c]; | |
| 145 | } while (__value != 0); | |
| 146 | return {__last, errc(0)}; | |
| 147 | } | |
| 148 | }; | |
| 149 | ||
| 150 | template <> | |
| 151 | struct _LIBCPP_HIDDEN __integral<8> { | |
| 152 | template <typename _Tp> | |
| 153 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 154 | // If value == 0 still need one digit. If the value != this has no | |
| 155 | // effect since the code scans for the most significat bit set. (Note | |
| 156 | // that __libcpp_clz doesn't work for 0.) | |
| 157 | return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3; | |
| 158 | } | |
| 159 | ||
| 160 | template <typename _Tp> | |
| 161 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result | |
| 162 | __to_chars(char* __first, char* __last, _Tp __value) { | |
| 163 | ptrdiff_t __cap = __last - __first; | |
| 164 | int __n = __width(__value); | |
| 165 | if (__n > __cap) | |
| 166 | return {__last, errc::value_too_large}; | |
| 167 | ||
| 168 | __last = __first + __n; | |
| 169 | char* __p = __last; | |
| 170 | unsigned __divisor = 64; | |
| 171 | while (__value > __divisor) { | |
| 172 | unsigned __c = __value % __divisor; | |
| 173 | __value /= __divisor; | |
| 174 | __p -= 2; | |
| 175 | std::copy_n(&__base_8_lut[2 * __c], 2, __p); | |
| 176 | } | |
| 177 | do { | |
| 178 | unsigned __c = __value % 8; | |
| 179 | __value /= 8; | |
| 180 | *--__p = "01234567"[__c]; | |
| 181 | } while (__value != 0); | |
| 182 | return {__last, errc(0)}; | |
| 183 | } | |
| 184 | }; | |
| 185 | ||
| 186 | template <> | |
| 187 | struct _LIBCPP_HIDDEN __integral<16> { | |
| 188 | template <typename _Tp> | |
| 189 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 190 | // If value == 0 still need one digit. If the value != this has no | |
| 191 | // effect since the code scans for the most significat bit set. (Note | |
| 192 | // that __libcpp_clz doesn't work for 0.) | |
| 193 | return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4; | |
| 194 | } | |
| 195 | ||
| 196 | template <typename _Tp> | |
| 197 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result | |
| 198 | __to_chars(char* __first, char* __last, _Tp __value) { | |
| 199 | ptrdiff_t __cap = __last - __first; | |
| 200 | int __n = __width(__value); | |
| 201 | if (__n > __cap) | |
| 202 | return {__last, errc::value_too_large}; | |
| 203 | ||
| 204 | __last = __first + __n; | |
| 205 | char* __p = __last; | |
| 206 | unsigned __divisor = 256; | |
| 207 | while (__value > __divisor) { | |
| 208 | unsigned __c = __value % __divisor; | |
| 209 | __value /= __divisor; | |
| 210 | __p -= 2; | |
| 211 | std::copy_n(&__base_16_lut[2 * __c], 2, __p); | |
| 212 | } | |
| 213 | if (__first != __last) | |
| 214 | do { | |
| 215 | unsigned __c = __value % 16; | |
| 216 | __value /= 16; | |
| 217 | *--__p = "0123456789abcdef"[__c]; | |
| 218 | } while (__value != 0); | |
| 219 | return {__last, errc(0)}; | |
| 220 | } | |
| 221 | }; | |
| 222 | ||
| 223 | } // namespace __itoa | |
| 224 | ||
| 225 | template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> | |
| 226 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { | |
| 227 | return __itoa::__integral<_Base>::__width(__value); | |
| 228 | } | |
| 229 | ||
| 230 | template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> | |
| 231 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { | |
| 232 | return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value)); | |
| 233 | } | |
| 234 | ||
| 235 | template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> | |
| 236 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 237 | __to_chars_integral(char* __first, char* __last, _Tp __value) { | |
| 238 | return __itoa::__integral<_Base>::__to_chars(__first, __last, __value); | |
| 239 | } | |
| 240 | ||
| 241 | template <unsigned _Base, typename _Tp, typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> | |
| 242 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 243 | __to_chars_integral(char* __first, char* __last, _Tp __value) { | |
| 244 | return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value)); | |
| 245 | } | |
| 246 | ||
| 247 | template <typename _Tp> | |
| 248 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) { | |
| 249 | _LIBCPP_ASSERT_UNCATEGORIZED(__value >= 0, "The function requires a non-negative value."); | |
| 250 | ||
| 251 | unsigned __base_2 = __base * __base; | |
| 252 | unsigned __base_3 = __base_2 * __base; | |
| 253 | unsigned __base_4 = __base_2 * __base_2; | |
| 254 | ||
| 255 | int __r = 0; | |
| 256 | while (true) { | |
| 257 | if (__value < __base) | |
| 258 | return __r + 1; | |
| 259 | if (__value < __base_2) | |
| 260 | return __r + 2; | |
| 261 | if (__value < __base_3) | |
| 262 | return __r + 3; | |
| 263 | if (__value < __base_4) | |
| 264 | return __r + 4; | |
| 265 | ||
| 266 | __value /= __base_4; | |
| 267 | __r += 4; | |
| 268 | } | |
| 269 | ||
| 270 | __libcpp_unreachable(); | |
| 271 | } | |
| 272 | ||
| 273 | template <typename _Tp> | |
| 274 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 275 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type) { | |
| 276 | if (__base == 10) [[likely]] | |
| 277 | return std::__to_chars_itoa(__first, __last, __value, false_type()); | |
| 278 | ||
| 279 | switch (__base) { | |
| 280 | case 2: | |
| 281 | return std::__to_chars_integral<2>(__first, __last, __value); | |
| 282 | case 8: | |
| 283 | return std::__to_chars_integral<8>(__first, __last, __value); | |
| 284 | case 16: | |
| 285 | return std::__to_chars_integral<16>(__first, __last, __value); | |
| 286 | } | |
| 287 | ||
| 288 | ptrdiff_t __cap = __last - __first; | |
| 289 | int __n = std::__to_chars_integral_width(__value, __base); | |
| 290 | if (__n > __cap) | |
| 291 | return {__last, errc::value_too_large}; | |
| 292 | ||
| 293 | __last = __first + __n; | |
| 294 | char* __p = __last; | |
| 295 | do { | |
| 296 | unsigned __c = __value % __base; | |
| 297 | __value /= __base; | |
| 298 | *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c]; | |
| 299 | } while (__value != 0); | |
| 300 | return {__last, errc(0)}; | |
| 301 | } | |
| 302 | ||
| 303 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 304 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 305 | to_chars(char* __first, char* __last, _Tp __value) { | |
| 306 | using _Type = __make_32_64_or_128_bit_t<_Tp>; | |
| 307 | static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars"); | |
| 308 | return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>()); | |
| 309 | } | |
| 310 | ||
| 311 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 312 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 313 | to_chars(char* __first, char* __last, _Tp __value, int __base) { | |
| 314 | _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]"); | |
| 315 | ||
| 316 | using _Type = __make_32_64_or_128_bit_t<_Tp>; | |
| 317 | return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>()); | |
| 318 | } | |
| 319 | ||
| 320 | #endif // _LIBCPP_STD_VER >= 17 | |
| 321 | ||
| 322 | _LIBCPP_END_NAMESPACE_STD | |
| 323 | ||
| 324 | _LIBCPP_POP_MACROS | |
| 325 | ||
| 326 | #endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H |
lib/libcxx/include/__charconv/to_chars_result.h+8-9| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__errc> | |
| 14 | #include <__system_error/errc.h> | |
| 15 | 15 | |
| 16 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 17 | # pragma GCC system_header |
| ... | ... | @@ -19,18 +19,17 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | |
| 24 | struct _LIBCPP_TYPE_VIS to_chars_result | |
| 25 | { | |
| 26 | char* ptr; | |
| 27 | errc ec; | |
| 28 | # if _LIBCPP_STD_VER > 17 | |
| 29 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; | |
| 24 | struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result { | |
| 25 | char* ptr; | |
| 26 | errc ec; | |
| 27 | # if _LIBCPP_STD_VER >= 20 | |
| 28 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; | |
| 30 | 29 | # endif |
| 31 | 30 | }; |
| 32 | 31 | |
| 33 | #endif // _LIBCPP_STD_VER > 14 | |
| 32 | #endif // _LIBCPP_STD_VER >= 17 | |
| 34 | 33 | |
| 35 | 34 | _LIBCPP_END_NAMESPACE_STD |
| 36 | 35 |
lib/libcxx/include/__charconv/traits.h created+199| ... | ... | @@ -0,0 +1,199 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHARCONV_TRAITS | |
| 11 | #define _LIBCPP___CHARCONV_TRAITS | |
| 12 | ||
| 13 | #include <__bit/countl.h> | |
| 14 | #include <__charconv/tables.h> | |
| 15 | #include <__charconv/to_chars_base_10.h> | |
| 16 | #include <__config> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_unsigned.h> | |
| 19 | #include <cstdint> | |
| 20 | #include <limits> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | #if _LIBCPP_STD_VER >= 17 | |
| 32 | ||
| 33 | namespace __itoa { | |
| 34 | ||
| 35 | template <typename _Tp, typename = void> | |
| 36 | struct _LIBCPP_HIDDEN __traits_base; | |
| 37 | ||
| 38 | template <typename _Tp> | |
| 39 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> { | |
| 40 | using type = uint32_t; | |
| 41 | ||
| 42 | /// The width estimation using a log10 algorithm. | |
| 43 | /// | |
| 44 | /// The algorithm is based on | |
| 45 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 46 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 47 | /// function requires its input to have at least one bit set the value of | |
| 48 | /// zero is set to one. This means the first element of the lookup table is | |
| 49 | /// zero. | |
| 50 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { | |
| 51 | auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; | |
| 52 | return __t - (__v < __itoa::__pow10_32[__t]) + 1; | |
| 53 | } | |
| 54 | ||
| 55 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { | |
| 56 | return __itoa::__base_10_u32(__p, __v); | |
| 57 | } | |
| 58 | ||
| 59 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { | |
| 60 | return __itoa::__pow10_32; | |
| 61 | } | |
| 62 | }; | |
| 63 | ||
| 64 | template <typename _Tp> | |
| 65 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> { | |
| 66 | using type = uint64_t; | |
| 67 | ||
| 68 | /// The width estimation using a log10 algorithm. | |
| 69 | /// | |
| 70 | /// The algorithm is based on | |
| 71 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 72 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 73 | /// function requires its input to have at least one bit set the value of | |
| 74 | /// zero is set to one. This means the first element of the lookup table is | |
| 75 | /// zero. | |
| 76 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { | |
| 77 | auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; | |
| 78 | return __t - (__v < __itoa::__pow10_64[__t]) + 1; | |
| 79 | } | |
| 80 | ||
| 81 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { | |
| 82 | return __itoa::__base_10_u64(__p, __v); | |
| 83 | } | |
| 84 | ||
| 85 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { | |
| 86 | return __itoa::__pow10_64; | |
| 87 | } | |
| 88 | }; | |
| 89 | ||
| 90 | # ifndef _LIBCPP_HAS_NO_INT128 | |
| 91 | template <typename _Tp> | |
| 92 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > { | |
| 93 | using type = __uint128_t; | |
| 94 | ||
| 95 | /// The width estimation using a log10 algorithm. | |
| 96 | /// | |
| 97 | /// The algorithm is based on | |
| 98 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 99 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 100 | /// function requires its input to have at least one bit set the value of | |
| 101 | /// zero is set to one. This means the first element of the lookup table is | |
| 102 | /// zero. | |
| 103 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { | |
| 104 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 105 | __v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true."); | |
| 106 | // There's always a bit set in the upper 64-bits. | |
| 107 | auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12; | |
| 108 | _LIBCPP_ASSERT_UNCATEGORIZED(__t >= __itoa::__pow10_128_offset, "Index out of bounds"); | |
| 109 | // __t is adjusted since the lookup table misses the lower entries. | |
| 110 | return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1; | |
| 111 | } | |
| 112 | ||
| 113 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { | |
| 114 | return __itoa::__base_10_u128(__p, __v); | |
| 115 | } | |
| 116 | ||
| 117 | // TODO FMT This pow function should get an index. | |
| 118 | // By moving this to its own header it can be reused by the pow function in to_chars_base_10. | |
| 119 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { | |
| 120 | return __itoa::__pow10_128; | |
| 121 | } | |
| 122 | }; | |
| 123 | # endif | |
| 124 | ||
| 125 | template <typename _Tp> | |
| 126 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 127 | __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) { | |
| 128 | auto __c = __a * __b; | |
| 129 | __r = __c; | |
| 130 | return __c > numeric_limits<unsigned char>::max(); | |
| 131 | } | |
| 132 | ||
| 133 | template <typename _Tp> | |
| 134 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 135 | __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) { | |
| 136 | auto __c = __a * __b; | |
| 137 | __r = __c; | |
| 138 | return __c > numeric_limits<unsigned short>::max(); | |
| 139 | } | |
| 140 | ||
| 141 | template <typename _Tp> | |
| 142 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) { | |
| 143 | static_assert(is_unsigned<_Tp>::value, ""); | |
| 144 | return __builtin_mul_overflow(__a, __b, &__r); | |
| 145 | } | |
| 146 | ||
| 147 | template <typename _Tp, typename _Up> | |
| 148 | inline _LIBCPP_HIDE_FROM_ABI bool _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) { | |
| 149 | return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r); | |
| 150 | } | |
| 151 | ||
| 152 | template <typename _Tp> | |
| 153 | struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> { | |
| 154 | static constexpr int digits = numeric_limits<_Tp>::digits10 + 1; | |
| 155 | using __traits_base<_Tp>::__pow; | |
| 156 | using typename __traits_base<_Tp>::type; | |
| 157 | ||
| 158 | // precondition: at least one non-zero character available | |
| 159 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const* | |
| 160 | __read(char const* __p, char const* __ep, type& __a, type& __b) { | |
| 161 | type __cprod[digits]; | |
| 162 | int __j = digits - 1; | |
| 163 | int __i = digits; | |
| 164 | do { | |
| 165 | if (*__p < '0' || *__p > '9') | |
| 166 | break; | |
| 167 | __cprod[--__i] = *__p++ - '0'; | |
| 168 | } while (__p != __ep && __i != 0); | |
| 169 | ||
| 170 | __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, __cprod[__i]); | |
| 171 | if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) | |
| 172 | --__p; | |
| 173 | return __p; | |
| 174 | } | |
| 175 | ||
| 176 | template <typename _It1, typename _It2, class _Up> | |
| 177 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up | |
| 178 | __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) { | |
| 179 | for (; __first1 < __last1; ++__first1, ++__first2) | |
| 180 | __init = __init + *__first1 * *__first2; | |
| 181 | return __init; | |
| 182 | } | |
| 183 | }; | |
| 184 | ||
| 185 | } // namespace __itoa | |
| 186 | ||
| 187 | template <typename _Tp> | |
| 188 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp __complement(_Tp __x) { | |
| 189 | static_assert(is_unsigned<_Tp>::value, "cast to unsigned first"); | |
| 190 | return _Tp(~__x + 1); | |
| 191 | } | |
| 192 | ||
| 193 | #endif // _LIBCPP_STD_VER >= 17 | |
| 194 | ||
| 195 | _LIBCPP_END_NAMESPACE_STD | |
| 196 | ||
| 197 | _LIBCPP_POP_MACROS | |
| 198 | ||
| 199 | #endif // _LIBCPP___CHARCONV_TRAITS |
lib/libcxx/include/__chrono/calendar.h+5-5| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -26,12 +26,12 @@ namespace chrono |
| 26 | 26 | { |
| 27 | 27 | |
| 28 | 28 | struct local_t {}; |
| 29 | template<class Duration> | |
| 30 | using local_time = time_point<local_t, Duration>; | |
| 29 | template<class _Duration> | |
| 30 | using local_time = time_point<local_t, _Duration>; | |
| 31 | 31 | using local_seconds = local_time<seconds>; |
| 32 | 32 | using local_days = local_time<days>; |
| 33 | 33 | |
| 34 | struct last_spec { _LIBCPP_HIDE_FROM_ABI explicit last_spec() = default; }; | |
| 34 | struct last_spec { explicit last_spec() = default; }; | |
| 35 | 35 | inline constexpr last_spec last{}; |
| 36 | 36 | |
| 37 | 37 | |
| ... | ... | @@ -39,6 +39,6 @@ inline constexpr last_spec last{}; |
| 39 | 39 | |
| 40 | 40 | _LIBCPP_END_NAMESPACE_STD |
| 41 | 41 | |
| 42 | #endif // _LIBCPP_STD_VER > 17 | |
| 42 | #endif // _LIBCPP_STD_VER >= 20 | |
| 43 | 43 | |
| 44 | 44 | #endif // _LIBCPP___CHRONO_CALENDAR_H |
lib/libcxx/include/__chrono/concepts.h created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___CHRONO_CONCEPTS_H | |
| 11 | #define _LIBCPP___CHRONO_CONCEPTS_H | |
| 12 | ||
| 13 | #include <__chrono/hh_mm_ss.h> | |
| 14 | #include <__chrono/time_point.h> | |
| 15 | #include <__config> | |
| 16 | #include <__type_traits/is_specialization.h> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | ||
| 26 | template <class _Tp> | |
| 27 | concept __is_hh_mm_ss = __is_specialization_v<_Tp, chrono::hh_mm_ss>; | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | concept __is_time_point = __is_specialization_v<_Tp, chrono::time_point>; | |
| 31 | ||
| 32 | #endif // _LIBCPP_STD_VER >= 20 | |
| 33 | ||
| 34 | _LIBCPP_END_NAMESPACE_STD | |
| 35 | ||
| 36 | #endif // _LIBCPP___CHRONO_CONCEPTS_H |
lib/libcxx/include/__chrono/convert_to_tm.h+68-9| ... | ... | @@ -10,8 +10,11 @@ |
| 10 | 10 | #ifndef _LIBCPP___CHRONO_CONVERT_TO_TM_H |
| 11 | 11 | #define _LIBCPP___CHRONO_CONVERT_TO_TM_H |
| 12 | 12 | |
| 13 | #include <__chrono/calendar.h> | |
| 14 | #include <__chrono/concepts.h> | |
| 13 | 15 | #include <__chrono/day.h> |
| 14 | 16 | #include <__chrono/duration.h> |
| 17 | #include <__chrono/file_clock.h> | |
| 15 | 18 | #include <__chrono/hh_mm_ss.h> |
| 16 | 19 | #include <__chrono/month.h> |
| 17 | 20 | #include <__chrono/month_weekday.h> |
| ... | ... | @@ -26,17 +29,23 @@ |
| 26 | 29 | #include <__chrono/year_month_weekday.h> |
| 27 | 30 | #include <__concepts/same_as.h> |
| 28 | 31 | #include <__config> |
| 32 | #include <__format/format_error.h> | |
| 29 | 33 | #include <__memory/addressof.h> |
| 34 | #include <__type_traits/is_convertible.h> | |
| 30 | 35 | #include <cstdint> |
| 31 | 36 | #include <ctime> |
| 37 | #include <limits> | |
| 32 | 38 | |
| 33 | 39 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 34 | 40 | # pragma GCC system_header |
| 35 | 41 | #endif |
| 36 | 42 | |
| 43 | _LIBCPP_PUSH_MACROS | |
| 44 | #include <__undef_macros> | |
| 45 | ||
| 37 | 46 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 47 | |
| 39 | #if _LIBCPP_STD_VER > 17 | |
| 48 | #if _LIBCPP_STD_VER >= 20 | |
| 40 | 49 | |
| 41 | 50 | // Conerts a chrono date and weekday to a given _Tm type. |
| 42 | 51 | // |
| ... | ... | @@ -67,6 +76,24 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday _ |
| 67 | 76 | return __result; |
| 68 | 77 | } |
| 69 | 78 | |
| 79 | template <class _Tm, class _Duration> | |
| 80 | _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const chrono::sys_time<_Duration> __tp) { | |
| 81 | chrono::sys_days __days = chrono::floor<chrono::days>(__tp); | |
| 82 | chrono::year_month_day __ymd{__days}; | |
| 83 | ||
| 84 | _Tm __result = std::__convert_to_tm<_Tm>(chrono::year_month_day{__ymd}, chrono::weekday{__days}); | |
| 85 | ||
| 86 | uint64_t __sec = | |
| 87 | chrono::duration_cast<chrono::seconds>(__tp - chrono::time_point_cast<chrono::seconds>(__days)).count(); | |
| 88 | __sec %= 24 * 3600; | |
| 89 | __result.tm_hour = __sec / 3600; | |
| 90 | __sec %= 3600; | |
| 91 | __result.tm_min = __sec / 60; | |
| 92 | __result.tm_sec = __sec % 60; | |
| 93 | ||
| 94 | return __result; | |
| 95 | } | |
| 96 | ||
| 70 | 97 | // Convert a chrono (calendar) time point, or dururation to the given _Tm type, |
| 71 | 98 | // which must have the same properties as std::tm. |
| 72 | 99 | template <class _Tm, class _ChronoT> |
| ... | ... | @@ -76,17 +103,37 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { |
| 76 | 103 | __result.tm_zone = "UTC"; |
| 77 | 104 | # endif |
| 78 | 105 | |
| 79 | if constexpr (chrono::__is_duration<_ChronoT>::value) { | |
| 106 | if constexpr (__is_time_point<_ChronoT>) { | |
| 107 | if constexpr (same_as<typename _ChronoT::clock, chrono::system_clock>) | |
| 108 | return std::__convert_to_tm<_Tm>(__value); | |
| 109 | else if constexpr (same_as<typename _ChronoT::clock, chrono::file_clock>) | |
| 110 | return std::__convert_to_tm<_Tm>(_ChronoT::clock::to_sys(__value)); | |
| 111 | else if constexpr (same_as<typename _ChronoT::clock, chrono::local_t>) | |
| 112 | return std::__convert_to_tm<_Tm>(chrono::sys_time<typename _ChronoT::duration>{__value.time_since_epoch()}); | |
| 113 | else | |
| 114 | static_assert(sizeof(_ChronoT) == 0, "TODO: Add the missing clock specialization"); | |
| 115 | } else if constexpr (chrono::__is_duration<_ChronoT>::value) { | |
| 80 | 116 | // [time.format]/6 |
| 81 | 117 | // ... However, if a flag refers to a "time of day" (e.g. %H, %I, %p, |
| 82 | 118 | // etc.), then a specialization of duration is interpreted as the time of |
| 83 | 119 | // day elapsed since midnight. |
| 84 | uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count(); | |
| 85 | __sec %= 24 * 3600; | |
| 86 | __result.tm_hour = __sec / 3600; | |
| 87 | __sec %= 3600; | |
| 88 | __result.tm_min = __sec / 60; | |
| 89 | __result.tm_sec = __sec % 60; | |
| 120 | ||
| 121 | // Not all values can be converted to hours, it may run into ratio | |
| 122 | // conversion errors. In that case the conversion to seconds works. | |
| 123 | if constexpr (is_convertible_v<_ChronoT, chrono::hours>) { | |
| 124 | auto __hour = chrono::floor<chrono::hours>(__value); | |
| 125 | auto __sec = chrono::duration_cast<chrono::seconds>(__value - __hour); | |
| 126 | __result.tm_hour = __hour.count() % 24; | |
| 127 | __result.tm_min = __sec.count() / 60; | |
| 128 | __result.tm_sec = __sec.count() % 60; | |
| 129 | } else { | |
| 130 | uint64_t __sec = chrono::duration_cast<chrono::seconds>(__value).count(); | |
| 131 | __sec %= 24 * 3600; | |
| 132 | __result.tm_hour = __sec / 3600; | |
| 133 | __sec %= 3600; | |
| 134 | __result.tm_min = __sec / 60; | |
| 135 | __result.tm_sec = __sec % 60; | |
| 136 | } | |
| 90 | 137 | } else if constexpr (same_as<_ChronoT, chrono::day>) |
| 91 | 138 | __result.tm_mday = static_cast<unsigned>(__value); |
| 92 | 139 | else if constexpr (same_as<_ChronoT, chrono::month>) |
| ... | ... | @@ -114,14 +161,26 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { |
| 114 | 161 | } else if constexpr (same_as<_ChronoT, chrono::year_month_weekday> || |
| 115 | 162 | same_as<_ChronoT, chrono::year_month_weekday_last>) { |
| 116 | 163 | return std::__convert_to_tm<_Tm>(chrono::year_month_day{static_cast<chrono::sys_days>(__value)}, __value.weekday()); |
| 164 | } else if constexpr (__is_hh_mm_ss<_ChronoT>) { | |
| 165 | __result.tm_sec = __value.seconds().count(); | |
| 166 | __result.tm_min = __value.minutes().count(); | |
| 167 | // In libc++ hours is stored as a long. The type in std::tm is an int. So | |
| 168 | // the overflow can only occur when hour uses more bits than an int | |
| 169 | // provides. | |
| 170 | if constexpr (sizeof(std::chrono::hours::rep) > sizeof(__result.tm_hour)) | |
| 171 | if (__value.hours().count() > std::numeric_limits<decltype(__result.tm_hour)>::max()) | |
| 172 | std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow"); | |
| 173 | __result.tm_hour = __value.hours().count(); | |
| 117 | 174 | } else |
| 118 | 175 | static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization"); |
| 119 | 176 | |
| 120 | 177 | return __result; |
| 121 | 178 | } |
| 122 | 179 | |
| 123 | #endif //if _LIBCPP_STD_VER > 17 | |
| 180 | #endif // if _LIBCPP_STD_VER >= 20 | |
| 124 | 181 | |
| 125 | 182 | _LIBCPP_END_NAMESPACE_STD |
| 126 | 183 | |
| 184 | _LIBCPP_POP_MACROS | |
| 185 | ||
| 127 | 186 | #endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H |
lib/libcxx/include/__chrono/day.h+3-3| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -29,7 +29,7 @@ class day { |
| 29 | 29 | private: |
| 30 | 30 | unsigned char __d_; |
| 31 | 31 | public: |
| 32 | _LIBCPP_HIDE_FROM_ABI day() = default; | |
| 32 | day() = default; | |
| 33 | 33 | _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast<unsigned char>(__val)) {} |
| 34 | 34 | _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; } |
| 35 | 35 | _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } |
| ... | ... | @@ -79,6 +79,6 @@ day& day::operator-=(const days& __dd) noexcept |
| 79 | 79 | |
| 80 | 80 | _LIBCPP_END_NAMESPACE_STD |
| 81 | 81 | |
| 82 | #endif // _LIBCPP_STD_VER > 17 | |
| 82 | #endif // _LIBCPP_STD_VER >= 20 | |
| 83 | 83 | |
| 84 | 84 | #endif // _LIBCPP___CHRONO_DAY_H |
lib/libcxx/include/__chrono/duration.h+31-12| ... | ... | @@ -10,6 +10,8 @@ |
| 10 | 10 | #ifndef _LIBCPP___CHRONO_DURATION_H |
| 11 | 11 | #define _LIBCPP___CHRONO_DURATION_H |
| 12 | 12 | |
| 13 | #include <__compare/ordering.h> | |
| 14 | #include <__compare/three_way_comparable.h> | |
| 13 | 15 | #include <__config> |
| 14 | 16 | #include <__type_traits/common_type.h> |
| 15 | 17 | #include <__type_traits/enable_if.h> |
| ... | ... | @@ -130,7 +132,7 @@ duration_cast(const duration<_Rep, _Period>& __fd) |
| 130 | 132 | template <class _Rep> |
| 131 | 133 | struct _LIBCPP_TEMPLATE_VIS treat_as_floating_point : is_floating_point<_Rep> {}; |
| 132 | 134 | |
| 133 | #if _LIBCPP_STD_VER > 14 | |
| 135 | #if _LIBCPP_STD_VER >= 17 | |
| 134 | 136 | template <class _Rep> |
| 135 | 137 | inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; |
| 136 | 138 | #endif |
| ... | ... | @@ -144,7 +146,7 @@ public: |
| 144 | 146 | _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} |
| 145 | 147 | }; |
| 146 | 148 | |
| 147 | #if _LIBCPP_STD_VER > 14 | |
| 149 | #if _LIBCPP_STD_VER >= 17 | |
| 148 | 150 | template <class _ToDuration, class _Rep, class _Period> |
| 149 | 151 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 150 | 152 | typename enable_if |
| ... | ... | @@ -186,11 +188,11 @@ round(const duration<_Rep, _Period>& __d) |
| 186 | 188 | { |
| 187 | 189 | _ToDuration __lower = chrono::floor<_ToDuration>(__d); |
| 188 | 190 | _ToDuration __upper = __lower + _ToDuration{1}; |
| 189 | auto __lowerDiff = __d - __lower; | |
| 190 | auto __upperDiff = __upper - __d; | |
| 191 | if (__lowerDiff < __upperDiff) | |
| 191 | auto __lower_diff = __d - __lower; | |
| 192 | auto __upper_diff = __upper - __d; | |
| 193 | if (__lower_diff < __upper_diff) | |
| 192 | 194 | return __lower; |
| 193 | if (__lowerDiff > __upperDiff) | |
| 195 | if (__lower_diff > __upper_diff) | |
| 194 | 196 | return __upper; |
| 195 | 197 | return __lower.count() & 1 ? __upper : __lower; |
| 196 | 198 | } |
| ... | ... | @@ -242,11 +244,10 @@ private: |
| 242 | 244 | rep __rep_; |
| 243 | 245 | public: |
| 244 | 246 | |
| 245 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 246 | 247 | #ifndef _LIBCPP_CXX03_LANG |
| 247 | duration() = default; | |
| 248 | constexpr duration() = default; | |
| 248 | 249 | #else |
| 249 | duration() {} | |
| 250 | _LIBCPP_HIDE_FROM_ABI duration() {} | |
| 250 | 251 | #endif |
| 251 | 252 | |
| 252 | 253 | template <class _Rep2> |
| ... | ... | @@ -307,7 +308,7 @@ typedef duration<long long, milli> milliseconds; |
| 307 | 308 | typedef duration<long long > seconds; |
| 308 | 309 | typedef duration< long, ratio< 60> > minutes; |
| 309 | 310 | typedef duration< long, ratio<3600> > hours; |
| 310 | #if _LIBCPP_STD_VER > 17 | |
| 311 | #if _LIBCPP_STD_VER >= 20 | |
| 311 | 312 | typedef duration< int, ratio_multiply<ratio<24>, hours::period>> days; |
| 312 | 313 | typedef duration< int, ratio_multiply<ratio<7>, days::period>> weeks; |
| 313 | 314 | typedef duration< int, ratio_multiply<ratio<146097, 400>, days::period>> years; |
| ... | ... | @@ -343,6 +344,8 @@ operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period |
| 343 | 344 | return __duration_eq<duration<_Rep1, _Period1>, duration<_Rep2, _Period2> >()(__lhs, __rhs); |
| 344 | 345 | } |
| 345 | 346 | |
| 347 | #if _LIBCPP_STD_VER <= 17 | |
| 348 | ||
| 346 | 349 | // Duration != |
| 347 | 350 | |
| 348 | 351 | template <class _Rep1, class _Period1, class _Rep2, class _Period2> |
| ... | ... | @@ -354,6 +357,8 @@ operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period |
| 354 | 357 | return !(__lhs == __rhs); |
| 355 | 358 | } |
| 356 | 359 | |
| 360 | #endif // _LIBCPP_STD_VER <= 17 | |
| 361 | ||
| 357 | 362 | // Duration < |
| 358 | 363 | |
| 359 | 364 | template <class _LhsDuration, class _RhsDuration> |
| ... | ... | @@ -417,6 +422,20 @@ operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period |
| 417 | 422 | return !(__lhs < __rhs); |
| 418 | 423 | } |
| 419 | 424 | |
| 425 | #if _LIBCPP_STD_VER >= 20 | |
| 426 | ||
| 427 | template<class _Rep1, class _Period1, class _Rep2, class _Period2> | |
| 428 | requires three_way_comparable<common_type_t<_Rep1, _Rep2>> | |
| 429 | _LIBCPP_HIDE_FROM_ABI | |
| 430 | constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs, | |
| 431 | const duration<_Rep2, _Period2>& __rhs) | |
| 432 | { | |
| 433 | using _Ct = common_type_t<duration<_Rep1, _Period1>, duration<_Rep2, _Period2>>; | |
| 434 | return _Ct(__lhs).count() <=> _Ct(__rhs).count(); | |
| 435 | } | |
| 436 | ||
| 437 | #endif // _LIBCPP_STD_VER >= 20 | |
| 438 | ||
| 420 | 439 | // Duration + |
| 421 | 440 | |
| 422 | 441 | template <class _Rep1, class _Period1, class _Rep2, class _Period2> |
| ... | ... | @@ -530,7 +549,7 @@ operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2 |
| 530 | 549 | |
| 531 | 550 | } // namespace chrono |
| 532 | 551 | |
| 533 | #if _LIBCPP_STD_VER > 11 | |
| 552 | #if _LIBCPP_STD_VER >= 14 | |
| 534 | 553 | // Suffixes for duration literals [time.duration.literals] |
| 535 | 554 | inline namespace literals |
| 536 | 555 | { |
| ... | ... | @@ -609,7 +628,7 @@ namespace chrono { // hoist the literals into namespace std::chrono |
| 609 | 628 | using namespace literals::chrono_literals; |
| 610 | 629 | } // namespace chrono |
| 611 | 630 | |
| 612 | #endif // _LIBCPP_STD_VER > 11 | |
| 631 | #endif // _LIBCPP_STD_VER >= 14 | |
| 613 | 632 | |
| 614 | 633 | _LIBCPP_END_NAMESPACE_STD |
| 615 | 634 |
lib/libcxx/include/__chrono/file_clock.h+5-5| ... | ... | @@ -27,7 +27,7 @@ struct _FilesystemClock; |
| 27 | 27 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 28 | 28 | #endif // !_LIBCPP_CXX03_LANG |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -44,7 +44,7 @@ using file_time = time_point<file_clock, _Duration>; |
| 44 | 44 | |
| 45 | 45 | _LIBCPP_END_NAMESPACE_STD |
| 46 | 46 | |
| 47 | #endif // _LIBCPP_STD_VER > 17 | |
| 47 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | 48 | |
| 49 | 49 | #ifndef _LIBCPP_CXX03_LANG |
| 50 | 50 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| ... | ... | @@ -63,9 +63,9 @@ struct _FilesystemClock { |
| 63 | 63 | _LIBCPP_EXPORTED_FROM_ABI |
| 64 | 64 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; |
| 65 | 65 | |
| 66 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; | |
| 66 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept; | |
| 67 | 67 | |
| 68 | #if _LIBCPP_STD_VER > 17 | |
| 68 | #if _LIBCPP_STD_VER >= 20 | |
| 69 | 69 | template <class _Duration> |
| 70 | 70 | _LIBCPP_HIDE_FROM_ABI |
| 71 | 71 | static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { |
| ... | ... | @@ -77,7 +77,7 @@ struct _FilesystemClock { |
| 77 | 77 | static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { |
| 78 | 78 | return chrono::file_time<_Duration>(__t.time_since_epoch()); |
| 79 | 79 | } |
| 80 | #endif // _LIBCPP_STD_VER > 17 | |
| 80 | #endif // _LIBCPP_STD_VER >= 20 | |
| 81 | 81 | }; |
| 82 | 82 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 83 | 83 | #endif // !_LIBCPP_CXX03_LANG |
lib/libcxx/include/__chrono/formatter.h+228-114| ... | ... | @@ -11,9 +11,11 @@ |
| 11 | 11 | #define _LIBCPP___CHRONO_FORMATTER_H |
| 12 | 12 | |
| 13 | 13 | #include <__chrono/calendar.h> |
| 14 | #include <__chrono/concepts.h> | |
| 14 | 15 | #include <__chrono/convert_to_tm.h> |
| 15 | 16 | #include <__chrono/day.h> |
| 16 | 17 | #include <__chrono/duration.h> |
| 18 | #include <__chrono/file_clock.h> | |
| 17 | 19 | #include <__chrono/hh_mm_ss.h> |
| 18 | 20 | #include <__chrono/month.h> |
| 19 | 21 | #include <__chrono/month_weekday.h> |
| ... | ... | @@ -21,6 +23,7 @@ |
| 21 | 23 | #include <__chrono/ostream.h> |
| 22 | 24 | #include <__chrono/parser_std_format_spec.h> |
| 23 | 25 | #include <__chrono/statically_widen.h> |
| 26 | #include <__chrono/system_clock.h> | |
| 24 | 27 | #include <__chrono/time_point.h> |
| 25 | 28 | #include <__chrono/weekday.h> |
| 26 | 29 | #include <__chrono/year.h> |
| ... | ... | @@ -35,13 +38,12 @@ |
| 35 | 38 | #include <__format/format_functions.h> |
| 36 | 39 | #include <__format/format_parse_context.h> |
| 37 | 40 | #include <__format/formatter.h> |
| 38 | #include <__format/formatter_output.h> | |
| 39 | 41 | #include <__format/parser_std_format_spec.h> |
| 42 | #include <__format/write_escaped.h> | |
| 40 | 43 | #include <__memory/addressof.h> |
| 41 | 44 | #include <cmath> |
| 42 | 45 | #include <ctime> |
| 43 | 46 | #include <sstream> |
| 44 | #include <string> | |
| 45 | 47 | #include <string_view> |
| 46 | 48 | |
| 47 | 49 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -50,7 +52,7 @@ |
| 50 | 52 | |
| 51 | 53 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 52 | 54 | |
| 53 | #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 55 | #if _LIBCPP_STD_VER >= 20 | |
| 54 | 56 | |
| 55 | 57 | namespace __formatter { |
| 56 | 58 | |
| ... | ... | @@ -75,13 +77,15 @@ namespace __formatter { |
| 75 | 77 | // For tiny ratios it's not possible to convert a duration to a hh_mm_ss. This |
| 76 | 78 | // fails compile-time due to the limited precision of the ratio (64-bit is too |
| 77 | 79 | // small). Therefore a duration uses its own conversion. |
| 78 | template <class _CharT, class _Tp> | |
| 79 | requires(chrono::__is_duration<_Tp>::value) | |
| 80 | _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) { | |
| 80 | template <class _CharT, class _Rep, class _Period> | |
| 81 | _LIBCPP_HIDE_FROM_ABI void | |
| 82 | __format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_stringstream<_CharT>& __sstr) { | |
| 81 | 83 | __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point(); |
| 82 | 84 | |
| 85 | using __duration = chrono::duration<_Rep, _Period>; | |
| 86 | ||
| 83 | 87 | auto __fraction = __value - chrono::duration_cast<chrono::seconds>(__value); |
| 84 | if constexpr (chrono::treat_as_floating_point_v<typename _Tp::rep>) | |
| 88 | if constexpr (chrono::treat_as_floating_point_v<_Rep>) | |
| 85 | 89 | // When the floating-point value has digits itself they are ignored based |
| 86 | 90 | // on the wording in [tab:time.format.spec] |
| 87 | 91 | // If the precision of the input cannot be exactly represented with |
| ... | ... | @@ -96,19 +100,44 @@ _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_string |
| 96 | 100 | // https://godbolt.org/z/6dsbnW8ba |
| 97 | 101 | std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, |
| 98 | 102 | _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), |
| 99 | __fraction.count(), | |
| 100 | chrono::hh_mm_ss<_Tp>::fractional_width); | |
| 103 | chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(), | |
| 104 | chrono::hh_mm_ss<__duration>::fractional_width); | |
| 105 | else | |
| 106 | std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, | |
| 107 | _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"), | |
| 108 | chrono::duration_cast<typename chrono::hh_mm_ss<__duration>::precision>(__fraction).count(), | |
| 109 | chrono::hh_mm_ss<__duration>::fractional_width); | |
| 110 | } | |
| 111 | ||
| 112 | template <class _CharT, __is_time_point _Tp> | |
| 113 | _LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) { | |
| 114 | __formatter::__format_sub_seconds(__value.time_since_epoch(), __sstr); | |
| 115 | } | |
| 116 | ||
| 117 | template <class _CharT, class _Duration> | |
| 118 | _LIBCPP_HIDE_FROM_ABI void | |
| 119 | __format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstream<_CharT>& __sstr) { | |
| 120 | __sstr << std::use_facet<numpunct<_CharT>>(__sstr.getloc()).decimal_point(); | |
| 121 | if constexpr (chrono::treat_as_floating_point_v<typename _Duration::rep>) | |
| 122 | std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, | |
| 123 | _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), | |
| 124 | __value.subseconds().count(), | |
| 125 | __value.fractional_width); | |
| 101 | 126 | else |
| 102 | 127 | std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, |
| 103 | 128 | _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"), |
| 104 | __fraction.count(), | |
| 105 | chrono::hh_mm_ss<_Tp>::fractional_width); | |
| 129 | __value.subseconds().count(), | |
| 130 | __value.fractional_width); | |
| 106 | 131 | } |
| 107 | 132 | |
| 108 | 133 | template <class _Tp> |
| 109 | 134 | consteval bool __use_fraction() { |
| 110 | if constexpr (chrono::__is_duration<_Tp>::value) | |
| 135 | if constexpr (__is_time_point<_Tp>) | |
| 136 | return chrono::hh_mm_ss<typename _Tp::duration>::fractional_width; | |
| 137 | else if constexpr (chrono::__is_duration<_Tp>::value) | |
| 111 | 138 | return chrono::hh_mm_ss<_Tp>::fractional_width; |
| 139 | else if constexpr (__is_hh_mm_ss<_Tp>) | |
| 140 | return _Tp::fractional_width; | |
| 112 | 141 | else |
| 113 | 142 | return false; |
| 114 | 143 | } |
| ... | ... | @@ -169,7 +198,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 169 | 198 | if (__year < 1000 || __year > 9999) |
| 170 | 199 | __formatter::__format_century(__year, __sstr); |
| 171 | 200 | else |
| 172 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 201 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 173 | 202 | } break; |
| 174 | 203 | |
| 175 | 204 | case _CharT('j'): |
| ... | ... | @@ -180,7 +209,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 180 | 209 | // an intemediate step. |
| 181 | 210 | __sstr << chrono::duration_cast<chrono::days>(chrono::duration_cast<chrono::seconds>(__value)).count(); |
| 182 | 211 | else |
| 183 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 212 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 184 | 213 | break; |
| 185 | 214 | |
| 186 | 215 | case _CharT('q'): |
| ... | ... | @@ -208,7 +237,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 208 | 237 | |
| 209 | 238 | case _CharT('S'): |
| 210 | 239 | case _CharT('T'): |
| 211 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 240 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 212 | 241 | if constexpr (__use_fraction<_Tp>()) |
| 213 | 242 | __formatter::__format_sub_seconds(__value, __sstr); |
| 214 | 243 | break; |
| ... | ... | @@ -240,20 +269,19 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 240 | 269 | // |
| 241 | 270 | // TODO FMT evaluate the comment above. |
| 242 | 271 | |
| 243 | # if defined(__GLIBC__) || defined(_AIX) | |
| 272 | # if defined(__GLIBC__) || defined(_AIX) || defined(_WIN32) | |
| 244 | 273 | case _CharT('y'): |
| 245 | 274 | // Glibc fails for negative values, AIX for positive values too. |
| 246 | 275 | __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), (std::abs(__t.tm_year + 1900)) % 100); |
| 247 | 276 | break; |
| 248 | # endif // defined(__GLIBC__) || defined(_AIX) | |
| 277 | # endif // defined(__GLIBC__) || defined(_AIX) || defined(_WIN32) | |
| 249 | 278 | |
| 250 | case _CharT('Y'): { | |
| 251 | int __year = __t.tm_year + 1900; | |
| 252 | if (__year < 1000) | |
| 253 | __formatter::__format_year(__year, __sstr); | |
| 254 | else | |
| 255 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 256 | } break; | |
| 279 | case _CharT('Y'): | |
| 280 | // Depending on the platform's libc the range of supported years is | |
| 281 | // limited. Intead of of testing all conditions use the internal | |
| 282 | // implementation unconditionally. | |
| 283 | __formatter::__format_year(__t.tm_year + 1900, __sstr); | |
| 284 | break; | |
| 257 | 285 | |
| 258 | 286 | case _CharT('F'): { |
| 259 | 287 | int __year = __t.tm_year + 1900; |
| ... | ... | @@ -261,9 +289,14 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 261 | 289 | __formatter::__format_year(__year, __sstr); |
| 262 | 290 | __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); |
| 263 | 291 | } else |
| 264 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 292 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 265 | 293 | } break; |
| 266 | 294 | |
| 295 | case _CharT('Z'): | |
| 296 | // TODO FMT Add proper timezone support. | |
| 297 | __sstr << _LIBCPP_STATICALLY_WIDEN(_CharT, "UTC"); | |
| 298 | break; | |
| 299 | ||
| 267 | 300 | case _CharT('O'): |
| 268 | 301 | if constexpr (__use_fraction<_Tp>()) { |
| 269 | 302 | // Handle OS using the normal representation for the non-fractional |
| ... | ... | @@ -271,7 +304,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 271 | 304 | // fractional part should be formatted. |
| 272 | 305 | if (*(__it + 1) == 'S') { |
| 273 | 306 | ++__it; |
| 274 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 307 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 275 | 308 | __formatter::__format_sub_seconds(__value, __sstr); |
| 276 | 309 | break; |
| 277 | 310 | } |
| ... | ... | @@ -281,7 +314,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 281 | 314 | ++__it; |
| 282 | 315 | [[fallthrough]]; |
| 283 | 316 | default: |
| 284 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), __s, __it + 1); | |
| 317 | __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); | |
| 285 | 318 | break; |
| 286 | 319 | } |
| 287 | 320 | } else { |
| ... | ... | @@ -292,7 +325,9 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( |
| 292 | 325 | |
| 293 | 326 | template <class _Tp> |
| 294 | 327 | _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { |
| 295 | if constexpr (same_as<_Tp, chrono::day>) | |
| 328 | if constexpr (__is_time_point<_Tp>) | |
| 329 | return true; | |
| 330 | else if constexpr (same_as<_Tp, chrono::day>) | |
| 296 | 331 | return true; |
| 297 | 332 | else if constexpr (same_as<_Tp, chrono::month>) |
| 298 | 333 | return __value.ok(); |
| ... | ... | @@ -322,13 +357,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { |
| 322 | 357 | return __value.weekday().ok(); |
| 323 | 358 | else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) |
| 324 | 359 | return __value.weekday().ok(); |
| 360 | else if constexpr (__is_hh_mm_ss<_Tp>) | |
| 361 | return true; | |
| 325 | 362 | else |
| 326 | 363 | static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); |
| 327 | 364 | } |
| 328 | 365 | |
| 329 | 366 | template <class _Tp> |
| 330 | 367 | _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { |
| 331 | if constexpr (same_as<_Tp, chrono::day>) | |
| 368 | if constexpr (__is_time_point<_Tp>) | |
| 369 | return true; | |
| 370 | else if constexpr (same_as<_Tp, chrono::day>) | |
| 332 | 371 | return true; |
| 333 | 372 | else if constexpr (same_as<_Tp, chrono::month>) |
| 334 | 373 | return __value.ok(); |
| ... | ... | @@ -358,13 +397,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { |
| 358 | 397 | return __value.weekday().ok(); |
| 359 | 398 | else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) |
| 360 | 399 | return __value.weekday().ok(); |
| 400 | else if constexpr (__is_hh_mm_ss<_Tp>) | |
| 401 | return true; | |
| 361 | 402 | else |
| 362 | 403 | static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); |
| 363 | 404 | } |
| 364 | 405 | |
| 365 | 406 | template <class _Tp> |
| 366 | 407 | _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { |
| 367 | if constexpr (same_as<_Tp, chrono::day>) | |
| 408 | if constexpr (__is_time_point<_Tp>) | |
| 409 | return true; | |
| 410 | else if constexpr (same_as<_Tp, chrono::day>) | |
| 368 | 411 | return true; |
| 369 | 412 | else if constexpr (same_as<_Tp, chrono::month>) |
| 370 | 413 | return __value.ok(); |
| ... | ... | @@ -394,13 +437,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { |
| 394 | 437 | return __value.ok(); |
| 395 | 438 | else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) |
| 396 | 439 | return __value.ok(); |
| 440 | else if constexpr (__is_hh_mm_ss<_Tp>) | |
| 441 | return true; | |
| 397 | 442 | else |
| 398 | 443 | static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); |
| 399 | 444 | } |
| 400 | 445 | |
| 401 | 446 | template <class _Tp> |
| 402 | 447 | _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { |
| 403 | if constexpr (same_as<_Tp, chrono::day>) | |
| 448 | if constexpr (__is_time_point<_Tp>) | |
| 449 | return true; | |
| 450 | else if constexpr (same_as<_Tp, chrono::day>) | |
| 404 | 451 | return true; |
| 405 | 452 | else if constexpr (same_as<_Tp, chrono::month>) |
| 406 | 453 | return __value.ok(); |
| ... | ... | @@ -430,16 +477,18 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { |
| 430 | 477 | return __value.month().ok(); |
| 431 | 478 | else if constexpr (same_as<_Tp, chrono::year_month_weekday_last>) |
| 432 | 479 | return __value.month().ok(); |
| 480 | else if constexpr (__is_hh_mm_ss<_Tp>) | |
| 481 | return true; | |
| 433 | 482 | else |
| 434 | 483 | static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); |
| 435 | 484 | } |
| 436 | 485 | |
| 437 | template <class _CharT, class _Tp> | |
| 486 | template <class _CharT, class _Tp, class _FormatContext> | |
| 438 | 487 | _LIBCPP_HIDE_FROM_ABI auto |
| 439 | 488 | __format_chrono(const _Tp& __value, |
| 440 | auto& __ctx, | |
| 489 | _FormatContext& __ctx, | |
| 441 | 490 | __format_spec::__parsed_specifications<_CharT> __specs, |
| 442 | basic_string_view<_CharT> __chrono_specs) -> decltype(__ctx.out()) { | |
| 491 | basic_string_view<_CharT> __chrono_specs) { | |
| 443 | 492 | basic_stringstream<_CharT> __sstr; |
| 444 | 493 | // [time.format]/2 |
| 445 | 494 | // 2.1 - the "C" locale if the L option is not present in chrono-format-spec, otherwise |
| ... | ... | @@ -464,42 +513,63 @@ __format_chrono(const _Tp& __value, |
| 464 | 513 | } else { |
| 465 | 514 | // Test __weekday_name_ before __weekday_ to give a better error. |
| 466 | 515 | if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value)) |
| 467 | std::__throw_format_error("formatting a weekday name needs a valid weekday"); | |
| 516 | std::__throw_format_error("Formatting a weekday name needs a valid weekday"); | |
| 468 | 517 | |
| 469 | 518 | if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value)) |
| 470 | std::__throw_format_error("formatting a weekday needs a valid weekday"); | |
| 519 | std::__throw_format_error("Formatting a weekday needs a valid weekday"); | |
| 471 | 520 | |
| 472 | 521 | if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value)) |
| 473 | std::__throw_format_error("formatting a day of year needs a valid date"); | |
| 522 | std::__throw_format_error("Formatting a day of year needs a valid date"); | |
| 474 | 523 | |
| 475 | 524 | if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value)) |
| 476 | std::__throw_format_error("formatting a week of year needs a valid date"); | |
| 525 | std::__throw_format_error("Formatting a week of year needs a valid date"); | |
| 477 | 526 | |
| 478 | 527 | if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value)) |
| 479 | std::__throw_format_error("formatting a month name from an invalid month number"); | |
| 528 | std::__throw_format_error("Formatting a month name from an invalid month number"); | |
| 529 | ||
| 530 | if constexpr (__is_hh_mm_ss<_Tp>) { | |
| 531 | // Note this is a pedantic intepretation of the Standard. A hh_mm_ss | |
| 532 | // is no longer a time_of_day and can store an arbitrary number of | |
| 533 | // hours. A number of hours in a 12 or 24 hour clock can't represent | |
| 534 | // 24 hours or more. The functions std::chrono::make12 and | |
| 535 | // std::chrono::make24 reaffirm this view point. | |
| 536 | // | |
| 537 | // Interestingly this will be the only output stream function that | |
| 538 | // throws. | |
| 539 | // | |
| 540 | // TODO FMT The wording probably needs to be adapted to | |
| 541 | // - The displayed hours is hh_mm_ss.hours() % 24 | |
| 542 | // - It should probably allow %j in the same fashion as duration. | |
| 543 | // - The stream formatter should change its output when hours >= 24 | |
| 544 | // - Write it as not valid, | |
| 545 | // - or write the number of days. | |
| 546 | if (__specs.__chrono_.__hour_ && __value.hours().count() > 23) | |
| 547 | std::__throw_format_error("Formatting a hour needs a valid value"); | |
| 548 | ||
| 549 | if (__value.is_negative()) | |
| 550 | __sstr << _CharT('-'); | |
| 551 | } | |
| 480 | 552 | |
| 481 | 553 | __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs); |
| 482 | 554 | } |
| 483 | 555 | } |
| 484 | 556 | |
| 485 | // TODO FMT Use the stringstream's view after P0408R7 has been implemented. | |
| 486 | basic_string<_CharT> __str = __sstr.str(); | |
| 487 | return __formatter::__write_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); | |
| 557 | return __formatter::__write_string(__sstr.view(), __ctx.out(), __specs); | |
| 488 | 558 | } |
| 489 | 559 | |
| 490 | 560 | } // namespace __formatter |
| 491 | 561 | |
| 492 | 562 | template <__fmt_char_type _CharT> |
| 493 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_chrono { | |
| 563 | struct _LIBCPP_TEMPLATE_VIS __formatter_chrono { | |
| 494 | 564 | public: |
| 495 | _LIBCPP_HIDE_FROM_ABI constexpr auto __parse( | |
| 496 | basic_format_parse_context<_CharT>& __parse_ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) | |
| 497 | -> decltype(__parse_ctx.begin()) { | |
| 498 | return __parser_.__parse(__parse_ctx, __fields, __flags); | |
| 565 | template <class _ParseContext> | |
| 566 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator | |
| 567 | __parse(_ParseContext& __ctx, __format_spec::__fields __fields, __format_spec::__flags __flags) { | |
| 568 | return __parser_.__parse(__ctx, __fields, __flags); | |
| 499 | 569 | } |
| 500 | 570 | |
| 501 | template <class _Tp> | |
| 502 | _LIBCPP_HIDE_FROM_ABI auto format(const _Tp& __value, auto& __ctx) const -> decltype(__ctx.out()) const { | |
| 571 | template <class _Tp, class _FormatContext> | |
| 572 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _Tp& __value, _FormatContext& __ctx) const { | |
| 503 | 573 | return __formatter::__format_chrono( |
| 504 | 574 | __value, __ctx, __parser_.__parser_.__get_parsed_chrono_specifications(__ctx), __parser_.__chrono_specs_); |
| 505 | 575 | } |
| ... | ... | @@ -507,13 +577,47 @@ public: |
| 507 | 577 | __format_spec::__parser_chrono<_CharT> __parser_; |
| 508 | 578 | }; |
| 509 | 579 | |
| 580 | template <class _Duration, __fmt_char_type _CharT> | |
| 581 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::sys_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { | |
| 582 | public: | |
| 583 | using _Base = __formatter_chrono<_CharT>; | |
| 584 | ||
| 585 | template <class _ParseContext> | |
| 586 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 587 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock); | |
| 588 | } | |
| 589 | }; | |
| 590 | ||
| 591 | template <class _Duration, __fmt_char_type _CharT> | |
| 592 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::file_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { | |
| 593 | public: | |
| 594 | using _Base = __formatter_chrono<_CharT>; | |
| 595 | ||
| 596 | template <class _ParseContext> | |
| 597 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 598 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock); | |
| 599 | } | |
| 600 | }; | |
| 601 | ||
| 602 | template <class _Duration, __fmt_char_type _CharT> | |
| 603 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::local_time<_Duration>, _CharT> : public __formatter_chrono<_CharT> { | |
| 604 | public: | |
| 605 | using _Base = __formatter_chrono<_CharT>; | |
| 606 | ||
| 607 | template <class _ParseContext> | |
| 608 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 609 | // The flags are not __clock since there is no associated time-zone. | |
| 610 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date_time); | |
| 611 | } | |
| 612 | }; | |
| 613 | ||
| 510 | 614 | template <class _Rep, class _Period, __fmt_char_type _CharT> |
| 511 | 615 | struct formatter<chrono::duration<_Rep, _Period>, _CharT> : public __formatter_chrono<_CharT> { |
| 512 | 616 | public: |
| 513 | 617 | using _Base = __formatter_chrono<_CharT>; |
| 514 | 618 | |
| 515 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 516 | -> decltype(__parse_ctx.begin()) { | |
| 619 | template <class _ParseContext> | |
| 620 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 517 | 621 | // [time.format]/1 |
| 518 | 622 | // Giving a precision specification in the chrono-format-spec is valid only |
| 519 | 623 | // for std::chrono::duration types where the representation type Rep is a |
| ... | ... | @@ -523,193 +627,203 @@ public: |
| 523 | 627 | // |
| 524 | 628 | // Note this doesn't refer to chrono::treat_as_floating_point_v<_Rep>. |
| 525 | 629 | if constexpr (std::floating_point<_Rep>) |
| 526 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration); | |
| 630 | return _Base::__parse(__ctx, __format_spec::__fields_chrono_fractional, __format_spec::__flags::__duration); | |
| 527 | 631 | else |
| 528 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration); | |
| 632 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__duration); | |
| 529 | 633 | } |
| 530 | 634 | }; |
| 531 | 635 | |
| 532 | 636 | template <__fmt_char_type _CharT> |
| 533 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::day, _CharT> | |
| 637 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::day, _CharT> | |
| 534 | 638 | : public __formatter_chrono<_CharT> { |
| 535 | 639 | public: |
| 536 | 640 | using _Base = __formatter_chrono<_CharT>; |
| 537 | 641 | |
| 538 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 539 | -> decltype(__parse_ctx.begin()) { | |
| 540 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day); | |
| 642 | template <class _ParseContext> | |
| 643 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 644 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__day); | |
| 541 | 645 | } |
| 542 | 646 | }; |
| 543 | 647 | |
| 544 | 648 | template <__fmt_char_type _CharT> |
| 545 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month, _CharT> | |
| 649 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month, _CharT> | |
| 546 | 650 | : public __formatter_chrono<_CharT> { |
| 547 | 651 | public: |
| 548 | 652 | using _Base = __formatter_chrono<_CharT>; |
| 549 | 653 | |
| 550 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 551 | -> decltype(__parse_ctx.begin()) { | |
| 552 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); | |
| 654 | template <class _ParseContext> | |
| 655 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 656 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); | |
| 553 | 657 | } |
| 554 | 658 | }; |
| 555 | 659 | |
| 556 | 660 | template <__fmt_char_type _CharT> |
| 557 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year, _CharT> | |
| 661 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year, _CharT> | |
| 558 | 662 | : public __formatter_chrono<_CharT> { |
| 559 | 663 | public: |
| 560 | 664 | using _Base = __formatter_chrono<_CharT>; |
| 561 | 665 | |
| 562 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 563 | -> decltype(__parse_ctx.begin()) { | |
| 564 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year); | |
| 666 | template <class _ParseContext> | |
| 667 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 668 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year); | |
| 565 | 669 | } |
| 566 | 670 | }; |
| 567 | 671 | |
| 568 | 672 | template <__fmt_char_type _CharT> |
| 569 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday, _CharT> | |
| 673 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday, _CharT> | |
| 570 | 674 | : public __formatter_chrono<_CharT> { |
| 571 | 675 | public: |
| 572 | 676 | using _Base = __formatter_chrono<_CharT>; |
| 573 | 677 | |
| 574 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 575 | -> decltype(__parse_ctx.begin()) { | |
| 576 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 678 | template <class _ParseContext> | |
| 679 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 680 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 577 | 681 | } |
| 578 | 682 | }; |
| 579 | 683 | |
| 580 | 684 | template <__fmt_char_type _CharT> |
| 581 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_indexed, _CharT> | |
| 685 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_indexed, _CharT> | |
| 582 | 686 | : public __formatter_chrono<_CharT> { |
| 583 | 687 | public: |
| 584 | 688 | using _Base = __formatter_chrono<_CharT>; |
| 585 | 689 | |
| 586 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 587 | -> decltype(__parse_ctx.begin()) { | |
| 588 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 690 | template <class _ParseContext> | |
| 691 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 692 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 589 | 693 | } |
| 590 | 694 | }; |
| 591 | 695 | |
| 592 | 696 | template <__fmt_char_type _CharT> |
| 593 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::weekday_last, _CharT> | |
| 697 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::weekday_last, _CharT> | |
| 594 | 698 | : public __formatter_chrono<_CharT> { |
| 595 | 699 | public: |
| 596 | 700 | using _Base = __formatter_chrono<_CharT>; |
| 597 | 701 | |
| 598 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 599 | -> decltype(__parse_ctx.begin()) { | |
| 600 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 702 | template <class _ParseContext> | |
| 703 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 704 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__weekday); | |
| 601 | 705 | } |
| 602 | 706 | }; |
| 603 | 707 | |
| 604 | 708 | template <__fmt_char_type _CharT> |
| 605 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day, _CharT> | |
| 709 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day, _CharT> | |
| 606 | 710 | : public __formatter_chrono<_CharT> { |
| 607 | 711 | public: |
| 608 | 712 | using _Base = __formatter_chrono<_CharT>; |
| 609 | 713 | |
| 610 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 611 | -> decltype(__parse_ctx.begin()) { | |
| 612 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day); | |
| 714 | template <class _ParseContext> | |
| 715 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 716 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_day); | |
| 613 | 717 | } |
| 614 | 718 | }; |
| 615 | 719 | |
| 616 | 720 | template <__fmt_char_type _CharT> |
| 617 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_day_last, _CharT> | |
| 721 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_day_last, _CharT> | |
| 618 | 722 | : public __formatter_chrono<_CharT> { |
| 619 | 723 | public: |
| 620 | 724 | using _Base = __formatter_chrono<_CharT>; |
| 621 | 725 | |
| 622 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 623 | -> decltype(__parse_ctx.begin()) { | |
| 624 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); | |
| 726 | template <class _ParseContext> | |
| 727 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 728 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month); | |
| 625 | 729 | } |
| 626 | 730 | }; |
| 627 | 731 | |
| 628 | 732 | template <__fmt_char_type _CharT> |
| 629 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday, _CharT> | |
| 733 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday, _CharT> | |
| 630 | 734 | : public __formatter_chrono<_CharT> { |
| 631 | 735 | public: |
| 632 | 736 | using _Base = __formatter_chrono<_CharT>; |
| 633 | 737 | |
| 634 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 635 | -> decltype(__parse_ctx.begin()) { | |
| 636 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); | |
| 738 | template <class _ParseContext> | |
| 739 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 740 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); | |
| 637 | 741 | } |
| 638 | 742 | }; |
| 639 | 743 | |
| 640 | 744 | template <__fmt_char_type _CharT> |
| 641 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::month_weekday_last, _CharT> | |
| 745 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::month_weekday_last, _CharT> | |
| 642 | 746 | : public __formatter_chrono<_CharT> { |
| 643 | 747 | public: |
| 644 | 748 | using _Base = __formatter_chrono<_CharT>; |
| 645 | 749 | |
| 646 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 647 | -> decltype(__parse_ctx.begin()) { | |
| 648 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); | |
| 750 | template <class _ParseContext> | |
| 751 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 752 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__month_weekday); | |
| 649 | 753 | } |
| 650 | 754 | }; |
| 651 | 755 | |
| 652 | 756 | template <__fmt_char_type _CharT> |
| 653 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month, _CharT> | |
| 757 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month, _CharT> | |
| 654 | 758 | : public __formatter_chrono<_CharT> { |
| 655 | 759 | public: |
| 656 | 760 | using _Base = __formatter_chrono<_CharT>; |
| 657 | 761 | |
| 658 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 659 | -> decltype(__parse_ctx.begin()) { | |
| 660 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month); | |
| 762 | template <class _ParseContext> | |
| 763 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 764 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__year_month); | |
| 661 | 765 | } |
| 662 | 766 | }; |
| 663 | 767 | |
| 664 | 768 | template <__fmt_char_type _CharT> |
| 665 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day, _CharT> | |
| 769 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day, _CharT> | |
| 666 | 770 | : public __formatter_chrono<_CharT> { |
| 667 | 771 | public: |
| 668 | 772 | using _Base = __formatter_chrono<_CharT>; |
| 669 | 773 | |
| 670 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 671 | -> decltype(__parse_ctx.begin()) { | |
| 672 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 774 | template <class _ParseContext> | |
| 775 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 776 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 673 | 777 | } |
| 674 | 778 | }; |
| 675 | 779 | |
| 676 | 780 | template <__fmt_char_type _CharT> |
| 677 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_day_last, _CharT> | |
| 781 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_day_last, _CharT> | |
| 678 | 782 | : public __formatter_chrono<_CharT> { |
| 679 | 783 | public: |
| 680 | 784 | using _Base = __formatter_chrono<_CharT>; |
| 681 | 785 | |
| 682 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 683 | -> decltype(__parse_ctx.begin()) { | |
| 684 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 786 | template <class _ParseContext> | |
| 787 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 788 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 685 | 789 | } |
| 686 | 790 | }; |
| 687 | 791 | |
| 688 | 792 | template <__fmt_char_type _CharT> |
| 689 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday, _CharT> | |
| 793 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday, _CharT> | |
| 690 | 794 | : public __formatter_chrono<_CharT> { |
| 691 | 795 | public: |
| 692 | 796 | using _Base = __formatter_chrono<_CharT>; |
| 693 | 797 | |
| 694 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 695 | -> decltype(__parse_ctx.begin()) { | |
| 696 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 798 | template <class _ParseContext> | |
| 799 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 800 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 697 | 801 | } |
| 698 | 802 | }; |
| 699 | 803 | |
| 700 | 804 | template <__fmt_char_type _CharT> |
| 701 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<chrono::year_month_weekday_last, _CharT> | |
| 805 | struct _LIBCPP_TEMPLATE_VIS formatter<chrono::year_month_weekday_last, _CharT> | |
| 702 | 806 | : public __formatter_chrono<_CharT> { |
| 703 | 807 | public: |
| 704 | 808 | using _Base = __formatter_chrono<_CharT>; |
| 705 | 809 | |
| 706 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 707 | -> decltype(__parse_ctx.begin()) { | |
| 708 | return _Base::__parse(__parse_ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 810 | template <class _ParseContext> | |
| 811 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 812 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__date); | |
| 709 | 813 | } |
| 710 | 814 | }; |
| 711 | 815 | |
| 712 | #endif // if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 816 | template <class _Duration, __fmt_char_type _CharT> | |
| 817 | struct formatter<chrono::hh_mm_ss<_Duration>, _CharT> : public __formatter_chrono<_CharT> { | |
| 818 | public: | |
| 819 | using _Base = __formatter_chrono<_CharT>; | |
| 820 | ||
| 821 | template <class _ParseContext> | |
| 822 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 823 | return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time); | |
| 824 | } | |
| 825 | }; | |
| 826 | #endif // if _LIBCPP_STD_VER >= 20 | |
| 713 | 827 | |
| 714 | 828 | _LIBCPP_END_NAMESPACE_STD |
| 715 | 829 |
lib/libcxx/include/__chrono/hh_mm_ss.h+4-3| ... | ... | @@ -13,14 +13,14 @@ |
| 13 | 13 | #include <__chrono/duration.h> |
| 14 | 14 | #include <__chrono/time_point.h> |
| 15 | 15 | #include <__config> |
| 16 | #include <__type_traits/common_type.h> | |
| 16 | 17 | #include <ratio> |
| 17 | #include <type_traits> | |
| 18 | 18 | |
| 19 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| ... | ... | @@ -85,6 +85,7 @@ private: |
| 85 | 85 | chrono::seconds __s_; |
| 86 | 86 | precision __f_; |
| 87 | 87 | }; |
| 88 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss); | |
| 88 | 89 | |
| 89 | 90 | _LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } |
| 90 | 91 | _LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } |
| ... | ... | @@ -107,6 +108,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noe |
| 107 | 108 | |
| 108 | 109 | _LIBCPP_END_NAMESPACE_STD |
| 109 | 110 | |
| 110 | #endif // _LIBCPP_STD_VER > 17 | |
| 111 | #endif // _LIBCPP_STD_VER >= 20 | |
| 111 | 112 | |
| 112 | 113 | #endif // _LIBCPP___CHRONO_HH_MM_SS_H |
lib/libcxx/include/__chrono/literals.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -44,6 +44,6 @@ namespace chrono { // hoist the literals into namespace std::chrono |
| 44 | 44 | |
| 45 | 45 | _LIBCPP_END_NAMESPACE_STD |
| 46 | 46 | |
| 47 | #endif // _LIBCPP_STD_VER > 17 | |
| 47 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | 48 | |
| 49 | 49 | #endif // _LIBCPP___CHRONO_LITERALS_H |
lib/libcxx/include/__chrono/month.h+5-5| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -29,11 +29,11 @@ class month { |
| 29 | 29 | private: |
| 30 | 30 | unsigned char __m_; |
| 31 | 31 | public: |
| 32 | _LIBCPP_HIDE_FROM_ABI month() = default; | |
| 32 | month() = default; | |
| 33 | 33 | _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast<unsigned char>(__val)) {} |
| 34 | _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m_; return *this; } | |
| 34 | _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { *this += months{1}; return *this; } | |
| 35 | 35 | _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } |
| 36 | _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m_; return *this; } | |
| 36 | _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { *this -= months{1}; return *this; } | |
| 37 | 37 | _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } |
| 38 | 38 | _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; |
| 39 | 39 | _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; |
| ... | ... | @@ -98,6 +98,6 @@ inline constexpr month December{12}; |
| 98 | 98 | |
| 99 | 99 | _LIBCPP_END_NAMESPACE_STD |
| 100 | 100 | |
| 101 | #endif // _LIBCPP_STD_VER > 17 | |
| 101 | #endif // _LIBCPP_STD_VER >= 20 | |
| 102 | 102 | |
| 103 | 103 | #endif // _LIBCPP___CHRONO_MONTH_H |
lib/libcxx/include/__chrono/month_weekday.h+2-11| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| ... | ... | @@ -41,10 +41,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 41 | 41 | bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept |
| 42 | 42 | { return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } |
| 43 | 43 | |
| 44 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 45 | bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept | |
| 46 | { return !(__lhs == __rhs); } | |
| 47 | ||
| 48 | 44 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 49 | 45 | month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept |
| 50 | 46 | { return month_weekday{__lhs, __rhs}; } |
| ... | ... | @@ -77,11 +73,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 77 | 73 | bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept |
| 78 | 74 | { return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } |
| 79 | 75 | |
| 80 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 81 | bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept | |
| 82 | { return !(__lhs == __rhs); } | |
| 83 | ||
| 84 | ||
| 85 | 76 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 86 | 77 | month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept |
| 87 | 78 | { return month_weekday_last{__lhs, __rhs}; } |
| ... | ... | @@ -101,6 +92,6 @@ month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept |
| 101 | 92 | |
| 102 | 93 | _LIBCPP_END_NAMESPACE_STD |
| 103 | 94 | |
| 104 | #endif // _LIBCPP_STD_VER > 17 | |
| 95 | #endif // _LIBCPP_STD_VER >= 20 | |
| 105 | 96 | |
| 106 | 97 | #endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H |
lib/libcxx/include/__chrono/monthday.h+3-3| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| ... | ... | @@ -32,7 +32,7 @@ private: |
| 32 | 32 | chrono::month __m_; |
| 33 | 33 | chrono::day __d_; |
| 34 | 34 | public: |
| 35 | _LIBCPP_HIDE_FROM_ABI month_day() = default; | |
| 35 | month_day() = default; | |
| 36 | 36 | _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept |
| 37 | 37 | : __m_{__mval}, __d_{__dval} {} |
| 38 | 38 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } |
| ... | ... | @@ -124,6 +124,6 @@ month_day_last operator/(last_spec, int __rhs) noexcept |
| 124 | 124 | |
| 125 | 125 | _LIBCPP_END_NAMESPACE_STD |
| 126 | 126 | |
| 127 | #endif // _LIBCPP_STD_VER > 17 | |
| 127 | #endif // _LIBCPP_STD_VER >= 20 | |
| 128 | 128 | |
| 129 | 129 | #endif // _LIBCPP___CHRONO_MONTHDAY_H |
lib/libcxx/include/__chrono/ostream.h+54-28| ... | ... | @@ -10,12 +10,16 @@ |
| 10 | 10 | #ifndef _LIBCPP___CHRONO_OSTREAM_H |
| 11 | 11 | #define _LIBCPP___CHRONO_OSTREAM_H |
| 12 | 12 | |
| 13 | #include <__chrono/calendar.h> | |
| 13 | 14 | #include <__chrono/day.h> |
| 14 | 15 | #include <__chrono/duration.h> |
| 16 | #include <__chrono/file_clock.h> | |
| 17 | #include <__chrono/hh_mm_ss.h> | |
| 15 | 18 | #include <__chrono/month.h> |
| 16 | 19 | #include <__chrono/month_weekday.h> |
| 17 | 20 | #include <__chrono/monthday.h> |
| 18 | 21 | #include <__chrono/statically_widen.h> |
| 22 | #include <__chrono/system_clock.h> | |
| 19 | 23 | #include <__chrono/weekday.h> |
| 20 | 24 | #include <__chrono/year.h> |
| 21 | 25 | #include <__chrono/year_month.h> |
| ... | ... | @@ -33,10 +37,28 @@ |
| 33 | 37 | |
| 34 | 38 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 39 | |
| 36 | #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 40 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 41 | |
| 38 | 42 | namespace chrono { |
| 39 | 43 | |
| 44 | template <class _CharT, class _Traits, class _Duration> | |
| 45 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 46 | operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration> __tp) { | |
| 47 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp); | |
| 48 | } | |
| 49 | ||
| 50 | template <class _CharT, class _Traits, class _Duration> | |
| 51 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 52 | operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) { | |
| 53 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp); | |
| 54 | } | |
| 55 | ||
| 56 | template <class _CharT, class _Traits, class _Duration> | |
| 57 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 58 | operator<<(basic_ostream<_CharT, _Traits>& __os, const local_time<_Duration> __tp) { | |
| 59 | return __os << sys_time<_Duration>{__tp.time_since_epoch()}; | |
| 60 | } | |
| 61 | ||
| 40 | 62 | // Depending on the type the return is a const _CharT* or a basic_string<_CharT> |
| 41 | 63 | template <class _CharT, class _Period> |
| 42 | 64 | _LIBCPP_HIDE_FROM_ABI auto __units_suffix() { |
| ... | ... | @@ -92,7 +114,7 @@ _LIBCPP_HIDE_FROM_ABI auto __units_suffix() { |
| 92 | 114 | } |
| 93 | 115 | |
| 94 | 116 | template <class _CharT, class _Traits, class _Rep, class _Period> |
| 95 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 117 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 96 | 118 | operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) { |
| 97 | 119 | basic_ostringstream<_CharT, _Traits> __s; |
| 98 | 120 | __s.flags(__os.flags()); |
| ... | ... | @@ -103,21 +125,19 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& |
| 103 | 125 | } |
| 104 | 126 | |
| 105 | 127 | template <class _CharT, class _Traits> |
| 106 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 107 | operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) { | |
| 108 | return __os | |
| 109 | << (__d.ok() | |
| 110 | ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d) | |
| 111 | // Note this error differs from the wording of the Standard. The | |
| 112 | // Standard wording doesn't work well on AIX or Windows. There | |
| 113 | // the formatted day seems to be either modulo 100 or completely | |
| 114 | // omitted. Judging by the wording this is valid. | |
| 115 | // TODO FMT Write a paper of file an LWG issue. | |
| 116 | : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), static_cast<unsigned>(__d))); | |
| 128 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const day& __d) { | |
| 129 | return __os << (__d.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%d}"), __d) | |
| 130 | // Note this error differs from the wording of the Standard. The | |
| 131 | // Standard wording doesn't work well on AIX or Windows. There | |
| 132 | // the formatted day seems to be either modulo 100 or completely | |
| 133 | // omitted. Judging by the wording this is valid. | |
| 134 | // TODO FMT Write a paper of file an LWG issue. | |
| 135 | : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02} is not a valid day"), | |
| 136 | static_cast<unsigned>(__d))); | |
| 117 | 137 | } |
| 118 | 138 | |
| 119 | 139 | template <class _CharT, class _Traits> |
| 120 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 140 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 121 | 141 | operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) { |
| 122 | 142 | return __os << (__m.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%b}"), __m) |
| 123 | 143 | : std::format(__os.getloc(), |
| ... | ... | @@ -126,14 +146,14 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month& __m) { |
| 126 | 146 | } |
| 127 | 147 | |
| 128 | 148 | template <class _CharT, class _Traits> |
| 129 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 149 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 130 | 150 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year& __y) { |
| 131 | 151 | return __os << (__y.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y}"), __y) |
| 132 | 152 | : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), __y)); |
| 133 | 153 | } |
| 134 | 154 | |
| 135 | 155 | template <class _CharT, class _Traits> |
| 136 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 156 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 137 | 157 | operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) { |
| 138 | 158 | return __os << (__wd.ok() ? std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%a}"), __wd) |
| 139 | 159 | : std::format(__os.getloc(), // TODO FMT Standard mandated locale isn't used. |
| ... | ... | @@ -142,7 +162,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday& __wd) { |
| 142 | 162 | } |
| 143 | 163 | |
| 144 | 164 | template <class _CharT, class _Traits> |
| 145 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 165 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 146 | 166 | operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) { |
| 147 | 167 | auto __i = __wdi.index(); |
| 148 | 168 | return __os << (__i >= 1 && __i <= 5 |
| ... | ... | @@ -154,13 +174,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_indexed& __wdi) { |
| 154 | 174 | } |
| 155 | 175 | |
| 156 | 176 | template <class _CharT, class _Traits> |
| 157 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 177 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 158 | 178 | operator<<(basic_ostream<_CharT, _Traits>& __os, const weekday_last& __wdl) { |
| 159 | 179 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}[last]"), __wdl.weekday()); |
| 160 | 180 | } |
| 161 | 181 | |
| 162 | 182 | template <class _CharT, class _Traits> |
| 163 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 183 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 164 | 184 | operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) { |
| 165 | 185 | // TODO FMT The Standard allows 30th of February to be printed. |
| 166 | 186 | // It would be nice to show an error message instead. |
| ... | ... | @@ -168,47 +188,47 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day& __md) { |
| 168 | 188 | } |
| 169 | 189 | |
| 170 | 190 | template <class _CharT, class _Traits> |
| 171 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 191 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 172 | 192 | operator<<(basic_ostream<_CharT, _Traits>& __os, const month_day_last& __mdl) { |
| 173 | 193 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/last"), __mdl.month()); |
| 174 | 194 | } |
| 175 | 195 | |
| 176 | 196 | template <class _CharT, class _Traits> |
| 177 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 197 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 178 | 198 | operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday& __mwd) { |
| 179 | 199 | return __os << std::format( |
| 180 | 200 | __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwd.month(), __mwd.weekday_indexed()); |
| 181 | 201 | } |
| 182 | 202 | |
| 183 | 203 | template <class _CharT, class _Traits> |
| 184 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 204 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 185 | 205 | operator<<(basic_ostream<_CharT, _Traits>& __os, const month_weekday_last& __mwdl) { |
| 186 | 206 | return __os << std::format( |
| 187 | 207 | __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L}/{:L}"), __mwdl.month(), __mwdl.weekday_last()); |
| 188 | 208 | } |
| 189 | 209 | |
| 190 | 210 | template <class _CharT, class _Traits> |
| 191 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 211 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 192 | 212 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month& __ym) { |
| 193 | 213 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ym.year(), __ym.month()); |
| 194 | 214 | } |
| 195 | 215 | |
| 196 | 216 | template <class _CharT, class _Traits> |
| 197 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 217 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 198 | 218 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day& __ymd) { |
| 199 | 219 | return __os << (__ymd.ok() ? std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F}"), __ymd) |
| 200 | 220 | : std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), __ymd)); |
| 201 | 221 | } |
| 202 | 222 | |
| 203 | 223 | template <class _CharT, class _Traits> |
| 204 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 224 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 205 | 225 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_day_last& __ymdl) { |
| 206 | 226 | return __os << std::format( |
| 207 | 227 | __os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{}/{:L}"), __ymdl.year(), __ymdl.month_day_last()); |
| 208 | 228 | } |
| 209 | 229 | |
| 210 | 230 | template <class _CharT, class _Traits> |
| 211 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 231 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 212 | 232 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymwd) { |
| 213 | 233 | return __os << std::format( |
| 214 | 234 | __os.getloc(), |
| ... | ... | @@ -219,7 +239,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday& __ymw |
| 219 | 239 | } |
| 220 | 240 | |
| 221 | 241 | template <class _CharT, class _Traits> |
| 222 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT basic_ostream<_CharT, _Traits>& | |
| 242 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 223 | 243 | operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& __ymwdl) { |
| 224 | 244 | return __os << std::format( |
| 225 | 245 | __os.getloc(), |
| ... | ... | @@ -229,9 +249,15 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const year_month_weekday_last& |
| 229 | 249 | __ymwdl.weekday_last()); |
| 230 | 250 | } |
| 231 | 251 | |
| 252 | template <class _CharT, class _Traits, class _Duration> | |
| 253 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 254 | operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms) { | |
| 255 | return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms); | |
| 256 | } | |
| 257 | ||
| 232 | 258 | } // namespace chrono |
| 233 | 259 | |
| 234 | #endif //if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 260 | #endif // if _LIBCPP_STD_VER >= 20 | |
| 235 | 261 | |
| 236 | 262 | _LIBCPP_END_NAMESPACE_STD |
| 237 | 263 |
lib/libcxx/include/__chrono/parser_std_format_spec.h+27-20| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | namespace __format_spec { |
| 30 | 30 | |
| ... | ... | @@ -137,17 +137,19 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __validate_time_zone(__flags __flags) { |
| 137 | 137 | |
| 138 | 138 | template <class _CharT> |
| 139 | 139 | class _LIBCPP_TEMPLATE_VIS __parser_chrono { |
| 140 | using _ConstIterator = typename basic_format_parse_context<_CharT>::const_iterator; | |
| 141 | ||
| 140 | 142 | public: |
| 141 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 142 | __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields, __flags __flags) | |
| 143 | -> decltype(__parse_ctx.begin()) { | |
| 144 | const _CharT* __begin = __parser_.__parse(__parse_ctx, __fields); | |
| 145 | const _CharT* __end = __parse_ctx.end(); | |
| 143 | template <class _ParseContext> | |
| 144 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator | |
| 145 | __parse(_ParseContext& __ctx, __fields __fields, __flags __flags) { | |
| 146 | _ConstIterator __begin = __parser_.__parse(__ctx, __fields); | |
| 147 | _ConstIterator __end = __ctx.end(); | |
| 146 | 148 | if (__begin == __end) |
| 147 | 149 | return __begin; |
| 148 | 150 | |
| 149 | const _CharT* __last = __parse_chrono_specs(__begin, __end, __flags); | |
| 150 | __chrono_specs_ = basic_string_view<_CharT>{__begin, __last}; | |
| 151 | _ConstIterator __last = __parse_chrono_specs(__begin, __end, __flags); | |
| 152 | __chrono_specs_ = basic_string_view<_CharT>{__begin, __last}; | |
| 151 | 153 | |
| 152 | 154 | return __last; |
| 153 | 155 | } |
| ... | ... | @@ -156,19 +158,20 @@ public: |
| 156 | 158 | basic_string_view<_CharT> __chrono_specs_; |
| 157 | 159 | |
| 158 | 160 | private: |
| 159 | _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* | |
| 160 | __parse_chrono_specs(const _CharT* __begin, const _CharT* __end, __flags __flags) { | |
| 161 | _LIBCPP_ASSERT(__begin != __end, | |
| 162 | "When called with an empty input the function will cause " | |
| 163 | "undefined behavior by evaluating data not in the input"); | |
| 161 | _LIBCPP_HIDE_FROM_ABI constexpr _ConstIterator | |
| 162 | __parse_chrono_specs(_ConstIterator __begin, _ConstIterator __end, __flags __flags) { | |
| 163 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 164 | __begin != __end, | |
| 165 | "When called with an empty input the function will cause " | |
| 166 | "undefined behavior by evaluating data not in the input"); | |
| 164 | 167 | |
| 165 | 168 | if (*__begin != _CharT('%') && *__begin != _CharT('}')) |
| 166 | std::__throw_format_error("Expected '%' or '}' in the chrono format-string"); | |
| 169 | std::__throw_format_error("The format specifier expects a '%' or a '}'"); | |
| 167 | 170 | |
| 168 | 171 | do { |
| 169 | 172 | switch (*__begin) { |
| 170 | 173 | case _CharT('{'): |
| 171 | std::__throw_format_error("The chrono-specs contains a '{'"); | |
| 174 | std::__throw_format_error("The chrono specifiers contain a '{'"); | |
| 172 | 175 | |
| 173 | 176 | case _CharT('}'): |
| 174 | 177 | return __begin; |
| ... | ... | @@ -190,10 +193,10 @@ private: |
| 190 | 193 | /// \pre *__begin == '%' |
| 191 | 194 | /// \post __begin points at the end parsed conversion-spec |
| 192 | 195 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 193 | __parse_conversion_spec(const _CharT*& __begin, const _CharT* __end, __flags __flags) { | |
| 196 | __parse_conversion_spec(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) { | |
| 194 | 197 | ++__begin; |
| 195 | 198 | if (__begin == __end) |
| 196 | std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec"); | |
| 199 | std::__throw_format_error("End of input while parsing a conversion specifier"); | |
| 197 | 200 | |
| 198 | 201 | switch (*__begin) { |
| 199 | 202 | case _CharT('n'): |
| ... | ... | @@ -212,6 +215,7 @@ private: |
| 212 | 215 | case _CharT('p'): // TODO FMT does the formater require an hour or a time? |
| 213 | 216 | case _CharT('H'): |
| 214 | 217 | case _CharT('I'): |
| 218 | __parser_.__hour_ = true; | |
| 215 | 219 | __validate_hour(__flags); |
| 216 | 220 | break; |
| 217 | 221 | |
| ... | ... | @@ -219,6 +223,7 @@ private: |
| 219 | 223 | case _CharT('R'): |
| 220 | 224 | case _CharT('T'): |
| 221 | 225 | case _CharT('X'): |
| 226 | __parser_.__hour_ = true; | |
| 222 | 227 | __format_spec::__validate_time(__flags); |
| 223 | 228 | break; |
| 224 | 229 | |
| ... | ... | @@ -304,13 +309,14 @@ private: |
| 304 | 309 | /// \pre *__begin == 'E' |
| 305 | 310 | /// \post __begin is incremented by one. |
| 306 | 311 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 307 | __parse_modifier_E(const _CharT*& __begin, const _CharT* __end, __flags __flags) { | |
| 312 | __parse_modifier_E(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) { | |
| 308 | 313 | ++__begin; |
| 309 | 314 | if (__begin == __end) |
| 310 | 315 | std::__throw_format_error("End of input while parsing the modifier E"); |
| 311 | 316 | |
| 312 | 317 | switch (*__begin) { |
| 313 | 318 | case _CharT('X'): |
| 319 | __parser_.__hour_ = true; | |
| 314 | 320 | __format_spec::__validate_time(__flags); |
| 315 | 321 | break; |
| 316 | 322 | |
| ... | ... | @@ -343,7 +349,7 @@ private: |
| 343 | 349 | /// \pre *__begin == 'O' |
| 344 | 350 | /// \post __begin is incremented by one. |
| 345 | 351 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 346 | __parse_modifier_O(const _CharT*& __begin, const _CharT* __end, __flags __flags) { | |
| 352 | __parse_modifier_O(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) { | |
| 347 | 353 | ++__begin; |
| 348 | 354 | if (__begin == __end) |
| 349 | 355 | std::__throw_format_error("End of input while parsing the modifier O"); |
| ... | ... | @@ -359,6 +365,7 @@ private: |
| 359 | 365 | |
| 360 | 366 | case _CharT('I'): |
| 361 | 367 | case _CharT('H'): |
| 368 | __parser_.__hour_ = true; | |
| 362 | 369 | __format_spec::__validate_hour(__flags); |
| 363 | 370 | break; |
| 364 | 371 | |
| ... | ... | @@ -403,7 +410,7 @@ private: |
| 403 | 410 | |
| 404 | 411 | } // namespace __format_spec |
| 405 | 412 | |
| 406 | #endif //_LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 413 | #endif //_LIBCPP_STD_VER >= 20 | |
| 407 | 414 | |
| 408 | 415 | _LIBCPP_END_NAMESPACE_STD |
| 409 | 416 |
lib/libcxx/include/__chrono/statically_widen.h+3-3| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 28 | 28 | template <__fmt_char_type _CharT> |
| ... | ... | @@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s |
| 33 | 33 | return __wstr; |
| 34 | 34 | } |
| 35 | 35 | # define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str, L##__str) |
| 36 | # else // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 36 | # else // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 37 | 37 | |
| 38 | 38 | // Without this indirection the unit test test/libcxx/modules_include.sh.cpp |
| 39 | 39 | // fails for the CI build "No wide characters". This seems like a bug. |
| ... | ... | @@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s |
| 45 | 45 | # define _LIBCPP_STATICALLY_WIDEN(_CharT, __str) ::std::__statically_widen<_CharT>(__str) |
| 46 | 46 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 47 | 47 | |
| 48 | #endif //_LIBCPP_STD_VER > 17 | |
| 48 | #endif //_LIBCPP_STD_VER >= 20 | |
| 49 | 49 | |
| 50 | 50 | _LIBCPP_END_NAMESPACE_STD |
| 51 | 51 |
lib/libcxx/include/__chrono/steady_clock.h+1-1| ... | ... | @@ -24,7 +24,7 @@ namespace chrono |
| 24 | 24 | { |
| 25 | 25 | |
| 26 | 26 | #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK |
| 27 | class _LIBCPP_TYPE_VIS steady_clock | |
| 27 | class _LIBCPP_EXPORTED_FROM_ABI steady_clock | |
| 28 | 28 | { |
| 29 | 29 | public: |
| 30 | 30 | typedef nanoseconds duration; |
lib/libcxx/include/__chrono/system_clock.h+2-2| ... | ... | @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | namespace chrono |
| 25 | 25 | { |
| 26 | 26 | |
| 27 | class _LIBCPP_TYPE_VIS system_clock | |
| 27 | class _LIBCPP_EXPORTED_FROM_ABI system_clock | |
| 28 | 28 | { |
| 29 | 29 | public: |
| 30 | 30 | typedef microseconds duration; |
| ... | ... | @@ -38,7 +38,7 @@ public: |
| 38 | 38 | static time_point from_time_t(time_t __t) _NOEXCEPT; |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | #if _LIBCPP_STD_VER > 17 | |
| 41 | #if _LIBCPP_STD_VER >= 20 | |
| 42 | 42 | |
| 43 | 43 | template <class _Duration> |
| 44 | 44 | using sys_time = time_point<system_clock, _Duration>; |
lib/libcxx/include/__chrono/time_point.h+18-2| ... | ... | @@ -11,6 +11,8 @@ |
| 11 | 11 | #define _LIBCPP___CHRONO_TIME_POINT_H |
| 12 | 12 | |
| 13 | 13 | #include <__chrono/duration.h> |
| 14 | #include <__compare/ordering.h> | |
| 15 | #include <__compare/three_way_comparable.h> | |
| 14 | 16 | #include <__config> |
| 15 | 17 | #include <__type_traits/common_type.h> |
| 16 | 18 | #include <__type_traits/enable_if.h> |
| ... | ... | @@ -90,7 +92,7 @@ time_point_cast(const time_point<_Clock, _Duration>& __t) |
| 90 | 92 | return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); |
| 91 | 93 | } |
| 92 | 94 | |
| 93 | #if _LIBCPP_STD_VER > 14 | |
| 95 | #if _LIBCPP_STD_VER >= 17 | |
| 94 | 96 | template <class _ToDuration, class _Clock, class _Duration> |
| 95 | 97 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 96 | 98 | typename enable_if |
| ... | ... | @@ -138,7 +140,7 @@ abs(duration<_Rep, _Period> __d) |
| 138 | 140 | { |
| 139 | 141 | return __d >= __d.zero() ? +__d : -__d; |
| 140 | 142 | } |
| 141 | #endif // _LIBCPP_STD_VER > 14 | |
| 143 | #endif // _LIBCPP_STD_VER >= 17 | |
| 142 | 144 | |
| 143 | 145 | // time_point == |
| 144 | 146 | |
| ... | ... | @@ -150,6 +152,8 @@ operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, |
| 150 | 152 | return __lhs.time_since_epoch() == __rhs.time_since_epoch(); |
| 151 | 153 | } |
| 152 | 154 | |
| 155 | #if _LIBCPP_STD_VER <= 17 | |
| 156 | ||
| 153 | 157 | // time_point != |
| 154 | 158 | |
| 155 | 159 | template <class _Clock, class _Duration1, class _Duration2> |
| ... | ... | @@ -160,6 +164,8 @@ operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, |
| 160 | 164 | return !(__lhs == __rhs); |
| 161 | 165 | } |
| 162 | 166 | |
| 167 | #endif // _LIBCPP_STD_VER <= 17 | |
| 168 | ||
| 163 | 169 | // time_point < |
| 164 | 170 | |
| 165 | 171 | template <class _Clock, class _Duration1, class _Duration2> |
| ... | ... | @@ -200,6 +206,16 @@ operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, |
| 200 | 206 | return !(__lhs < __rhs); |
| 201 | 207 | } |
| 202 | 208 | |
| 209 | #if _LIBCPP_STD_VER >= 20 | |
| 210 | ||
| 211 | template <class _Clock, class _Duration1, three_way_comparable_with<_Duration1> _Duration2> | |
| 212 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 213 | operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { | |
| 214 | return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); | |
| 215 | } | |
| 216 | ||
| 217 | #endif // _LIBCPP_STD_VER >= 20 | |
| 218 | ||
| 203 | 219 | // time_point operator+(time_point x, duration y); |
| 204 | 220 | |
| 205 | 221 | template <class _Clock, class _Duration1, class _Rep2, class _Period2> |
lib/libcxx/include/__chrono/weekday.h+4-17| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| ... | ... | @@ -35,7 +35,7 @@ private: |
| 35 | 35 | unsigned char __wd_; |
| 36 | 36 | _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; |
| 37 | 37 | public: |
| 38 | _LIBCPP_HIDE_FROM_ABI weekday() = default; | |
| 38 | weekday() = default; | |
| 39 | 39 | _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast<unsigned char>(__val == 7 ? 0 : __val)) {} |
| 40 | 40 | _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept |
| 41 | 41 | : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} |
| ... | ... | @@ -69,10 +69,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 69 | 69 | bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept |
| 70 | 70 | { return __lhs.c_encoding() == __rhs.c_encoding(); } |
| 71 | 71 | |
| 72 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 73 | bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept | |
| 74 | { return !(__lhs == __rhs); } | |
| 75 | ||
| 76 | 72 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 77 | 73 | bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept |
| 78 | 74 | { return __lhs.c_encoding() < __rhs.c_encoding(); } |
| ... | ... | @@ -126,7 +122,7 @@ private: |
| 126 | 122 | chrono::weekday __wd_; |
| 127 | 123 | unsigned char __idx_; |
| 128 | 124 | public: |
| 129 | _LIBCPP_HIDE_FROM_ABI weekday_indexed() = default; | |
| 125 | weekday_indexed() = default; | |
| 130 | 126 | _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept |
| 131 | 127 | : __wd_{__wdval}, __idx_(__idxval) {} |
| 132 | 128 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } |
| ... | ... | @@ -138,11 +134,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 138 | 134 | bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept |
| 139 | 135 | { return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } |
| 140 | 136 | |
| 141 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 142 | bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept | |
| 143 | { return !(__lhs == __rhs); } | |
| 144 | ||
| 145 | ||
| 146 | 137 | class weekday_last { |
| 147 | 138 | private: |
| 148 | 139 | chrono::weekday __wd_; |
| ... | ... | @@ -157,10 +148,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 157 | 148 | bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept |
| 158 | 149 | { return __lhs.weekday() == __rhs.weekday(); } |
| 159 | 150 | |
| 160 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 161 | bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept | |
| 162 | { return !(__lhs == __rhs); } | |
| 163 | ||
| 164 | 151 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 165 | 152 | weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } |
| 166 | 153 | |
| ... | ... | @@ -180,6 +167,6 @@ inline constexpr weekday Saturday{6}; |
| 180 | 167 | |
| 181 | 168 | _LIBCPP_END_NAMESPACE_STD |
| 182 | 169 | |
| 183 | #endif // _LIBCPP_STD_VER > 17 | |
| 170 | #endif // _LIBCPP_STD_VER >= 20 | |
| 184 | 171 | |
| 185 | 172 | #endif // _LIBCPP___CHRONO_WEEKDAY_H |
lib/libcxx/include/__chrono/year.h+3-3| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | _LIBCPP_PUSH_MACROS |
| 23 | 23 | #include <__undef_macros> |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| ... | ... | @@ -33,7 +33,7 @@ class year { |
| 33 | 33 | private: |
| 34 | 34 | short __y_; |
| 35 | 35 | public: |
| 36 | _LIBCPP_HIDE_FROM_ABI year() = default; | |
| 36 | year() = default; | |
| 37 | 37 | _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast<short>(__val)) {} |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; } |
| ... | ... | @@ -95,7 +95,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { |
| 95 | 95 | |
| 96 | 96 | _LIBCPP_END_NAMESPACE_STD |
| 97 | 97 | |
| 98 | #endif // _LIBCPP_STD_VER > 17 | |
| 98 | #endif // _LIBCPP_STD_VER >= 20 | |
| 99 | 99 | |
| 100 | 100 | _LIBCPP_POP_MACROS |
| 101 | 101 |
lib/libcxx/include/__chrono/year_month.h+3-3| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| ... | ... | @@ -31,7 +31,7 @@ class year_month { |
| 31 | 31 | chrono::year __y_; |
| 32 | 32 | chrono::month __m_; |
| 33 | 33 | public: |
| 34 | _LIBCPP_HIDE_FROM_ABI year_month() = default; | |
| 34 | year_month() = default; | |
| 35 | 35 | _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept |
| 36 | 36 | : __y_{__yval}, __m_{__mval} {} |
| 37 | 37 | _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } |
| ... | ... | @@ -96,6 +96,6 @@ year_month operator-(const year_month& __lhs, const years& __rhs) noexcept |
| 96 | 96 | |
| 97 | 97 | _LIBCPP_END_NAMESPACE_STD |
| 98 | 98 | |
| 99 | #endif // _LIBCPP_STD_VER > 17 | |
| 99 | #endif // _LIBCPP_STD_VER >= 20 | |
| 100 | 100 | |
| 101 | 101 | #endif // _LIBCPP___CHRONO_YEAR_MONTH_H |
lib/libcxx/include/__chrono/year_month_day.h+3-3| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -42,7 +42,7 @@ private: |
| 42 | 42 | chrono::month __m_; |
| 43 | 43 | chrono::day __d_; |
| 44 | 44 | public: |
| 45 | _LIBCPP_HIDE_FROM_ABI year_month_day() = default; | |
| 45 | year_month_day() = default; | |
| 46 | 46 | _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( |
| 47 | 47 | const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept |
| 48 | 48 | : __y_{__yval}, __m_{__mval}, __d_{__dval} {} |
| ... | ... | @@ -302,6 +302,6 @@ bool year_month_day::ok() const noexcept |
| 302 | 302 | |
| 303 | 303 | _LIBCPP_END_NAMESPACE_STD |
| 304 | 304 | |
| 305 | #endif // _LIBCPP_STD_VER > 17 | |
| 305 | #endif // _LIBCPP_STD_VER >= 20 | |
| 306 | 306 | |
| 307 | 307 | #endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H |
lib/libcxx/include/__chrono/year_month_weekday.h+3-12| ... | ... | @@ -27,7 +27,7 @@ |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| ... | ... | @@ -39,7 +39,7 @@ class year_month_weekday { |
| 39 | 39 | chrono::month __m_; |
| 40 | 40 | chrono::weekday_indexed __wdi_; |
| 41 | 41 | public: |
| 42 | _LIBCPP_HIDE_FROM_ABI year_month_weekday() = default; | |
| 42 | year_month_weekday() = default; | |
| 43 | 43 | _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, |
| 44 | 44 | const chrono::weekday_indexed& __wdival) noexcept |
| 45 | 45 | : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} |
| ... | ... | @@ -98,10 +98,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 98 | 98 | bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept |
| 99 | 99 | { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } |
| 100 | 100 | |
| 101 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 102 | bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept | |
| 103 | { return !(__lhs == __rhs); } | |
| 104 | ||
| 105 | 101 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 106 | 102 | year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept |
| 107 | 103 | { return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } |
| ... | ... | @@ -191,11 +187,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 191 | 187 | bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept |
| 192 | 188 | { return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } |
| 193 | 189 | |
| 194 | _LIBCPP_HIDE_FROM_ABI inline constexpr | |
| 195 | bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept | |
| 196 | { return !(__lhs == __rhs); } | |
| 197 | ||
| 198 | ||
| 199 | 190 | _LIBCPP_HIDE_FROM_ABI inline constexpr |
| 200 | 191 | year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept |
| 201 | 192 | { return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } |
| ... | ... | @@ -250,6 +241,6 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekd |
| 250 | 241 | |
| 251 | 242 | _LIBCPP_END_NAMESPACE_STD |
| 252 | 243 | |
| 253 | #endif // _LIBCPP_STD_VER > 17 | |
| 244 | #endif // _LIBCPP_STD_VER >= 20 | |
| 254 | 245 | |
| 255 | 246 | #endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H |
lib/libcxx/include/__compare/common_comparison_category.h+7-7| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | namespace __comp_detail { |
| 26 | 26 | |
| ... | ... | @@ -65,14 +65,14 @@ _LIBCPP_HIDE_FROM_ABI |
| 65 | 65 | constexpr auto __get_comp_type() { |
| 66 | 66 | using _CCC = _ClassifyCompCategory; |
| 67 | 67 | constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; |
| 68 | constexpr _CCC _Cat = __comp_detail::__compute_comp_type(__type_kinds); | |
| 69 | if constexpr (_Cat == _None) | |
| 68 | constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds); | |
| 69 | if constexpr (__cat == _None) | |
| 70 | 70 | return void(); |
| 71 | else if constexpr (_Cat == _PartialOrd) | |
| 71 | else if constexpr (__cat == _PartialOrd) | |
| 72 | 72 | return partial_ordering::equivalent; |
| 73 | else if constexpr (_Cat == _WeakOrd) | |
| 73 | else if constexpr (__cat == _WeakOrd) | |
| 74 | 74 | return weak_ordering::equivalent; |
| 75 | else if constexpr (_Cat == _StrongOrd) | |
| 75 | else if constexpr (__cat == _StrongOrd) | |
| 76 | 76 | return strong_ordering::equivalent; |
| 77 | 77 | else |
| 78 | 78 | static_assert(_False, "unhandled case"); |
| ... | ... | @@ -88,7 +88,7 @@ struct _LIBCPP_TEMPLATE_VIS common_comparison_category { |
| 88 | 88 | template<class... _Ts> |
| 89 | 89 | using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; |
| 90 | 90 | |
| 91 | #endif // _LIBCPP_STD_VER > 17 | |
| 91 | #endif // _LIBCPP_STD_VER >= 20 | |
| 92 | 92 | |
| 93 | 93 | _LIBCPP_END_NAMESPACE_STD |
| 94 | 94 |
lib/libcxx/include/__compare/compare_partial_order_fallback.h+2-2| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | // [cmp.alg] |
| 29 | 29 | namespace __compare_partial_order_fallback { |
| ... | ... | @@ -67,7 +67,7 @@ inline namespace __cpo { |
| 67 | 67 | inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; |
| 68 | 68 | } // namespace __cpo |
| 69 | 69 | |
| 70 | #endif // _LIBCPP_STD_VER > 17 | |
| 70 | #endif // _LIBCPP_STD_VER >= 20 | |
| 71 | 71 | |
| 72 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 73 | 73 |
lib/libcxx/include/__compare/compare_strong_order_fallback.h+2-2| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | // [cmp.alg] |
| 29 | 29 | namespace __compare_strong_order_fallback { |
| ... | ... | @@ -64,7 +64,7 @@ inline namespace __cpo { |
| 64 | 64 | inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; |
| 65 | 65 | } // namespace __cpo |
| 66 | 66 | |
| 67 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 68 | 68 | |
| 69 | 69 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 70 |
lib/libcxx/include/__compare/compare_three_way.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | struct _LIBCPP_TEMPLATE_VIS compare_three_way |
| 26 | 26 | { |
| ... | ... | @@ -34,7 +34,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way |
| 34 | 34 | using is_transparent = void; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | #endif // _LIBCPP_STD_VER > 17 | |
| 37 | #endif // _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 40 | 40 |
lib/libcxx/include/__compare/compare_three_way_result.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | template<class, class, class> |
| 25 | 25 | struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; |
| ... | ... | @@ -37,7 +37,7 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_resul |
| 37 | 37 | template<class _Tp, class _Up = _Tp> |
| 38 | 38 | using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; |
| 39 | 39 | |
| 40 | #endif // _LIBCPP_STD_VER > 17 | |
| 40 | #endif // _LIBCPP_STD_VER >= 20 | |
| 41 | 41 | |
| 42 | 42 | _LIBCPP_END_NAMESPACE_STD |
| 43 | 43 |
lib/libcxx/include/__compare/compare_weak_order_fallback.h+2-2| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | // [cmp.alg] |
| 29 | 29 | namespace __compare_weak_order_fallback { |
| ... | ... | @@ -64,7 +64,7 @@ inline namespace __cpo { |
| 64 | 64 | inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; |
| 65 | 65 | } // namespace __cpo |
| 66 | 66 | |
| 67 | #endif // _LIBCPP_STD_VER > 17 | |
| 67 | #endif // _LIBCPP_STD_VER >= 20 | |
| 68 | 68 | |
| 69 | 69 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 70 |
lib/libcxx/include/__compare/is_eq.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_eq(partial_ordering __c) noexcept { return __c == 0; } |
| 24 | 24 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_neq(partial_ordering __c) noexcept { return __c != 0; } |
| ... | ... | @@ -27,7 +27,7 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_lteq(partial_ordering __c) noexce |
| 27 | 27 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gt(partial_ordering __c) noexcept { return __c > 0; } |
| 28 | 28 | _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexcept { return __c >= 0; } |
| 29 | 29 | |
| 30 | #endif // _LIBCPP_STD_VER > 17 | |
| 30 | #endif // _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 33 | 33 |
lib/libcxx/include/__compare/ordering.h+3-3| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // exposition only |
| 25 | 25 | enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { |
| ... | ... | @@ -40,7 +40,7 @@ template<class _Tp, class... _Args> |
| 40 | 40 | inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); |
| 41 | 41 | |
| 42 | 42 | struct _CmpUnspecifiedParam { |
| 43 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEVAL | |
| 43 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 44 | 44 | _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} |
| 45 | 45 | |
| 46 | 46 | template<class _Tp, class = enable_if_t<!__one_of_v<_Tp, int, partial_ordering, weak_ordering, strong_ordering>>> |
| ... | ... | @@ -319,7 +319,7 @@ inline constexpr strong_ordering strong_ordering::greater(_OrdResult::__greater) |
| 319 | 319 | template <class _Tp> |
| 320 | 320 | concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, strong_ordering>; |
| 321 | 321 | |
| 322 | #endif // _LIBCPP_STD_VER > 17 | |
| 322 | #endif // _LIBCPP_STD_VER >= 20 | |
| 323 | 323 | |
| 324 | 324 | _LIBCPP_END_NAMESPACE_STD |
| 325 | 325 |
lib/libcxx/include/__compare/partial_order.h+2-2| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | // [cmp.alg] |
| 30 | 30 | namespace __partial_order { |
| ... | ... | @@ -67,7 +67,7 @@ inline namespace __cpo { |
| 67 | 67 | inline constexpr auto partial_order = __partial_order::__fn{}; |
| 68 | 68 | } // namespace __cpo |
| 69 | 69 | |
| 70 | #endif // _LIBCPP_STD_VER > 17 | |
| 70 | #endif // _LIBCPP_STD_VER >= 20 | |
| 71 | 71 | |
| 72 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 73 | 73 |
lib/libcxx/include/__compare/strong_order.h+2-2| ... | ... | @@ -30,7 +30,7 @@ _LIBCPP_PUSH_MACROS |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | // [cmp.alg] |
| 36 | 36 | namespace __strong_order { |
| ... | ... | @@ -130,7 +130,7 @@ inline namespace __cpo { |
| 130 | 130 | inline constexpr auto strong_order = __strong_order::__fn{}; |
| 131 | 131 | } // namespace __cpo |
| 132 | 132 | |
| 133 | #endif // _LIBCPP_STD_VER > 17 | |
| 133 | #endif // _LIBCPP_STD_VER >= 20 | |
| 134 | 134 | |
| 135 | 135 | _LIBCPP_END_NAMESPACE_STD |
| 136 | 136 |
lib/libcxx/include/__compare/synth_three_way.h+23-17| ... | ... | @@ -21,30 +21,36 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | // [expos.only.func] |
| 27 | 27 | |
| 28 | _LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = | |
| 29 | []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u) | |
| 30 | requires requires { | |
| 31 | { __t < __u } -> __boolean_testable; | |
| 32 | { __u < __t } -> __boolean_testable; | |
| 33 | } | |
| 34 | { | |
| 35 | if constexpr (three_way_comparable_with<_Tp, _Up>) { | |
| 36 | return __t <=> __u; | |
| 37 | } else { | |
| 38 | if (__t < __u) return weak_ordering::less; | |
| 39 | if (__u < __t) return weak_ordering::greater; | |
| 40 | return weak_ordering::equivalent; | |
| 41 | } | |
| 42 | }; | |
| 28 | // TODO MODULES restore the lamba to match the Standard. | |
| 29 | // See https://github.com/llvm/llvm-project/issues/57222 | |
| 30 | //_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = | |
| 31 | // []<class _Tp, class _Up>(const _Tp& __t, const _Up& __u) | |
| 32 | template <class _Tp, class _Up> | |
| 33 | _LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up& __u) | |
| 34 | requires requires { | |
| 35 | { __t < __u } -> __boolean_testable; | |
| 36 | { __u < __t } -> __boolean_testable; | |
| 37 | } | |
| 38 | { | |
| 39 | if constexpr (three_way_comparable_with<_Tp, _Up>) { | |
| 40 | return __t <=> __u; | |
| 41 | } else { | |
| 42 | if (__t < __u) | |
| 43 | return weak_ordering::less; | |
| 44 | if (__u < __t) | |
| 45 | return weak_ordering::greater; | |
| 46 | return weak_ordering::equivalent; | |
| 47 | } | |
| 48 | } | |
| 43 | 49 | |
| 44 | 50 | template <class _Tp, class _Up = _Tp> |
| 45 | 51 | using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); |
| 46 | 52 | |
| 47 | #endif // _LIBCPP_STD_VER > 17 | |
| 53 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | 54 | |
| 49 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 50 | 56 |
lib/libcxx/include/__compare/three_way_comparable.h+2-2| ... | ... | @@ -25,7 +25,7 @@ |
| 25 | 25 | |
| 26 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | template<class _Tp, class _Cat> |
| 31 | 31 | concept __compares_as = |
| ... | ... | @@ -52,7 +52,7 @@ concept three_way_comparable_with = |
| 52 | 52 | { __u <=> __t } -> __compares_as<_Cat>; |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | #endif // _LIBCPP_STD_VER > 17 | |
| 55 | #endif // _LIBCPP_STD_VER >= 20 | |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 58 |
lib/libcxx/include/__compare/weak_order.h+2-2| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | // [cmp.alg] |
| 30 | 30 | namespace __weak_order { |
| ... | ... | @@ -95,7 +95,7 @@ inline namespace __cpo { |
| 95 | 95 | inline constexpr auto weak_order = __weak_order::__fn{}; |
| 96 | 96 | } // namespace __cpo |
| 97 | 97 | |
| 98 | #endif // _LIBCPP_STD_VER > 17 | |
| 98 | #endif // _LIBCPP_STD_VER >= 20 | |
| 99 | 99 | |
| 100 | 100 | _LIBCPP_END_NAMESPACE_STD |
| 101 | 101 |
lib/libcxx/include/__concepts/arithmetic.h+6-6| ... | ... | @@ -22,20 +22,20 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | // [concepts.arithmetic], arithmetic concepts |
| 28 | 28 | |
| 29 | template<class _Tp> | |
| 29 | template <class _Tp> | |
| 30 | 30 | concept integral = is_integral_v<_Tp>; |
| 31 | 31 | |
| 32 | template<class _Tp> | |
| 32 | template <class _Tp> | |
| 33 | 33 | concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; |
| 34 | 34 | |
| 35 | template<class _Tp> | |
| 35 | template <class _Tp> | |
| 36 | 36 | concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; |
| 37 | 37 | |
| 38 | template<class _Tp> | |
| 38 | template <class _Tp> | |
| 39 | 39 | concept floating_point = is_floating_point_v<_Tp>; |
| 40 | 40 | |
| 41 | 41 | // Concept helpers for the internal type traits for the fundamental types. |
| ... | ... | @@ -45,7 +45,7 @@ concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; |
| 45 | 45 | template <class _Tp> |
| 46 | 46 | concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; |
| 47 | 47 | |
| 48 | #endif // _LIBCPP_STD_VER > 17 | |
| 48 | #endif // _LIBCPP_STD_VER >= 20 | |
| 49 | 49 | |
| 50 | 50 | _LIBCPP_END_NAMESPACE_STD |
| 51 | 51 |
lib/libcxx/include/__concepts/assignable.h+8-8| ... | ... | @@ -22,19 +22,19 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | // [concept.assignable] |
| 28 | 28 | |
| 29 | template<class _Lhs, class _Rhs> | |
| 29 | template <class _Lhs, class _Rhs> | |
| 30 | 30 | concept assignable_from = |
| 31 | is_lvalue_reference_v<_Lhs> && | |
| 32 | common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && | |
| 33 | requires (_Lhs __lhs, _Rhs&& __rhs) { | |
| 34 | { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; | |
| 35 | }; | |
| 31 | is_lvalue_reference_v<_Lhs> && | |
| 32 | common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && | |
| 33 | requires(_Lhs __lhs, _Rhs&& __rhs) { | |
| 34 | { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; | |
| 35 | }; | |
| 36 | 36 | |
| 37 | #endif // _LIBCPP_STD_VER > 17 | |
| 37 | #endif // _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 40 | 40 |
lib/libcxx/include/__concepts/boolean_testable.h+4-4| ... | ... | @@ -19,19 +19,19 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concepts.booleantestable] |
| 25 | 25 | |
| 26 | template<class _Tp> | |
| 26 | template <class _Tp> | |
| 27 | 27 | concept __boolean_testable_impl = convertible_to<_Tp, bool>; |
| 28 | 28 | |
| 29 | template<class _Tp> | |
| 29 | template <class _Tp> | |
| 30 | 30 | concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { |
| 31 | 31 | { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl; |
| 32 | 32 | }; |
| 33 | 33 | |
| 34 | #endif // _LIBCPP_STD_VER > 17 | |
| 34 | #endif // _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_END_NAMESPACE_STD |
| 37 | 37 |
lib/libcxx/include/__concepts/class_or_enum.h+4-4| ... | ... | @@ -21,19 +21,19 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | // Whether a type is a class type or enumeration type according to the Core wording. |
| 27 | 27 | |
| 28 | template<class _Tp> | |
| 28 | template <class _Tp> | |
| 29 | 29 | concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; |
| 30 | 30 | |
| 31 | 31 | // Work around Clang bug https://llvm.org/PR52970 |
| 32 | 32 | // TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14). |
| 33 | template<class _Tp> | |
| 33 | template <class _Tp> | |
| 34 | 34 | concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>; |
| 35 | 35 | |
| 36 | #endif // _LIBCPP_STD_VER > 17 | |
| 36 | #endif // _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_END_NAMESPACE_STD |
| 39 | 39 |
lib/libcxx/include/__concepts/common_reference_with.h+5-6| ... | ... | @@ -20,17 +20,16 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | // [concept.commonref] |
| 26 | 26 | |
| 27 | template<class _Tp, class _Up> | |
| 27 | template <class _Tp, class _Up> | |
| 28 | 28 | concept common_reference_with = |
| 29 | same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> && | |
| 30 | convertible_to<_Tp, common_reference_t<_Tp, _Up>> && | |
| 31 | convertible_to<_Up, common_reference_t<_Tp, _Up>>; | |
| 29 | same_as<common_reference_t<_Tp, _Up>, common_reference_t<_Up, _Tp>> && | |
| 30 | convertible_to<_Tp, common_reference_t<_Tp, _Up>> && convertible_to<_Up, common_reference_t<_Tp, _Up>>; | |
| 32 | 31 | |
| 33 | #endif // _LIBCPP_STD_VER > 17 | |
| 32 | #endif // _LIBCPP_STD_VER >= 20 | |
| 34 | 33 | |
| 35 | 34 | _LIBCPP_END_NAMESPACE_STD |
| 36 | 35 |
lib/libcxx/include/__concepts/common_with.h+19-17| ... | ... | @@ -23,27 +23,29 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | // [concept.common] |
| 29 | 29 | |
| 30 | template<class _Tp, class _Up> | |
| 30 | // clang-format off | |
| 31 | template <class _Tp, class _Up> | |
| 31 | 32 | concept common_with = |
| 32 | same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> && | |
| 33 | requires { | |
| 34 | static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>()); | |
| 35 | static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>()); | |
| 36 | } && | |
| 37 | common_reference_with< | |
| 38 | add_lvalue_reference_t<const _Tp>, | |
| 39 | add_lvalue_reference_t<const _Up>> && | |
| 40 | common_reference_with< | |
| 41 | add_lvalue_reference_t<common_type_t<_Tp, _Up>>, | |
| 42 | common_reference_t< | |
| 43 | add_lvalue_reference_t<const _Tp>, | |
| 44 | add_lvalue_reference_t<const _Up>>>; | |
| 45 | ||
| 46 | #endif // _LIBCPP_STD_VER > 17 | |
| 33 | same_as<common_type_t<_Tp, _Up>, common_type_t<_Up, _Tp>> && | |
| 34 | requires { | |
| 35 | static_cast<common_type_t<_Tp, _Up>>(std::declval<_Tp>()); | |
| 36 | static_cast<common_type_t<_Tp, _Up>>(std::declval<_Up>()); | |
| 37 | } && | |
| 38 | common_reference_with< | |
| 39 | add_lvalue_reference_t<const _Tp>, | |
| 40 | add_lvalue_reference_t<const _Up>> && | |
| 41 | common_reference_with< | |
| 42 | add_lvalue_reference_t<common_type_t<_Tp, _Up>>, | |
| 43 | common_reference_t< | |
| 44 | add_lvalue_reference_t<const _Tp>, | |
| 45 | add_lvalue_reference_t<const _Up>>>; | |
| 46 | // clang-format on | |
| 47 | ||
| 48 | #endif // _LIBCPP_STD_VER >= 20 | |
| 47 | 49 | |
| 48 | 50 | _LIBCPP_END_NAMESPACE_STD |
| 49 | 51 |
lib/libcxx/include/__concepts/constructible.h+16-17| ... | ... | @@ -20,36 +20,35 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | // [concept.constructible] |
| 26 | template<class _Tp, class... _Args> | |
| 27 | concept constructible_from = | |
| 28 | destructible<_Tp> && is_constructible_v<_Tp, _Args...>; | |
| 26 | template <class _Tp, class... _Args> | |
| 27 | concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>; | |
| 29 | 28 | |
| 30 | 29 | // [concept.default.init] |
| 31 | 30 | |
| 32 | template<class _Tp> | |
| 31 | template <class _Tp> | |
| 33 | 32 | concept __default_initializable = requires { ::new _Tp; }; |
| 34 | 33 | |
| 35 | template<class _Tp> | |
| 36 | concept default_initializable = constructible_from<_Tp> && | |
| 37 | requires { _Tp{}; } && __default_initializable<_Tp>; | |
| 34 | template <class _Tp> | |
| 35 | concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>; | |
| 38 | 36 | |
| 39 | 37 | // [concept.moveconstructible] |
| 40 | template<class _Tp> | |
| 41 | concept move_constructible = | |
| 42 | constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; | |
| 38 | template <class _Tp> | |
| 39 | concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; | |
| 43 | 40 | |
| 44 | 41 | // [concept.copyconstructible] |
| 45 | template<class _Tp> | |
| 42 | // clang-format off | |
| 43 | template <class _Tp> | |
| 46 | 44 | concept copy_constructible = |
| 47 | move_constructible<_Tp> && | |
| 48 | constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && | |
| 49 | constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && | |
| 50 | constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; | |
| 45 | move_constructible<_Tp> && | |
| 46 | constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && | |
| 47 | constructible_from<_Tp, const _Tp&> && convertible_to<const _Tp&, _Tp> && | |
| 48 | constructible_from<_Tp, const _Tp> && convertible_to<const _Tp, _Tp>; | |
| 49 | // clang-format on | |
| 51 | 50 | |
| 52 | #endif // _LIBCPP_STD_VER > 17 | |
| 51 | #endif // _LIBCPP_STD_VER >= 20 | |
| 53 | 52 | |
| 54 | 53 | _LIBCPP_END_NAMESPACE_STD |
| 55 | 54 |
lib/libcxx/include/__concepts/convertible_to.h+4-8| ... | ... | @@ -19,18 +19,14 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concept.convertible] |
| 25 | 25 | |
| 26 | template<class _From, class _To> | |
| 27 | concept convertible_to = | |
| 28 | is_convertible_v<_From, _To> && | |
| 29 | requires { | |
| 30 | static_cast<_To>(std::declval<_From>()); | |
| 31 | }; | |
| 26 | template <class _From, class _To> | |
| 27 | concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast<_To>(std::declval<_From>()); }; | |
| 32 | 28 | |
| 33 | #endif // _LIBCPP_STD_VER > 17 | |
| 29 | #endif // _LIBCPP_STD_VER >= 20 | |
| 34 | 30 | |
| 35 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 36 | 32 |
lib/libcxx/include/__concepts/copyable.h+11-9| ... | ... | @@ -20,19 +20,21 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | // [concepts.object] |
| 26 | 26 | |
| 27 | template<class _Tp> | |
| 27 | // clang-format off | |
| 28 | template <class _Tp> | |
| 28 | 29 | concept copyable = |
| 29 | copy_constructible<_Tp> && | |
| 30 | movable<_Tp> && | |
| 31 | assignable_from<_Tp&, _Tp&> && | |
| 32 | assignable_from<_Tp&, const _Tp&> && | |
| 33 | assignable_from<_Tp&, const _Tp>; | |
| 34 | ||
| 35 | #endif // _LIBCPP_STD_VER > 17 | |
| 30 | copy_constructible<_Tp> && | |
| 31 | movable<_Tp> && | |
| 32 | assignable_from<_Tp&, _Tp&> && | |
| 33 | assignable_from<_Tp&, const _Tp&> && | |
| 34 | assignable_from<_Tp&, const _Tp>; | |
| 35 | // clang-format on | |
| 36 | ||
| 37 | #endif // _LIBCPP_STD_VER >= 20 | |
| 36 | 38 | |
| 37 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 38 | 40 |
lib/libcxx/include/__concepts/derived_from.h+4-6| ... | ... | @@ -19,16 +19,14 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concept.derived] |
| 25 | 25 | |
| 26 | template<class _Dp, class _Bp> | |
| 27 | concept derived_from = | |
| 28 | is_base_of_v<_Bp, _Dp> && | |
| 29 | is_convertible_v<const volatile _Dp*, const volatile _Bp*>; | |
| 26 | template <class _Dp, class _Bp> | |
| 27 | concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v<const volatile _Dp*, const volatile _Bp*>; | |
| 30 | 28 | |
| 31 | #endif // _LIBCPP_STD_VER > 17 | |
| 29 | #endif // _LIBCPP_STD_VER >= 20 | |
| 32 | 30 | |
| 33 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 32 |
lib/libcxx/include/__concepts/destructible.h+3-3| ... | ... | @@ -18,14 +18,14 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | // [concept.destructible] |
| 24 | 24 | |
| 25 | template<class _Tp> | |
| 25 | template <class _Tp> | |
| 26 | 26 | concept destructible = is_nothrow_destructible_v<_Tp>; |
| 27 | 27 | |
| 28 | #endif // _LIBCPP_STD_VER > 17 | |
| 28 | #endif // _LIBCPP_STD_VER >= 20 | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_END_NAMESPACE_STD |
| 31 | 31 |
lib/libcxx/include/__concepts/different_from.h+3-3| ... | ... | @@ -19,12 +19,12 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | template<class _Tp, class _Up> | |
| 24 | template <class _Tp, class _Up> | |
| 25 | 25 | concept __different_from = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>; |
| 26 | 26 | |
| 27 | #endif // _LIBCPP_STD_VER > 17 | |
| 27 | #endif // _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_END_NAMESPACE_STD |
| 30 | 30 |
lib/libcxx/include/__concepts/equality_comparable.h+22-20| ... | ... | @@ -21,33 +21,35 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | // [concept.equalitycomparable] |
| 27 | 27 | |
| 28 | template<class _Tp, class _Up> | |
| 28 | template <class _Tp, class _Up> | |
| 29 | 29 | concept __weakly_equality_comparable_with = |
| 30 | requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
| 31 | { __t == __u } -> __boolean_testable; | |
| 32 | { __t != __u } -> __boolean_testable; | |
| 33 | { __u == __t } -> __boolean_testable; | |
| 34 | { __u != __t } -> __boolean_testable; | |
| 35 | }; | |
| 36 | ||
| 37 | template<class _Tp> | |
| 30 | requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
| 31 | { __t == __u } -> __boolean_testable; | |
| 32 | { __t != __u } -> __boolean_testable; | |
| 33 | { __u == __t } -> __boolean_testable; | |
| 34 | { __u != __t } -> __boolean_testable; | |
| 35 | }; | |
| 36 | ||
| 37 | template <class _Tp> | |
| 38 | 38 | concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; |
| 39 | 39 | |
| 40 | template<class _Tp, class _Up> | |
| 40 | // clang-format off | |
| 41 | template <class _Tp, class _Up> | |
| 41 | 42 | concept equality_comparable_with = |
| 42 | equality_comparable<_Tp> && equality_comparable<_Up> && | |
| 43 | common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && | |
| 44 | equality_comparable< | |
| 45 | common_reference_t< | |
| 46 | __make_const_lvalue_ref<_Tp>, | |
| 47 | __make_const_lvalue_ref<_Up>>> && | |
| 48 | __weakly_equality_comparable_with<_Tp, _Up>; | |
| 49 | ||
| 50 | #endif // _LIBCPP_STD_VER > 17 | |
| 43 | equality_comparable<_Tp> && equality_comparable<_Up> && | |
| 44 | common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && | |
| 45 | equality_comparable< | |
| 46 | common_reference_t< | |
| 47 | __make_const_lvalue_ref<_Tp>, | |
| 48 | __make_const_lvalue_ref<_Up>>> && | |
| 49 | __weakly_equality_comparable_with<_Tp, _Up>; | |
| 50 | // clang-format on | |
| 51 | ||
| 52 | #endif // _LIBCPP_STD_VER >= 20 | |
| 51 | 53 | |
| 52 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 55 |
lib/libcxx/include/__concepts/invocable.h+4-4| ... | ... | @@ -19,21 +19,21 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concept.invocable] |
| 25 | 25 | |
| 26 | template<class _Fn, class... _Args> | |
| 26 | template <class _Fn, class... _Args> | |
| 27 | 27 | concept invocable = requires(_Fn&& __fn, _Args&&... __args) { |
| 28 | 28 | _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | 31 | // [concept.regular.invocable] |
| 32 | 32 | |
| 33 | template<class _Fn, class... _Args> | |
| 33 | template <class _Fn, class... _Args> | |
| 34 | 34 | concept regular_invocable = invocable<_Fn, _Args...>; |
| 35 | 35 | |
| 36 | #endif // _LIBCPP_STD_VER > 17 | |
| 36 | #endif // _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_END_NAMESPACE_STD |
| 39 | 39 |
lib/libcxx/include/__concepts/movable.h+4-8| ... | ... | @@ -21,18 +21,14 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | // [concepts.object] |
| 27 | 27 | |
| 28 | template<class _Tp> | |
| 29 | concept movable = | |
| 30 | is_object_v<_Tp> && | |
| 31 | move_constructible<_Tp> && | |
| 32 | assignable_from<_Tp&, _Tp> && | |
| 33 | swappable<_Tp>; | |
| 28 | template <class _Tp> | |
| 29 | concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>; | |
| 34 | 30 | |
| 35 | #endif // _LIBCPP_STD_VER > 17 | |
| 31 | #endif // _LIBCPP_STD_VER >= 20 | |
| 36 | 32 | |
| 37 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 38 | 34 |
lib/libcxx/include/__concepts/predicate.h+4-5| ... | ... | @@ -20,15 +20,14 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | // [concept.predicate] |
| 26 | 26 | |
| 27 | template<class _Fn, class... _Args> | |
| 28 | concept predicate = | |
| 29 | regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>; | |
| 27 | template <class _Fn, class... _Args> | |
| 28 | concept predicate = regular_invocable<_Fn, _Args...> && __boolean_testable<invoke_result_t<_Fn, _Args...>>; | |
| 30 | 29 | |
| 31 | #endif // _LIBCPP_STD_VER > 17 | |
| 30 | #endif // _LIBCPP_STD_VER >= 20 | |
| 32 | 31 | |
| 33 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 33 |
lib/libcxx/include/__concepts/regular.h+3-3| ... | ... | @@ -19,14 +19,14 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concept.object] |
| 25 | 25 | |
| 26 | template<class _Tp> | |
| 26 | template <class _Tp> | |
| 27 | 27 | concept regular = semiregular<_Tp> && equality_comparable<_Tp>; |
| 28 | 28 | |
| 29 | #endif // _LIBCPP_STD_VER > 17 | |
| 29 | #endif // _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 32 |
lib/libcxx/include/__concepts/relation.h+6-7| ... | ... | @@ -18,26 +18,25 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | // [concept.relation] |
| 24 | 24 | |
| 25 | template<class _Rp, class _Tp, class _Up> | |
| 25 | template <class _Rp, class _Tp, class _Up> | |
| 26 | 26 | concept relation = |
| 27 | predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && | |
| 28 | predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; | |
| 27 | predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; | |
| 29 | 28 | |
| 30 | 29 | // [concept.equiv] |
| 31 | 30 | |
| 32 | template<class _Rp, class _Tp, class _Up> | |
| 31 | template <class _Rp, class _Tp, class _Up> | |
| 33 | 32 | concept equivalence_relation = relation<_Rp, _Tp, _Up>; |
| 34 | 33 | |
| 35 | 34 | // [concept.strictweakorder] |
| 36 | 35 | |
| 37 | template<class _Rp, class _Tp, class _Up> | |
| 36 | template <class _Rp, class _Tp, class _Up> | |
| 38 | 37 | concept strict_weak_order = relation<_Rp, _Tp, _Up>; |
| 39 | 38 | |
| 40 | #endif // _LIBCPP_STD_VER > 17 | |
| 39 | #endif // _LIBCPP_STD_VER >= 20 | |
| 41 | 40 | |
| 42 | 41 | _LIBCPP_END_NAMESPACE_STD |
| 43 | 42 |
lib/libcxx/include/__concepts/same_as.h+4-4| ... | ... | @@ -18,17 +18,17 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | // [concept.same] |
| 24 | 24 | |
| 25 | template<class _Tp, class _Up> | |
| 25 | template <class _Tp, class _Up> | |
| 26 | 26 | concept __same_as_impl = _IsSame<_Tp, _Up>::value; |
| 27 | 27 | |
| 28 | template<class _Tp, class _Up> | |
| 28 | template <class _Tp, class _Up> | |
| 29 | 29 | concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; |
| 30 | 30 | |
| 31 | #endif // _LIBCPP_STD_VER > 17 | |
| 31 | #endif // _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 34 |
lib/libcxx/include/__concepts/semiregular.h+3-3| ... | ... | @@ -19,14 +19,14 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | // [concept.object] |
| 25 | 25 | |
| 26 | template<class _Tp> | |
| 26 | template <class _Tp> | |
| 27 | 27 | concept semiregular = copyable<_Tp> && default_initializable<_Tp>; |
| 28 | 28 | |
| 29 | #endif // _LIBCPP_STD_VER > 17 | |
| 29 | #endif // _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 32 |
lib/libcxx/include/__concepts/swappable.h+63-61| ... | ... | @@ -28,94 +28,96 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | _LIBCPP_PUSH_MACROS | |
| 32 | #include <__undef_macros> | |
| 33 | ||
| 31 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 35 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 37 | |
| 35 | 38 | // [concept.swappable] |
| 36 | 39 | |
| 37 | 40 | namespace ranges { |
| 38 | 41 | namespace __swap { |
| 39 | 42 | |
| 40 | template<class _Tp> | |
| 41 | void swap(_Tp&, _Tp&) = delete; | |
| 43 | template <class _Tp> | |
| 44 | void swap(_Tp&, _Tp&) = delete; | |
| 42 | 45 | |
| 43 | template<class _Tp, class _Up> | |
| 44 | concept __unqualified_swappable_with = | |
| 46 | // clang-format off | |
| 47 | template <class _Tp, class _Up> | |
| 48 | concept __unqualified_swappable_with = | |
| 45 | 49 | (__class_or_enum<remove_cvref_t<_Tp>> || __class_or_enum<remove_cvref_t<_Up>>) && |
| 46 | 50 | requires(_Tp&& __t, _Up&& __u) { |
| 47 | swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 51 | swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 48 | 52 | }; |
| 53 | // clang-format on | |
| 49 | 54 | |
| 50 | struct __fn; | |
| 55 | struct __fn; | |
| 51 | 56 | |
| 52 | template<class _Tp, class _Up, size_t _Size> | |
| 53 | concept __swappable_arrays = | |
| 54 | !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && | |
| 57 | // clang-format off | |
| 58 | template <class _Tp, class _Up, size_t _Size> | |
| 59 | concept __swappable_arrays = | |
| 60 | !__unqualified_swappable_with<_Tp (&)[_Size], _Up (&)[_Size]> && | |
| 55 | 61 | extent_v<_Tp> == extent_v<_Up> && |
| 56 | requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { | |
| 57 | __swap(__t[0], __u[0]); | |
| 62 | requires(_Tp (&__t)[_Size], _Up (&__u)[_Size], const __fn& __swap) { | |
| 63 | __swap(__t[0], __u[0]); | |
| 58 | 64 | }; |
| 59 | ||
| 60 | template<class _Tp> | |
| 61 | concept __exchangeable = | |
| 62 | !__unqualified_swappable_with<_Tp&, _Tp&> && | |
| 63 | move_constructible<_Tp> && | |
| 64 | assignable_from<_Tp&, _Tp>; | |
| 65 | ||
| 66 | struct __fn { | |
| 67 | // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... | |
| 68 | // *The name `swap` is used here unqualified. | |
| 69 | template<class _Tp, class _Up> | |
| 70 | requires __unqualified_swappable_with<_Tp, _Up> | |
| 71 | constexpr void operator()(_Tp&& __t, _Up&& __u) const | |
| 72 | noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) | |
| 73 | { | |
| 74 | swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 75 | } | |
| 76 | ||
| 77 | // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... | |
| 78 | template<class _Tp, class _Up, size_t _Size> | |
| 79 | requires __swappable_arrays<_Tp, _Up, _Size> | |
| 80 | constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const | |
| 81 | noexcept(noexcept((*this)(*__t, *__u))) | |
| 82 | { | |
| 83 | // TODO(cjdb): replace with `ranges::swap_ranges`. | |
| 84 | for (size_t __i = 0; __i < _Size; ++__i) { | |
| 85 | (*this)(__t[__i], __u[__i]); | |
| 86 | } | |
| 65 | // clang-format on | |
| 66 | ||
| 67 | template <class _Tp> | |
| 68 | concept __exchangeable = | |
| 69 | !__unqualified_swappable_with<_Tp&, _Tp&> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp>; | |
| 70 | ||
| 71 | struct __fn { | |
| 72 | // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... | |
| 73 | // *The name `swap` is used here unqualified. | |
| 74 | template <class _Tp, class _Up> | |
| 75 | requires __unqualified_swappable_with<_Tp, _Up> | |
| 76 | _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp&& __t, _Up&& __u) const | |
| 77 | noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) { | |
| 78 | swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 79 | } | |
| 80 | ||
| 81 | // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... | |
| 82 | template <class _Tp, class _Up, size_t _Size> | |
| 83 | requires __swappable_arrays<_Tp, _Up, _Size> | |
| 84 | _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp (&__t)[_Size], _Up (&__u)[_Size]) const | |
| 85 | noexcept(noexcept((*this)(*__t, *__u))) { | |
| 86 | // TODO(cjdb): replace with `ranges::swap_ranges`. | |
| 87 | for (size_t __i = 0; __i < _Size; ++__i) { | |
| 88 | (*this)(__t[__i], __u[__i]); | |
| 87 | 89 | } |
| 88 | ||
| 89 | // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... | |
| 90 | template<__exchangeable _Tp> | |
| 91 | constexpr void operator()(_Tp& __x, _Tp& __y) const | |
| 92 | noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) | |
| 93 | { | |
| 94 | __y = _VSTD::exchange(__x, _VSTD::move(__y)); | |
| 95 | } | |
| 96 | }; | |
| 90 | } | |
| 91 | ||
| 92 | // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... | |
| 93 | template <__exchangeable _Tp> | |
| 94 | _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp& __x, _Tp& __y) const | |
| 95 | noexcept(is_nothrow_move_constructible_v<_Tp>&& is_nothrow_move_assignable_v<_Tp>) { | |
| 96 | __y = _VSTD::exchange(__x, _VSTD::move(__y)); | |
| 97 | } | |
| 98 | }; | |
| 97 | 99 | } // namespace __swap |
| 98 | 100 | |
| 99 | 101 | inline namespace __cpo { |
| 100 | inline constexpr auto swap = __swap::__fn{}; | |
| 102 | inline constexpr auto swap = __swap::__fn{}; | |
| 101 | 103 | } // namespace __cpo |
| 102 | 104 | } // namespace ranges |
| 103 | 105 | |
| 104 | template<class _Tp> | |
| 106 | template <class _Tp> | |
| 105 | 107 | concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; |
| 106 | 108 | |
| 107 | template<class _Tp, class _Up> | |
| 108 | concept swappable_with = | |
| 109 | common_reference_with<_Tp, _Up> && | |
| 110 | requires(_Tp&& __t, _Up&& __u) { | |
| 111 | ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); | |
| 112 | ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); | |
| 113 | ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 114 | ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); | |
| 115 | }; | |
| 109 | template <class _Tp, class _Up> | |
| 110 | concept swappable_with = common_reference_with<_Tp, _Up> && requires(_Tp&& __t, _Up&& __u) { | |
| 111 | ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); | |
| 112 | ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); | |
| 113 | ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); | |
| 114 | ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); | |
| 115 | }; | |
| 116 | 116 | |
| 117 | #endif // _LIBCPP_STD_VER > 17 | |
| 117 | #endif // _LIBCPP_STD_VER >= 20 | |
| 118 | 118 | |
| 119 | 119 | _LIBCPP_END_NAMESPACE_STD |
| 120 | 120 | |
| 121 | _LIBCPP_POP_MACROS | |
| 122 | ||
| 121 | 123 | #endif // _LIBCPP___CONCEPTS_SWAPPABLE_H |
lib/libcxx/include/__concepts/totally_ordered.h+26-25| ... | ... | @@ -21,37 +21,38 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | // [concept.totallyordered] |
| 27 | 27 | |
| 28 | template<class _Tp, class _Up> | |
| 29 | concept __partially_ordered_with = | |
| 30 | requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
| 31 | { __t < __u } -> __boolean_testable; | |
| 32 | { __t > __u } -> __boolean_testable; | |
| 33 | { __t <= __u } -> __boolean_testable; | |
| 34 | { __t >= __u } -> __boolean_testable; | |
| 35 | { __u < __t } -> __boolean_testable; | |
| 36 | { __u > __t } -> __boolean_testable; | |
| 37 | { __u <= __t } -> __boolean_testable; | |
| 38 | { __u >= __t } -> __boolean_testable; | |
| 39 | }; | |
| 40 | ||
| 41 | template<class _Tp> | |
| 28 | template <class _Tp, class _Up> | |
| 29 | concept __partially_ordered_with = requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { | |
| 30 | { __t < __u } -> __boolean_testable; | |
| 31 | { __t > __u } -> __boolean_testable; | |
| 32 | { __t <= __u } -> __boolean_testable; | |
| 33 | { __t >= __u } -> __boolean_testable; | |
| 34 | { __u < __t } -> __boolean_testable; | |
| 35 | { __u > __t } -> __boolean_testable; | |
| 36 | { __u <= __t } -> __boolean_testable; | |
| 37 | { __u >= __t } -> __boolean_testable; | |
| 38 | }; | |
| 39 | ||
| 40 | template <class _Tp> | |
| 42 | 41 | concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; |
| 43 | 42 | |
| 44 | template<class _Tp, class _Up> | |
| 43 | // clang-format off | |
| 44 | template <class _Tp, class _Up> | |
| 45 | 45 | concept totally_ordered_with = |
| 46 | totally_ordered<_Tp> && totally_ordered<_Up> && | |
| 47 | equality_comparable_with<_Tp, _Up> && | |
| 48 | totally_ordered< | |
| 49 | common_reference_t< | |
| 50 | __make_const_lvalue_ref<_Tp>, | |
| 51 | __make_const_lvalue_ref<_Up>>> && | |
| 52 | __partially_ordered_with<_Tp, _Up>; | |
| 53 | ||
| 54 | #endif // _LIBCPP_STD_VER > 17 | |
| 46 | totally_ordered<_Tp> && totally_ordered<_Up> && | |
| 47 | equality_comparable_with<_Tp, _Up> && | |
| 48 | totally_ordered< | |
| 49 | common_reference_t< | |
| 50 | __make_const_lvalue_ref<_Tp>, | |
| 51 | __make_const_lvalue_ref<_Up>>> && | |
| 52 | __partially_ordered_with<_Tp, _Up>; | |
| 53 | // clang-format on | |
| 54 | ||
| 55 | #endif // _LIBCPP_STD_VER >= 20 | |
| 55 | 56 | |
| 56 | 57 | _LIBCPP_END_NAMESPACE_STD |
| 57 | 58 |
lib/libcxx/include/__condition_variable/condition_variable.h created+245| ... | ... | @@ -0,0 +1,245 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H | |
| 10 | #define _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H | |
| 11 | ||
| 12 | #include <__chrono/steady_clock.h> | |
| 13 | #include <__chrono/system_clock.h> | |
| 14 | #include <__chrono/time_point.h> | |
| 15 | #include <__config> | |
| 16 | #include <__mutex/mutex.h> | |
| 17 | #include <__mutex/unique_lock.h> | |
| 18 | #include <__system_error/system_error.h> | |
| 19 | #include <__threading_support> | |
| 20 | #include <__type_traits/enable_if.h> | |
| 21 | #include <__type_traits/is_floating_point.h> | |
| 22 | #include <__utility/move.h> | |
| 23 | #include <limits> | |
| 24 | #include <ratio> | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 27 | # pragma GCC system_header | |
| 28 | #endif | |
| 29 | ||
| 30 | _LIBCPP_PUSH_MACROS | |
| 31 | #include <__undef_macros> | |
| 32 | ||
| 33 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 34 | ||
| 35 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 36 | ||
| 37 | // enum class cv_status | |
| 38 | _LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout}; | |
| 39 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) | |
| 40 | ||
| 41 | class _LIBCPP_EXPORTED_FROM_ABI condition_variable { | |
| 42 | __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; | |
| 43 | ||
| 44 | public: | |
| 45 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default; | |
| 46 | ||
| 47 | # ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION | |
| 48 | ~condition_variable() = default; | |
| 49 | # else | |
| 50 | ~condition_variable(); | |
| 51 | # endif | |
| 52 | ||
| 53 | condition_variable(const condition_variable&) = delete; | |
| 54 | condition_variable& operator=(const condition_variable&) = delete; | |
| 55 | ||
| 56 | void notify_one() _NOEXCEPT; | |
| 57 | void notify_all() _NOEXCEPT; | |
| 58 | ||
| 59 | void wait(unique_lock<mutex>& __lk) _NOEXCEPT; | |
| 60 | template <class _Predicate> | |
| 61 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS void wait(unique_lock<mutex>& __lk, _Predicate __pred); | |
| 62 | ||
| 63 | template <class _Clock, class _Duration> | |
| 64 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status | |
| 65 | wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t); | |
| 66 | ||
| 67 | template <class _Clock, class _Duration, class _Predicate> | |
| 68 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool | |
| 69 | wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred); | |
| 70 | ||
| 71 | template <class _Rep, class _Period> | |
| 72 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS cv_status | |
| 73 | wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d); | |
| 74 | ||
| 75 | template <class _Rep, class _Period, class _Predicate> | |
| 76 | bool _LIBCPP_HIDE_FROM_ABI | |
| 77 | wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred); | |
| 78 | ||
| 79 | typedef __libcpp_condvar_t* native_handle_type; | |
| 80 | _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__cv_; } | |
| 81 | ||
| 82 | private: | |
| 83 | void | |
| 84 | __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 85 | # if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 86 | _LIBCPP_HIDE_FROM_ABI void | |
| 87 | __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 88 | # endif | |
| 89 | template <class _Clock> | |
| 90 | _LIBCPP_HIDE_FROM_ABI void | |
| 91 | __do_timed_wait(unique_lock<mutex>& __lk, chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 92 | }; | |
| 93 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 94 | ||
| 95 | template <class _Rep, class _Period> | |
| 96 | inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds> | |
| 97 | __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { | |
| 98 | using namespace chrono; | |
| 99 | using __ratio = ratio_divide<_Period, nano>; | |
| 100 | using __ns_rep = nanoseconds::rep; | |
| 101 | _Rep __result_float = __d.count() * __ratio::num / __ratio::den; | |
| 102 | ||
| 103 | _Rep __result_max = numeric_limits<__ns_rep>::max(); | |
| 104 | if (__result_float >= __result_max) { | |
| 105 | return nanoseconds::max(); | |
| 106 | } | |
| 107 | ||
| 108 | _Rep __result_min = numeric_limits<__ns_rep>::min(); | |
| 109 | if (__result_float <= __result_min) { | |
| 110 | return nanoseconds::min(); | |
| 111 | } | |
| 112 | ||
| 113 | return nanoseconds(static_cast<__ns_rep>(__result_float)); | |
| 114 | } | |
| 115 | ||
| 116 | template <class _Rep, class _Period> | |
| 117 | inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds> | |
| 118 | __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { | |
| 119 | using namespace chrono; | |
| 120 | if (__d.count() == 0) { | |
| 121 | return nanoseconds(0); | |
| 122 | } | |
| 123 | ||
| 124 | using __ratio = ratio_divide<_Period, nano>; | |
| 125 | using __ns_rep = nanoseconds::rep; | |
| 126 | __ns_rep __result_max = numeric_limits<__ns_rep>::max(); | |
| 127 | if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) { | |
| 128 | return nanoseconds::max(); | |
| 129 | } | |
| 130 | ||
| 131 | __ns_rep __result_min = numeric_limits<__ns_rep>::min(); | |
| 132 | if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) { | |
| 133 | return nanoseconds::min(); | |
| 134 | } | |
| 135 | ||
| 136 | __ns_rep __result = __d.count() * __ratio::num / __ratio::den; | |
| 137 | if (__result == 0) { | |
| 138 | return nanoseconds(1); | |
| 139 | } | |
| 140 | ||
| 141 | return nanoseconds(__result); | |
| 142 | } | |
| 143 | ||
| 144 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 145 | template <class _Predicate> | |
| 146 | void condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) { | |
| 147 | while (!__pred()) | |
| 148 | wait(__lk); | |
| 149 | } | |
| 150 | ||
| 151 | template <class _Clock, class _Duration> | |
| 152 | cv_status condition_variable::wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) { | |
| 153 | using namespace chrono; | |
| 154 | using __clock_tp_ns = time_point<_Clock, nanoseconds>; | |
| 155 | ||
| 156 | typename _Clock::time_point __now = _Clock::now(); | |
| 157 | if (__t <= __now) | |
| 158 | return cv_status::timeout; | |
| 159 | ||
| 160 | __clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch())); | |
| 161 | ||
| 162 | __do_timed_wait(__lk, __t_ns); | |
| 163 | return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; | |
| 164 | } | |
| 165 | ||
| 166 | template <class _Clock, class _Duration, class _Predicate> | |
| 167 | bool condition_variable::wait_until( | |
| 168 | unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t, _Predicate __pred) { | |
| 169 | while (!__pred()) { | |
| 170 | if (wait_until(__lk, __t) == cv_status::timeout) | |
| 171 | return __pred(); | |
| 172 | } | |
| 173 | return true; | |
| 174 | } | |
| 175 | ||
| 176 | template <class _Rep, class _Period> | |
| 177 | cv_status condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d) { | |
| 178 | using namespace chrono; | |
| 179 | if (__d <= __d.zero()) | |
| 180 | return cv_status::timeout; | |
| 181 | using __ns_rep = nanoseconds::rep; | |
| 182 | steady_clock::time_point __c_now = steady_clock::now(); | |
| 183 | ||
| 184 | # if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 185 | using __clock_tp_ns = time_point<steady_clock, nanoseconds>; | |
| 186 | __ns_rep __now_count_ns = std::__safe_nanosecond_cast(__c_now.time_since_epoch()).count(); | |
| 187 | # else | |
| 188 | using __clock_tp_ns = time_point<system_clock, nanoseconds>; | |
| 189 | __ns_rep __now_count_ns = std::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count(); | |
| 190 | # endif | |
| 191 | ||
| 192 | __ns_rep __d_ns_count = std::__safe_nanosecond_cast(__d).count(); | |
| 193 | ||
| 194 | if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) { | |
| 195 | __do_timed_wait(__lk, __clock_tp_ns::max()); | |
| 196 | } else { | |
| 197 | __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count))); | |
| 198 | } | |
| 199 | ||
| 200 | return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : cv_status::timeout; | |
| 201 | } | |
| 202 | ||
| 203 | template <class _Rep, class _Period, class _Predicate> | |
| 204 | inline bool | |
| 205 | condition_variable::wait_for(unique_lock<mutex>& __lk, const chrono::duration<_Rep, _Period>& __d, _Predicate __pred) { | |
| 206 | return wait_until(__lk, chrono::steady_clock::now() + __d, std::move(__pred)); | |
| 207 | } | |
| 208 | ||
| 209 | # if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 210 | inline void condition_variable::__do_timed_wait( | |
| 211 | unique_lock<mutex>& __lk, chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT { | |
| 212 | using namespace chrono; | |
| 213 | if (!__lk.owns_lock()) | |
| 214 | __throw_system_error(EPERM, "condition_variable::timed wait: mutex not locked"); | |
| 215 | nanoseconds __d = __tp.time_since_epoch(); | |
| 216 | timespec __ts; | |
| 217 | seconds __s = duration_cast<seconds>(__d); | |
| 218 | using __ts_sec = decltype(__ts.tv_sec); | |
| 219 | const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); | |
| 220 | if (__s.count() < __ts_sec_max) { | |
| 221 | __ts.tv_sec = static_cast<__ts_sec>(__s.count()); | |
| 222 | __ts.tv_nsec = (__d - __s).count(); | |
| 223 | } else { | |
| 224 | __ts.tv_sec = __ts_sec_max; | |
| 225 | __ts.tv_nsec = giga::num - 1; | |
| 226 | } | |
| 227 | int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts); | |
| 228 | if (__ec != 0 && __ec != ETIMEDOUT) | |
| 229 | __throw_system_error(__ec, "condition_variable timed_wait failed"); | |
| 230 | } | |
| 231 | # endif // _LIBCPP_HAS_COND_CLOCKWAIT | |
| 232 | ||
| 233 | template <class _Clock> | |
| 234 | inline void condition_variable::__do_timed_wait(unique_lock<mutex>& __lk, | |
| 235 | chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT { | |
| 236 | wait_for(__lk, __tp - _Clock::now()); | |
| 237 | } | |
| 238 | ||
| 239 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 240 | ||
| 241 | _LIBCPP_END_NAMESPACE_STD | |
| 242 | ||
| 243 | _LIBCPP_POP_MACROS | |
| 244 | ||
| 245 | #endif // _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H |
lib/libcxx/include/__config+270-69| ... | ... | @@ -35,10 +35,12 @@ |
| 35 | 35 | |
| 36 | 36 | #ifdef __cplusplus |
| 37 | 37 | |
| 38 | // The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html | |
| 39 | ||
| 38 | 40 | // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. |
| 39 | // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is | |
| 41 | // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is | |
| 40 | 42 | // defined to XXYYZZ. |
| 41 | # define _LIBCPP_VERSION 160001 | |
| 43 | # define _LIBCPP_VERSION 170000 | |
| 42 | 44 | |
| 43 | 45 | # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y |
| 44 | 46 | # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) |
| ... | ... | @@ -51,6 +53,7 @@ |
| 51 | 53 | # define _LIBCPP_FREESTANDING |
| 52 | 54 | # endif |
| 53 | 55 | |
| 56 | // NOLINTBEGIN(libcpp-cpp-version-check) | |
| 54 | 57 | # ifndef _LIBCPP_STD_VER |
| 55 | 58 | # if __cplusplus <= 201103L |
| 56 | 59 | # define _LIBCPP_STD_VER 11 |
| ... | ... | @@ -60,11 +63,14 @@ |
| 60 | 63 | # define _LIBCPP_STD_VER 17 |
| 61 | 64 | # elif __cplusplus <= 202002L |
| 62 | 65 | # define _LIBCPP_STD_VER 20 |
| 66 | # elif __cplusplus <= 202302L | |
| 67 | # define _LIBCPP_STD_VER 23 | |
| 63 | 68 | # else |
| 64 | 69 | // Expected release year of the next C++ standard |
| 65 | # define _LIBCPP_STD_VER 23 | |
| 70 | # define _LIBCPP_STD_VER 26 | |
| 66 | 71 | # endif |
| 67 | 72 | # endif // _LIBCPP_STD_VER |
| 73 | // NOLINTEND(libcpp-cpp-version-check) | |
| 68 | 74 | |
| 69 | 75 | # if defined(__ELF__) |
| 70 | 76 | # define _LIBCPP_OBJECT_FORMAT_ELF 1 |
| ... | ... | @@ -80,6 +86,8 @@ |
| 80 | 86 | // ... add new file formats here ... |
| 81 | 87 | # endif |
| 82 | 88 | |
| 89 | // ABI { | |
| 90 | ||
| 83 | 91 | # if _LIBCPP_ABI_VERSION >= 2 |
| 84 | 92 | // Change short string representation so that string data starts at offset 0, |
| 85 | 93 | // improving its alignment in some cases. |
| ... | ... | @@ -165,6 +173,12 @@ |
| 165 | 173 | # if defined(__FreeBSD__) |
| 166 | 174 | # define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR |
| 167 | 175 | # endif |
| 176 | // For XCOFF linkers, we have problems if we see a weak hidden version of a symbol | |
| 177 | // in user code (like you get with -fvisibility-inlines-hidden) and then a strong def | |
| 178 | // in the library, so we need to always rely on the library version. | |
| 179 | # if defined(_AIX) | |
| 180 | # define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION | |
| 181 | # endif | |
| 168 | 182 | # endif |
| 169 | 183 | |
| 170 | 184 | # if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2 |
| ... | ... | @@ -179,9 +193,137 @@ |
| 179 | 193 | # define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION |
| 180 | 194 | # endif |
| 181 | 195 | |
| 196 | // Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's | |
| 197 | // within the bounds of the original container and asserts it on every dereference. | |
| 198 | // | |
| 199 | // ABI impact: changes the iterator type of the relevant containers. | |
| 200 | // | |
| 201 | // Supported containers: | |
| 202 | // - `span`; | |
| 203 | // - `string_view`; | |
| 204 | // - `array`. | |
| 205 | // #define _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 206 | ||
| 207 | // } ABI | |
| 208 | ||
| 209 | // HARDENING { | |
| 210 | ||
| 211 | // TODO(hardening): remove this in LLVM 18. | |
| 212 | // This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes) | |
| 213 | // equivalent to setting the hardened mode. | |
| 214 | # ifdef _LIBCPP_ENABLE_ASSERTIONS | |
| 215 | # warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_ENABLE_HARDENED_MODE instead." | |
| 216 | # if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 | |
| 217 | # error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" | |
| 218 | # endif | |
| 219 | # if _LIBCPP_ENABLE_ASSERTIONS | |
| 220 | # define _LIBCPP_ENABLE_HARDENED_MODE 1 | |
| 221 | # endif | |
| 222 | # endif | |
| 223 | ||
| 224 | // Enables the hardened mode which consists of all checks intended to be used in production. Hardened mode prioritizes | |
| 225 | // security-critical checks that can be done with relatively little overhead in constant time. Mutually exclusive with | |
| 226 | // `_LIBCPP_ENABLE_DEBUG_MODE`. | |
| 227 | // | |
| 228 | // #define _LIBCPP_ENABLE_HARDENED_MODE 1 | |
| 229 | ||
| 230 | // Enables the debug mode which contains all the checks from the hardened mode and additionally more expensive checks | |
| 231 | // that may affect the complexity of algorithms. The debug mode is intended to be used for testing, not in production. | |
| 232 | // Mutually exclusive with `_LIBCPP_ENABLE_HARDENED_MODE`. | |
| 233 | // | |
| 234 | // #define _LIBCPP_ENABLE_DEBUG_MODE 1 | |
| 235 | ||
| 236 | // Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These | |
| 237 | // macros are only for internal use -- users should only pick one of the high-level hardening modes described above. | |
| 238 | // | |
| 239 | // - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and | |
| 240 | // a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid: | |
| 241 | // - the sentinel is reachable from the begin iterator; | |
| 242 | // - TODO(hardening): both iterators refer to the same container. | |
| 243 | // | |
| 244 | // - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through | |
| 245 | // the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access | |
| 246 | // a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like | |
| 247 | // `optional` and `function` are considered one-element containers for the purposes of this check. | |
| 248 | // | |
| 249 | // - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the | |
| 250 | // given ranges do not overlap. | |
| 251 | // | |
| 252 | // - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure | |
| 253 | // the containers have compatible allocators. | |
| 254 | // | |
| 255 | // - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on | |
| 256 | // user input. | |
| 257 | // | |
| 258 | // - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet. | |
| 259 | ||
| 260 | # ifndef _LIBCPP_ENABLE_HARDENED_MODE | |
| 261 | # define _LIBCPP_ENABLE_HARDENED_MODE _LIBCPP_ENABLE_HARDENED_MODE_DEFAULT | |
| 262 | # endif | |
| 263 | # if _LIBCPP_ENABLE_HARDENED_MODE != 0 && _LIBCPP_ENABLE_HARDENED_MODE != 1 | |
| 264 | # error "_LIBCPP_ENABLE_HARDENED_MODE must be set to 0 or 1." | |
| 265 | # endif | |
| 266 | ||
| 267 | # ifndef _LIBCPP_ENABLE_DEBUG_MODE | |
| 268 | # define _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_ENABLE_DEBUG_MODE_DEFAULT | |
| 269 | # endif | |
| 270 | # if _LIBCPP_ENABLE_DEBUG_MODE != 0 && _LIBCPP_ENABLE_DEBUG_MODE != 1 | |
| 271 | # error "_LIBCPP_ENABLE_DEBUG_MODE must be set to 0 or 1." | |
| 272 | # endif | |
| 273 | ||
| 274 | # if _LIBCPP_ENABLE_HARDENED_MODE && _LIBCPP_ENABLE_DEBUG_MODE | |
| 275 | # error "Only one of _LIBCPP_ENABLE_HARDENED_MODE and _LIBCPP_ENABLE_DEBUG_MODE can be enabled." | |
| 276 | # endif | |
| 277 | ||
| 278 | // Hardened mode checks. | |
| 279 | ||
| 280 | // clang-format off | |
| 281 | # if _LIBCPP_ENABLE_HARDENED_MODE | |
| 282 | ||
| 283 | // Enabled checks. | |
| 284 | # define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 285 | # define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 286 | // Disabled checks. | |
| 287 | // Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security | |
| 288 | // vulnerability. | |
| 289 | # define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) | |
| 290 | # define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) | |
| 291 | # define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) | |
| 292 | # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) | |
| 293 | ||
| 294 | // Debug mode checks. | |
| 295 | ||
| 296 | # elif _LIBCPP_ENABLE_DEBUG_MODE | |
| 297 | ||
| 298 | // All checks enabled. | |
| 299 | # define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 300 | # define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 301 | # define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 302 | # define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 303 | # define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 304 | # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) | |
| 305 | ||
| 306 | // Disable all checks if hardening is not enabled. | |
| 307 | ||
| 308 | # else | |
| 309 | ||
| 310 | // All checks disabled. | |
| 311 | # define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression) | |
| 312 | # define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression) | |
| 313 | # define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) | |
| 314 | # define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) | |
| 315 | # define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) | |
| 316 | # define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) | |
| 317 | ||
| 318 | # endif // _LIBCPP_ENABLE_HARDENED_MODE | |
| 319 | // clang-format on | |
| 320 | ||
| 321 | // } HARDENING | |
| 322 | ||
| 182 | 323 | # define _LIBCPP_TOSTRING2(x) #x |
| 183 | 324 | # define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) |
| 184 | 325 | |
| 326 | // NOLINTNEXTLINE(libcpp-cpp-version-check) | |
| 185 | 327 | # if __cplusplus < 201103L |
| 186 | 328 | # define _LIBCPP_CXX03_LANG |
| 187 | 329 | # endif |
| ... | ... | @@ -262,7 +404,11 @@ |
| 262 | 404 | // Incomplete features get their own specific disabling flags. This makes it |
| 263 | 405 | // easier to grep for target specific flags once the feature is complete. |
| 264 | 406 | # if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) |
| 265 | # define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT | |
| 407 | # define _LIBCPP_HAS_NO_INCOMPLETE_PSTL | |
| 408 | # endif | |
| 409 | ||
| 410 | # if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) | |
| 411 | # define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN | |
| 266 | 412 | # endif |
| 267 | 413 | |
| 268 | 414 | // Need to detect which libc we're using if we're on Linux. |
| ... | ... | @@ -300,8 +446,8 @@ |
| 300 | 446 | # endif // __BYTE_ORDER__ |
| 301 | 447 | |
| 302 | 448 | # ifdef __FreeBSD__ |
| 303 | # include <sys/endian.h> | |
| 304 | 449 | # include <osreldate.h> |
| 450 | # include <sys/endian.h> | |
| 305 | 451 | # if _BYTE_ORDER == _LITTLE_ENDIAN |
| 306 | 452 | # define _LIBCPP_LITTLE_ENDIAN |
| 307 | 453 | # else // _BYTE_ORDER == _LITTLE_ENDIAN |
| ... | ... | @@ -335,15 +481,6 @@ |
| 335 | 481 | # define _LIBCPP_HAS_OPEN_WITH_WCHAR |
| 336 | 482 | # endif // defined(_WIN32) |
| 337 | 483 | |
| 338 | # ifdef __sun__ | |
| 339 | # include <sys/isa_defs.h> | |
| 340 | # ifdef _LITTLE_ENDIAN | |
| 341 | # define _LIBCPP_LITTLE_ENDIAN | |
| 342 | # else | |
| 343 | # define _LIBCPP_BIG_ENDIAN | |
| 344 | # endif | |
| 345 | # endif // __sun__ | |
| 346 | ||
| 347 | 484 | # if defined(_AIX) && !defined(__64BIT__) |
| 348 | 485 | // The size of wchar is 2 byte on 32-bit mode on AIX. |
| 349 | 486 | # define _LIBCPP_SHORT_WCHAR 1 |
| ... | ... | @@ -388,7 +525,7 @@ |
| 388 | 525 | // When this option is used, the token passed to `std::random_device`'s |
| 389 | 526 | // constructor *must* be "/dev/urandom" -- anything else is an error. |
| 390 | 527 | # if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ |
| 391 | defined(__DragonFly__) || defined(__sun__) | |
| 528 | defined(__DragonFly__) | |
| 392 | 529 | # define _LIBCPP_USING_ARC4_RANDOM |
| 393 | 530 | # elif defined(__wasi__) || defined(__EMSCRIPTEN__) |
| 394 | 531 | # define _LIBCPP_USING_GETENTROPY |
| ... | ... | @@ -449,15 +586,24 @@ typedef __char32_t char32_t; |
| 449 | 586 | # endif |
| 450 | 587 | |
| 451 | 588 | # if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L |
| 452 | # define _LIBCPP_NO_EXCEPTIONS | |
| 589 | # define _LIBCPP_HAS_NO_EXCEPTIONS | |
| 453 | 590 | # endif |
| 454 | 591 | |
| 455 | 592 | # define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) |
| 456 | 593 | |
| 457 | 594 | # if defined(_LIBCPP_COMPILER_CLANG_BASED) |
| 458 | 595 | |
| 459 | # if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2) | |
| 460 | # define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT | |
| 596 | # if defined(__APPLE__) | |
| 597 | # if defined(__i386__) || defined(__x86_64__) | |
| 598 | // use old string layout on x86_64 and i386 | |
| 599 | # elif defined(__arm__) | |
| 600 | // use old string layout on arm (which does not include aarch64/arm64), except on watch ABIs | |
| 601 | # if defined(__ARM_ARCH_7K__) && __ARM_ARCH_7K__ >= 2 | |
| 602 | # define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT | |
| 603 | # endif | |
| 604 | # else | |
| 605 | # define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT | |
| 606 | # endif | |
| 461 | 607 | # endif |
| 462 | 608 | |
| 463 | 609 | // Objective-C++ features (opt-in) |
| ... | ... | @@ -535,9 +681,6 @@ typedef __char32_t char32_t; |
| 535 | 681 | # define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport) |
| 536 | 682 | # endif |
| 537 | 683 | |
| 538 | # define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS | |
| 539 | # define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS | |
| 540 | # define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS | |
| 541 | 684 | # define _LIBCPP_HIDDEN |
| 542 | 685 | # define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS |
| 543 | 686 | # define _LIBCPP_TEMPLATE_VIS |
| ... | ... | @@ -553,11 +696,8 @@ typedef __char32_t char32_t; |
| 553 | 696 | # endif |
| 554 | 697 | |
| 555 | 698 | # define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden") |
| 556 | # define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default") | |
| 557 | # define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default") | |
| 558 | 699 | # define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default") |
| 559 | 700 | # define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default") |
| 560 | # define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default") | |
| 561 | 701 | # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default") |
| 562 | 702 | # define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS |
| 563 | 703 | |
| ... | ... | @@ -666,7 +806,7 @@ typedef __char32_t char32_t; |
| 666 | 806 | |
| 667 | 807 | _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 668 | 808 | |
| 669 | # if _LIBCPP_STD_VER > 14 | |
| 809 | # if _LIBCPP_STD_VER >= 17 | |
| 670 | 810 | # define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ |
| 671 | 811 | _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { |
| 672 | 812 | # else |
| ... | ... | @@ -683,16 +823,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 683 | 823 | # define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, ""))) |
| 684 | 824 | # endif |
| 685 | 825 | |
| 686 | # ifndef __SIZEOF_INT128__ | |
| 826 | # if !defined(__SIZEOF_INT128__) || defined(_MSC_VER) | |
| 687 | 827 | # define _LIBCPP_HAS_NO_INT128 |
| 688 | 828 | # endif |
| 689 | 829 | |
| 690 | # ifndef __cpp_consteval | |
| 691 | # define _LIBCPP_CONSTEVAL _LIBCPP_CONSTEXPR | |
| 692 | # else | |
| 693 | # define _LIBCPP_CONSTEVAL consteval | |
| 694 | # endif | |
| 695 | ||
| 696 | 830 | # if __has_attribute(__malloc__) |
| 697 | 831 | # define _LIBCPP_NOALIAS __attribute__((__malloc__)) |
| 698 | 832 | # else |
| ... | ... | @@ -707,7 +841,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 707 | 841 | |
| 708 | 842 | # ifdef _LIBCPP_CXX03_LANG |
| 709 | 843 | # define _LIBCPP_DECLARE_STRONG_ENUM(x) \ |
| 710 | struct _LIBCPP_TYPE_VIS x { \ | |
| 844 | struct _LIBCPP_EXPORTED_FROM_ABI x { \ | |
| 711 | 845 | enum __lx |
| 712 | 846 | // clang-format off |
| 713 | 847 | # define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ |
| ... | ... | @@ -723,8 +857,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 723 | 857 | # define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) |
| 724 | 858 | # endif // _LIBCPP_CXX03_LANG |
| 725 | 859 | |
| 726 | # if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__sun__) || \ | |
| 727 | defined(__NetBSD__) | |
| 860 | # if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || defined(__NetBSD__) | |
| 728 | 861 | # define _LIBCPP_LOCALE__L_EXTENSIONS 1 |
| 729 | 862 | # endif |
| 730 | 863 | |
| ... | ... | @@ -764,7 +897,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 764 | 897 | # define _LIBCPP_HAS_DEFAULTRUNELOCALE |
| 765 | 898 | # endif |
| 766 | 899 | |
| 767 | # if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__) | |
| 900 | # if defined(__APPLE__) || defined(__FreeBSD__) | |
| 768 | 901 | # define _LIBCPP_WCTYPE_IS_MASK |
| 769 | 902 | # endif |
| 770 | 903 | |
| ... | ... | @@ -777,10 +910,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 777 | 910 | // Deprecations warnings are always enabled, except when users explicitly opt-out |
| 778 | 911 | // by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS. |
| 779 | 912 | # if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) |
| 780 | # if __has_attribute(deprecated) | |
| 781 | # define _LIBCPP_DEPRECATED __attribute__((deprecated)) | |
| 782 | # define _LIBCPP_DEPRECATED_(m) __attribute__((deprecated(m))) | |
| 783 | # elif _LIBCPP_STD_VER > 11 | |
| 913 | # if __has_attribute(__deprecated__) | |
| 914 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | |
| 915 | # define _LIBCPP_DEPRECATED_(m) __attribute__((__deprecated__(m))) | |
| 916 | # elif _LIBCPP_STD_VER >= 14 | |
| 784 | 917 | # define _LIBCPP_DEPRECATED [[deprecated]] |
| 785 | 918 | # define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]] |
| 786 | 919 | # else |
| ... | ... | @@ -798,29 +931,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 798 | 931 | # define _LIBCPP_DEPRECATED_IN_CXX11 |
| 799 | 932 | # endif |
| 800 | 933 | |
| 801 | # if _LIBCPP_STD_VER > 11 | |
| 934 | # if _LIBCPP_STD_VER >= 14 | |
| 802 | 935 | # define _LIBCPP_DEPRECATED_IN_CXX14 _LIBCPP_DEPRECATED |
| 803 | 936 | # else |
| 804 | 937 | # define _LIBCPP_DEPRECATED_IN_CXX14 |
| 805 | 938 | # endif |
| 806 | 939 | |
| 807 | # if _LIBCPP_STD_VER > 14 | |
| 940 | # if _LIBCPP_STD_VER >= 17 | |
| 808 | 941 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED |
| 809 | 942 | # else |
| 810 | 943 | # define _LIBCPP_DEPRECATED_IN_CXX17 |
| 811 | 944 | # endif |
| 812 | 945 | |
| 813 | # if _LIBCPP_STD_VER > 17 | |
| 946 | # if _LIBCPP_STD_VER >= 20 | |
| 814 | 947 | # define _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_DEPRECATED |
| 815 | 948 | # else |
| 816 | 949 | # define _LIBCPP_DEPRECATED_IN_CXX20 |
| 817 | 950 | # endif |
| 818 | 951 | |
| 819 | #if _LIBCPP_STD_VER >= 23 | |
| 820 | # define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED | |
| 821 | #else | |
| 822 | # define _LIBCPP_DEPRECATED_IN_CXX23 | |
| 823 | #endif | |
| 952 | # if _LIBCPP_STD_VER >= 23 | |
| 953 | # define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED | |
| 954 | # else | |
| 955 | # define _LIBCPP_DEPRECATED_IN_CXX23 | |
| 956 | # endif | |
| 824 | 957 | |
| 825 | 958 | # if !defined(_LIBCPP_HAS_NO_CHAR8_T) |
| 826 | 959 | # define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED |
| ... | ... | @@ -840,37 +973,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 840 | 973 | # endif |
| 841 | 974 | |
| 842 | 975 | # if _LIBCPP_STD_VER <= 11 |
| 843 | # define _LIBCPP_EXPLICIT_AFTER_CXX11 | |
| 976 | # define _LIBCPP_EXPLICIT_SINCE_CXX14 | |
| 977 | # else | |
| 978 | # define _LIBCPP_EXPLICIT_SINCE_CXX14 explicit | |
| 979 | # endif | |
| 980 | ||
| 981 | # if _LIBCPP_STD_VER >= 23 | |
| 982 | # define _LIBCPP_EXPLICIT_SINCE_CXX23 explicit | |
| 844 | 983 | # else |
| 845 | # define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit | |
| 984 | # define _LIBCPP_EXPLICIT_SINCE_CXX23 | |
| 846 | 985 | # endif |
| 847 | 986 | |
| 848 | # if _LIBCPP_STD_VER > 11 | |
| 987 | # if _LIBCPP_STD_VER >= 14 | |
| 849 | 988 | # define _LIBCPP_CONSTEXPR_SINCE_CXX14 constexpr |
| 850 | 989 | # else |
| 851 | 990 | # define _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 852 | 991 | # endif |
| 853 | 992 | |
| 854 | # if _LIBCPP_STD_VER > 14 | |
| 993 | # if _LIBCPP_STD_VER >= 17 | |
| 855 | 994 | # define _LIBCPP_CONSTEXPR_SINCE_CXX17 constexpr |
| 856 | 995 | # else |
| 857 | 996 | # define _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 858 | 997 | # endif |
| 859 | 998 | |
| 860 | # if _LIBCPP_STD_VER > 17 | |
| 999 | # if _LIBCPP_STD_VER >= 20 | |
| 861 | 1000 | # define _LIBCPP_CONSTEXPR_SINCE_CXX20 constexpr |
| 862 | 1001 | # else |
| 863 | 1002 | # define _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 864 | 1003 | # endif |
| 865 | 1004 | |
| 866 | # if _LIBCPP_STD_VER > 20 | |
| 1005 | # if _LIBCPP_STD_VER >= 23 | |
| 867 | 1006 | # define _LIBCPP_CONSTEXPR_SINCE_CXX23 constexpr |
| 868 | 1007 | # else |
| 869 | 1008 | # define _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| 870 | 1009 | # endif |
| 871 | 1010 | |
| 872 | 1011 | # if __has_cpp_attribute(nodiscard) |
| 873 | # define _LIBCPP_NODISCARD [[nodiscard]] | |
| 1012 | # define _LIBCPP_NODISCARD [[__nodiscard__]] | |
| 874 | 1013 | # else |
| 875 | 1014 | // We can't use GCC's [[gnu::warn_unused_result]] and |
| 876 | 1015 | // __attribute__((warn_unused_result)), because GCC does not silence them via |
| ... | ... | @@ -886,7 +1025,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 886 | 1025 | # define _LIBCPP_NODISCARD_EXT |
| 887 | 1026 | # endif |
| 888 | 1027 | |
| 889 | # if _LIBCPP_STD_VER > 17 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) | |
| 1028 | # if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) | |
| 890 | 1029 | # define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD |
| 891 | 1030 | # else |
| 892 | 1031 | # define _LIBCPP_NODISCARD_AFTER_CXX17 |
| ... | ... | @@ -899,8 +1038,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 899 | 1038 | # endif |
| 900 | 1039 | |
| 901 | 1040 | # ifndef _LIBCPP_HAS_NO_ASAN |
| 902 | extern "C" _LIBCPP_FUNC_VIS void | |
| 1041 | extern "C" _LIBCPP_EXPORTED_FROM_ABI void | |
| 903 | 1042 | __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); |
| 1043 | # if _LIBCPP_CLANG_VER >= 1600 | |
| 1044 | extern "C" _LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container( | |
| 1045 | const void*, const void*, const void*, const void*, const void*, const void*); | |
| 1046 | extern "C" _LIBCPP_EXPORTED_FROM_ABI int | |
| 1047 | __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*); | |
| 1048 | # endif | |
| 904 | 1049 | # endif |
| 905 | 1050 | |
| 906 | 1051 | // Try to find out if RTTI is disabled. |
| ... | ... | @@ -927,7 +1072,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 927 | 1072 | defined(__linux__) || \ |
| 928 | 1073 | defined(__GNU__) || \ |
| 929 | 1074 | defined(__APPLE__) || \ |
| 930 | defined(__sun__) || \ | |
| 931 | 1075 | defined(__MVS__) || \ |
| 932 | 1076 | defined(_AIX) || \ |
| 933 | 1077 | defined(__EMSCRIPTEN__) |
| ... | ... | @@ -1034,6 +1178,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1034 | 1178 | # define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK |
| 1035 | 1179 | # endif |
| 1036 | 1180 | |
| 1181 | # if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__) | |
| 1182 | # define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__)) | |
| 1183 | # else | |
| 1184 | # define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS | |
| 1185 | # endif | |
| 1186 | ||
| 1037 | 1187 | # if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) |
| 1038 | 1188 | # if defined(__clang__) && __has_attribute(acquire_capability) |
| 1039 | 1189 | // Work around the attribute handling in clang. When both __declspec and |
| ... | ... | @@ -1052,7 +1202,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1052 | 1202 | # define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) |
| 1053 | 1203 | # endif |
| 1054 | 1204 | |
| 1055 | # if _LIBCPP_STD_VER > 17 | |
| 1205 | # if _LIBCPP_STD_VER >= 20 | |
| 1056 | 1206 | # define _LIBCPP_CONSTINIT constinit |
| 1057 | 1207 | # elif __has_attribute(__require_constant_initialization__) |
| 1058 | 1208 | # define _LIBCPP_CONSTINIT __attribute__((__require_constant_initialization__)) |
| ... | ... | @@ -1099,6 +1249,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1099 | 1249 | # define _LIBCPP_PREFERRED_NAME(x) |
| 1100 | 1250 | # endif |
| 1101 | 1251 | |
| 1252 | # if __has_attribute(__no_sanitize__) | |
| 1253 | # define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__))) | |
| 1254 | # else | |
| 1255 | # define _LIBCPP_NO_SANITIZE(...) | |
| 1256 | # endif | |
| 1257 | ||
| 1102 | 1258 | // We often repeat things just for handling wide characters in the library. |
| 1103 | 1259 | // When wide characters are disabled, it can be useful to have a quick way of |
| 1104 | 1260 | // disabling it without having to resort to #if-#endif, which has a larger |
| ... | ... | @@ -1132,8 +1288,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1132 | 1288 | # define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS |
| 1133 | 1289 | # endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES |
| 1134 | 1290 | |
| 1135 | # define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") | |
| 1136 | # define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") | |
| 1291 | // clang-format off | |
| 1292 | # define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh()\")") _Pragma("push_macro(\"move(int, int)\")") _Pragma("push_macro(\"erase()\")") | |
| 1293 | # define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh()\")") _Pragma("pop_macro(\"move(int, int)\")") _Pragma("pop_macro(\"erase()\")") | |
| 1294 | // clang-format on | |
| 1137 | 1295 | |
| 1138 | 1296 | # ifndef _LIBCPP_NO_AUTO_LINK |
| 1139 | 1297 | # if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) |
| ... | ... | @@ -1189,7 +1347,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1189 | 1347 | // [[msvc::no_unique_address]], this should be preferred though. |
| 1190 | 1348 | # define _LIBCPP_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] |
| 1191 | 1349 | # elif __has_cpp_attribute(no_unique_address) |
| 1192 | # define _LIBCPP_NO_UNIQUE_ADDRESS [[no_unique_address]] | |
| 1350 | # define _LIBCPP_NO_UNIQUE_ADDRESS [[__no_unique_address__]] | |
| 1193 | 1351 | # else |
| 1194 | 1352 | # define _LIBCPP_NO_UNIQUE_ADDRESS /* nothing */ |
| 1195 | 1353 | // Note that this can be replaced by #error as soon as clang-cl |
| ... | ... | @@ -1252,13 +1410,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1252 | 1410 | // macro is used to mark them as such, which suppresses the |
| 1253 | 1411 | // '-Wctad-maybe-unsupported' compiler warning when CTAD is used in user code |
| 1254 | 1412 | // with these classes. |
| 1255 | #if _LIBCPP_STD_VER >= 17 | |
| 1256 | # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \ | |
| 1257 | template <class ..._Tag> \ | |
| 1258 | _ClassName(typename _Tag::__allow_ctad...) -> _ClassName<_Tag...> | |
| 1259 | #else | |
| 1260 | # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") | |
| 1261 | #endif | |
| 1413 | # if _LIBCPP_STD_VER >= 17 | |
| 1414 | # ifdef _LIBCPP_COMPILER_CLANG_BASED | |
| 1415 | # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \ | |
| 1416 | template <class... _Tag> \ | |
| 1417 | [[maybe_unused]] _ClassName(typename _Tag::__allow_ctad...)->_ClassName<_Tag...> | |
| 1418 | # else | |
| 1419 | # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(ClassName) \ | |
| 1420 | template <class... _Tag> \ | |
| 1421 | ClassName(typename _Tag::__allow_ctad...)->ClassName<_Tag...> | |
| 1422 | # endif | |
| 1423 | # else | |
| 1424 | # define _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(_ClassName) static_assert(true, "") | |
| 1425 | # endif | |
| 1262 | 1426 | |
| 1263 | 1427 | // TODO(varconst): currently, there are bugs in Clang's intrinsics when handling Objective-C++ `id`, so don't use |
| 1264 | 1428 | // compiler intrinsics in the Objective-C++ mode. |
| ... | ... | @@ -1266,6 +1430,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD |
| 1266 | 1430 | # define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS |
| 1267 | 1431 | # endif |
| 1268 | 1432 | |
| 1433 | # define _PSTL_PRAGMA(x) _Pragma(#x) | |
| 1434 | ||
| 1435 | // Enable SIMD for compilers that support OpenMP 4.0 | |
| 1436 | # if (defined(_OPENMP) && _OPENMP >= 201307) | |
| 1437 | ||
| 1438 | # define _PSTL_UDR_PRESENT | |
| 1439 | # define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd) | |
| 1440 | # define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd) | |
| 1441 | # define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM)) | |
| 1442 | # define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM)) | |
| 1443 | # define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM)) | |
| 1444 | # define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM)) | |
| 1445 | ||
| 1446 | // Declaration of reduction functor, where | |
| 1447 | // NAME - the name of the functor | |
| 1448 | // OP - type of the callable object with the reduction operation | |
| 1449 | // omp_in - refers to the local partial result | |
| 1450 | // omp_out - refers to the final value of the combiner operator | |
| 1451 | // omp_priv - refers to the private copy of the initial value | |
| 1452 | // omp_orig - refers to the original variable to be reduced | |
| 1453 | # define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \ | |
| 1454 | _PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig)) | |
| 1455 | ||
| 1456 | # else // (defined(_OPENMP) && _OPENMP >= 201307) | |
| 1457 | ||
| 1458 | # define _PSTL_PRAGMA_SIMD | |
| 1459 | # define _PSTL_PRAGMA_DECLARE_SIMD | |
| 1460 | # define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) | |
| 1461 | # define _PSTL_PRAGMA_SIMD_SCAN(PRM) | |
| 1462 | # define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) | |
| 1463 | # define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) | |
| 1464 | # define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) | |
| 1465 | ||
| 1466 | # endif // (defined(_OPENMP) && _OPENMP >= 201307) | |
| 1467 | ||
| 1468 | # define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED | |
| 1469 | ||
| 1269 | 1470 | #endif // __cplusplus |
| 1270 | 1471 | |
| 1271 | 1472 | #endif // _LIBCPP___CONFIG |
lib/libcxx/include/__coroutine/coroutine_handle.h+12-14| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | # pragma GCC system_header |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | |
| ... | ... | @@ -33,7 +33,6 @@ template <> |
| 33 | 33 | struct _LIBCPP_TEMPLATE_VIS coroutine_handle<void> { |
| 34 | 34 | public: |
| 35 | 35 | // [coroutine.handle.con], construct/reset |
| 36 | _LIBCPP_HIDE_FROM_ABI | |
| 37 | 36 | constexpr coroutine_handle() noexcept = default; |
| 38 | 37 | |
| 39 | 38 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -64,7 +63,7 @@ public: |
| 64 | 63 | |
| 65 | 64 | _LIBCPP_HIDE_FROM_ABI |
| 66 | 65 | bool done() const { |
| 67 | _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); | |
| 66 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); | |
| 68 | 67 | return __builtin_coro_done(__handle_); |
| 69 | 68 | } |
| 70 | 69 | |
| ... | ... | @@ -74,19 +73,19 @@ public: |
| 74 | 73 | |
| 75 | 74 | _LIBCPP_HIDE_FROM_ABI |
| 76 | 75 | void resume() const { |
| 77 | _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); | |
| 78 | _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); | |
| 76 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); | |
| 77 | _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); | |
| 79 | 78 | __builtin_coro_resume(__handle_); |
| 80 | 79 | } |
| 81 | 80 | |
| 82 | 81 | _LIBCPP_HIDE_FROM_ABI |
| 83 | 82 | void destroy() const { |
| 84 | _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); | |
| 83 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); | |
| 85 | 84 | __builtin_coro_destroy(__handle_); |
| 86 | 85 | } |
| 87 | 86 | |
| 88 | 87 | private: |
| 89 | bool __is_suspended() const { | |
| 88 | _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { | |
| 90 | 89 | // FIXME actually implement a check for if the coro is suspended. |
| 91 | 90 | return __handle_ != nullptr; |
| 92 | 91 | } |
| ... | ... | @@ -108,7 +107,6 @@ template <class _Promise> |
| 108 | 107 | struct _LIBCPP_TEMPLATE_VIS coroutine_handle { |
| 109 | 108 | public: |
| 110 | 109 | // [coroutine.handle.con], construct/reset |
| 111 | _LIBCPP_HIDE_FROM_ABI | |
| 112 | 110 | constexpr coroutine_handle() noexcept = default; |
| 113 | 111 | |
| 114 | 112 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -154,7 +152,7 @@ public: |
| 154 | 152 | |
| 155 | 153 | _LIBCPP_HIDE_FROM_ABI |
| 156 | 154 | bool done() const { |
| 157 | _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); | |
| 155 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "done() can be called only on suspended coroutines"); | |
| 158 | 156 | return __builtin_coro_done(__handle_); |
| 159 | 157 | } |
| 160 | 158 | |
| ... | ... | @@ -164,14 +162,14 @@ public: |
| 164 | 162 | |
| 165 | 163 | _LIBCPP_HIDE_FROM_ABI |
| 166 | 164 | void resume() const { |
| 167 | _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); | |
| 168 | _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); | |
| 165 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "resume() can be called only on suspended coroutines"); | |
| 166 | _LIBCPP_ASSERT_UNCATEGORIZED(!done(), "resume() has undefined behavior when the coroutine is done"); | |
| 169 | 167 | __builtin_coro_resume(__handle_); |
| 170 | 168 | } |
| 171 | 169 | |
| 172 | 170 | _LIBCPP_HIDE_FROM_ABI |
| 173 | 171 | void destroy() const { |
| 174 | _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); | |
| 172 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_suspended(), "destroy() can be called only on suspended coroutines"); | |
| 175 | 173 | __builtin_coro_destroy(__handle_); |
| 176 | 174 | } |
| 177 | 175 | |
| ... | ... | @@ -182,7 +180,7 @@ public: |
| 182 | 180 | } |
| 183 | 181 | |
| 184 | 182 | private: |
| 185 | bool __is_suspended() const { | |
| 183 | _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { | |
| 186 | 184 | // FIXME actually implement a check for if the coro is suspended. |
| 187 | 185 | return __handle_ != nullptr; |
| 188 | 186 | } |
| ... | ... | @@ -198,6 +196,6 @@ struct hash<coroutine_handle<_Tp>> { |
| 198 | 196 | |
| 199 | 197 | _LIBCPP_END_NAMESPACE_STD |
| 200 | 198 | |
| 201 | #endif // __LIBCPP_STD_VER > 17 | |
| 199 | #endif // __LIBCPP_STD_VER >= 20 | |
| 202 | 200 | |
| 203 | 201 | #endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H |
lib/libcxx/include/__coroutine/coroutine_traits.h+2-2| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | #if _LIBCPP_STD_VER > 17 | |
| 19 | #if _LIBCPP_STD_VER >= 20 | |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| ... | ... | @@ -48,6 +48,6 @@ struct coroutine_traits |
| 48 | 48 | |
| 49 | 49 | _LIBCPP_END_NAMESPACE_STD |
| 50 | 50 | |
| 51 | #endif // __LIBCPP_STD_VER > 17 | |
| 51 | #endif // __LIBCPP_STD_VER >= 20 | |
| 52 | 52 | |
| 53 | 53 | #endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H |
lib/libcxx/include/__coroutine/noop_coroutine_handle.h+2-2| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | #if _LIBCPP_STD_VER > 17 | |
| 19 | #if _LIBCPP_STD_VER >= 20 | |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| ... | ... | @@ -107,6 +107,6 @@ noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle() |
| 107 | 107 | |
| 108 | 108 | _LIBCPP_END_NAMESPACE_STD |
| 109 | 109 | |
| 110 | #endif // __LIBCPP_STD_VER > 17 | |
| 110 | #endif // __LIBCPP_STD_VER >= 20 | |
| 111 | 111 | |
| 112 | 112 | #endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H |
lib/libcxx/include/__coroutine/trivial_awaitables.h+2-2| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | #if _LIBCPP_STD_VER > 17 | |
| 19 | #if _LIBCPP_STD_VER >= 20 | |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| ... | ... | @@ -41,6 +41,6 @@ struct suspend_always { |
| 41 | 41 | |
| 42 | 42 | _LIBCPP_END_NAMESPACE_STD |
| 43 | 43 | |
| 44 | #endif // __LIBCPP_STD_VER > 17 | |
| 44 | #endif // __LIBCPP_STD_VER >= 20 | |
| 45 | 45 | |
| 46 | 46 | #endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H |
lib/libcxx/include/__debug deleted-266| ... | ... | @@ -1,266 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___DEBUG | |
| 11 | #define _LIBCPP___DEBUG | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <__type_traits/is_constant_evaluated.h> | |
| 16 | #include <cstddef> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | #if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) | |
| 23 | # define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY | |
| 24 | #endif | |
| 25 | ||
| 26 | #if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING) | |
| 27 | # define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 28 | #endif | |
| 29 | ||
| 30 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 31 | # define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m) | |
| 32 | #else | |
| 33 | # define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) | |
| 34 | #endif | |
| 35 | ||
| 36 | #if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 37 | ||
| 38 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 39 | ||
| 40 | struct _LIBCPP_TYPE_VIS __c_node; | |
| 41 | ||
| 42 | struct _LIBCPP_TYPE_VIS __i_node | |
| 43 | { | |
| 44 | void* __i_; | |
| 45 | __i_node* __next_; | |
| 46 | __c_node* __c_; | |
| 47 | ||
| 48 | __i_node(const __i_node&) = delete; | |
| 49 | __i_node& operator=(const __i_node&) = delete; | |
| 50 | ||
| 51 | _LIBCPP_INLINE_VISIBILITY | |
| 52 | __i_node(void* __i, __i_node* __next, __c_node* __c) | |
| 53 | : __i_(__i), __next_(__next), __c_(__c) {} | |
| 54 | ~__i_node(); | |
| 55 | }; | |
| 56 | ||
| 57 | struct _LIBCPP_TYPE_VIS __c_node | |
| 58 | { | |
| 59 | void* __c_; | |
| 60 | __c_node* __next_; | |
| 61 | __i_node** beg_; | |
| 62 | __i_node** end_; | |
| 63 | __i_node** cap_; | |
| 64 | ||
| 65 | __c_node(const __c_node&) = delete; | |
| 66 | __c_node& operator=(const __c_node&) = delete; | |
| 67 | ||
| 68 | _LIBCPP_INLINE_VISIBILITY | |
| 69 | explicit __c_node(void* __c, __c_node* __next) | |
| 70 | : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} | |
| 71 | virtual ~__c_node(); | |
| 72 | ||
| 73 | virtual bool __dereferenceable(const void*) const = 0; | |
| 74 | virtual bool __decrementable(const void*) const = 0; | |
| 75 | virtual bool __addable(const void*, ptrdiff_t) const = 0; | |
| 76 | virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; | |
| 77 | ||
| 78 | void __add(__i_node* __i); | |
| 79 | _LIBCPP_HIDDEN void __remove(__i_node* __i); | |
| 80 | }; | |
| 81 | ||
| 82 | template <class _Cont> | |
| 83 | struct _C_node | |
| 84 | : public __c_node | |
| 85 | { | |
| 86 | explicit _C_node(void* __c, __c_node* __n) | |
| 87 | : __c_node(__c, __n) {} | |
| 88 | ||
| 89 | bool __dereferenceable(const void*) const override; | |
| 90 | bool __decrementable(const void*) const override; | |
| 91 | bool __addable(const void*, ptrdiff_t) const override; | |
| 92 | bool __subscriptable(const void*, ptrdiff_t) const override; | |
| 93 | }; | |
| 94 | ||
| 95 | template <class _Cont> | |
| 96 | inline bool | |
| 97 | _C_node<_Cont>::__dereferenceable(const void* __i) const | |
| 98 | { | |
| 99 | typedef typename _Cont::const_iterator iterator; | |
| 100 | const iterator* __j = static_cast<const iterator*>(__i); | |
| 101 | _Cont* _Cp = static_cast<_Cont*>(__c_); | |
| 102 | return _Cp->__dereferenceable(__j); | |
| 103 | } | |
| 104 | ||
| 105 | template <class _Cont> | |
| 106 | inline bool | |
| 107 | _C_node<_Cont>::__decrementable(const void* __i) const | |
| 108 | { | |
| 109 | typedef typename _Cont::const_iterator iterator; | |
| 110 | const iterator* __j = static_cast<const iterator*>(__i); | |
| 111 | _Cont* _Cp = static_cast<_Cont*>(__c_); | |
| 112 | return _Cp->__decrementable(__j); | |
| 113 | } | |
| 114 | ||
| 115 | template <class _Cont> | |
| 116 | inline bool | |
| 117 | _C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const | |
| 118 | { | |
| 119 | typedef typename _Cont::const_iterator iterator; | |
| 120 | const iterator* __j = static_cast<const iterator*>(__i); | |
| 121 | _Cont* _Cp = static_cast<_Cont*>(__c_); | |
| 122 | return _Cp->__addable(__j, __n); | |
| 123 | } | |
| 124 | ||
| 125 | template <class _Cont> | |
| 126 | inline bool | |
| 127 | _C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const | |
| 128 | { | |
| 129 | typedef typename _Cont::const_iterator iterator; | |
| 130 | const iterator* __j = static_cast<const iterator*>(__i); | |
| 131 | _Cont* _Cp = static_cast<_Cont*>(__c_); | |
| 132 | return _Cp->__subscriptable(__j, __n); | |
| 133 | } | |
| 134 | ||
| 135 | class _LIBCPP_TYPE_VIS __libcpp_db | |
| 136 | { | |
| 137 | __c_node** __cbeg_; | |
| 138 | __c_node** __cend_; | |
| 139 | size_t __csz_; | |
| 140 | __i_node** __ibeg_; | |
| 141 | __i_node** __iend_; | |
| 142 | size_t __isz_; | |
| 143 | ||
| 144 | explicit __libcpp_db(); | |
| 145 | public: | |
| 146 | __libcpp_db(const __libcpp_db&) = delete; | |
| 147 | __libcpp_db& operator=(const __libcpp_db&) = delete; | |
| 148 | ||
| 149 | ~__libcpp_db(); | |
| 150 | ||
| 151 | class __db_c_iterator; | |
| 152 | class __db_c_const_iterator; | |
| 153 | class __db_i_iterator; | |
| 154 | class __db_i_const_iterator; | |
| 155 | ||
| 156 | __db_c_const_iterator __c_end() const; | |
| 157 | __db_i_const_iterator __i_end() const; | |
| 158 | ||
| 159 | typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); | |
| 160 | ||
| 161 | template <class _Cont> | |
| 162 | _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { | |
| 163 | return ::new (__mem) _C_node<_Cont>(__c, __next); | |
| 164 | } | |
| 165 | ||
| 166 | template <class _Cont> | |
| 167 | _LIBCPP_INLINE_VISIBILITY | |
| 168 | void __insert_c(_Cont* __c) | |
| 169 | { | |
| 170 | __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>); | |
| 171 | } | |
| 172 | ||
| 173 | void __insert_i(void* __i); | |
| 174 | void __insert_c(void* __c, _InsertConstruct* __fn); | |
| 175 | void __erase_c(void* __c); | |
| 176 | ||
| 177 | void __insert_ic(void* __i, const void* __c); | |
| 178 | void __iterator_copy(void* __i, const void* __i0); | |
| 179 | void __erase_i(void* __i); | |
| 180 | ||
| 181 | void* __find_c_from_i(void* __i) const; | |
| 182 | void __invalidate_all(void* __c); | |
| 183 | __c_node* __find_c_and_lock(void* __c) const; | |
| 184 | __c_node* __find_c(void* __c) const; | |
| 185 | void unlock() const; | |
| 186 | ||
| 187 | void swap(void* __c1, void* __c2); | |
| 188 | ||
| 189 | ||
| 190 | bool __dereferenceable(const void* __i) const; | |
| 191 | bool __decrementable(const void* __i) const; | |
| 192 | bool __addable(const void* __i, ptrdiff_t __n) const; | |
| 193 | bool __subscriptable(const void* __i, ptrdiff_t __n) const; | |
| 194 | bool __less_than_comparable(const void* __i, const void* __j) const; | |
| 195 | private: | |
| 196 | _LIBCPP_HIDDEN | |
| 197 | __i_node* __insert_iterator(void* __i); | |
| 198 | _LIBCPP_HIDDEN | |
| 199 | __i_node* __find_iterator(const void* __i) const; | |
| 200 | ||
| 201 | friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); | |
| 202 | }; | |
| 203 | ||
| 204 | _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); | |
| 205 | _LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); | |
| 206 | ||
| 207 | _LIBCPP_END_NAMESPACE_STD | |
| 208 | ||
| 209 | #endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 210 | ||
| 211 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 212 | ||
| 213 | template <class _Tp> | |
| 214 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) { | |
| 215 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 216 | if (!__libcpp_is_constant_evaluated()) | |
| 217 | __get_db()->__insert_c(__c); | |
| 218 | #else | |
| 219 | (void)(__c); | |
| 220 | #endif | |
| 221 | } | |
| 222 | ||
| 223 | template <class _Tp> | |
| 224 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) { | |
| 225 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 226 | if (!__libcpp_is_constant_evaluated()) | |
| 227 | __get_db()->__insert_i(__i); | |
| 228 | #else | |
| 229 | (void)(__i); | |
| 230 | #endif | |
| 231 | } | |
| 232 | ||
| 233 | template <class _Tp> | |
| 234 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) { | |
| 235 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 236 | if (!__libcpp_is_constant_evaluated()) | |
| 237 | __get_db()->__erase_c(__c); | |
| 238 | #else | |
| 239 | (void)(__c); | |
| 240 | #endif | |
| 241 | } | |
| 242 | ||
| 243 | template <class _Tp> | |
| 244 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) { | |
| 245 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 246 | if (!__libcpp_is_constant_evaluated()) | |
| 247 | __get_db()->swap(__lhs, __rhs); | |
| 248 | #else | |
| 249 | (void)(__lhs); | |
| 250 | (void)(__rhs); | |
| 251 | #endif | |
| 252 | } | |
| 253 | ||
| 254 | template <class _Tp> | |
| 255 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) { | |
| 256 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 257 | if (!__libcpp_is_constant_evaluated()) | |
| 258 | __get_db()->__invalidate_all(__c); | |
| 259 | #else | |
| 260 | (void)(__c); | |
| 261 | #endif | |
| 262 | } | |
| 263 | ||
| 264 | _LIBCPP_END_NAMESPACE_STD | |
| 265 | ||
| 266 | #endif // _LIBCPP___DEBUG |
lib/libcxx/include/__debug_utils/strict_weak_ordering_check.h created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK | |
| 10 | #define _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #include <__algorithm/comp_ref_type.h> | |
| 15 | #include <__algorithm/is_sorted.h> | |
| 16 | #include <__assert> | |
| 17 | #include <__iterator/iterator_traits.h> | |
| 18 | #include <__type_traits/is_constant_evaluated.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <class _RandomAccessIterator, class _Comp> | |
| 27 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void | |
| 28 | __check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { | |
| 29 | #ifdef _LIBCPP_DEBUG_STRICT_WEAK_ORDERING_CHECK | |
| 30 | using __diff_t = __iter_diff_t<_RandomAccessIterator>; | |
| 31 | using _Comp_ref = __comp_ref_type<_Comp>; | |
| 32 | if (!__libcpp_is_constant_evaluated()) { | |
| 33 | // Check if the range is actually sorted. | |
| 34 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 35 | (std::is_sorted<_RandomAccessIterator, _Comp_ref>(__first, __last, _Comp_ref(__comp))), | |
| 36 | "The range is not sorted after the sort, your comparator is not a valid strict-weak ordering"); | |
| 37 | // Limit the number of elements we need to check. | |
| 38 | __diff_t __size = __last - __first > __diff_t(100) ? __diff_t(100) : __last - __first; | |
| 39 | __diff_t __p = 0; | |
| 40 | while (__p < __size) { | |
| 41 | __diff_t __q = __p + __diff_t(1); | |
| 42 | // Find first element that is greater than *(__first+__p). | |
| 43 | while (__q < __size && !__comp(*(__first + __p), *(__first + __q))) { | |
| 44 | ++__q; | |
| 45 | } | |
| 46 | // Check that the elements from __p to __q are equal between each other. | |
| 47 | for (__diff_t __b = __p; __b < __q; ++__b) { | |
| 48 | for (__diff_t __a = __p; __a <= __b; ++__a) { | |
| 49 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 50 | !__comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering"); | |
| 51 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 52 | !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering"); | |
| 53 | } | |
| 54 | } | |
| 55 | // Check that elements between __p and __q are less than between __q and __size. | |
| 56 | for (__diff_t __a = __p; __a < __q; ++__a) { | |
| 57 | for (__diff_t __b = __q; __b < __size; ++__b) { | |
| 58 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 59 | __comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering"); | |
| 60 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 61 | !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering"); | |
| 62 | } | |
| 63 | } | |
| 64 | // Skip these equal elements. | |
| 65 | __p = __q; | |
| 66 | } | |
| 67 | } | |
| 68 | #else | |
| 69 | (void)__first; | |
| 70 | (void)__last; | |
| 71 | (void)__comp; | |
| 72 | #endif | |
| 73 | } | |
| 74 | ||
| 75 | _LIBCPP_END_NAMESPACE_STD | |
| 76 | ||
| 77 | #endif // _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK |
lib/libcxx/include/__errc deleted-217| ... | ... | @@ -1,217 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___ERRC | |
| 11 | #define _LIBCPP___ERRC | |
| 12 | ||
| 13 | /* | |
| 14 | system_error synopsis | |
| 15 | ||
| 16 | namespace std | |
| 17 | { | |
| 18 | ||
| 19 | enum class errc | |
| 20 | { | |
| 21 | address_family_not_supported, // EAFNOSUPPORT | |
| 22 | address_in_use, // EADDRINUSE | |
| 23 | address_not_available, // EADDRNOTAVAIL | |
| 24 | already_connected, // EISCONN | |
| 25 | argument_list_too_long, // E2BIG | |
| 26 | argument_out_of_domain, // EDOM | |
| 27 | bad_address, // EFAULT | |
| 28 | bad_file_descriptor, // EBADF | |
| 29 | bad_message, // EBADMSG | |
| 30 | broken_pipe, // EPIPE | |
| 31 | connection_aborted, // ECONNABORTED | |
| 32 | connection_already_in_progress, // EALREADY | |
| 33 | connection_refused, // ECONNREFUSED | |
| 34 | connection_reset, // ECONNRESET | |
| 35 | cross_device_link, // EXDEV | |
| 36 | destination_address_required, // EDESTADDRREQ | |
| 37 | device_or_resource_busy, // EBUSY | |
| 38 | directory_not_empty, // ENOTEMPTY | |
| 39 | executable_format_error, // ENOEXEC | |
| 40 | file_exists, // EEXIST | |
| 41 | file_too_large, // EFBIG | |
| 42 | filename_too_long, // ENAMETOOLONG | |
| 43 | function_not_supported, // ENOSYS | |
| 44 | host_unreachable, // EHOSTUNREACH | |
| 45 | identifier_removed, // EIDRM | |
| 46 | illegal_byte_sequence, // EILSEQ | |
| 47 | inappropriate_io_control_operation, // ENOTTY | |
| 48 | interrupted, // EINTR | |
| 49 | invalid_argument, // EINVAL | |
| 50 | invalid_seek, // ESPIPE | |
| 51 | io_error, // EIO | |
| 52 | is_a_directory, // EISDIR | |
| 53 | message_size, // EMSGSIZE | |
| 54 | network_down, // ENETDOWN | |
| 55 | network_reset, // ENETRESET | |
| 56 | network_unreachable, // ENETUNREACH | |
| 57 | no_buffer_space, // ENOBUFS | |
| 58 | no_child_process, // ECHILD | |
| 59 | no_link, // ENOLINK | |
| 60 | no_lock_available, // ENOLCK | |
| 61 | no_message_available, // ENODATA | |
| 62 | no_message, // ENOMSG | |
| 63 | no_protocol_option, // ENOPROTOOPT | |
| 64 | no_space_on_device, // ENOSPC | |
| 65 | no_stream_resources, // ENOSR | |
| 66 | no_such_device_or_address, // ENXIO | |
| 67 | no_such_device, // ENODEV | |
| 68 | no_such_file_or_directory, // ENOENT | |
| 69 | no_such_process, // ESRCH | |
| 70 | not_a_directory, // ENOTDIR | |
| 71 | not_a_socket, // ENOTSOCK | |
| 72 | not_a_stream, // ENOSTR | |
| 73 | not_connected, // ENOTCONN | |
| 74 | not_enough_memory, // ENOMEM | |
| 75 | not_supported, // ENOTSUP | |
| 76 | operation_canceled, // ECANCELED | |
| 77 | operation_in_progress, // EINPROGRESS | |
| 78 | operation_not_permitted, // EPERM | |
| 79 | operation_not_supported, // EOPNOTSUPP | |
| 80 | operation_would_block, // EWOULDBLOCK | |
| 81 | owner_dead, // EOWNERDEAD | |
| 82 | permission_denied, // EACCES | |
| 83 | protocol_error, // EPROTO | |
| 84 | protocol_not_supported, // EPROTONOSUPPORT | |
| 85 | read_only_file_system, // EROFS | |
| 86 | resource_deadlock_would_occur, // EDEADLK | |
| 87 | resource_unavailable_try_again, // EAGAIN | |
| 88 | result_out_of_range, // ERANGE | |
| 89 | state_not_recoverable, // ENOTRECOVERABLE | |
| 90 | stream_timeout, // ETIME | |
| 91 | text_file_busy, // ETXTBSY | |
| 92 | timed_out, // ETIMEDOUT | |
| 93 | too_many_files_open_in_system, // ENFILE | |
| 94 | too_many_files_open, // EMFILE | |
| 95 | too_many_links, // EMLINK | |
| 96 | too_many_symbolic_link_levels, // ELOOP | |
| 97 | value_too_large, // EOVERFLOW | |
| 98 | wrong_protocol_type // EPROTOTYPE | |
| 99 | }; | |
| 100 | ||
| 101 | */ | |
| 102 | ||
| 103 | #include <__config> | |
| 104 | #include <cerrno> | |
| 105 | ||
| 106 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 107 | # pragma GCC system_header | |
| 108 | #endif | |
| 109 | ||
| 110 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 111 | ||
| 112 | // Some error codes are not present on all platforms, so we provide equivalents | |
| 113 | // for them: | |
| 114 | ||
| 115 | //enum class errc | |
| 116 | _LIBCPP_DECLARE_STRONG_ENUM(errc) | |
| 117 | { | |
| 118 | address_family_not_supported = EAFNOSUPPORT, | |
| 119 | address_in_use = EADDRINUSE, | |
| 120 | address_not_available = EADDRNOTAVAIL, | |
| 121 | already_connected = EISCONN, | |
| 122 | argument_list_too_long = E2BIG, | |
| 123 | argument_out_of_domain = EDOM, | |
| 124 | bad_address = EFAULT, | |
| 125 | bad_file_descriptor = EBADF, | |
| 126 | bad_message = EBADMSG, | |
| 127 | broken_pipe = EPIPE, | |
| 128 | connection_aborted = ECONNABORTED, | |
| 129 | connection_already_in_progress = EALREADY, | |
| 130 | connection_refused = ECONNREFUSED, | |
| 131 | connection_reset = ECONNRESET, | |
| 132 | cross_device_link = EXDEV, | |
| 133 | destination_address_required = EDESTADDRREQ, | |
| 134 | device_or_resource_busy = EBUSY, | |
| 135 | directory_not_empty = ENOTEMPTY, | |
| 136 | executable_format_error = ENOEXEC, | |
| 137 | file_exists = EEXIST, | |
| 138 | file_too_large = EFBIG, | |
| 139 | filename_too_long = ENAMETOOLONG, | |
| 140 | function_not_supported = ENOSYS, | |
| 141 | host_unreachable = EHOSTUNREACH, | |
| 142 | identifier_removed = EIDRM, | |
| 143 | illegal_byte_sequence = EILSEQ, | |
| 144 | inappropriate_io_control_operation = ENOTTY, | |
| 145 | interrupted = EINTR, | |
| 146 | invalid_argument = EINVAL, | |
| 147 | invalid_seek = ESPIPE, | |
| 148 | io_error = EIO, | |
| 149 | is_a_directory = EISDIR, | |
| 150 | message_size = EMSGSIZE, | |
| 151 | network_down = ENETDOWN, | |
| 152 | network_reset = ENETRESET, | |
| 153 | network_unreachable = ENETUNREACH, | |
| 154 | no_buffer_space = ENOBUFS, | |
| 155 | no_child_process = ECHILD, | |
| 156 | no_link = ENOLINK, | |
| 157 | no_lock_available = ENOLCK, | |
| 158 | #ifdef ENODATA | |
| 159 | no_message_available = ENODATA, | |
| 160 | #else | |
| 161 | no_message_available = ENOMSG, | |
| 162 | #endif | |
| 163 | no_message = ENOMSG, | |
| 164 | no_protocol_option = ENOPROTOOPT, | |
| 165 | no_space_on_device = ENOSPC, | |
| 166 | #ifdef ENOSR | |
| 167 | no_stream_resources = ENOSR, | |
| 168 | #else | |
| 169 | no_stream_resources = ENOMEM, | |
| 170 | #endif | |
| 171 | no_such_device_or_address = ENXIO, | |
| 172 | no_such_device = ENODEV, | |
| 173 | no_such_file_or_directory = ENOENT, | |
| 174 | no_such_process = ESRCH, | |
| 175 | not_a_directory = ENOTDIR, | |
| 176 | not_a_socket = ENOTSOCK, | |
| 177 | #ifdef ENOSTR | |
| 178 | not_a_stream = ENOSTR, | |
| 179 | #else | |
| 180 | not_a_stream = EINVAL, | |
| 181 | #endif | |
| 182 | not_connected = ENOTCONN, | |
| 183 | not_enough_memory = ENOMEM, | |
| 184 | not_supported = ENOTSUP, | |
| 185 | operation_canceled = ECANCELED, | |
| 186 | operation_in_progress = EINPROGRESS, | |
| 187 | operation_not_permitted = EPERM, | |
| 188 | operation_not_supported = EOPNOTSUPP, | |
| 189 | operation_would_block = EWOULDBLOCK, | |
| 190 | owner_dead = EOWNERDEAD, | |
| 191 | permission_denied = EACCES, | |
| 192 | protocol_error = EPROTO, | |
| 193 | protocol_not_supported = EPROTONOSUPPORT, | |
| 194 | read_only_file_system = EROFS, | |
| 195 | resource_deadlock_would_occur = EDEADLK, | |
| 196 | resource_unavailable_try_again = EAGAIN, | |
| 197 | result_out_of_range = ERANGE, | |
| 198 | state_not_recoverable = ENOTRECOVERABLE, | |
| 199 | #ifdef ETIME | |
| 200 | stream_timeout = ETIME, | |
| 201 | #else | |
| 202 | stream_timeout = ETIMEDOUT, | |
| 203 | #endif | |
| 204 | text_file_busy = ETXTBSY, | |
| 205 | timed_out = ETIMEDOUT, | |
| 206 | too_many_files_open_in_system = ENFILE, | |
| 207 | too_many_files_open = EMFILE, | |
| 208 | too_many_links = EMLINK, | |
| 209 | too_many_symbolic_link_levels = ELOOP, | |
| 210 | value_too_large = EOVERFLOW, | |
| 211 | wrong_protocol_type = EPROTOTYPE | |
| 212 | }; | |
| 213 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) | |
| 214 | ||
| 215 | _LIBCPP_END_NAMESPACE_STD | |
| 216 | ||
| 217 | #endif // _LIBCPP___ERRC |
lib/libcxx/include/__exception/exception.h created+91| ... | ... | @@ -0,0 +1,91 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___EXCEPTION_EXCEPTION_H | |
| 10 | #define _LIBCPP___EXCEPTION_EXCEPTION_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | // <vcruntime_exception.h> defines its own std::exception and std::bad_exception types, | |
| 15 | // which we use in order to be ABI-compatible with other STLs on Windows. | |
| 16 | #if defined(_LIBCPP_ABI_VCRUNTIME) | |
| 17 | # include <vcruntime_exception.h> | |
| 18 | #endif | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | namespace std { // purposefully not using versioning namespace | |
| 25 | ||
| 26 | #if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0) | |
| 27 | // The std::exception class was already included above, but we're explicit about this condition here for clarity. | |
| 28 | ||
| 29 | #elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 | |
| 30 | // However, <vcruntime_exception.h> does not define std::exception and std::bad_exception | |
| 31 | // when _HAS_EXCEPTIONS == 0. | |
| 32 | // | |
| 33 | // Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0 | |
| 34 | // (after all those are simply types like any other), we define an ABI-compatible version | |
| 35 | // of the VCRuntime std::exception and std::bad_exception types in that mode. | |
| 36 | ||
| 37 | struct __std_exception_data { | |
| 38 | char const* _What; | |
| 39 | bool _DoFree; | |
| 40 | }; | |
| 41 | ||
| 42 | class exception { // base of all library exceptions | |
| 43 | public: | |
| 44 | exception() _NOEXCEPT : __data_() {} | |
| 45 | ||
| 46 | explicit exception(char const* __message) _NOEXCEPT : __data_() { | |
| 47 | __data_._What = __message; | |
| 48 | __data_._DoFree = true; | |
| 49 | } | |
| 50 | ||
| 51 | exception(exception const&) _NOEXCEPT {} | |
| 52 | ||
| 53 | exception& operator=(exception const&) _NOEXCEPT { return *this; } | |
| 54 | ||
| 55 | virtual ~exception() _NOEXCEPT {} | |
| 56 | ||
| 57 | virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; } | |
| 58 | ||
| 59 | private: | |
| 60 | __std_exception_data __data_; | |
| 61 | }; | |
| 62 | ||
| 63 | class bad_exception : public exception { | |
| 64 | public: | |
| 65 | bad_exception() _NOEXCEPT : exception("bad exception") {} | |
| 66 | }; | |
| 67 | ||
| 68 | #else // !defined(_LIBCPP_ABI_VCRUNTIME) | |
| 69 | // On all other platforms, we define our own std::exception and std::bad_exception types | |
| 70 | // regardless of whether exceptions are turned on as a language feature. | |
| 71 | ||
| 72 | class _LIBCPP_EXPORTED_FROM_ABI exception { | |
| 73 | public: | |
| 74 | _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {} | |
| 75 | _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default; | |
| 76 | ||
| 77 | virtual ~exception() _NOEXCEPT; | |
| 78 | virtual const char* what() const _NOEXCEPT; | |
| 79 | }; | |
| 80 | ||
| 81 | class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception { | |
| 82 | public: | |
| 83 | _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {} | |
| 84 | ~bad_exception() _NOEXCEPT override; | |
| 85 | const char* what() const _NOEXCEPT override; | |
| 86 | }; | |
| 87 | #endif // !_LIBCPP_ABI_VCRUNTIME | |
| 88 | ||
| 89 | } // namespace std | |
| 90 | ||
| 91 | #endif // _LIBCPP___EXCEPTION_EXCEPTION_H |
lib/libcxx/include/__exception/exception_ptr.h created+109| ... | ... | @@ -0,0 +1,109 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H | |
| 10 | #define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__exception/operations.h> | |
| 14 | #include <__memory/addressof.h> | |
| 15 | #include <cstddef> | |
| 16 | #include <cstdlib> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | namespace std { // purposefully not using versioning namespace | |
| 23 | ||
| 24 | #ifndef _LIBCPP_ABI_MICROSOFT | |
| 25 | ||
| 26 | class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { | |
| 27 | void* __ptr_; | |
| 28 | ||
| 29 | public: | |
| 30 | _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {} | |
| 31 | _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} | |
| 32 | ||
| 33 | exception_ptr(const exception_ptr&) _NOEXCEPT; | |
| 34 | exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; | |
| 35 | ~exception_ptr() _NOEXCEPT; | |
| 36 | ||
| 37 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __ptr_ != nullptr; } | |
| 38 | ||
| 39 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT { | |
| 40 | return __x.__ptr_ == __y.__ptr_; | |
| 41 | } | |
| 42 | ||
| 43 | friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT { | |
| 44 | return !(__x == __y); | |
| 45 | } | |
| 46 | ||
| 47 | friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; | |
| 48 | friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); | |
| 49 | }; | |
| 50 | ||
| 51 | template <class _Ep> | |
| 52 | _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { | |
| 53 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 54 | try { | |
| 55 | throw __e; | |
| 56 | } catch (...) { | |
| 57 | return current_exception(); | |
| 58 | } | |
| 59 | # else | |
| 60 | ((void)__e); | |
| 61 | std::abort(); | |
| 62 | # endif | |
| 63 | } | |
| 64 | ||
| 65 | #else // _LIBCPP_ABI_MICROSOFT | |
| 66 | ||
| 67 | class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { | |
| 68 | _LIBCPP_DIAGNOSTIC_PUSH | |
| 69 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") | |
| 70 | void* __ptr1_; | |
| 71 | void* __ptr2_; | |
| 72 | _LIBCPP_DIAGNOSTIC_POP | |
| 73 | ||
| 74 | public: | |
| 75 | exception_ptr() _NOEXCEPT; | |
| 76 | exception_ptr(nullptr_t) _NOEXCEPT; | |
| 77 | exception_ptr(const exception_ptr& __other) _NOEXCEPT; | |
| 78 | exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; | |
| 79 | exception_ptr& operator=(nullptr_t) _NOEXCEPT; | |
| 80 | ~exception_ptr() _NOEXCEPT; | |
| 81 | explicit operator bool() const _NOEXCEPT; | |
| 82 | }; | |
| 83 | ||
| 84 | _LIBCPP_EXPORTED_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; | |
| 85 | ||
| 86 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT { | |
| 87 | return !(__x == __y); | |
| 88 | } | |
| 89 | ||
| 90 | _LIBCPP_EXPORTED_FROM_ABI void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; | |
| 91 | ||
| 92 | _LIBCPP_EXPORTED_FROM_ABI exception_ptr __copy_exception_ptr(void* __except, const void* __ptr); | |
| 93 | _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; | |
| 94 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); | |
| 95 | ||
| 96 | // This is a built-in template function which automagically extracts the required | |
| 97 | // information. | |
| 98 | template <class _E> | |
| 99 | void* __GetExceptionInfo(_E); | |
| 100 | ||
| 101 | template <class _Ep> | |
| 102 | _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { | |
| 103 | return __copy_exception_ptr(std::addressof(__e), __GetExceptionInfo(__e)); | |
| 104 | } | |
| 105 | ||
| 106 | #endif // _LIBCPP_ABI_MICROSOFT | |
| 107 | } // namespace std | |
| 108 | ||
| 109 | #endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H |
lib/libcxx/include/__exception/nested_exception.h created+101| ... | ... | @@ -0,0 +1,101 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H | |
| 10 | #define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__exception/exception_ptr.h> | |
| 14 | #include <__memory/addressof.h> | |
| 15 | #include <__type_traits/decay.h> | |
| 16 | #include <__type_traits/is_base_of.h> | |
| 17 | #include <__type_traits/is_class.h> | |
| 18 | #include <__type_traits/is_convertible.h> | |
| 19 | #include <__type_traits/is_copy_constructible.h> | |
| 20 | #include <__type_traits/is_final.h> | |
| 21 | #include <__type_traits/is_polymorphic.h> | |
| 22 | #include <__utility/forward.h> | |
| 23 | #include <cstddef> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | namespace std { // purposefully not using versioning namespace | |
| 30 | ||
| 31 | class _LIBCPP_EXPORTED_FROM_ABI nested_exception { | |
| 32 | exception_ptr __ptr_; | |
| 33 | ||
| 34 | public: | |
| 35 | nested_exception() _NOEXCEPT; | |
| 36 | // nested_exception(const nested_exception&) noexcept = default; | |
| 37 | // nested_exception& operator=(const nested_exception&) noexcept = default; | |
| 38 | virtual ~nested_exception() _NOEXCEPT; | |
| 39 | ||
| 40 | // access functions | |
| 41 | _LIBCPP_NORETURN void rethrow_nested() const; | |
| 42 | _LIBCPP_HIDE_FROM_ABI exception_ptr nested_ptr() const _NOEXCEPT { return __ptr_; } | |
| 43 | }; | |
| 44 | ||
| 45 | template <class _Tp> | |
| 46 | struct __nested : public _Tp, public nested_exception { | |
| 47 | _LIBCPP_HIDE_FROM_ABI explicit __nested(const _Tp& __t) : _Tp(__t) {} | |
| 48 | }; | |
| 49 | ||
| 50 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 51 | template <class _Tp, class _Up, bool> | |
| 52 | struct __throw_with_nested; | |
| 53 | ||
| 54 | template <class _Tp, class _Up> | |
| 55 | struct __throw_with_nested<_Tp, _Up, true> { | |
| 56 | _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { | |
| 57 | throw __nested<_Up>(std::forward<_Tp>(__t)); | |
| 58 | } | |
| 59 | }; | |
| 60 | ||
| 61 | template <class _Tp, class _Up> | |
| 62 | struct __throw_with_nested<_Tp, _Up, false> { | |
| 63 | _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); } | |
| 64 | }; | |
| 65 | #endif | |
| 66 | ||
| 67 | template <class _Tp> | |
| 68 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI void throw_with_nested(_Tp&& __t) { | |
| 69 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 70 | using _Up = __decay_t<_Tp>; | |
| 71 | static_assert(is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible"); | |
| 72 | __throw_with_nested<_Tp, | |
| 73 | _Up, | |
| 74 | is_class<_Up>::value && !is_base_of<nested_exception, _Up>::value && | |
| 75 | !__libcpp_is_final<_Up>::value>::__do_throw(std::forward<_Tp>(__t)); | |
| 76 | #else | |
| 77 | ((void)__t); | |
| 78 | // FIXME: Make this abort | |
| 79 | #endif | |
| 80 | } | |
| 81 | ||
| 82 | template <class _From, class _To> | |
| 83 | struct __can_dynamic_cast | |
| 84 | : _BoolConstant< is_polymorphic<_From>::value && | |
| 85 | (!is_base_of<_To, _From>::value || is_convertible<const _From*, const _To*>::value)> {}; | |
| 86 | ||
| 87 | template <class _Ep> | |
| 88 | inline _LIBCPP_HIDE_FROM_ABI void | |
| 89 | rethrow_if_nested(const _Ep& __e, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) { | |
| 90 | const nested_exception* __nep = dynamic_cast<const nested_exception*>(std::addressof(__e)); | |
| 91 | if (__nep) | |
| 92 | __nep->rethrow_nested(); | |
| 93 | } | |
| 94 | ||
| 95 | template <class _Ep> | |
| 96 | inline _LIBCPP_HIDE_FROM_ABI void | |
| 97 | rethrow_if_nested(const _Ep&, __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) {} | |
| 98 | ||
| 99 | } // namespace std | |
| 100 | ||
| 101 | #endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H |
lib/libcxx/include/__exception/operations.h created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___EXCEPTION_OPERATIONS_H | |
| 10 | #define _LIBCPP___EXCEPTION_OPERATIONS_H | |
| 11 | ||
| 12 | #include <__availability> | |
| 13 | #include <__config> | |
| 14 | #include <cstddef> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | namespace std { // purposefully not using versioning namespace | |
| 21 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) || \ | |
| 22 | defined(_LIBCPP_BUILDING_LIBRARY) | |
| 23 | using unexpected_handler = void (*)(); | |
| 24 | _LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; | |
| 25 | _LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT; | |
| 26 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void unexpected(); | |
| 27 | #endif | |
| 28 | ||
| 29 | using terminate_handler = void (*)(); | |
| 30 | _LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT; | |
| 31 | _LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; | |
| 32 | ||
| 33 | _LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT; | |
| 34 | _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT; | |
| 35 | ||
| 36 | class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; | |
| 37 | ||
| 38 | _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; | |
| 39 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); | |
| 40 | } // namespace std | |
| 41 | ||
| 42 | #endif // _LIBCPP___EXCEPTION_OPERATIONS_H |
lib/libcxx/include/__exception/terminate.h created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___EXCEPTION_TERMINATE_H | |
| 10 | #define _LIBCPP___EXCEPTION_TERMINATE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | namespace std { // purposefully not using versioning namespace | |
| 19 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT; | |
| 20 | } // namespace std | |
| 21 | ||
| 22 | #endif // _LIBCPP___EXCEPTION_TERMINATE_H |
lib/libcxx/include/__expected/bad_expected_access.h+8-4| ... | ... | @@ -10,14 +10,16 @@ |
| 10 | 10 | #define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <__exception/exception.h> | |
| 13 | 14 | #include <__utility/move.h> |
| 14 | 15 | |
| 15 | #include <exception> | |
| 16 | ||
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
| 19 | 18 | #endif |
| 20 | 19 | |
| 20 | _LIBCPP_PUSH_MACROS | |
| 21 | #include <__undef_macros> | |
| 22 | ||
| 21 | 23 | #if _LIBCPP_STD_VER >= 23 |
| 22 | 24 | |
| 23 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| ... | ... | @@ -33,14 +35,14 @@ protected: |
| 33 | 35 | _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default; |
| 34 | 36 | _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default; |
| 35 | 37 | _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default; |
| 36 | ~bad_expected_access() override = default; | |
| 38 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default; | |
| 37 | 39 | |
| 38 | 40 | public: |
| 39 | 41 | // The way this has been designed (by using a class template below) means that we'll already |
| 40 | 42 | // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch |
| 41 | 43 | // of work to do. So it is not worth hiding the <void> specialization in the dylib, given that |
| 42 | 44 | // it adds deployment target restrictions. |
| 43 | const char* what() const noexcept override { return "bad access to std::expected"; } | |
| 45 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; } | |
| 44 | 46 | }; |
| 45 | 47 | |
| 46 | 48 | template <class _Err> |
| ... | ... | @@ -61,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 61 | 63 | |
| 62 | 64 | #endif // _LIBCPP_STD_VER >= 23 |
| 63 | 65 | |
| 66 | _LIBCPP_POP_MACROS | |
| 67 | ||
| 64 | 68 | #endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H |
lib/libcxx/include/__expected/expected.h+626-40| ... | ... | @@ -14,10 +14,12 @@ |
| 14 | 14 | #include <__expected/bad_expected_access.h> |
| 15 | 15 | #include <__expected/unexpect.h> |
| 16 | 16 | #include <__expected/unexpected.h> |
| 17 | #include <__functional/invoke.h> | |
| 17 | 18 | #include <__memory/addressof.h> |
| 18 | 19 | #include <__memory/construct_at.h> |
| 19 | 20 | #include <__type_traits/conjunction.h> |
| 20 | 21 | #include <__type_traits/disjunction.h> |
| 22 | #include <__type_traits/integral_constant.h> | |
| 21 | 23 | #include <__type_traits/is_assignable.h> |
| 22 | 24 | #include <__type_traits/is_constructible.h> |
| 23 | 25 | #include <__type_traits/is_convertible.h> |
| ... | ... | @@ -44,36 +46,48 @@ |
| 44 | 46 | #include <__type_traits/negation.h> |
| 45 | 47 | #include <__type_traits/remove_cv.h> |
| 46 | 48 | #include <__type_traits/remove_cvref.h> |
| 49 | #include <__utility/as_const.h> | |
| 47 | 50 | #include <__utility/exception_guard.h> |
| 48 | 51 | #include <__utility/forward.h> |
| 49 | 52 | #include <__utility/in_place.h> |
| 50 | 53 | #include <__utility/move.h> |
| 51 | 54 | #include <__utility/swap.h> |
| 52 | #include <cstdlib> // for std::abort | |
| 55 | #include <__verbose_abort> | |
| 53 | 56 | #include <initializer_list> |
| 54 | 57 | |
| 55 | 58 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 56 | 59 | # pragma GCC system_header |
| 57 | 60 | #endif |
| 58 | 61 | |
| 62 | _LIBCPP_PUSH_MACROS | |
| 63 | #include <__undef_macros> | |
| 64 | ||
| 59 | 65 | #if _LIBCPP_STD_VER >= 23 |
| 60 | 66 | |
| 61 | 67 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 62 | 68 | |
| 63 | namespace __expected { | |
| 69 | template <class _Tp, class _Err> | |
| 70 | class expected; | |
| 71 | ||
| 72 | template <class _Tp> | |
| 73 | struct __is_std_expected : false_type {}; | |
| 74 | ||
| 75 | template <class _Tp, class _Err> | |
| 76 | struct __is_std_expected<expected<_Tp, _Err>> : true_type {}; | |
| 77 | ||
| 78 | struct __expected_construct_in_place_from_invoke_tag {}; | |
| 79 | struct __expected_construct_unexpected_from_invoke_tag {}; | |
| 64 | 80 | |
| 65 | 81 | template <class _Err, class _Arg> |
| 66 | 82 | _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { |
| 67 | # ifndef _LIBCPP_NO_EXCEPTIONS | |
| 83 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 68 | 84 | throw bad_expected_access<_Err>(std::forward<_Arg>(__arg)); |
| 69 | 85 | # else |
| 70 | 86 | (void)__arg; |
| 71 | std::abort(); | |
| 87 | _LIBCPP_VERBOSE_ABORT("bad_expected_access was thrown in -fno-exceptions mode"); | |
| 72 | 88 | # endif |
| 73 | 89 | } |
| 74 | 90 | |
| 75 | } // namespace __expected | |
| 76 | ||
| 77 | 91 | template <class _Tp, class _Err> |
| 78 | 92 | class expected { |
| 79 | 93 | static_assert( |
| ... | ... | @@ -166,6 +180,15 @@ private: |
| 166 | 180 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, |
| 167 | 181 | _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >; |
| 168 | 182 | |
| 183 | template <class _Func, class... _Args> | |
| 184 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( | |
| 185 | std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) | |
| 186 | : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {} | |
| 187 | ||
| 188 | template <class _Func, class... _Args> | |
| 189 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( | |
| 190 | std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) | |
| 191 | : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} | |
| 169 | 192 | |
| 170 | 193 | public: |
| 171 | 194 | template <class _Up, class _OtherErr> |
| ... | ... | @@ -503,32 +526,32 @@ public: |
| 503 | 526 | |
| 504 | 527 | // [expected.object.obs], observers |
| 505 | 528 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { |
| 506 | _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); | |
| 529 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value"); | |
| 507 | 530 | return std::addressof(__union_.__val_); |
| 508 | 531 | } |
| 509 | 532 | |
| 510 | 533 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { |
| 511 | _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); | |
| 534 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator-> requires the expected to contain a value"); | |
| 512 | 535 | return std::addressof(__union_.__val_); |
| 513 | 536 | } |
| 514 | 537 | |
| 515 | 538 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { |
| 516 | _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 539 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 517 | 540 | return __union_.__val_; |
| 518 | 541 | } |
| 519 | 542 | |
| 520 | 543 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { |
| 521 | _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 544 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 522 | 545 | return __union_.__val_; |
| 523 | 546 | } |
| 524 | 547 | |
| 525 | 548 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { |
| 526 | _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 549 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 527 | 550 | return std::move(__union_.__val_); |
| 528 | 551 | } |
| 529 | 552 | |
| 530 | 553 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { |
| 531 | _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 554 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 532 | 555 | return std::move(__union_.__val_); |
| 533 | 556 | } |
| 534 | 557 | |
| ... | ... | @@ -537,50 +560,56 @@ public: |
| 537 | 560 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } |
| 538 | 561 | |
| 539 | 562 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { |
| 563 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); | |
| 540 | 564 | if (!__has_val_) { |
| 541 | __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); | |
| 565 | std::__throw_bad_expected_access<_Err>(std::as_const(error())); | |
| 542 | 566 | } |
| 543 | 567 | return __union_.__val_; |
| 544 | 568 | } |
| 545 | 569 | |
| 546 | 570 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { |
| 571 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); | |
| 547 | 572 | if (!__has_val_) { |
| 548 | __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); | |
| 573 | std::__throw_bad_expected_access<_Err>(std::as_const(error())); | |
| 549 | 574 | } |
| 550 | 575 | return __union_.__val_; |
| 551 | 576 | } |
| 552 | 577 | |
| 553 | 578 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { |
| 579 | static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, | |
| 580 | "error_type has to be both copy constructible and constructible from decltype(std::move(error()))"); | |
| 554 | 581 | if (!__has_val_) { |
| 555 | __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); | |
| 582 | std::__throw_bad_expected_access<_Err>(std::move(error())); | |
| 556 | 583 | } |
| 557 | 584 | return std::move(__union_.__val_); |
| 558 | 585 | } |
| 559 | 586 | |
| 560 | 587 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { |
| 588 | static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, | |
| 589 | "error_type has to be both copy constructible and constructible from decltype(std::move(error()))"); | |
| 561 | 590 | if (!__has_val_) { |
| 562 | __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); | |
| 591 | std::__throw_bad_expected_access<_Err>(std::move(error())); | |
| 563 | 592 | } |
| 564 | 593 | return std::move(__union_.__val_); |
| 565 | 594 | } |
| 566 | 595 | |
| 567 | 596 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { |
| 568 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 597 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 569 | 598 | return __union_.__unex_; |
| 570 | 599 | } |
| 571 | 600 | |
| 572 | 601 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { |
| 573 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 602 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 574 | 603 | return __union_.__unex_; |
| 575 | 604 | } |
| 576 | 605 | |
| 577 | 606 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { |
| 578 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 607 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 579 | 608 | return std::move(__union_.__unex_); |
| 580 | 609 | } |
| 581 | 610 | |
| 582 | 611 | _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { |
| 583 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 612 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 584 | 613 | return std::move(__union_.__unex_); |
| 585 | 614 | } |
| 586 | 615 | |
| ... | ... | @@ -598,6 +627,245 @@ public: |
| 598 | 627 | return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); |
| 599 | 628 | } |
| 600 | 629 | |
| 630 | template <class _Up = _Err> | |
| 631 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { | |
| 632 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); | |
| 633 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); | |
| 634 | if (has_value()) | |
| 635 | return std::forward<_Up>(__error); | |
| 636 | return error(); | |
| 637 | } | |
| 638 | ||
| 639 | template <class _Up = _Err> | |
| 640 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { | |
| 641 | static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible"); | |
| 642 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); | |
| 643 | if (has_value()) | |
| 644 | return std::forward<_Up>(__error); | |
| 645 | return std::move(error()); | |
| 646 | } | |
| 647 | ||
| 648 | // [expected.void.monadic], monadic | |
| 649 | template <class _Func> | |
| 650 | requires is_constructible_v<_Err, _Err&> | |
| 651 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { | |
| 652 | using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&>>; | |
| 653 | static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); | |
| 654 | static_assert(is_same_v<typename _Up::error_type, _Err>, | |
| 655 | "The result of f(value()) must have the same error_type as this expected"); | |
| 656 | if (has_value()) { | |
| 657 | return std::invoke(std::forward<_Func>(__f), value()); | |
| 658 | } | |
| 659 | return _Up(unexpect, error()); | |
| 660 | } | |
| 661 | ||
| 662 | template <class _Func> | |
| 663 | requires is_constructible_v<_Err, const _Err&> | |
| 664 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { | |
| 665 | using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&>>; | |
| 666 | static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); | |
| 667 | static_assert(is_same_v<typename _Up::error_type, _Err>, | |
| 668 | "The result of f(value()) must have the same error_type as this expected"); | |
| 669 | if (has_value()) { | |
| 670 | return std::invoke(std::forward<_Func>(__f), value()); | |
| 671 | } | |
| 672 | return _Up(unexpect, error()); | |
| 673 | } | |
| 674 | ||
| 675 | template <class _Func> | |
| 676 | requires is_constructible_v<_Err, _Err&&> | |
| 677 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { | |
| 678 | using _Up = remove_cvref_t<invoke_result_t<_Func, _Tp&&>>; | |
| 679 | static_assert( | |
| 680 | __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); | |
| 681 | static_assert(is_same_v<typename _Up::error_type, _Err>, | |
| 682 | "The result of f(std::move(value())) must have the same error_type as this expected"); | |
| 683 | if (has_value()) { | |
| 684 | return std::invoke(std::forward<_Func>(__f), std::move(value())); | |
| 685 | } | |
| 686 | return _Up(unexpect, std::move(error())); | |
| 687 | } | |
| 688 | ||
| 689 | template <class _Func> | |
| 690 | requires is_constructible_v<_Err, const _Err&&> | |
| 691 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { | |
| 692 | using _Up = remove_cvref_t<invoke_result_t<_Func, const _Tp&&>>; | |
| 693 | static_assert( | |
| 694 | __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); | |
| 695 | static_assert(is_same_v<typename _Up::error_type, _Err>, | |
| 696 | "The result of f(std::move(value())) must have the same error_type as this expected"); | |
| 697 | if (has_value()) { | |
| 698 | return std::invoke(std::forward<_Func>(__f), std::move(value())); | |
| 699 | } | |
| 700 | return _Up(unexpect, std::move(error())); | |
| 701 | } | |
| 702 | ||
| 703 | template <class _Func> | |
| 704 | requires is_constructible_v<_Tp, _Tp&> | |
| 705 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { | |
| 706 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; | |
| 707 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); | |
| 708 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 709 | "The result of f(error()) must have the same value_type as this expected"); | |
| 710 | if (has_value()) { | |
| 711 | return _Gp(in_place, value()); | |
| 712 | } | |
| 713 | return std::invoke(std::forward<_Func>(__f), error()); | |
| 714 | } | |
| 715 | ||
| 716 | template <class _Func> | |
| 717 | requires is_constructible_v<_Tp, const _Tp&> | |
| 718 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { | |
| 719 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; | |
| 720 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); | |
| 721 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 722 | "The result of f(error()) must have the same value_type as this expected"); | |
| 723 | if (has_value()) { | |
| 724 | return _Gp(in_place, value()); | |
| 725 | } | |
| 726 | return std::invoke(std::forward<_Func>(__f), error()); | |
| 727 | } | |
| 728 | ||
| 729 | template <class _Func> | |
| 730 | requires is_constructible_v<_Tp, _Tp&&> | |
| 731 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { | |
| 732 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; | |
| 733 | static_assert( | |
| 734 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); | |
| 735 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 736 | "The result of f(std::move(error())) must have the same value_type as this expected"); | |
| 737 | if (has_value()) { | |
| 738 | return _Gp(in_place, std::move(value())); | |
| 739 | } | |
| 740 | return std::invoke(std::forward<_Func>(__f), std::move(error())); | |
| 741 | } | |
| 742 | ||
| 743 | template <class _Func> | |
| 744 | requires is_constructible_v<_Tp, const _Tp&&> | |
| 745 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { | |
| 746 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; | |
| 747 | static_assert( | |
| 748 | __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); | |
| 749 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 750 | "The result of f(std::move(error())) must have the same value_type as this expected"); | |
| 751 | if (has_value()) { | |
| 752 | return _Gp(in_place, std::move(value())); | |
| 753 | } | |
| 754 | return std::invoke(std::forward<_Func>(__f), std::move(error())); | |
| 755 | } | |
| 756 | ||
| 757 | template <class _Func> | |
| 758 | requires is_constructible_v<_Err, _Err&> | |
| 759 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { | |
| 760 | using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&>>; | |
| 761 | if (!has_value()) { | |
| 762 | return expected<_Up, _Err>(unexpect, error()); | |
| 763 | } | |
| 764 | if constexpr (!is_void_v<_Up>) { | |
| 765 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); | |
| 766 | } else { | |
| 767 | std::invoke(std::forward<_Func>(__f), value()); | |
| 768 | return expected<_Up, _Err>(); | |
| 769 | } | |
| 770 | } | |
| 771 | ||
| 772 | template <class _Func> | |
| 773 | requires is_constructible_v<_Err, const _Err&> | |
| 774 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { | |
| 775 | using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&>>; | |
| 776 | if (!has_value()) { | |
| 777 | return expected<_Up, _Err>(unexpect, error()); | |
| 778 | } | |
| 779 | if constexpr (!is_void_v<_Up>) { | |
| 780 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); | |
| 781 | } else { | |
| 782 | std::invoke(std::forward<_Func>(__f), value()); | |
| 783 | return expected<_Up, _Err>(); | |
| 784 | } | |
| 785 | } | |
| 786 | ||
| 787 | template <class _Func> | |
| 788 | requires is_constructible_v<_Err, _Err&&> | |
| 789 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { | |
| 790 | using _Up = remove_cv_t<invoke_result_t<_Func, _Tp&&>>; | |
| 791 | if (!has_value()) { | |
| 792 | return expected<_Up, _Err>(unexpect, std::move(error())); | |
| 793 | } | |
| 794 | if constexpr (!is_void_v<_Up>) { | |
| 795 | return expected<_Up, _Err>( | |
| 796 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); | |
| 797 | } else { | |
| 798 | std::invoke(std::forward<_Func>(__f), std::move(value())); | |
| 799 | return expected<_Up, _Err>(); | |
| 800 | } | |
| 801 | } | |
| 802 | ||
| 803 | template <class _Func> | |
| 804 | requires is_constructible_v<_Err, const _Err&&> | |
| 805 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { | |
| 806 | using _Up = remove_cv_t<invoke_result_t<_Func, const _Tp&&>>; | |
| 807 | if (!has_value()) { | |
| 808 | return expected<_Up, _Err>(unexpect, std::move(error())); | |
| 809 | } | |
| 810 | if constexpr (!is_void_v<_Up>) { | |
| 811 | return expected<_Up, _Err>( | |
| 812 | __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); | |
| 813 | } else { | |
| 814 | std::invoke(std::forward<_Func>(__f), std::move(value())); | |
| 815 | return expected<_Up, _Err>(); | |
| 816 | } | |
| 817 | } | |
| 818 | ||
| 819 | template <class _Func> | |
| 820 | requires is_constructible_v<_Tp, _Tp&> | |
| 821 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { | |
| 822 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; | |
| 823 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 824 | "The result of f(error()) must be a valid template argument for unexpected"); | |
| 825 | if (has_value()) { | |
| 826 | return expected<_Tp, _Gp>(in_place, value()); | |
| 827 | } | |
| 828 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); | |
| 829 | } | |
| 830 | ||
| 831 | template <class _Func> | |
| 832 | requires is_constructible_v<_Tp, const _Tp&> | |
| 833 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { | |
| 834 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; | |
| 835 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 836 | "The result of f(error()) must be a valid template argument for unexpected"); | |
| 837 | if (has_value()) { | |
| 838 | return expected<_Tp, _Gp>(in_place, value()); | |
| 839 | } | |
| 840 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); | |
| 841 | } | |
| 842 | ||
| 843 | template <class _Func> | |
| 844 | requires is_constructible_v<_Tp, _Tp&&> | |
| 845 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { | |
| 846 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; | |
| 847 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 848 | "The result of f(std::move(error())) must be a valid template argument for unexpected"); | |
| 849 | if (has_value()) { | |
| 850 | return expected<_Tp, _Gp>(in_place, std::move(value())); | |
| 851 | } | |
| 852 | return expected<_Tp, _Gp>( | |
| 853 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); | |
| 854 | } | |
| 855 | ||
| 856 | template <class _Func> | |
| 857 | requires is_constructible_v<_Tp, const _Tp&&> | |
| 858 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { | |
| 859 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; | |
| 860 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 861 | "The result of f(std::move(error())) must be a valid template argument for unexpected"); | |
| 862 | if (has_value()) { | |
| 863 | return expected<_Tp, _Gp>(in_place, std::move(value())); | |
| 864 | } | |
| 865 | return expected<_Tp, _Gp>( | |
| 866 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); | |
| 867 | } | |
| 868 | ||
| 601 | 869 | // [expected.object.eq], equality operators |
| 602 | 870 | template <class _T2, class _E2> |
| 603 | 871 | requires(!is_void_v<_T2>) |
| ... | ... | @@ -625,24 +893,66 @@ public: |
| 625 | 893 | |
| 626 | 894 | private: |
| 627 | 895 | struct __empty_t {}; |
| 628 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union | |
| 629 | _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { | |
| 896 | ||
| 897 | template <class _ValueType, class _ErrorType> | |
| 898 | union __union_t { | |
| 899 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {} | |
| 900 | ||
| 901 | template <class _Func, class... _Args> | |
| 902 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 903 | std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 904 | : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 905 | ||
| 906 | template <class _Func, class... _Args> | |
| 907 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 908 | std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 909 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 910 | ||
| 911 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() | |
| 912 | requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) | |
| 913 | = default; | |
| 914 | ||
| 915 | // the expected's destructor handles this | |
| 916 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} | |
| 917 | ||
| 918 | _ValueType __val_; | |
| 919 | _ErrorType __unex_; | |
| 920 | }; | |
| 921 | ||
| 922 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union, | |
| 923 | // also guaranteed elision into a potentially-overlapping subobject is unsettled (and | |
| 924 | // it's not clear that it's implementable, given that the function is allowed to clobber | |
| 925 | // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. | |
| 926 | template <class _ValueType, class _ErrorType> | |
| 927 | requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>) | |
| 928 | union __union_t<_ValueType, _ErrorType> { | |
| 630 | 929 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} |
| 631 | 930 | |
| 931 | template <class _Func, class... _Args> | |
| 932 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 933 | std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 934 | : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 935 | ||
| 936 | template <class _Func, class... _Args> | |
| 937 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 938 | std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 939 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 940 | ||
| 632 | 941 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
| 633 | requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) | |
| 942 | requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) | |
| 634 | 943 | = default; |
| 635 | 944 | |
| 636 | 945 | // the expected's destructor handles this |
| 637 | 946 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
| 638 | requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) | |
| 947 | requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>) | |
| 639 | 948 | {} |
| 640 | 949 | |
| 641 | 950 | _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; |
| 642 | _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; | |
| 643 | _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; | |
| 644 | } __union_; | |
| 951 | _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_; | |
| 952 | _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; | |
| 953 | }; | |
| 645 | 954 | |
| 955 | _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_; | |
| 646 | 956 | bool __has_val_; |
| 647 | 957 | }; |
| 648 | 958 | |
| ... | ... | @@ -762,6 +1072,19 @@ public: |
| 762 | 1072 | std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); |
| 763 | 1073 | } |
| 764 | 1074 | |
| 1075 | private: | |
| 1076 | template <class _Func> | |
| 1077 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f) | |
| 1078 | : __has_val_(true) { | |
| 1079 | std::invoke(std::forward<_Func>(__f)); | |
| 1080 | } | |
| 1081 | ||
| 1082 | template <class _Func, class... _Args> | |
| 1083 | _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( | |
| 1084 | __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) | |
| 1085 | : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} | |
| 1086 | ||
| 1087 | public: | |
| 765 | 1088 | // [expected.void.dtor], destructor |
| 766 | 1089 | |
| 767 | 1090 | _LIBCPP_HIDE_FROM_ABI constexpr ~expected() |
| ... | ... | @@ -894,41 +1217,270 @@ public: |
| 894 | 1217 | _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } |
| 895 | 1218 | |
| 896 | 1219 | _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { |
| 897 | _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 1220 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__has_val_, "expected::operator* requires the expected to contain a value"); | |
| 898 | 1221 | } |
| 899 | 1222 | |
| 900 | 1223 | _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { |
| 901 | 1224 | if (!__has_val_) { |
| 902 | __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); | |
| 1225 | std::__throw_bad_expected_access<_Err>(__union_.__unex_); | |
| 903 | 1226 | } |
| 904 | 1227 | } |
| 905 | 1228 | |
| 906 | 1229 | _LIBCPP_HIDE_FROM_ABI constexpr void value() && { |
| 907 | 1230 | if (!__has_val_) { |
| 908 | __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); | |
| 1231 | std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); | |
| 909 | 1232 | } |
| 910 | 1233 | } |
| 911 | 1234 | |
| 912 | 1235 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { |
| 913 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 1236 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 914 | 1237 | return __union_.__unex_; |
| 915 | 1238 | } |
| 916 | 1239 | |
| 917 | 1240 | _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { |
| 918 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 1241 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 919 | 1242 | return __union_.__unex_; |
| 920 | 1243 | } |
| 921 | 1244 | |
| 922 | 1245 | _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { |
| 923 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 1246 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 924 | 1247 | return std::move(__union_.__unex_); |
| 925 | 1248 | } |
| 926 | 1249 | |
| 927 | 1250 | _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { |
| 928 | _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 1251 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!__has_val_, "expected::error requires the expected to contain an error"); | |
| 929 | 1252 | return std::move(__union_.__unex_); |
| 930 | 1253 | } |
| 931 | 1254 | |
| 1255 | template <class _Up = _Err> | |
| 1256 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) const& { | |
| 1257 | static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); | |
| 1258 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); | |
| 1259 | if (has_value()) { | |
| 1260 | return std::forward<_Up>(__error); | |
| 1261 | } | |
| 1262 | return error(); | |
| 1263 | } | |
| 1264 | ||
| 1265 | template <class _Up = _Err> | |
| 1266 | _LIBCPP_HIDE_FROM_ABI constexpr _Err error_or(_Up&& __error) && { | |
| 1267 | static_assert(is_move_constructible_v<_Err>, "error_type has to be move constructible"); | |
| 1268 | static_assert(is_convertible_v<_Up, _Err>, "argument has to be convertible to error_type"); | |
| 1269 | if (has_value()) { | |
| 1270 | return std::forward<_Up>(__error); | |
| 1271 | } | |
| 1272 | return std::move(error()); | |
| 1273 | } | |
| 1274 | ||
| 1275 | // [expected.void.monadic], monadic | |
| 1276 | template <class _Func> | |
| 1277 | requires is_constructible_v<_Err, _Err&> | |
| 1278 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { | |
| 1279 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; | |
| 1280 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); | |
| 1281 | static_assert( | |
| 1282 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); | |
| 1283 | if (has_value()) { | |
| 1284 | return std::invoke(std::forward<_Func>(__f)); | |
| 1285 | } | |
| 1286 | return _Up(unexpect, error()); | |
| 1287 | } | |
| 1288 | ||
| 1289 | template <class _Func> | |
| 1290 | requires is_constructible_v<_Err, const _Err&> | |
| 1291 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { | |
| 1292 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; | |
| 1293 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); | |
| 1294 | static_assert( | |
| 1295 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); | |
| 1296 | if (has_value()) { | |
| 1297 | return std::invoke(std::forward<_Func>(__f)); | |
| 1298 | } | |
| 1299 | return _Up(unexpect, error()); | |
| 1300 | } | |
| 1301 | ||
| 1302 | template <class _Func> | |
| 1303 | requires is_constructible_v<_Err, _Err&&> | |
| 1304 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { | |
| 1305 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; | |
| 1306 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); | |
| 1307 | static_assert( | |
| 1308 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); | |
| 1309 | if (has_value()) { | |
| 1310 | return std::invoke(std::forward<_Func>(__f)); | |
| 1311 | } | |
| 1312 | return _Up(unexpect, std::move(error())); | |
| 1313 | } | |
| 1314 | ||
| 1315 | template <class _Func> | |
| 1316 | requires is_constructible_v<_Err, const _Err&&> | |
| 1317 | _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { | |
| 1318 | using _Up = remove_cvref_t<invoke_result_t<_Func>>; | |
| 1319 | static_assert(__is_std_expected<_Up>::value, "The result of f() must be a specialization of std::expected"); | |
| 1320 | static_assert( | |
| 1321 | is_same_v<typename _Up::error_type, _Err>, "The result of f() must have the same error_type as this expected"); | |
| 1322 | if (has_value()) { | |
| 1323 | return std::invoke(std::forward<_Func>(__f)); | |
| 1324 | } | |
| 1325 | return _Up(unexpect, std::move(error())); | |
| 1326 | } | |
| 1327 | ||
| 1328 | template <class _Func> | |
| 1329 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) & { | |
| 1330 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&>>; | |
| 1331 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); | |
| 1332 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 1333 | "The result of f(error()) must have the same value_type as this expected"); | |
| 1334 | if (has_value()) { | |
| 1335 | return _Gp(); | |
| 1336 | } | |
| 1337 | return std::invoke(std::forward<_Func>(__f), error()); | |
| 1338 | } | |
| 1339 | ||
| 1340 | template <class _Func> | |
| 1341 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const& { | |
| 1342 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&>>; | |
| 1343 | static_assert(__is_std_expected<_Gp>::value, "The result of f(error()) must be a specialization of std::expected"); | |
| 1344 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 1345 | "The result of f(error()) must have the same value_type as this expected"); | |
| 1346 | if (has_value()) { | |
| 1347 | return _Gp(); | |
| 1348 | } | |
| 1349 | return std::invoke(std::forward<_Func>(__f), error()); | |
| 1350 | } | |
| 1351 | ||
| 1352 | template <class _Func> | |
| 1353 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { | |
| 1354 | using _Gp = remove_cvref_t<invoke_result_t<_Func, _Err&&>>; | |
| 1355 | static_assert(__is_std_expected<_Gp>::value, | |
| 1356 | "The result of f(std::move(error())) must be a specialization of std::expected"); | |
| 1357 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 1358 | "The result of f(std::move(error())) must have the same value_type as this expected"); | |
| 1359 | if (has_value()) { | |
| 1360 | return _Gp(); | |
| 1361 | } | |
| 1362 | return std::invoke(std::forward<_Func>(__f), std::move(error())); | |
| 1363 | } | |
| 1364 | ||
| 1365 | template <class _Func> | |
| 1366 | _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { | |
| 1367 | using _Gp = remove_cvref_t<invoke_result_t<_Func, const _Err&&>>; | |
| 1368 | static_assert(__is_std_expected<_Gp>::value, | |
| 1369 | "The result of f(std::move(error())) must be a specialization of std::expected"); | |
| 1370 | static_assert(is_same_v<typename _Gp::value_type, _Tp>, | |
| 1371 | "The result of f(std::move(error())) must have the same value_type as this expected"); | |
| 1372 | if (has_value()) { | |
| 1373 | return _Gp(); | |
| 1374 | } | |
| 1375 | return std::invoke(std::forward<_Func>(__f), std::move(error())); | |
| 1376 | } | |
| 1377 | ||
| 1378 | template <class _Func> | |
| 1379 | requires is_constructible_v<_Err, _Err&> | |
| 1380 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) & { | |
| 1381 | using _Up = remove_cv_t<invoke_result_t<_Func>>; | |
| 1382 | if (!has_value()) { | |
| 1383 | return expected<_Up, _Err>(unexpect, error()); | |
| 1384 | } | |
| 1385 | if constexpr (!is_void_v<_Up>) { | |
| 1386 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); | |
| 1387 | } else { | |
| 1388 | std::invoke(std::forward<_Func>(__f)); | |
| 1389 | return expected<_Up, _Err>(); | |
| 1390 | } | |
| 1391 | } | |
| 1392 | ||
| 1393 | template <class _Func> | |
| 1394 | requires is_constructible_v<_Err, const _Err&> | |
| 1395 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const& { | |
| 1396 | using _Up = remove_cv_t<invoke_result_t<_Func>>; | |
| 1397 | if (!has_value()) { | |
| 1398 | return expected<_Up, _Err>(unexpect, error()); | |
| 1399 | } | |
| 1400 | if constexpr (!is_void_v<_Up>) { | |
| 1401 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); | |
| 1402 | } else { | |
| 1403 | std::invoke(std::forward<_Func>(__f)); | |
| 1404 | return expected<_Up, _Err>(); | |
| 1405 | } | |
| 1406 | } | |
| 1407 | ||
| 1408 | template <class _Func> | |
| 1409 | requires is_constructible_v<_Err, _Err&&> | |
| 1410 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) && { | |
| 1411 | using _Up = remove_cv_t<invoke_result_t<_Func>>; | |
| 1412 | if (!has_value()) { | |
| 1413 | return expected<_Up, _Err>(unexpect, std::move(error())); | |
| 1414 | } | |
| 1415 | if constexpr (!is_void_v<_Up>) { | |
| 1416 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); | |
| 1417 | } else { | |
| 1418 | std::invoke(std::forward<_Func>(__f)); | |
| 1419 | return expected<_Up, _Err>(); | |
| 1420 | } | |
| 1421 | } | |
| 1422 | ||
| 1423 | template <class _Func> | |
| 1424 | requires is_constructible_v<_Err, const _Err&&> | |
| 1425 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform(_Func&& __f) const&& { | |
| 1426 | using _Up = remove_cv_t<invoke_result_t<_Func>>; | |
| 1427 | if (!has_value()) { | |
| 1428 | return expected<_Up, _Err>(unexpect, std::move(error())); | |
| 1429 | } | |
| 1430 | if constexpr (!is_void_v<_Up>) { | |
| 1431 | return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f)); | |
| 1432 | } else { | |
| 1433 | std::invoke(std::forward<_Func>(__f)); | |
| 1434 | return expected<_Up, _Err>(); | |
| 1435 | } | |
| 1436 | } | |
| 1437 | ||
| 1438 | template <class _Func> | |
| 1439 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) & { | |
| 1440 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&>>; | |
| 1441 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 1442 | "The result of f(error()) must be a valid template argument for unexpected"); | |
| 1443 | if (has_value()) { | |
| 1444 | return expected<_Tp, _Gp>(); | |
| 1445 | } | |
| 1446 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); | |
| 1447 | } | |
| 1448 | ||
| 1449 | template <class _Func> | |
| 1450 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const& { | |
| 1451 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&>>; | |
| 1452 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 1453 | "The result of f(error()) must be a valid template argument for unexpected"); | |
| 1454 | if (has_value()) { | |
| 1455 | return expected<_Tp, _Gp>(); | |
| 1456 | } | |
| 1457 | return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); | |
| 1458 | } | |
| 1459 | ||
| 1460 | template <class _Func> | |
| 1461 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) && { | |
| 1462 | using _Gp = remove_cv_t<invoke_result_t<_Func, _Err&&>>; | |
| 1463 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 1464 | "The result of f(std::move(error())) must be a valid template argument for unexpected"); | |
| 1465 | if (has_value()) { | |
| 1466 | return expected<_Tp, _Gp>(); | |
| 1467 | } | |
| 1468 | return expected<_Tp, _Gp>( | |
| 1469 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); | |
| 1470 | } | |
| 1471 | ||
| 1472 | template <class _Func> | |
| 1473 | _LIBCPP_HIDE_FROM_ABI constexpr auto transform_error(_Func&& __f) const&& { | |
| 1474 | using _Gp = remove_cv_t<invoke_result_t<_Func, const _Err&&>>; | |
| 1475 | static_assert(__valid_std_unexpected<_Gp>::value, | |
| 1476 | "The result of f(std::move(error())) must be a valid template argument for unexpected"); | |
| 1477 | if (has_value()) { | |
| 1478 | return expected<_Tp, _Gp>(); | |
| 1479 | } | |
| 1480 | return expected<_Tp, _Gp>( | |
| 1481 | __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); | |
| 1482 | } | |
| 1483 | ||
| 932 | 1484 | // [expected.void.eq], equality operators |
| 933 | 1485 | template <class _T2, class _E2> |
| 934 | 1486 | requires is_void_v<_T2> |
| ... | ... | @@ -947,23 +1499,55 @@ public: |
| 947 | 1499 | |
| 948 | 1500 | private: |
| 949 | 1501 | struct __empty_t {}; |
| 950 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union | |
| 951 | _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { | |
| 1502 | ||
| 1503 | template <class _ErrorType> | |
| 1504 | union __union_t { | |
| 952 | 1505 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} |
| 953 | 1506 | |
| 1507 | template <class _Func, class... _Args> | |
| 1508 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 1509 | __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 1510 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 1511 | ||
| 954 | 1512 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
| 955 | requires(is_trivially_destructible_v<_Err>) | |
| 1513 | requires(is_trivially_destructible_v<_ErrorType>) | |
| 956 | 1514 | = default; |
| 957 | 1515 | |
| 958 | 1516 | // the expected's destructor handles this |
| 1517 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} | |
| 1518 | ||
| 1519 | __empty_t __empty_; | |
| 1520 | _ErrorType __unex_; | |
| 1521 | }; | |
| 1522 | ||
| 1523 | // use named union because [[no_unique_address]] cannot be applied to an unnamed union, | |
| 1524 | // also guaranteed elision into a potentially-overlapping subobject is unsettled (and | |
| 1525 | // it's not clear that it's implementable, given that the function is allowed to clobber | |
| 1526 | // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. | |
| 1527 | template <class _ErrorType> | |
| 1528 | requires is_trivially_move_constructible_v<_ErrorType> | |
| 1529 | union __union_t<_ErrorType> { | |
| 1530 | _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} | |
| 1531 | ||
| 1532 | template <class _Func, class... _Args> | |
| 1533 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( | |
| 1534 | __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) | |
| 1535 | : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} | |
| 1536 | ||
| 959 | 1537 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() |
| 960 | requires(!is_trivially_destructible_v<_Err>) | |
| 1538 | requires(is_trivially_destructible_v<_ErrorType>) | |
| 1539 | = default; | |
| 1540 | ||
| 1541 | // the expected's destructor handles this | |
| 1542 | _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() | |
| 1543 | requires(!is_trivially_destructible_v<_ErrorType>) | |
| 961 | 1544 | {} |
| 962 | 1545 | |
| 963 | 1546 | _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; |
| 964 | _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; | |
| 965 | } __union_; | |
| 1547 | _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; | |
| 1548 | }; | |
| 966 | 1549 | |
| 1550 | _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_; | |
| 967 | 1551 | bool __has_val_; |
| 968 | 1552 | }; |
| 969 | 1553 | |
| ... | ... | @@ -971,4 +1555,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 971 | 1555 | |
| 972 | 1556 | #endif // _LIBCPP_STD_VER >= 23 |
| 973 | 1557 | |
| 1558 | _LIBCPP_POP_MACROS | |
| 1559 | ||
| 974 | 1560 | #endif // _LIBCPP___EXPECTED_EXPECTED_H |
lib/libcxx/include/__expected/unexpect.h+1-1| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | struct unexpect_t { |
| 23 | _LIBCPP_HIDE_FROM_ABI explicit unexpect_t() = default; | |
| 23 | explicit unexpect_t() = default; | |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | inline constexpr unexpect_t unexpect{}; |
lib/libcxx/include/__expected/unexpected.h+5| ... | ... | @@ -31,6 +31,9 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | _LIBCPP_PUSH_MACROS | |
| 35 | #include <__undef_macros> | |
| 36 | ||
| 34 | 37 | #if _LIBCPP_STD_VER >= 23 |
| 35 | 38 | |
| 36 | 39 | _LIBCPP_BEGIN_NAMESPACE_STD |
| ... | ... | @@ -119,4 +122,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 119 | 122 | |
| 120 | 123 | #endif // _LIBCPP_STD_VER >= 23 |
| 121 | 124 | |
| 125 | _LIBCPP_POP_MACROS | |
| 126 | ||
| 122 | 127 | #endif // _LIBCPP___EXPECTED_UNEXPECTED_H |
lib/libcxx/include/__filesystem/copy_options.h-4| ... | ... | @@ -21,8 +21,6 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 23 | 23 | |
| 24 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 25 | ||
| 26 | 24 | enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { |
| 27 | 25 | none = 0, |
| 28 | 26 | skip_existing = 1, |
| ... | ... | @@ -75,8 +73,6 @@ inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { |
| 75 | 73 | return __lhs = __lhs ^ __rhs; |
| 76 | 74 | } |
| 77 | 75 | |
| 78 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 79 | ||
| 80 | 76 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 81 | 77 | |
| 82 | 78 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/directory_entry.h+17-18| ... | ... | @@ -12,8 +12,8 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__availability> |
| 14 | 14 | #include <__chrono/time_point.h> |
| 15 | #include <__compare/ordering.h> | |
| 15 | 16 | #include <__config> |
| 16 | #include <__errc> | |
| 17 | 17 | #include <__filesystem/file_status.h> |
| 18 | 18 | #include <__filesystem/file_time_type.h> |
| 19 | 19 | #include <__filesystem/file_type.h> |
| ... | ... | @@ -21,11 +21,12 @@ |
| 21 | 21 | #include <__filesystem/operations.h> |
| 22 | 22 | #include <__filesystem/path.h> |
| 23 | 23 | #include <__filesystem/perms.h> |
| 24 | #include <__system_error/errc.h> | |
| 25 | #include <__system_error/error_code.h> | |
| 26 | #include <__utility/move.h> | |
| 24 | 27 | #include <__utility/unreachable.h> |
| 25 | 28 | #include <cstdint> |
| 26 | #include <cstdlib> | |
| 27 | 29 | #include <iosfwd> |
| 28 | #include <system_error> | |
| 29 | 30 | |
| 30 | 31 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 31 | 32 | # pragma GCC system_header |
| ... | ... | @@ -34,21 +35,20 @@ |
| 34 | 35 | _LIBCPP_PUSH_MACROS |
| 35 | 36 | #include <__undef_macros> |
| 36 | 37 | |
| 37 | #ifndef _LIBCPP_CXX03_LANG | |
| 38 | #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 38 | 39 | |
| 39 | 40 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 40 | 41 | |
| 41 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 42 | ||
| 42 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 43 | 43 | |
| 44 | 44 | class directory_entry { |
| 45 | 45 | typedef _VSTD_FS::path _Path; |
| 46 | 46 | |
| 47 | 47 | public: |
| 48 | 48 | // constructors and destructors |
| 49 | directory_entry() noexcept = default; | |
| 50 | directory_entry(directory_entry const&) = default; | |
| 51 | directory_entry(directory_entry&&) noexcept = default; | |
| 49 | _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; | |
| 50 | _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; | |
| 51 | _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default; | |
| 52 | 52 | |
| 53 | 53 | _LIBCPP_INLINE_VISIBILITY |
| 54 | 54 | explicit directory_entry(_Path const& __p) : __p_(__p) { |
| ... | ... | @@ -61,10 +61,10 @@ public: |
| 61 | 61 | __refresh(&__ec); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | ~directory_entry() {} | |
| 64 | _LIBCPP_HIDE_FROM_ABI ~directory_entry() {} | |
| 65 | 65 | |
| 66 | directory_entry& operator=(directory_entry const&) = default; | |
| 67 | directory_entry& operator=(directory_entry&&) noexcept = default; | |
| 66 | _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; | |
| 67 | _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default; | |
| 68 | 68 | |
| 69 | 69 | _LIBCPP_INLINE_VISIBILITY |
| 70 | 70 | void assign(_Path const& __p) { |
| ... | ... | @@ -321,8 +321,7 @@ private: |
| 321 | 321 | __data_ = __dt; |
| 322 | 322 | } |
| 323 | 323 | |
| 324 | _LIBCPP_FUNC_VIS | |
| 325 | error_code __do_refresh() noexcept; | |
| 324 | _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept; | |
| 326 | 325 | |
| 327 | 326 | _LIBCPP_INLINE_VISIBILITY |
| 328 | 327 | static bool __is_dne_error(error_code const& __ec) { |
| ... | ... | @@ -510,17 +509,17 @@ public: |
| 510 | 509 | private: |
| 511 | 510 | friend class directory_iterator; |
| 512 | 511 | friend class recursive_directory_iterator; |
| 513 | explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} | |
| 514 | __dir_element_proxy(__dir_element_proxy&& __o) | |
| 512 | _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} | |
| 513 | _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) | |
| 515 | 514 | : __elem_(_VSTD::move(__o.__elem_)) {} |
| 516 | 515 | directory_entry __elem_; |
| 517 | 516 | }; |
| 518 | 517 | |
| 519 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 518 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 520 | 519 | |
| 521 | 520 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 522 | 521 | |
| 523 | #endif // _LIBCPP_CXX03_LANG | |
| 522 | #endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 524 | 523 | |
| 525 | 524 | _LIBCPP_POP_MACROS |
| 526 | 525 |
lib/libcxx/include/__filesystem/directory_iterator.h+21-17| ... | ... | @@ -16,22 +16,24 @@ |
| 16 | 16 | #include <__filesystem/directory_entry.h> |
| 17 | 17 | #include <__filesystem/directory_options.h> |
| 18 | 18 | #include <__filesystem/path.h> |
| 19 | #include <__iterator/default_sentinel.h> | |
| 19 | 20 | #include <__iterator/iterator_traits.h> |
| 20 | 21 | #include <__memory/shared_ptr.h> |
| 21 | 22 | #include <__ranges/enable_borrowed_range.h> |
| 22 | 23 | #include <__ranges/enable_view.h> |
| 24 | #include <__system_error/error_code.h> | |
| 25 | #include <__utility/move.h> | |
| 23 | 26 | #include <cstddef> |
| 24 | #include <system_error> | |
| 25 | 27 | |
| 26 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 29 | # pragma GCC system_header |
| 28 | 30 | #endif |
| 29 | 31 | |
| 30 | #ifndef _LIBCPP_CXX03_LANG | |
| 32 | #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 31 | 33 | |
| 32 | 34 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 33 | 35 | |
| 34 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 36 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 35 | 37 | |
| 36 | 38 | class _LIBCPP_HIDDEN __dir_stream; |
| 37 | 39 | class directory_iterator { |
| ... | ... | @@ -81,7 +83,7 @@ public: |
| 81 | 83 | |
| 82 | 84 | _LIBCPP_HIDE_FROM_ABI |
| 83 | 85 | const directory_entry& operator*() const { |
| 84 | _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); | |
| 86 | _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "The end iterator cannot be dereferenced"); | |
| 85 | 87 | return __dereference(); |
| 86 | 88 | } |
| 87 | 89 | |
| ... | ... | @@ -101,21 +103,23 @@ public: |
| 101 | 103 | _LIBCPP_HIDE_FROM_ABI |
| 102 | 104 | directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } |
| 103 | 105 | |
| 106 | # if _LIBCPP_STD_VER >= 20 | |
| 107 | ||
| 108 | _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); } | |
| 109 | ||
| 110 | # endif | |
| 111 | ||
| 104 | 112 | private: |
| 105 | 113 | inline _LIBCPP_HIDE_FROM_ABI friend bool |
| 106 | 114 | operator==(const directory_iterator& __lhs, |
| 107 | 115 | const directory_iterator& __rhs) noexcept; |
| 108 | 116 | |
| 109 | 117 | // construct the dir_stream |
| 110 | _LIBCPP_FUNC_VIS | |
| 111 | directory_iterator(const path&, error_code*, | |
| 112 | directory_options = directory_options::none); | |
| 118 | _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none); | |
| 113 | 119 | |
| 114 | _LIBCPP_FUNC_VIS | |
| 115 | directory_iterator& __increment(error_code* __ec = nullptr); | |
| 120 | _LIBCPP_EXPORTED_FROM_ABI directory_iterator& __increment(error_code* __ec = nullptr); | |
| 116 | 121 | |
| 117 | _LIBCPP_FUNC_VIS | |
| 118 | const directory_entry& __dereference() const; | |
| 122 | _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const; | |
| 119 | 123 | |
| 120 | 124 | private: |
| 121 | 125 | shared_ptr<__dir_stream> __imp_; |
| ... | ... | @@ -144,22 +148,22 @@ end(directory_iterator) noexcept { |
| 144 | 148 | return directory_iterator(); |
| 145 | 149 | } |
| 146 | 150 | |
| 147 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 151 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 148 | 152 | |
| 149 | 153 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 150 | 154 | |
| 151 | #if _LIBCPP_STD_VER > 17 | |
| 155 | #if _LIBCPP_STD_VER >= 20 | |
| 152 | 156 | |
| 153 | 157 | template <> |
| 154 | _LIBCPP_AVAILABILITY_FILESYSTEM | |
| 158 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 155 | 159 | inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; |
| 156 | 160 | |
| 157 | 161 | template <> |
| 158 | _LIBCPP_AVAILABILITY_FILESYSTEM | |
| 162 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 159 | 163 | inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; |
| 160 | 164 | |
| 161 | #endif // _LIBCPP_STD_VER > 17 | |
| 165 | #endif // _LIBCPP_STD_VER >= 20 | |
| 162 | 166 | |
| 163 | #endif // _LIBCPP_CXX03_LANG | |
| 167 | #endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 164 | 168 | |
| 165 | 169 | #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H |
lib/libcxx/include/__filesystem/directory_options.h-4| ... | ... | @@ -21,8 +21,6 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 23 | 23 | |
| 24 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 25 | ||
| 26 | 24 | enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { |
| 27 | 25 | none = 0, |
| 28 | 26 | follow_directory_symlink = 1, |
| ... | ... | @@ -73,8 +71,6 @@ inline directory_options& operator^=(directory_options& __lhs, |
| 73 | 71 | return __lhs = __lhs ^ __rhs; |
| 74 | 72 | } |
| 75 | 73 | |
| 76 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 77 | ||
| 78 | 74 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 79 | 75 | |
| 80 | 76 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/file_status.h+13-9| ... | ... | @@ -23,9 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 25 | 25 | |
| 26 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 27 | ||
| 28 | class _LIBCPP_TYPE_VIS file_status { | |
| 26 | class _LIBCPP_EXPORTED_FROM_ABI file_status { | |
| 29 | 27 | public: |
| 30 | 28 | // constructors |
| 31 | 29 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -35,14 +33,14 @@ public: |
| 35 | 33 | : __ft_(__ft), |
| 36 | 34 | __prms_(__prms) {} |
| 37 | 35 | |
| 38 | file_status(const file_status&) noexcept = default; | |
| 39 | file_status(file_status&&) noexcept = default; | |
| 36 | _LIBCPP_HIDE_FROM_ABI file_status(const file_status&) noexcept = default; | |
| 37 | _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default; | |
| 40 | 38 | |
| 41 | 39 | _LIBCPP_INLINE_VISIBILITY |
| 42 | 40 | ~file_status() {} |
| 43 | 41 | |
| 44 | file_status& operator=(const file_status&) noexcept = default; | |
| 45 | file_status& operator=(file_status&&) noexcept = default; | |
| 42 | _LIBCPP_HIDE_FROM_ABI file_status& operator=(const file_status&) noexcept = default; | |
| 43 | _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default; | |
| 46 | 44 | |
| 47 | 45 | // observers |
| 48 | 46 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -58,13 +56,19 @@ public: |
| 58 | 56 | _LIBCPP_INLINE_VISIBILITY |
| 59 | 57 | void permissions(perms __p) noexcept { __prms_ = __p; } |
| 60 | 58 | |
| 59 | # if _LIBCPP_STD_VER >= 20 | |
| 60 | ||
| 61 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const file_status& __lhs, const file_status& __rhs) noexcept { | |
| 62 | return __lhs.type() == __rhs.type() && __lhs.permissions() == __rhs.permissions(); | |
| 63 | } | |
| 64 | ||
| 65 | # endif | |
| 66 | ||
| 61 | 67 | private: |
| 62 | 68 | file_type __ft_; |
| 63 | 69 | perms __prms_; |
| 64 | 70 | }; |
| 65 | 71 | |
| 66 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 67 | ||
| 68 | 72 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 69 | 73 | |
| 70 | 74 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/filesystem_error.h+25-38| ... | ... | @@ -14,11 +14,13 @@ |
| 14 | 14 | #include <__config> |
| 15 | 15 | #include <__filesystem/path.h> |
| 16 | 16 | #include <__memory/shared_ptr.h> |
| 17 | #include <__system_error/error_code.h> | |
| 18 | #include <__system_error/system_error.h> | |
| 17 | 19 | #include <__utility/forward.h> |
| 20 | #include <__verbose_abort> | |
| 18 | 21 | #include <iosfwd> |
| 19 | 22 | #include <new> |
| 20 | #include <system_error> | |
| 21 | #include <type_traits> | |
| 23 | #include <string> | |
| 22 | 24 | |
| 23 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 26 | # pragma GCC system_header |
| ... | ... | @@ -28,50 +30,38 @@ |
| 28 | 30 | |
| 29 | 31 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 30 | 32 | |
| 31 | class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { | |
| 33 | class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error { | |
| 32 | 34 | public: |
| 33 | _LIBCPP_INLINE_VISIBILITY | |
| 34 | filesystem_error(const string& __what, error_code __ec) | |
| 35 | : system_error(__ec, __what), | |
| 36 | __storage_(make_shared<_Storage>(path(), path())) { | |
| 35 | _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, error_code __ec) | |
| 36 | : system_error(__ec, __what), __storage_(make_shared<_Storage>(path(), path())) { | |
| 37 | 37 | __create_what(0); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | _LIBCPP_INLINE_VISIBILITY | |
| 41 | filesystem_error(const string& __what, const path& __p1, error_code __ec) | |
| 42 | : system_error(__ec, __what), | |
| 43 | __storage_(make_shared<_Storage>(__p1, path())) { | |
| 40 | _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, error_code __ec) | |
| 41 | : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, path())) { | |
| 44 | 42 | __create_what(1); |
| 45 | 43 | } |
| 46 | 44 | |
| 47 | _LIBCPP_INLINE_VISIBILITY | |
| 48 | filesystem_error(const string& __what, const path& __p1, const path& __p2, | |
| 49 | error_code __ec) | |
| 50 | : system_error(__ec, __what), | |
| 51 | __storage_(make_shared<_Storage>(__p1, __p2)) { | |
| 45 | _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, const path& __p2, error_code __ec) | |
| 46 | : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, __p2)) { | |
| 52 | 47 | __create_what(2); |
| 53 | 48 | } |
| 54 | 49 | |
| 55 | _LIBCPP_INLINE_VISIBILITY | |
| 56 | const path& path1() const noexcept { return __storage_->__p1_; } | |
| 50 | _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; } | |
| 57 | 51 | |
| 58 | _LIBCPP_INLINE_VISIBILITY | |
| 59 | const path& path2() const noexcept { return __storage_->__p2_; } | |
| 52 | _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; } | |
| 60 | 53 | |
| 61 | filesystem_error(const filesystem_error&) = default; | |
| 54 | _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default; | |
| 62 | 55 | ~filesystem_error() override; // key function |
| 63 | 56 | |
| 64 | 57 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL |
| 65 | const char* what() const noexcept override { | |
| 66 | return __storage_->__what_.c_str(); | |
| 67 | } | |
| 58 | const char* what() const noexcept override { return __storage_->__what_.c_str(); } | |
| 68 | 59 | |
| 69 | 60 | void __create_what(int __num_paths); |
| 70 | 61 | |
| 71 | 62 | private: |
| 72 | 63 | struct _LIBCPP_HIDDEN _Storage { |
| 73 | _LIBCPP_INLINE_VISIBILITY | |
| 74 | _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} | |
| 64 | _LIBCPP_HIDE_FROM_ABI _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} | |
| 75 | 65 | |
| 76 | 66 | path __p1_; |
| 77 | 67 | path __p2_; |
| ... | ... | @@ -80,22 +70,19 @@ private: |
| 80 | 70 | shared_ptr<_Storage> __storage_; |
| 81 | 71 | }; |
| 82 | 72 | |
| 83 | // TODO(ldionne): We need to pop the pragma and push it again after | |
| 84 | // filesystem_error to work around PR41078. | |
| 85 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 86 | ||
| 73 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 87 | 74 | template <class... _Args> |
| 88 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY | |
| 89 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 90 | void __throw_filesystem_error(_Args&&... __args) { | |
| 75 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void | |
| 76 | __throw_filesystem_error(_Args&&... __args) { | |
| 91 | 77 | throw filesystem_error(_VSTD::forward<_Args>(__args)...); |
| 92 | 78 | } |
| 93 | #else | |
| 94 | void __throw_filesystem_error(_Args&&...) { | |
| 95 | _VSTD::abort(); | |
| 79 | # else | |
| 80 | template <class... _Args> | |
| 81 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void | |
| 82 | __throw_filesystem_error(_Args&&...) { | |
| 83 | _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode"); | |
| 96 | 84 | } |
| 97 | #endif | |
| 98 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 85 | # endif | |
| 99 | 86 | |
| 100 | 87 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 101 | 88 |
lib/libcxx/include/__filesystem/operations.h+36-36| ... | ... | @@ -21,46 +21,46 @@ |
| 21 | 21 | #include <__filesystem/perm_options.h> |
| 22 | 22 | #include <__filesystem/perms.h> |
| 23 | 23 | #include <__filesystem/space_info.h> |
| 24 | #include <__system_error/error_code.h> | |
| 24 | 25 | #include <cstdint> |
| 25 | #include <system_error> | |
| 26 | 26 | |
| 27 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | #ifndef _LIBCPP_CXX03_LANG | |
| 31 | #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 34 | 34 | |
| 35 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 36 | ||
| 37 | _LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); | |
| 38 | _LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); | |
| 39 | _LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); | |
| 40 | _LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); | |
| 41 | _LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); | |
| 42 | _LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr); | |
| 43 | _LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); | |
| 44 | _LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr); | |
| 45 | _LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); | |
| 46 | _LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); | |
| 47 | _LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); | |
| 48 | _LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); | |
| 49 | _LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); | |
| 50 | _LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); | |
| 51 | _LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); | |
| 52 | _LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); | |
| 53 | _LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); | |
| 54 | _LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); | |
| 55 | _LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr); | |
| 56 | _LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); | |
| 57 | _LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); | |
| 58 | _LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr); | |
| 59 | _LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr); | |
| 60 | _LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr); | |
| 61 | _LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); | |
| 62 | _LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); | |
| 63 | _LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); | |
| 35 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 36 | ||
| 37 | _LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr); | |
| 38 | _LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr); | |
| 39 | _LIBCPP_EXPORTED_FROM_ABI bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); | |
| 40 | _LIBCPP_EXPORTED_FROM_ABI void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); | |
| 41 | _LIBCPP_EXPORTED_FROM_ABI void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); | |
| 42 | _LIBCPP_EXPORTED_FROM_ABI bool __create_directories(const path&, error_code* = nullptr); | |
| 43 | _LIBCPP_EXPORTED_FROM_ABI void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); | |
| 44 | _LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, error_code* = nullptr); | |
| 45 | _LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); | |
| 46 | _LIBCPP_EXPORTED_FROM_ABI void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); | |
| 47 | _LIBCPP_EXPORTED_FROM_ABI void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); | |
| 48 | _LIBCPP_EXPORTED_FROM_ABI path __current_path(error_code* __ec = nullptr); | |
| 49 | _LIBCPP_EXPORTED_FROM_ABI void __current_path(const path&, error_code* __ec = nullptr); | |
| 50 | _LIBCPP_EXPORTED_FROM_ABI bool __equivalent(const path&, const path&, error_code* __ec = nullptr); | |
| 51 | _LIBCPP_EXPORTED_FROM_ABI file_status __status(const path&, error_code* __ec = nullptr); | |
| 52 | _LIBCPP_EXPORTED_FROM_ABI uintmax_t __file_size(const path&, error_code* __ec = nullptr); | |
| 53 | _LIBCPP_EXPORTED_FROM_ABI uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); | |
| 54 | _LIBCPP_EXPORTED_FROM_ABI file_status __symlink_status(const path&, error_code* __ec = nullptr); | |
| 55 | _LIBCPP_EXPORTED_FROM_ABI file_time_type __last_write_time(const path&, error_code* __ec = nullptr); | |
| 56 | _LIBCPP_EXPORTED_FROM_ABI void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); | |
| 57 | _LIBCPP_EXPORTED_FROM_ABI path __weakly_canonical(path const& __p, error_code* __ec = nullptr); | |
| 58 | _LIBCPP_EXPORTED_FROM_ABI path __read_symlink(const path&, error_code* __ec = nullptr); | |
| 59 | _LIBCPP_EXPORTED_FROM_ABI uintmax_t __remove_all(const path&, error_code* __ec = nullptr); | |
| 60 | _LIBCPP_EXPORTED_FROM_ABI bool __remove(const path&, error_code* __ec = nullptr); | |
| 61 | _LIBCPP_EXPORTED_FROM_ABI void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); | |
| 62 | _LIBCPP_EXPORTED_FROM_ABI void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); | |
| 63 | _LIBCPP_EXPORTED_FROM_ABI path __temp_directory_path(error_code* __ec = nullptr); | |
| 64 | 64 | |
| 65 | 65 | inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); } |
| 66 | 66 | inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } |
| ... | ... | @@ -118,7 +118,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& |
| 118 | 118 | inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } |
| 119 | 119 | inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); } |
| 120 | 120 | inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } |
| 121 | _LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); | |
| 121 | _LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); | |
| 122 | 122 | inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); } |
| 123 | 123 | inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } |
| 124 | 124 | inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } |
| ... | ... | @@ -140,7 +140,7 @@ inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { r |
| 140 | 140 | inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } |
| 141 | 141 | inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } |
| 142 | 142 | inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } |
| 143 | _LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); | |
| 143 | _LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr); | |
| 144 | 144 | inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } |
| 145 | 145 | inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } |
| 146 | 146 | inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } |
| ... | ... | @@ -180,7 +180,7 @@ inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { |
| 180 | 180 | inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } |
| 181 | 181 | inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } |
| 182 | 182 | inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } |
| 183 | _LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); | |
| 183 | _LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr); | |
| 184 | 184 | inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); } |
| 185 | 185 | inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } |
| 186 | 186 | inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); } |
| ... | ... | @@ -192,10 +192,10 @@ inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return |
| 192 | 192 | inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } |
| 193 | 193 | inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } |
| 194 | 194 | |
| 195 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 195 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 196 | 196 | |
| 197 | 197 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 198 | 198 | |
| 199 | #endif // _LIBCPP_CXX03_LANG | |
| 199 | #endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 200 | 200 | |
| 201 | 201 | #endif // _LIBCPP___FILESYSTEM_OPERATIONS_H |
lib/libcxx/include/__filesystem/path.h+31-17| ... | ... | @@ -14,12 +14,18 @@ |
| 14 | 14 | #include <__algorithm/replace_copy.h> |
| 15 | 15 | #include <__availability> |
| 16 | 16 | #include <__config> |
| 17 | #include <__functional/hash.h> | |
| 18 | #include <__functional/unary_function.h> | |
| 19 | #include <__fwd/hash.h> | |
| 17 | 20 | #include <__iterator/back_insert_iterator.h> |
| 18 | 21 | #include <__iterator/iterator_traits.h> |
| 22 | #include <__type_traits/decay.h> | |
| 23 | #include <__type_traits/is_pointer.h> | |
| 24 | #include <__type_traits/remove_const.h> | |
| 25 | #include <__type_traits/remove_pointer.h> | |
| 19 | 26 | #include <cstddef> |
| 20 | 27 | #include <string> |
| 21 | 28 | #include <string_view> |
| 22 | #include <type_traits> | |
| 23 | 29 | |
| 24 | 30 | #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) |
| 25 | 31 | # include <iomanip> // for quoted |
| ... | ... | @@ -34,7 +40,7 @@ |
| 34 | 40 | |
| 35 | 41 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 36 | 42 | |
| 37 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 43 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 38 | 44 | |
| 39 | 45 | template <class _Tp> |
| 40 | 46 | struct __can_convert_char { |
| ... | ... | @@ -139,7 +145,7 @@ struct __is_pathable_string< |
| 139 | 145 | } |
| 140 | 146 | }; |
| 141 | 147 | |
| 142 | template <class _Source, class _DS = typename decay<_Source>::type, | |
| 148 | template <class _Source, class _DS = __decay_t<_Source>, | |
| 143 | 149 | class _UnqualPtrType = |
| 144 | 150 | __remove_const_t<__remove_pointer_t<_DS> >, |
| 145 | 151 | bool _IsCharPtr = is_pointer<_DS>::value&& |
| ... | ... | @@ -168,7 +174,7 @@ struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> |
| 168 | 174 | static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } |
| 169 | 175 | }; |
| 170 | 176 | |
| 171 | template <class _Iter, bool _IsIt = __is_cpp17_input_iterator<_Iter>::value, | |
| 177 | template <class _Iter, bool _IsIt = __has_input_iterator_category<_Iter>::value, | |
| 172 | 178 | class = void> |
| 173 | 179 | struct __is_pathable_iter : false_type {}; |
| 174 | 180 | |
| ... | ... | @@ -217,10 +223,8 @@ typedef char __path_value; |
| 217 | 223 | #endif |
| 218 | 224 | |
| 219 | 225 | #if defined(_LIBCPP_WIN32API) |
| 220 | _LIBCPP_FUNC_VIS | |
| 221 | size_t __wide_to_char(const wstring&, char*, size_t); | |
| 222 | _LIBCPP_FUNC_VIS | |
| 223 | size_t __char_to_wide(const string&, wchar_t*, size_t); | |
| 226 | _LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t); | |
| 227 | _LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t); | |
| 224 | 228 | #endif |
| 225 | 229 | |
| 226 | 230 | template <class _ECharT> |
| ... | ... | @@ -303,7 +307,7 @@ struct _PathCVT<__path_value> { |
| 303 | 307 | |
| 304 | 308 | template <class _Iter> |
| 305 | 309 | _LIBCPP_HIDE_FROM_ABI |
| 306 | static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type | |
| 310 | static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type | |
| 307 | 311 | __append_range(__path_string& __dest, _Iter __b, _Iter __e) { |
| 308 | 312 | for (; __b != __e; ++__b) |
| 309 | 313 | __dest.push_back(*__b); |
| ... | ... | @@ -311,7 +315,7 @@ struct _PathCVT<__path_value> { |
| 311 | 315 | |
| 312 | 316 | template <class _Iter> |
| 313 | 317 | _LIBCPP_HIDE_FROM_ABI |
| 314 | static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type | |
| 318 | static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type | |
| 315 | 319 | __append_range(__path_string& __dest, _Iter __b, _Iter __e) { |
| 316 | 320 | __dest.append(__b, __e); |
| 317 | 321 | } |
| ... | ... | @@ -348,7 +352,7 @@ struct _PathCVT<char> { |
| 348 | 352 | |
| 349 | 353 | template <class _Iter> |
| 350 | 354 | _LIBCPP_HIDE_FROM_ABI |
| 351 | static typename enable_if<__is_exactly_cpp17_input_iterator<_Iter>::value>::type | |
| 355 | static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type | |
| 352 | 356 | __append_range(__path_string& __dest, _Iter __b, _Iter __e) { |
| 353 | 357 | basic_string<char> __tmp(__b, __e); |
| 354 | 358 | __append_string(__dest, __tmp); |
| ... | ... | @@ -356,7 +360,7 @@ struct _PathCVT<char> { |
| 356 | 360 | |
| 357 | 361 | template <class _Iter> |
| 358 | 362 | _LIBCPP_HIDE_FROM_ABI |
| 359 | static typename enable_if<__is_cpp17_forward_iterator<_Iter>::value>::type | |
| 363 | static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type | |
| 360 | 364 | __append_range(__path_string& __dest, _Iter __b, _Iter __e) { |
| 361 | 365 | basic_string<char> __tmp(__b, __e); |
| 362 | 366 | __append_string(__dest, __tmp); |
| ... | ... | @@ -439,7 +443,7 @@ struct _PathExport<char8_t> { |
| 439 | 443 | #endif /* !_LIBCPP_HAS_NO_CHAR8_T */ |
| 440 | 444 | #endif /* _LIBCPP_WIN32API */ |
| 441 | 445 | |
| 442 | class _LIBCPP_TYPE_VIS path { | |
| 446 | class _LIBCPP_EXPORTED_FROM_ABI path { | |
| 443 | 447 | template <class _SourceOrIter, class _Tp = path&> |
| 444 | 448 | using _EnableIfPathable = |
| 445 | 449 | typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; |
| ... | ... | @@ -1029,7 +1033,7 @@ public: |
| 1029 | 1033 | } |
| 1030 | 1034 | |
| 1031 | 1035 | // iterators |
| 1032 | class _LIBCPP_TYPE_VIS iterator; | |
| 1036 | class _LIBCPP_EXPORTED_FROM_ABI iterator; | |
| 1033 | 1037 | typedef iterator const_iterator; |
| 1034 | 1038 | |
| 1035 | 1039 | iterator begin() const; |
| ... | ... | @@ -1079,13 +1083,23 @@ inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { |
| 1079 | 1083 | __lhs.swap(__rhs); |
| 1080 | 1084 | } |
| 1081 | 1085 | |
| 1082 | _LIBCPP_FUNC_VIS | |
| 1083 | size_t hash_value(const path& __p) noexcept; | |
| 1086 | _LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept; | |
| 1084 | 1087 | |
| 1085 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 1088 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 1086 | 1089 | |
| 1087 | 1090 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 1088 | 1091 | |
| 1092 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 1093 | ||
| 1094 | template <> | |
| 1095 | struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash<_VSTD_FS::path> : __unary_function<_VSTD_FS::path, size_t> { | |
| 1096 | _LIBCPP_HIDE_FROM_ABI size_t operator()(_VSTD_FS::path const& __p) const noexcept { | |
| 1097 | return _VSTD_FS::hash_value(__p); | |
| 1098 | } | |
| 1099 | }; | |
| 1100 | ||
| 1101 | _LIBCPP_END_NAMESPACE_STD | |
| 1102 | ||
| 1089 | 1103 | #endif // _LIBCPP_CXX03_LANG |
| 1090 | 1104 | |
| 1091 | 1105 | #endif // _LIBCPP___FILESYSTEM_PATH_H |
lib/libcxx/include/__filesystem/path_iterator.h+14-16| ... | ... | @@ -27,9 +27,7 @@ |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 29 | 29 | |
| 30 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 31 | ||
| 32 | class _LIBCPP_TYPE_VIS path::iterator { | |
| 30 | class _LIBCPP_EXPORTED_FROM_ABI path::iterator { | |
| 33 | 31 | public: |
| 34 | 32 | enum _ParserState : unsigned char { |
| 35 | 33 | _Singular, |
| ... | ... | @@ -56,10 +54,10 @@ public: |
| 56 | 54 | : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), |
| 57 | 55 | __state_(_Singular) {} |
| 58 | 56 | |
| 59 | iterator(const iterator&) = default; | |
| 60 | ~iterator() = default; | |
| 57 | _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default; | |
| 58 | _LIBCPP_HIDE_FROM_ABI ~iterator() = default; | |
| 61 | 59 | |
| 62 | iterator& operator=(const iterator&) = default; | |
| 60 | _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default; | |
| 63 | 61 | |
| 64 | 62 | _LIBCPP_INLINE_VISIBILITY |
| 65 | 63 | reference operator*() const { return __stashed_elem_; } |
| ... | ... | @@ -69,10 +67,10 @@ public: |
| 69 | 67 | |
| 70 | 68 | _LIBCPP_INLINE_VISIBILITY |
| 71 | 69 | iterator& operator++() { |
| 72 | _LIBCPP_ASSERT(__state_ != _Singular, | |
| 73 | "attempting to increment a singular iterator"); | |
| 74 | _LIBCPP_ASSERT(__state_ != _AtEnd, | |
| 75 | "attempting to increment the end iterator"); | |
| 70 | _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, | |
| 71 | "attempting to increment a singular iterator"); | |
| 72 | _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, | |
| 73 | "attempting to increment the end iterator"); | |
| 76 | 74 | return __increment(); |
| 77 | 75 | } |
| 78 | 76 | |
| ... | ... | @@ -85,10 +83,10 @@ public: |
| 85 | 83 | |
| 86 | 84 | _LIBCPP_INLINE_VISIBILITY |
| 87 | 85 | iterator& operator--() { |
| 88 | _LIBCPP_ASSERT(__state_ != _Singular, | |
| 89 | "attempting to decrement a singular iterator"); | |
| 90 | _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), | |
| 91 | "attempting to decrement the begin iterator"); | |
| 86 | _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _Singular, | |
| 87 | "attempting to decrement a singular iterator"); | |
| 88 | _LIBCPP_ASSERT_UNCATEGORIZED(__entry_.data() != __path_ptr_->native().data(), | |
| 89 | "attempting to decrement the begin iterator"); | |
| 92 | 90 | return __decrement(); |
| 93 | 91 | } |
| 94 | 92 | |
| ... | ... | @@ -114,19 +112,19 @@ private: |
| 114 | 112 | _ParserState __state_; |
| 115 | 113 | }; |
| 116 | 114 | |
| 115 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 117 | 116 | inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, |
| 118 | 117 | const path::iterator& __rhs) { |
| 119 | 118 | return __lhs.__path_ptr_ == __rhs.__path_ptr_ && |
| 120 | 119 | __lhs.__entry_.data() == __rhs.__entry_.data(); |
| 121 | 120 | } |
| 122 | 121 | |
| 122 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 123 | 123 | inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, |
| 124 | 124 | const path::iterator& __rhs) { |
| 125 | 125 | return !(__lhs == __rhs); |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 129 | ||
| 130 | 128 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 131 | 129 | |
| 132 | 130 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/perm_options.h-4| ... | ... | @@ -21,8 +21,6 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 23 | 23 | |
| 24 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 25 | ||
| 26 | 24 | enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { |
| 27 | 25 | replace = 1, |
| 28 | 26 | add = 2, |
| ... | ... | @@ -68,8 +66,6 @@ inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { |
| 68 | 66 | return __lhs = __lhs ^ __rhs; |
| 69 | 67 | } |
| 70 | 68 | |
| 71 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 72 | ||
| 73 | 69 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 74 | 70 | |
| 75 | 71 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/perms.h-4| ... | ... | @@ -21,8 +21,6 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 23 | 23 | |
| 24 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 25 | ||
| 26 | 24 | // On Windows, these permission bits map to one single readonly flag per |
| 27 | 25 | // file, and the executable bit is always returned as set. When setting |
| 28 | 26 | // permissions, as long as the write bit is set for either owner, group or |
| ... | ... | @@ -86,8 +84,6 @@ inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __r |
| 86 | 84 | _LIBCPP_INLINE_VISIBILITY |
| 87 | 85 | inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } |
| 88 | 86 | |
| 89 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 90 | ||
| 91 | 87 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 92 | 88 | |
| 93 | 89 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/recursive_directory_iterator.h+30-32| ... | ... | @@ -15,22 +15,24 @@ |
| 15 | 15 | #include <__filesystem/directory_entry.h> |
| 16 | 16 | #include <__filesystem/directory_options.h> |
| 17 | 17 | #include <__filesystem/path.h> |
| 18 | #include <__iterator/default_sentinel.h> | |
| 18 | 19 | #include <__iterator/iterator_traits.h> |
| 19 | 20 | #include <__memory/shared_ptr.h> |
| 20 | 21 | #include <__ranges/enable_borrowed_range.h> |
| 21 | 22 | #include <__ranges/enable_view.h> |
| 23 | #include <__system_error/error_code.h> | |
| 24 | #include <__utility/move.h> | |
| 22 | 25 | #include <cstddef> |
| 23 | #include <system_error> | |
| 24 | 26 | |
| 25 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 28 | # pragma GCC system_header |
| 27 | 29 | #endif |
| 28 | 30 | |
| 29 | #ifndef _LIBCPP_CXX03_LANG | |
| 31 | #if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 30 | 32 | |
| 31 | 33 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 32 | 34 | |
| 33 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 35 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 34 | 36 | |
| 35 | 37 | class recursive_directory_iterator { |
| 36 | 38 | public: |
| ... | ... | @@ -59,10 +61,10 @@ public: |
| 59 | 61 | recursive_directory_iterator(const path& __p, error_code& __ec) |
| 60 | 62 | : recursive_directory_iterator(__p, directory_options::none, &__ec) {} |
| 61 | 63 | |
| 62 | recursive_directory_iterator(const recursive_directory_iterator&) = default; | |
| 63 | recursive_directory_iterator(recursive_directory_iterator&&) = default; | |
| 64 | _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default; | |
| 65 | _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; | |
| 64 | 66 | |
| 65 | recursive_directory_iterator& | |
| 67 | _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& | |
| 66 | 68 | operator=(const recursive_directory_iterator&) = default; |
| 67 | 69 | |
| 68 | 70 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -76,7 +78,7 @@ public: |
| 76 | 78 | return *this; |
| 77 | 79 | } |
| 78 | 80 | |
| 79 | ~recursive_directory_iterator() = default; | |
| 81 | _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default; | |
| 80 | 82 | |
| 81 | 83 | _LIBCPP_INLINE_VISIBILITY |
| 82 | 84 | const directory_entry& operator*() const { return __dereference(); } |
| ... | ... | @@ -84,7 +86,7 @@ public: |
| 84 | 86 | _LIBCPP_INLINE_VISIBILITY |
| 85 | 87 | const directory_entry* operator->() const { return &__dereference(); } |
| 86 | 88 | |
| 87 | recursive_directory_iterator& operator++() { return __increment(); } | |
| 89 | _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); } | |
| 88 | 90 | |
| 89 | 91 | _LIBCPP_INLINE_VISIBILITY |
| 90 | 92 | __dir_element_proxy operator++(int) { |
| ... | ... | @@ -98,8 +100,8 @@ public: |
| 98 | 100 | return __increment(&__ec); |
| 99 | 101 | } |
| 100 | 102 | |
| 101 | _LIBCPP_FUNC_VIS directory_options options() const; | |
| 102 | _LIBCPP_FUNC_VIS int depth() const; | |
| 103 | _LIBCPP_EXPORTED_FROM_ABI directory_options options() const; | |
| 104 | _LIBCPP_EXPORTED_FROM_ABI int depth() const; | |
| 103 | 105 | |
| 104 | 106 | _LIBCPP_INLINE_VISIBILITY |
| 105 | 107 | void pop() { __pop(); } |
| ... | ... | @@ -113,25 +115,21 @@ public: |
| 113 | 115 | _LIBCPP_INLINE_VISIBILITY |
| 114 | 116 | void disable_recursion_pending() { __rec_ = false; } |
| 115 | 117 | |
| 116 | private: | |
| 117 | _LIBCPP_FUNC_VIS | |
| 118 | recursive_directory_iterator(const path& __p, directory_options __opt, | |
| 119 | error_code* __ec); | |
| 120 | ||
| 121 | _LIBCPP_FUNC_VIS | |
| 122 | const directory_entry& __dereference() const; | |
| 118 | # if _LIBCPP_STD_VER >= 20 | |
| 123 | 119 | |
| 124 | _LIBCPP_FUNC_VIS | |
| 125 | bool __try_recursion(error_code* __ec); | |
| 126 | ||
| 127 | _LIBCPP_FUNC_VIS | |
| 128 | void __advance(error_code* __ec = nullptr); | |
| 120 | _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { | |
| 121 | return *this == recursive_directory_iterator(); | |
| 122 | } | |
| 129 | 123 | |
| 130 | _LIBCPP_FUNC_VIS | |
| 131 | recursive_directory_iterator& __increment(error_code* __ec = nullptr); | |
| 124 | # endif | |
| 132 | 125 | |
| 133 | _LIBCPP_FUNC_VIS | |
| 134 | void __pop(error_code* __ec = nullptr); | |
| 126 | private: | |
| 127 | _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec); | |
| 128 | _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const; | |
| 129 | _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec); | |
| 130 | _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr); | |
| 131 | _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr); | |
| 132 | _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr); | |
| 135 | 133 | |
| 136 | 134 | inline _LIBCPP_INLINE_VISIBILITY friend bool |
| 137 | 135 | operator==(const recursive_directory_iterator&, |
| ... | ... | @@ -164,22 +162,22 @@ end(recursive_directory_iterator) noexcept { |
| 164 | 162 | return recursive_directory_iterator(); |
| 165 | 163 | } |
| 166 | 164 | |
| 167 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 165 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 168 | 166 | |
| 169 | 167 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 170 | 168 | |
| 171 | #if _LIBCPP_STD_VER > 17 | |
| 169 | #if _LIBCPP_STD_VER >= 20 | |
| 172 | 170 | |
| 173 | 171 | template <> |
| 174 | _LIBCPP_AVAILABILITY_FILESYSTEM | |
| 172 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 175 | 173 | inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; |
| 176 | 174 | |
| 177 | 175 | template <> |
| 178 | _LIBCPP_AVAILABILITY_FILESYSTEM | |
| 176 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY | |
| 179 | 177 | inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; |
| 180 | 178 | |
| 181 | #endif // _LIBCPP_STD_VER > 17 | |
| 179 | #endif // _LIBCPP_STD_VER >= 20 | |
| 182 | 180 | |
| 183 | #endif // _LIBCPP_CXX03_LANG | |
| 181 | #endif // !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 184 | 182 | |
| 185 | 183 | #endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H |
lib/libcxx/include/__filesystem/space_info.h+2-6| ... | ... | @@ -22,20 +22,16 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 24 | 24 | |
| 25 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 26 | ||
| 27 | struct _LIBCPP_TYPE_VIS space_info { | |
| 25 | struct _LIBCPP_EXPORTED_FROM_ABI space_info { | |
| 28 | 26 | uintmax_t capacity; |
| 29 | 27 | uintmax_t free; |
| 30 | 28 | uintmax_t available; |
| 31 | 29 | |
| 32 | # if _LIBCPP_STD_VER > 17 | |
| 30 | # if _LIBCPP_STD_VER >= 20 | |
| 33 | 31 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(const space_info&, const space_info&) = default; |
| 34 | 32 | # endif |
| 35 | 33 | }; |
| 36 | 34 | |
| 37 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 38 | ||
| 39 | 35 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 40 | 36 | |
| 41 | 37 | #endif // _LIBCPP_CXX03_LANG |
lib/libcxx/include/__filesystem/u8path.h+2-3| ... | ... | @@ -15,7 +15,6 @@ |
| 15 | 15 | #include <__config> |
| 16 | 16 | #include <__filesystem/path.h> |
| 17 | 17 | #include <string> |
| 18 | #include <type_traits> | |
| 19 | 18 | |
| 20 | 19 | // Only required on Windows for __widen_from_utf8, and included conservatively |
| 21 | 20 | // because it requires support for localization. |
| ... | ... | @@ -31,7 +30,7 @@ |
| 31 | 30 | |
| 32 | 31 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 33 | 32 | |
| 34 | _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH | |
| 33 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH | |
| 35 | 34 | |
| 36 | 35 | template <class _InputIt> |
| 37 | 36 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T |
| ... | ... | @@ -99,7 +98,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T |
| 99 | 98 | #endif |
| 100 | 99 | } |
| 101 | 100 | |
| 102 | _LIBCPP_AVAILABILITY_FILESYSTEM_POP | |
| 101 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP | |
| 103 | 102 | |
| 104 | 103 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
| 105 | 104 |
lib/libcxx/include/__format/buffer.h+101-23| ... | ... | @@ -27,11 +27,18 @@ |
| 27 | 27 | #include <__iterator/incrementable_traits.h> |
| 28 | 28 | #include <__iterator/iterator_traits.h> |
| 29 | 29 | #include <__iterator/wrap_iter.h> |
| 30 | #include <__memory/addressof.h> | |
| 31 | #include <__memory/allocate_at_least.h> | |
| 32 | #include <__memory/allocator_traits.h> | |
| 33 | #include <__memory/construct_at.h> | |
| 34 | #include <__memory/ranges_construct_at.h> | |
| 35 | #include <__memory/uninitialized_algorithms.h> | |
| 36 | #include <__type_traits/add_pointer.h> | |
| 37 | #include <__type_traits/conditional.h> | |
| 38 | #include <__utility/exception_guard.h> | |
| 30 | 39 | #include <__utility/move.h> |
| 31 | 40 | #include <cstddef> |
| 32 | 41 | #include <string_view> |
| 33 | #include <type_traits> | |
| 34 | #include <vector> | |
| 35 | 42 | |
| 36 | 43 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 37 | 44 | # pragma GCC system_header |
| ... | ... | @@ -42,7 +49,7 @@ _LIBCPP_PUSH_MACROS |
| 42 | 49 | |
| 43 | 50 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 44 | 51 | |
| 45 | #if _LIBCPP_STD_VER > 17 | |
| 52 | #if _LIBCPP_STD_VER >= 20 | |
| 46 | 53 | |
| 47 | 54 | namespace __format { |
| 48 | 55 | |
| ... | ... | @@ -100,7 +107,7 @@ public: |
| 100 | 107 | size_t __n = __str.size(); |
| 101 | 108 | |
| 102 | 109 | __flush_on_overflow(__n); |
| 103 | if (__n <= __capacity_) { | |
| 110 | if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). | |
| 104 | 111 | _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_])); |
| 105 | 112 | __size_ += __n; |
| 106 | 113 | return; |
| ... | ... | @@ -108,7 +115,7 @@ public: |
| 108 | 115 | |
| 109 | 116 | // The output doesn't fit in the internal buffer. |
| 110 | 117 | // Copy the data in "__capacity_" sized chunks. |
| 111 | _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 118 | _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 112 | 119 | const _InCharT* __first = __str.data(); |
| 113 | 120 | do { |
| 114 | 121 | size_t __chunk = _VSTD::min(__n, __capacity_); |
| ... | ... | @@ -125,11 +132,11 @@ public: |
| 125 | 132 | /// Like @ref __copy it may need to do type conversion. |
| 126 | 133 | template <__fmt_char_type _InCharT, class _UnaryOperation> |
| 127 | 134 | _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { |
| 128 | _LIBCPP_ASSERT(__first <= __last, "not a valid range"); | |
| 135 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range"); | |
| 129 | 136 | |
| 130 | 137 | size_t __n = static_cast<size_t>(__last - __first); |
| 131 | 138 | __flush_on_overflow(__n); |
| 132 | if (__n <= __capacity_) { | |
| 139 | if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). | |
| 133 | 140 | _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation)); |
| 134 | 141 | __size_ += __n; |
| 135 | 142 | return; |
| ... | ... | @@ -137,7 +144,7 @@ public: |
| 137 | 144 | |
| 138 | 145 | // The output doesn't fit in the internal buffer. |
| 139 | 146 | // Transform the data in "__capacity_" sized chunks. |
| 140 | _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 147 | _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 141 | 148 | do { |
| 142 | 149 | size_t __chunk = _VSTD::min(__n, __capacity_); |
| 143 | 150 | _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation); |
| ... | ... | @@ -151,7 +158,7 @@ public: |
| 151 | 158 | /// A \c fill_n wrapper. |
| 152 | 159 | _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { |
| 153 | 160 | __flush_on_overflow(__n); |
| 154 | if (__n <= __capacity_) { | |
| 161 | if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). | |
| 155 | 162 | _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value); |
| 156 | 163 | __size_ += __n; |
| 157 | 164 | return; |
| ... | ... | @@ -159,7 +166,7 @@ public: |
| 159 | 166 | |
| 160 | 167 | // The output doesn't fit in the internal buffer. |
| 161 | 168 | // Fill the buffer in "__capacity_" sized chunks. |
| 162 | _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 169 | _LIBCPP_ASSERT_UNCATEGORIZED(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); | |
| 163 | 170 | do { |
| 164 | 171 | size_t __chunk = _VSTD::min(__n, __capacity_); |
| 165 | 172 | _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value); |
| ... | ... | @@ -246,9 +253,9 @@ class _LIBCPP_TEMPLATE_VIS __direct_storage {}; |
| 246 | 253 | template <class _OutIt, class _CharT> |
| 247 | 254 | concept __enable_direct_output = __fmt_char_type<_CharT> && |
| 248 | 255 | (same_as<_OutIt, _CharT*> |
| 249 | #ifndef _LIBCPP_ENABLE_DEBUG_MODE | |
| 256 | // TODO(hardening): the following check might not apply to hardened iterators and might need to be wrapped in an | |
| 257 | // `#ifdef`. | |
| 250 | 258 | || same_as<_OutIt, __wrap_iter<_CharT*>> |
| 251 | #endif | |
| 252 | 259 | ); |
| 253 | 260 | |
| 254 | 261 | /// Write policy for directly writing to the underlying output. |
| ... | ... | @@ -510,13 +517,19 @@ public: |
| 510 | 517 | // context and the format arguments need to be retargeted to the new context. |
| 511 | 518 | // This retargeting is done by a basic_format_context specialized for the |
| 512 | 519 | // __iterator of this container. |
| 520 | // | |
| 521 | // This class uses its own buffer management, since using vector | |
| 522 | // would lead to a circular include with formatter for vector<bool>. | |
| 513 | 523 | template <__fmt_char_type _CharT> |
| 514 | 524 | class _LIBCPP_TEMPLATE_VIS __retarget_buffer { |
| 525 | using _Alloc = allocator<_CharT>; | |
| 526 | ||
| 515 | 527 | public: |
| 516 | 528 | using value_type = _CharT; |
| 517 | 529 | |
| 518 | 530 | struct __iterator { |
| 519 | 531 | using difference_type = ptrdiff_t; |
| 532 | using value_type = _CharT; | |
| 520 | 533 | |
| 521 | 534 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer) |
| 522 | 535 | : __buffer_(std::addressof(__buffer)) {} |
| ... | ... | @@ -535,36 +548,101 @@ public: |
| 535 | 548 | __retarget_buffer* __buffer_; |
| 536 | 549 | }; |
| 537 | 550 | |
| 538 | _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { __buffer_.reserve(__size_hint); } | |
| 551 | __retarget_buffer(const __retarget_buffer&) = delete; | |
| 552 | __retarget_buffer& operator=(const __retarget_buffer&) = delete; | |
| 553 | ||
| 554 | _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { | |
| 555 | // When the initial size is very small a lot of resizes happen | |
| 556 | // when elements added. So use a hard-coded minimum size. | |
| 557 | // | |
| 558 | // Note a size < 2 will not work | |
| 559 | // - 0 there is no buffer, while push_back requires 1 empty element. | |
| 560 | // - 1 multiplied by the grow factor is 1 and thus the buffer never | |
| 561 | // grows. | |
| 562 | auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT))); | |
| 563 | __ptr_ = __result.ptr; | |
| 564 | __capacity_ = __result.count; | |
| 565 | } | |
| 566 | ||
| 567 | _LIBCPP_HIDE_FROM_ABI ~__retarget_buffer() { | |
| 568 | ranges::destroy_n(__ptr_, __size_); | |
| 569 | allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_); | |
| 570 | } | |
| 539 | 571 | |
| 540 | 572 | _LIBCPP_HIDE_FROM_ABI __iterator __make_output_iterator() { return __iterator{*this}; } |
| 541 | 573 | |
| 542 | _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { __buffer_.push_back(__c); } | |
| 574 | _LIBCPP_HIDE_FROM_ABI void push_back(_CharT __c) { | |
| 575 | std::construct_at(__ptr_ + __size_, __c); | |
| 576 | ++__size_; | |
| 577 | ||
| 578 | if (__size_ == __capacity_) | |
| 579 | __grow_buffer(); | |
| 580 | } | |
| 543 | 581 | |
| 544 | 582 | template <__fmt_char_type _InCharT> |
| 545 | 583 | _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { |
| 546 | __buffer_.insert(__buffer_.end(), __str.begin(), __str.end()); | |
| 584 | size_t __n = __str.size(); | |
| 585 | if (__size_ + __n >= __capacity_) | |
| 586 | // Push_back requires the buffer to have room for at least one character. | |
| 587 | __grow_buffer(__size_ + __n + 1); | |
| 588 | ||
| 589 | std::uninitialized_copy_n(__str.data(), __n, __ptr_ + __size_); | |
| 590 | __size_ += __n; | |
| 547 | 591 | } |
| 548 | 592 | |
| 549 | 593 | template <__fmt_char_type _InCharT, class _UnaryOperation> |
| 550 | 594 | _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { |
| 551 | _LIBCPP_ASSERT(__first <= __last, "not a valid range"); | |
| 552 | std::transform(__first, __last, std::back_inserter(__buffer_), std::move(__operation)); | |
| 595 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "not a valid range"); | |
| 596 | ||
| 597 | size_t __n = static_cast<size_t>(__last - __first); | |
| 598 | if (__size_ + __n >= __capacity_) | |
| 599 | // Push_back requires the buffer to have room for at least one character. | |
| 600 | __grow_buffer(__size_ + __n + 1); | |
| 601 | ||
| 602 | std::uninitialized_default_construct_n(__ptr_ + __size_, __n); | |
| 603 | std::transform(__first, __last, __ptr_ + __size_, std::move(__operation)); | |
| 604 | __size_ += __n; | |
| 553 | 605 | } |
| 554 | 606 | |
| 555 | _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __buffer_.insert(__buffer_.end(), __n, __value); } | |
| 607 | _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { | |
| 608 | if (__size_ + __n >= __capacity_) | |
| 609 | // Push_back requires the buffer to have room for at least one character. | |
| 610 | __grow_buffer(__size_ + __n + 1); | |
| 611 | ||
| 612 | std::uninitialized_fill_n(__ptr_ + __size_, __n, __value); | |
| 613 | __size_ += __n; | |
| 614 | } | |
| 556 | 615 | |
| 557 | _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__buffer_.data(), __buffer_.size()}; } | |
| 616 | _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT> __view() { return {__ptr_, __size_}; } | |
| 558 | 617 | |
| 559 | 618 | private: |
| 560 | // Use vector instead of string to avoid adding zeros after every append | |
| 561 | // operation. The buffer is exposed as a string_view and not as a c-string. | |
| 562 | vector<_CharT> __buffer_; | |
| 619 | _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); } | |
| 620 | ||
| 621 | _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) { | |
| 622 | _LIBCPP_ASSERT_UNCATEGORIZED(__capacity > __capacity_, "the buffer must grow"); | |
| 623 | auto __result = std::__allocate_at_least(__alloc_, __capacity); | |
| 624 | auto __guard = std::__make_exception_guard([&] { | |
| 625 | allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count); | |
| 626 | }); | |
| 627 | // This shouldn't throw, but just to be safe. Note that at -O1 this | |
| 628 | // guard is optimized away so there is no runtime overhead. | |
| 629 | std::uninitialized_move_n(__ptr_, __size_, __result.ptr); | |
| 630 | __guard.__complete(); | |
| 631 | ranges::destroy_n(__ptr_, __size_); | |
| 632 | allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __capacity_); | |
| 633 | ||
| 634 | __ptr_ = __result.ptr; | |
| 635 | __capacity_ = __result.count; | |
| 636 | } | |
| 637 | _LIBCPP_NO_UNIQUE_ADDRESS _Alloc __alloc_; | |
| 638 | _CharT* __ptr_; | |
| 639 | size_t __capacity_; | |
| 640 | size_t __size_{0}; | |
| 563 | 641 | }; |
| 564 | 642 | |
| 565 | 643 | } // namespace __format |
| 566 | 644 | |
| 567 | #endif //_LIBCPP_STD_VER > 17 | |
| 645 | #endif //_LIBCPP_STD_VER >= 20 | |
| 568 | 646 | |
| 569 | 647 | _LIBCPP_END_NAMESPACE_STD |
| 570 | 648 |
lib/libcxx/include/__format/concepts.h+18-14| ... | ... | @@ -16,9 +16,9 @@ |
| 16 | 16 | #include <__format/format_fwd.h> |
| 17 | 17 | #include <__format/format_parse_context.h> |
| 18 | 18 | #include <__type_traits/is_specialization.h> |
| 19 | #include <__type_traits/remove_const.h> | |
| 19 | 20 | #include <__utility/pair.h> |
| 20 | 21 | #include <tuple> |
| 21 | #include <type_traits> | |
| 22 | 22 | |
| 23 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 24 | # pragma GCC system_header |
| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | /// The character type specializations of \ref formatter. |
| 32 | 32 | template <class _CharT> |
| ... | ... | @@ -44,19 +44,23 @@ concept __fmt_char_type = |
| 44 | 44 | template <class _CharT> |
| 45 | 45 | using __fmt_iter_for = _CharT*; |
| 46 | 46 | |
| 47 | template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>> | |
| 48 | concept __formattable_with = | |
| 49 | semiregular<_Formatter> && | |
| 50 | requires(_Formatter& __f, | |
| 51 | const _Formatter& __cf, | |
| 52 | _Tp&& __t, | |
| 53 | _Context __fc, | |
| 54 | basic_format_parse_context<typename _Context::char_type> __pc) { | |
| 55 | { __f.parse(__pc) } -> same_as<typename decltype(__pc)::iterator>; | |
| 56 | { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; | |
| 57 | }; | |
| 58 | ||
| 47 | 59 | template <class _Tp, class _CharT> |
| 48 | 60 | concept __formattable = |
| 49 | (semiregular<formatter<remove_cvref_t<_Tp>, _CharT>>) && | |
| 50 | requires(formatter<remove_cvref_t<_Tp>, _CharT> __f, | |
| 51 | const formatter<remove_cvref_t<_Tp>, _CharT> __cf, | |
| 52 | _Tp __t, | |
| 53 | basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc, | |
| 54 | basic_format_parse_context<_CharT> __pc) { | |
| 55 | { __f.parse(__pc) } -> same_as<typename basic_format_parse_context<_CharT>::iterator>; | |
| 56 | { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>; | |
| 57 | }; | |
| 61 | __formattable_with<remove_reference_t<_Tp>, basic_format_context<__fmt_iter_for<_CharT>, _CharT>>; | |
| 58 | 62 | |
| 59 | # if _LIBCPP_STD_VER > 20 | |
| 63 | # if _LIBCPP_STD_VER >= 23 | |
| 60 | 64 | template <class _Tp, class _CharT> |
| 61 | 65 | concept formattable = __formattable<_Tp, _CharT>; |
| 62 | 66 | |
| ... | ... | @@ -69,8 +73,8 @@ template <class _Tp> |
| 69 | 73 | concept __fmt_pair_like = |
| 70 | 74 | __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); |
| 71 | 75 | |
| 72 | # endif //_LIBCPP_STD_VER > 20 | |
| 73 | #endif //_LIBCPP_STD_VER > 17 | |
| 76 | # endif //_LIBCPP_STD_VER >= 23 | |
| 77 | #endif //_LIBCPP_STD_VER >= 20 | |
| 74 | 78 | |
| 75 | 79 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 80 |
lib/libcxx/include/__format/container_adaptor.h+12-9| ... | ... | @@ -14,17 +14,19 @@ |
| 14 | 14 | # pragma GCC system_header |
| 15 | 15 | #endif |
| 16 | 16 | |
| 17 | #include <__availability> | |
| 18 | 17 | #include <__config> |
| 19 | 18 | #include <__format/concepts.h> |
| 20 | 19 | #include <__format/formatter.h> |
| 21 | 20 | #include <__format/range_default_formatter.h> |
| 21 | #include <__ranges/ref_view.h> | |
| 22 | #include <__type_traits/is_const.h> | |
| 23 | #include <__type_traits/maybe_const.h> | |
| 22 | 24 | #include <queue> |
| 23 | 25 | #include <stack> |
| 24 | 26 | |
| 25 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 28 | |
| 27 | #if _LIBCPP_STD_VER > 20 | |
| 29 | #if _LIBCPP_STD_VER >= 23 | |
| 28 | 30 | |
| 29 | 31 | // [container.adaptors.format] only specifies the library should provide the |
| 30 | 32 | // formatter specializations, not which header should provide them. |
| ... | ... | @@ -33,10 +35,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 35 | // adaptor headers. To use the format functions users already include <format>. |
| 34 | 36 | |
| 35 | 37 | template <class _Adaptor, class _CharT> |
| 36 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_container_adaptor { | |
| 38 | struct _LIBCPP_TEMPLATE_VIS __formatter_container_adaptor { | |
| 37 | 39 | private: |
| 38 | using __maybe_const_adaptor = __fmt_maybe_const<_Adaptor, _CharT>; | |
| 39 | formatter<typename _Adaptor::container_type, _CharT> __underlying_; | |
| 40 | using __maybe_const_container = __fmt_maybe_const<typename _Adaptor::container_type, _CharT>; | |
| 41 | using __maybe_const_adaptor = __maybe_const<is_const_v<__maybe_const_container>, _Adaptor>; | |
| 42 | formatter<ranges::ref_view<__maybe_const_container>, _CharT> __underlying_; | |
| 40 | 43 | |
| 41 | 44 | public: |
| 42 | 45 | template <class _ParseContext> |
| ... | ... | @@ -52,18 +55,18 @@ public: |
| 52 | 55 | }; |
| 53 | 56 | |
| 54 | 57 | template <class _CharT, class _Tp, formattable<_CharT> _Container> |
| 55 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<queue<_Tp, _Container>, _CharT> | |
| 58 | struct _LIBCPP_TEMPLATE_VIS formatter<queue<_Tp, _Container>, _CharT> | |
| 56 | 59 | : public __formatter_container_adaptor<queue<_Tp, _Container>, _CharT> {}; |
| 57 | 60 | |
| 58 | 61 | template <class _CharT, class _Tp, class _Container, class _Compare> |
| 59 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<priority_queue<_Tp, _Container, _Compare>, _CharT> | |
| 62 | struct _LIBCPP_TEMPLATE_VIS formatter<priority_queue<_Tp, _Container, _Compare>, _CharT> | |
| 60 | 63 | : public __formatter_container_adaptor<priority_queue<_Tp, _Container, _Compare>, _CharT> {}; |
| 61 | 64 | |
| 62 | 65 | template <class _CharT, class _Tp, formattable<_CharT> _Container> |
| 63 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<stack<_Tp, _Container>, _CharT> | |
| 66 | struct _LIBCPP_TEMPLATE_VIS formatter<stack<_Tp, _Container>, _CharT> | |
| 64 | 67 | : public __formatter_container_adaptor<stack<_Tp, _Container>, _CharT> {}; |
| 65 | 68 | |
| 66 | #endif //_LIBCPP_STD_VER > 20 | |
| 69 | #endif //_LIBCPP_STD_VER >= 23 | |
| 67 | 70 | |
| 68 | 71 | _LIBCPP_END_NAMESPACE_STD |
| 69 | 72 |
lib/libcxx/include/__format/enable_insertable.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | namespace __format { |
| 24 | 24 | |
| ... | ... | @@ -28,7 +28,7 @@ inline constexpr bool __enable_insertable = false; |
| 28 | 28 | |
| 29 | 29 | } // namespace __format |
| 30 | 30 | |
| 31 | #endif //_LIBCPP_STD_VER > 17 | |
| 31 | #endif //_LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 34 |
lib/libcxx/include/__format/escaped_output_table.h+2-2| ... | ... | @@ -72,7 +72,7 @@ |
| 72 | 72 | |
| 73 | 73 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 74 | 74 | |
| 75 | #if _LIBCPP_STD_VER > 20 | |
| 75 | #if _LIBCPP_STD_VER >= 23 | |
| 76 | 76 | |
| 77 | 77 | namespace __escaped_output_table { |
| 78 | 78 | |
| ... | ... | @@ -1031,7 +1031,7 @@ inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0; |
| 1031 | 1031 | |
| 1032 | 1032 | } // namespace __escaped_output_table |
| 1033 | 1033 | |
| 1034 | #endif //_LIBCPP_STD_VER > 20 | |
| 1034 | #endif //_LIBCPP_STD_VER >= 23 | |
| 1035 | 1035 | |
| 1036 | 1036 | _LIBCPP_END_NAMESPACE_STD |
| 1037 | 1037 |
lib/libcxx/include/__format/extended_grapheme_cluster_table.h+2-2| ... | ... | @@ -73,7 +73,7 @@ |
| 73 | 73 | |
| 74 | 74 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 75 | 75 | |
| 76 | #if _LIBCPP_STD_VER > 17 | |
| 76 | #if _LIBCPP_STD_VER >= 20 | |
| 77 | 77 | |
| 78 | 78 | namespace __extended_grapheme_custer_property_boundary { |
| 79 | 79 | |
| ... | ... | @@ -1654,7 +1654,7 @@ inline constexpr uint32_t __entries[1496] = { |
| 1654 | 1654 | |
| 1655 | 1655 | } // namespace __extended_grapheme_custer_property_boundary |
| 1656 | 1656 | |
| 1657 | #endif //_LIBCPP_STD_VER > 17 | |
| 1657 | #endif //_LIBCPP_STD_VER >= 20 | |
| 1658 | 1658 | |
| 1659 | 1659 | _LIBCPP_END_NAMESPACE_STD |
| 1660 | 1660 |
lib/libcxx/include/__format/format_arg.h+16-20| ... | ... | @@ -13,15 +13,17 @@ |
| 13 | 13 | #include <__assert> |
| 14 | 14 | #include <__concepts/arithmetic.h> |
| 15 | 15 | #include <__config> |
| 16 | #include <__format/format_error.h> | |
| 16 | #include <__format/concepts.h> | |
| 17 | 17 | #include <__format/format_fwd.h> |
| 18 | 18 | #include <__format/format_parse_context.h> |
| 19 | 19 | #include <__functional/invoke.h> |
| 20 | 20 | #include <__memory/addressof.h> |
| 21 | #include <__type_traits/conditional.h> | |
| 21 | 22 | #include <__utility/forward.h> |
| 23 | #include <__utility/move.h> | |
| 22 | 24 | #include <__utility/unreachable.h> |
| 23 | 25 | #include <__variant/monostate.h> |
| 24 | #include <string> | |
| 26 | #include <cstdint> | |
| 25 | 27 | #include <string_view> |
| 26 | 28 | |
| 27 | 29 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -30,7 +32,7 @@ |
| 30 | 32 | |
| 31 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 34 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 36 | |
| 35 | 37 | namespace __format { |
| 36 | 38 | /// The type stored in @ref basic_format_arg. |
| ... | ... | @@ -81,7 +83,7 @@ constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= _ |
| 81 | 83 | |
| 82 | 84 | _LIBCPP_HIDE_FROM_ABI |
| 83 | 85 | constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { |
| 84 | _LIBCPP_ASSERT(__id <= __packed_types_max, ""); | |
| 86 | _LIBCPP_ASSERT_UNCATEGORIZED(__id <= __packed_types_max, ""); | |
| 85 | 87 | |
| 86 | 88 | if (__id > 0) |
| 87 | 89 | __types >>= __id * __packed_arg_t_bits; |
| ... | ... | @@ -94,7 +96,7 @@ constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { |
| 94 | 96 | // This function is not user obervable, so it can directly use the non-standard |
| 95 | 97 | // types of the "variant". See __arg_t for more details. |
| 96 | 98 | template <class _Visitor, class _Context> |
| 97 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) | |
| 99 | _LIBCPP_HIDE_FROM_ABI decltype(auto) | |
| 98 | 100 | __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { |
| 99 | 101 | switch (__arg.__type_) { |
| 100 | 102 | case __format::__arg_t::__none: |
| ... | ... | @@ -155,18 +157,14 @@ public: |
| 155 | 157 | /// Contains the implementation for basic_format_arg::handle. |
| 156 | 158 | struct __handle { |
| 157 | 159 | template <class _Tp> |
| 158 | _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept | |
| 160 | _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp& __v) noexcept | |
| 159 | 161 | : __ptr_(_VSTD::addressof(__v)), |
| 160 | 162 | __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) { |
| 161 | using _Dp = remove_cvref_t<_Tp>; | |
| 162 | using _Formatter = typename _Context::template formatter_type<_Dp>; | |
| 163 | constexpr bool __const_formattable = | |
| 164 | requires { _Formatter().format(std::declval<const _Dp&>(), std::declval<_Context&>()); }; | |
| 165 | using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>; | |
| 163 | using _Dp = remove_const_t<_Tp>; | |
| 164 | using _Qp = conditional_t<__formattable_with<const _Dp, _Context>, const _Dp, _Dp>; | |
| 165 | static_assert(__formattable_with<_Qp, _Context>, "Mandated by [format.arg]/10"); | |
| 166 | 166 | |
| 167 | static_assert(__const_formattable || !is_const_v<remove_reference_t<_Tp>>, "Mandated by [format.arg]/18"); | |
| 168 | ||
| 169 | _Formatter __f; | |
| 167 | typename _Context::template formatter_type<_Dp> __f; | |
| 170 | 168 | __parse_ctx.advance_to(__f.parse(__parse_ctx)); |
| 171 | 169 | __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast<const _Dp*>(__ptr)), __ctx)); |
| 172 | 170 | }) {} |
| ... | ... | @@ -218,13 +216,11 @@ public: |
| 218 | 216 | _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept |
| 219 | 217 | : __string_view_(__value) {} |
| 220 | 218 | _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {} |
| 221 | _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept | |
| 222 | // TODO FMT Investigate why it doesn't work without the forward. | |
| 223 | : __handle_(std::forward<__handle>(__value)) {} | |
| 219 | _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle&& __value) noexcept : __handle_(std::move(__value)) {} | |
| 224 | 220 | }; |
| 225 | 221 | |
| 226 | 222 | template <class _Context> |
| 227 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg { | |
| 223 | class _LIBCPP_TEMPLATE_VIS basic_format_arg { | |
| 228 | 224 | public: |
| 229 | 225 | class _LIBCPP_TEMPLATE_VIS handle; |
| 230 | 226 | |
| ... | ... | @@ -276,7 +272,7 @@ private: |
| 276 | 272 | // This function is user facing, so it must wrap the non-standard types of |
| 277 | 273 | // the "variant" in a handle to stay conforming. See __arg_t for more details. |
| 278 | 274 | template <class _Visitor, class _Context> |
| 279 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT decltype(auto) | |
| 275 | _LIBCPP_HIDE_FROM_ABI decltype(auto) | |
| 280 | 276 | visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { |
| 281 | 277 | switch (__arg.__type_) { |
| 282 | 278 | # ifndef _LIBCPP_HAS_NO_INT128 |
| ... | ... | @@ -295,7 +291,7 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { |
| 295 | 291 | } |
| 296 | 292 | } |
| 297 | 293 | |
| 298 | #endif //_LIBCPP_STD_VER > 17 | |
| 294 | #endif //_LIBCPP_STD_VER >= 20 | |
| 299 | 295 | |
| 300 | 296 | _LIBCPP_END_NAMESPACE_STD |
| 301 | 297 |
lib/libcxx/include/__format/format_arg_store.h+25-16| ... | ... | @@ -19,15 +19,15 @@ |
| 19 | 19 | #include <__config> |
| 20 | 20 | #include <__format/concepts.h> |
| 21 | 21 | #include <__format/format_arg.h> |
| 22 | #include <__utility/forward.h> | |
| 23 | #include <cstring> | |
| 22 | #include <__type_traits/conditional.h> | |
| 23 | #include <__type_traits/extent.h> | |
| 24 | #include <__type_traits/remove_const.h> | |
| 24 | 25 | #include <string> |
| 25 | 26 | #include <string_view> |
| 26 | #include <type_traits> | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | namespace __format { |
| 33 | 33 | |
| ... | ... | @@ -142,21 +142,31 @@ consteval __arg_t __determine_arg_t() { |
| 142 | 142 | // |
| 143 | 143 | // Note this version can't be constrained avoiding ambiguous overloads. |
| 144 | 144 | // That means it can be instantiated by disabled formatters. To solve this, a |
| 145 | // constrained version for not formattable formatters is added. That overload | |
| 146 | // is marked as deleted to fail creating a storage type for disabled formatters. | |
| 145 | // constrained version for not formattable formatters is added. | |
| 147 | 146 | template <class _Context, class _Tp> |
| 148 | 147 | consteval __arg_t __determine_arg_t() { |
| 149 | 148 | return __arg_t::__handle; |
| 150 | 149 | } |
| 151 | 150 | |
| 151 | // The overload for not formattable types allows triggering the static | |
| 152 | // assertion below. | |
| 152 | 153 | template <class _Context, class _Tp> |
| 153 | 154 | requires(!__formattable<_Tp, typename _Context::char_type>) |
| 154 | consteval __arg_t __determine_arg_t() = delete; | |
| 155 | consteval __arg_t __determine_arg_t() { | |
| 156 | return __arg_t::__none; | |
| 157 | } | |
| 155 | 158 | |
| 159 | // Pseudo constuctor for basic_format_arg | |
| 160 | // | |
| 161 | // Modeled after template<class T> explicit basic_format_arg(T& v) noexcept; | |
| 162 | // [format.arg]/4-6 | |
| 156 | 163 | template <class _Context, class _Tp> |
| 157 | _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept { | |
| 158 | constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>(); | |
| 159 | static_assert(__arg != __arg_t::__none); | |
| 164 | _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __value) noexcept { | |
| 165 | using _Dp = remove_const_t<_Tp>; | |
| 166 | constexpr __arg_t __arg = __determine_arg_t<_Context, _Dp>(); | |
| 167 | static_assert(__arg != __arg_t::__none, "the supplied type is not formattable"); | |
| 168 | ||
| 169 | static_assert(__formattable_with<_Tp, _Context>); | |
| 160 | 170 | |
| 161 | 171 | // Not all types can be used to directly initialize the |
| 162 | 172 | // __basic_format_arg_value. First handle all types needing adjustment, the |
| ... | ... | @@ -175,9 +185,9 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val |
| 175 | 185 | return basic_format_arg<_Context>{__arg, static_cast<unsigned long long>(__value)}; |
| 176 | 186 | else if constexpr (__arg == __arg_t::__string_view) |
| 177 | 187 | // Using std::size on a character array will add the NUL-terminator to the size. |
| 178 | if constexpr (is_array_v<remove_cvref_t<_Tp>>) | |
| 188 | if constexpr (is_array_v<_Dp>) | |
| 179 | 189 | return basic_format_arg<_Context>{ |
| 180 | __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<remove_cvref_t<_Tp>> - 1}}; | |
| 190 | __arg, basic_string_view<typename _Context::char_type>{__value, extent_v<_Dp> - 1}}; | |
| 181 | 191 | else |
| 182 | 192 | // When the _Traits or _Allocator are different an implicit conversion will |
| 183 | 193 | // fail. |
| ... | ... | @@ -186,8 +196,7 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val |
| 186 | 196 | else if constexpr (__arg == __arg_t::__ptr) |
| 187 | 197 | return basic_format_arg<_Context>{__arg, static_cast<const void*>(__value)}; |
| 188 | 198 | else if constexpr (__arg == __arg_t::__handle) |
| 189 | return basic_format_arg<_Context>{ | |
| 190 | __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}}; | |
| 199 | return basic_format_arg<_Context>{__arg, typename __basic_format_arg_value<_Context>::__handle{__value}}; | |
| 191 | 200 | else |
| 192 | 201 | return basic_format_arg<_Context>{__arg, __value}; |
| 193 | 202 | } |
| ... | ... | @@ -218,7 +227,7 @@ _LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* |
| 218 | 227 | template <class _Context, size_t N> |
| 219 | 228 | struct __packed_format_arg_store { |
| 220 | 229 | __basic_format_arg_value<_Context> __values_[N]; |
| 221 | uint64_t __types_; | |
| 230 | uint64_t __types_ = 0; | |
| 222 | 231 | }; |
| 223 | 232 | |
| 224 | 233 | template <class _Context, size_t N> |
| ... | ... | @@ -247,7 +256,7 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store { |
| 247 | 256 | _Storage __storage; |
| 248 | 257 | }; |
| 249 | 258 | |
| 250 | #endif //_LIBCPP_STD_VER > 17 | |
| 259 | #endif //_LIBCPP_STD_VER >= 20 | |
| 251 | 260 | |
| 252 | 261 | _LIBCPP_END_NAMESPACE_STD |
| 253 | 262 |
lib/libcxx/include/__format/format_args.h+7-5| ... | ... | @@ -24,12 +24,12 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | template <class _Context> |
| 30 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_args { | |
| 30 | class _LIBCPP_TEMPLATE_VIS basic_format_args { | |
| 31 | 31 | public: |
| 32 | _LIBCPP_HIDE_FROM_ABI basic_format_args() noexcept = default; | |
| 32 | basic_format_args() noexcept = default; | |
| 33 | 33 | |
| 34 | 34 | template <class... _Args> |
| 35 | 35 | _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept |
| ... | ... | @@ -71,9 +71,11 @@ private: |
| 71 | 71 | const basic_format_arg<_Context>* __args_; |
| 72 | 72 | }; |
| 73 | 73 | }; |
| 74 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_args); | |
| 75 | 74 | |
| 76 | #endif //_LIBCPP_STD_VER > 17 | |
| 75 | template <class _Context, class... _Args> | |
| 76 | basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_Context>; | |
| 77 | ||
| 78 | #endif //_LIBCPP_STD_VER >= 20 | |
| 77 | 79 | |
| 78 | 80 | _LIBCPP_END_NAMESPACE_STD |
| 79 | 81 |
lib/libcxx/include/__format/format_context.h+10-11| ... | ... | @@ -37,11 +37,11 @@ |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 39 | |
| 40 | #if _LIBCPP_STD_VER > 17 | |
| 40 | #if _LIBCPP_STD_VER >= 20 | |
| 41 | 41 | |
| 42 | 42 | template <class _OutIt, class _CharT> |
| 43 | 43 | requires output_iterator<_OutIt, const _CharT&> |
| 44 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; | |
| 44 | class _LIBCPP_TEMPLATE_VIS basic_format_context; | |
| 45 | 45 | |
| 46 | 46 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION |
| 47 | 47 | /** |
| ... | ... | @@ -80,7 +80,6 @@ requires output_iterator<_OutIt, const _CharT&> |
| 80 | 80 | class |
| 81 | 81 | // clang-format off |
| 82 | 82 | _LIBCPP_TEMPLATE_VIS |
| 83 | _LIBCPP_AVAILABILITY_FORMAT | |
| 84 | 83 | _LIBCPP_PREFERRED_NAME(format_context) |
| 85 | 84 | _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) |
| 86 | 85 | // clang-format on |
| ... | ... | @@ -121,9 +120,9 @@ private: |
| 121 | 120 | // TODO FMT Validate whether lazy creation is the best solution. |
| 122 | 121 | optional<_VSTD::locale> __loc_; |
| 123 | 122 | |
| 124 | template <class __OutIt, class __CharT> | |
| 125 | friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> | |
| 126 | __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>, | |
| 123 | template <class _OtherOutIt, class _OtherCharT> | |
| 124 | friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> | |
| 125 | __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>, | |
| 127 | 126 | optional<_VSTD::locale>&&); |
| 128 | 127 | |
| 129 | 128 | // Note: the Standard doesn't specify the required constructors. |
| ... | ... | @@ -134,9 +133,9 @@ private: |
| 134 | 133 | : __out_it_(_VSTD::move(__out_it)), __args_(__args), |
| 135 | 134 | __loc_(_VSTD::move(__loc)) {} |
| 136 | 135 | #else |
| 137 | template <class __OutIt, class __CharT> | |
| 138 | friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> | |
| 139 | __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>); | |
| 136 | template <class _OtherOutIt, class _OtherCharT> | |
| 137 | friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> | |
| 138 | __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>); | |
| 140 | 139 | |
| 141 | 140 | _LIBCPP_HIDE_FROM_ABI |
| 142 | 141 | explicit basic_format_context(_OutIt __out_it, |
| ... | ... | @@ -162,7 +161,7 @@ private: |
| 162 | 161 | // Here the width of an element in input is determined dynamically. |
| 163 | 162 | // Note when the top-level element has no width the retargeting is not needed. |
| 164 | 163 | template <class _CharT> |
| 165 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT | |
| 164 | class _LIBCPP_TEMPLATE_VIS | |
| 166 | 165 | basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> { |
| 167 | 166 | public: |
| 168 | 167 | using iterator = typename __format::__retarget_buffer<_CharT>::__iterator; |
| ... | ... | @@ -216,7 +215,7 @@ private: |
| 216 | 215 | }; |
| 217 | 216 | |
| 218 | 217 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context); |
| 219 | #endif //_LIBCPP_STD_VER > 17 | |
| 218 | #endif //_LIBCPP_STD_VER >= 20 | |
| 220 | 219 | |
| 221 | 220 | _LIBCPP_END_NAMESPACE_STD |
| 222 | 221 |
lib/libcxx/include/__format/format_error.h+11-15| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___FORMAT_FORMAT_ERROR_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <cstdlib> | |
| 14 | #include <__verbose_abort> | |
| 15 | 15 | #include <stdexcept> |
| 16 | 16 | |
| 17 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -20,35 +20,31 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { | |
| 25 | _LIBCPP_DIAGNOSTIC_PUSH | |
| 26 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") | |
| 27 | class _LIBCPP_EXPORTED_FROM_ABI format_error : public runtime_error { | |
| 26 | 28 | public: |
| 27 | 29 | _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) |
| 28 | 30 | : runtime_error(__s) {} |
| 29 | 31 | _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) |
| 30 | 32 | : runtime_error(__s) {} |
| 31 | // TODO FMT Remove when format is no longer experimental. | |
| 32 | // Avoids linker errors when building the Clang-cl Windows DLL which doesn't | |
| 33 | // support the experimental library. | |
| 34 | # ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR | |
| 35 | ~format_error() noexcept override; | |
| 36 | # else | |
| 37 | ~format_error() noexcept override {} | |
| 38 | # endif | |
| 33 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL | |
| 34 | ~format_error() noexcept override = default; | |
| 39 | 35 | }; |
| 36 | _LIBCPP_DIAGNOSTIC_POP | |
| 40 | 37 | |
| 41 | 38 | _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void |
| 42 | 39 | __throw_format_error(const char* __s) { |
| 43 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 40 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 44 | 41 | throw format_error(__s); |
| 45 | 42 | #else |
| 46 | (void)__s; | |
| 47 | _VSTD::abort(); | |
| 43 | _LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s); | |
| 48 | 44 | #endif |
| 49 | 45 | } |
| 50 | 46 | |
| 51 | #endif //_LIBCPP_STD_VER > 17 | |
| 47 | #endif //_LIBCPP_STD_VER >= 20 | |
| 52 | 48 | |
| 53 | 49 | _LIBCPP_END_NAMESPACE_STD |
| 54 | 50 |
lib/libcxx/include/__format/format_functions.h+113-117| ... | ... | @@ -10,16 +10,10 @@ |
| 10 | 10 | #ifndef _LIBCPP___FORMAT_FORMAT_FUNCTIONS |
| 11 | 11 | #define _LIBCPP___FORMAT_FORMAT_FUNCTIONS |
| 12 | 12 | |
| 13 | // TODO FMT This is added to fix Apple back-deployment. | |
| 14 | #include <version> | |
| 15 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 16 | ||
| 17 | 13 | #include <__algorithm/clamp.h> |
| 18 | #include <__availability> | |
| 19 | 14 | #include <__concepts/convertible_to.h> |
| 20 | 15 | #include <__concepts/same_as.h> |
| 21 | 16 | #include <__config> |
| 22 | #include <__debug> | |
| 23 | 17 | #include <__format/buffer.h> |
| 24 | 18 | #include <__format/format_arg.h> |
| 25 | 19 | #include <__format/format_arg_store.h> |
| ... | ... | @@ -38,7 +32,9 @@ |
| 38 | 32 | #include <__format/formatter_string.h> |
| 39 | 33 | #include <__format/parser_std_format_spec.h> |
| 40 | 34 | #include <__iterator/back_insert_iterator.h> |
| 35 | #include <__iterator/concepts.h> | |
| 41 | 36 | #include <__iterator/incrementable_traits.h> |
| 37 | #include <__iterator/iterator_traits.h> // iter_value_t | |
| 42 | 38 | #include <__variant/monostate.h> |
| 43 | 39 | #include <array> |
| 44 | 40 | #include <string> |
| ... | ... | @@ -54,7 +50,7 @@ |
| 54 | 50 | |
| 55 | 51 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 56 | 52 | |
| 57 | #if _LIBCPP_STD_VER > 17 | |
| 53 | #if _LIBCPP_STD_VER >= 20 | |
| 58 | 54 | |
| 59 | 55 | // TODO FMT Evaluate which templates should be external templates. This |
| 60 | 56 | // improves the efficiency of the header. However since the header is still |
| ... | ... | @@ -67,16 +63,17 @@ using wformat_args = basic_format_args<wformat_context>; |
| 67 | 63 | #endif |
| 68 | 64 | |
| 69 | 65 | template <class _Context = format_context, class... _Args> |
| 70 | _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) { | |
| 66 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) { | |
| 71 | 67 | return _VSTD::__format_arg_store<_Context, _Args...>(__args...); |
| 72 | 68 | } |
| 73 | 69 | |
| 74 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 70 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 75 | 71 | template <class... _Args> |
| 76 | _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> make_wformat_args(_Args&&... __args) { | |
| 72 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...> | |
| 73 | make_wformat_args(_Args&&... __args) { | |
| 77 | 74 | return _VSTD::__format_arg_store<wformat_context, _Args...>(__args...); |
| 78 | 75 | } |
| 79 | #endif | |
| 76 | # endif | |
| 80 | 77 | |
| 81 | 78 | namespace __format { |
| 82 | 79 | |
| ... | ... | @@ -87,14 +84,16 @@ namespace __format { |
| 87 | 84 | template <class _CharT> |
| 88 | 85 | class _LIBCPP_TEMPLATE_VIS __compile_time_handle { |
| 89 | 86 | public: |
| 90 | _LIBCPP_HIDE_FROM_ABI | |
| 91 | constexpr void __parse(basic_format_parse_context<_CharT>& __parse_ctx) const { __parse_(__parse_ctx); } | |
| 87 | template <class _ParseContext> | |
| 88 | _LIBCPP_HIDE_FROM_ABI constexpr void __parse(_ParseContext& __ctx) const { | |
| 89 | __parse_(__ctx); | |
| 90 | } | |
| 92 | 91 | |
| 93 | 92 | template <class _Tp> |
| 94 | 93 | _LIBCPP_HIDE_FROM_ABI constexpr void __enable() { |
| 95 | __parse_ = [](basic_format_parse_context<_CharT>& __parse_ctx) { | |
| 94 | __parse_ = [](basic_format_parse_context<_CharT>& __ctx) { | |
| 96 | 95 | formatter<_Tp, _CharT> __f; |
| 97 | __parse_ctx.advance_to(__f.parse(__parse_ctx)); | |
| 96 | __ctx.advance_to(__f.parse(__ctx)); | |
| 98 | 97 | }; |
| 99 | 98 | } |
| 100 | 99 | |
| ... | ... | @@ -128,13 +127,13 @@ public: |
| 128 | 127 | |
| 129 | 128 | _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const { |
| 130 | 129 | if (__id >= __size_) |
| 131 | std::__throw_format_error("Argument index out of bounds"); | |
| 130 | std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); | |
| 132 | 131 | return __args_[__id]; |
| 133 | 132 | } |
| 134 | 133 | |
| 135 | 134 | _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const { |
| 136 | 135 | if (__id >= __size_) |
| 137 | std::__throw_format_error("Argument index out of bounds"); | |
| 136 | std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); | |
| 138 | 137 | return __handles_[__id]; |
| 139 | 138 | } |
| 140 | 139 | |
| ... | ... | @@ -147,41 +146,44 @@ private: |
| 147 | 146 | size_t __size_; |
| 148 | 147 | }; |
| 149 | 148 | |
| 150 | _LIBCPP_HIDE_FROM_ABI | |
| 151 | constexpr void __compile_time_validate_integral(__arg_t __type) { | |
| 152 | switch (__type) { | |
| 153 | case __arg_t::__int: | |
| 154 | case __arg_t::__long_long: | |
| 155 | case __arg_t::__i128: | |
| 156 | case __arg_t::__unsigned: | |
| 157 | case __arg_t::__unsigned_long_long: | |
| 158 | case __arg_t::__u128: | |
| 159 | return; | |
| 160 | ||
| 161 | default: | |
| 162 | std::__throw_format_error("Argument isn't an integral type"); | |
| 163 | } | |
| 164 | } | |
| 165 | ||
| 149 | // [format.string.std]/8 | |
| 150 | // If { arg-idopt } is used in a width or precision, the value of the | |
| 151 | // corresponding formatting argument is used in its place. If the | |
| 152 | // corresponding formatting argument is not of standard signed or unsigned | |
| 153 | // integer type, or its value is negative for precision or non-positive for | |
| 154 | // width, an exception of type format_error is thrown. | |
| 155 | // | |
| 166 | 156 | // _HasPrecision does the formatter have a precision? |
| 167 | 157 | template <class _CharT, class _Tp, bool _HasPrecision = false> |
| 168 | _LIBCPP_HIDE_FROM_ABI constexpr void | |
| 169 | __compile_time_validate_argument(basic_format_parse_context<_CharT>& __parse_ctx, | |
| 170 | __compile_time_basic_format_context<_CharT>& __ctx) { | |
| 158 | _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument( | |
| 159 | basic_format_parse_context<_CharT>& __parse_ctx, __compile_time_basic_format_context<_CharT>& __ctx) { | |
| 160 | auto __validate_type = [](__arg_t __type) { | |
| 161 | // LWG3720 originally allowed "signed or unsigned integer types", however | |
| 162 | // the final version explicitly changed it to "*standard* signed or unsigned | |
| 163 | // integer types". It's trivial to use 128-bit integrals in libc++'s | |
| 164 | // implementation, but other implementations may not implement it. | |
| 165 | // (Using a width or precision, that does not fit in 64-bits, sounds very | |
| 166 | // unlikely in real world code.) | |
| 167 | switch (__type) { | |
| 168 | case __arg_t::__int: | |
| 169 | case __arg_t::__long_long: | |
| 170 | case __arg_t::__unsigned: | |
| 171 | case __arg_t::__unsigned_long_long: | |
| 172 | return; | |
| 173 | ||
| 174 | default: | |
| 175 | std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type"); | |
| 176 | } | |
| 177 | }; | |
| 178 | ||
| 171 | 179 | formatter<_Tp, _CharT> __formatter; |
| 172 | 180 | __parse_ctx.advance_to(__formatter.parse(__parse_ctx)); |
| 173 | // [format.string.std]/7 | |
| 174 | // ... If the corresponding formatting argument is not of integral type, or | |
| 175 | // its value is negative for precision or non-positive for width, an | |
| 176 | // exception of type format_error is thrown. | |
| 177 | // | |
| 178 | // Validate whether the arguments are integrals. | |
| 179 | 181 | if (__formatter.__parser_.__width_as_arg_) |
| 180 | __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__width_)); | |
| 182 | __validate_type(__ctx.arg(__formatter.__parser_.__width_)); | |
| 181 | 183 | |
| 182 | 184 | if constexpr (_HasPrecision) |
| 183 | 185 | if (__formatter.__parser_.__precision_as_arg_) |
| 184 | __format::__compile_time_validate_integral(__ctx.arg(__formatter.__parser_.__precision_)); | |
| 186 | __validate_type(__ctx.arg(__formatter.__parser_.__precision_)); | |
| 185 | 187 | } |
| 186 | 188 | |
| 187 | 189 | // This function is not user facing, so it can directly use the non-standard types of the "variant". |
| ... | ... | @@ -236,30 +238,31 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma |
| 236 | 238 | std::__throw_format_error("Invalid argument"); |
| 237 | 239 | } |
| 238 | 240 | |
| 239 | template <class _CharT, class _ParseCtx, class _Ctx> | |
| 240 | _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* | |
| 241 | __handle_replacement_field(const _CharT* __begin, const _CharT* __end, | |
| 241 | template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx> | |
| 242 | _LIBCPP_HIDE_FROM_ABI constexpr _Iterator | |
| 243 | __handle_replacement_field(_Iterator __begin, _Iterator __end, | |
| 242 | 244 | _ParseCtx& __parse_ctx, _Ctx& __ctx) { |
| 245 | using _CharT = iter_value_t<_Iterator>; | |
| 243 | 246 | __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); |
| 244 | 247 | |
| 245 | bool __parse = *__r.__ptr == _CharT(':'); | |
| 246 | switch (*__r.__ptr) { | |
| 248 | bool __parse = *__r.__last == _CharT(':'); | |
| 249 | switch (*__r.__last) { | |
| 247 | 250 | case _CharT(':'): |
| 248 | 251 | // The arg-id has a format-specifier, advance the input to the format-spec. |
| 249 | __parse_ctx.advance_to(__r.__ptr + 1); | |
| 252 | __parse_ctx.advance_to(__r.__last + 1); | |
| 250 | 253 | break; |
| 251 | 254 | case _CharT('}'): |
| 252 | 255 | // The arg-id has no format-specifier. |
| 253 | __parse_ctx.advance_to(__r.__ptr); | |
| 256 | __parse_ctx.advance_to(__r.__last); | |
| 254 | 257 | break; |
| 255 | 258 | default: |
| 256 | std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'"); | |
| 259 | std::__throw_format_error("The argument index should end with a ':' or a '}'"); | |
| 257 | 260 | } |
| 258 | 261 | |
| 259 | 262 | if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { |
| 260 | 263 | __arg_t __type = __ctx.arg(__r.__value); |
| 261 | 264 | if (__type == __arg_t::__none) |
| 262 | std::__throw_format_error("Argument index out of bounds"); | |
| 265 | std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); | |
| 263 | 266 | else if (__type == __arg_t::__handle) |
| 264 | 267 | __ctx.__handle(__r.__value).__parse(__parse_ctx); |
| 265 | 268 | else if (__parse) |
| ... | ... | @@ -268,7 +271,7 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end, |
| 268 | 271 | _VSTD::__visit_format_arg( |
| 269 | 272 | [&](auto __arg) { |
| 270 | 273 | if constexpr (same_as<decltype(__arg), monostate>) |
| 271 | std::__throw_format_error("Argument index out of bounds"); | |
| 274 | std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); | |
| 272 | 275 | else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Ctx>::handle>) |
| 273 | 276 | __arg.format(__parse_ctx, __ctx); |
| 274 | 277 | else { |
| ... | ... | @@ -293,8 +296,8 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { |
| 293 | 296 | using _CharT = typename _ParseCtx::char_type; |
| 294 | 297 | static_assert(same_as<typename _Ctx::char_type, _CharT>); |
| 295 | 298 | |
| 296 | const _CharT* __begin = __parse_ctx.begin(); | |
| 297 | const _CharT* __end = __parse_ctx.end(); | |
| 299 | auto __begin = __parse_ctx.begin(); | |
| 300 | auto __end = __parse_ctx.end(); | |
| 298 | 301 | typename _Ctx::iterator __out_it = __ctx.out(); |
| 299 | 302 | while (__begin != __end) { |
| 300 | 303 | switch (*__begin) { |
| ... | ... | @@ -341,7 +344,7 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string { |
| 341 | 344 | _Context{__types_.data(), __handles_.data(), sizeof...(_Args)}); |
| 342 | 345 | } |
| 343 | 346 | |
| 344 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT constexpr basic_string_view<_CharT> get() const noexcept { | |
| 347 | _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { | |
| 345 | 348 | return __str_; |
| 346 | 349 | } |
| 347 | 350 | |
| ... | ... | @@ -353,20 +356,6 @@ private: |
| 353 | 356 | static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{ |
| 354 | 357 | __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...}; |
| 355 | 358 | |
| 356 | // TODO FMT remove this work-around when the AIX ICE has been resolved. | |
| 357 | # if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400 | |
| 358 | template <class _Tp> | |
| 359 | static constexpr __format::__compile_time_handle<_CharT> __get_handle() { | |
| 360 | __format::__compile_time_handle<_CharT> __handle; | |
| 361 | if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) | |
| 362 | __handle.template __enable<_Tp>(); | |
| 363 | ||
| 364 | return __handle; | |
| 365 | } | |
| 366 | ||
| 367 | static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{ | |
| 368 | __get_handle<_Args>()...}; | |
| 369 | # else | |
| 370 | 359 | static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] { |
| 371 | 360 | using _Tp = remove_cvref_t<_Args>; |
| 372 | 361 | __format::__compile_time_handle<_CharT> __handle; |
| ... | ... | @@ -375,7 +364,6 @@ private: |
| 375 | 364 | |
| 376 | 365 | return __handle; |
| 377 | 366 | }()...}; |
| 378 | # endif | |
| 379 | 367 | }; |
| 380 | 368 | |
| 381 | 369 | template <class... _Args> |
| ... | ... | @@ -406,21 +394,21 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt |
| 406 | 394 | // https://reviews.llvm.org/D110499#inline-1180704 |
| 407 | 395 | // TODO FMT Evaluate whether we want to file a Clang bug report regarding this. |
| 408 | 396 | template <output_iterator<const char&> _OutIt> |
| 409 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 397 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 410 | 398 | vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { |
| 411 | 399 | return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); |
| 412 | 400 | } |
| 413 | 401 | |
| 414 | 402 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 415 | 403 | template <output_iterator<const wchar_t&> _OutIt> |
| 416 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 404 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 417 | 405 | vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { |
| 418 | 406 | return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); |
| 419 | 407 | } |
| 420 | 408 | #endif |
| 421 | 409 | |
| 422 | 410 | template <output_iterator<const char&> _OutIt, class... _Args> |
| 423 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 411 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 424 | 412 | format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { |
| 425 | 413 | return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), |
| 426 | 414 | _VSTD::make_format_args(__args...)); |
| ... | ... | @@ -428,42 +416,48 @@ format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { |
| 428 | 416 | |
| 429 | 417 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 430 | 418 | template <output_iterator<const wchar_t&> _OutIt, class... _Args> |
| 431 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 419 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 432 | 420 | format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 433 | 421 | return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), |
| 434 | 422 | _VSTD::make_wformat_args(__args...)); |
| 435 | 423 | } |
| 436 | 424 | #endif |
| 437 | 425 | |
| 438 | _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | |
| 426 | // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup | |
| 427 | // fires too eagerly, see http://llvm.org/PR61563. | |
| 428 | template <class = void> | |
| 429 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string | |
| 439 | 430 | vformat(string_view __fmt, format_args __args) { |
| 440 | 431 | string __res; |
| 441 | 432 | _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); |
| 442 | 433 | return __res; |
| 443 | 434 | } |
| 444 | 435 | |
| 445 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 446 | _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring | |
| 436 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 437 | // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup | |
| 438 | // fires too eagerly, see http://llvm.org/PR61563. | |
| 439 | template <class = void> | |
| 440 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring | |
| 447 | 441 | vformat(wstring_view __fmt, wformat_args __args) { |
| 448 | 442 | wstring __res; |
| 449 | 443 | _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); |
| 450 | 444 | return __res; |
| 451 | 445 | } |
| 452 | #endif | |
| 446 | # endif | |
| 453 | 447 | |
| 454 | 448 | template <class... _Args> |
| 455 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(format_string<_Args...> __fmt, | |
| 456 | _Args&&... __args) { | |
| 449 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string | |
| 450 | format(format_string<_Args...> __fmt, _Args&&... __args) { | |
| 457 | 451 | return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...)); |
| 458 | 452 | } |
| 459 | 453 | |
| 460 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 454 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 461 | 455 | template <class... _Args> |
| 462 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring | |
| 456 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring | |
| 463 | 457 | format(wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 464 | 458 | return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...)); |
| 465 | 459 | } |
| 466 | #endif | |
| 460 | # endif | |
| 467 | 461 | |
| 468 | 462 | template <class _Context, class _OutIt, class _CharT> |
| 469 | 463 | _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, |
| ... | ... | @@ -476,14 +470,14 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, |
| 476 | 470 | } |
| 477 | 471 | |
| 478 | 472 | template <output_iterator<const char&> _OutIt, class... _Args> |
| 479 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> | |
| 473 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> | |
| 480 | 474 | format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) { |
| 481 | 475 | return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...)); |
| 482 | 476 | } |
| 483 | 477 | |
| 484 | 478 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 485 | 479 | template <output_iterator<const wchar_t&> _OutIt, class... _Args> |
| 486 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> | |
| 480 | _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> | |
| 487 | 481 | format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, |
| 488 | 482 | _Args&&... __args) { |
| 489 | 483 | return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...)); |
| ... | ... | @@ -499,20 +493,20 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, |
| 499 | 493 | } |
| 500 | 494 | |
| 501 | 495 | template <class... _Args> |
| 502 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | |
| 496 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t | |
| 503 | 497 | formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { |
| 504 | 498 | return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); |
| 505 | 499 | } |
| 506 | 500 | |
| 507 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 501 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 508 | 502 | template <class... _Args> |
| 509 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | |
| 503 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t | |
| 510 | 504 | formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 511 | 505 | return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); |
| 512 | 506 | } |
| 513 | #endif | |
| 507 | # endif | |
| 514 | 508 | |
| 515 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION | |
| 509 | # ifndef _LIBCPP_HAS_NO_LOCALIZATION | |
| 516 | 510 | |
| 517 | 511 | template <class _OutIt, class _CharT, class _FormatOutIt> |
| 518 | 512 | requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt |
| ... | ... | @@ -533,7 +527,7 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt |
| 533 | 527 | } |
| 534 | 528 | |
| 535 | 529 | template <output_iterator<const char&> _OutIt> |
| 536 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( | |
| 530 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( | |
| 537 | 531 | _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { |
| 538 | 532 | return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, |
| 539 | 533 | __args); |
| ... | ... | @@ -541,7 +535,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v |
| 541 | 535 | |
| 542 | 536 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 543 | 537 | template <output_iterator<const wchar_t&> _OutIt> |
| 544 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt vformat_to( | |
| 538 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( | |
| 545 | 539 | _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { |
| 546 | 540 | return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, |
| 547 | 541 | __args); |
| ... | ... | @@ -549,7 +543,7 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt v |
| 549 | 543 | #endif |
| 550 | 544 | |
| 551 | 545 | template <output_iterator<const char&> _OutIt, class... _Args> |
| 552 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 546 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 553 | 547 | format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { |
| 554 | 548 | return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), |
| 555 | 549 | _VSTD::make_format_args(__args...)); |
| ... | ... | @@ -557,14 +551,17 @@ format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&. |
| 557 | 551 | |
| 558 | 552 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 559 | 553 | template <output_iterator<const wchar_t&> _OutIt, class... _Args> |
| 560 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT _OutIt | |
| 554 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt | |
| 561 | 555 | format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 562 | 556 | return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), |
| 563 | 557 | _VSTD::make_wformat_args(__args...)); |
| 564 | 558 | } |
| 565 | 559 | #endif |
| 566 | 560 | |
| 567 | _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string | |
| 561 | // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup | |
| 562 | // fires too eagerly, see http://llvm.org/PR61563. | |
| 563 | template <class = void> | |
| 564 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string | |
| 568 | 565 | vformat(locale __loc, string_view __fmt, format_args __args) { |
| 569 | 566 | string __res; |
| 570 | 567 | _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, |
| ... | ... | @@ -572,32 +569,34 @@ vformat(locale __loc, string_view __fmt, format_args __args) { |
| 572 | 569 | return __res; |
| 573 | 570 | } |
| 574 | 571 | |
| 575 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 576 | _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring | |
| 572 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 573 | // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup | |
| 574 | // fires too eagerly, see http://llvm.org/PR61563. | |
| 575 | template <class = void> | |
| 576 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring | |
| 577 | 577 | vformat(locale __loc, wstring_view __fmt, wformat_args __args) { |
| 578 | 578 | wstring __res; |
| 579 | 579 | _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, |
| 580 | 580 | __args); |
| 581 | 581 | return __res; |
| 582 | 582 | } |
| 583 | #endif | |
| 583 | # endif | |
| 584 | 584 | |
| 585 | 585 | template <class... _Args> |
| 586 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string format(locale __loc, | |
| 587 | format_string<_Args...> __fmt, | |
| 588 | _Args&&... __args) { | |
| 586 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string | |
| 587 | format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { | |
| 589 | 588 | return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), |
| 590 | 589 | _VSTD::make_format_args(__args...)); |
| 591 | 590 | } |
| 592 | 591 | |
| 593 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 592 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 594 | 593 | template <class... _Args> |
| 595 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring | |
| 594 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring | |
| 596 | 595 | format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 597 | 596 | return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), |
| 598 | 597 | _VSTD::make_wformat_args(__args...)); |
| 599 | 598 | } |
| 600 | #endif | |
| 599 | # endif | |
| 601 | 600 | |
| 602 | 601 | template <class _Context, class _OutIt, class _CharT> |
| 603 | 602 | _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, |
| ... | ... | @@ -611,7 +610,7 @@ _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, |
| 611 | 610 | } |
| 612 | 611 | |
| 613 | 612 | template <output_iterator<const char&> _OutIt, class... _Args> |
| 614 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> | |
| 613 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> | |
| 615 | 614 | format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, |
| 616 | 615 | _Args&&... __args) { |
| 617 | 616 | return _VSTD::__vformat_to_n<format_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), |
| ... | ... | @@ -620,7 +619,7 @@ format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format |
| 620 | 619 | |
| 621 | 620 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 622 | 621 | template <output_iterator<const wchar_t&> _OutIt, class... _Args> |
| 623 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT format_to_n_result<_OutIt> | |
| 622 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> | |
| 624 | 623 | format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, |
| 625 | 624 | _Args&&... __args) { |
| 626 | 625 | return _VSTD::__vformat_to_n<wformat_context>(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), |
| ... | ... | @@ -638,26 +637,23 @@ _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_ |
| 638 | 637 | } |
| 639 | 638 | |
| 640 | 639 | template <class... _Args> |
| 641 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | |
| 640 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t | |
| 642 | 641 | formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { |
| 643 | 642 | return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); |
| 644 | 643 | } |
| 645 | 644 | |
| 646 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 645 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 647 | 646 | template <class... _Args> |
| 648 | _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t | |
| 647 | _LIBCPP_NODISCARD_EXT _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t | |
| 649 | 648 | formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { |
| 650 | 649 | return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); |
| 651 | 650 | } |
| 652 | #endif | |
| 653 | ||
| 654 | #endif // _LIBCPP_HAS_NO_LOCALIZATION | |
| 651 | # endif | |
| 655 | 652 | |
| 653 | # endif // _LIBCPP_HAS_NO_LOCALIZATION | |
| 656 | 654 | |
| 657 | #endif //_LIBCPP_STD_VER > 17 | |
| 655 | #endif //_LIBCPP_STD_VER >= 20 | |
| 658 | 656 | |
| 659 | 657 | _LIBCPP_END_NAMESPACE_STD |
| 660 | 658 | |
| 661 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 662 | ||
| 663 | 659 | #endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS |
lib/libcxx/include/__format/format_fwd.h+5-5| ... | ... | @@ -20,19 +20,19 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | template <class _Context> |
| 26 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_arg; | |
| 26 | class _LIBCPP_TEMPLATE_VIS basic_format_arg; | |
| 27 | 27 | |
| 28 | 28 | template <class _OutIt, class _CharT> |
| 29 | 29 | requires output_iterator<_OutIt, const _CharT&> |
| 30 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; | |
| 30 | class _LIBCPP_TEMPLATE_VIS basic_format_context; | |
| 31 | 31 | |
| 32 | 32 | template <class _Tp, class _CharT = char> |
| 33 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter; | |
| 33 | struct _LIBCPP_TEMPLATE_VIS formatter; | |
| 34 | 34 | |
| 35 | #endif //_LIBCPP_STD_VER > 17 | |
| 35 | #endif //_LIBCPP_STD_VER >= 20 | |
| 36 | 36 | |
| 37 | 37 | _LIBCPP_END_NAMESPACE_STD |
| 38 | 38 |
lib/libcxx/include/__format/format_parse_context.h+16-3| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__format/format_error.h> |
| 15 | #include <__type_traits/is_constant_evaluated.h> | |
| 15 | 16 | #include <string_view> |
| 16 | 17 | |
| 17 | 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -20,10 +21,10 @@ |
| 20 | 21 | |
| 21 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 23 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 25 | |
| 25 | 26 | template <class _CharT> |
| 26 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context { | |
| 27 | class _LIBCPP_TEMPLATE_VIS basic_format_parse_context { | |
| 27 | 28 | public: |
| 28 | 29 | using char_type = _CharT; |
| 29 | 30 | using const_iterator = typename basic_string_view<_CharT>::const_iterator; |
| ... | ... | @@ -58,6 +59,18 @@ public: |
| 58 | 59 | |
| 59 | 60 | if (__indexing_ == __unknown) |
| 60 | 61 | __indexing_ = __automatic; |
| 62 | ||
| 63 | // Throws an exception to make the expression a non core constant | |
| 64 | // expression as required by: | |
| 65 | // [format.parse.ctx]/8 | |
| 66 | // Remarks: Let cur-arg-id be the value of next_arg_id_ prior to this | |
| 67 | // call. Call expressions where cur-arg-id >= num_args_ is true are not | |
| 68 | // core constant expressions (7.7 [expr.const]). | |
| 69 | // Note: the Throws clause [format.parse.ctx]/9 doesn't specify the | |
| 70 | // behavior when id >= num_args_. | |
| 71 | if (is_constant_evaluated() && __next_arg_id_ >= __num_args_) | |
| 72 | std::__throw_format_error("Argument index outside the valid range"); | |
| 73 | ||
| 61 | 74 | return __next_arg_id_++; |
| 62 | 75 | } |
| 63 | 76 | _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) { |
| ... | ... | @@ -93,7 +106,7 @@ using format_parse_context = basic_format_parse_context<char>; |
| 93 | 106 | using wformat_parse_context = basic_format_parse_context<wchar_t>; |
| 94 | 107 | #endif |
| 95 | 108 | |
| 96 | #endif //_LIBCPP_STD_VER > 17 | |
| 109 | #endif //_LIBCPP_STD_VER >= 20 | |
| 97 | 110 | |
| 98 | 111 | _LIBCPP_END_NAMESPACE_STD |
| 99 | 112 |
lib/libcxx/include/__format/format_string.h+35-30| ... | ... | @@ -13,6 +13,8 @@ |
| 13 | 13 | #include <__assert> |
| 14 | 14 | #include <__config> |
| 15 | 15 | #include <__format/format_error.h> |
| 16 | #include <__iterator/concepts.h> | |
| 17 | #include <__iterator/iterator_traits.h> // iter_value_t | |
| 16 | 18 | #include <cstddef> |
| 17 | 19 | #include <cstdint> |
| 18 | 20 | |
| ... | ... | @@ -22,22 +24,22 @@ |
| 22 | 24 | |
| 23 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 26 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 28 | |
| 27 | 29 | namespace __format { |
| 28 | 30 | |
| 29 | template <class _CharT> | |
| 31 | template <contiguous_iterator _Iterator> | |
| 30 | 32 | struct _LIBCPP_TEMPLATE_VIS __parse_number_result { |
| 31 | const _CharT* __ptr; | |
| 33 | _Iterator __last; | |
| 32 | 34 | uint32_t __value; |
| 33 | 35 | }; |
| 34 | 36 | |
| 35 | template <class _CharT> | |
| 36 | __parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>; | |
| 37 | template <contiguous_iterator _Iterator> | |
| 38 | __parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>; | |
| 37 | 39 | |
| 38 | template <class _CharT> | |
| 39 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 40 | __parse_number(const _CharT* __begin, const _CharT* __end); | |
| 40 | template <contiguous_iterator _Iterator> | |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 42 | __parse_number(_Iterator __begin, _Iterator __end); | |
| 41 | 43 | |
| 42 | 44 | /** |
| 43 | 45 | * The maximum value of a numeric argument. |
| ... | ... | @@ -53,27 +55,28 @@ __parse_number(const _CharT* __begin, const _CharT* __end); |
| 53 | 55 | inline constexpr uint32_t __number_max = INT32_MAX; |
| 54 | 56 | |
| 55 | 57 | namespace __detail { |
| 56 | template <class _CharT> | |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 58 | __parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { | |
| 58 | template <contiguous_iterator _Iterator> | |
| 59 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 60 | __parse_zero(_Iterator __begin, _Iterator, auto& __parse_ctx) { | |
| 59 | 61 | __parse_ctx.check_arg_id(0); |
| 60 | 62 | return {++__begin, 0}; // can never be larger than the maximum. |
| 61 | 63 | } |
| 62 | 64 | |
| 63 | template <class _CharT> | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 65 | __parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) { | |
| 65 | template <contiguous_iterator _Iterator> | |
| 66 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 67 | __parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) { | |
| 66 | 68 | size_t __value = __parse_ctx.next_arg_id(); |
| 67 | _LIBCPP_ASSERT(__value <= __number_max, | |
| 68 | "Compilers don't support this number of arguments"); | |
| 69 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 70 | __value <= __number_max, | |
| 71 | "Compilers don't support this number of arguments"); | |
| 69 | 72 | |
| 70 | 73 | return {__begin, uint32_t(__value)}; |
| 71 | 74 | } |
| 72 | 75 | |
| 73 | template <class _CharT> | |
| 74 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 75 | __parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { | |
| 76 | __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end); | |
| 76 | template <contiguous_iterator _Iterator> | |
| 77 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 78 | __parse_manual(_Iterator __begin, _Iterator __end, auto& __parse_ctx) { | |
| 79 | __parse_number_result<_Iterator> __r = __format::__parse_number(__begin, __end); | |
| 77 | 80 | __parse_ctx.check_arg_id(__r.__value); |
| 78 | 81 | return __r; |
| 79 | 82 | } |
| ... | ... | @@ -86,9 +89,10 @@ __parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { |
| 86 | 89 | * The number is used for the 31-bit values @em width and @em precision. This |
| 87 | 90 | * allows a maximum value of 2147483647. |
| 88 | 91 | */ |
| 89 | template <class _CharT> | |
| 90 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 91 | __parse_number(const _CharT* __begin, const _CharT* __end_input) { | |
| 92 | template <contiguous_iterator _Iterator> | |
| 93 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 94 | __parse_number(_Iterator __begin, _Iterator __end_input) { | |
| 95 | using _CharT = iter_value_t<_Iterator>; | |
| 92 | 96 | static_assert(__format::__number_max == INT32_MAX, |
| 93 | 97 | "The algorithm is implemented based on this value."); |
| 94 | 98 | /* |
| ... | ... | @@ -98,7 +102,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) { |
| 98 | 102 | * - Does the value exceed width of an uint32_t? (Switching to uint64_t would |
| 99 | 103 | * have the same issue, but with a higher maximum.) |
| 100 | 104 | */ |
| 101 | const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; | |
| 105 | _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; | |
| 102 | 106 | uint32_t __value = *__begin - _CharT('0'); |
| 103 | 107 | while (++__begin != __end) { |
| 104 | 108 | if (*__begin < _CharT('0') || *__begin > _CharT('9')) |
| ... | ... | @@ -120,7 +124,7 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) { |
| 120 | 124 | if (__v > __number_max || |
| 121 | 125 | (__begin != __end_input && *__begin >= _CharT('0') && |
| 122 | 126 | *__begin <= _CharT('9'))) |
| 123 | std::__throw_format_error("The numeric value of the format-spec is too large"); | |
| 127 | std::__throw_format_error("The numeric value of the format specifier is too large"); | |
| 124 | 128 | |
| 125 | 129 | __value = __v; |
| 126 | 130 | } |
| ... | ... | @@ -134,9 +138,10 @@ __parse_number(const _CharT* __begin, const _CharT* __end_input) { |
| 134 | 138 | * The parser will return a pointer beyond the last consumed character. This |
| 135 | 139 | * should be the closing '}' of the arg-id. |
| 136 | 140 | */ |
| 137 | template <class _CharT> | |
| 138 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT> | |
| 139 | __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { | |
| 141 | template <contiguous_iterator _Iterator> | |
| 142 | _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> | |
| 143 | __parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) { | |
| 144 | using _CharT = iter_value_t<_Iterator>; | |
| 140 | 145 | switch (*__begin) { |
| 141 | 146 | case _CharT('0'): |
| 142 | 147 | return __detail::__parse_zero(__begin, __end, __parse_ctx); |
| ... | ... | @@ -149,14 +154,14 @@ __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { |
| 149 | 154 | return __detail::__parse_automatic(__begin, __end, __parse_ctx); |
| 150 | 155 | } |
| 151 | 156 | if (*__begin < _CharT('0') || *__begin > _CharT('9')) |
| 152 | std::__throw_format_error("The arg-id of the format-spec starts with an invalid character"); | |
| 157 | std::__throw_format_error("The argument index starts with an invalid character"); | |
| 153 | 158 | |
| 154 | 159 | return __detail::__parse_manual(__begin, __end, __parse_ctx); |
| 155 | 160 | } |
| 156 | 161 | |
| 157 | 162 | } // namespace __format |
| 158 | 163 | |
| 159 | #endif //_LIBCPP_STD_VER > 17 | |
| 164 | #endif //_LIBCPP_STD_VER >= 20 | |
| 160 | 165 | |
| 161 | 166 | _LIBCPP_END_NAMESPACE_STD |
| 162 | 167 |
lib/libcxx/include/__format/format_to_n_result.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | template <class _OutIt> |
| 25 | 25 | struct _LIBCPP_TEMPLATE_VIS format_to_n_result { |
| ... | ... | @@ -28,7 +28,7 @@ struct _LIBCPP_TEMPLATE_VIS format_to_n_result { |
| 28 | 28 | }; |
| 29 | 29 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result); |
| 30 | 30 | |
| 31 | #endif //_LIBCPP_STD_VER > 17 | |
| 31 | #endif //_LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 34 |
lib/libcxx/include/__format/formatter.h+5-5| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | /// The default formatter template. |
| 26 | 26 | /// |
| ... | ... | @@ -32,13 +32,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | /// - is_copy_assignable<F>, and |
| 33 | 33 | /// - is_move_assignable<F>. |
| 34 | 34 | template <class _Tp, class _CharT> |
| 35 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter { | |
| 35 | struct _LIBCPP_TEMPLATE_VIS formatter { | |
| 36 | 36 | formatter() = delete; |
| 37 | 37 | formatter(const formatter&) = delete; |
| 38 | 38 | formatter& operator=(const formatter&) = delete; |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | # if _LIBCPP_STD_VER > 20 | |
| 41 | # if _LIBCPP_STD_VER >= 23 | |
| 42 | 42 | |
| 43 | 43 | template <class _Tp> |
| 44 | 44 | _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) { |
| ... | ... | @@ -46,8 +46,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) { |
| 46 | 46 | __formatter.set_debug_format(); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | # endif // _LIBCPP_STD_VER > 20 | |
| 50 | #endif // _LIBCPP_STD_VER > 17 | |
| 49 | # endif // _LIBCPP_STD_VER >= 23 | |
| 50 | #endif // _LIBCPP_STD_VER >= 20 | |
| 51 | 51 | |
| 52 | 52 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 53 |
lib/libcxx/include/__format/formatter_bool.h+11-12| ... | ... | @@ -11,17 +11,15 @@ |
| 11 | 11 | #define _LIBCPP___FORMAT_FORMATTER_BOOL_H |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/copy.h> |
| 14 | #include <__assert> | |
| 14 | 15 | #include <__availability> |
| 15 | 16 | #include <__config> |
| 16 | #include <__debug> | |
| 17 | 17 | #include <__format/concepts.h> |
| 18 | #include <__format/format_error.h> | |
| 19 | 18 | #include <__format/format_parse_context.h> |
| 20 | 19 | #include <__format/formatter.h> |
| 21 | 20 | #include <__format/formatter_integral.h> |
| 22 | 21 | #include <__format/parser_std_format_spec.h> |
| 23 | 22 | #include <__utility/unreachable.h> |
| 24 | #include <string_view> | |
| 25 | 23 | |
| 26 | 24 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION |
| 27 | 25 | # include <locale> |
| ... | ... | @@ -33,19 +31,20 @@ |
| 33 | 31 | |
| 34 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 33 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 35 | |
| 38 | 36 | template <__fmt_char_type _CharT> |
| 39 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<bool, _CharT> { | |
| 37 | struct _LIBCPP_TEMPLATE_VIS formatter<bool, _CharT> { | |
| 40 | 38 | public: |
| 41 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 42 | parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { | |
| 43 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); | |
| 44 | __format_spec::__process_parsed_bool(__parser_); | |
| 39 | template <class _ParseContext> | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 41 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); | |
| 42 | __format_spec::__process_parsed_bool(__parser_, "a bool"); | |
| 45 | 43 | return __result; |
| 46 | 44 | } |
| 47 | 45 | |
| 48 | _LIBCPP_HIDE_FROM_ABI auto format(bool __value, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 46 | template <class _FormatContext> | |
| 47 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(bool __value, _FormatContext& __ctx) const { | |
| 49 | 48 | switch (__parser_.__type_) { |
| 50 | 49 | case __format_spec::__type::__default: |
| 51 | 50 | case __format_spec::__type::__string: |
| ... | ... | @@ -63,7 +62,7 @@ public: |
| 63 | 62 | static_cast<unsigned>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); |
| 64 | 63 | |
| 65 | 64 | default: |
| 66 | _LIBCPP_ASSERT(false, "The parse function should have validated the type"); | |
| 65 | _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type"); | |
| 67 | 66 | __libcpp_unreachable(); |
| 68 | 67 | } |
| 69 | 68 | } |
| ... | ... | @@ -71,7 +70,7 @@ public: |
| 71 | 70 | __format_spec::__parser<_CharT> __parser_; |
| 72 | 71 | }; |
| 73 | 72 | |
| 74 | #endif //_LIBCPP_STD_VER > 17 | |
| 73 | #endif //_LIBCPP_STD_VER >= 20 | |
| 75 | 74 | |
| 76 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 76 |
lib/libcxx/include/__format/formatter_char.h+17-14| ... | ... | @@ -19,6 +19,7 @@ |
| 19 | 19 | #include <__format/formatter_integral.h> |
| 20 | 20 | #include <__format/formatter_output.h> |
| 21 | 21 | #include <__format/parser_std_format_spec.h> |
| 22 | #include <__format/write_escaped.h> | |
| 22 | 23 | #include <__type_traits/conditional.h> |
| 23 | 24 | #include <__type_traits/is_signed.h> |
| 24 | 25 | |
| ... | ... | @@ -28,23 +29,24 @@ |
| 28 | 29 | |
| 29 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 31 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 33 | |
| 33 | 34 | template <__fmt_char_type _CharT> |
| 34 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_char { | |
| 35 | struct _LIBCPP_TEMPLATE_VIS __formatter_char { | |
| 35 | 36 | public: |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 37 | parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { | |
| 38 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); | |
| 39 | __format_spec::__process_parsed_char(__parser_); | |
| 37 | template <class _ParseContext> | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 39 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); | |
| 40 | __format_spec::__process_parsed_char(__parser_, "a character"); | |
| 40 | 41 | return __result; |
| 41 | 42 | } |
| 42 | 43 | |
| 43 | _LIBCPP_HIDE_FROM_ABI auto format(_CharT __value, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 44 | template <class _FormatContext> | |
| 45 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT __value, _FormatContext& __ctx) const { | |
| 44 | 46 | if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char) |
| 45 | 47 | return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); |
| 46 | 48 | |
| 47 | # if _LIBCPP_STD_VER > 20 | |
| 49 | # if _LIBCPP_STD_VER >= 23 | |
| 48 | 50 | if (__parser_.__type_ == __format_spec::__type::__debug) |
| 49 | 51 | return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); |
| 50 | 52 | # endif |
| ... | ... | @@ -60,13 +62,14 @@ public: |
| 60 | 62 | return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); |
| 61 | 63 | } |
| 62 | 64 | |
| 63 | _LIBCPP_HIDE_FROM_ABI auto format(char __value, auto& __ctx) const -> decltype(__ctx.out()) | |
| 65 | template <class _FormatContext> | |
| 66 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(char __value, _FormatContext& __ctx) const | |
| 64 | 67 | requires(same_as<_CharT, wchar_t>) |
| 65 | 68 | { |
| 66 | 69 | return format(static_cast<wchar_t>(__value), __ctx); |
| 67 | 70 | } |
| 68 | 71 | |
| 69 | # if _LIBCPP_STD_VER > 20 | |
| 72 | # if _LIBCPP_STD_VER >= 23 | |
| 70 | 73 | _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } |
| 71 | 74 | # endif |
| 72 | 75 | |
| ... | ... | @@ -74,19 +77,19 @@ public: |
| 74 | 77 | }; |
| 75 | 78 | |
| 76 | 79 | template <> |
| 77 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, char> : public __formatter_char<char> {}; | |
| 80 | struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {}; | |
| 78 | 81 | |
| 79 | 82 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 80 | 83 | template <> |
| 81 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<char, wchar_t> : public __formatter_char<wchar_t> {}; | |
| 84 | struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {}; | |
| 82 | 85 | |
| 83 | 86 | template <> |
| 84 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> { | |
| 87 | struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> { | |
| 85 | 88 | }; |
| 86 | 89 | |
| 87 | 90 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 88 | 91 | |
| 89 | #endif //_LIBCPP_STD_VER > 17 | |
| 92 | #endif //_LIBCPP_STD_VER >= 20 | |
| 90 | 93 | |
| 91 | 94 | _LIBCPP_END_NAMESPACE_STD |
| 92 | 95 |
lib/libcxx/include/__format/formatter_floating_point.h+80-43| ... | ... | @@ -16,6 +16,9 @@ |
| 16 | 16 | #include <__algorithm/min.h> |
| 17 | 17 | #include <__algorithm/rotate.h> |
| 18 | 18 | #include <__algorithm/transform.h> |
| 19 | #include <__charconv/chars_format.h> | |
| 20 | #include <__charconv/to_chars_floating_point.h> | |
| 21 | #include <__charconv/to_chars_result.h> | |
| 19 | 22 | #include <__concepts/arithmetic.h> |
| 20 | 23 | #include <__concepts/same_as.h> |
| 21 | 24 | #include <__config> |
| ... | ... | @@ -25,10 +28,14 @@ |
| 25 | 28 | #include <__format/formatter_integral.h> |
| 26 | 29 | #include <__format/formatter_output.h> |
| 27 | 30 | #include <__format/parser_std_format_spec.h> |
| 31 | #include <__iterator/concepts.h> | |
| 28 | 32 | #include <__memory/allocator.h> |
| 33 | #include <__system_error/errc.h> | |
| 34 | #include <__type_traits/conditional.h> | |
| 29 | 35 | #include <__utility/move.h> |
| 30 | 36 | #include <__utility/unreachable.h> |
| 31 | #include <charconv> | |
| 37 | #include <cmath> | |
| 38 | #include <cstddef> | |
| 32 | 39 | |
| 33 | 40 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION |
| 34 | 41 | # include <locale> |
| ... | ... | @@ -43,28 +50,28 @@ _LIBCPP_PUSH_MACROS |
| 43 | 50 | |
| 44 | 51 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 45 | 52 | |
| 46 | #if _LIBCPP_STD_VER > 17 | |
| 53 | #if _LIBCPP_STD_VER >= 20 | |
| 47 | 54 | |
| 48 | 55 | namespace __formatter { |
| 49 | 56 | |
| 50 | 57 | template <floating_point _Tp> |
| 51 | 58 | _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { |
| 52 | 59 | to_chars_result __r = _VSTD::to_chars(__first, __last, __value); |
| 53 | _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); | |
| 60 | _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); | |
| 54 | 61 | return __r.ptr; |
| 55 | 62 | } |
| 56 | 63 | |
| 57 | 64 | template <floating_point _Tp> |
| 58 | 65 | _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { |
| 59 | 66 | to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); |
| 60 | _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); | |
| 67 | _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); | |
| 61 | 68 | return __r.ptr; |
| 62 | 69 | } |
| 63 | 70 | |
| 64 | 71 | template <floating_point _Tp> |
| 65 | 72 | _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { |
| 66 | 73 | to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); |
| 67 | _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); | |
| 74 | _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); | |
| 68 | 75 | return __r.ptr; |
| 69 | 76 | } |
| 70 | 77 | |
| ... | ... | @@ -246,10 +253,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe |
| 246 | 253 | __result.__radix_point = __result.__last; |
| 247 | 254 | |
| 248 | 255 | // clang-format off |
| 249 | _LIBCPP_ASSERT((__result.__integral != __result.__last) && | |
| 250 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 251 | (__result.__exponent == __result.__last || *__result.__exponent == 'e'), | |
| 252 | "Post-condition failure."); | |
| 256 | _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && | |
| 257 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 258 | (__result.__exponent == __result.__last || *__result.__exponent == 'e'), | |
| 259 | "Post-condition failure."); | |
| 253 | 260 | // clang-format on |
| 254 | 261 | |
| 255 | 262 | return __result; |
| ... | ... | @@ -299,10 +306,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons |
| 299 | 306 | } |
| 300 | 307 | |
| 301 | 308 | // clang-format off |
| 302 | _LIBCPP_ASSERT((__result.__integral != __result.__last) && | |
| 303 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 304 | (__result.__exponent != __result.__last && *__result.__exponent == 'p'), | |
| 305 | "Post-condition failure."); | |
| 309 | _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && | |
| 310 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 311 | (__result.__exponent != __result.__last && *__result.__exponent == 'p'), | |
| 312 | "Post-condition failure."); | |
| 306 | 313 | // clang-format on |
| 307 | 314 | |
| 308 | 315 | return __result; |
| ... | ... | @@ -329,7 +336,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const |
| 329 | 336 | __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); |
| 330 | 337 | |
| 331 | 338 | char* __first = __integral + 1; |
| 332 | _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); | |
| 339 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __result.__last, "No exponent present"); | |
| 333 | 340 | if (*__first == '.') { |
| 334 | 341 | __result.__radix_point = __first; |
| 335 | 342 | __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last); |
| ... | ... | @@ -339,10 +346,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const |
| 339 | 346 | } |
| 340 | 347 | |
| 341 | 348 | // clang-format off |
| 342 | _LIBCPP_ASSERT((__result.__integral != __result.__last) && | |
| 343 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 344 | (__result.__exponent != __result.__last && *__result.__exponent == 'e'), | |
| 345 | "Post-condition failure."); | |
| 349 | _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && | |
| 350 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 351 | (__result.__exponent != __result.__last && *__result.__exponent == 'e'), | |
| 352 | "Post-condition failure."); | |
| 346 | 353 | // clang-format on |
| 347 | 354 | return __result; |
| 348 | 355 | } |
| ... | ... | @@ -372,10 +379,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer< |
| 372 | 379 | __result.__exponent = __result.__last; |
| 373 | 380 | |
| 374 | 381 | // clang-format off |
| 375 | _LIBCPP_ASSERT((__result.__integral != __result.__last) && | |
| 376 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 377 | (__result.__exponent == __result.__last), | |
| 378 | "Post-condition failure."); | |
| 382 | _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && | |
| 383 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 384 | (__result.__exponent == __result.__last), | |
| 385 | "Post-condition failure."); | |
| 379 | 386 | // clang-format on |
| 380 | 387 | return __result; |
| 381 | 388 | } |
| ... | ... | @@ -409,10 +416,10 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ |
| 409 | 416 | } |
| 410 | 417 | |
| 411 | 418 | // clang-format off |
| 412 | _LIBCPP_ASSERT((__result.__integral != __result.__last) && | |
| 413 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 414 | (__result.__exponent == __result.__last || *__result.__exponent == 'e'), | |
| 415 | "Post-condition failure."); | |
| 419 | _LIBCPP_ASSERT_UNCATEGORIZED((__result.__integral != __result.__last) && | |
| 420 | (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && | |
| 421 | (__result.__exponent == __result.__last || *__result.__exponent == 'e'), | |
| 422 | "Post-condition failure."); | |
| 416 | 423 | // clang-format on |
| 417 | 424 | |
| 418 | 425 | return __result; |
| ... | ... | @@ -484,7 +491,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer( |
| 484 | 491 | return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); |
| 485 | 492 | |
| 486 | 493 | default: |
| 487 | _LIBCPP_ASSERT(false, "The parser should have validated the type"); | |
| 494 | _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parser should have validated the type"); | |
| 488 | 495 | __libcpp_unreachable(); |
| 489 | 496 | } |
| 490 | 497 | } |
| ... | ... | @@ -522,7 +529,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( |
| 522 | 529 | if (__size < __specs.__width_) { |
| 523 | 530 | if (__zero_padding) { |
| 524 | 531 | __specs.__alignment_ = __format_spec::__alignment::__right; |
| 525 | __specs.__fill_ = _CharT('0'); | |
| 532 | __specs.__fill_.__data[0] = _CharT('0'); | |
| 526 | 533 | } |
| 527 | 534 | |
| 528 | 535 | __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); |
| ... | ... | @@ -602,10 +609,40 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite( |
| 602 | 609 | return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs); |
| 603 | 610 | } |
| 604 | 611 | |
| 605 | template <floating_point _Tp, class _CharT> | |
| 606 | _LIBCPP_HIDE_FROM_ABI auto | |
| 607 | __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) | |
| 608 | -> decltype(__ctx.out()) { | |
| 612 | /// Writes additional zero's for the precision before the exponent. | |
| 613 | /// This is used when the precision requested in the format string is larger | |
| 614 | /// than the maximum precision of the floating-point type. These precision | |
| 615 | /// digits are always 0. | |
| 616 | /// | |
| 617 | /// \param __exponent The location of the exponent character. | |
| 618 | /// \param __num_trailing_zeros The number of 0's to write before the exponent | |
| 619 | /// character. | |
| 620 | template <class _CharT, class _ParserCharT> | |
| 621 | _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( | |
| 622 | const _CharT* __first, | |
| 623 | const _CharT* __last, | |
| 624 | output_iterator<const _CharT&> auto __out_it, | |
| 625 | __format_spec::__parsed_specifications<_ParserCharT> __specs, | |
| 626 | size_t __size, | |
| 627 | const _CharT* __exponent, | |
| 628 | size_t __num_trailing_zeros) -> decltype(__out_it) { | |
| 629 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); | |
| 630 | _LIBCPP_ASSERT_UNCATEGORIZED(__num_trailing_zeros > 0, | |
| 631 | "The overload not writing trailing zeros should have been used"); | |
| 632 | ||
| 633 | __padding_size_result __padding = | |
| 634 | __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); | |
| 635 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); | |
| 636 | __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it)); | |
| 637 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); | |
| 638 | __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it)); | |
| 639 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); | |
| 640 | } | |
| 641 | ||
| 642 | ||
| 643 | template <floating_point _Tp, class _CharT, class _FormatContext> | |
| 644 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 645 | __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) { | |
| 609 | 646 | bool __negative = _VSTD::signbit(__value); |
| 610 | 647 | |
| 611 | 648 | if (!_VSTD::isfinite(__value)) [[unlikely]] |
| ... | ... | @@ -707,7 +744,7 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif |
| 707 | 744 | // After the sign is written, zero padding is the same a right alignment |
| 708 | 745 | // with '0'. |
| 709 | 746 | __specs.__alignment_ = __format_spec::__alignment::__right; |
| 710 | __specs.__fill_ = _CharT('0'); | |
| 747 | __specs.__fill_.__data[0] = _CharT('0'); | |
| 711 | 748 | } |
| 712 | 749 | |
| 713 | 750 | if (__num_trailing_zeros) |
| ... | ... | @@ -722,15 +759,15 @@ __format_floating_point(_Tp __value, auto& __ctx, __format_spec::__parsed_specif |
| 722 | 759 | template <__fmt_char_type _CharT> |
| 723 | 760 | struct _LIBCPP_TEMPLATE_VIS __formatter_floating_point { |
| 724 | 761 | public: |
| 725 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 726 | parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { | |
| 727 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_floating_point); | |
| 728 | __format_spec::__process_parsed_floating_point(__parser_); | |
| 762 | template <class _ParseContext> | |
| 763 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 764 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_floating_point); | |
| 765 | __format_spec::__process_parsed_floating_point(__parser_, "a floating-point"); | |
| 729 | 766 | return __result; |
| 730 | 767 | } |
| 731 | 768 | |
| 732 | template <floating_point _Tp> | |
| 733 | _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 769 | template <floating_point _Tp, class _FormatContext> | |
| 770 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const { | |
| 734 | 771 | return __formatter::__format_floating_point(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); |
| 735 | 772 | } |
| 736 | 773 | |
| ... | ... | @@ -738,16 +775,16 @@ public: |
| 738 | 775 | }; |
| 739 | 776 | |
| 740 | 777 | template <__fmt_char_type _CharT> |
| 741 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<float, _CharT> | |
| 778 | struct _LIBCPP_TEMPLATE_VIS formatter<float, _CharT> | |
| 742 | 779 | : public __formatter_floating_point<_CharT> {}; |
| 743 | 780 | template <__fmt_char_type _CharT> |
| 744 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<double, _CharT> | |
| 781 | struct _LIBCPP_TEMPLATE_VIS formatter<double, _CharT> | |
| 745 | 782 | : public __formatter_floating_point<_CharT> {}; |
| 746 | 783 | template <__fmt_char_type _CharT> |
| 747 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long double, _CharT> | |
| 784 | struct _LIBCPP_TEMPLATE_VIS formatter<long double, _CharT> | |
| 748 | 785 | : public __formatter_floating_point<_CharT> {}; |
| 749 | 786 | |
| 750 | #endif //_LIBCPP_STD_VER > 17 | |
| 787 | #endif //_LIBCPP_STD_VER >= 20 | |
| 751 | 788 | |
| 752 | 789 | _LIBCPP_END_NAMESPACE_STD |
| 753 | 790 |
lib/libcxx/include/__format/formatter_integer.h+23-23| ... | ... | @@ -19,8 +19,8 @@ |
| 19 | 19 | #include <__format/formatter_integral.h> |
| 20 | 20 | #include <__format/formatter_output.h> |
| 21 | 21 | #include <__format/parser_std_format_spec.h> |
| 22 | #include <__type_traits/is_void.h> | |
| 22 | 23 | #include <__type_traits/make_32_64_or_128_bit.h> |
| 23 | #include <type_traits> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
| ... | ... | @@ -28,28 +28,28 @@ |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | template <__fmt_char_type _CharT> |
| 34 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_integer { | |
| 34 | struct _LIBCPP_TEMPLATE_VIS __formatter_integer { | |
| 35 | 35 | |
| 36 | 36 | public: |
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 38 | parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { | |
| 39 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_integral); | |
| 40 | __format_spec::__process_parsed_integer(__parser_); | |
| 37 | template <class _ParseContext> | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 39 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); | |
| 40 | __format_spec::__process_parsed_integer(__parser_, "an integer"); | |
| 41 | 41 | return __result; |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | template <integral _Tp> | |
| 45 | _LIBCPP_HIDE_FROM_ABI auto format(_Tp __value, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 44 | template <integral _Tp, class _FormatContext> | |
| 45 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_Tp __value, _FormatContext& __ctx) const { | |
| 46 | 46 | __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); |
| 47 | 47 | |
| 48 | 48 | if (__specs.__std_.__type_ == __format_spec::__type::__char) |
| 49 | 49 | return __formatter::__format_char(__value, __ctx.out(), __specs); |
| 50 | 50 | |
| 51 | 51 | using _Type = __make_32_64_or_128_bit_t<_Tp>; |
| 52 | static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format"); | |
| 52 | static_assert(!is_void<_Type>::value, "unsupported integral type used in __formatter_integer::__format"); | |
| 53 | 53 | |
| 54 | 54 | // Reduce the number of instantiation of the integer formatter |
| 55 | 55 | return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs); |
| ... | ... | @@ -60,47 +60,47 @@ public: |
| 60 | 60 | |
| 61 | 61 | // Signed integral types. |
| 62 | 62 | template <__fmt_char_type _CharT> |
| 63 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<signed char, _CharT> | |
| 63 | struct _LIBCPP_TEMPLATE_VIS formatter<signed char, _CharT> | |
| 64 | 64 | : public __formatter_integer<_CharT> {}; |
| 65 | 65 | template <__fmt_char_type _CharT> |
| 66 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<short, _CharT> : public __formatter_integer<_CharT> { | |
| 66 | struct _LIBCPP_TEMPLATE_VIS formatter<short, _CharT> : public __formatter_integer<_CharT> { | |
| 67 | 67 | }; |
| 68 | 68 | template <__fmt_char_type _CharT> |
| 69 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<int, _CharT> : public __formatter_integer<_CharT> {}; | |
| 69 | struct _LIBCPP_TEMPLATE_VIS formatter<int, _CharT> : public __formatter_integer<_CharT> {}; | |
| 70 | 70 | template <__fmt_char_type _CharT> |
| 71 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long, _CharT> : public __formatter_integer<_CharT> {}; | |
| 71 | struct _LIBCPP_TEMPLATE_VIS formatter<long, _CharT> : public __formatter_integer<_CharT> {}; | |
| 72 | 72 | template <__fmt_char_type _CharT> |
| 73 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<long long, _CharT> | |
| 73 | struct _LIBCPP_TEMPLATE_VIS formatter<long long, _CharT> | |
| 74 | 74 | : public __formatter_integer<_CharT> {}; |
| 75 | 75 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 76 | 76 | template <__fmt_char_type _CharT> |
| 77 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> | |
| 77 | struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> | |
| 78 | 78 | : public __formatter_integer<_CharT> {}; |
| 79 | 79 | # endif |
| 80 | 80 | |
| 81 | 81 | // Unsigned integral types. |
| 82 | 82 | template <__fmt_char_type _CharT> |
| 83 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned char, _CharT> | |
| 83 | struct _LIBCPP_TEMPLATE_VIS formatter<unsigned char, _CharT> | |
| 84 | 84 | : public __formatter_integer<_CharT> {}; |
| 85 | 85 | template <__fmt_char_type _CharT> |
| 86 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned short, _CharT> | |
| 86 | struct _LIBCPP_TEMPLATE_VIS formatter<unsigned short, _CharT> | |
| 87 | 87 | : public __formatter_integer<_CharT> {}; |
| 88 | 88 | template <__fmt_char_type _CharT> |
| 89 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned, _CharT> | |
| 89 | struct _LIBCPP_TEMPLATE_VIS formatter<unsigned, _CharT> | |
| 90 | 90 | : public __formatter_integer<_CharT> {}; |
| 91 | 91 | template <__fmt_char_type _CharT> |
| 92 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long, _CharT> | |
| 92 | struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long, _CharT> | |
| 93 | 93 | : public __formatter_integer<_CharT> {}; |
| 94 | 94 | template <__fmt_char_type _CharT> |
| 95 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<unsigned long long, _CharT> | |
| 95 | struct _LIBCPP_TEMPLATE_VIS formatter<unsigned long long, _CharT> | |
| 96 | 96 | : public __formatter_integer<_CharT> {}; |
| 97 | 97 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 98 | 98 | template <__fmt_char_type _CharT> |
| 99 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> | |
| 99 | struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> | |
| 100 | 100 | : public __formatter_integer<_CharT> {}; |
| 101 | 101 | # endif |
| 102 | 102 | |
| 103 | #endif //_LIBCPP_STD_VER > 17 | |
| 103 | #endif //_LIBCPP_STD_VER >= 20 | |
| 104 | 104 | |
| 105 | 105 | _LIBCPP_END_NAMESPACE_STD |
| 106 | 106 |
lib/libcxx/include/__format/formatter_integral.h+96-25| ... | ... | @@ -10,6 +10,9 @@ |
| 10 | 10 | #ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H |
| 11 | 11 | #define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H |
| 12 | 12 | |
| 13 | #include <__charconv/to_chars_integral.h> | |
| 14 | #include <__charconv/to_chars_result.h> | |
| 15 | #include <__charconv/traits.h> | |
| 13 | 16 | #include <__concepts/arithmetic.h> |
| 14 | 17 | #include <__concepts/same_as.h> |
| 15 | 18 | #include <__config> |
| ... | ... | @@ -17,11 +20,13 @@ |
| 17 | 20 | #include <__format/format_error.h> |
| 18 | 21 | #include <__format/formatter_output.h> |
| 19 | 22 | #include <__format/parser_std_format_spec.h> |
| 23 | #include <__system_error/errc.h> | |
| 24 | #include <__type_traits/make_unsigned.h> | |
| 20 | 25 | #include <__utility/unreachable.h> |
| 21 | 26 | #include <array> |
| 22 | #include <charconv> | |
| 23 | 27 | #include <limits> |
| 24 | 28 | #include <string> |
| 29 | #include <string_view> | |
| 25 | 30 | |
| 26 | 31 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION |
| 27 | 32 | # include <locale> |
| ... | ... | @@ -36,7 +41,7 @@ _LIBCPP_PUSH_MACROS |
| 36 | 41 | |
| 37 | 42 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 43 | |
| 39 | #if _LIBCPP_STD_VER > 17 | |
| 44 | #if _LIBCPP_STD_VER >= 20 | |
| 40 | 45 | |
| 41 | 46 | namespace __formatter { |
| 42 | 47 | |
| ... | ... | @@ -80,9 +85,9 @@ _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, _ |
| 80 | 85 | * regardless whether the @c std::numpunct's type is @c char or @c wchar_t. |
| 81 | 86 | */ |
| 82 | 87 | _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) { |
| 83 | _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0], | |
| 84 | "The slow grouping formatting is used while there will be no " | |
| 85 | "separators written"); | |
| 88 | _LIBCPP_ASSERT_UNCATEGORIZED(!__grouping.empty() && __size > __grouping[0], | |
| 89 | "The slow grouping formatting is used while there will be no " | |
| 90 | "separators written"); | |
| 86 | 91 | string __r; |
| 87 | 92 | auto __end = __grouping.end() - 1; |
| 88 | 93 | auto __ptr = __grouping.begin(); |
| ... | ... | @@ -149,7 +154,7 @@ _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value |
| 149 | 154 | // TODO FMT Evaluate code overhead due to not calling the internal function |
| 150 | 155 | // directly. (Should be zero overhead.) |
| 151 | 156 | to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base); |
| 152 | _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); | |
| 157 | _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); | |
| 153 | 158 | return __r.ptr; |
| 154 | 159 | } |
| 155 | 160 | |
| ... | ... | @@ -198,16 +203,82 @@ consteval size_t __buffer_size() noexcept |
| 198 | 203 | + 1; // Reserve space for the sign. |
| 199 | 204 | } |
| 200 | 205 | |
| 201 | template <unsigned_integral _Tp, class _CharT> | |
| 202 | _LIBCPP_HIDE_FROM_ABI auto __format_integer( | |
| 206 | template <class _OutIt, class _CharT> | |
| 207 | _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, | |
| 208 | const char* __last, string&& __grouping, _CharT __sep, | |
| 209 | __format_spec::__parsed_specifications<_CharT> __specs) { | |
| 210 | int __size = (__first - __begin) + // [sign][prefix] | |
| 211 | (__last - __first) + // data | |
| 212 | (__grouping.size() - 1); // number of separator characters | |
| 213 | ||
| 214 | __padding_size_result __padding = {0, 0}; | |
| 215 | if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { | |
| 216 | // Write [sign][prefix]. | |
| 217 | __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); | |
| 218 | ||
| 219 | if (__specs.__width_ > __size) { | |
| 220 | // Write zero padding. | |
| 221 | __padding.__before_ = __specs.__width_ - __size; | |
| 222 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0')); | |
| 223 | } | |
| 224 | } else { | |
| 225 | if (__specs.__width_ > __size) { | |
| 226 | // Determine padding and write padding. | |
| 227 | __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); | |
| 228 | ||
| 229 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); | |
| 230 | } | |
| 231 | // Write [sign][prefix]. | |
| 232 | __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); | |
| 233 | } | |
| 234 | ||
| 235 | auto __r = __grouping.rbegin(); | |
| 236 | auto __e = __grouping.rend() - 1; | |
| 237 | _LIBCPP_ASSERT_UNCATEGORIZED(__r != __e, "The slow grouping formatting is used while " | |
| 238 | "there will be no separators written."); | |
| 239 | // The output is divided in small groups of numbers to write: | |
| 240 | // - A group before the first separator. | |
| 241 | // - A separator and a group, repeated for the number of separators. | |
| 242 | // - A group after the last separator. | |
| 243 | // This loop achieves that process by testing the termination condition | |
| 244 | // midway in the loop. | |
| 245 | // | |
| 246 | // TODO FMT This loop evaluates the loop invariant `__parser.__type != | |
| 247 | // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test | |
| 248 | // happens in the __write call.) Benchmark whether making two loops and | |
| 249 | // hoisting the invariant is worth the effort. | |
| 250 | while (true) { | |
| 251 | if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { | |
| 252 | __last = __first + *__r; | |
| 253 | __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper); | |
| 254 | __first = __last; | |
| 255 | } else { | |
| 256 | __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); | |
| 257 | __first += *__r; | |
| 258 | } | |
| 259 | ||
| 260 | if (__r == __e) | |
| 261 | break; | |
| 262 | ||
| 263 | ++__r; | |
| 264 | *__out_it++ = __sep; | |
| 265 | } | |
| 266 | ||
| 267 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); | |
| 268 | } | |
| 269 | ||
| 270 | ||
| 271 | ||
| 272 | template <unsigned_integral _Tp, class _CharT, class _FormatContext> | |
| 273 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer( | |
| 203 | 274 | _Tp __value, |
| 204 | auto& __ctx, | |
| 275 | _FormatContext& __ctx, | |
| 205 | 276 | __format_spec::__parsed_specifications<_CharT> __specs, |
| 206 | 277 | bool __negative, |
| 207 | 278 | char* __begin, |
| 208 | 279 | char* __end, |
| 209 | 280 | const char* __prefix, |
| 210 | int __base) -> decltype(__ctx.out()) { | |
| 281 | int __base) { | |
| 211 | 282 | char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); |
| 212 | 283 | if (__specs.__std_.__alternate_form_ && __prefix) |
| 213 | 284 | while (*__prefix) |
| ... | ... | @@ -246,7 +317,7 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer( |
| 246 | 317 | // - Write data right aligned with '0' as fill character. |
| 247 | 318 | __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); |
| 248 | 319 | __specs.__alignment_ = __format_spec::__alignment::__right; |
| 249 | __specs.__fill_ = _CharT('0'); | |
| 320 | __specs.__fill_.__data[0] = _CharT('0'); | |
| 250 | 321 | int32_t __size = __first - __begin; |
| 251 | 322 | |
| 252 | 323 | __specs.__width_ -= _VSTD::min(__size, __specs.__width_); |
| ... | ... | @@ -258,10 +329,12 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer( |
| 258 | 329 | return __formatter::__write_transformed(__first, __last, __ctx.out(), __specs, __formatter::__hex_to_upper); |
| 259 | 330 | } |
| 260 | 331 | |
| 261 | template <unsigned_integral _Tp, class _CharT> | |
| 262 | _LIBCPP_HIDE_FROM_ABI auto __format_integer( | |
| 263 | _Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative = false) | |
| 264 | -> decltype(__ctx.out()) { | |
| 332 | template <unsigned_integral _Tp, class _CharT, class _FormatContext> | |
| 333 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 334 | __format_integer(_Tp __value, | |
| 335 | _FormatContext& __ctx, | |
| 336 | __format_spec::__parsed_specifications<_CharT> __specs, | |
| 337 | bool __negative = false) { | |
| 265 | 338 | switch (__specs.__std_.__type_) { |
| 266 | 339 | case __format_spec::__type::__binary_lower_case: { |
| 267 | 340 | array<char, __formatter::__buffer_size<decltype(__value), 2>()> __array; |
| ... | ... | @@ -292,15 +365,14 @@ _LIBCPP_HIDE_FROM_ABI auto __format_integer( |
| 292 | 365 | return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16); |
| 293 | 366 | } |
| 294 | 367 | default: |
| 295 | _LIBCPP_ASSERT(false, "The parse function should have validated the type"); | |
| 368 | _LIBCPP_ASSERT_UNCATEGORIZED(false, "The parse function should have validated the type"); | |
| 296 | 369 | __libcpp_unreachable(); |
| 297 | 370 | } |
| 298 | 371 | } |
| 299 | 372 | |
| 300 | template <signed_integral _Tp, class _CharT> | |
| 301 | _LIBCPP_HIDE_FROM_ABI auto | |
| 302 | __format_integer(_Tp __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) | |
| 303 | -> decltype(__ctx.out()) { | |
| 373 | template <signed_integral _Tp, class _CharT, class _FormatContext> | |
| 374 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 375 | __format_integer(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) { | |
| 304 | 376 | // Depending on the std-format-spec string the sign and the value |
| 305 | 377 | // might not be outputted together: |
| 306 | 378 | // - alternate form may insert a prefix string. |
| ... | ... | @@ -336,10 +408,9 @@ struct _LIBCPP_TEMPLATE_VIS __bool_strings<wchar_t> { |
| 336 | 408 | }; |
| 337 | 409 | # endif |
| 338 | 410 | |
| 339 | template <class _CharT> | |
| 340 | _LIBCPP_HIDE_FROM_ABI auto | |
| 341 | __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) | |
| 342 | -> decltype(__ctx.out()) { | |
| 411 | template <class _CharT, class _FormatContext> | |
| 412 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 413 | __format_bool(bool __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) { | |
| 343 | 414 | # ifndef _LIBCPP_HAS_NO_LOCALIZATION |
| 344 | 415 | if (__specs.__std_.__locale_specific_form_) { |
| 345 | 416 | const auto& __np = std::use_facet<numpunct<_CharT>>(__ctx.locale()); |
| ... | ... | @@ -354,7 +425,7 @@ __format_bool(bool __value, auto& __ctx, __format_spec::__parsed_specifications< |
| 354 | 425 | |
| 355 | 426 | } // namespace __formatter |
| 356 | 427 | |
| 357 | #endif //_LIBCPP_STD_VER > 17 | |
| 428 | #endif //_LIBCPP_STD_VER >= 20 | |
| 358 | 429 | |
| 359 | 430 | _LIBCPP_END_NAMESPACE_STD |
| 360 | 431 |
lib/libcxx/include/__format/formatter_output.h+58-308| ... | ... | @@ -13,22 +13,21 @@ |
| 13 | 13 | #include <__algorithm/ranges_copy.h> |
| 14 | 14 | #include <__algorithm/ranges_fill_n.h> |
| 15 | 15 | #include <__algorithm/ranges_transform.h> |
| 16 | #include <__chrono/statically_widen.h> | |
| 16 | #include <__bit/countl.h> | |
| 17 | 17 | #include <__concepts/same_as.h> |
| 18 | 18 | #include <__config> |
| 19 | 19 | #include <__format/buffer.h> |
| 20 | 20 | #include <__format/concepts.h> |
| 21 | #include <__format/escaped_output_table.h> | |
| 22 | 21 | #include <__format/formatter.h> |
| 23 | 22 | #include <__format/parser_std_format_spec.h> |
| 24 | 23 | #include <__format/unicode.h> |
| 25 | 24 | #include <__iterator/back_insert_iterator.h> |
| 26 | #include <__type_traits/make_unsigned.h> | |
| 25 | #include <__iterator/concepts.h> | |
| 26 | #include <__iterator/iterator_traits.h> // iter_value_t | |
| 27 | #include <__memory/addressof.h> | |
| 27 | 28 | #include <__utility/move.h> |
| 28 | 29 | #include <__utility/unreachable.h> |
| 29 | #include <charconv> | |
| 30 | 30 | #include <cstddef> |
| 31 | #include <string> | |
| 32 | 31 | #include <string_view> |
| 33 | 32 | |
| 34 | 33 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -37,7 +36,7 @@ |
| 37 | 36 | |
| 38 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 38 | |
| 40 | #if _LIBCPP_STD_VER > 17 | |
| 39 | #if _LIBCPP_STD_VER >= 20 | |
| 41 | 40 | |
| 42 | 41 | namespace __formatter { |
| 43 | 42 | |
| ... | ... | @@ -59,15 +58,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) { |
| 59 | 58 | return __c; |
| 60 | 59 | } |
| 61 | 60 | |
| 62 | struct _LIBCPP_TYPE_VIS __padding_size_result { | |
| 61 | struct _LIBCPP_EXPORTED_FROM_ABI __padding_size_result { | |
| 63 | 62 | size_t __before_; |
| 64 | 63 | size_t __after_; |
| 65 | 64 | }; |
| 66 | 65 | |
| 67 | 66 | _LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result |
| 68 | 67 | __padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) { |
| 69 | _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required"); | |
| 70 | _LIBCPP_ASSERT( | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED(__width > __size, "don't call this function when no padding is required"); | |
| 69 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 71 | 70 | __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding"); |
| 72 | 71 | |
| 73 | 72 | size_t __fill = __width - __size; |
| ... | ... | @@ -161,69 +160,45 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value) |
| 161 | 160 | } |
| 162 | 161 | } |
| 163 | 162 | |
| 164 | template <class _OutIt, class _CharT> | |
| 165 | _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, | |
| 166 | const char* __last, string&& __grouping, _CharT __sep, | |
| 167 | __format_spec::__parsed_specifications<_CharT> __specs) { | |
| 168 | int __size = (__first - __begin) + // [sign][prefix] | |
| 169 | (__last - __first) + // data | |
| 170 | (__grouping.size() - 1); // number of separator characters | |
| 171 | ||
| 172 | __padding_size_result __padding = {0, 0}; | |
| 173 | if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { | |
| 174 | // Write [sign][prefix]. | |
| 175 | __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); | |
| 176 | ||
| 177 | if (__specs.__width_ > __size) { | |
| 178 | // Write zero padding. | |
| 179 | __padding.__before_ = __specs.__width_ - __size; | |
| 180 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0')); | |
| 181 | } | |
| 182 | } else { | |
| 183 | if (__specs.__width_ > __size) { | |
| 184 | // Determine padding and write padding. | |
| 185 | __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); | |
| 186 | ||
| 187 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); | |
| 188 | } | |
| 189 | // Write [sign][prefix]. | |
| 190 | __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); | |
| 191 | } | |
| 163 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 164 | template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt> | |
| 165 | requires(same_as<_CharT, char>) | |
| 166 | _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) { | |
| 167 | std::size_t __bytes = std::countl_one(static_cast<unsigned char>(__value.__data[0])); | |
| 168 | if (__bytes == 0) | |
| 169 | return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]); | |
| 170 | ||
| 171 | for (size_t __i = 0; __i < __n; ++__i) | |
| 172 | __out_it = __formatter::__copy( | |
| 173 | std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + __bytes, std::move(__out_it)); | |
| 174 | return __out_it; | |
| 175 | } | |
| 192 | 176 | |
| 193 | auto __r = __grouping.rbegin(); | |
| 194 | auto __e = __grouping.rend() - 1; | |
| 195 | _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while " | |
| 196 | "there will be no separators written."); | |
| 197 | // The output is divided in small groups of numbers to write: | |
| 198 | // - A group before the first separator. | |
| 199 | // - A separator and a group, repeated for the number of separators. | |
| 200 | // - A group after the last separator. | |
| 201 | // This loop achieves that process by testing the termination condition | |
| 202 | // midway in the loop. | |
| 203 | // | |
| 204 | // TODO FMT This loop evaluates the loop invariant `__parser.__type != | |
| 205 | // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test | |
| 206 | // happens in the __write call.) Benchmark whether making two loops and | |
| 207 | // hoisting the invariant is worth the effort. | |
| 208 | while (true) { | |
| 209 | if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { | |
| 210 | __last = __first + *__r; | |
| 211 | __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper); | |
| 212 | __first = __last; | |
| 213 | } else { | |
| 214 | __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); | |
| 215 | __first += *__r; | |
| 216 | } | |
| 217 | ||
| 218 | if (__r == __e) | |
| 219 | break; | |
| 220 | ||
| 221 | ++__r; | |
| 222 | *__out_it++ = __sep; | |
| 223 | } | |
| 177 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 178 | template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt> | |
| 179 | requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) | |
| 180 | _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) { | |
| 181 | if (!__unicode::__is_high_surrogate(__value.__data[0])) | |
| 182 | return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]); | |
| 183 | ||
| 184 | for (size_t __i = 0; __i < __n; ++__i) | |
| 185 | __out_it = __formatter::__copy( | |
| 186 | std::addressof(__value.__data[0]), std::addressof(__value.__data[0]) + 2, std::move(__out_it)); | |
| 187 | return __out_it; | |
| 188 | } | |
| 224 | 189 | |
| 225 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); | |
| 190 | template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt> | |
| 191 | requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) | |
| 192 | _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) { | |
| 193 | return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]); | |
| 226 | 194 | } |
| 195 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 196 | # else // _LIBCPP_HAS_NO_UNICODE | |
| 197 | template <__fmt_char_type _CharT, output_iterator<const _CharT&> _OutIt> | |
| 198 | _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec::__code_point<_CharT> __value) { | |
| 199 | return __formatter::__fill(std::move(__out_it), __n, __value.__data[0]); | |
| 200 | } | |
| 201 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 227 | 202 | |
| 228 | 203 | /// Writes the input to the output with the required padding. |
| 229 | 204 | /// |
| ... | ... | @@ -261,27 +236,27 @@ __write(basic_string_view<_CharT> __str, |
| 261 | 236 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); |
| 262 | 237 | } |
| 263 | 238 | |
| 264 | template <class _CharT, class _ParserCharT> | |
| 239 | template <contiguous_iterator _Iterator, class _ParserCharT> | |
| 265 | 240 | _LIBCPP_HIDE_FROM_ABI auto |
| 266 | __write(const _CharT* __first, | |
| 267 | const _CharT* __last, | |
| 268 | output_iterator<const _CharT&> auto __out_it, | |
| 241 | __write(_Iterator __first, | |
| 242 | _Iterator __last, | |
| 243 | output_iterator<const iter_value_t<_Iterator>&> auto __out_it, | |
| 269 | 244 | __format_spec::__parsed_specifications<_ParserCharT> __specs, |
| 270 | 245 | ptrdiff_t __size) -> decltype(__out_it) { |
| 271 | _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); | |
| 246 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); | |
| 272 | 247 | return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size); |
| 273 | 248 | } |
| 274 | 249 | |
| 275 | 250 | /// \overload |
| 276 | 251 | /// |
| 277 | 252 | /// Calls the function above where \a __size = \a __last - \a __first. |
| 278 | template <class _CharT, class _ParserCharT> | |
| 253 | template <contiguous_iterator _Iterator, class _ParserCharT> | |
| 279 | 254 | _LIBCPP_HIDE_FROM_ABI auto |
| 280 | __write(const _CharT* __first, | |
| 281 | const _CharT* __last, | |
| 282 | output_iterator<const _CharT&> auto __out_it, | |
| 255 | __write(_Iterator __first, | |
| 256 | _Iterator __last, | |
| 257 | output_iterator<const iter_value_t<_Iterator>&> auto __out_it, | |
| 283 | 258 | __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) { |
| 284 | _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); | |
| 259 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); | |
| 285 | 260 | return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first); |
| 286 | 261 | } |
| 287 | 262 | |
| ... | ... | @@ -290,7 +265,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha |
| 290 | 265 | output_iterator<const _CharT&> auto __out_it, |
| 291 | 266 | __format_spec::__parsed_specifications<_ParserCharT> __specs, |
| 292 | 267 | _UnaryOperation __op) -> decltype(__out_it) { |
| 293 | _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); | |
| 268 | _LIBCPP_ASSERT_UNCATEGORIZED(__first <= __last, "Not a valid range"); | |
| 294 | 269 | |
| 295 | 270 | ptrdiff_t __size = __last - __first; |
| 296 | 271 | if (__size >= __specs.__width_) |
| ... | ... | @@ -302,35 +277,6 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha |
| 302 | 277 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); |
| 303 | 278 | } |
| 304 | 279 | |
| 305 | /// Writes additional zero's for the precision before the exponent. | |
| 306 | /// This is used when the precision requested in the format string is larger | |
| 307 | /// than the maximum precision of the floating-point type. These precision | |
| 308 | /// digits are always 0. | |
| 309 | /// | |
| 310 | /// \param __exponent The location of the exponent character. | |
| 311 | /// \param __num_trailing_zeros The number of 0's to write before the exponent | |
| 312 | /// character. | |
| 313 | template <class _CharT, class _ParserCharT> | |
| 314 | _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( | |
| 315 | const _CharT* __first, | |
| 316 | const _CharT* __last, | |
| 317 | output_iterator<const _CharT&> auto __out_it, | |
| 318 | __format_spec::__parsed_specifications<_ParserCharT> __specs, | |
| 319 | size_t __size, | |
| 320 | const _CharT* __exponent, | |
| 321 | size_t __num_trailing_zeros) -> decltype(__out_it) { | |
| 322 | _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); | |
| 323 | _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); | |
| 324 | ||
| 325 | __padding_size_result __padding = | |
| 326 | __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); | |
| 327 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); | |
| 328 | __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it)); | |
| 329 | __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); | |
| 330 | __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it)); | |
| 331 | return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); | |
| 332 | } | |
| 333 | ||
| 334 | 280 | /// Writes a string using format's width estimation algorithm. |
| 335 | 281 | /// |
| 336 | 282 | /// \pre !__specs.__has_precision() |
| ... | ... | @@ -342,7 +288,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( |
| 342 | 288 | basic_string_view<_CharT> __str, |
| 343 | 289 | output_iterator<const _CharT&> auto __out_it, |
| 344 | 290 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { |
| 345 | _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string"); | |
| 291 | _LIBCPP_ASSERT_UNCATEGORIZED(!__specs.__has_precision(), "use __write_string"); | |
| 346 | 292 | |
| 347 | 293 | // No padding -> copy the string |
| 348 | 294 | if (!__specs.__has_width()) |
| ... | ... | @@ -359,211 +305,15 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( |
| 359 | 305 | |
| 360 | 306 | template <class _CharT> |
| 361 | 307 | _LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) { |
| 362 | __format_spec::__column_width_result<_CharT> __result = | |
| 308 | __format_spec::__column_width_result __result = | |
| 363 | 309 | __format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down); |
| 364 | 310 | __str = basic_string_view<_CharT>{__str.begin(), __result.__last_}; |
| 365 | 311 | return __result.__width_; |
| 366 | 312 | } |
| 367 | 313 | |
| 368 | /// Writes a string using format's width estimation algorithm. | |
| 369 | /// | |
| 370 | /// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the | |
| 371 | /// input is ASCII. | |
| 372 | template <class _CharT> | |
| 373 | _LIBCPP_HIDE_FROM_ABI auto __write_string( | |
| 374 | basic_string_view<_CharT> __str, | |
| 375 | output_iterator<const _CharT&> auto __out_it, | |
| 376 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 377 | if (!__specs.__has_precision()) | |
| 378 | return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs); | |
| 379 | ||
| 380 | int __size = __formatter::__truncate(__str, __specs.__precision_); | |
| 381 | ||
| 382 | return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); | |
| 383 | } | |
| 384 | ||
| 385 | # if _LIBCPP_STD_VER > 20 | |
| 386 | ||
| 387 | struct __nul_terminator {}; | |
| 388 | ||
| 389 | template <class _CharT> | |
| 390 | _LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { | |
| 391 | return *__cstr == _CharT('\0'); | |
| 392 | } | |
| 393 | ||
| 394 | template <class _CharT> | |
| 395 | _LIBCPP_HIDE_FROM_ABI void | |
| 396 | __write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { | |
| 397 | back_insert_iterator __out_it{__str}; | |
| 398 | std::ranges::copy(__prefix, __nul_terminator{}, __out_it); | |
| 399 | ||
| 400 | char __buffer[8]; | |
| 401 | to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); | |
| 402 | _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); | |
| 403 | std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); | |
| 404 | ||
| 405 | __str += _CharT('}'); | |
| 406 | } | |
| 407 | ||
| 408 | // [format.string.escaped]/2.2.1.2 | |
| 409 | // ... | |
| 410 | // then the sequence \u{hex-digit-sequence} is appended to E, where | |
| 411 | // hex-digit-sequence is the shortest hexadecimal representation of C using | |
| 412 | // lower-case hexadecimal digits. | |
| 413 | template <class _CharT> | |
| 414 | _LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { | |
| 415 | __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); | |
| 416 | } | |
| 417 | ||
| 418 | // [format.string.escaped]/2.2.3 | |
| 419 | // Otherwise (X is a sequence of ill-formed code units), each code unit U is | |
| 420 | // appended to E in order as the sequence \x{hex-digit-sequence}, where | |
| 421 | // hex-digit-sequence is the shortest hexadecimal representation of U using | |
| 422 | // lower-case hexadecimal digits. | |
| 423 | template <class _CharT> | |
| 424 | _LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { | |
| 425 | __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); | |
| 426 | } | |
| 427 | ||
| 428 | template <class _CharT> | |
| 429 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { | |
| 430 | # ifdef _LIBCPP_HAS_NO_UNICODE | |
| 431 | // For ASCII assume everything above 127 is printable. | |
| 432 | if (__value > 127) | |
| 433 | return false; | |
| 434 | # endif | |
| 435 | ||
| 436 | if (!__escaped_output_table::__needs_escape(__value)) | |
| 437 | return false; | |
| 438 | ||
| 439 | __formatter::__write_well_formed_escaped_code_unit(__str, __value); | |
| 440 | return true; | |
| 441 | } | |
| 442 | ||
| 443 | template <class _CharT> | |
| 444 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { | |
| 445 | return static_cast<make_unsigned_t<_CharT>>(__value); | |
| 446 | } | |
| 447 | ||
| 448 | enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote }; | |
| 449 | ||
| 450 | // [format.string.escaped]/2 | |
| 451 | template <class _CharT> | |
| 452 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool | |
| 453 | __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) { | |
| 454 | // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] | |
| 455 | switch (__value) { | |
| 456 | case _CharT('\t'): | |
| 457 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); | |
| 458 | return true; | |
| 459 | case _CharT('\n'): | |
| 460 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); | |
| 461 | return true; | |
| 462 | case _CharT('\r'): | |
| 463 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); | |
| 464 | return true; | |
| 465 | case _CharT('\''): | |
| 466 | if (__mark == __escape_quotation_mark::__apostrophe) | |
| 467 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); | |
| 468 | else | |
| 469 | __str += __value; | |
| 470 | return true; | |
| 471 | case _CharT('"'): | |
| 472 | if (__mark == __escape_quotation_mark::__double_quote) | |
| 473 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); | |
| 474 | else | |
| 475 | __str += __value; | |
| 476 | return true; | |
| 477 | case _CharT('\\'): | |
| 478 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); | |
| 479 | return true; | |
| 480 | ||
| 481 | // 2.2.1.2 - Space | |
| 482 | case _CharT(' '): | |
| 483 | __str += __value; | |
| 484 | return true; | |
| 485 | } | |
| 486 | ||
| 487 | // 2.2.2 | |
| 488 | // Otherwise, if X is a shift sequence, the effect on E and further | |
| 489 | // decoding of S is unspecified. | |
| 490 | // For now shift sequences are ignored and treated as Unicode. Other parts | |
| 491 | // of the format library do the same. It's unknown how ostream treats them. | |
| 492 | // TODO FMT determine what to do with shift sequences. | |
| 493 | ||
| 494 | // 2.2.1.2.1 and 2.2.1.2.2 - Escape | |
| 495 | return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value)); | |
| 496 | } | |
| 497 | ||
| 498 | template <class _CharT> | |
| 499 | _LIBCPP_HIDE_FROM_ABI void | |
| 500 | __escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { | |
| 501 | __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; | |
| 502 | ||
| 503 | while (!__view.__at_end()) { | |
| 504 | const _CharT* __first = __view.__position(); | |
| 505 | typename __unicode::__consume_p2286_result __result = __view.__consume_p2286(); | |
| 506 | if (__result.__ill_formed_size == 0) { | |
| 507 | if (!__formatter::__is_escaped_sequence_written(__str, __result.__value, __mark)) | |
| 508 | // 2.2.1.3 - Add the character | |
| 509 | ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); | |
| 510 | ||
| 511 | } else { | |
| 512 | // 2.2.3 sequence of ill-formed code units | |
| 513 | // The number of code-units in __result.__value depends on the character type being used. | |
| 514 | if constexpr (sizeof(_CharT) == 1) { | |
| 515 | _LIBCPP_ASSERT(__result.__ill_formed_size == 1 || __result.__ill_formed_size == 4, | |
| 516 | "illegal number of invalid code units."); | |
| 517 | if (__result.__ill_formed_size == 1) // ill-formed, one code unit | |
| 518 | __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xff); | |
| 519 | else { // out of valid range, four code units | |
| 520 | // The code point was properly encoded, decode the value. | |
| 521 | __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value >> 18 | 0xf0); | |
| 522 | __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 12 & 0x3f) | 0x80); | |
| 523 | __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value >> 6 & 0x3f) | 0x80); | |
| 524 | __formatter::__write_escape_ill_formed_code_unit(__str, (__result.__value & 0x3f) | 0x80); | |
| 525 | } | |
| 526 | } else if constexpr (sizeof(_CharT) == 2) { | |
| 527 | _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-16 at most one invalid code unit"); | |
| 528 | __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value & 0xffff); | |
| 529 | } else { | |
| 530 | static_assert(sizeof(_CharT) == 4, "unsupported character width"); | |
| 531 | _LIBCPP_ASSERT(__result.__ill_formed_size == 1, "for UTF-32 one code unit is one code point"); | |
| 532 | __formatter::__write_escape_ill_formed_code_unit(__str, __result.__value); | |
| 533 | } | |
| 534 | } | |
| 535 | } | |
| 536 | } | |
| 537 | ||
| 538 | template <class _CharT> | |
| 539 | _LIBCPP_HIDE_FROM_ABI auto | |
| 540 | __format_escaped_char(_CharT __value, | |
| 541 | output_iterator<const _CharT&> auto __out_it, | |
| 542 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 543 | basic_string<_CharT> __str; | |
| 544 | __str += _CharT('\''); | |
| 545 | __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); | |
| 546 | __str += _CharT('\''); | |
| 547 | return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size()); | |
| 548 | } | |
| 549 | ||
| 550 | template <class _CharT> | |
| 551 | _LIBCPP_HIDE_FROM_ABI auto | |
| 552 | __format_escaped_string(basic_string_view<_CharT> __values, | |
| 553 | output_iterator<const _CharT&> auto __out_it, | |
| 554 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 555 | basic_string<_CharT> __str; | |
| 556 | __str += _CharT('"'); | |
| 557 | __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); | |
| 558 | __str += _CharT('"'); | |
| 559 | return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs); | |
| 560 | } | |
| 561 | ||
| 562 | # endif // _LIBCPP_STD_VER > 20 | |
| 563 | ||
| 564 | 314 | } // namespace __formatter |
| 565 | 315 | |
| 566 | #endif //_LIBCPP_STD_VER > 17 | |
| 316 | #endif //_LIBCPP_STD_VER >= 20 | |
| 567 | 317 | |
| 568 | 318 | _LIBCPP_END_NAMESPACE_STD |
| 569 | 319 |
lib/libcxx/include/__format/formatter_pointer.h+16-13| ... | ... | @@ -27,24 +27,27 @@ |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | template <__fmt_char_type _CharT> |
| 33 | 33 | struct _LIBCPP_TEMPLATE_VIS __formatter_pointer { |
| 34 | 34 | public: |
| 35 | constexpr __formatter_pointer() { __parser_.__alignment_ = __format_spec::__alignment::__right; } | |
| 36 | ||
| 37 | _LIBCPP_HIDE_FROM_ABI constexpr auto | |
| 38 | parse(basic_format_parse_context<_CharT>& __parse_ctx) -> decltype(__parse_ctx.begin()) { | |
| 39 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_pointer); | |
| 40 | __format_spec::__process_display_type_pointer(__parser_.__type_); | |
| 35 | template <class _ParseContext> | |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 37 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_pointer); | |
| 38 | __format_spec::__process_display_type_pointer(__parser_.__type_, "a pointer"); | |
| 41 | 39 | return __result; |
| 42 | 40 | } |
| 43 | 41 | |
| 44 | _LIBCPP_HIDE_FROM_ABI auto format(const void* __ptr, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 42 | template <class _FormatContext> | |
| 43 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const void* __ptr, _FormatContext& __ctx) const { | |
| 45 | 44 | __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); |
| 46 | 45 | __specs.__std_.__alternate_form_ = true; |
| 47 | __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; | |
| 46 | __specs.__std_.__type_ = | |
| 47 | __specs.__std_.__type_ == __format_spec::__type::__pointer_upper_case | |
| 48 | ? __format_spec::__type::__hexadecimal_upper_case | |
| 49 | : __format_spec::__type::__hexadecimal_lower_case; | |
| 50 | ||
| 48 | 51 | return __formatter::__format_integer(reinterpret_cast<uintptr_t>(__ptr), __ctx, __specs); |
| 49 | 52 | } |
| 50 | 53 | |
| ... | ... | @@ -57,16 +60,16 @@ public: |
| 57 | 60 | // - template<> struct formatter<void*, charT>; |
| 58 | 61 | // - template<> struct formatter<const void*, charT>; |
| 59 | 62 | template <__fmt_char_type _CharT> |
| 60 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<nullptr_t, _CharT> | |
| 63 | struct _LIBCPP_TEMPLATE_VIS formatter<nullptr_t, _CharT> | |
| 61 | 64 | : public __formatter_pointer<_CharT> {}; |
| 62 | 65 | template <__fmt_char_type _CharT> |
| 63 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<void*, _CharT> : public __formatter_pointer<_CharT> { | |
| 66 | struct _LIBCPP_TEMPLATE_VIS formatter<void*, _CharT> : public __formatter_pointer<_CharT> { | |
| 64 | 67 | }; |
| 65 | 68 | template <__fmt_char_type _CharT> |
| 66 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const void*, _CharT> | |
| 69 | struct _LIBCPP_TEMPLATE_VIS formatter<const void*, _CharT> | |
| 67 | 70 | : public __formatter_pointer<_CharT> {}; |
| 68 | 71 | |
| 69 | #endif //_LIBCPP_STD_VER > 17 | |
| 72 | #endif //_LIBCPP_STD_VER >= 20 | |
| 70 | 73 | |
| 71 | 74 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 75 |
lib/libcxx/include/__format/formatter_string.h+32-35| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | #include <__format/formatter.h> |
| 18 | 18 | #include <__format/formatter_output.h> |
| 19 | 19 | #include <__format/parser_std_format_spec.h> |
| 20 | #include <__utility/move.h> | |
| 20 | #include <__format/write_escaped.h> | |
| 21 | 21 | #include <string> |
| 22 | 22 | #include <string_view> |
| 23 | 23 | |
| ... | ... | @@ -27,20 +27,22 @@ |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | template <__fmt_char_type _CharT> |
| 33 | 33 | struct _LIBCPP_TEMPLATE_VIS __formatter_string { |
| 34 | 34 | public: |
| 35 | _LIBCPP_HIDE_FROM_ABI constexpr auto parse(basic_format_parse_context<_CharT>& __parse_ctx) | |
| 36 | -> decltype(__parse_ctx.begin()) { | |
| 37 | auto __result = __parser_.__parse(__parse_ctx, __format_spec::__fields_string); | |
| 35 | template <class _ParseContext> | |
| 36 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 37 | typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_string); | |
| 38 | 38 | __format_spec::__process_display_type_string(__parser_.__type_); |
| 39 | 39 | return __result; |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT> __str, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 43 | # if _LIBCPP_STD_VER > 20 | |
| 42 | template <class _FormatContext> | |
| 43 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 44 | format(basic_string_view<_CharT> __str, _FormatContext& __ctx) const { | |
| 45 | # if _LIBCPP_STD_VER >= 23 | |
| 44 | 46 | if (__parser_.__type_ == __format_spec::__type::__debug) |
| 45 | 47 | return __formatter::__format_escaped_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); |
| 46 | 48 | # endif |
| ... | ... | @@ -48,7 +50,7 @@ public: |
| 48 | 50 | return __formatter::__write_string(__str, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); |
| 49 | 51 | } |
| 50 | 52 | |
| 51 | # if _LIBCPP_STD_VER > 20 | |
| 53 | # if _LIBCPP_STD_VER >= 23 | |
| 52 | 54 | _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } |
| 53 | 55 | # endif |
| 54 | 56 | |
| ... | ... | @@ -57,16 +59,17 @@ public: |
| 57 | 59 | |
| 58 | 60 | // Formatter const char*. |
| 59 | 61 | template <__fmt_char_type _CharT> |
| 60 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, _CharT> | |
| 62 | struct _LIBCPP_TEMPLATE_VIS formatter<const _CharT*, _CharT> | |
| 61 | 63 | : public __formatter_string<_CharT> { |
| 62 | 64 | using _Base = __formatter_string<_CharT>; |
| 63 | 65 | |
| 64 | _LIBCPP_HIDE_FROM_ABI auto format(const _CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 65 | _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have " | |
| 66 | "prevented an invalid pointer."); | |
| 66 | template <class _FormatContext> | |
| 67 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const { | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED(__str, "The basic_format_arg constructor should have " | |
| 69 | "prevented an invalid pointer."); | |
| 67 | 70 | |
| 68 | 71 | __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); |
| 69 | # if _LIBCPP_STD_VER > 20 | |
| 72 | # if _LIBCPP_STD_VER >= 23 | |
| 70 | 73 | if (_Base::__parser_.__type_ == __format_spec::__type::__debug) |
| 71 | 74 | return __formatter::__format_escaped_string(basic_string_view<_CharT>{__str}, __ctx.out(), __specs); |
| 72 | 75 | # endif |
| ... | ... | @@ -95,45 +98,38 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT*, |
| 95 | 98 | |
| 96 | 99 | // Formatter char*. |
| 97 | 100 | template <__fmt_char_type _CharT> |
| 98 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT*, _CharT> | |
| 101 | struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> | |
| 99 | 102 | : public formatter<const _CharT*, _CharT> { |
| 100 | 103 | using _Base = formatter<const _CharT*, _CharT>; |
| 101 | 104 | |
| 102 | _LIBCPP_HIDE_FROM_ABI auto format(_CharT* __str, auto& __ctx) const -> decltype(__ctx.out()) { | |
| 105 | template <class _FormatContext> | |
| 106 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT* __str, _FormatContext& __ctx) const { | |
| 103 | 107 | return _Base::format(__str, __ctx); |
| 104 | 108 | } |
| 105 | 109 | }; |
| 106 | 110 | |
| 107 | 111 | // Formatter char[]. |
| 108 | 112 | template <__fmt_char_type _CharT, size_t _Size> |
| 109 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_CharT[_Size], _CharT> | |
| 113 | struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> | |
| 110 | 114 | : public __formatter_string<_CharT> { |
| 111 | 115 | using _Base = __formatter_string<_CharT>; |
| 112 | 116 | |
| 113 | _LIBCPP_HIDE_FROM_ABI auto format(_CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { | |
| 114 | return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); | |
| 115 | } | |
| 116 | }; | |
| 117 | ||
| 118 | // Formatter const char[]. | |
| 119 | template <__fmt_char_type _CharT, size_t _Size> | |
| 120 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<const _CharT[_Size], _CharT> | |
| 121 | : public __formatter_string<_CharT> { | |
| 122 | using _Base = __formatter_string<_CharT>; | |
| 123 | ||
| 124 | _LIBCPP_HIDE_FROM_ABI auto format(const _CharT __str[_Size], auto& __ctx) const -> decltype(__ctx.out()) { | |
| 117 | template <class _FormatContext> | |
| 118 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 119 | format(const _CharT (&__str)[_Size], _FormatContext& __ctx) const { | |
| 125 | 120 | return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); |
| 126 | 121 | } |
| 127 | 122 | }; |
| 128 | 123 | |
| 129 | 124 | // Formatter std::string. |
| 130 | 125 | template <__fmt_char_type _CharT, class _Traits, class _Allocator> |
| 131 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT> | |
| 126 | struct _LIBCPP_TEMPLATE_VIS formatter<basic_string<_CharT, _Traits, _Allocator>, _CharT> | |
| 132 | 127 | : public __formatter_string<_CharT> { |
| 133 | 128 | using _Base = __formatter_string<_CharT>; |
| 134 | 129 | |
| 135 | _LIBCPP_HIDE_FROM_ABI auto format(const basic_string<_CharT, _Traits, _Allocator>& __str, auto& __ctx) const | |
| 136 | -> decltype(__ctx.out()) { | |
| 130 | template <class _FormatContext> | |
| 131 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 132 | format(const basic_string<_CharT, _Traits, _Allocator>& __str, _FormatContext& __ctx) const { | |
| 137 | 133 | // Drop _Traits and _Allocator to have one std::basic_string formatter. |
| 138 | 134 | return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); |
| 139 | 135 | } |
| ... | ... | @@ -141,18 +137,19 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string<_ |
| 141 | 137 | |
| 142 | 138 | // Formatter std::string_view. |
| 143 | 139 | template <__fmt_char_type _CharT, class _Traits> |
| 144 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<basic_string_view<_CharT, _Traits>, _CharT> | |
| 140 | struct _LIBCPP_TEMPLATE_VIS formatter<basic_string_view<_CharT, _Traits>, _CharT> | |
| 145 | 141 | : public __formatter_string<_CharT> { |
| 146 | 142 | using _Base = __formatter_string<_CharT>; |
| 147 | 143 | |
| 148 | _LIBCPP_HIDE_FROM_ABI auto format(basic_string_view<_CharT, _Traits> __str, auto& __ctx) const | |
| 149 | -> decltype(__ctx.out()) { | |
| 144 | template <class _FormatContext> | |
| 145 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 146 | format(basic_string_view<_CharT, _Traits> __str, _FormatContext& __ctx) const { | |
| 150 | 147 | // Drop _Traits to have one std::basic_string_view formatter. |
| 151 | 148 | return _Base::format(basic_string_view<_CharT>(__str.data(), __str.size()), __ctx); |
| 152 | 149 | } |
| 153 | 150 | }; |
| 154 | 151 | |
| 155 | #endif //_LIBCPP_STD_VER > 17 | |
| 152 | #endif //_LIBCPP_STD_VER >= 20 | |
| 156 | 153 | |
| 157 | 154 | _LIBCPP_END_NAMESPACE_STD |
| 158 | 155 |
lib/libcxx/include/__format/formatter_tuple.h+47-75| ... | ... | @@ -11,18 +11,16 @@ |
| 11 | 11 | #define _LIBCPP___FORMAT_FORMATTER_TUPLE_H |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/ranges_copy.h> |
| 14 | #include <__availability> | |
| 15 | 14 | #include <__chrono/statically_widen.h> |
| 16 | 15 | #include <__config> |
| 16 | #include <__format/buffer.h> | |
| 17 | 17 | #include <__format/concepts.h> |
| 18 | #include <__format/format_args.h> | |
| 19 | 18 | #include <__format/format_context.h> |
| 20 | 19 | #include <__format/format_error.h> |
| 21 | 20 | #include <__format/format_parse_context.h> |
| 22 | 21 | #include <__format/formatter.h> |
| 23 | 22 | #include <__format/formatter_output.h> |
| 24 | 23 | #include <__format/parser_std_format_spec.h> |
| 25 | #include <__iterator/back_insert_iterator.h> | |
| 26 | 24 | #include <__type_traits/remove_cvref.h> |
| 27 | 25 | #include <__utility/integer_sequence.h> |
| 28 | 26 | #include <__utility/pair.h> |
| ... | ... | @@ -35,49 +33,52 @@ |
| 35 | 33 | |
| 36 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 35 | |
| 38 | #if _LIBCPP_STD_VER > 20 | |
| 36 | #if _LIBCPP_STD_VER >= 23 | |
| 39 | 37 | |
| 40 | 38 | template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args> |
| 41 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple { | |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { | |
| 39 | struct _LIBCPP_TEMPLATE_VIS __formatter_tuple { | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept { | |
| 43 | 41 | __separator_ = __separator; |
| 44 | 42 | } |
| 45 | 43 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 46 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { | |
| 44 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept { | |
| 47 | 45 | __opening_bracket_ = __opening_bracket; |
| 48 | 46 | __closing_bracket_ = __closing_bracket; |
| 49 | 47 | } |
| 50 | 48 | |
| 51 | 49 | template <class _ParseContext> |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { | |
| 53 | const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_tuple); | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 51 | auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_tuple); | |
| 54 | 52 | |
| 55 | // [format.tuple]/7 | |
| 56 | // ... For each element e in underlying_, if e.set_debug_format() | |
| 57 | // is a valid expression, calls e.set_debug_format(). | |
| 58 | // TODO FMT this can be removed when P2733 is accepted. | |
| 59 | std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> { | |
| 60 | std::__set_debug_format(std::get<_Index>(__underlying_)); | |
| 61 | }); | |
| 62 | ||
| 63 | const _CharT* __end = __parse_ctx.end(); | |
| 64 | if (__begin == __end) | |
| 65 | return __begin; | |
| 66 | ||
| 67 | if (*__begin == _CharT('m')) { | |
| 53 | auto __end = __ctx.end(); | |
| 54 | // Note 'n' is part of the type here | |
| 55 | if (__parser_.__clear_brackets_) | |
| 56 | set_brackets({}, {}); | |
| 57 | else if (__begin != __end && *__begin == _CharT('m')) { | |
| 68 | 58 | if constexpr (sizeof...(_Args) == 2) { |
| 69 | 59 | set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); |
| 70 | 60 | set_brackets({}, {}); |
| 71 | 61 | ++__begin; |
| 72 | 62 | } else |
| 73 | std::__throw_format_error("The format specifier m requires a pair or a two-element tuple"); | |
| 74 | } else if (*__begin == _CharT('n')) { | |
| 75 | set_brackets({}, {}); | |
| 76 | ++__begin; | |
| 63 | std::__throw_format_error("Type m requires a pair or a tuple with two elements"); | |
| 77 | 64 | } |
| 78 | 65 | |
| 79 | 66 | if (__begin != __end && *__begin != _CharT('}')) |
| 80 | std::__throw_format_error("The format-spec should consume the input or end with a '}'"); | |
| 67 | std::__throw_format_error("The format specifier should consume the input or end with a '}'"); | |
| 68 | ||
| 69 | __ctx.advance_to(__begin); | |
| 70 | ||
| 71 | // [format.tuple]/7 | |
| 72 | // ... For each element e in underlying_, if e.set_debug_format() | |
| 73 | // is a valid expression, calls e.set_debug_format(). | |
| 74 | std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> { | |
| 75 | auto& __formatter = std::get<_Index>(__underlying_); | |
| 76 | __formatter.parse(__ctx); | |
| 77 | // Unlike the range_formatter we don't guard against evil parsers. Since | |
| 78 | // this format-spec never has a format-spec for the underlying type | |
| 79 | // adding the test would give additional overhead. | |
| 80 | std::__set_debug_format(__formatter); | |
| 81 | }); | |
| 81 | 82 | |
| 82 | 83 | return __begin; |
| 83 | 84 | } |
| ... | ... | @@ -91,26 +92,25 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple { |
| 91 | 92 | if (!__specs.__has_width()) |
| 92 | 93 | return __format_tuple(__tuple, __ctx); |
| 93 | 94 | |
| 94 | basic_string<_CharT> __str; | |
| 95 | ||
| 96 | // Since the output is written to a different iterator a new context is | |
| 97 | // created. Since the underlying formatter uses the default formatting it | |
| 98 | // doesn't need a locale or the formatting arguments. So creating a new | |
| 99 | // context works. | |
| 100 | // | |
| 101 | // This solution works for this formatter, but it will not work for the | |
| 102 | // range_formatter. In that patch a generic solution is work in progress. | |
| 103 | // Once that is finished it can be used here. (The range_formatter will use | |
| 104 | // these features so it's easier to add it there and then port it.) | |
| 105 | // | |
| 106 | // TODO FMT Use formatting wrapping used in the range_formatter. | |
| 107 | basic_format_context __c = std::__format_context_create( | |
| 108 | back_insert_iterator{__str}, | |
| 109 | basic_format_args<basic_format_context<back_insert_iterator<basic_string<_CharT>>, _CharT>>{}); | |
| 95 | // The size of the buffer needed is: | |
| 96 | // - open bracket characters | |
| 97 | // - close bracket character | |
| 98 | // - n elements where every element may have a different size | |
| 99 | // - (n -1) separators | |
| 100 | // The size of the element is hard to predict, knowing the type helps but | |
| 101 | // it depends on the format-spec. As an initial estimate we guess 6 | |
| 102 | // characters. | |
| 103 | // Typically both brackets are 1 character and the separator is 2 | |
| 104 | // characters. Which means there will be | |
| 105 | // (n - 1) * 2 + 1 + 1 = n * 2 character | |
| 106 | // So estimate 8 times the range size as buffer. | |
| 107 | __format::__retarget_buffer<_CharT> __buffer{8 * tuple_size_v<_Tuple>}; | |
| 108 | basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{ | |
| 109 | __buffer.__make_output_iterator(), __ctx}; | |
| 110 | 110 | |
| 111 | 111 | __format_tuple(__tuple, __c); |
| 112 | 112 | |
| 113 | return __formatter::__write_string_no_precision(basic_string_view{__str}, __ctx.out(), __specs); | |
| 113 | return __formatter::__write_string_no_precision(basic_string_view{__buffer.__view()}, __ctx.out(), __specs); | |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | template <class _FormatContext> |
| ... | ... | @@ -120,35 +120,7 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __formatter_tuple { |
| 120 | 120 | std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> { |
| 121 | 121 | if constexpr (_Index) |
| 122 | 122 | __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out); |
| 123 | ||
| 124 | // During review Victor suggested to make the exposition only | |
| 125 | // __underlying_ member a local variable. Currently the Standard | |
| 126 | // requires nested debug-enabled formatter specializations not to | |
| 127 | // output escaped output. P2733 fixes that bug, once accepted the | |
| 128 | // code below can be used. | |
| 129 | // (Note when a paper allows parsing a tuple-underlying-spec the | |
| 130 | // exposition only member needs to be a class member. Earlier | |
| 131 | // revisions of P2286 proposed that, but this was not pursued, | |
| 132 | // due to time constrains and complexity of the matter.) | |
| 133 | // TODO FMT This can be updated after P2733 is accepted. | |
| 134 | # if 0 | |
| 135 | // P2286 uses an exposition only member in the formatter | |
| 136 | // tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_; | |
| 137 | // This was used in earlier versions of the paper since | |
| 138 | // __underlying_.parse(...) was called. This is no longer the case | |
| 139 | // so we can reduce the scope of the formatter. | |
| 140 | // | |
| 141 | // It does require the underlying's parse effect to be moved here too. | |
| 142 | using _Arg = tuple_element<_Index, decltype(__tuple)>; | |
| 143 | formatter<remove_cvref_t<_Args>, _CharT> __underlying; | |
| 144 | ||
| 145 | // [format.tuple]/7 | |
| 146 | // ... For each element e in underlying_, if e.set_debug_format() | |
| 147 | // is a valid expression, calls e.set_debug_format(). | |
| 148 | std::__set_debug_format(__underlying); | |
| 149 | # else | |
| 150 | 123 | __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx)); |
| 151 | # endif | |
| 152 | 124 | }); |
| 153 | 125 | |
| 154 | 126 | return std::ranges::copy(__closing_bracket_, __ctx.out()).out; |
| ... | ... | @@ -164,14 +136,14 @@ private: |
| 164 | 136 | }; |
| 165 | 137 | |
| 166 | 138 | template <__fmt_char_type _CharT, formattable<_CharT>... _Args> |
| 167 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<pair<_Args...>, _CharT> | |
| 139 | struct _LIBCPP_TEMPLATE_VIS formatter<pair<_Args...>, _CharT> | |
| 168 | 140 | : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {}; |
| 169 | 141 | |
| 170 | 142 | template <__fmt_char_type _CharT, formattable<_CharT>... _Args> |
| 171 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<tuple<_Args...>, _CharT> | |
| 143 | struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT> | |
| 172 | 144 | : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {}; |
| 173 | 145 | |
| 174 | #endif //_LIBCPP_STD_VER > 20 | |
| 146 | #endif //_LIBCPP_STD_VER >= 23 | |
| 175 | 147 | |
| 176 | 148 | _LIBCPP_END_NAMESPACE_STD |
| 177 | 149 |
lib/libcxx/include/__format/parser_std_format_spec.h+415-194| ... | ... | @@ -16,23 +16,28 @@ |
| 16 | 16 | /// This header has some support for the chrono-format-spec since it doesn't |
| 17 | 17 | /// affect the std-format-spec. |
| 18 | 18 | |
| 19 | #include <__algorithm/find_if.h> | |
| 19 | #include <__algorithm/copy_n.h> | |
| 20 | 20 | #include <__algorithm/min.h> |
| 21 | 21 | #include <__assert> |
| 22 | 22 | #include <__concepts/arithmetic.h> |
| 23 | 23 | #include <__concepts/same_as.h> |
| 24 | 24 | #include <__config> |
| 25 | #include <__debug> | |
| 26 | 25 | #include <__format/format_arg.h> |
| 27 | 26 | #include <__format/format_error.h> |
| 28 | 27 | #include <__format/format_parse_context.h> |
| 29 | 28 | #include <__format/format_string.h> |
| 30 | 29 | #include <__format/unicode.h> |
| 30 | #include <__format/width_estimation_table.h> | |
| 31 | #include <__iterator/concepts.h> | |
| 32 | #include <__iterator/iterator_traits.h> // iter_value_t | |
| 33 | #include <__memory/addressof.h> | |
| 34 | #include <__type_traits/common_type.h> | |
| 35 | #include <__type_traits/is_constant_evaluated.h> | |
| 36 | #include <__type_traits/is_trivially_copyable.h> | |
| 31 | 37 | #include <__variant/monostate.h> |
| 32 | #include <bit> | |
| 33 | 38 | #include <cstdint> |
| 39 | #include <string> | |
| 34 | 40 | #include <string_view> |
| 35 | #include <type_traits> | |
| 36 | 41 | |
| 37 | 42 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 38 | 43 | # pragma GCC system_header |
| ... | ... | @@ -43,24 +48,36 @@ _LIBCPP_PUSH_MACROS |
| 43 | 48 | |
| 44 | 49 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 45 | 50 | |
| 46 | #if _LIBCPP_STD_VER > 17 | |
| 51 | #if _LIBCPP_STD_VER >= 20 | |
| 47 | 52 | |
| 48 | 53 | namespace __format_spec { |
| 49 | 54 | |
| 50 | template <class _CharT> | |
| 51 | _LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT> | |
| 52 | __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) { | |
| 55 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void | |
| 56 | __throw_invalid_option_format_error(const char* __id, const char* __option) { | |
| 57 | std::__throw_format_error( | |
| 58 | (string("The format specifier for ") + __id + " does not allow the " + __option + " option").c_str()); | |
| 59 | } | |
| 60 | ||
| 61 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) { | |
| 62 | std::__throw_format_error( | |
| 63 | (string("The type option contains an invalid value for ") + __id + " formatting argument").c_str()); | |
| 64 | } | |
| 65 | ||
| 66 | template <contiguous_iterator _Iterator, class _ParseContext> | |
| 67 | _LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator> | |
| 68 | __parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) { | |
| 69 | using _CharT = iter_value_t<_Iterator>; | |
| 53 | 70 | // This function is a wrapper to call the real parser. But it does the |
| 54 | 71 | // validation for the pre-conditions and post-conditions. |
| 55 | 72 | if (__begin == __end) |
| 56 | std::__throw_format_error("End of input while parsing format-spec arg-id"); | |
| 73 | std::__throw_format_error("End of input while parsing an argument index"); | |
| 57 | 74 | |
| 58 | __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); | |
| 75 | __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __ctx); | |
| 59 | 76 | |
| 60 | if (__r.__ptr == __end || *__r.__ptr != _CharT('}')) | |
| 61 | std::__throw_format_error("Invalid arg-id"); | |
| 77 | if (__r.__last == __end || *__r.__last != _CharT('}')) | |
| 78 | std::__throw_format_error("The argument index is invalid"); | |
| 62 | 79 | |
| 63 | ++__r.__ptr; | |
| 80 | ++__r.__last; | |
| 64 | 81 | return __r; |
| 65 | 82 | } |
| 66 | 83 | |
| ... | ... | @@ -78,22 +95,33 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { |
| 78 | 95 | return _VSTD::__visit_format_arg( |
| 79 | 96 | [](auto __arg) -> uint32_t { |
| 80 | 97 | using _Type = decltype(__arg); |
| 81 | if constexpr (integral<_Type>) { | |
| 98 | if constexpr (same_as<_Type, monostate>) | |
| 99 | std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); | |
| 100 | ||
| 101 | // [format.string.std]/8 | |
| 102 | // If { arg-idopt } is used in a width or precision, the value of the | |
| 103 | // corresponding formatting argument is used in its place. If the | |
| 104 | // corresponding formatting argument is not of standard signed or unsigned | |
| 105 | // integer type, or its value is negative for precision or non-positive for | |
| 106 | // width, an exception of type format_error is thrown. | |
| 107 | // | |
| 108 | // When an integral is used in a format function, it is stored as one of | |
| 109 | // the types checked below. Other integral types are promoted. For example, | |
| 110 | // a signed char is stored as an int. | |
| 111 | if constexpr (same_as<_Type, int> || same_as<_Type, unsigned int> || // | |
| 112 | same_as<_Type, long long> || same_as<_Type, unsigned long long>) { | |
| 82 | 113 | if constexpr (signed_integral<_Type>) { |
| 83 | 114 | if (__arg < 0) |
| 84 | std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value"); | |
| 115 | std::__throw_format_error("An argument index may not have a negative value"); | |
| 85 | 116 | } |
| 86 | 117 | |
| 87 | 118 | using _CT = common_type_t<_Type, decltype(__format::__number_max)>; |
| 88 | if (static_cast<_CT>(__arg) > | |
| 89 | static_cast<_CT>(__format::__number_max)) | |
| 90 | std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value"); | |
| 119 | if (static_cast<_CT>(__arg) > static_cast<_CT>(__format::__number_max)) | |
| 120 | std::__throw_format_error("The value of the argument index exceeds its maximum value"); | |
| 91 | 121 | |
| 92 | 122 | return __arg; |
| 93 | } else if constexpr (same_as<_Type, monostate>) | |
| 94 | std::__throw_format_error("Argument index out of bounds"); | |
| 95 | else | |
| 96 | std::__throw_format_error("A format-spec arg-id replacement argument isn't an integral type"); | |
| 123 | } else | |
| 124 | std::__throw_format_error("Replacement argument isn't a standard signed or unsigned integer type"); | |
| 97 | 125 | }, |
| 98 | 126 | __format_arg); |
| 99 | 127 | } |
| ... | ... | @@ -104,42 +132,48 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { |
| 104 | 132 | /// explicitly. |
| 105 | 133 | // TODO FMT Use an ABI tag for this struct. |
| 106 | 134 | struct __fields { |
| 107 | uint8_t __sign_ : 1 {false}; | |
| 108 | uint8_t __alternate_form_ : 1 {false}; | |
| 109 | uint8_t __zero_padding_ : 1 {false}; | |
| 110 | uint8_t __precision_ : 1 {false}; | |
| 111 | uint8_t __locale_specific_form_ : 1 {false}; | |
| 112 | uint8_t __type_ : 1 {false}; | |
| 135 | uint16_t __sign_ : 1 {false}; | |
| 136 | uint16_t __alternate_form_ : 1 {false}; | |
| 137 | uint16_t __zero_padding_ : 1 {false}; | |
| 138 | uint16_t __precision_ : 1 {false}; | |
| 139 | uint16_t __locale_specific_form_ : 1 {false}; | |
| 140 | uint16_t __type_ : 1 {false}; | |
| 113 | 141 | // Determines the valid values for fill. |
| 114 | 142 | // |
| 115 | 143 | // Originally the fill could be any character except { and }. Range-based |
| 116 | 144 | // formatters use the colon to mark the beginning of the |
| 117 | 145 | // underlying-format-spec. To avoid parsing ambiguities these formatter |
| 118 | 146 | // specializations prohibit the use of the colon as a fill character. |
| 119 | uint8_t __allow_colon_in_fill_ : 1 {false}; | |
| 147 | uint16_t __use_range_fill_ : 1 {false}; | |
| 148 | uint16_t __clear_brackets_ : 1 {false}; | |
| 149 | uint16_t __consume_all_ : 1 {false}; | |
| 120 | 150 | }; |
| 121 | 151 | |
| 122 | 152 | // By not placing this constant in the formatter class it's not duplicated for |
| 123 | 153 | // char and wchar_t. |
| 154 | inline constexpr __fields __fields_bool{.__locale_specific_form_ = true, .__type_ = true, .__consume_all_ = true}; | |
| 124 | 155 | inline constexpr __fields __fields_integral{ |
| 125 | 156 | .__sign_ = true, |
| 126 | 157 | .__alternate_form_ = true, |
| 127 | 158 | .__zero_padding_ = true, |
| 128 | 159 | .__locale_specific_form_ = true, |
| 129 | .__type_ = true}; | |
| 160 | .__type_ = true, | |
| 161 | .__consume_all_ = true}; | |
| 130 | 162 | inline constexpr __fields __fields_floating_point{ |
| 131 | 163 | .__sign_ = true, |
| 132 | 164 | .__alternate_form_ = true, |
| 133 | 165 | .__zero_padding_ = true, |
| 134 | 166 | .__precision_ = true, |
| 135 | 167 | .__locale_specific_form_ = true, |
| 136 | .__type_ = true}; | |
| 137 | inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true}; | |
| 138 | inline constexpr __fields __fields_pointer{.__type_ = true}; | |
| 139 | ||
| 140 | # if _LIBCPP_STD_VER > 20 | |
| 141 | inline constexpr __fields __fields_tuple{.__type_ = false, .__allow_colon_in_fill_ = true}; | |
| 142 | inline constexpr __fields __fields_range{.__type_ = false, .__allow_colon_in_fill_ = true}; | |
| 168 | .__type_ = true, | |
| 169 | .__consume_all_ = true}; | |
| 170 | inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true, .__consume_all_ = true}; | |
| 171 | inline constexpr __fields __fields_pointer{.__zero_padding_ = true, .__type_ = true, .__consume_all_ = true}; | |
| 172 | ||
| 173 | # if _LIBCPP_STD_VER >= 23 | |
| 174 | inline constexpr __fields __fields_tuple{.__use_range_fill_ = true, .__clear_brackets_ = true}; | |
| 175 | inline constexpr __fields __fields_range{.__use_range_fill_ = true, .__clear_brackets_ = true}; | |
| 176 | inline constexpr __fields __fields_fill_align_width{}; | |
| 143 | 177 | # endif |
| 144 | 178 | |
| 145 | 179 | enum class _LIBCPP_ENUM_VIS __alignment : uint8_t { |
| ... | ... | @@ -164,7 +198,7 @@ enum class _LIBCPP_ENUM_VIS __sign : uint8_t { |
| 164 | 198 | }; |
| 165 | 199 | |
| 166 | 200 | enum class _LIBCPP_ENUM_VIS __type : uint8_t { |
| 167 | __default, | |
| 201 | __default = 0, | |
| 168 | 202 | __string, |
| 169 | 203 | __binary_lower_case, |
| 170 | 204 | __binary_upper_case, |
| ... | ... | @@ -172,7 +206,8 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t { |
| 172 | 206 | __decimal, |
| 173 | 207 | __hexadecimal_lower_case, |
| 174 | 208 | __hexadecimal_upper_case, |
| 175 | __pointer, | |
| 209 | __pointer_lower_case, | |
| 210 | __pointer_upper_case, | |
| 176 | 211 | __char, |
| 177 | 212 | __hexfloat_lower_case, |
| 178 | 213 | __hexfloat_upper_case, |
| ... | ... | @@ -185,6 +220,25 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t { |
| 185 | 220 | __debug |
| 186 | 221 | }; |
| 187 | 222 | |
| 223 | _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __create_type_mask(__type __t) { | |
| 224 | uint32_t __shift = static_cast<uint32_t>(__t); | |
| 225 | if (__shift == 0) | |
| 226 | return 1; | |
| 227 | ||
| 228 | if (__shift > 31) | |
| 229 | std::__throw_format_error("The type does not fit in the mask"); | |
| 230 | ||
| 231 | return 1 << __shift; | |
| 232 | } | |
| 233 | ||
| 234 | inline constexpr uint32_t __type_mask_integer = | |
| 235 | __create_type_mask(__type::__binary_lower_case) | // | |
| 236 | __create_type_mask(__type::__binary_upper_case) | // | |
| 237 | __create_type_mask(__type::__decimal) | // | |
| 238 | __create_type_mask(__type::__octal) | // | |
| 239 | __create_type_mask(__type::__hexadecimal_lower_case) | // | |
| 240 | __create_type_mask(__type::__hexadecimal_upper_case); | |
| 241 | ||
| 188 | 242 | struct __std { |
| 189 | 243 | __alignment __alignment_ : 3; |
| 190 | 244 | __sign __sign_ : 2; |
| ... | ... | @@ -196,6 +250,7 @@ struct __std { |
| 196 | 250 | struct __chrono { |
| 197 | 251 | __alignment __alignment_ : 3; |
| 198 | 252 | bool __locale_specific_form_ : 1; |
| 253 | bool __hour_ : 1; | |
| 199 | 254 | bool __weekday_name_ : 1; |
| 200 | 255 | bool __weekday_ : 1; |
| 201 | 256 | bool __day_of_year_ : 1; |
| ... | ... | @@ -203,6 +258,25 @@ struct __chrono { |
| 203 | 258 | bool __month_name_ : 1; |
| 204 | 259 | }; |
| 205 | 260 | |
| 261 | // The fill UCS scalar value. | |
| 262 | // | |
| 263 | // This is always an array, with 1, 2, or 4 elements. | |
| 264 | // The size of the data structure is always 32-bits. | |
| 265 | template <class _CharT> | |
| 266 | struct __code_point; | |
| 267 | ||
| 268 | template <> | |
| 269 | struct __code_point<char> { | |
| 270 | char __data[4] = {' '}; | |
| 271 | }; | |
| 272 | ||
| 273 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 274 | template <> | |
| 275 | struct __code_point<wchar_t> { | |
| 276 | wchar_t __data[4 / sizeof(wchar_t)] = {L' '}; | |
| 277 | }; | |
| 278 | # endif | |
| 279 | ||
| 206 | 280 | /// Contains the parsed formatting specifications. |
| 207 | 281 | /// |
| 208 | 282 | /// This contains information for both the std-format-spec and the |
| ... | ... | @@ -238,7 +312,7 @@ struct __parsed_specifications { |
| 238 | 312 | /// replaced with the value of that arg-id. |
| 239 | 313 | int32_t __precision_; |
| 240 | 314 | |
| 241 | _CharT __fill_; | |
| 315 | __code_point<_CharT> __fill_; | |
| 242 | 316 | |
| 243 | 317 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_width() const { return __width_ > 0; } |
| 244 | 318 | |
| ... | ... | @@ -265,48 +339,161 @@ static_assert(is_trivially_copyable_v<__parsed_specifications<wchar_t>>); |
| 265 | 339 | template <class _CharT> |
| 266 | 340 | class _LIBCPP_TEMPLATE_VIS __parser { |
| 267 | 341 | public: |
| 268 | _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields) | |
| 269 | -> decltype(__parse_ctx.begin()) { | |
| 270 | ||
| 271 | const _CharT* __begin = __parse_ctx.begin(); | |
| 272 | const _CharT* __end = __parse_ctx.end(); | |
| 342 | // Parses the format specification. | |
| 343 | // | |
| 344 | // Depending on whether the parsing is done compile-time or run-time | |
| 345 | // the method slightly differs. | |
| 346 | // - Only parses a field when it is in the __fields. Accepting all | |
| 347 | // fields and then validating the valid ones has a performance impact. | |
| 348 | // This is faster but gives slighly worse error messages. | |
| 349 | // - At compile-time when a field is not accepted the parser will still | |
| 350 | // parse it and give an error when it's present. This gives a more | |
| 351 | // accurate error. | |
| 352 | // The idea is that most times the format instead of the vformat | |
| 353 | // functions are used. In that case the error will be detected during | |
| 354 | // compilation and there is no need to pay for the run-time overhead. | |
| 355 | template <class _ParseContext> | |
| 356 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator __parse(_ParseContext& __ctx, __fields __fields) { | |
| 357 | auto __begin = __ctx.begin(); | |
| 358 | auto __end = __ctx.end(); | |
| 273 | 359 | if (__begin == __end) |
| 274 | 360 | return __begin; |
| 275 | 361 | |
| 276 | if (__parse_fill_align(__begin, __end, __fields.__allow_colon_in_fill_) && __begin == __end) | |
| 362 | if (__parse_fill_align(__begin, __end, __fields.__use_range_fill_) && __begin == __end) | |
| 277 | 363 | return __begin; |
| 278 | 364 | |
| 279 | if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end) | |
| 280 | return __begin; | |
| 365 | if (__fields.__sign_) { | |
| 366 | if (__parse_sign(__begin) && __begin == __end) | |
| 367 | return __begin; | |
| 368 | } else if (std::is_constant_evaluated() && __parse_sign(__begin)) { | |
| 369 | std::__throw_format_error("The format specification does not allow the sign option"); | |
| 370 | } | |
| 281 | 371 | |
| 282 | if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end) | |
| 283 | return __begin; | |
| 372 | if (__fields.__alternate_form_) { | |
| 373 | if (__parse_alternate_form(__begin) && __begin == __end) | |
| 374 | return __begin; | |
| 375 | } else if (std::is_constant_evaluated() && __parse_alternate_form(__begin)) { | |
| 376 | std::__throw_format_error("The format specifier does not allow the alternate form option"); | |
| 377 | } | |
| 284 | 378 | |
| 285 | if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end) | |
| 286 | return __begin; | |
| 379 | if (__fields.__zero_padding_) { | |
| 380 | if (__parse_zero_padding(__begin) && __begin == __end) | |
| 381 | return __begin; | |
| 382 | } else if (std::is_constant_evaluated() && __parse_zero_padding(__begin)) { | |
| 383 | std::__throw_format_error("The format specifier does not allow the zero-padding option"); | |
| 384 | } | |
| 287 | 385 | |
| 288 | if (__parse_width(__begin, __end, __parse_ctx) && __begin == __end) | |
| 386 | if (__parse_width(__begin, __end, __ctx) && __begin == __end) | |
| 289 | 387 | return __begin; |
| 290 | 388 | |
| 291 | if (__fields.__precision_ && __parse_precision(__begin, __end, __parse_ctx) && __begin == __end) | |
| 292 | return __begin; | |
| 389 | if (__fields.__precision_) { | |
| 390 | if (__parse_precision(__begin, __end, __ctx) && __begin == __end) | |
| 391 | return __begin; | |
| 392 | } else if (std::is_constant_evaluated() && __parse_precision(__begin, __end, __ctx)) { | |
| 393 | std::__throw_format_error("The format specifier does not allow the precision option"); | |
| 394 | } | |
| 293 | 395 | |
| 294 | if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end) | |
| 295 | return __begin; | |
| 396 | if (__fields.__locale_specific_form_) { | |
| 397 | if (__parse_locale_specific_form(__begin) && __begin == __end) | |
| 398 | return __begin; | |
| 399 | } else if (std::is_constant_evaluated() && __parse_locale_specific_form(__begin)) { | |
| 400 | std::__throw_format_error("The format specifier does not allow the locale-specific form option"); | |
| 401 | } | |
| 402 | ||
| 403 | if (__fields.__clear_brackets_) { | |
| 404 | if (__parse_clear_brackets(__begin) && __begin == __end) | |
| 405 | return __begin; | |
| 406 | } else if (std::is_constant_evaluated() && __parse_clear_brackets(__begin)) { | |
| 407 | std::__throw_format_error("The format specifier does not allow the n option"); | |
| 408 | } | |
| 296 | 409 | |
| 297 | if (__fields.__type_) { | |
| 410 | if (__fields.__type_) | |
| 298 | 411 | __parse_type(__begin); |
| 299 | 412 | |
| 300 | // When __type_ is false the calling parser is expected to do additional | |
| 301 | // parsing. In that case that parser should do the end of format string | |
| 302 | // validation. | |
| 303 | if (__begin != __end && *__begin != _CharT('}')) | |
| 304 | std::__throw_format_error("The format-spec should consume the input or end with a '}'"); | |
| 305 | } | |
| 413 | if (!__fields.__consume_all_) | |
| 414 | return __begin; | |
| 415 | ||
| 416 | if (__begin != __end && *__begin != _CharT('}')) | |
| 417 | std::__throw_format_error("The format specifier should consume the input or end with a '}'"); | |
| 306 | 418 | |
| 307 | 419 | return __begin; |
| 308 | 420 | } |
| 309 | 421 | |
| 422 | // Validates the selected the parsed data. | |
| 423 | // | |
| 424 | // The valid fields in the parser may depend on the display type | |
| 425 | // selected. But the type is the last optional field, so by the time | |
| 426 | // it's known an option can't be used, it already has been parsed. | |
| 427 | // This does the validation again. | |
| 428 | // | |
| 429 | // For example an integral may have a sign, zero-padding, or alternate | |
| 430 | // form when the type option is not 'c'. So the generic approach is: | |
| 431 | // | |
| 432 | // typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); | |
| 433 | // if (__parser.__type_ == __format_spec::__type::__char) { | |
| 434 | // __parser.__validate((__format_spec::__fields_bool, "an integer"); | |
| 435 | // ... // more char adjustments | |
| 436 | // } else { | |
| 437 | // ... // validate an integral type. | |
| 438 | // } | |
| 439 | // | |
| 440 | // For some types all valid options need a second validation run, like | |
| 441 | // boolean types. | |
| 442 | // | |
| 443 | // Depending on whether the validation is done at compile-time or | |
| 444 | // run-time the error differs | |
| 445 | // - run-time the exception is thrown and contains the type of field | |
| 446 | // being validated. | |
| 447 | // - at compile-time the line with `std::__throw_format_error` is shown | |
| 448 | // in the output. In that case it's important for the error to be on one | |
| 449 | // line. | |
| 450 | // Note future versions of C++ may allow better compile-time error | |
| 451 | // reporting. | |
| 452 | _LIBCPP_HIDE_FROM_ABI constexpr void | |
| 453 | __validate(__fields __fields, const char* __id, uint32_t __type_mask = -1) const { | |
| 454 | if (!__fields.__sign_ && __sign_ != __sign::__default) { | |
| 455 | if (std::is_constant_evaluated()) | |
| 456 | std::__throw_format_error("The format specifier does not allow the sign option"); | |
| 457 | else | |
| 458 | __format_spec::__throw_invalid_option_format_error(__id, "sign"); | |
| 459 | } | |
| 460 | ||
| 461 | if (!__fields.__alternate_form_ && __alternate_form_) { | |
| 462 | if (std::is_constant_evaluated()) | |
| 463 | std::__throw_format_error("The format specifier does not allow the alternate form option"); | |
| 464 | else | |
| 465 | __format_spec::__throw_invalid_option_format_error(__id, "alternate form"); | |
| 466 | } | |
| 467 | ||
| 468 | if (!__fields.__zero_padding_ && __alignment_ == __alignment::__zero_padding) { | |
| 469 | if (std::is_constant_evaluated()) | |
| 470 | std::__throw_format_error("The format specifier does not allow the zero-padding option"); | |
| 471 | else | |
| 472 | __format_spec::__throw_invalid_option_format_error(__id, "zero-padding"); | |
| 473 | } | |
| 474 | ||
| 475 | if (!__fields.__precision_ && __precision_ != -1) { // Works both when the precision has a value or an arg-id. | |
| 476 | if (std::is_constant_evaluated()) | |
| 477 | std::__throw_format_error("The format specifier does not allow the precision option"); | |
| 478 | else | |
| 479 | __format_spec::__throw_invalid_option_format_error(__id, "precision"); | |
| 480 | } | |
| 481 | ||
| 482 | if (!__fields.__locale_specific_form_ && __locale_specific_form_) { | |
| 483 | if (std::is_constant_evaluated()) | |
| 484 | std::__throw_format_error("The format specifier does not allow the locale-specific form option"); | |
| 485 | else | |
| 486 | __format_spec::__throw_invalid_option_format_error(__id, "locale-specific form"); | |
| 487 | } | |
| 488 | ||
| 489 | if ((__create_type_mask(__type_) & __type_mask) == 0) { | |
| 490 | if (std::is_constant_evaluated()) | |
| 491 | std::__throw_format_error("The format specifier uses an invalid value for the type option"); | |
| 492 | else | |
| 493 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 494 | } | |
| 495 | } | |
| 496 | ||
| 310 | 497 | /// \returns the `__parsed_specifications` with the resolved dynamic sizes.. |
| 311 | 498 | _LIBCPP_HIDE_FROM_ABI |
| 312 | 499 | __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { |
| ... | ... | @@ -326,6 +513,7 @@ public: |
| 326 | 513 | .__chrono_ = |
| 327 | 514 | __chrono{.__alignment_ = __alignment_, |
| 328 | 515 | .__locale_specific_form_ = __locale_specific_form_, |
| 516 | .__hour_ = __hour_, | |
| 329 | 517 | .__weekday_name_ = __weekday_name_, |
| 330 | 518 | .__weekday_ = __weekday_, |
| 331 | 519 | .__day_of_year_ = __day_of_year_, |
| ... | ... | @@ -340,11 +528,13 @@ public: |
| 340 | 528 | __sign __sign_ : 2 {__sign::__default}; |
| 341 | 529 | bool __alternate_form_ : 1 {false}; |
| 342 | 530 | bool __locale_specific_form_ : 1 {false}; |
| 343 | bool __reserved_0_ : 1 {false}; | |
| 531 | bool __clear_brackets_ : 1 {false}; | |
| 344 | 532 | __type __type_{__type::__default}; |
| 345 | 533 | |
| 346 | 534 | // These flags are only used for formatting chrono. Since the struct has |
| 347 | 535 | // padding space left it's added to this structure. |
| 536 | bool __hour_ : 1 {false}; | |
| 537 | ||
| 348 | 538 | bool __weekday_name_ : 1 {false}; |
| 349 | 539 | bool __weekday_ : 1 {false}; |
| 350 | 540 | |
| ... | ... | @@ -353,8 +543,8 @@ public: |
| 353 | 543 | |
| 354 | 544 | bool __month_name_ : 1 {false}; |
| 355 | 545 | |
| 356 | uint8_t __reserved_1_ : 3 {0}; | |
| 357 | uint8_t __reserved_2_ : 6 {0}; | |
| 546 | uint8_t __reserved_0_ : 2 {0}; | |
| 547 | uint8_t __reserved_1_ : 6 {0}; | |
| 358 | 548 | // These two flags are only used internally and not part of the |
| 359 | 549 | // __parsed_specifications. Therefore put them at the end. |
| 360 | 550 | bool __width_as_arg_ : 1 {false}; |
| ... | ... | @@ -366,11 +556,7 @@ public: |
| 366 | 556 | /// The requested precision, either the value or the arg-id. |
| 367 | 557 | int32_t __precision_{-1}; |
| 368 | 558 | |
| 369 | // LWG 3576 will probably change this to always accept a Unicode code point | |
| 370 | // To avoid changing the size with that change align the field so when it | |
| 371 | // becomes 32-bit its alignment will remain the same. That also means the | |
| 372 | // size will remain the same. (D2572 addresses the solution for LWG 3576.) | |
| 373 | _CharT __fill_{_CharT(' ')}; | |
| 559 | __code_point<_CharT> __fill_{}; | |
| 374 | 560 | |
| 375 | 561 | private: |
| 376 | 562 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alignment(_CharT __c) { |
| ... | ... | @@ -390,19 +576,90 @@ private: |
| 390 | 576 | return false; |
| 391 | 577 | } |
| 392 | 578 | |
| 579 | _LIBCPP_HIDE_FROM_ABI constexpr void __validate_fill_character(_CharT __fill, bool __use_range_fill) { | |
| 580 | // The forbidden fill characters all code points formed from a single code unit, thus the | |
| 581 | // check can be omitted when more code units are used. | |
| 582 | if (__use_range_fill && (__fill == _CharT('{') || __fill == _CharT('}') || __fill == _CharT(':'))) | |
| 583 | std::__throw_format_error("The fill option contains an invalid value"); | |
| 584 | else if (__fill == _CharT('{') || __fill == _CharT('}')) | |
| 585 | std::__throw_format_error("The fill option contains an invalid value"); | |
| 586 | } | |
| 587 | ||
| 588 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 589 | // range-fill and tuple-fill are identical | |
| 590 | template <contiguous_iterator _Iterator> | |
| 591 | requires same_as<_CharT, char> | |
| 592 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 593 | || (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) | |
| 594 | # endif | |
| 595 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { | |
| 596 | _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, | |
| 597 | "when called with an empty input the function will cause " | |
| 598 | "undefined behavior by evaluating data not in the input"); | |
| 599 | __unicode::__code_point_view<_CharT> __view{__begin, __end}; | |
| 600 | __unicode::__consume_result __consumed = __view.__consume(); | |
| 601 | if (__consumed.__status != __unicode::__consume_result::__ok) | |
| 602 | std::__throw_format_error("The format specifier contains malformed Unicode characters"); | |
| 603 | ||
| 604 | if (__view.__position() < __end && __parse_alignment(*__view.__position())) { | |
| 605 | ptrdiff_t __code_units = __view.__position() - __begin; | |
| 606 | if (__code_units == 1) | |
| 607 | // The forbidden fill characters all are code points encoded | |
| 608 | // in one code unit, thus the check can be omitted when more | |
| 609 | // code units are used. | |
| 610 | __validate_fill_character(*__begin, __use_range_fill); | |
| 611 | ||
| 612 | std::copy_n(__begin, __code_units, std::addressof(__fill_.__data[0])); | |
| 613 | __begin += __code_units + 1; | |
| 614 | return true; | |
| 615 | } | |
| 616 | ||
| 617 | if (!__parse_alignment(*__begin)) | |
| 618 | return false; | |
| 619 | ||
| 620 | ++__begin; | |
| 621 | return true; | |
| 622 | } | |
| 623 | ||
| 624 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 625 | template <contiguous_iterator _Iterator> | |
| 626 | requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) | |
| 627 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { | |
| 628 | _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, | |
| 629 | "when called with an empty input the function will cause " | |
| 630 | "undefined behavior by evaluating data not in the input"); | |
| 631 | if (__begin + 1 != __end && __parse_alignment(*(__begin + 1))) { | |
| 632 | if (!__unicode::__is_scalar_value(*__begin)) | |
| 633 | std::__throw_format_error("The fill option contains an invalid value"); | |
| 634 | ||
| 635 | __validate_fill_character(*__begin, __use_range_fill); | |
| 636 | ||
| 637 | __fill_.__data[0] = *__begin; | |
| 638 | __begin += 2; | |
| 639 | return true; | |
| 640 | } | |
| 641 | ||
| 642 | if (!__parse_alignment(*__begin)) | |
| 643 | return false; | |
| 644 | ||
| 645 | ++__begin; | |
| 646 | return true; | |
| 647 | } | |
| 648 | ||
| 649 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 650 | ||
| 651 | # else // _LIBCPP_HAS_NO_UNICODE | |
| 393 | 652 | // range-fill and tuple-fill are identical |
| 394 | _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 395 | __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) { | |
| 396 | _LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause " | |
| 397 | "undefined behavior by evaluating data not in the input"); | |
| 653 | template <contiguous_iterator _Iterator> | |
| 654 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { | |
| 655 | _LIBCPP_ASSERT_UNCATEGORIZED(__begin != __end, | |
| 656 | "when called with an empty input the function will cause " | |
| 657 | "undefined behavior by evaluating data not in the input"); | |
| 398 | 658 | if (__begin + 1 != __end) { |
| 399 | 659 | if (__parse_alignment(*(__begin + 1))) { |
| 400 | if (__use_range_fill && (*__begin == _CharT('{') || *__begin == _CharT('}') || *__begin == _CharT(':'))) | |
| 401 | std::__throw_format_error("The format-spec range-fill field contains an invalid character"); | |
| 402 | else if (*__begin == _CharT('{') || *__begin == _CharT('}')) | |
| 403 | std::__throw_format_error("The format-spec fill field contains an invalid character"); | |
| 660 | __validate_fill_character(*__begin, __use_range_fill); | |
| 404 | 661 | |
| 405 | __fill_ = *__begin; | |
| 662 | __fill_.__data[0] = *__begin; | |
| 406 | 663 | __begin += 2; |
| 407 | 664 | return true; |
| 408 | 665 | } |
| ... | ... | @@ -415,7 +672,10 @@ private: |
| 415 | 672 | return true; |
| 416 | 673 | } |
| 417 | 674 | |
| 418 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) { | |
| 675 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 676 | ||
| 677 | template <contiguous_iterator _Iterator> | |
| 678 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) { | |
| 419 | 679 | switch (*__begin) { |
| 420 | 680 | case _CharT('-'): |
| 421 | 681 | __sign_ = __sign::__minus; |
| ... | ... | @@ -433,7 +693,8 @@ private: |
| 433 | 693 | return true; |
| 434 | 694 | } |
| 435 | 695 | |
| 436 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) { | |
| 696 | template <contiguous_iterator _Iterator> | |
| 697 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(_Iterator& __begin) { | |
| 437 | 698 | if (*__begin != _CharT('#')) |
| 438 | 699 | return false; |
| 439 | 700 | |
| ... | ... | @@ -442,7 +703,8 @@ private: |
| 442 | 703 | return true; |
| 443 | 704 | } |
| 444 | 705 | |
| 445 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) { | |
| 706 | template <contiguous_iterator _Iterator> | |
| 707 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(_Iterator& __begin) { | |
| 446 | 708 | if (*__begin != _CharT('0')) |
| 447 | 709 | return false; |
| 448 | 710 | |
| ... | ... | @@ -452,15 +714,16 @@ private: |
| 452 | 714 | return true; |
| 453 | 715 | } |
| 454 | 716 | |
| 455 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) { | |
| 717 | template <contiguous_iterator _Iterator> | |
| 718 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __ctx) { | |
| 456 | 719 | if (*__begin == _CharT('0')) |
| 457 | std::__throw_format_error("A format-spec width field shouldn't have a leading zero"); | |
| 720 | std::__throw_format_error("The width option should not have a leading zero"); | |
| 458 | 721 | |
| 459 | 722 | if (*__begin == _CharT('{')) { |
| 460 | __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); | |
| 723 | __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __ctx); | |
| 461 | 724 | __width_as_arg_ = true; |
| 462 | 725 | __width_ = __r.__value; |
| 463 | __begin = __r.__ptr; | |
| 726 | __begin = __r.__last; | |
| 464 | 727 | return true; |
| 465 | 728 | } |
| 466 | 729 | |
| ... | ... | @@ -469,40 +732,41 @@ private: |
| 469 | 732 | |
| 470 | 733 | __format::__parse_number_result __r = __format::__parse_number(__begin, __end); |
| 471 | 734 | __width_ = __r.__value; |
| 472 | _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, " | |
| 473 | "due to validations in this function"); | |
| 474 | __begin = __r.__ptr; | |
| 735 | _LIBCPP_ASSERT_UNCATEGORIZED(__width_ != 0, "A zero value isn't allowed and should be impossible, " | |
| 736 | "due to validations in this function"); | |
| 737 | __begin = __r.__last; | |
| 475 | 738 | return true; |
| 476 | 739 | } |
| 477 | 740 | |
| 478 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end, | |
| 479 | auto& __parse_ctx) { | |
| 741 | template <contiguous_iterator _Iterator> | |
| 742 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(_Iterator& __begin, _Iterator __end, auto& __ctx) { | |
| 480 | 743 | if (*__begin != _CharT('.')) |
| 481 | 744 | return false; |
| 482 | 745 | |
| 483 | 746 | ++__begin; |
| 484 | 747 | if (__begin == __end) |
| 485 | std::__throw_format_error("End of input while parsing format-spec precision"); | |
| 748 | std::__throw_format_error("End of input while parsing format specifier precision"); | |
| 486 | 749 | |
| 487 | 750 | if (*__begin == _CharT('{')) { |
| 488 | __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx); | |
| 751 | __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __ctx); | |
| 489 | 752 | __precision_as_arg_ = true; |
| 490 | 753 | __precision_ = __arg_id.__value; |
| 491 | __begin = __arg_id.__ptr; | |
| 754 | __begin = __arg_id.__last; | |
| 492 | 755 | return true; |
| 493 | 756 | } |
| 494 | 757 | |
| 495 | 758 | if (*__begin < _CharT('0') || *__begin > _CharT('9')) |
| 496 | std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id"); | |
| 759 | std::__throw_format_error("The precision option does not contain a value or an argument index"); | |
| 497 | 760 | |
| 498 | 761 | __format::__parse_number_result __r = __format::__parse_number(__begin, __end); |
| 499 | 762 | __precision_ = __r.__value; |
| 500 | 763 | __precision_as_arg_ = false; |
| 501 | __begin = __r.__ptr; | |
| 764 | __begin = __r.__last; | |
| 502 | 765 | return true; |
| 503 | 766 | } |
| 504 | 767 | |
| 505 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) { | |
| 768 | template <contiguous_iterator _Iterator> | |
| 769 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(_Iterator& __begin) { | |
| 506 | 770 | if (*__begin != _CharT('L')) |
| 507 | 771 | return false; |
| 508 | 772 | |
| ... | ... | @@ -511,7 +775,18 @@ private: |
| 511 | 775 | return true; |
| 512 | 776 | } |
| 513 | 777 | |
| 514 | _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) { | |
| 778 | template <contiguous_iterator _Iterator> | |
| 779 | _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_clear_brackets(_Iterator& __begin) { | |
| 780 | if (*__begin != _CharT('n')) | |
| 781 | return false; | |
| 782 | ||
| 783 | __clear_brackets_ = true; | |
| 784 | ++__begin; | |
| 785 | return true; | |
| 786 | } | |
| 787 | ||
| 788 | template <contiguous_iterator _Iterator> | |
| 789 | _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) { | |
| 515 | 790 | // Determines the type. It does not validate whether the selected type is |
| 516 | 791 | // valid. Most formatters have optional fields that are only allowed for |
| 517 | 792 | // certain types. These parsers need to do validation after the type has |
| ... | ... | @@ -561,7 +836,10 @@ private: |
| 561 | 836 | __type_ = __type::__octal; |
| 562 | 837 | break; |
| 563 | 838 | case 'p': |
| 564 | __type_ = __type::__pointer; | |
| 839 | __type_ = __type::__pointer_lower_case; | |
| 840 | break; | |
| 841 | case 'P': | |
| 842 | __type_ = __type::__pointer_upper_case; | |
| 565 | 843 | break; |
| 566 | 844 | case 's': |
| 567 | 845 | __type_ = __type::__string; |
| ... | ... | @@ -569,7 +847,7 @@ private: |
| 569 | 847 | case 'x': |
| 570 | 848 | __type_ = __type::__hexadecimal_lower_case; |
| 571 | 849 | break; |
| 572 | # if _LIBCPP_STD_VER > 20 | |
| 850 | # if _LIBCPP_STD_VER >= 23 | |
| 573 | 851 | case '?': |
| 574 | 852 | __type_ = __type::__debug; |
| 575 | 853 | break; |
| ... | ... | @@ -611,36 +889,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec |
| 611 | 889 | break; |
| 612 | 890 | |
| 613 | 891 | default: |
| 614 | std::__throw_format_error("The format-spec type has a type not supported for a string argument"); | |
| 892 | std::__throw_format_error("The type option contains an invalid value for a string formatting argument"); | |
| 615 | 893 | } |
| 616 | 894 | } |
| 617 | 895 | |
| 618 | 896 | template <class _CharT> |
| 619 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) { | |
| 620 | if (__parser.__sign_ != __sign::__default) | |
| 621 | std::__throw_format_error("A sign field isn't allowed in this format-spec"); | |
| 622 | ||
| 623 | if (__parser.__alternate_form_) | |
| 624 | std::__throw_format_error("An alternate form field isn't allowed in this format-spec"); | |
| 625 | ||
| 626 | if (__parser.__alignment_ == __alignment::__zero_padding) | |
| 627 | std::__throw_format_error("A zero-padding field isn't allowed in this format-spec"); | |
| 628 | ||
| 897 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser, const char* __id) { | |
| 898 | __parser.__validate(__format_spec::__fields_bool, __id); | |
| 629 | 899 | if (__parser.__alignment_ == __alignment::__default) |
| 630 | 900 | __parser.__alignment_ = __alignment::__left; |
| 631 | 901 | } |
| 632 | 902 | |
| 633 | 903 | template <class _CharT> |
| 634 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) { | |
| 635 | __format_spec::__process_display_type_bool_string(__parser); | |
| 904 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser, const char* __id) { | |
| 905 | __format_spec::__process_display_type_bool_string(__parser, __id); | |
| 636 | 906 | } |
| 637 | 907 | |
| 638 | 908 | template <class _CharT> |
| 639 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) { | |
| 909 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser, const char* __id) { | |
| 640 | 910 | switch (__parser.__type_) { |
| 641 | 911 | case __format_spec::__type::__default: |
| 642 | 912 | case __format_spec::__type::__string: |
| 643 | __format_spec::__process_display_type_bool_string(__parser); | |
| 913 | __format_spec::__process_display_type_bool_string(__parser, __id); | |
| 644 | 914 | break; |
| 645 | 915 | |
| 646 | 916 | case __format_spec::__type::__binary_lower_case: |
| ... | ... | @@ -652,17 +922,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p |
| 652 | 922 | break; |
| 653 | 923 | |
| 654 | 924 | default: |
| 655 | std::__throw_format_error("The format-spec type has a type not supported for a bool argument"); | |
| 925 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 656 | 926 | } |
| 657 | 927 | } |
| 658 | 928 | |
| 659 | 929 | template <class _CharT> |
| 660 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) { | |
| 930 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser, const char* __id) { | |
| 661 | 931 | switch (__parser.__type_) { |
| 662 | 932 | case __format_spec::__type::__default: |
| 663 | 933 | case __format_spec::__type::__char: |
| 664 | 934 | case __format_spec::__type::__debug: |
| 665 | __format_spec::__process_display_type_char(__parser); | |
| 935 | __format_spec::__process_display_type_char(__parser, __id); | |
| 666 | 936 | break; |
| 667 | 937 | |
| 668 | 938 | case __format_spec::__type::__binary_lower_case: |
| ... | ... | @@ -674,12 +944,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p |
| 674 | 944 | break; |
| 675 | 945 | |
| 676 | 946 | default: |
| 677 | std::__throw_format_error("The format-spec type has a type not supported for a char argument"); | |
| 947 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 678 | 948 | } |
| 679 | 949 | } |
| 680 | 950 | |
| 681 | 951 | template <class _CharT> |
| 682 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) { | |
| 952 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser, const char* __id) { | |
| 683 | 953 | switch (__parser.__type_) { |
| 684 | 954 | case __format_spec::__type::__default: |
| 685 | 955 | case __format_spec::__type::__binary_lower_case: |
| ... | ... | @@ -691,16 +961,16 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& |
| 691 | 961 | break; |
| 692 | 962 | |
| 693 | 963 | case __format_spec::__type::__char: |
| 694 | __format_spec::__process_display_type_char(__parser); | |
| 964 | __format_spec::__process_display_type_char(__parser, __id); | |
| 695 | 965 | break; |
| 696 | 966 | |
| 697 | 967 | default: |
| 698 | std::__throw_format_error("The format-spec type has a type not supported for an integer argument"); | |
| 968 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 699 | 969 | } |
| 700 | 970 | } |
| 701 | 971 | |
| 702 | 972 | template <class _CharT> |
| 703 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) { | |
| 973 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser, const char* __id) { | |
| 704 | 974 | switch (__parser.__type_) { |
| 705 | 975 | case __format_spec::__type::__default: |
| 706 | 976 | case __format_spec::__type::__hexfloat_lower_case: |
| ... | ... | @@ -719,33 +989,34 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_C |
| 719 | 989 | break; |
| 720 | 990 | |
| 721 | 991 | default: |
| 722 | std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument"); | |
| 992 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 723 | 993 | } |
| 724 | 994 | } |
| 725 | 995 | |
| 726 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) { | |
| 996 | _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type, const char* __id) { | |
| 727 | 997 | switch (__type) { |
| 728 | 998 | case __format_spec::__type::__default: |
| 729 | case __format_spec::__type::__pointer: | |
| 999 | case __format_spec::__type::__pointer_lower_case: | |
| 1000 | case __format_spec::__type::__pointer_upper_case: | |
| 730 | 1001 | break; |
| 731 | 1002 | |
| 732 | 1003 | default: |
| 733 | std::__throw_format_error("The format-spec type has a type not supported for a pointer argument"); | |
| 1004 | __format_spec::__throw_invalid_type_format_error(__id); | |
| 734 | 1005 | } |
| 735 | 1006 | } |
| 736 | 1007 | |
| 737 | template <class _CharT> | |
| 1008 | template <contiguous_iterator _Iterator> | |
| 738 | 1009 | struct __column_width_result { |
| 739 | 1010 | /// The number of output columns. |
| 740 | 1011 | size_t __width_; |
| 741 | 1012 | /// One beyond the last code unit used in the estimation. |
| 742 | 1013 | /// |
| 743 | 1014 | /// This limits the original output to fit in the wanted number of columns. |
| 744 | const _CharT* __last_; | |
| 1015 | _Iterator __last_; | |
| 745 | 1016 | }; |
| 746 | 1017 | |
| 747 | template <class _CharT> | |
| 748 | __column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>; | |
| 1018 | template <contiguous_iterator _Iterator> | |
| 1019 | __column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>; | |
| 749 | 1020 | |
| 750 | 1021 | /// Since a column width can be two it's possible that the requested column |
| 751 | 1022 | /// width can't be achieved. Depending on the intended usage the policy can be |
| ... | ... | @@ -761,66 +1032,16 @@ enum class __column_width_rounding { __down, __up }; |
| 761 | 1032 | # ifndef _LIBCPP_HAS_NO_UNICODE |
| 762 | 1033 | |
| 763 | 1034 | namespace __detail { |
| 764 | ||
| 765 | /// Converts a code point to the column width. | |
| 766 | /// | |
| 767 | /// The estimations are conforming to [format.string.general]/11 | |
| 768 | /// | |
| 769 | /// This version expects a value less than 0x1'0000, which is a 3-byte UTF-8 | |
| 770 | /// character. | |
| 771 | _LIBCPP_HIDE_FROM_ABI constexpr int __column_width_3(uint32_t __c) noexcept { | |
| 772 | _LIBCPP_ASSERT(__c < 0x10000, "Use __column_width_4 or __column_width for larger values"); | |
| 773 | ||
| 774 | // clang-format off | |
| 775 | return 1 + (__c >= 0x1100 && (__c <= 0x115f || | |
| 776 | (__c >= 0x2329 && (__c <= 0x232a || | |
| 777 | (__c >= 0x2e80 && (__c <= 0x303e || | |
| 778 | (__c >= 0x3040 && (__c <= 0xa4cf || | |
| 779 | (__c >= 0xac00 && (__c <= 0xd7a3 || | |
| 780 | (__c >= 0xf900 && (__c <= 0xfaff || | |
| 781 | (__c >= 0xfe10 && (__c <= 0xfe19 || | |
| 782 | (__c >= 0xfe30 && (__c <= 0xfe6f || | |
| 783 | (__c >= 0xff00 && (__c <= 0xff60 || | |
| 784 | (__c >= 0xffe0 && (__c <= 0xffe6 | |
| 785 | )))))))))))))))))))); | |
| 786 | // clang-format on | |
| 787 | } | |
| 788 | ||
| 789 | /// @overload | |
| 790 | /// | |
| 791 | /// This version expects a value greater than or equal to 0x1'0000, which is a | |
| 792 | /// 4-byte UTF-8 character. | |
| 793 | _LIBCPP_HIDE_FROM_ABI constexpr int __column_width_4(uint32_t __c) noexcept { | |
| 794 | _LIBCPP_ASSERT(__c >= 0x10000, "Use __column_width_3 or __column_width for smaller values"); | |
| 795 | ||
| 796 | // clang-format off | |
| 797 | return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f || | |
| 798 | (__c >= 0x1'f900 && (__c <= 0x1'f9ff || | |
| 799 | (__c >= 0x2'0000 && (__c <= 0x2'fffd || | |
| 800 | (__c >= 0x3'0000 && (__c <= 0x3'fffd | |
| 801 | )))))))); | |
| 802 | // clang-format on | |
| 803 | } | |
| 804 | ||
| 805 | /// @overload | |
| 806 | /// | |
| 807 | /// The general case, accepting all values. | |
| 808 | _LIBCPP_HIDE_FROM_ABI constexpr int __column_width(uint32_t __c) noexcept { | |
| 809 | if (__c < 0x10000) | |
| 810 | return __detail::__column_width_3(__c); | |
| 811 | ||
| 812 | return __detail::__column_width_4(__c); | |
| 813 | } | |
| 814 | ||
| 815 | template <class _CharT> | |
| 816 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering( | |
| 817 | const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept { | |
| 1035 | template <contiguous_iterator _Iterator> | |
| 1036 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width_grapheme_clustering( | |
| 1037 | _Iterator __first, _Iterator __last, size_t __maximum, __column_width_rounding __rounding) noexcept { | |
| 1038 | using _CharT = iter_value_t<_Iterator>; | |
| 818 | 1039 | __unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last}; |
| 819 | 1040 | |
| 820 | __column_width_result<_CharT> __result{0, __first}; | |
| 1041 | __column_width_result<_Iterator> __result{0, __first}; | |
| 821 | 1042 | while (__result.__last_ != __last && __result.__width_ <= __maximum) { |
| 822 | 1043 | typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume(); |
| 823 | int __width = __detail::__column_width(__cluster.__code_point_); | |
| 1044 | int __width = __width_estimation_table::__estimated_width(__cluster.__code_point_); | |
| 824 | 1045 | |
| 825 | 1046 | // When the next entry would exceed the maximum width the previous width |
| 826 | 1047 | // might be returned. For example when a width of 100 is requested the |
| ... | ... | @@ -884,8 +1105,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ascii(char32_t __c) { return __c < 0x8 |
| 884 | 1105 | /// \param __rounding Selects the rounding method. |
| 885 | 1106 | /// \c __down result.__width_ <= __maximum |
| 886 | 1107 | /// \c __up result.__width_ <= __maximum + 1 |
| 887 | template <class _CharT> | |
| 888 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width( | |
| 1108 | template <class _CharT, class _Iterator = typename basic_string_view<_CharT>::const_iterator> | |
| 1109 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width( | |
| 889 | 1110 | basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept { |
| 890 | 1111 | // The width estimation is done in two steps: |
| 891 | 1112 | // - Quickly process for the ASCII part. ASCII has the following properties |
| ... | ... | @@ -904,7 +1125,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_ |
| 904 | 1125 | // need to scan one code unit beyond the requested precision. When this code |
| 905 | 1126 | // unit is non-ASCII we omit the current code unit and let the Grapheme |
| 906 | 1127 | // clustering algorithm do its work. |
| 907 | const _CharT* __it = __str.begin(); | |
| 1128 | auto __it = __str.begin(); | |
| 908 | 1129 | if (__format_spec::__is_ascii(*__it)) { |
| 909 | 1130 | do { |
| 910 | 1131 | --__maximum; |
| ... | ... | @@ -932,7 +1153,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_ |
| 932 | 1153 | } |
| 933 | 1154 | # else // !defined(_LIBCPP_HAS_NO_UNICODE) |
| 934 | 1155 | template <class _CharT> |
| 935 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> | |
| 1156 | _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<typename basic_string_view<_CharT>::const_iterator> | |
| 936 | 1157 | __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept { |
| 937 | 1158 | // When Unicode isn't supported assume ASCII and every code unit is one code |
| 938 | 1159 | // point. In ASCII the estimated column width is always one. Thus there's no |
| ... | ... | @@ -945,7 +1166,7 @@ __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __col |
| 945 | 1166 | |
| 946 | 1167 | } // namespace __format_spec |
| 947 | 1168 | |
| 948 | #endif //_LIBCPP_STD_VER > 17 | |
| 1169 | #endif //_LIBCPP_STD_VER >= 20 | |
| 949 | 1170 | |
| 950 | 1171 | _LIBCPP_END_NAMESPACE_STD |
| 951 | 1172 |
lib/libcxx/include/__format/range_default_formatter.h+52-33| ... | ... | @@ -14,22 +14,25 @@ |
| 14 | 14 | # pragma GCC system_header |
| 15 | 15 | #endif |
| 16 | 16 | |
| 17 | #include <__availability> | |
| 17 | #include <__algorithm/ranges_copy.h> | |
| 18 | 18 | #include <__chrono/statically_widen.h> |
| 19 | 19 | #include <__concepts/same_as.h> |
| 20 | 20 | #include <__config> |
| 21 | 21 | #include <__format/concepts.h> |
| 22 | 22 | #include <__format/formatter.h> |
| 23 | 23 | #include <__format/range_formatter.h> |
| 24 | #include <__iterator/back_insert_iterator.h> | |
| 24 | 25 | #include <__ranges/concepts.h> |
| 26 | #include <__ranges/data.h> | |
| 27 | #include <__ranges/size.h> | |
| 28 | #include <__type_traits/conditional.h> | |
| 25 | 29 | #include <__type_traits/remove_cvref.h> |
| 26 | 30 | #include <__utility/pair.h> |
| 27 | 31 | #include <string_view> |
| 28 | #include <tuple> | |
| 29 | 32 | |
| 30 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 34 | |
| 32 | #if _LIBCPP_STD_VER > 20 | |
| 35 | #if _LIBCPP_STD_VER >= 23 | |
| 33 | 36 | |
| 34 | 37 | template <class _Rp, class _CharT> |
| 35 | 38 | concept __const_formattable_range = |
| ... | ... | @@ -83,40 +86,23 @@ inline constexpr range_format format_kind<_Rp> = [] { |
| 83 | 86 | return range_format::sequence; |
| 84 | 87 | }(); |
| 85 | 88 | |
| 86 | // This is a non-standard work-around to fix instantiation of | |
| 87 | // formatter<const _CharT[N], _CharT> | |
| 88 | // const _CharT[N] satisfies the ranges::input_range concept. | |
| 89 | // remove_cvref_t<const _CharT[N]> is _CharT[N] so it does not satisfy the | |
| 90 | // requirement of the above specialization. Instead it will instantiate the | |
| 91 | // primary template, which is ill-formed. | |
| 92 | // | |
| 93 | // An alternative solution is to remove the offending formatter. | |
| 94 | // | |
| 95 | // https://godbolt.org/z/bqjhhaexx | |
| 96 | // | |
| 97 | // The removal is proposed in LWG3833, but use the work-around until the issue | |
| 98 | // has been adopted. | |
| 99 | // TODO FMT Implement LWG3833. | |
| 100 | template <class _CharT, size_t N> | |
| 101 | inline constexpr range_format format_kind<const _CharT[N]> = range_format::disabled; | |
| 102 | ||
| 103 | 89 | template <range_format _Kp, ranges::input_range _Rp, class _CharT> |
| 104 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter; | |
| 90 | struct _LIBCPP_TEMPLATE_VIS __range_default_formatter; | |
| 105 | 91 | |
| 106 | 92 | // Required specializations |
| 107 | 93 | |
| 108 | 94 | template <ranges::input_range _Rp, class _CharT> |
| 109 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::sequence, _Rp, _CharT> { | |
| 95 | struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> { | |
| 110 | 96 | private: |
| 111 | 97 | using __maybe_const_r = __fmt_maybe_const<_Rp, _CharT>; |
| 112 | 98 | range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_; |
| 113 | 99 | |
| 114 | 100 | public: |
| 115 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { | |
| 101 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept { | |
| 116 | 102 | __underlying_.set_separator(__separator); |
| 117 | 103 | } |
| 118 | 104 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 119 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { | |
| 105 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept { | |
| 120 | 106 | __underlying_.set_brackets(__opening_bracket, __closing_bracket); |
| 121 | 107 | } |
| 122 | 108 | |
| ... | ... | @@ -125,14 +111,15 @@ public: |
| 125 | 111 | return __underlying_.parse(__ctx); |
| 126 | 112 | } |
| 127 | 113 | |
| 128 | template <class FormatContext> | |
| 129 | _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const { | |
| 114 | template <class _FormatContext> | |
| 115 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 116 | format(__maybe_const_r& __range, _FormatContext& __ctx) const { | |
| 130 | 117 | return __underlying_.format(__range, __ctx); |
| 131 | 118 | } |
| 132 | 119 | }; |
| 133 | 120 | |
| 134 | 121 | template <ranges::input_range _Rp, class _CharT> |
| 135 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::map, _Rp, _CharT> { | |
| 122 | struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> { | |
| 136 | 123 | private: |
| 137 | 124 | using __maybe_const_map = __fmt_maybe_const<_Rp, _CharT>; |
| 138 | 125 | using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>; |
| ... | ... | @@ -160,7 +147,7 @@ public: |
| 160 | 147 | }; |
| 161 | 148 | |
| 162 | 149 | template <ranges::input_range _Rp, class _CharT> |
| 163 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<range_format::set, _Rp, _CharT> { | |
| 150 | struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> { | |
| 164 | 151 | private: |
| 165 | 152 | using __maybe_const_set = __fmt_maybe_const<_Rp, _CharT>; |
| 166 | 153 | using __element_type = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>; |
| ... | ... | @@ -185,16 +172,48 @@ public: |
| 185 | 172 | |
| 186 | 173 | template <range_format _Kp, ranges::input_range _Rp, class _CharT> |
| 187 | 174 | requires(_Kp == range_format::string || _Kp == range_format::debug_string) |
| 188 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT __range_default_formatter<_Kp, _Rp, _CharT> { | |
| 189 | __range_default_formatter() = delete; // TODO FMT Implement | |
| 175 | struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<_Kp, _Rp, _CharT> { | |
| 176 | private: | |
| 177 | // This deviates from the Standard, there the exposition only type is | |
| 178 | // formatter<basic_string<charT>, charT> underlying_; | |
| 179 | // Using a string_view allows the format function to avoid a copy of the | |
| 180 | // input range when it is a contigious range. | |
| 181 | formatter<basic_string_view<_CharT>, _CharT> __underlying_; | |
| 182 | ||
| 183 | public: | |
| 184 | template <class _ParseContext> | |
| 185 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 186 | typename _ParseContext::iterator __i = __underlying_.parse(__ctx); | |
| 187 | if constexpr (_Kp == range_format::debug_string) | |
| 188 | __underlying_.set_debug_format(); | |
| 189 | return __i; | |
| 190 | } | |
| 191 | ||
| 192 | template <class _FormatContext> | |
| 193 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator | |
| 194 | format(conditional_t<ranges::input_range<const _Rp>, const _Rp&, _Rp&> __range, _FormatContext& __ctx) const { | |
| 195 | // When the range is contiguous use a basic_string_view instead to avoid a | |
| 196 | // copy of the underlying data. The basic_string_view formatter | |
| 197 | // specialization is the "basic" string formatter in libc++. | |
| 198 | if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) | |
| 199 | return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx); | |
| 200 | else { | |
| 201 | // P2106's from_range has not been implemented yet. Instead use a simple | |
| 202 | // copy operation. | |
| 203 | // TODO FMT use basic_string's "from_range" constructor. | |
| 204 | // return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx); | |
| 205 | basic_string<_CharT> __str; | |
| 206 | std::ranges::copy(__range, back_insert_iterator{__str}); | |
| 207 | return __underlying_.format(static_cast<basic_string_view<_CharT>>(__str), __ctx); | |
| 208 | } | |
| 209 | } | |
| 190 | 210 | }; |
| 191 | 211 | |
| 192 | 212 | template <ranges::input_range _Rp, class _CharT> |
| 193 | 213 | requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>) |
| 194 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Rp, _CharT> | |
| 195 | : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {}; | |
| 214 | struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {}; | |
| 196 | 215 | |
| 197 | #endif //_LIBCPP_STD_VER > 20 | |
| 216 | #endif //_LIBCPP_STD_VER >= 23 | |
| 198 | 217 | |
| 199 | 218 | _LIBCPP_END_NAMESPACE_STD |
| 200 | 219 |
lib/libcxx/include/__format/range_formatter.h+62-47| ... | ... | @@ -15,13 +15,11 @@ |
| 15 | 15 | #endif |
| 16 | 16 | |
| 17 | 17 | #include <__algorithm/ranges_copy.h> |
| 18 | #include <__availability> | |
| 19 | 18 | #include <__chrono/statically_widen.h> |
| 20 | 19 | #include <__concepts/same_as.h> |
| 21 | 20 | #include <__config> |
| 22 | 21 | #include <__format/buffer.h> |
| 23 | 22 | #include <__format/concepts.h> |
| 24 | #include <__format/format_args.h> | |
| 25 | 23 | #include <__format/format_context.h> |
| 26 | 24 | #include <__format/format_error.h> |
| 27 | 25 | #include <__format/formatter.h> |
| ... | ... | @@ -36,54 +34,73 @@ |
| 36 | 34 | |
| 37 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 36 | |
| 39 | #if _LIBCPP_STD_VER > 20 | |
| 37 | #if _LIBCPP_STD_VER >= 23 | |
| 40 | 38 | |
| 41 | 39 | template <class _Tp, class _CharT = char> |
| 42 | 40 | requires same_as<remove_cvref_t<_Tp>, _Tp> && formattable<_Tp, _CharT> |
| 43 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter { | |
| 44 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) { | |
| 41 | struct _LIBCPP_TEMPLATE_VIS range_formatter { | |
| 42 | _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept { | |
| 45 | 43 | __separator_ = __separator; |
| 46 | 44 | } |
| 47 | 45 | _LIBCPP_HIDE_FROM_ABI constexpr void |
| 48 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) { | |
| 46 | set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept { | |
| 49 | 47 | __opening_bracket_ = __opening_bracket; |
| 50 | 48 | __closing_bracket_ = __closing_bracket; |
| 51 | 49 | } |
| 52 | 50 | |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() { return __underlying_; } | |
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const { return __underlying_; } | |
| 51 | _LIBCPP_HIDE_FROM_ABI constexpr formatter<_Tp, _CharT>& underlying() noexcept { return __underlying_; } | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr const formatter<_Tp, _CharT>& underlying() const noexcept { return __underlying_; } | |
| 55 | 53 | |
| 56 | 54 | template <class _ParseContext> |
| 57 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __parse_ctx) { | |
| 58 | const _CharT* __begin = __parser_.__parse(__parse_ctx, __format_spec::__fields_range); | |
| 59 | const _CharT* __end = __parse_ctx.end(); | |
| 60 | if (__begin == __end) | |
| 61 | return __begin; | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 56 | auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_range); | |
| 57 | auto __end = __ctx.end(); | |
| 58 | // Note the cases where __begin == __end in this code only happens when the | |
| 59 | // replacement-field has no terminating }, or when the parse is manually | |
| 60 | // called with a format-spec. The former is an error and the latter means | |
| 61 | // using a formatter without the format functions or print. | |
| 62 | if (__begin == __end) [[unlikely]] | |
| 63 | return __parse_empty_range_underlying_spec(__ctx, __begin); | |
| 62 | 64 | |
| 63 | 65 | // The n field overrides a possible m type, therefore delay applying the |
| 64 | 66 | // effect of n until the type has been procesed. |
| 65 | bool __clear_brackets = (*__begin == _CharT('n')); | |
| 66 | if (__clear_brackets) { | |
| 67 | ++__begin; | |
| 68 | if (__begin == __end) { | |
| 69 | // Since there is no more data, clear the brackets before returning. | |
| 70 | set_brackets({}, {}); | |
| 71 | return __begin; | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | 67 | __parse_type(__begin, __end); |
| 76 | if (__clear_brackets) | |
| 68 | if (__parser_.__clear_brackets_) | |
| 77 | 69 | set_brackets({}, {}); |
| 78 | if (__begin == __end) | |
| 79 | return __begin; | |
| 70 | if (__begin == __end) [[unlikely]] | |
| 71 | return __parse_empty_range_underlying_spec(__ctx, __begin); | |
| 80 | 72 | |
| 81 | 73 | bool __has_range_underlying_spec = *__begin == _CharT(':'); |
| 74 | if (__has_range_underlying_spec) { | |
| 75 | // range-underlying-spec: | |
| 76 | // : format-spec | |
| 77 | ++__begin; | |
| 78 | } else if (__begin != __end && *__begin != _CharT('}')) | |
| 79 | // When there is no underlaying range the current parse should have | |
| 80 | // consumed the format-spec. If not, the not consumed input will be | |
| 81 | // processed by the underlying. For example {:-} for a range in invalid, | |
| 82 | // the sign field is not present. Without this check the underlying_ will | |
| 83 | // get -} as input which my be valid. | |
| 84 | std::__throw_format_error("The format specifier should consume the input or end with a '}'"); | |
| 85 | ||
| 86 | __ctx.advance_to(__begin); | |
| 87 | __begin = __underlying_.parse(__ctx); | |
| 88 | ||
| 89 | // This test should not be required if __has_range_underlying_spec is false. | |
| 90 | // However this test makes sure the underlying formatter left the parser in | |
| 91 | // a valid state. (Note this is not a full protection against evil parsers. | |
| 92 | // For example | |
| 93 | // } this is test for the next argument {} | |
| 94 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ | |
| 95 | // could consume more than it should. | |
| 96 | if (__begin != __end && *__begin != _CharT('}')) | |
| 97 | std::__throw_format_error("The format specifier should consume the input or end with a '}'"); | |
| 98 | ||
| 82 | 99 | if (__parser_.__type_ != __format_spec::__type::__default) { |
| 83 | 100 | // [format.range.formatter]/6 |
| 84 | 101 | // If the range-type is s or ?s, then there shall be no n option and no |
| 85 | 102 | // range-underlying-spec. |
| 86 | if (__clear_brackets) { | |
| 103 | if (__parser_.__clear_brackets_) { | |
| 87 | 104 | if (__parser_.__type_ == __format_spec::__type::__string) |
| 88 | 105 | std::__throw_format_error("The n option and type s can't be used together"); |
| 89 | 106 | std::__throw_format_error("The n option and type ?s can't be used together"); |
| ... | ... | @@ -96,20 +113,6 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter { |
| 96 | 113 | } else if (!__has_range_underlying_spec) |
| 97 | 114 | std::__set_debug_format(__underlying_); |
| 98 | 115 | |
| 99 | if (__has_range_underlying_spec) { | |
| 100 | // range-underlying-spec: | |
| 101 | // : format-spec | |
| 102 | ++__begin; | |
| 103 | if (__begin == __end) | |
| 104 | return __begin; | |
| 105 | ||
| 106 | __parse_ctx.advance_to(__begin); | |
| 107 | __begin = __underlying_.parse(__parse_ctx); | |
| 108 | } | |
| 109 | ||
| 110 | if (__begin != __end && *__begin != _CharT('}')) | |
| 111 | std::__throw_format_error("The format-spec should consume the input or end with a '}'"); | |
| 112 | ||
| 113 | 116 | return __begin; |
| 114 | 117 | } |
| 115 | 118 | |
| ... | ... | @@ -211,7 +214,8 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT range_formatter { |
| 211 | 214 | __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left}; |
| 212 | 215 | |
| 213 | 216 | private: |
| 214 | _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin, const _CharT* __end) { | |
| 217 | template <contiguous_iterator _Iterator> | |
| 218 | _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin, _Iterator __end) { | |
| 215 | 219 | switch (*__begin) { |
| 216 | 220 | case _CharT('m'): |
| 217 | 221 | if constexpr (__fmt_pair_like<_Tp>) { |
| ... | ... | @@ -219,7 +223,7 @@ private: |
| 219 | 223 | set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", ")); |
| 220 | 224 | ++__begin; |
| 221 | 225 | } else |
| 222 | std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple"); | |
| 226 | std::__throw_format_error("Type m requires a pair or a tuple with two elements"); | |
| 223 | 227 | break; |
| 224 | 228 | |
| 225 | 229 | case _CharT('s'): |
| ... | ... | @@ -227,28 +231,39 @@ private: |
| 227 | 231 | __parser_.__type_ = __format_spec::__type::__string; |
| 228 | 232 | ++__begin; |
| 229 | 233 | } else |
| 230 | std::__throw_format_error("The range-format-spec type s requires formatting a character type"); | |
| 234 | std::__throw_format_error("Type s requires character type as formatting argument"); | |
| 231 | 235 | break; |
| 232 | 236 | |
| 233 | 237 | case _CharT('?'): |
| 234 | 238 | ++__begin; |
| 235 | 239 | if (__begin == __end || *__begin != _CharT('s')) |
| 236 | std::__throw_format_error("The format-spec should consume the input or end with a '}'"); | |
| 240 | std::__throw_format_error("The format specifier should consume the input or end with a '}'"); | |
| 237 | 241 | if constexpr (same_as<_Tp, _CharT>) { |
| 238 | 242 | __parser_.__type_ = __format_spec::__type::__debug; |
| 239 | 243 | ++__begin; |
| 240 | 244 | } else |
| 241 | std::__throw_format_error("The range-format-spec type ?s requires formatting a character type"); | |
| 245 | std::__throw_format_error("Type ?s requires character type as formatting argument"); | |
| 242 | 246 | } |
| 243 | 247 | } |
| 244 | 248 | |
| 249 | template <class _ParseContext> | |
| 250 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator | |
| 251 | __parse_empty_range_underlying_spec(_ParseContext& __ctx, typename _ParseContext::iterator __begin) { | |
| 252 | __ctx.advance_to(__begin); | |
| 253 | [[maybe_unused]] typename _ParseContext::iterator __result = __underlying_.parse(__ctx); | |
| 254 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 255 | __result == __begin, | |
| 256 | "the underlying's parse function should not advance the input beyond the end of the input"); | |
| 257 | return __begin; | |
| 258 | } | |
| 259 | ||
| 245 | 260 | formatter<_Tp, _CharT> __underlying_; |
| 246 | 261 | basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", "); |
| 247 | 262 | basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "["); |
| 248 | 263 | basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "]"); |
| 249 | 264 | }; |
| 250 | 265 | |
| 251 | #endif //_LIBCPP_STD_VER > 20 | |
| 266 | #endif //_LIBCPP_STD_VER >= 23 | |
| 252 | 267 | |
| 253 | 268 | _LIBCPP_END_NAMESPACE_STD |
| 254 | 269 |
lib/libcxx/include/__format/unicode.h+186-194| ... | ... | @@ -11,11 +11,13 @@ |
| 11 | 11 | #define _LIBCPP___FORMAT_UNICODE_H |
| 12 | 12 | |
| 13 | 13 | #include <__assert> |
| 14 | #include <__bit/countl.h> | |
| 15 | #include <__concepts/same_as.h> | |
| 14 | 16 | #include <__config> |
| 15 | 17 | #include <__format/extended_grapheme_cluster_table.h> |
| 16 | #include <__type_traits/make_unsigned.h> | |
| 17 | #include <__utility/unreachable.h> | |
| 18 | #include <bit> | |
| 18 | #include <__iterator/concepts.h> | |
| 19 | #include <__iterator/readable_traits.h> // iter_value_t | |
| 20 | #include <string_view> | |
| 19 | 21 | |
| 20 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 23 | # pragma GCC system_header |
| ... | ... | @@ -23,27 +25,32 @@ |
| 23 | 25 | |
| 24 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 27 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 29 | |
| 28 | 30 | namespace __unicode { |
| 29 | 31 | |
| 30 | # if _LIBCPP_STD_VER > 20 | |
| 31 | ||
| 32 | /// The result of consuming a code point using P2286' semantics | |
| 33 | /// | |
| 34 | /// TODO FMT Combine __consume and __consume_p2286 in one function. | |
| 35 | struct __consume_p2286_result { | |
| 36 | // A size of 0 means well formed. This to differenciate between | |
| 37 | // a valid code point and a code unit that's invalid like 0b11111xxx. | |
| 38 | int __ill_formed_size; | |
| 39 | ||
| 40 | // If well formed the consumed code point. | |
| 41 | // Otherwise the ill-formed code units as unsigned 8-bit values. They are | |
| 42 | // stored in reverse order, to make it easier to extract the values. | |
| 43 | char32_t __value; | |
| 32 | // Helper struct for the result of a consume operation. | |
| 33 | // | |
| 34 | // The status value for a correct code point is 0. This allows a valid value to | |
| 35 | // be used without masking. | |
| 36 | // When the decoding fails it know the number of code units affected. For the | |
| 37 | // current use-cases that value is not needed, therefore it is not stored. | |
| 38 | // The escape routine needs the number of code units for both a valid and | |
| 39 | // invalid character and keeps track of it itself. Doing it in this result | |
| 40 | // unconditionally would give some overhead when the value is unneeded. | |
| 41 | struct __consume_result { | |
| 42 | // When __status == __ok it contains the decoded code point. | |
| 43 | // Else it contains the replacement character U+FFFD | |
| 44 | char32_t __code_point : 31; | |
| 45 | ||
| 46 | enum : char32_t { | |
| 47 | // Consumed a well-formed code point. | |
| 48 | __ok = 0, | |
| 49 | // Encountered invalid UTF-8 | |
| 50 | __error = 1 | |
| 51 | } __status : 1 {__ok}; | |
| 44 | 52 | }; |
| 45 | ||
| 46 | # endif // _LIBCPP_STD_VER > 20 | |
| 53 | static_assert(sizeof(__consume_result) == sizeof(char32_t)); | |
| 47 | 54 | |
| 48 | 55 | # ifndef _LIBCPP_HAS_NO_UNICODE |
| 49 | 56 | |
| ... | ... | @@ -62,9 +69,41 @@ struct __consume_p2286_result { |
| 62 | 69 | |
| 63 | 70 | inline constexpr char32_t __replacement_character = U'\ufffd'; |
| 64 | 71 | |
| 65 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) { | |
| 72 | // The error of a consume operation. | |
| 73 | // | |
| 74 | // This sets the code point to the replacement character. This code point does | |
| 75 | // not participate in the grapheme clustering, so grapheme clustering code can | |
| 76 | // ignore the error status and always use the code point. | |
| 77 | inline constexpr __consume_result __consume_result_error{__replacement_character, __consume_result::__error}; | |
| 78 | ||
| 79 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_high_surrogate(char32_t __value) { | |
| 80 | return __value >= 0xd800 && __value <= 0xdbff; | |
| 81 | } | |
| 82 | ||
| 83 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __is_low_surrogate(char32_t __value) { | |
| 84 | return __value >= 0xdc00 && __value <= 0xdfff; | |
| 85 | } | |
| 86 | ||
| 87 | // https://www.unicode.org/glossary/#surrogate_code_point | |
| 88 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_surrogate(char32_t __value) { | |
| 89 | return __value >= 0xd800 && __value <= 0xdfff; | |
| 90 | } | |
| 91 | ||
| 92 | // https://www.unicode.org/glossary/#code_point | |
| 93 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_code_point(char32_t __value) { | |
| 94 | return __value <= 0x10ffff; | |
| 95 | } | |
| 96 | ||
| 97 | // https://www.unicode.org/glossary/#unicode_scalar_value | |
| 98 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline constexpr bool __is_scalar_value(char32_t __value) { | |
| 99 | return __unicode::__is_code_point(__value) && !__unicode::__is_surrogate(__value); | |
| 100 | } | |
| 101 | ||
| 102 | template <contiguous_iterator _Iterator> | |
| 103 | requires same_as<iter_value_t<_Iterator>, char> | |
| 104 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) { | |
| 66 | 105 | do { |
| 67 | if ((*__char & 0b1000'0000) != 0b1000'0000) | |
| 106 | if ((*__char & 0b1100'0000) != 0b1000'0000) | |
| 68 | 107 | return false; |
| 69 | 108 | --__count; |
| 70 | 109 | ++__char; |
| ... | ... | @@ -82,133 +121,116 @@ class __code_point_view; |
| 82 | 121 | /// UTF-8 specialization. |
| 83 | 122 | template <> |
| 84 | 123 | class __code_point_view<char> { |
| 124 | using _Iterator = basic_string_view<char>::const_iterator; | |
| 125 | ||
| 85 | 126 | public: |
| 86 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last) | |
| 127 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last) | |
| 87 | 128 | : __first_(__first), __last_(__last) {} |
| 88 | 129 | |
| 89 | 130 | _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } |
| 90 | _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; } | |
| 131 | _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; } | |
| 91 | 132 | |
| 92 | _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { | |
| 93 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 133 | // https://www.unicode.org/versions/latest/ch03.pdf#G7404 | |
| 134 | // Based on Table 3-7, Well-Formed UTF-8 Byte Sequences | |
| 135 | // | |
| 136 | // Code Points First Byte Second Byte Third Byte Fourth Byte Remarks | |
| 137 | // U+0000..U+007F 00..7F U+0000..U+007F 1 code unit range | |
| 138 | // C0..C1 80..BF invalid overlong encoding | |
| 139 | // U+0080..U+07FF C2..DF 80..BF U+0080..U+07FF 2 code unit range | |
| 140 | // E0 80..9F 80..BF invalid overlong encoding | |
| 141 | // U+0800..U+0FFF E0 A0..BF 80..BF U+0800..U+FFFF 3 code unit range | |
| 142 | // U+1000..U+CFFF E1..EC 80..BF 80..BF | |
| 143 | // U+D000..U+D7FF ED 80..9F 80..BF | |
| 144 | // U+D800..U+DFFF ED A0..BF 80..BF invalid encoding of surrogate code point | |
| 145 | // U+E000..U+FFFF EE..EF 80..BF 80..BF | |
| 146 | // F0 80..8F 80..BF 80..BF invalid overlong encoding | |
| 147 | // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF U+10000..U+10FFFF 4 code unit range | |
| 148 | // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF | |
| 149 | // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF | |
| 150 | // F4 90..BF 80..BF 80..BF U+110000.. invalid code point range | |
| 151 | // | |
| 152 | // Unlike other parsers, these invalid entries are tested after decoding. | |
| 153 | // - The parser always needs to consume these code units | |
| 154 | // - The code is optimized for well-formed UTF-8 | |
| 155 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { | |
| 156 | _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input"); | |
| 94 | 157 | |
| 95 | 158 | // Based on the number of leading 1 bits the number of code units in the |
| 96 | 159 | // code point can be determined. See |
| 97 | 160 | // https://en.wikipedia.org/wiki/UTF-8#Encoding |
| 98 | switch (_VSTD::countl_one(static_cast<unsigned char>(*__first_))) { | |
| 161 | switch (std::countl_one(static_cast<unsigned char>(*__first_))) { | |
| 99 | 162 | case 0: |
| 100 | return *__first_++; | |
| 163 | return {static_cast<unsigned char>(*__first_++)}; | |
| 101 | 164 | |
| 102 | case 2: | |
| 165 | case 2: { | |
| 103 | 166 | if (__last_ - __first_ < 2 || !__unicode::__is_continuation(__first_ + 1, 1)) [[unlikely]] |
| 104 | 167 | break; |
| 105 | else { | |
| 106 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f; | |
| 107 | __value <<= 6; | |
| 108 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 109 | return __value; | |
| 110 | } | |
| 111 | 168 | |
| 112 | case 3: | |
| 113 | if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]] | |
| 114 | break; | |
| 115 | else { | |
| 116 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f; | |
| 117 | __value <<= 6; | |
| 118 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 119 | __value <<= 6; | |
| 120 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 121 | return __value; | |
| 122 | } | |
| 169 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f; | |
| 170 | __value <<= 6; | |
| 171 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 123 | 172 | |
| 124 | case 4: | |
| 125 | if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]] | |
| 126 | break; | |
| 127 | else { | |
| 128 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07; | |
| 129 | __value <<= 6; | |
| 130 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 131 | __value <<= 6; | |
| 132 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 133 | __value <<= 6; | |
| 134 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 135 | return __value; | |
| 136 | } | |
| 137 | } | |
| 138 | // An invalid number of leading ones can be garbage or a code unit in the | |
| 139 | // middle of a code point. By consuming one code unit the parser may get | |
| 140 | // "in sync" after a few code units. | |
| 141 | ++__first_; | |
| 142 | return __replacement_character; | |
| 143 | } | |
| 144 | ||
| 145 | # if _LIBCPP_STD_VER > 20 | |
| 146 | _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { | |
| 147 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 173 | // These values should be encoded in 1 UTF-8 code unit. | |
| 174 | if (__value < 0x0080) [[unlikely]] | |
| 175 | return __consume_result_error; | |
| 148 | 176 | |
| 149 | // Based on the number of leading 1 bits the number of code units in the | |
| 150 | // code point can be determined. See | |
| 151 | // https://en.wikipedia.org/wiki/UTF-8#Encoding | |
| 152 | switch (std::countl_one(static_cast<unsigned char>(*__first_))) { | |
| 153 | case 0: | |
| 154 | return {0, static_cast<unsigned char>(*__first_++)}; | |
| 177 | return {__value}; | |
| 178 | } | |
| 155 | 179 | |
| 156 | case 2: | |
| 157 | if (__last_ - __first_ < 2) [[unlikely]] | |
| 180 | case 3: { | |
| 181 | if (__last_ - __first_ < 3 || !__unicode::__is_continuation(__first_ + 1, 2)) [[unlikely]] | |
| 158 | 182 | break; |
| 159 | 183 | |
| 160 | if (__unicode::__is_continuation(__first_ + 1, 1)) { | |
| 161 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x1f; | |
| 162 | __value <<= 6; | |
| 163 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 164 | return {0, __value}; | |
| 165 | } | |
| 166 | break; | |
| 184 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f; | |
| 185 | __value <<= 6; | |
| 186 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 187 | __value <<= 6; | |
| 188 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 167 | 189 | |
| 168 | case 3: | |
| 169 | if (__last_ - __first_ < 3) [[unlikely]] | |
| 170 | break; | |
| 190 | // These values should be encoded in 1 or 2 UTF-8 code units. | |
| 191 | if (__value < 0x0800) [[unlikely]] | |
| 192 | return __consume_result_error; | |
| 171 | 193 | |
| 172 | if (__unicode::__is_continuation(__first_ + 1, 2)) { | |
| 173 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x0f; | |
| 174 | __value <<= 6; | |
| 175 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 176 | __value <<= 6; | |
| 177 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 178 | return {0, __value}; | |
| 179 | } | |
| 180 | break; | |
| 194 | // A surrogate value is always encoded in 3 UTF-8 code units. | |
| 195 | if (__unicode::__is_surrogate(__value)) [[unlikely]] | |
| 196 | return __consume_result_error; | |
| 197 | ||
| 198 | return {__value}; | |
| 199 | } | |
| 181 | 200 | |
| 182 | case 4: | |
| 183 | if (__last_ - __first_ < 4) [[unlikely]] | |
| 201 | case 4: { | |
| 202 | if (__last_ - __first_ < 4 || !__unicode::__is_continuation(__first_ + 1, 3)) [[unlikely]] | |
| 184 | 203 | break; |
| 185 | 204 | |
| 186 | if (__unicode::__is_continuation(__first_ + 1, 3)) { | |
| 187 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07; | |
| 188 | __value <<= 6; | |
| 189 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 190 | __value <<= 6; | |
| 191 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 192 | __value <<= 6; | |
| 193 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 205 | char32_t __value = static_cast<unsigned char>(*__first_++) & 0x07; | |
| 206 | __value <<= 6; | |
| 207 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 208 | __value <<= 6; | |
| 209 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 210 | __value <<= 6; | |
| 211 | __value |= static_cast<unsigned char>(*__first_++) & 0x3f; | |
| 194 | 212 | |
| 195 | if (__value > 0x10FFFF) // Outside the valid Unicode range? | |
| 196 | return {4, __value}; | |
| 213 | // These values should be encoded in 1, 2, or 3 UTF-8 code units. | |
| 214 | if (__value < 0x10000) [[unlikely]] | |
| 215 | return __consume_result_error; | |
| 197 | 216 | |
| 198 | return {0, __value}; | |
| 199 | } | |
| 200 | break; | |
| 217 | // A value too large is always encoded in 4 UTF-8 code units. | |
| 218 | if (!__unicode::__is_code_point(__value)) [[unlikely]] | |
| 219 | return __consume_result_error; | |
| 220 | ||
| 221 | return {__value}; | |
| 222 | } | |
| 201 | 223 | } |
| 202 | 224 | // An invalid number of leading ones can be garbage or a code unit in the |
| 203 | 225 | // middle of a code point. By consuming one code unit the parser may get |
| 204 | 226 | // "in sync" after a few code units. |
| 205 | return {1, static_cast<unsigned char>(*__first_++)}; | |
| 227 | ++__first_; | |
| 228 | return __consume_result_error; | |
| 206 | 229 | } |
| 207 | # endif // _LIBCPP_STD_VER > 20 | |
| 208 | 230 | |
| 209 | 231 | private: |
| 210 | const char* __first_; | |
| 211 | const char* __last_; | |
| 232 | _Iterator __first_; | |
| 233 | _Iterator __last_; | |
| 212 | 234 | }; |
| 213 | 235 | |
| 214 | 236 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -225,75 +247,48 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __is_surrogate_pair_low(wchar_t __value) { |
| 225 | 247 | /// - 4 UTF-32 (for example Linux) |
| 226 | 248 | template <> |
| 227 | 249 | class __code_point_view<wchar_t> { |
| 250 | using _Iterator = typename basic_string_view<wchar_t>::const_iterator; | |
| 251 | ||
| 228 | 252 | public: |
| 229 | 253 | static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value"); |
| 230 | 254 | |
| 231 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last) | |
| 255 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last) | |
| 232 | 256 | : __first_(__first), __last_(__last) {} |
| 233 | 257 | |
| 234 | _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; } | |
| 258 | _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; } | |
| 235 | 259 | _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } |
| 236 | 260 | |
| 237 | _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { | |
| 238 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 261 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { | |
| 262 | _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input"); | |
| 239 | 263 | |
| 264 | char32_t __value = static_cast<char32_t>(*__first_++); | |
| 240 | 265 | if constexpr (sizeof(wchar_t) == 2) { |
| 241 | char32_t __result = *__first_++; | |
| 242 | // Is the code unit part of a surrogate pair? See | |
| 243 | // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF | |
| 244 | if (__result >= 0xd800 && __result <= 0xDfff) { | |
| 245 | // Malformed Unicode. | |
| 246 | if (__first_ == __last_) [[unlikely]] | |
| 247 | return __replacement_character; | |
| 248 | ||
| 249 | __result -= 0xd800; | |
| 250 | __result <<= 10; | |
| 251 | __result += *__first_++ - 0xdc00; | |
| 252 | __result += 0x10000; | |
| 253 | } | |
| 254 | return __result; | |
| 266 | if (__unicode::__is_low_surrogate(__value)) [[unlikely]] | |
| 267 | return __consume_result_error; | |
| 255 | 268 | |
| 256 | } else if constexpr (sizeof(wchar_t) == 4) { | |
| 257 | char32_t __result = *__first_++; | |
| 258 | if (__result > 0x10FFFF) [[unlikely]] | |
| 259 | return __replacement_character; | |
| 260 | return __result; | |
| 261 | } else { | |
| 262 | __libcpp_unreachable(); | |
| 263 | } | |
| 264 | } | |
| 269 | if (__unicode::__is_high_surrogate(__value)) { | |
| 270 | if (__first_ == __last_ || !__unicode::__is_low_surrogate(static_cast<char32_t>(*__first_))) [[unlikely]] | |
| 271 | return __consume_result_error; | |
| 265 | 272 | |
| 266 | # if _LIBCPP_STD_VER > 20 | |
| 267 | _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { | |
| 268 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 273 | __value -= 0xd800; | |
| 274 | __value <<= 10; | |
| 275 | __value += static_cast<char32_t>(*__first_++) - 0xdc00; | |
| 276 | __value += 0x10000; | |
| 269 | 277 | |
| 270 | char32_t __result = *__first_++; | |
| 271 | if constexpr (sizeof(wchar_t) == 2) { | |
| 272 | // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF | |
| 273 | if (__is_surrogate_pair_high(__result)) { | |
| 274 | // Malformed Unicode. | |
| 275 | if (__first_ == __last_ || !__is_surrogate_pair_low(*(__first_ + 1))) [[unlikely]] | |
| 276 | return {1, __result}; | |
| 277 | ||
| 278 | __result -= 0xd800; | |
| 279 | __result <<= 10; | |
| 280 | __result += *__first_++ - 0xdc00; | |
| 281 | __result += 0x10000; | |
| 282 | } else if (__is_surrogate_pair_low(__result)) | |
| 283 | // A code point shouldn't start with the low surrogate pair | |
| 284 | return {1, __result}; | |
| 278 | if (!__unicode::__is_code_point(__value)) [[unlikely]] | |
| 279 | return __consume_result_error; | |
| 280 | } | |
| 285 | 281 | } else { |
| 286 | if (__result > 0x10FFFF) [[unlikely]] | |
| 287 | return {1, __result}; | |
| 282 | if (!__unicode::__is_scalar_value(__value)) [[unlikely]] | |
| 283 | return __consume_result_error; | |
| 288 | 284 | } |
| 289 | 285 | |
| 290 | return {0, __result}; | |
| 286 | return {__value}; | |
| 291 | 287 | } |
| 292 | # endif // _LIBCPP_STD_VER > 20 | |
| 293 | 288 | |
| 294 | 289 | private: |
| 295 | const wchar_t* __first_; | |
| 296 | const wchar_t* __last_; | |
| 290 | _Iterator __first_; | |
| 291 | _Iterator __last_; | |
| 297 | 292 | }; |
| 298 | 293 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 299 | 294 | |
| ... | ... | @@ -310,8 +305,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( |
| 310 | 305 | |
| 311 | 306 | // *** Break at the start and end of text, unless the text is empty. *** |
| 312 | 307 | |
| 313 | _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1 | |
| 314 | _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller"); // GB2 | |
| 308 | _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__sot, "should be handled in the constructor"); // GB1 | |
| 309 | _LIBCPP_ASSERT_UNCATEGORIZED(__prev != __property::__eot, "should be handled by our caller"); // GB2 | |
| 315 | 310 | |
| 316 | 311 | // *** Do not break between a CR and LF. Otherwise, break before and after controls. *** |
| 317 | 312 | if (__prev == __property::__CR && __next == __property::__LF) // GB3 |
| ... | ... | @@ -384,10 +379,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( |
| 384 | 379 | /// Therefore only this code point is extracted. |
| 385 | 380 | template <class _CharT> |
| 386 | 381 | class __extended_grapheme_cluster_view { |
| 382 | using _Iterator = typename basic_string_view<_CharT>::const_iterator; | |
| 383 | ||
| 387 | 384 | public: |
| 388 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last) | |
| 385 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last) | |
| 389 | 386 | : __code_point_view_(__first, __last), |
| 390 | __next_code_point_(__code_point_view_.__consume()), | |
| 387 | __next_code_point_(__code_point_view_.__consume().__code_point), | |
| 391 | 388 | __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {} |
| 392 | 389 | |
| 393 | 390 | struct __cluster { |
| ... | ... | @@ -401,13 +398,14 @@ public: |
| 401 | 398 | /// |
| 402 | 399 | /// It's expected the caller has the start position and thus can determine |
| 403 | 400 | /// the code unit range of the extended grapheme cluster. |
| 404 | const _CharT* __last_; | |
| 401 | _Iterator __last_; | |
| 405 | 402 | }; |
| 406 | 403 | |
| 407 | 404 | _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { |
| 408 | _LIBCPP_ASSERT( | |
| 405 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 409 | 406 | __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, |
| 410 | 407 | "can't move beyond the end of input"); |
| 408 | ||
| 411 | 409 | char32_t __code_point = __next_code_point_; |
| 412 | 410 | if (!__code_point_view_.__at_end()) |
| 413 | 411 | return {__code_point, __get_break()}; |
| ... | ... | @@ -422,17 +420,17 @@ private: |
| 422 | 420 | char32_t __next_code_point_; |
| 423 | 421 | __extended_grapheme_custer_property_boundary::__property __next_prop_; |
| 424 | 422 | |
| 425 | _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() { | |
| 423 | _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() { | |
| 426 | 424 | bool __ri_break_allowed = true; |
| 427 | 425 | bool __has_extened_pictographic = false; |
| 428 | 426 | while (true) { |
| 429 | const _CharT* __result = __code_point_view_.__position(); | |
| 427 | _Iterator __result = __code_point_view_.__position(); | |
| 430 | 428 | __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_; |
| 431 | 429 | if (__code_point_view_.__at_end()) { |
| 432 | 430 | __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; |
| 433 | 431 | return __result; |
| 434 | 432 | } |
| 435 | __next_code_point_ = __code_point_view_.__consume(); | |
| 433 | __next_code_point_ = __code_point_view_.__consume().__code_point; | |
| 436 | 434 | __next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_); |
| 437 | 435 | |
| 438 | 436 | __has_extened_pictographic |= |
| ... | ... | @@ -444,8 +442,8 @@ private: |
| 444 | 442 | } |
| 445 | 443 | }; |
| 446 | 444 | |
| 447 | template <class _CharT> | |
| 448 | __extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>; | |
| 445 | template <contiguous_iterator _Iterator> | |
| 446 | __extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>; | |
| 449 | 447 | |
| 450 | 448 | # else // _LIBCPP_HAS_NO_UNICODE |
| 451 | 449 | |
| ... | ... | @@ -453,36 +451,30 @@ __extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_gra |
| 453 | 451 | // This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define. |
| 454 | 452 | template <class _CharT> |
| 455 | 453 | class __code_point_view { |
| 454 | using _Iterator = typename basic_string_view<_CharT>::const_iterator; | |
| 455 | ||
| 456 | 456 | public: |
| 457 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last) | |
| 457 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last) | |
| 458 | 458 | : __first_(__first), __last_(__last) {} |
| 459 | 459 | |
| 460 | 460 | _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } |
| 461 | _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; } | |
| 462 | ||
| 463 | _LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept { | |
| 464 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 465 | return *__first_++; | |
| 466 | } | |
| 467 | ||
| 468 | # if _LIBCPP_STD_VER > 20 | |
| 469 | _LIBCPP_HIDE_FROM_ABI constexpr __consume_p2286_result __consume_p2286() noexcept { | |
| 470 | _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); | |
| 461 | _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; } | |
| 471 | 462 | |
| 472 | return {0, std::make_unsigned_t<_CharT>(*__first_++)}; | |
| 463 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { | |
| 464 | _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != __last_, "can't move beyond the end of input"); | |
| 465 | return {static_cast<char32_t>(*__first_++)}; | |
| 473 | 466 | } |
| 474 | # endif // _LIBCPP_STD_VER > 20 | |
| 475 | 467 | |
| 476 | 468 | private: |
| 477 | const _CharT* __first_; | |
| 478 | const _CharT* __last_; | |
| 469 | _Iterator __first_; | |
| 470 | _Iterator __last_; | |
| 479 | 471 | }; |
| 480 | 472 | |
| 481 | 473 | # endif // _LIBCPP_HAS_NO_UNICODE |
| 482 | 474 | |
| 483 | 475 | } // namespace __unicode |
| 484 | 476 | |
| 485 | #endif //_LIBCPP_STD_VER > 17 | |
| 477 | #endif //_LIBCPP_STD_VER >= 20 | |
| 486 | 478 | |
| 487 | 479 | _LIBCPP_END_NAMESPACE_STD |
| 488 | 480 |
lib/libcxx/include/__format/width_estimation_table.h created+271| ... | ... | @@ -0,0 +1,271 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | // WARNING, this entire header is generated by | |
| 11 | // utils/generate_width_estimation_table.py | |
| 12 | // DO NOT MODIFY! | |
| 13 | ||
| 14 | // UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE | |
| 15 | // | |
| 16 | // See Terms of Use <https://www.unicode.org/copyright.html> | |
| 17 | // for definitions of Unicode Inc.'s Data Files and Software. | |
| 18 | // | |
| 19 | // NOTICE TO USER: Carefully read the following legal agreement. | |
| 20 | // BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S | |
| 21 | // DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), | |
| 22 | // YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE | |
| 23 | // TERMS AND CONDITIONS OF THIS AGREEMENT. | |
| 24 | // IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE | |
| 25 | // THE DATA FILES OR SOFTWARE. | |
| 26 | // | |
| 27 | // COPYRIGHT AND PERMISSION NOTICE | |
| 28 | // | |
| 29 | // Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. | |
| 30 | // Distributed under the Terms of Use in https://www.unicode.org/copyright.html. | |
| 31 | // | |
| 32 | // Permission is hereby granted, free of charge, to any person obtaining | |
| 33 | // a copy of the Unicode data files and any associated documentation | |
| 34 | // (the "Data Files") or Unicode software and any associated documentation | |
| 35 | // (the "Software") to deal in the Data Files or Software | |
| 36 | // without restriction, including without limitation the rights to use, | |
| 37 | // copy, modify, merge, publish, distribute, and/or sell copies of | |
| 38 | // the Data Files or Software, and to permit persons to whom the Data Files | |
| 39 | // or Software are furnished to do so, provided that either | |
| 40 | // (a) this copyright and permission notice appear with all copies | |
| 41 | // of the Data Files or Software, or | |
| 42 | // (b) this copyright and permission notice appear in associated | |
| 43 | // Documentation. | |
| 44 | // | |
| 45 | // THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF | |
| 46 | // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |
| 47 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 48 | // NONINFRINGEMENT OF THIRD PARTY RIGHTS. | |
| 49 | // IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS | |
| 50 | // NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL | |
| 51 | // DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
| 52 | // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
| 53 | // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
| 54 | // PERFORMANCE OF THE DATA FILES OR SOFTWARE. | |
| 55 | // | |
| 56 | // Except as contained in this notice, the name of a copyright holder | |
| 57 | // shall not be used in advertising or otherwise to promote the sale, | |
| 58 | // use or other dealings in these Data Files or Software without prior | |
| 59 | // written authorization of the copyright holder. | |
| 60 | ||
| 61 | #ifndef _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H | |
| 62 | #define _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H | |
| 63 | ||
| 64 | #include <__algorithm/ranges_upper_bound.h> | |
| 65 | #include <__config> | |
| 66 | #include <cstddef> | |
| 67 | #include <cstdint> | |
| 68 | ||
| 69 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 70 | # pragma GCC system_header | |
| 71 | #endif | |
| 72 | ||
| 73 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 74 | ||
| 75 | #if _LIBCPP_STD_VER >= 20 | |
| 76 | ||
| 77 | namespace __width_estimation_table { | |
| 78 | ||
| 79 | /// The entries of the characters with an estimated width of 2. | |
| 80 | /// | |
| 81 | /// Contains the entries for [format.string.std]/12 | |
| 82 | /// - Any code point with the East_Asian_Width="W" or East_Asian_Width="F" | |
| 83 | /// Derived Extracted Property as described by UAX #44 | |
| 84 | /// - U+4DC0 - U+4DFF (Yijing Hexagram Symbols) | |
| 85 | /// - U+1F300 - U+1F5FF (Miscellaneous Symbols and Pictographs) | |
| 86 | /// - U+1F900 - U+1F9FF (Supplemental Symbols and Pictographs) | |
| 87 | /// | |
| 88 | /// The data is generated from | |
| 89 | /// - https://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt | |
| 90 | /// - The "overrides" in [format.string.std]/12 | |
| 91 | /// | |
| 92 | /// The format of EastAsianWidth.txt is two fields separated by a semicolon. | |
| 93 | /// Field 0: Unicode code point value or range of code point values | |
| 94 | /// Field 1: East_Asian_Width property, consisting of one of the following values: | |
| 95 | /// "A", "F", "H", "N", "Na", "W" | |
| 96 | /// - All code points, assigned or unassigned, that are not listed | |
| 97 | /// explicitly are given the value "N". | |
| 98 | /// - The unassigned code points in the following blocks default to "W": | |
| 99 | /// CJK Unified Ideographs Extension A: U+3400..U+4DBF | |
| 100 | /// CJK Unified Ideographs: U+4E00..U+9FFF | |
| 101 | /// CJK Compatibility Ideographs: U+F900..U+FAFF | |
| 102 | /// - All undesignated code points in Planes 2 and 3, whether inside or | |
| 103 | /// outside of allocated blocks, default to "W": | |
| 104 | /// Plane 2: U+20000..U+2FFFD | |
| 105 | /// Plane 3: U+30000..U+3FFFD | |
| 106 | /// | |
| 107 | /// The table is similar to the table | |
| 108 | /// __extended_grapheme_custer_property_boundary::__entries | |
| 109 | /// which explains the details of these classes. The only difference is this | |
| 110 | /// table lacks a property, thus having more bits available for the size. | |
| 111 | /// | |
| 112 | /// The maximum code point that has an estimated width of 2 is U+3FFFD. This | |
| 113 | /// value can be encoded in 18 bits. Thus the upper 3 bits of the code point | |
| 114 | /// are always 0. These 3 bits are used to enlarge the offset range. This | |
| 115 | /// optimization reduces the table in Unicode 15 from 184 to 104 entries, | |
| 116 | /// saving 320 bytes. | |
| 117 | /// | |
| 118 | /// The data has 2 values: | |
| 119 | /// - bits [0, 13] The size of the range, allowing 16384 elements. | |
| 120 | /// - bits [14, 31] The lower bound code point of the range. The upper bound of | |
| 121 | /// the range is lower bound + size. | |
| 122 | inline constexpr uint32_t __entries[108] = { | |
| 123 | 0x0440005f /* 00001100 - 0000115f [ 96] */, // | |
| 124 | 0x08c68001 /* 0000231a - 0000231b [ 2] */, // | |
| 125 | 0x08ca4001 /* 00002329 - 0000232a [ 2] */, // | |
| 126 | 0x08fa4003 /* 000023e9 - 000023ec [ 4] */, // | |
| 127 | 0x08fc0000 /* 000023f0 - 000023f0 [ 1] */, // | |
| 128 | 0x08fcc000 /* 000023f3 - 000023f3 [ 1] */, // | |
| 129 | 0x097f4001 /* 000025fd - 000025fe [ 2] */, // | |
| 130 | 0x09850001 /* 00002614 - 00002615 [ 2] */, // | |
| 131 | 0x0992000b /* 00002648 - 00002653 [ 12] */, // | |
| 132 | 0x099fc000 /* 0000267f - 0000267f [ 1] */, // | |
| 133 | 0x09a4c000 /* 00002693 - 00002693 [ 1] */, // | |
| 134 | 0x09a84000 /* 000026a1 - 000026a1 [ 1] */, // | |
| 135 | 0x09aa8001 /* 000026aa - 000026ab [ 2] */, // | |
| 136 | 0x09af4001 /* 000026bd - 000026be [ 2] */, // | |
| 137 | 0x09b10001 /* 000026c4 - 000026c5 [ 2] */, // | |
| 138 | 0x09b38000 /* 000026ce - 000026ce [ 1] */, // | |
| 139 | 0x09b50000 /* 000026d4 - 000026d4 [ 1] */, // | |
| 140 | 0x09ba8000 /* 000026ea - 000026ea [ 1] */, // | |
| 141 | 0x09bc8001 /* 000026f2 - 000026f3 [ 2] */, // | |
| 142 | 0x09bd4000 /* 000026f5 - 000026f5 [ 1] */, // | |
| 143 | 0x09be8000 /* 000026fa - 000026fa [ 1] */, // | |
| 144 | 0x09bf4000 /* 000026fd - 000026fd [ 1] */, // | |
| 145 | 0x09c14000 /* 00002705 - 00002705 [ 1] */, // | |
| 146 | 0x09c28001 /* 0000270a - 0000270b [ 2] */, // | |
| 147 | 0x09ca0000 /* 00002728 - 00002728 [ 1] */, // | |
| 148 | 0x09d30000 /* 0000274c - 0000274c [ 1] */, // | |
| 149 | 0x09d38000 /* 0000274e - 0000274e [ 1] */, // | |
| 150 | 0x09d4c002 /* 00002753 - 00002755 [ 3] */, // | |
| 151 | 0x09d5c000 /* 00002757 - 00002757 [ 1] */, // | |
| 152 | 0x09e54002 /* 00002795 - 00002797 [ 3] */, // | |
| 153 | 0x09ec0000 /* 000027b0 - 000027b0 [ 1] */, // | |
| 154 | 0x09efc000 /* 000027bf - 000027bf [ 1] */, // | |
| 155 | 0x0ac6c001 /* 00002b1b - 00002b1c [ 2] */, // | |
| 156 | 0x0ad40000 /* 00002b50 - 00002b50 [ 1] */, // | |
| 157 | 0x0ad54000 /* 00002b55 - 00002b55 [ 1] */, // | |
| 158 | 0x0ba00019 /* 00002e80 - 00002e99 [ 26] */, // | |
| 159 | 0x0ba6c058 /* 00002e9b - 00002ef3 [ 89] */, // | |
| 160 | 0x0bc000d5 /* 00002f00 - 00002fd5 [ 214] */, // | |
| 161 | 0x0bfc000b /* 00002ff0 - 00002ffb [ 12] */, // | |
| 162 | 0x0c00003e /* 00003000 - 0000303e [ 63] */, // | |
| 163 | 0x0c104055 /* 00003041 - 00003096 [ 86] */, // | |
| 164 | 0x0c264066 /* 00003099 - 000030ff [ 103] */, // | |
| 165 | 0x0c41402a /* 00003105 - 0000312f [ 43] */, // | |
| 166 | 0x0c4c405d /* 00003131 - 0000318e [ 94] */, // | |
| 167 | 0x0c640053 /* 00003190 - 000031e3 [ 84] */, // | |
| 168 | 0x0c7c002e /* 000031f0 - 0000321e [ 47] */, // | |
| 169 | 0x0c880027 /* 00003220 - 00003247 [ 40] */, // | |
| 170 | 0x0c943fff /* 00003250 - 0000724f [16384] */, // | |
| 171 | 0x1c94323c /* 00007250 - 0000a48c [12861] */, // | |
| 172 | 0x29240036 /* 0000a490 - 0000a4c6 [ 55] */, // | |
| 173 | 0x2a58001c /* 0000a960 - 0000a97c [ 29] */, // | |
| 174 | 0x2b002ba3 /* 0000ac00 - 0000d7a3 [11172] */, // | |
| 175 | 0x3e4001ff /* 0000f900 - 0000faff [ 512] */, // | |
| 176 | 0x3f840009 /* 0000fe10 - 0000fe19 [ 10] */, // | |
| 177 | 0x3f8c0022 /* 0000fe30 - 0000fe52 [ 35] */, // | |
| 178 | 0x3f950012 /* 0000fe54 - 0000fe66 [ 19] */, // | |
| 179 | 0x3f9a0003 /* 0000fe68 - 0000fe6b [ 4] */, // | |
| 180 | 0x3fc0405f /* 0000ff01 - 0000ff60 [ 96] */, // | |
| 181 | 0x3ff80006 /* 0000ffe0 - 0000ffe6 [ 7] */, // | |
| 182 | 0x5bf80004 /* 00016fe0 - 00016fe4 [ 5] */, // | |
| 183 | 0x5bfc0001 /* 00016ff0 - 00016ff1 [ 2] */, // | |
| 184 | 0x5c0017f7 /* 00017000 - 000187f7 [ 6136] */, // | |
| 185 | 0x620004d5 /* 00018800 - 00018cd5 [ 1238] */, // | |
| 186 | 0x63400008 /* 00018d00 - 00018d08 [ 9] */, // | |
| 187 | 0x6bfc0003 /* 0001aff0 - 0001aff3 [ 4] */, // | |
| 188 | 0x6bfd4006 /* 0001aff5 - 0001affb [ 7] */, // | |
| 189 | 0x6bff4001 /* 0001affd - 0001affe [ 2] */, // | |
| 190 | 0x6c000122 /* 0001b000 - 0001b122 [ 291] */, // | |
| 191 | 0x6c4c8000 /* 0001b132 - 0001b132 [ 1] */, // | |
| 192 | 0x6c540002 /* 0001b150 - 0001b152 [ 3] */, // | |
| 193 | 0x6c554000 /* 0001b155 - 0001b155 [ 1] */, // | |
| 194 | 0x6c590003 /* 0001b164 - 0001b167 [ 4] */, // | |
| 195 | 0x6c5c018b /* 0001b170 - 0001b2fb [ 396] */, // | |
| 196 | 0x7c010000 /* 0001f004 - 0001f004 [ 1] */, // | |
| 197 | 0x7c33c000 /* 0001f0cf - 0001f0cf [ 1] */, // | |
| 198 | 0x7c638000 /* 0001f18e - 0001f18e [ 1] */, // | |
| 199 | 0x7c644009 /* 0001f191 - 0001f19a [ 10] */, // | |
| 200 | 0x7c800002 /* 0001f200 - 0001f202 [ 3] */, // | |
| 201 | 0x7c84002b /* 0001f210 - 0001f23b [ 44] */, // | |
| 202 | 0x7c900008 /* 0001f240 - 0001f248 [ 9] */, // | |
| 203 | 0x7c940001 /* 0001f250 - 0001f251 [ 2] */, // | |
| 204 | 0x7c980005 /* 0001f260 - 0001f265 [ 6] */, // | |
| 205 | 0x7cc0034f /* 0001f300 - 0001f64f [ 848] */, // | |
| 206 | 0x7da00045 /* 0001f680 - 0001f6c5 [ 70] */, // | |
| 207 | 0x7db30000 /* 0001f6cc - 0001f6cc [ 1] */, // | |
| 208 | 0x7db40002 /* 0001f6d0 - 0001f6d2 [ 3] */, // | |
| 209 | 0x7db54002 /* 0001f6d5 - 0001f6d7 [ 3] */, // | |
| 210 | 0x7db70003 /* 0001f6dc - 0001f6df [ 4] */, // | |
| 211 | 0x7dbac001 /* 0001f6eb - 0001f6ec [ 2] */, // | |
| 212 | 0x7dbd0008 /* 0001f6f4 - 0001f6fc [ 9] */, // | |
| 213 | 0x7df8000b /* 0001f7e0 - 0001f7eb [ 12] */, // | |
| 214 | 0x7dfc0000 /* 0001f7f0 - 0001f7f0 [ 1] */, // | |
| 215 | 0x7e4000ff /* 0001f900 - 0001f9ff [ 256] */, // | |
| 216 | 0x7e9c000c /* 0001fa70 - 0001fa7c [ 13] */, // | |
| 217 | 0x7ea00008 /* 0001fa80 - 0001fa88 [ 9] */, // | |
| 218 | 0x7ea4002d /* 0001fa90 - 0001fabd [ 46] */, // | |
| 219 | 0x7eafc006 /* 0001fabf - 0001fac5 [ 7] */, // | |
| 220 | 0x7eb3800d /* 0001face - 0001fadb [ 14] */, // | |
| 221 | 0x7eb80008 /* 0001fae0 - 0001fae8 [ 9] */, // | |
| 222 | 0x7ebc0008 /* 0001faf0 - 0001faf8 [ 9] */, // | |
| 223 | 0x80003fff /* 00020000 - 00023fff [16384] */, // | |
| 224 | 0x90003fff /* 00024000 - 00027fff [16384] */, // | |
| 225 | 0xa0003fff /* 00028000 - 0002bfff [16384] */, // | |
| 226 | 0xb0003ffd /* 0002c000 - 0002fffd [16382] */, // | |
| 227 | 0xc0003fff /* 00030000 - 00033fff [16384] */, // | |
| 228 | 0xd0003fff /* 00034000 - 00037fff [16384] */, // | |
| 229 | 0xe0003fff /* 00038000 - 0003bfff [16384] */, // | |
| 230 | 0xf0003ffd /* 0003c000 - 0003fffd [16382] */}; | |
| 231 | ||
| 232 | /// The upper bound entry of EastAsianWidth.txt. | |
| 233 | /// | |
| 234 | /// Values greater than this value may have more than 18 significant bits. | |
| 235 | /// They always have a width of 1. This property makes it possible to store | |
| 236 | /// the table in its compact form. | |
| 237 | inline constexpr uint32_t __table_upper_bound = 0x0003fffd; | |
| 238 | ||
| 239 | /// Returns the estimated width of a Unicode code point. | |
| 240 | /// | |
| 241 | /// \pre The code point is a valid Unicode code point. | |
| 242 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int __estimated_width(const char32_t __code_point) noexcept { | |
| 243 | // Since __table_upper_bound contains the unshifted range do the | |
| 244 | // comparison without shifting. | |
| 245 | if (__code_point > __table_upper_bound) [[unlikely]] | |
| 246 | return 1; | |
| 247 | ||
| 248 | // When the code-point is less than the first element in the table | |
| 249 | // the lookup is quite expensive. Since quite some scripts are in | |
| 250 | // that range, it makes sense to validate that first. | |
| 251 | // The std_format_spec_string_unicode benchmark gives a measurable | |
| 252 | // improvement. | |
| 253 | if (__code_point < (__entries[0] >> 14)) | |
| 254 | return 1; | |
| 255 | ||
| 256 | ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries; | |
| 257 | if (__i == 0) | |
| 258 | return 1; | |
| 259 | ||
| 260 | --__i; | |
| 261 | uint32_t __upper_bound = (__entries[__i] >> 14) + (__entries[__i] & 0x3fffu); | |
| 262 | return 1 + (__code_point <= __upper_bound); | |
| 263 | } | |
| 264 | ||
| 265 | } // namespace __width_estimation_table | |
| 266 | ||
| 267 | #endif //_LIBCPP_STD_VER >= 20 | |
| 268 | ||
| 269 | _LIBCPP_END_NAMESPACE_STD | |
| 270 | ||
| 271 | #endif // _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H |
lib/libcxx/include/__format/write_escaped.h created+222| ... | ... | @@ -0,0 +1,222 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___FORMAT_WRITE_ESCAPED_H | |
| 11 | #define _LIBCPP___FORMAT_WRITE_ESCAPED_H | |
| 12 | ||
| 13 | #include <__algorithm/ranges_copy.h> | |
| 14 | #include <__algorithm/ranges_for_each.h> | |
| 15 | #include <__charconv/to_chars_integral.h> | |
| 16 | #include <__charconv/to_chars_result.h> | |
| 17 | #include <__chrono/statically_widen.h> | |
| 18 | #include <__format/escaped_output_table.h> | |
| 19 | #include <__format/formatter_output.h> | |
| 20 | #include <__format/parser_std_format_spec.h> | |
| 21 | #include <__format/unicode.h> | |
| 22 | #include <__iterator/back_insert_iterator.h> | |
| 23 | #include <__memory/addressof.h> | |
| 24 | #include <__system_error/errc.h> | |
| 25 | #include <__type_traits/make_unsigned.h> | |
| 26 | #include <__utility/move.h> | |
| 27 | #include <string_view> | |
| 28 | ||
| 29 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 30 | # pragma GCC system_header | |
| 31 | #endif | |
| 32 | ||
| 33 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 34 | ||
| 35 | ||
| 36 | namespace __formatter { | |
| 37 | ||
| 38 | #if _LIBCPP_STD_VER >= 20 | |
| 39 | ||
| 40 | /// Writes a string using format's width estimation algorithm. | |
| 41 | /// | |
| 42 | /// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the | |
| 43 | /// input is ASCII. | |
| 44 | template <class _CharT> | |
| 45 | _LIBCPP_HIDE_FROM_ABI auto __write_string( | |
| 46 | basic_string_view<_CharT> __str, | |
| 47 | output_iterator<const _CharT&> auto __out_it, | |
| 48 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 49 | if (!__specs.__has_precision()) | |
| 50 | return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs); | |
| 51 | ||
| 52 | int __size = __formatter::__truncate(__str, __specs.__precision_); | |
| 53 | ||
| 54 | return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); | |
| 55 | } | |
| 56 | ||
| 57 | # endif // _LIBCPP_STD_VER >= 20 | |
| 58 | # if _LIBCPP_STD_VER >= 23 | |
| 59 | ||
| 60 | struct __nul_terminator {}; | |
| 61 | ||
| 62 | template <class _CharT> | |
| 63 | _LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { | |
| 64 | return *__cstr == _CharT('\0'); | |
| 65 | } | |
| 66 | ||
| 67 | template <class _CharT> | |
| 68 | _LIBCPP_HIDE_FROM_ABI void | |
| 69 | __write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { | |
| 70 | back_insert_iterator __out_it{__str}; | |
| 71 | std::ranges::copy(__prefix, __nul_terminator{}, __out_it); | |
| 72 | ||
| 73 | char __buffer[8]; | |
| 74 | to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); | |
| 75 | _LIBCPP_ASSERT_UNCATEGORIZED(__r.ec == errc(0), "Internal buffer too small"); | |
| 76 | std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); | |
| 77 | ||
| 78 | __str += _CharT('}'); | |
| 79 | } | |
| 80 | ||
| 81 | // [format.string.escaped]/2.2.1.2 | |
| 82 | // ... | |
| 83 | // then the sequence \u{hex-digit-sequence} is appended to E, where | |
| 84 | // hex-digit-sequence is the shortest hexadecimal representation of C using | |
| 85 | // lower-case hexadecimal digits. | |
| 86 | template <class _CharT> | |
| 87 | _LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { | |
| 88 | __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); | |
| 89 | } | |
| 90 | ||
| 91 | // [format.string.escaped]/2.2.3 | |
| 92 | // Otherwise (X is a sequence of ill-formed code units), each code unit U is | |
| 93 | // appended to E in order as the sequence \x{hex-digit-sequence}, where | |
| 94 | // hex-digit-sequence is the shortest hexadecimal representation of U using | |
| 95 | // lower-case hexadecimal digits. | |
| 96 | template <class _CharT> | |
| 97 | _LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { | |
| 98 | __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); | |
| 99 | } | |
| 100 | ||
| 101 | template <class _CharT> | |
| 102 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { | |
| 103 | # ifdef _LIBCPP_HAS_NO_UNICODE | |
| 104 | // For ASCII assume everything above 127 is printable. | |
| 105 | if (__value > 127) | |
| 106 | return false; | |
| 107 | # endif | |
| 108 | ||
| 109 | if (!__escaped_output_table::__needs_escape(__value)) | |
| 110 | return false; | |
| 111 | ||
| 112 | __formatter::__write_well_formed_escaped_code_unit(__str, __value); | |
| 113 | return true; | |
| 114 | } | |
| 115 | ||
| 116 | template <class _CharT> | |
| 117 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { | |
| 118 | return static_cast<make_unsigned_t<_CharT>>(__value); | |
| 119 | } | |
| 120 | ||
| 121 | enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote }; | |
| 122 | ||
| 123 | // [format.string.escaped]/2 | |
| 124 | template <class _CharT> | |
| 125 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool | |
| 126 | __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) { | |
| 127 | // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] | |
| 128 | switch (__value) { | |
| 129 | case _CharT('\t'): | |
| 130 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); | |
| 131 | return true; | |
| 132 | case _CharT('\n'): | |
| 133 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); | |
| 134 | return true; | |
| 135 | case _CharT('\r'): | |
| 136 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); | |
| 137 | return true; | |
| 138 | case _CharT('\''): | |
| 139 | if (__mark == __escape_quotation_mark::__apostrophe) | |
| 140 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); | |
| 141 | else | |
| 142 | __str += __value; | |
| 143 | return true; | |
| 144 | case _CharT('"'): | |
| 145 | if (__mark == __escape_quotation_mark::__double_quote) | |
| 146 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); | |
| 147 | else | |
| 148 | __str += __value; | |
| 149 | return true; | |
| 150 | case _CharT('\\'): | |
| 151 | __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); | |
| 152 | return true; | |
| 153 | ||
| 154 | // 2.2.1.2 - Space | |
| 155 | case _CharT(' '): | |
| 156 | __str += __value; | |
| 157 | return true; | |
| 158 | } | |
| 159 | ||
| 160 | // 2.2.2 | |
| 161 | // Otherwise, if X is a shift sequence, the effect on E and further | |
| 162 | // decoding of S is unspecified. | |
| 163 | // For now shift sequences are ignored and treated as Unicode. Other parts | |
| 164 | // of the format library do the same. It's unknown how ostream treats them. | |
| 165 | // TODO FMT determine what to do with shift sequences. | |
| 166 | ||
| 167 | // 2.2.1.2.1 and 2.2.1.2.2 - Escape | |
| 168 | return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value)); | |
| 169 | } | |
| 170 | ||
| 171 | template <class _CharT> | |
| 172 | _LIBCPP_HIDE_FROM_ABI void | |
| 173 | __escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { | |
| 174 | __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; | |
| 175 | ||
| 176 | while (!__view.__at_end()) { | |
| 177 | auto __first = __view.__position(); | |
| 178 | typename __unicode::__consume_result __result = __view.__consume(); | |
| 179 | if (__result.__status == __unicode::__consume_result::__ok) { | |
| 180 | if (!__formatter::__is_escaped_sequence_written(__str, __result.__code_point, __mark)) | |
| 181 | // 2.2.1.3 - Add the character | |
| 182 | ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); | |
| 183 | } else { | |
| 184 | // 2.2.3 sequence of ill-formed code units | |
| 185 | ranges::for_each(__first, __view.__position(), [&](_CharT __value) { | |
| 186 | __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value)); | |
| 187 | }); | |
| 188 | } | |
| 189 | } | |
| 190 | } | |
| 191 | ||
| 192 | template <class _CharT> | |
| 193 | _LIBCPP_HIDE_FROM_ABI auto | |
| 194 | __format_escaped_char(_CharT __value, | |
| 195 | output_iterator<const _CharT&> auto __out_it, | |
| 196 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 197 | basic_string<_CharT> __str; | |
| 198 | __str += _CharT('\''); | |
| 199 | __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); | |
| 200 | __str += _CharT('\''); | |
| 201 | return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size()); | |
| 202 | } | |
| 203 | ||
| 204 | template <class _CharT> | |
| 205 | _LIBCPP_HIDE_FROM_ABI auto | |
| 206 | __format_escaped_string(basic_string_view<_CharT> __values, | |
| 207 | output_iterator<const _CharT&> auto __out_it, | |
| 208 | __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { | |
| 209 | basic_string<_CharT> __str; | |
| 210 | __str += _CharT('"'); | |
| 211 | __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); | |
| 212 | __str += _CharT('"'); | |
| 213 | return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs); | |
| 214 | } | |
| 215 | ||
| 216 | # endif // _LIBCPP_STD_VER >= 23 | |
| 217 | ||
| 218 | } // namespace __formatter | |
| 219 | ||
| 220 | _LIBCPP_END_NAMESPACE_STD | |
| 221 | ||
| 222 | #endif // _LIBCPP___FORMAT_WRITE_ESCAPED_H |
lib/libcxx/include/__functional/bind.h+36-39| ... | ... | @@ -13,9 +13,11 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/invoke.h> |
| 15 | 15 | #include <__functional/weak_result_type.h> |
| 16 | #include <__type_traits/decay.h> | |
| 17 | #include <__type_traits/is_reference_wrapper.h> | |
| 18 | #include <__type_traits/is_void.h> | |
| 16 | 19 | #include <cstddef> |
| 17 | 20 | #include <tuple> |
| 18 | #include <type_traits> | |
| 19 | 21 | |
| 20 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 23 | # pragma GCC system_header |
| ... | ... | @@ -30,9 +32,9 @@ struct is_bind_expression : _If< |
| 30 | 32 | is_bind_expression<__remove_cvref_t<_Tp> > |
| 31 | 33 | > {}; |
| 32 | 34 | |
| 33 | #if _LIBCPP_STD_VER > 14 | |
| 35 | #if _LIBCPP_STD_VER >= 17 | |
| 34 | 36 | template <class _Tp> |
| 35 | inline constexpr size_t is_bind_expression_v = is_bind_expression<_Tp>::value; | |
| 37 | inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; | |
| 36 | 38 | #endif |
| 37 | 39 | |
| 38 | 40 | template<class _Tp> |
| ... | ... | @@ -42,9 +44,9 @@ struct is_placeholder : _If< |
| 42 | 44 | is_placeholder<__remove_cvref_t<_Tp> > |
| 43 | 45 | > {}; |
| 44 | 46 | |
| 45 | #if _LIBCPP_STD_VER > 14 | |
| 47 | #if _LIBCPP_STD_VER >= 17 | |
| 46 | 48 | template <class _Tp> |
| 47 | inline constexpr size_t is_placeholder_v = is_placeholder<_Tp>::value; | |
| 49 | inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; | |
| 48 | 50 | #endif |
| 49 | 51 | |
| 50 | 52 | namespace placeholders |
| ... | ... | @@ -52,29 +54,24 @@ namespace placeholders |
| 52 | 54 | |
| 53 | 55 | template <int _Np> struct __ph {}; |
| 54 | 56 | |
| 55 | #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 56 | _LIBCPP_FUNC_VIS extern const __ph<1> _1; | |
| 57 | _LIBCPP_FUNC_VIS extern const __ph<2> _2; | |
| 58 | _LIBCPP_FUNC_VIS extern const __ph<3> _3; | |
| 59 | _LIBCPP_FUNC_VIS extern const __ph<4> _4; | |
| 60 | _LIBCPP_FUNC_VIS extern const __ph<5> _5; | |
| 61 | _LIBCPP_FUNC_VIS extern const __ph<6> _6; | |
| 62 | _LIBCPP_FUNC_VIS extern const __ph<7> _7; | |
| 63 | _LIBCPP_FUNC_VIS extern const __ph<8> _8; | |
| 64 | _LIBCPP_FUNC_VIS extern const __ph<9> _9; | |
| 65 | _LIBCPP_FUNC_VIS extern const __ph<10> _10; | |
| 66 | #else | |
| 67 | /* inline */ constexpr __ph<1> _1{}; | |
| 68 | /* inline */ constexpr __ph<2> _2{}; | |
| 69 | /* inline */ constexpr __ph<3> _3{}; | |
| 70 | /* inline */ constexpr __ph<4> _4{}; | |
| 71 | /* inline */ constexpr __ph<5> _5{}; | |
| 72 | /* inline */ constexpr __ph<6> _6{}; | |
| 73 | /* inline */ constexpr __ph<7> _7{}; | |
| 74 | /* inline */ constexpr __ph<8> _8{}; | |
| 75 | /* inline */ constexpr __ph<9> _9{}; | |
| 76 | /* inline */ constexpr __ph<10> _10{}; | |
| 77 | #endif // defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 57 | // C++17 recommends that we implement placeholders as `inline constexpr`, but allows | |
| 58 | // implementing them as `extern <implementation-defined>`. Libc++ implements them as | |
| 59 | // `extern const` in all standard modes to avoid an ABI break in C++03: making them | |
| 60 | // `inline constexpr` requires removing their definition in the shared library to | |
| 61 | // avoid ODR violations, which is an ABI break. | |
| 62 | // | |
| 63 | // In practice, since placeholders are empty, `extern const` is almost impossible | |
| 64 | // to distinguish from `inline constexpr` from a usage stand point. | |
| 65 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1; | |
| 66 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2; | |
| 67 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3; | |
| 68 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4; | |
| 69 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5; | |
| 70 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6; | |
| 71 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7; | |
| 72 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8; | |
| 73 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9; | |
| 74 | _LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10; | |
| 78 | 75 | |
| 79 | 76 | } // namespace placeholders |
| 80 | 77 | |
| ... | ... | @@ -86,7 +83,7 @@ struct is_placeholder<placeholders::__ph<_Np> > |
| 86 | 83 | #ifndef _LIBCPP_CXX03_LANG |
| 87 | 84 | |
| 88 | 85 | template <class _Tp, class _Uj> |
| 89 | inline _LIBCPP_INLINE_VISIBILITY | |
| 86 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 90 | 87 | _Tp& |
| 91 | 88 | __mu(reference_wrapper<_Tp> __t, _Uj&) |
| 92 | 89 | { |
| ... | ... | @@ -94,7 +91,7 @@ __mu(reference_wrapper<_Tp> __t, _Uj&) |
| 94 | 91 | } |
| 95 | 92 | |
| 96 | 93 | template <class _Ti, class ..._Uj, size_t ..._Indx> |
| 97 | inline _LIBCPP_INLINE_VISIBILITY | |
| 94 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 98 | 95 | typename __invoke_of<_Ti&, _Uj...>::type |
| 99 | 96 | __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) |
| 100 | 97 | { |
| ... | ... | @@ -102,7 +99,7 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) |
| 102 | 99 | } |
| 103 | 100 | |
| 104 | 101 | template <class _Ti, class ..._Uj> |
| 105 | inline _LIBCPP_INLINE_VISIBILITY | |
| 102 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 106 | 103 | typename __enable_if_t |
| 107 | 104 | < |
| 108 | 105 | is_bind_expression<_Ti>::value, |
| ... | ... | @@ -124,7 +121,7 @@ struct __mu_return2<true, _Ti, _Uj> |
| 124 | 121 | }; |
| 125 | 122 | |
| 126 | 123 | template <class _Ti, class _Uj> |
| 127 | inline _LIBCPP_INLINE_VISIBILITY | |
| 124 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 128 | 125 | typename enable_if |
| 129 | 126 | < |
| 130 | 127 | 0 < is_placeholder<_Ti>::value, |
| ... | ... | @@ -132,12 +129,12 @@ typename enable_if |
| 132 | 129 | >::type |
| 133 | 130 | __mu(_Ti&, _Uj& __uj) |
| 134 | 131 | { |
| 135 | const size_t _Indx = is_placeholder<_Ti>::value - 1; | |
| 136 | return _VSTD::forward<typename tuple_element<_Indx, _Uj>::type>(_VSTD::get<_Indx>(__uj)); | |
| 132 | const size_t __indx = is_placeholder<_Ti>::value - 1; | |
| 133 | return _VSTD::forward<typename tuple_element<__indx, _Uj>::type>(_VSTD::get<__indx>(__uj)); | |
| 137 | 134 | } |
| 138 | 135 | |
| 139 | 136 | template <class _Ti, class _Uj> |
| 140 | inline _LIBCPP_INLINE_VISIBILITY | |
| 137 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 141 | 138 | typename enable_if |
| 142 | 139 | < |
| 143 | 140 | !is_bind_expression<_Ti>::value && |
| ... | ... | @@ -255,7 +252,7 @@ struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> |
| 255 | 252 | }; |
| 256 | 253 | |
| 257 | 254 | template <class _Fp, class _BoundArgs, size_t ..._Indx, class _Args> |
| 258 | inline _LIBCPP_INLINE_VISIBILITY | |
| 255 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 259 | 256 | typename __bind_return<_Fp, _BoundArgs, _Args>::type |
| 260 | 257 | __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, |
| 261 | 258 | _Args&& __args) |
| ... | ... | @@ -264,11 +261,11 @@ __apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, |
| 264 | 261 | } |
| 265 | 262 | |
| 266 | 263 | template<class _Fp, class ..._BoundArgs> |
| 267 | class __bind : public __weak_result_type<typename decay<_Fp>::type> | |
| 264 | class __bind : public __weak_result_type<__decay_t<_Fp> > | |
| 268 | 265 | { |
| 269 | 266 | protected: |
| 270 | typedef typename decay<_Fp>::type _Fd; | |
| 271 | typedef tuple<typename decay<_BoundArgs>::type...> _Td; | |
| 267 | using _Fd = __decay_t<_Fp>; | |
| 268 | typedef tuple<__decay_t<_BoundArgs>...> _Td; | |
| 272 | 269 | private: |
| 273 | 270 | _Fd __f_; |
| 274 | 271 | _Td __bound_args_; |
lib/libcxx/include/__functional/bind_back.h+3-3| ... | ... | @@ -13,10 +13,10 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/invoke.h> |
| 15 | 15 | #include <__functional/perfect_forward.h> |
| 16 | #include <__type_traits/decay.h> | |
| 16 | 17 | #include <__utility/forward.h> |
| 17 | 18 | #include <__utility/integer_sequence.h> |
| 18 | 19 | #include <tuple> |
| 19 | #include <type_traits> | |
| 20 | 20 | |
| 21 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 22 | # pragma GCC system_header |
| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | template <size_t _NBound, class = make_index_sequence<_NBound>> |
| 30 | 30 | struct __bind_back_op; |
| ... | ... | @@ -57,7 +57,7 @@ constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) |
| 57 | 57 | -> decltype( __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))) |
| 58 | 58 | { return __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } |
| 59 | 59 | |
| 60 | #endif // _LIBCPP_STD_VER > 17 | |
| 60 | #endif // _LIBCPP_STD_VER >= 20 | |
| 61 | 61 | |
| 62 | 62 | _LIBCPP_END_NAMESPACE_STD |
| 63 | 63 |
lib/libcxx/include/__functional/bind_front.h+7-3| ... | ... | @@ -13,8 +13,12 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/invoke.h> |
| 15 | 15 | #include <__functional/perfect_forward.h> |
| 16 | #include <__type_traits/conjunction.h> | |
| 17 | #include <__type_traits/decay.h> | |
| 18 | #include <__type_traits/enable_if.h> | |
| 19 | #include <__type_traits/is_constructible.h> | |
| 20 | #include <__type_traits/is_move_constructible.h> | |
| 16 | 21 | #include <__utility/forward.h> |
| 17 | #include <type_traits> | |
| 18 | 22 | |
| 19 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 24 | # pragma GCC system_header |
| ... | ... | @@ -22,7 +26,7 @@ |
| 22 | 26 | |
| 23 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 28 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 30 | |
| 27 | 31 | struct __bind_front_op { |
| 28 | 32 | template <class ..._Args> |
| ... | ... | @@ -51,7 +55,7 @@ constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { |
| 51 | 55 | return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); |
| 52 | 56 | } |
| 53 | 57 | |
| 54 | #endif // _LIBCPP_STD_VER > 17 | |
| 58 | #endif // _LIBCPP_STD_VER >= 20 | |
| 55 | 59 | |
| 56 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 57 | 61 |
lib/libcxx/include/__functional/binder1st.h+14-14| ... | ... | @@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) |
| 23 | 23 | |
| 24 | template <class __Operation> | |
| 24 | template <class _Operation> | |
| 25 | 25 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st |
| 26 | : public __unary_function<typename __Operation::second_argument_type, typename __Operation::result_type> | |
| 26 | : public __unary_function<typename _Operation::second_argument_type, typename _Operation::result_type> | |
| 27 | 27 | { |
| 28 | 28 | protected: |
| 29 | __Operation op; | |
| 30 | typename __Operation::first_argument_type value; | |
| 29 | _Operation op; | |
| 30 | typename _Operation::first_argument_type value; | |
| 31 | 31 | public: |
| 32 | _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x, | |
| 33 | const typename __Operation::first_argument_type __y) | |
| 32 | _LIBCPP_INLINE_VISIBILITY binder1st(const _Operation& __x, | |
| 33 | const typename _Operation::first_argument_type __y) | |
| 34 | 34 | : op(__x), value(__y) {} |
| 35 | _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() | |
| 36 | (typename __Operation::second_argument_type& __x) const | |
| 35 | _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator() | |
| 36 | (typename _Operation::second_argument_type& __x) const | |
| 37 | 37 | {return op(value, __x);} |
| 38 | _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() | |
| 39 | (const typename __Operation::second_argument_type& __x) const | |
| 38 | _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator() | |
| 39 | (const typename _Operation::second_argument_type& __x) const | |
| 40 | 40 | {return op(value, __x);} |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | template <class __Operation, class _Tp> | |
| 43 | template <class _Operation, class _Tp> | |
| 44 | 44 | _LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY |
| 45 | binder1st<__Operation> | |
| 46 | bind1st(const __Operation& __op, const _Tp& __x) | |
| 47 | {return binder1st<__Operation>(__op, __x);} | |
| 45 | binder1st<_Operation> | |
| 46 | bind1st(const _Operation& __op, const _Tp& __x) | |
| 47 | {return binder1st<_Operation>(__op, __x);} | |
| 48 | 48 | |
| 49 | 49 | #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) |
| 50 | 50 |
lib/libcxx/include/__functional/binder2nd.h+13-13| ... | ... | @@ -21,30 +21,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) |
| 23 | 23 | |
| 24 | template <class __Operation> | |
| 24 | template <class _Operation> | |
| 25 | 25 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd |
| 26 | : public __unary_function<typename __Operation::first_argument_type, typename __Operation::result_type> | |
| 26 | : public __unary_function<typename _Operation::first_argument_type, typename _Operation::result_type> | |
| 27 | 27 | { |
| 28 | 28 | protected: |
| 29 | __Operation op; | |
| 30 | typename __Operation::second_argument_type value; | |
| 29 | _Operation op; | |
| 30 | typename _Operation::second_argument_type value; | |
| 31 | 31 | public: |
| 32 | 32 | _LIBCPP_INLINE_VISIBILITY |
| 33 | binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y) | |
| 33 | binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y) | |
| 34 | 34 | : op(__x), value(__y) {} |
| 35 | _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() | |
| 36 | ( typename __Operation::first_argument_type& __x) const | |
| 35 | _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator() | |
| 36 | ( typename _Operation::first_argument_type& __x) const | |
| 37 | 37 | {return op(__x, value);} |
| 38 | _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() | |
| 39 | (const typename __Operation::first_argument_type& __x) const | |
| 38 | _LIBCPP_INLINE_VISIBILITY typename _Operation::result_type operator() | |
| 39 | (const typename _Operation::first_argument_type& __x) const | |
| 40 | 40 | {return op(__x, value);} |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | template <class __Operation, class _Tp> | |
| 43 | template <class _Operation, class _Tp> | |
| 44 | 44 | _LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY |
| 45 | binder2nd<__Operation> | |
| 46 | bind2nd(const __Operation& __op, const _Tp& __x) | |
| 47 | {return binder2nd<__Operation>(__op, __x);} | |
| 45 | binder2nd<_Operation> | |
| 46 | bind2nd(const _Operation& __op, const _Tp& __x) | |
| 47 | {return binder2nd<_Operation>(__op, __x);} | |
| 48 | 48 | |
| 49 | 49 | #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) |
| 50 | 50 |
lib/libcxx/include/__functional/boyer_moore_searcher.h+13-8| ... | ... | @@ -20,12 +20,13 @@ |
| 20 | 20 | #include <__iterator/distance.h> |
| 21 | 21 | #include <__iterator/iterator_traits.h> |
| 22 | 22 | #include <__memory/shared_ptr.h> |
| 23 | #include <__type_traits/make_unsigned.h> | |
| 23 | 24 | #include <__utility/pair.h> |
| 24 | 25 | #include <array> |
| 25 | 26 | #include <unordered_map> |
| 26 | 27 | #include <vector> |
| 27 | 28 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 29 | 30 | |
| 30 | 31 | _LIBCPP_PUSH_MACROS |
| 31 | 32 | #include <__undef_macros> |
| ... | ... | @@ -113,6 +114,7 @@ private: |
| 113 | 114 | && is_same_v<_BinaryPredicate, equal_to<>>>; |
| 114 | 115 | |
| 115 | 116 | public: |
| 117 | _LIBCPP_HIDE_FROM_ABI | |
| 116 | 118 | boyer_moore_searcher(_RandomAccessIterator1 __first, |
| 117 | 119 | _RandomAccessIterator1 __last, |
| 118 | 120 | _Hash __hash = _Hash(), |
| ... | ... | @@ -134,7 +136,7 @@ public: |
| 134 | 136 | } |
| 135 | 137 | |
| 136 | 138 | template <class _RandomAccessIterator2> |
| 137 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 139 | _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 138 | 140 | operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { |
| 139 | 141 | static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type, |
| 140 | 142 | typename iterator_traits<_RandomAccessIterator2>::value_type>::value, |
| ... | ... | @@ -158,7 +160,7 @@ private: |
| 158 | 160 | shared_ptr<difference_type[]> __suffix_; |
| 159 | 161 | |
| 160 | 162 | template <class _RandomAccessIterator2> |
| 161 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 163 | _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 162 | 164 | __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { |
| 163 | 165 | _RandomAccessIterator2 __current = __f; |
| 164 | 166 | const _RandomAccessIterator2 __last = __l - __pattern_length_; |
| ... | ... | @@ -183,7 +185,8 @@ private: |
| 183 | 185 | } |
| 184 | 186 | |
| 185 | 187 | template <class _Iterator, class _Container> |
| 186 | void __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) { | |
| 188 | _LIBCPP_HIDE_FROM_ABI void | |
| 189 | __compute_bm_prefix(_Iterator __first, _Iterator __last, _BinaryPredicate __pred, _Container& __prefix) { | |
| 187 | 190 | const size_t __count = __last - __first; |
| 188 | 191 | |
| 189 | 192 | __prefix[0] = 0; |
| ... | ... | @@ -199,7 +202,8 @@ private: |
| 199 | 202 | } |
| 200 | 203 | } |
| 201 | 204 | |
| 202 | void __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) { | |
| 205 | _LIBCPP_HIDE_FROM_ABI void | |
| 206 | __build_suffix_table(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _BinaryPredicate __pred) { | |
| 203 | 207 | const size_t __count = __last - __first; |
| 204 | 208 | |
| 205 | 209 | if (__count == 0) |
| ... | ... | @@ -241,6 +245,7 @@ private: |
| 241 | 245 | && is_same_v<_Hash, hash<value_type>> |
| 242 | 246 | && is_same_v<_BinaryPredicate, equal_to<>>>; |
| 243 | 247 | public: |
| 248 | _LIBCPP_HIDE_FROM_ABI | |
| 244 | 249 | boyer_moore_horspool_searcher(_RandomAccessIterator1 __first, |
| 245 | 250 | _RandomAccessIterator1 __last, |
| 246 | 251 | _Hash __hash = _Hash(), |
| ... | ... | @@ -262,7 +267,7 @@ public: |
| 262 | 267 | } |
| 263 | 268 | |
| 264 | 269 | template <class _RandomAccessIterator2> |
| 265 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 270 | _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 266 | 271 | operator()(_RandomAccessIterator2 __first, _RandomAccessIterator2 __last) const { |
| 267 | 272 | static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type, |
| 268 | 273 | typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value, |
| ... | ... | @@ -286,7 +291,7 @@ private: |
| 286 | 291 | shared_ptr<__skip_table_type> __skip_table_; |
| 287 | 292 | |
| 288 | 293 | template <class _RandomAccessIterator2> |
| 289 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 294 | _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 290 | 295 | __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { |
| 291 | 296 | _RandomAccessIterator2 __current = __f; |
| 292 | 297 | const _RandomAccessIterator2 __last = __l - __pattern_length_; |
| ... | ... | @@ -310,6 +315,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 310 | 315 | |
| 311 | 316 | _LIBCPP_POP_MACROS |
| 312 | 317 | |
| 313 | #endif // _LIBCPP_STD_VER > 14 | |
| 318 | #endif // _LIBCPP_STD_VER >= 17 | |
| 314 | 319 | |
| 315 | 320 | #endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H |
lib/libcxx/include/__functional/compose.h+3-3| ... | ... | @@ -13,8 +13,8 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/invoke.h> |
| 15 | 15 | #include <__functional/perfect_forward.h> |
| 16 | #include <__type_traits/decay.h> | |
| 16 | 17 | #include <__utility/forward.h> |
| 17 | #include <type_traits> | |
| 18 | 18 | |
| 19 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 20 | # pragma GCC system_header |
| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | struct __compose_op { |
| 28 | 28 | template<class _Fn1, class _Fn2, class ..._Args> |
| ... | ... | @@ -45,7 +45,7 @@ constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) |
| 45 | 45 | -> decltype( __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))) |
| 46 | 46 | { return __compose_t<decay_t<_Fn1>, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); } |
| 47 | 47 | |
| 48 | #endif // _LIBCPP_STD_VER > 17 | |
| 48 | #endif // _LIBCPP_STD_VER >= 20 | |
| 49 | 49 | |
| 50 | 50 | _LIBCPP_END_NAMESPACE_STD |
| 51 | 51 |
lib/libcxx/include/__functional/default_searcher.h+2-2| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | |
| 28 | 28 | // default searcher |
| 29 | 29 | template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> |
| ... | ... | @@ -50,7 +50,7 @@ private: |
| 50 | 50 | }; |
| 51 | 51 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); |
| 52 | 52 | |
| 53 | #endif // _LIBCPP_STD_VER > 14 | |
| 53 | #endif // _LIBCPP_STD_VER >= 17 | |
| 54 | 54 | |
| 55 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 56 | 56 |
lib/libcxx/include/__functional/function.h+67-51| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__assert> |
| 14 | 14 | #include <__config> |
| 15 | #include <__exception/exception.h> | |
| 15 | 16 | #include <__functional/binary_function.h> |
| 16 | 17 | #include <__functional/invoke.h> |
| 17 | 18 | #include <__functional/unary_function.h> |
| ... | ... | @@ -23,15 +24,21 @@ |
| 23 | 24 | #include <__memory/builtin_new_allocator.h> |
| 24 | 25 | #include <__memory/compressed_pair.h> |
| 25 | 26 | #include <__memory/unique_ptr.h> |
| 27 | #include <__type_traits/aligned_storage.h> | |
| 28 | #include <__type_traits/decay.h> | |
| 29 | #include <__type_traits/is_core_convertible.h> | |
| 30 | #include <__type_traits/is_scalar.h> | |
| 31 | #include <__type_traits/is_trivially_copy_constructible.h> | |
| 32 | #include <__type_traits/is_trivially_destructible.h> | |
| 33 | #include <__type_traits/is_void.h> | |
| 26 | 34 | #include <__type_traits/strip_signature.h> |
| 27 | 35 | #include <__utility/forward.h> |
| 28 | 36 | #include <__utility/move.h> |
| 29 | 37 | #include <__utility/piecewise_construct.h> |
| 30 | 38 | #include <__utility/swap.h> |
| 31 | #include <exception> | |
| 39 | #include <__verbose_abort> | |
| 32 | 40 | #include <new> |
| 33 | 41 | #include <tuple> |
| 34 | #include <type_traits> | |
| 35 | 42 | #include <typeinfo> |
| 36 | 43 | |
| 37 | 44 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -46,7 +53,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 46 | 53 | |
| 47 | 54 | _LIBCPP_DIAGNOSTIC_PUSH |
| 48 | 55 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") |
| 49 | class _LIBCPP_EXCEPTION_ABI bad_function_call | |
| 56 | class _LIBCPP_EXPORTED_FROM_ABI bad_function_call | |
| 50 | 57 | : public exception |
| 51 | 58 | { |
| 52 | 59 | public: |
| ... | ... | @@ -56,7 +63,7 @@ public: |
| 56 | 63 | #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION |
| 57 | 64 | ~bad_function_call() _NOEXCEPT override; |
| 58 | 65 | #else |
| 59 | ~bad_function_call() _NOEXCEPT override {} | |
| 66 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} | |
| 60 | 67 | #endif |
| 61 | 68 | |
| 62 | 69 | #ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE |
| ... | ... | @@ -68,10 +75,10 @@ _LIBCPP_DIAGNOSTIC_POP |
| 68 | 75 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 69 | 76 | void __throw_bad_function_call() |
| 70 | 77 | { |
| 71 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 78 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 72 | 79 | throw bad_function_call(); |
| 73 | 80 | #else |
| 74 | _VSTD::abort(); | |
| 81 | _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); | |
| 75 | 82 | #endif |
| 76 | 83 | } |
| 77 | 84 | |
| ... | ... | @@ -201,7 +208,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> |
| 201 | 208 | _LIBCPP_INLINE_VISIBILITY |
| 202 | 209 | void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } |
| 203 | 210 | |
| 204 | static void __destroy_and_delete(__alloc_func* __f) { | |
| 211 | _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { | |
| 205 | 212 | typedef allocator_traits<_Alloc> __alloc_traits; |
| 206 | 213 | typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; |
| 207 | 214 | _FunAlloc __a(__f->__get_allocator()); |
| ... | ... | @@ -245,7 +252,7 @@ public: |
| 245 | 252 | _LIBCPP_INLINE_VISIBILITY |
| 246 | 253 | void destroy() _NOEXCEPT { __f_.~_Target(); } |
| 247 | 254 | |
| 248 | static void __destroy_and_delete(__default_alloc_func* __f) { | |
| 255 | _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { | |
| 249 | 256 | __f->destroy(); |
| 250 | 257 | __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); |
| 251 | 258 | } |
| ... | ... | @@ -300,14 +307,14 @@ public: |
| 300 | 307 | explicit __func(_Fp&& __f, _Alloc&& __a) |
| 301 | 308 | : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} |
| 302 | 309 | |
| 303 | virtual __base<_Rp(_ArgTypes...)>* __clone() const; | |
| 304 | virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; | |
| 305 | virtual void destroy() _NOEXCEPT; | |
| 306 | virtual void destroy_deallocate() _NOEXCEPT; | |
| 307 | virtual _Rp operator()(_ArgTypes&&... __arg); | |
| 310 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; | |
| 311 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; | |
| 312 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; | |
| 313 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; | |
| 314 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); | |
| 308 | 315 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 309 | virtual const void* target(const type_info&) const _NOEXCEPT; | |
| 310 | virtual const std::type_info& target_type() const _NOEXCEPT; | |
| 316 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; | |
| 317 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; | |
| 311 | 318 | #endif // _LIBCPP_HAS_NO_RTTI |
| 312 | 319 | }; |
| 313 | 320 | |
| ... | ... | @@ -389,7 +396,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)> |
| 389 | 396 | typedef __base<_Rp(_ArgTypes...)> __func; |
| 390 | 397 | __func* __f_; |
| 391 | 398 | |
| 392 | _LIBCPP_NO_CFI static __func* __as_base(void* __p) | |
| 399 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) | |
| 393 | 400 | { |
| 394 | 401 | return reinterpret_cast<__func*>(__p); |
| 395 | 402 | } |
| ... | ... | @@ -427,7 +434,7 @@ template <class _Rp, class... _ArgTypes> class __value_func<_Rp(_ArgTypes...)> |
| 427 | 434 | } |
| 428 | 435 | |
| 429 | 436 | template <class _Fp, |
| 430 | class = typename enable_if<!is_same<typename decay<_Fp>::type, __value_func>::value>::type> | |
| 437 | class = typename enable_if<!is_same<__decay_t<_Fp>, __value_func>::value>::type> | |
| 431 | 438 | _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) |
| 432 | 439 | : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} |
| 433 | 440 | |
| ... | ... | @@ -614,33 +621,34 @@ struct __policy |
| 614 | 621 | _LIBCPP_INLINE_VISIBILITY |
| 615 | 622 | static const __policy* __create_empty() |
| 616 | 623 | { |
| 617 | static const _LIBCPP_CONSTEXPR __policy __policy_ = {nullptr, nullptr, | |
| 618 | true, | |
| 624 | static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr, | |
| 625 | true, | |
| 619 | 626 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 620 | &typeid(void) | |
| 627 | &typeid(void) | |
| 621 | 628 | #else |
| 622 | nullptr | |
| 629 | nullptr | |
| 623 | 630 | #endif |
| 624 | 631 | }; |
| 625 | return &__policy_; | |
| 632 | return &__policy; | |
| 626 | 633 | } |
| 627 | 634 | |
| 628 | 635 | private: |
| 629 | template <typename _Fun> static void* __large_clone(const void* __s) | |
| 636 | template <typename _Fun> | |
| 637 | _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) | |
| 630 | 638 | { |
| 631 | 639 | const _Fun* __f = static_cast<const _Fun*>(__s); |
| 632 | 640 | return __f->__clone(); |
| 633 | 641 | } |
| 634 | 642 | |
| 635 | 643 | template <typename _Fun> |
| 636 | static void __large_destroy(void* __s) { | |
| 644 | _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { | |
| 637 | 645 | _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); |
| 638 | 646 | } |
| 639 | 647 | |
| 640 | 648 | template <typename _Fun> |
| 641 | 649 | _LIBCPP_INLINE_VISIBILITY static const __policy* |
| 642 | 650 | __choose_policy(/* is_small = */ false_type) { |
| 643 | static const _LIBCPP_CONSTEXPR __policy __policy_ = { | |
| 651 | static const _LIBCPP_CONSTEXPR __policy __policy = { | |
| 644 | 652 | &__large_clone<_Fun>, &__large_destroy<_Fun>, false, |
| 645 | 653 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 646 | 654 | &typeid(typename _Fun::_Target) |
| ... | ... | @@ -648,14 +656,14 @@ struct __policy |
| 648 | 656 | nullptr |
| 649 | 657 | #endif |
| 650 | 658 | }; |
| 651 | return &__policy_; | |
| 659 | return &__policy; | |
| 652 | 660 | } |
| 653 | 661 | |
| 654 | 662 | template <typename _Fun> |
| 655 | 663 | _LIBCPP_INLINE_VISIBILITY static const __policy* |
| 656 | 664 | __choose_policy(/* is_small = */ true_type) |
| 657 | 665 | { |
| 658 | static const _LIBCPP_CONSTEXPR __policy __policy_ = { | |
| 666 | static const _LIBCPP_CONSTEXPR __policy __policy = { | |
| 659 | 667 | nullptr, nullptr, false, |
| 660 | 668 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 661 | 669 | &typeid(typename _Fun::_Target) |
| ... | ... | @@ -663,7 +671,7 @@ struct __policy |
| 663 | 671 | nullptr |
| 664 | 672 | #endif |
| 665 | 673 | }; |
| 666 | return &__policy_; | |
| 674 | return &__policy; | |
| 667 | 675 | } |
| 668 | 676 | }; |
| 669 | 677 | |
| ... | ... | @@ -699,14 +707,14 @@ struct __policy_invoker<_Rp(_ArgTypes...)> |
| 699 | 707 | _LIBCPP_INLINE_VISIBILITY |
| 700 | 708 | explicit __policy_invoker(__Call __c) : __call_(__c) {} |
| 701 | 709 | |
| 702 | static _Rp __call_empty(const __policy_storage*, | |
| 710 | _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, | |
| 703 | 711 | __fast_forward<_ArgTypes>...) |
| 704 | 712 | { |
| 705 | 713 | __throw_bad_function_call(); |
| 706 | 714 | } |
| 707 | 715 | |
| 708 | 716 | template <typename _Fun> |
| 709 | static _Rp __call_impl(const __policy_storage* __buf, | |
| 717 | _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, | |
| 710 | 718 | __fast_forward<_ArgTypes>... __args) |
| 711 | 719 | { |
| 712 | 720 | _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value |
| ... | ... | @@ -770,7 +778,7 @@ template <class _Rp, class... _ArgTypes> class __policy_func<_Rp(_ArgTypes...)> |
| 770 | 778 | } |
| 771 | 779 | } |
| 772 | 780 | |
| 773 | template <class _Fp, class = typename enable_if<!is_same<typename decay<_Fp>::type, __policy_func>::value>::type> | |
| 781 | template <class _Fp, class = typename enable_if<!is_same<__decay_t<_Fp>, __policy_func>::value>::type> | |
| 774 | 782 | _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) |
| 775 | 783 | : __policy_(__policy::__create_empty()) { |
| 776 | 784 | typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; |
| ... | ... | @@ -915,7 +923,7 @@ public: |
| 915 | 923 | { } |
| 916 | 924 | |
| 917 | 925 | virtual __base<_Rp(_ArgTypes...)>* __clone() const { |
| 918 | _LIBCPP_ASSERT(false, | |
| 926 | _LIBCPP_ASSERT_INTERNAL(false, | |
| 919 | 927 | "Block pointers are just pointers, so they should always fit into " |
| 920 | 928 | "std::function's small buffer optimization. This function should " |
| 921 | 929 | "never be invoked."); |
| ... | ... | @@ -935,7 +943,7 @@ public: |
| 935 | 943 | } |
| 936 | 944 | |
| 937 | 945 | virtual void destroy_deallocate() _NOEXCEPT { |
| 938 | _LIBCPP_ASSERT(false, | |
| 946 | _LIBCPP_ASSERT_INTERNAL(false, | |
| 939 | 947 | "Block pointers are just pointers, so they should always fit into " |
| 940 | 948 | "std::function's small buffer optimization. This function should " |
| 941 | 949 | "never be invoked."); |
| ... | ... | @@ -1002,11 +1010,11 @@ public: |
| 1002 | 1010 | _LIBCPP_INLINE_VISIBILITY |
| 1003 | 1011 | function() _NOEXCEPT { } |
| 1004 | 1012 | _LIBCPP_INLINE_VISIBILITY |
| 1005 | function(nullptr_t) _NOEXCEPT {} | |
| 1006 | function(const function&); | |
| 1007 | function(function&&) _NOEXCEPT; | |
| 1013 | _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} | |
| 1014 | _LIBCPP_HIDE_FROM_ABI function(const function&); | |
| 1015 | _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; | |
| 1008 | 1016 | template<class _Fp, class = _EnableIfLValueCallable<_Fp>> |
| 1009 | function(_Fp); | |
| 1017 | _LIBCPP_HIDE_FROM_ABI function(_Fp); | |
| 1010 | 1018 | |
| 1011 | 1019 | #if _LIBCPP_STD_VER <= 14 |
| 1012 | 1020 | template<class _Alloc> |
| ... | ... | @@ -1016,23 +1024,23 @@ public: |
| 1016 | 1024 | _LIBCPP_INLINE_VISIBILITY |
| 1017 | 1025 | function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} |
| 1018 | 1026 | template<class _Alloc> |
| 1019 | function(allocator_arg_t, const _Alloc&, const function&); | |
| 1027 | _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); | |
| 1020 | 1028 | template<class _Alloc> |
| 1021 | function(allocator_arg_t, const _Alloc&, function&&); | |
| 1029 | _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); | |
| 1022 | 1030 | template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>> |
| 1023 | function(allocator_arg_t, const _Alloc& __a, _Fp __f); | |
| 1031 | _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); | |
| 1024 | 1032 | #endif |
| 1025 | 1033 | |
| 1026 | function& operator=(const function&); | |
| 1027 | function& operator=(function&&) _NOEXCEPT; | |
| 1028 | function& operator=(nullptr_t) _NOEXCEPT; | |
| 1029 | template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>> | |
| 1030 | function& operator=(_Fp&&); | |
| 1034 | _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); | |
| 1035 | _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; | |
| 1036 | _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; | |
| 1037 | template<class _Fp, class = _EnableIfLValueCallable<__decay_t<_Fp>>> | |
| 1038 | _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); | |
| 1031 | 1039 | |
| 1032 | ~function(); | |
| 1040 | _LIBCPP_HIDE_FROM_ABI ~function(); | |
| 1033 | 1041 | |
| 1034 | 1042 | // function modifiers: |
| 1035 | void swap(function&) _NOEXCEPT; | |
| 1043 | _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; | |
| 1036 | 1044 | |
| 1037 | 1045 | #if _LIBCPP_STD_VER <= 14 |
| 1038 | 1046 | template<class _Fp, class _Alloc> |
| ... | ... | @@ -1050,17 +1058,21 @@ public: |
| 1050 | 1058 | // deleted overloads close possible hole in the type system |
| 1051 | 1059 | template<class _R2, class... _ArgTypes2> |
| 1052 | 1060 | bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; |
| 1061 | #if _LIBCPP_STD_VER <= 17 | |
| 1053 | 1062 | template<class _R2, class... _ArgTypes2> |
| 1054 | 1063 | bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; |
| 1064 | #endif | |
| 1055 | 1065 | public: |
| 1056 | 1066 | // function invocation: |
| 1057 | _Rp operator()(_ArgTypes...) const; | |
| 1067 | _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; | |
| 1058 | 1068 | |
| 1059 | 1069 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 1060 | 1070 | // function target access: |
| 1061 | const std::type_info& target_type() const _NOEXCEPT; | |
| 1062 | template <typename _Tp> _Tp* target() _NOEXCEPT; | |
| 1063 | template <typename _Tp> const _Tp* target() const _NOEXCEPT; | |
| 1071 | _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; | |
| 1072 | template <typename _Tp> | |
| 1073 | _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; | |
| 1074 | template <typename _Tp> | |
| 1075 | _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; | |
| 1064 | 1076 | #endif // _LIBCPP_HAS_NO_RTTI |
| 1065 | 1077 | }; |
| 1066 | 1078 | |
| ... | ... | @@ -1188,6 +1200,8 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 1188 | 1200 | bool |
| 1189 | 1201 | operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} |
| 1190 | 1202 | |
| 1203 | #if _LIBCPP_STD_VER <= 17 | |
| 1204 | ||
| 1191 | 1205 | template <class _Rp, class... _ArgTypes> |
| 1192 | 1206 | inline _LIBCPP_INLINE_VISIBILITY |
| 1193 | 1207 | bool |
| ... | ... | @@ -1203,6 +1217,8 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 1203 | 1217 | bool |
| 1204 | 1218 | operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} |
| 1205 | 1219 | |
| 1220 | #endif // _LIBCPP_STD_VER <= 17 | |
| 1221 | ||
| 1206 | 1222 | template <class _Rp, class... _ArgTypes> |
| 1207 | 1223 | inline _LIBCPP_INLINE_VISIBILITY |
| 1208 | 1224 | void |
lib/libcxx/include/__functional/hash.h+125-135| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #include <__functional/invoke.h> |
| 14 | 14 | #include <__functional/unary_function.h> |
| 15 | 15 | #include <__fwd/hash.h> |
| 16 | #include <__tuple_dir/sfinae_helpers.h> | |
| 16 | #include <__tuple/sfinae_helpers.h> | |
| 17 | 17 | #include <__type_traits/is_copy_constructible.h> |
| 18 | 18 | #include <__type_traits/is_default_constructible.h> |
| 19 | 19 | #include <__type_traits/is_enum.h> |
| ... | ... | @@ -35,7 +35,7 @@ |
| 35 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 36 | |
| 37 | 37 | template <class _Size> |
| 38 | inline _LIBCPP_INLINE_VISIBILITY | |
| 38 | inline _LIBCPP_HIDE_FROM_ABI | |
| 39 | 39 | _Size |
| 40 | 40 | __loadword(const void* __p) |
| 41 | 41 | { |
| ... | ... | @@ -53,73 +53,113 @@ struct __murmur2_or_cityhash; |
| 53 | 53 | template <class _Size> |
| 54 | 54 | struct __murmur2_or_cityhash<_Size, 32> |
| 55 | 55 | { |
| 56 | inline _Size operator()(const void* __key, _Size __len) | |
| 57 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; | |
| 56 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 57 | _Size operator()(const void* __key, _Size __len) const { | |
| 58 | // murmur2 | |
| 59 | const _Size __m = 0x5bd1e995; | |
| 60 | const _Size __r = 24; | |
| 61 | _Size __h = __len; | |
| 62 | const unsigned char* __data = static_cast<const unsigned char*>(__key); | |
| 63 | for (; __len >= 4; __data += 4, __len -= 4) | |
| 64 | { | |
| 65 | _Size __k = std::__loadword<_Size>(__data); | |
| 66 | __k *= __m; | |
| 67 | __k ^= __k >> __r; | |
| 68 | __k *= __m; | |
| 69 | __h *= __m; | |
| 70 | __h ^= __k; | |
| 71 | } | |
| 72 | switch (__len) | |
| 73 | { | |
| 74 | case 3: | |
| 75 | __h ^= static_cast<_Size>(__data[2] << 16); | |
| 76 | _LIBCPP_FALLTHROUGH(); | |
| 77 | case 2: | |
| 78 | __h ^= static_cast<_Size>(__data[1] << 8); | |
| 79 | _LIBCPP_FALLTHROUGH(); | |
| 80 | case 1: | |
| 81 | __h ^= __data[0]; | |
| 82 | __h *= __m; | |
| 83 | } | |
| 84 | __h ^= __h >> 13; | |
| 85 | __h *= __m; | |
| 86 | __h ^= __h >> 15; | |
| 87 | return __h; | |
| 88 | } | |
| 58 | 89 | }; |
| 59 | 90 | |
| 60 | // murmur2 | |
| 61 | 91 | template <class _Size> |
| 62 | _Size | |
| 63 | __murmur2_or_cityhash<_Size, 32>::operator()(const void* __key, _Size __len) | |
| 92 | struct __murmur2_or_cityhash<_Size, 64> | |
| 64 | 93 | { |
| 65 | const _Size __m = 0x5bd1e995; | |
| 66 | const _Size __r = 24; | |
| 67 | _Size __h = __len; | |
| 68 | const unsigned char* __data = static_cast<const unsigned char*>(__key); | |
| 69 | for (; __len >= 4; __data += 4, __len -= 4) | |
| 70 | { | |
| 71 | _Size __k = std::__loadword<_Size>(__data); | |
| 72 | __k *= __m; | |
| 73 | __k ^= __k >> __r; | |
| 74 | __k *= __m; | |
| 75 | __h *= __m; | |
| 76 | __h ^= __k; | |
| 77 | } | |
| 78 | switch (__len) | |
| 79 | { | |
| 80 | case 3: | |
| 81 | __h ^= static_cast<_Size>(__data[2] << 16); | |
| 82 | _LIBCPP_FALLTHROUGH(); | |
| 83 | case 2: | |
| 84 | __h ^= static_cast<_Size>(__data[1] << 8); | |
| 85 | _LIBCPP_FALLTHROUGH(); | |
| 86 | case 1: | |
| 87 | __h ^= __data[0]; | |
| 88 | __h *= __m; | |
| 94 | // cityhash64 | |
| 95 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 96 | _Size operator()(const void* __key, _Size __len) const { | |
| 97 | const char* __s = static_cast<const char*>(__key); | |
| 98 | if (__len <= 32) { | |
| 99 | if (__len <= 16) { | |
| 100 | return __hash_len_0_to_16(__s, __len); | |
| 101 | } else { | |
| 102 | return __hash_len_17_to_32(__s, __len); | |
| 103 | } | |
| 104 | } else if (__len <= 64) { | |
| 105 | return __hash_len_33_to_64(__s, __len); | |
| 89 | 106 | } |
| 90 | __h ^= __h >> 13; | |
| 91 | __h *= __m; | |
| 92 | __h ^= __h >> 15; | |
| 93 | return __h; | |
| 94 | } | |
| 95 | 107 | |
| 96 | template <class _Size> | |
| 97 | struct __murmur2_or_cityhash<_Size, 64> | |
| 98 | { | |
| 99 | inline _Size operator()(const void* __key, _Size __len) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK; | |
| 108 | // For strings over 64 bytes we hash the end first, and then as we | |
| 109 | // loop we keep 56 bytes of state: v, w, x, y, and z. | |
| 110 | _Size __x = std::__loadword<_Size>(__s + __len - 40); | |
| 111 | _Size __y = std::__loadword<_Size>(__s + __len - 16) + | |
| 112 | std::__loadword<_Size>(__s + __len - 56); | |
| 113 | _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, | |
| 114 | std::__loadword<_Size>(__s + __len - 24)); | |
| 115 | pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); | |
| 116 | pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); | |
| 117 | __x = __x * __k1 + std::__loadword<_Size>(__s); | |
| 118 | ||
| 119 | // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. | |
| 120 | __len = (__len - 1) & ~static_cast<_Size>(63); | |
| 121 | do { | |
| 122 | __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; | |
| 123 | __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; | |
| 124 | __x ^= __w.second; | |
| 125 | __y += __v.first + std::__loadword<_Size>(__s + 40); | |
| 126 | __z = __rotate(__z + __w.first, 33) * __k1; | |
| 127 | __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); | |
| 128 | __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, | |
| 129 | __y + std::__loadword<_Size>(__s + 16)); | |
| 130 | _VSTD::swap(__z, __x); | |
| 131 | __s += 64; | |
| 132 | __len -= 64; | |
| 133 | } while (__len != 0); | |
| 134 | return __hash_len_16( | |
| 135 | __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, | |
| 136 | __hash_len_16(__v.second, __w.second) + __x); | |
| 137 | } | |
| 100 | 138 | |
| 101 | private: | |
| 102 | // Some primes between 2^63 and 2^64. | |
| 103 | static const _Size __k0 = 0xc3a5c85c97cb3127ULL; | |
| 104 | static const _Size __k1 = 0xb492b66fbe98f273ULL; | |
| 105 | static const _Size __k2 = 0x9ae16a3b2f90404fULL; | |
| 106 | static const _Size __k3 = 0xc949d7c7509e6557ULL; | |
| 139 | private: | |
| 140 | // Some primes between 2^63 and 2^64. | |
| 141 | static const _Size __k0 = 0xc3a5c85c97cb3127ULL; | |
| 142 | static const _Size __k1 = 0xb492b66fbe98f273ULL; | |
| 143 | static const _Size __k2 = 0x9ae16a3b2f90404fULL; | |
| 144 | static const _Size __k3 = 0xc949d7c7509e6557ULL; | |
| 107 | 145 | |
| 146 | _LIBCPP_HIDE_FROM_ABI | |
| 108 | 147 | static _Size __rotate(_Size __val, int __shift) { |
| 109 | 148 | return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); |
| 110 | 149 | } |
| 111 | 150 | |
| 151 | _LIBCPP_HIDE_FROM_ABI | |
| 112 | 152 | static _Size __rotate_by_at_least_1(_Size __val, int __shift) { |
| 113 | 153 | return (__val >> __shift) | (__val << (64 - __shift)); |
| 114 | 154 | } |
| 115 | 155 | |
| 156 | _LIBCPP_HIDE_FROM_ABI | |
| 116 | 157 | static _Size __shift_mix(_Size __val) { |
| 117 | 158 | return __val ^ (__val >> 47); |
| 118 | 159 | } |
| 119 | 160 | |
| 120 | static _Size __hash_len_16(_Size __u, _Size __v) | |
| 121 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 122 | { | |
| 161 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 162 | static _Size __hash_len_16(_Size __u, _Size __v) { | |
| 123 | 163 | const _Size __mul = 0x9ddfea08eb382d69ULL; |
| 124 | 164 | _Size __a = (__u ^ __v) * __mul; |
| 125 | 165 | __a ^= (__a >> 47); |
| ... | ... | @@ -129,9 +169,8 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 129 | 169 | return __b; |
| 130 | 170 | } |
| 131 | 171 | |
| 132 | static _Size __hash_len_0_to_16(const char* __s, _Size __len) | |
| 133 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 134 | { | |
| 172 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 173 | static _Size __hash_len_0_to_16(const char* __s, _Size __len) { | |
| 135 | 174 | if (__len > 8) { |
| 136 | 175 | const _Size __a = std::__loadword<_Size>(__s); |
| 137 | 176 | const _Size __b = std::__loadword<_Size>(__s + __len - 8); |
| ... | ... | @@ -158,9 +197,8 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 158 | 197 | return __k2; |
| 159 | 198 | } |
| 160 | 199 | |
| 161 | static _Size __hash_len_17_to_32(const char *__s, _Size __len) | |
| 162 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 163 | { | |
| 200 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 201 | static _Size __hash_len_17_to_32(const char *__s, _Size __len) { | |
| 164 | 202 | const _Size __a = std::__loadword<_Size>(__s) * __k1; |
| 165 | 203 | const _Size __b = std::__loadword<_Size>(__s + 8); |
| 166 | 204 | const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; |
| ... | ... | @@ -171,9 +209,9 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 171 | 209 | |
| 172 | 210 | // Return a 16-byte hash for 48 bytes. Quick and dirty. |
| 173 | 211 | // Callers do best to use "random-looking" values for a and b. |
| 212 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 174 | 213 | static pair<_Size, _Size> __weak_hash_len_32_with_seeds( |
| 175 | 214 | _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) |
| 176 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 177 | 215 | { |
| 178 | 216 | __a += __w; |
| 179 | 217 | __b = __rotate(__b + __a + __z, 21); |
| ... | ... | @@ -185,9 +223,9 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 185 | 223 | } |
| 186 | 224 | |
| 187 | 225 | // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. |
| 226 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 188 | 227 | static pair<_Size, _Size> __weak_hash_len_32_with_seeds( |
| 189 | 228 | const char* __s, _Size __a, _Size __b) |
| 190 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 191 | 229 | { |
| 192 | 230 | return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s), |
| 193 | 231 | std::__loadword<_Size>(__s + 8), |
| ... | ... | @@ -198,9 +236,8 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 198 | 236 | } |
| 199 | 237 | |
| 200 | 238 | // Return an 8-byte hash for 33 to 64 bytes. |
| 201 | static _Size __hash_len_33_to_64(const char *__s, size_t __len) | |
| 202 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 203 | { | |
| 239 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK | |
| 240 | static _Size __hash_len_33_to_64(const char *__s, size_t __len) { | |
| 204 | 241 | _Size __z = std::__loadword<_Size>(__s + 24); |
| 205 | 242 | _Size __a = std::__loadword<_Size>(__s) + |
| 206 | 243 | (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; |
| ... | ... | @@ -225,53 +262,6 @@ struct __murmur2_or_cityhash<_Size, 64> |
| 225 | 262 | } |
| 226 | 263 | }; |
| 227 | 264 | |
| 228 | // cityhash64 | |
| 229 | template <class _Size> | |
| 230 | _Size | |
| 231 | __murmur2_or_cityhash<_Size, 64>::operator()(const void* __key, _Size __len) | |
| 232 | { | |
| 233 | const char* __s = static_cast<const char*>(__key); | |
| 234 | if (__len <= 32) { | |
| 235 | if (__len <= 16) { | |
| 236 | return __hash_len_0_to_16(__s, __len); | |
| 237 | } else { | |
| 238 | return __hash_len_17_to_32(__s, __len); | |
| 239 | } | |
| 240 | } else if (__len <= 64) { | |
| 241 | return __hash_len_33_to_64(__s, __len); | |
| 242 | } | |
| 243 | ||
| 244 | // For strings over 64 bytes we hash the end first, and then as we | |
| 245 | // loop we keep 56 bytes of state: v, w, x, y, and z. | |
| 246 | _Size __x = std::__loadword<_Size>(__s + __len - 40); | |
| 247 | _Size __y = std::__loadword<_Size>(__s + __len - 16) + | |
| 248 | std::__loadword<_Size>(__s + __len - 56); | |
| 249 | _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, | |
| 250 | std::__loadword<_Size>(__s + __len - 24)); | |
| 251 | pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); | |
| 252 | pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); | |
| 253 | __x = __x * __k1 + std::__loadword<_Size>(__s); | |
| 254 | ||
| 255 | // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. | |
| 256 | __len = (__len - 1) & ~static_cast<_Size>(63); | |
| 257 | do { | |
| 258 | __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; | |
| 259 | __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; | |
| 260 | __x ^= __w.second; | |
| 261 | __y += __v.first + std::__loadword<_Size>(__s + 40); | |
| 262 | __z = __rotate(__z + __w.first, 33) * __k1; | |
| 263 | __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); | |
| 264 | __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, | |
| 265 | __y + std::__loadword<_Size>(__s + 16)); | |
| 266 | _VSTD::swap(__z, __x); | |
| 267 | __s += 64; | |
| 268 | __len -= 64; | |
| 269 | } while (__len != 0); | |
| 270 | return __hash_len_16( | |
| 271 | __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, | |
| 272 | __hash_len_16(__v.second, __w.second) + __x); | |
| 273 | } | |
| 274 | ||
| 275 | 265 | template <class _Tp, size_t = sizeof(_Tp) / sizeof(size_t)> |
| 276 | 266 | struct __scalar_hash; |
| 277 | 267 | |
| ... | ... | @@ -279,7 +269,7 @@ template <class _Tp> |
| 279 | 269 | struct __scalar_hash<_Tp, 0> |
| 280 | 270 | : public __unary_function<_Tp, size_t> |
| 281 | 271 | { |
| 282 | _LIBCPP_INLINE_VISIBILITY | |
| 272 | _LIBCPP_HIDE_FROM_ABI | |
| 283 | 273 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 284 | 274 | { |
| 285 | 275 | union |
| ... | ... | @@ -297,7 +287,7 @@ template <class _Tp> |
| 297 | 287 | struct __scalar_hash<_Tp, 1> |
| 298 | 288 | : public __unary_function<_Tp, size_t> |
| 299 | 289 | { |
| 300 | _LIBCPP_INLINE_VISIBILITY | |
| 290 | _LIBCPP_HIDE_FROM_ABI | |
| 301 | 291 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 302 | 292 | { |
| 303 | 293 | union |
| ... | ... | @@ -314,7 +304,7 @@ template <class _Tp> |
| 314 | 304 | struct __scalar_hash<_Tp, 2> |
| 315 | 305 | : public __unary_function<_Tp, size_t> |
| 316 | 306 | { |
| 317 | _LIBCPP_INLINE_VISIBILITY | |
| 307 | _LIBCPP_HIDE_FROM_ABI | |
| 318 | 308 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 319 | 309 | { |
| 320 | 310 | union |
| ... | ... | @@ -335,7 +325,7 @@ template <class _Tp> |
| 335 | 325 | struct __scalar_hash<_Tp, 3> |
| 336 | 326 | : public __unary_function<_Tp, size_t> |
| 337 | 327 | { |
| 338 | _LIBCPP_INLINE_VISIBILITY | |
| 328 | _LIBCPP_HIDE_FROM_ABI | |
| 339 | 329 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 340 | 330 | { |
| 341 | 331 | union |
| ... | ... | @@ -357,7 +347,7 @@ template <class _Tp> |
| 357 | 347 | struct __scalar_hash<_Tp, 4> |
| 358 | 348 | : public __unary_function<_Tp, size_t> |
| 359 | 349 | { |
| 360 | _LIBCPP_INLINE_VISIBILITY | |
| 350 | _LIBCPP_HIDE_FROM_ABI | |
| 361 | 351 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 362 | 352 | { |
| 363 | 353 | union |
| ... | ... | @@ -381,7 +371,7 @@ struct _PairT { |
| 381 | 371 | size_t second; |
| 382 | 372 | }; |
| 383 | 373 | |
| 384 | _LIBCPP_INLINE_VISIBILITY | |
| 374 | _LIBCPP_HIDE_FROM_ABI | |
| 385 | 375 | inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { |
| 386 | 376 | typedef __scalar_hash<_PairT> _HashT; |
| 387 | 377 | const _PairT __p = {__lhs, __rhs}; |
| ... | ... | @@ -392,7 +382,7 @@ template<class _Tp> |
| 392 | 382 | struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> |
| 393 | 383 | : public __unary_function<_Tp*, size_t> |
| 394 | 384 | { |
| 395 | _LIBCPP_INLINE_VISIBILITY | |
| 385 | _LIBCPP_HIDE_FROM_ABI | |
| 396 | 386 | size_t operator()(_Tp* __v) const _NOEXCEPT |
| 397 | 387 | { |
| 398 | 388 | union |
| ... | ... | @@ -409,7 +399,7 @@ template <> |
| 409 | 399 | struct _LIBCPP_TEMPLATE_VIS hash<bool> |
| 410 | 400 | : public __unary_function<bool, size_t> |
| 411 | 401 | { |
| 412 | _LIBCPP_INLINE_VISIBILITY | |
| 402 | _LIBCPP_HIDE_FROM_ABI | |
| 413 | 403 | size_t operator()(bool __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 414 | 404 | }; |
| 415 | 405 | |
| ... | ... | @@ -417,7 +407,7 @@ template <> |
| 417 | 407 | struct _LIBCPP_TEMPLATE_VIS hash<char> |
| 418 | 408 | : public __unary_function<char, size_t> |
| 419 | 409 | { |
| 420 | _LIBCPP_INLINE_VISIBILITY | |
| 410 | _LIBCPP_HIDE_FROM_ABI | |
| 421 | 411 | size_t operator()(char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 422 | 412 | }; |
| 423 | 413 | |
| ... | ... | @@ -425,7 +415,7 @@ template <> |
| 425 | 415 | struct _LIBCPP_TEMPLATE_VIS hash<signed char> |
| 426 | 416 | : public __unary_function<signed char, size_t> |
| 427 | 417 | { |
| 428 | _LIBCPP_INLINE_VISIBILITY | |
| 418 | _LIBCPP_HIDE_FROM_ABI | |
| 429 | 419 | size_t operator()(signed char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 430 | 420 | }; |
| 431 | 421 | |
| ... | ... | @@ -433,7 +423,7 @@ template <> |
| 433 | 423 | struct _LIBCPP_TEMPLATE_VIS hash<unsigned char> |
| 434 | 424 | : public __unary_function<unsigned char, size_t> |
| 435 | 425 | { |
| 436 | _LIBCPP_INLINE_VISIBILITY | |
| 426 | _LIBCPP_HIDE_FROM_ABI | |
| 437 | 427 | size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 438 | 428 | }; |
| 439 | 429 | |
| ... | ... | @@ -442,7 +432,7 @@ template <> |
| 442 | 432 | struct _LIBCPP_TEMPLATE_VIS hash<char8_t> |
| 443 | 433 | : public __unary_function<char8_t, size_t> |
| 444 | 434 | { |
| 445 | _LIBCPP_INLINE_VISIBILITY | |
| 435 | _LIBCPP_HIDE_FROM_ABI | |
| 446 | 436 | size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 447 | 437 | }; |
| 448 | 438 | #endif // !_LIBCPP_HAS_NO_CHAR8_T |
| ... | ... | @@ -451,7 +441,7 @@ template <> |
| 451 | 441 | struct _LIBCPP_TEMPLATE_VIS hash<char16_t> |
| 452 | 442 | : public __unary_function<char16_t, size_t> |
| 453 | 443 | { |
| 454 | _LIBCPP_INLINE_VISIBILITY | |
| 444 | _LIBCPP_HIDE_FROM_ABI | |
| 455 | 445 | size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 456 | 446 | }; |
| 457 | 447 | |
| ... | ... | @@ -459,7 +449,7 @@ template <> |
| 459 | 449 | struct _LIBCPP_TEMPLATE_VIS hash<char32_t> |
| 460 | 450 | : public __unary_function<char32_t, size_t> |
| 461 | 451 | { |
| 462 | _LIBCPP_INLINE_VISIBILITY | |
| 452 | _LIBCPP_HIDE_FROM_ABI | |
| 463 | 453 | size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 464 | 454 | }; |
| 465 | 455 | |
| ... | ... | @@ -468,7 +458,7 @@ template <> |
| 468 | 458 | struct _LIBCPP_TEMPLATE_VIS hash<wchar_t> |
| 469 | 459 | : public __unary_function<wchar_t, size_t> |
| 470 | 460 | { |
| 471 | _LIBCPP_INLINE_VISIBILITY | |
| 461 | _LIBCPP_HIDE_FROM_ABI | |
| 472 | 462 | size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 473 | 463 | }; |
| 474 | 464 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -477,7 +467,7 @@ template <> |
| 477 | 467 | struct _LIBCPP_TEMPLATE_VIS hash<short> |
| 478 | 468 | : public __unary_function<short, size_t> |
| 479 | 469 | { |
| 480 | _LIBCPP_INLINE_VISIBILITY | |
| 470 | _LIBCPP_HIDE_FROM_ABI | |
| 481 | 471 | size_t operator()(short __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 482 | 472 | }; |
| 483 | 473 | |
| ... | ... | @@ -485,7 +475,7 @@ template <> |
| 485 | 475 | struct _LIBCPP_TEMPLATE_VIS hash<unsigned short> |
| 486 | 476 | : public __unary_function<unsigned short, size_t> |
| 487 | 477 | { |
| 488 | _LIBCPP_INLINE_VISIBILITY | |
| 478 | _LIBCPP_HIDE_FROM_ABI | |
| 489 | 479 | size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 490 | 480 | }; |
| 491 | 481 | |
| ... | ... | @@ -493,7 +483,7 @@ template <> |
| 493 | 483 | struct _LIBCPP_TEMPLATE_VIS hash<int> |
| 494 | 484 | : public __unary_function<int, size_t> |
| 495 | 485 | { |
| 496 | _LIBCPP_INLINE_VISIBILITY | |
| 486 | _LIBCPP_HIDE_FROM_ABI | |
| 497 | 487 | size_t operator()(int __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 498 | 488 | }; |
| 499 | 489 | |
| ... | ... | @@ -501,7 +491,7 @@ template <> |
| 501 | 491 | struct _LIBCPP_TEMPLATE_VIS hash<unsigned int> |
| 502 | 492 | : public __unary_function<unsigned int, size_t> |
| 503 | 493 | { |
| 504 | _LIBCPP_INLINE_VISIBILITY | |
| 494 | _LIBCPP_HIDE_FROM_ABI | |
| 505 | 495 | size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 506 | 496 | }; |
| 507 | 497 | |
| ... | ... | @@ -509,7 +499,7 @@ template <> |
| 509 | 499 | struct _LIBCPP_TEMPLATE_VIS hash<long> |
| 510 | 500 | : public __unary_function<long, size_t> |
| 511 | 501 | { |
| 512 | _LIBCPP_INLINE_VISIBILITY | |
| 502 | _LIBCPP_HIDE_FROM_ABI | |
| 513 | 503 | size_t operator()(long __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 514 | 504 | }; |
| 515 | 505 | |
| ... | ... | @@ -517,7 +507,7 @@ template <> |
| 517 | 507 | struct _LIBCPP_TEMPLATE_VIS hash<unsigned long> |
| 518 | 508 | : public __unary_function<unsigned long, size_t> |
| 519 | 509 | { |
| 520 | _LIBCPP_INLINE_VISIBILITY | |
| 510 | _LIBCPP_HIDE_FROM_ABI | |
| 521 | 511 | size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast<size_t>(__v);} |
| 522 | 512 | }; |
| 523 | 513 | |
| ... | ... | @@ -553,7 +543,7 @@ template <> |
| 553 | 543 | struct _LIBCPP_TEMPLATE_VIS hash<float> |
| 554 | 544 | : public __scalar_hash<float> |
| 555 | 545 | { |
| 556 | _LIBCPP_INLINE_VISIBILITY | |
| 546 | _LIBCPP_HIDE_FROM_ABI | |
| 557 | 547 | size_t operator()(float __v) const _NOEXCEPT |
| 558 | 548 | { |
| 559 | 549 | // -0.0 and 0.0 should return same hash |
| ... | ... | @@ -567,7 +557,7 @@ template <> |
| 567 | 557 | struct _LIBCPP_TEMPLATE_VIS hash<double> |
| 568 | 558 | : public __scalar_hash<double> |
| 569 | 559 | { |
| 570 | _LIBCPP_INLINE_VISIBILITY | |
| 560 | _LIBCPP_HIDE_FROM_ABI | |
| 571 | 561 | size_t operator()(double __v) const _NOEXCEPT |
| 572 | 562 | { |
| 573 | 563 | // -0.0 and 0.0 should return same hash |
| ... | ... | @@ -581,7 +571,7 @@ template <> |
| 581 | 571 | struct _LIBCPP_TEMPLATE_VIS hash<long double> |
| 582 | 572 | : public __scalar_hash<long double> |
| 583 | 573 | { |
| 584 | _LIBCPP_INLINE_VISIBILITY | |
| 574 | _LIBCPP_HIDE_FROM_ABI | |
| 585 | 575 | size_t operator()(long double __v) const _NOEXCEPT |
| 586 | 576 | { |
| 587 | 577 | // -0.0 and 0.0 should return same hash |
| ... | ... | @@ -631,7 +621,7 @@ template <class _Tp, bool = is_enum<_Tp>::value> |
| 631 | 621 | struct _LIBCPP_TEMPLATE_VIS __enum_hash |
| 632 | 622 | : public __unary_function<_Tp, size_t> |
| 633 | 623 | { |
| 634 | _LIBCPP_INLINE_VISIBILITY | |
| 624 | _LIBCPP_HIDE_FROM_ABI | |
| 635 | 625 | size_t operator()(_Tp __v) const _NOEXCEPT |
| 636 | 626 | { |
| 637 | 627 | typedef typename underlying_type<_Tp>::type type; |
| ... | ... | @@ -650,13 +640,13 @@ struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> |
| 650 | 640 | { |
| 651 | 641 | }; |
| 652 | 642 | |
| 653 | #if _LIBCPP_STD_VER > 14 | |
| 643 | #if _LIBCPP_STD_VER >= 17 | |
| 654 | 644 | |
| 655 | 645 | template <> |
| 656 | 646 | struct _LIBCPP_TEMPLATE_VIS hash<nullptr_t> |
| 657 | 647 | : public __unary_function<nullptr_t, size_t> |
| 658 | 648 | { |
| 659 | _LIBCPP_INLINE_VISIBILITY | |
| 649 | _LIBCPP_HIDE_FROM_ABI | |
| 660 | 650 | size_t operator()(nullptr_t) const _NOEXCEPT { |
| 661 | 651 | return 662607004ull; |
| 662 | 652 | } |
| ... | ... | @@ -677,7 +667,7 @@ using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant<bool, |
| 677 | 667 | is_default_constructible<_Hash>::value |
| 678 | 668 | >; |
| 679 | 669 | |
| 680 | #if _LIBCPP_STD_VER > 14 | |
| 670 | #if _LIBCPP_STD_VER >= 17 | |
| 681 | 671 | template <class _Type, class> |
| 682 | 672 | using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; |
| 683 | 673 |
lib/libcxx/include/__functional/identity.h+15-4| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___FUNCTIONAL_IDENTITY_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__type_traits/integral_constant.h> | |
| 14 | 15 | #include <__utility/forward.h> |
| 15 | 16 | |
| 16 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -19,27 +20,37 @@ |
| 19 | 20 | |
| 20 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 22 | |
| 23 | template <class _Tp> | |
| 24 | struct __is_identity : false_type {}; | |
| 25 | ||
| 22 | 26 | struct __identity { |
| 23 | 27 | template <class _Tp> |
| 24 | _LIBCPP_NODISCARD _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT { | |
| 28 | _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp&& operator()(_Tp&& __t) const _NOEXCEPT { | |
| 25 | 29 | return std::forward<_Tp>(__t); |
| 26 | 30 | } |
| 27 | 31 | |
| 28 | 32 | using is_transparent = void; |
| 29 | 33 | }; |
| 30 | 34 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 35 | template <> | |
| 36 | struct __is_identity<__identity> : true_type {}; | |
| 37 | ||
| 38 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 39 | |
| 33 | 40 | struct identity { |
| 34 | 41 | template<class _Tp> |
| 35 | _LIBCPP_NODISCARD_EXT constexpr _Tp&& operator()(_Tp&& __t) const noexcept | |
| 42 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept | |
| 36 | 43 | { |
| 37 | 44 | return _VSTD::forward<_Tp>(__t); |
| 38 | 45 | } |
| 39 | 46 | |
| 40 | 47 | using is_transparent = void; |
| 41 | 48 | }; |
| 42 | #endif // _LIBCPP_STD_VER > 17 | |
| 49 | ||
| 50 | template <> | |
| 51 | struct __is_identity<identity> : true_type {}; | |
| 52 | ||
| 53 | #endif // _LIBCPP_STD_VER >= 20 | |
| 43 | 54 | |
| 44 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 45 | 56 |
lib/libcxx/include/__functional/invoke.h+22-512| ... | ... | @@ -11,525 +11,16 @@ |
| 11 | 11 | #define _LIBCPP___FUNCTIONAL_INVOKE_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__type_traits/add_lvalue_reference.h> | |
| 15 | #include <__type_traits/apply_cv.h> | |
| 16 | #include <__type_traits/conditional.h> | |
| 17 | #include <__type_traits/decay.h> | |
| 18 | #include <__type_traits/enable_if.h> | |
| 19 | #include <__type_traits/integral_constant.h> | |
| 20 | #include <__type_traits/is_base_of.h> | |
| 21 | #include <__type_traits/is_core_convertible.h> | |
| 22 | #include <__type_traits/is_member_function_pointer.h> | |
| 23 | #include <__type_traits/is_member_object_pointer.h> | |
| 24 | #include <__type_traits/is_reference_wrapper.h> | |
| 25 | #include <__type_traits/is_same.h> | |
| 26 | #include <__type_traits/is_void.h> | |
| 27 | #include <__type_traits/nat.h> | |
| 28 | #include <__type_traits/remove_cv.h> | |
| 29 | #include <__utility/declval.h> | |
| 14 | #include <__type_traits/invoke.h> | |
| 30 | 15 | #include <__utility/forward.h> |
| 31 | 16 | |
| 32 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 33 | 18 | # pragma GCC system_header |
| 34 | 19 | #endif |
| 35 | 20 | |
| 36 | // TODO: Disentangle the type traits and std::invoke properly | |
| 37 | ||
| 38 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 22 | |
| 40 | struct __any | |
| 41 | { | |
| 42 | __any(...); | |
| 43 | }; | |
| 44 | ||
| 45 | template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> | |
| 46 | struct __member_pointer_traits_imp | |
| 47 | { | |
| 48 | }; | |
| 49 | ||
| 50 | template <class _Rp, class _Class, class ..._Param> | |
| 51 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> | |
| 52 | { | |
| 53 | typedef _Class _ClassType; | |
| 54 | typedef _Rp _ReturnType; | |
| 55 | typedef _Rp (_FnType) (_Param...); | |
| 56 | }; | |
| 57 | ||
| 58 | template <class _Rp, class _Class, class ..._Param> | |
| 59 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> | |
| 60 | { | |
| 61 | typedef _Class _ClassType; | |
| 62 | typedef _Rp _ReturnType; | |
| 63 | typedef _Rp (_FnType) (_Param..., ...); | |
| 64 | }; | |
| 65 | ||
| 66 | template <class _Rp, class _Class, class ..._Param> | |
| 67 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> | |
| 68 | { | |
| 69 | typedef _Class const _ClassType; | |
| 70 | typedef _Rp _ReturnType; | |
| 71 | typedef _Rp (_FnType) (_Param...); | |
| 72 | }; | |
| 73 | ||
| 74 | template <class _Rp, class _Class, class ..._Param> | |
| 75 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> | |
| 76 | { | |
| 77 | typedef _Class const _ClassType; | |
| 78 | typedef _Rp _ReturnType; | |
| 79 | typedef _Rp (_FnType) (_Param..., ...); | |
| 80 | }; | |
| 81 | ||
| 82 | template <class _Rp, class _Class, class ..._Param> | |
| 83 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> | |
| 84 | { | |
| 85 | typedef _Class volatile _ClassType; | |
| 86 | typedef _Rp _ReturnType; | |
| 87 | typedef _Rp (_FnType) (_Param...); | |
| 88 | }; | |
| 89 | ||
| 90 | template <class _Rp, class _Class, class ..._Param> | |
| 91 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> | |
| 92 | { | |
| 93 | typedef _Class volatile _ClassType; | |
| 94 | typedef _Rp _ReturnType; | |
| 95 | typedef _Rp (_FnType) (_Param..., ...); | |
| 96 | }; | |
| 97 | ||
| 98 | template <class _Rp, class _Class, class ..._Param> | |
| 99 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> | |
| 100 | { | |
| 101 | typedef _Class const volatile _ClassType; | |
| 102 | typedef _Rp _ReturnType; | |
| 103 | typedef _Rp (_FnType) (_Param...); | |
| 104 | }; | |
| 105 | ||
| 106 | template <class _Rp, class _Class, class ..._Param> | |
| 107 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> | |
| 108 | { | |
| 109 | typedef _Class const volatile _ClassType; | |
| 110 | typedef _Rp _ReturnType; | |
| 111 | typedef _Rp (_FnType) (_Param..., ...); | |
| 112 | }; | |
| 113 | ||
| 114 | template <class _Rp, class _Class, class ..._Param> | |
| 115 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> | |
| 116 | { | |
| 117 | typedef _Class& _ClassType; | |
| 118 | typedef _Rp _ReturnType; | |
| 119 | typedef _Rp (_FnType) (_Param...); | |
| 120 | }; | |
| 121 | ||
| 122 | template <class _Rp, class _Class, class ..._Param> | |
| 123 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> | |
| 124 | { | |
| 125 | typedef _Class& _ClassType; | |
| 126 | typedef _Rp _ReturnType; | |
| 127 | typedef _Rp (_FnType) (_Param..., ...); | |
| 128 | }; | |
| 129 | ||
| 130 | template <class _Rp, class _Class, class ..._Param> | |
| 131 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> | |
| 132 | { | |
| 133 | typedef _Class const& _ClassType; | |
| 134 | typedef _Rp _ReturnType; | |
| 135 | typedef _Rp (_FnType) (_Param...); | |
| 136 | }; | |
| 137 | ||
| 138 | template <class _Rp, class _Class, class ..._Param> | |
| 139 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> | |
| 140 | { | |
| 141 | typedef _Class const& _ClassType; | |
| 142 | typedef _Rp _ReturnType; | |
| 143 | typedef _Rp (_FnType) (_Param..., ...); | |
| 144 | }; | |
| 145 | ||
| 146 | template <class _Rp, class _Class, class ..._Param> | |
| 147 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> | |
| 148 | { | |
| 149 | typedef _Class volatile& _ClassType; | |
| 150 | typedef _Rp _ReturnType; | |
| 151 | typedef _Rp (_FnType) (_Param...); | |
| 152 | }; | |
| 153 | ||
| 154 | template <class _Rp, class _Class, class ..._Param> | |
| 155 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> | |
| 156 | { | |
| 157 | typedef _Class volatile& _ClassType; | |
| 158 | typedef _Rp _ReturnType; | |
| 159 | typedef _Rp (_FnType) (_Param..., ...); | |
| 160 | }; | |
| 161 | ||
| 162 | template <class _Rp, class _Class, class ..._Param> | |
| 163 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> | |
| 164 | { | |
| 165 | typedef _Class const volatile& _ClassType; | |
| 166 | typedef _Rp _ReturnType; | |
| 167 | typedef _Rp (_FnType) (_Param...); | |
| 168 | }; | |
| 169 | ||
| 170 | template <class _Rp, class _Class, class ..._Param> | |
| 171 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> | |
| 172 | { | |
| 173 | typedef _Class const volatile& _ClassType; | |
| 174 | typedef _Rp _ReturnType; | |
| 175 | typedef _Rp (_FnType) (_Param..., ...); | |
| 176 | }; | |
| 177 | ||
| 178 | template <class _Rp, class _Class, class ..._Param> | |
| 179 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> | |
| 180 | { | |
| 181 | typedef _Class&& _ClassType; | |
| 182 | typedef _Rp _ReturnType; | |
| 183 | typedef _Rp (_FnType) (_Param...); | |
| 184 | }; | |
| 185 | ||
| 186 | template <class _Rp, class _Class, class ..._Param> | |
| 187 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> | |
| 188 | { | |
| 189 | typedef _Class&& _ClassType; | |
| 190 | typedef _Rp _ReturnType; | |
| 191 | typedef _Rp (_FnType) (_Param..., ...); | |
| 192 | }; | |
| 193 | ||
| 194 | template <class _Rp, class _Class, class ..._Param> | |
| 195 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> | |
| 196 | { | |
| 197 | typedef _Class const&& _ClassType; | |
| 198 | typedef _Rp _ReturnType; | |
| 199 | typedef _Rp (_FnType) (_Param...); | |
| 200 | }; | |
| 201 | ||
| 202 | template <class _Rp, class _Class, class ..._Param> | |
| 203 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> | |
| 204 | { | |
| 205 | typedef _Class const&& _ClassType; | |
| 206 | typedef _Rp _ReturnType; | |
| 207 | typedef _Rp (_FnType) (_Param..., ...); | |
| 208 | }; | |
| 209 | ||
| 210 | template <class _Rp, class _Class, class ..._Param> | |
| 211 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> | |
| 212 | { | |
| 213 | typedef _Class volatile&& _ClassType; | |
| 214 | typedef _Rp _ReturnType; | |
| 215 | typedef _Rp (_FnType) (_Param...); | |
| 216 | }; | |
| 217 | ||
| 218 | template <class _Rp, class _Class, class ..._Param> | |
| 219 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> | |
| 220 | { | |
| 221 | typedef _Class volatile&& _ClassType; | |
| 222 | typedef _Rp _ReturnType; | |
| 223 | typedef _Rp (_FnType) (_Param..., ...); | |
| 224 | }; | |
| 225 | ||
| 226 | template <class _Rp, class _Class, class ..._Param> | |
| 227 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> | |
| 228 | { | |
| 229 | typedef _Class const volatile&& _ClassType; | |
| 230 | typedef _Rp _ReturnType; | |
| 231 | typedef _Rp (_FnType) (_Param...); | |
| 232 | }; | |
| 233 | ||
| 234 | template <class _Rp, class _Class, class ..._Param> | |
| 235 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> | |
| 236 | { | |
| 237 | typedef _Class const volatile&& _ClassType; | |
| 238 | typedef _Rp _ReturnType; | |
| 239 | typedef _Rp (_FnType) (_Param..., ...); | |
| 240 | }; | |
| 241 | ||
| 242 | template <class _Rp, class _Class> | |
| 243 | struct __member_pointer_traits_imp<_Rp _Class::*, false, true> | |
| 244 | { | |
| 245 | typedef _Class _ClassType; | |
| 246 | typedef _Rp _ReturnType; | |
| 247 | }; | |
| 248 | ||
| 249 | template <class _MP> | |
| 250 | struct __member_pointer_traits | |
| 251 | : public __member_pointer_traits_imp<__remove_cv_t<_MP>, | |
| 252 | is_member_function_pointer<_MP>::value, | |
| 253 | is_member_object_pointer<_MP>::value> | |
| 254 | { | |
| 255 | // typedef ... _ClassType; | |
| 256 | // typedef ... _ReturnType; | |
| 257 | // typedef ... _FnType; | |
| 258 | }; | |
| 259 | ||
| 260 | template <class _DecayedFp> | |
| 261 | struct __member_pointer_class_type {}; | |
| 262 | ||
| 263 | template <class _Ret, class _ClassType> | |
| 264 | struct __member_pointer_class_type<_Ret _ClassType::*> { | |
| 265 | typedef _ClassType type; | |
| 266 | }; | |
| 267 | ||
| 268 | template <class _Fp, class _A0, | |
| 269 | class _DecayFp = typename decay<_Fp>::type, | |
| 270 | class _DecayA0 = typename decay<_A0>::type, | |
| 271 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 272 | using __enable_if_bullet1 = typename enable_if | |
| 273 | < | |
| 274 | is_member_function_pointer<_DecayFp>::value | |
| 275 | && is_base_of<_ClassT, _DecayA0>::value | |
| 276 | >::type; | |
| 277 | ||
| 278 | template <class _Fp, class _A0, | |
| 279 | class _DecayFp = typename decay<_Fp>::type, | |
| 280 | class _DecayA0 = typename decay<_A0>::type> | |
| 281 | using __enable_if_bullet2 = typename enable_if | |
| 282 | < | |
| 283 | is_member_function_pointer<_DecayFp>::value | |
| 284 | && __is_reference_wrapper<_DecayA0>::value | |
| 285 | >::type; | |
| 286 | ||
| 287 | template <class _Fp, class _A0, | |
| 288 | class _DecayFp = typename decay<_Fp>::type, | |
| 289 | class _DecayA0 = typename decay<_A0>::type, | |
| 290 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 291 | using __enable_if_bullet3 = typename enable_if | |
| 292 | < | |
| 293 | is_member_function_pointer<_DecayFp>::value | |
| 294 | && !is_base_of<_ClassT, _DecayA0>::value | |
| 295 | && !__is_reference_wrapper<_DecayA0>::value | |
| 296 | >::type; | |
| 297 | ||
| 298 | template <class _Fp, class _A0, | |
| 299 | class _DecayFp = typename decay<_Fp>::type, | |
| 300 | class _DecayA0 = typename decay<_A0>::type, | |
| 301 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 302 | using __enable_if_bullet4 = typename enable_if | |
| 303 | < | |
| 304 | is_member_object_pointer<_DecayFp>::value | |
| 305 | && is_base_of<_ClassT, _DecayA0>::value | |
| 306 | >::type; | |
| 307 | ||
| 308 | template <class _Fp, class _A0, | |
| 309 | class _DecayFp = typename decay<_Fp>::type, | |
| 310 | class _DecayA0 = typename decay<_A0>::type> | |
| 311 | using __enable_if_bullet5 = typename enable_if | |
| 312 | < | |
| 313 | is_member_object_pointer<_DecayFp>::value | |
| 314 | && __is_reference_wrapper<_DecayA0>::value | |
| 315 | >::type; | |
| 316 | ||
| 317 | template <class _Fp, class _A0, | |
| 318 | class _DecayFp = typename decay<_Fp>::type, | |
| 319 | class _DecayA0 = typename decay<_A0>::type, | |
| 320 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 321 | using __enable_if_bullet6 = typename enable_if | |
| 322 | < | |
| 323 | is_member_object_pointer<_DecayFp>::value | |
| 324 | && !is_base_of<_ClassT, _DecayA0>::value | |
| 325 | && !__is_reference_wrapper<_DecayA0>::value | |
| 326 | >::type; | |
| 327 | ||
| 328 | // __invoke forward declarations | |
| 329 | ||
| 330 | // fall back - none of the bullets | |
| 331 | ||
| 332 | template <class ..._Args> | |
| 333 | __nat __invoke(__any, _Args&& ...__args); | |
| 334 | ||
| 335 | // bullets 1, 2 and 3 | |
| 336 | ||
| 337 | template <class _Fp, class _A0, class ..._Args, | |
| 338 | class = __enable_if_bullet1<_Fp, _A0> > | |
| 339 | inline _LIBCPP_INLINE_VISIBILITY | |
| 340 | _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 341 | __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) | |
| 342 | _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) | |
| 343 | { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } | |
| 344 | ||
| 345 | template <class _Fp, class _A0, class ..._Args, | |
| 346 | class = __enable_if_bullet2<_Fp, _A0> > | |
| 347 | inline _LIBCPP_INLINE_VISIBILITY | |
| 348 | _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 349 | __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) | |
| 350 | _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) | |
| 351 | { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } | |
| 352 | ||
| 353 | template <class _Fp, class _A0, class ..._Args, | |
| 354 | class = __enable_if_bullet3<_Fp, _A0> > | |
| 355 | inline _LIBCPP_INLINE_VISIBILITY | |
| 356 | _LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 357 | __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) | |
| 358 | _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) | |
| 359 | { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } | |
| 360 | ||
| 361 | // bullets 4, 5 and 6 | |
| 362 | ||
| 363 | template <class _Fp, class _A0, | |
| 364 | class = __enable_if_bullet4<_Fp, _A0> > | |
| 365 | inline _LIBCPP_INLINE_VISIBILITY | |
| 366 | _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>()) | |
| 367 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 368 | _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) | |
| 369 | { return static_cast<_A0&&>(__a0).*__f; } | |
| 370 | ||
| 371 | template <class _Fp, class _A0, | |
| 372 | class = __enable_if_bullet5<_Fp, _A0> > | |
| 373 | inline _LIBCPP_INLINE_VISIBILITY | |
| 374 | _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>()) | |
| 375 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 376 | _NOEXCEPT_(noexcept(__a0.get().*__f)) | |
| 377 | { return __a0.get().*__f; } | |
| 378 | ||
| 379 | template <class _Fp, class _A0, | |
| 380 | class = __enable_if_bullet6<_Fp, _A0> > | |
| 381 | inline _LIBCPP_INLINE_VISIBILITY | |
| 382 | _LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>()) | |
| 383 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 384 | _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) | |
| 385 | { return (*static_cast<_A0&&>(__a0)).*__f; } | |
| 386 | ||
| 387 | // bullet 7 | |
| 388 | ||
| 389 | template <class _Fp, class ..._Args> | |
| 390 | inline _LIBCPP_INLINE_VISIBILITY | |
| 391 | _LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...)) | |
| 392 | __invoke(_Fp&& __f, _Args&& ...__args) | |
| 393 | _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) | |
| 394 | { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } | |
| 395 | ||
| 396 | // __invokable | |
| 397 | template <class _Ret, class _Fp, class ..._Args> | |
| 398 | struct __invokable_r | |
| 399 | { | |
| 400 | template <class _XFp, class ..._XArgs> | |
| 401 | static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int); | |
| 402 | template <class _XFp, class ..._XArgs> | |
| 403 | static __nat __try_call(...); | |
| 404 | ||
| 405 | // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, | |
| 406 | // or incomplete array types as required by the standard. | |
| 407 | using _Result = decltype(__try_call<_Fp, _Args...>(0)); | |
| 408 | ||
| 409 | using type = __conditional_t< | |
| 410 | _IsNotSame<_Result, __nat>::value, | |
| 411 | __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >, | |
| 412 | false_type>; | |
| 413 | static const bool value = type::value; | |
| 414 | }; | |
| 415 | template <class _Fp, class ..._Args> | |
| 416 | using __invokable = __invokable_r<void, _Fp, _Args...>; | |
| 417 | ||
| 418 | template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args> | |
| 419 | struct __nothrow_invokable_r_imp { | |
| 420 | static const bool value = false; | |
| 421 | }; | |
| 422 | ||
| 423 | template <class _Ret, class _Fp, class ..._Args> | |
| 424 | struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> | |
| 425 | { | |
| 426 | typedef __nothrow_invokable_r_imp _ThisT; | |
| 427 | ||
| 428 | template <class _Tp> | |
| 429 | static void __test_noexcept(_Tp) _NOEXCEPT; | |
| 430 | ||
| 431 | #ifdef _LIBCPP_CXX03_LANG | |
| 432 | static const bool value = false; | |
| 433 | #else | |
| 434 | static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( | |
| 435 | _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...))); | |
| 436 | #endif | |
| 437 | }; | |
| 438 | ||
| 439 | template <class _Ret, class _Fp, class ..._Args> | |
| 440 | struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> | |
| 441 | { | |
| 442 | #ifdef _LIBCPP_CXX03_LANG | |
| 443 | static const bool value = false; | |
| 444 | #else | |
| 445 | static const bool value = noexcept( | |
| 446 | _VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)); | |
| 447 | #endif | |
| 448 | }; | |
| 449 | ||
| 450 | template <class _Ret, class _Fp, class ..._Args> | |
| 451 | using __nothrow_invokable_r = | |
| 452 | __nothrow_invokable_r_imp< | |
| 453 | __invokable_r<_Ret, _Fp, _Args...>::value, | |
| 454 | is_void<_Ret>::value, | |
| 455 | _Ret, _Fp, _Args... | |
| 456 | >; | |
| 457 | ||
| 458 | template <class _Fp, class ..._Args> | |
| 459 | using __nothrow_invokable = | |
| 460 | __nothrow_invokable_r_imp< | |
| 461 | __invokable<_Fp, _Args...>::value, | |
| 462 | true, void, _Fp, _Args... | |
| 463 | >; | |
| 464 | ||
| 465 | template <class _Fp, class ..._Args> | |
| 466 | struct __invoke_of | |
| 467 | : public enable_if< | |
| 468 | __invokable<_Fp, _Args...>::value, | |
| 469 | typename __invokable_r<void, _Fp, _Args...>::_Result> | |
| 470 | { | |
| 471 | }; | |
| 472 | ||
| 473 | template <class _Ret, bool = is_void<_Ret>::value> | |
| 474 | struct __invoke_void_return_wrapper | |
| 475 | { | |
| 476 | template <class ..._Args> | |
| 477 | static _Ret __call(_Args&&... __args) { | |
| 478 | return std::__invoke(std::forward<_Args>(__args)...); | |
| 479 | } | |
| 480 | }; | |
| 481 | ||
| 482 | template <class _Ret> | |
| 483 | struct __invoke_void_return_wrapper<_Ret, true> | |
| 484 | { | |
| 485 | template <class ..._Args> | |
| 486 | static void __call(_Args&&... __args) { | |
| 487 | std::__invoke(std::forward<_Args>(__args)...); | |
| 488 | } | |
| 489 | }; | |
| 490 | ||
| 491 | #if _LIBCPP_STD_VER > 14 | |
| 492 | ||
| 493 | // is_invocable | |
| 494 | ||
| 495 | template <class _Fn, class ..._Args> | |
| 496 | struct _LIBCPP_TEMPLATE_VIS is_invocable | |
| 497 | : integral_constant<bool, __invokable<_Fn, _Args...>::value> {}; | |
| 498 | ||
| 499 | template <class _Ret, class _Fn, class ..._Args> | |
| 500 | struct _LIBCPP_TEMPLATE_VIS is_invocable_r | |
| 501 | : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {}; | |
| 502 | ||
| 503 | template <class _Fn, class ..._Args> | |
| 504 | inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; | |
| 505 | ||
| 506 | template <class _Ret, class _Fn, class ..._Args> | |
| 507 | inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; | |
| 508 | ||
| 509 | // is_nothrow_invocable | |
| 510 | ||
| 511 | template <class _Fn, class ..._Args> | |
| 512 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable | |
| 513 | : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {}; | |
| 514 | ||
| 515 | template <class _Ret, class _Fn, class ..._Args> | |
| 516 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r | |
| 517 | : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {}; | |
| 518 | ||
| 519 | template <class _Fn, class ..._Args> | |
| 520 | inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; | |
| 521 | ||
| 522 | template <class _Ret, class _Fn, class ..._Args> | |
| 523 | inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; | |
| 524 | ||
| 525 | template <class _Fn, class... _Args> | |
| 526 | struct _LIBCPP_TEMPLATE_VIS invoke_result | |
| 527 | : __invoke_of<_Fn, _Args...> | |
| 528 | { | |
| 529 | }; | |
| 530 | ||
| 531 | template <class _Fn, class... _Args> | |
| 532 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 533 | 24 | |
| 534 | 25 | template <class _Fn, class ..._Args> |
| 535 | 26 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...> |
| ... | ... | @@ -539,7 +30,26 @@ invoke(_Fn&& __f, _Args&&... __args) |
| 539 | 30 | return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); |
| 540 | 31 | } |
| 541 | 32 | |
| 542 | #endif // _LIBCPP_STD_VER > 14 | |
| 33 | #endif // _LIBCPP_STD_VER >= 17 | |
| 34 | ||
| 35 | #if _LIBCPP_STD_VER >= 23 | |
| 36 | template <class _Result, class _Fn, class... _Args> | |
| 37 | requires is_invocable_r_v<_Result, _Fn, _Args...> | |
| 38 | _LIBCPP_HIDE_FROM_ABI constexpr _Result | |
| 39 | invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result, _Fn, _Args...>) { | |
| 40 | if constexpr (is_void_v<_Result>) { | |
| 41 | static_cast<void>(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...)); | |
| 42 | } else { | |
| 43 | // TODO: Use reference_converts_from_temporary_v once implemented | |
| 44 | // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>; | |
| 45 | // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>, | |
| 46 | static_assert(true, | |
| 47 | "Returning from invoke_r would bind a temporary object to the reference return type, " | |
| 48 | "which would result in a dangling reference."); | |
| 49 | return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); | |
| 50 | } | |
| 51 | } | |
| 52 | #endif | |
| 543 | 53 | |
| 544 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 545 | 55 |
lib/libcxx/include/__functional/is_transparent.h+3-2| ... | ... | @@ -11,7 +11,8 @@ |
| 11 | 11 | #define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <type_traits> | |
| 14 | #include <__type_traits/integral_constant.h> | |
| 15 | #include <__type_traits/void_t.h> | |
| 15 | 16 | |
| 16 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 18 | # pragma GCC system_header |
| ... | ... | @@ -19,7 +20,7 @@ |
| 19 | 20 | |
| 20 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 22 | |
| 22 | #if _LIBCPP_STD_VER > 11 | |
| 23 | #if _LIBCPP_STD_VER >= 14 | |
| 23 | 24 | |
| 24 | 25 | template <class _Tp, class, class = void> |
| 25 | 26 | struct __is_transparent : false_type {}; |
lib/libcxx/include/__functional/mem_fn.h-1| ... | ... | @@ -15,7 +15,6 @@ |
| 15 | 15 | #include <__functional/invoke.h> |
| 16 | 16 | #include <__functional/weak_result_type.h> |
| 17 | 17 | #include <__utility/forward.h> |
| 18 | #include <type_traits> | |
| 19 | 18 | |
| 20 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 20 | # pragma GCC system_header |
lib/libcxx/include/__functional/not_fn.h+6-3| ... | ... | @@ -13,8 +13,11 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/invoke.h> |
| 15 | 15 | #include <__functional/perfect_forward.h> |
| 16 | #include <__type_traits/decay.h> | |
| 17 | #include <__type_traits/enable_if.h> | |
| 18 | #include <__type_traits/is_constructible.h> | |
| 19 | #include <__type_traits/is_move_constructible.h> | |
| 16 | 20 | #include <__utility/forward.h> |
| 17 | #include <type_traits> | |
| 18 | 21 | |
| 19 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 23 | # pragma GCC system_header |
| ... | ... | @@ -22,7 +25,7 @@ |
| 22 | 25 | |
| 23 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 27 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 28 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 29 | |
| 27 | 30 | struct __not_fn_op { |
| 28 | 31 | template <class... _Args> |
| ... | ... | @@ -47,7 +50,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { |
| 47 | 50 | return __not_fn_t<decay_t<_Fn>>(_VSTD::forward<_Fn>(__f)); |
| 48 | 51 | } |
| 49 | 52 | |
| 50 | #endif // _LIBCPP_STD_VER > 14 | |
| 53 | #endif // _LIBCPP_STD_VER >= 17 | |
| 51 | 54 | |
| 52 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 56 |
lib/libcxx/include/__functional/operations.h+56-37| ... | ... | @@ -13,6 +13,9 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/binary_function.h> |
| 15 | 15 | #include <__functional/unary_function.h> |
| 16 | #include <__type_traits/integral_constant.h> | |
| 17 | #include <__type_traits/operation_traits.h> | |
| 18 | #include <__type_traits/predicate_traits.h> | |
| 16 | 19 | #include <__utility/forward.h> |
| 17 | 20 | |
| 18 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -23,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 26 | |
| 24 | 27 | // Arithmetic operations |
| 25 | 28 | |
| 26 | #if _LIBCPP_STD_VER > 11 | |
| 29 | #if _LIBCPP_STD_VER >= 14 | |
| 27 | 30 | template <class _Tp = void> |
| 28 | 31 | #else |
| 29 | 32 | template <class _Tp> |
| ... | ... | @@ -38,7 +41,15 @@ struct _LIBCPP_TEMPLATE_VIS plus |
| 38 | 41 | }; |
| 39 | 42 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); |
| 40 | 43 | |
| 41 | #if _LIBCPP_STD_VER > 11 | |
| 44 | template <class _Tp> | |
| 45 | struct __is_trivial_plus_operation<plus<_Tp>, _Tp, _Tp> : true_type {}; | |
| 46 | ||
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | template <class _Tp, class _Up> | |
| 49 | struct __is_trivial_plus_operation<plus<>, _Tp, _Up> : true_type {}; | |
| 50 | #endif | |
| 51 | ||
| 52 | #if _LIBCPP_STD_VER >= 14 | |
| 42 | 53 | template <> |
| 43 | 54 | struct _LIBCPP_TEMPLATE_VIS plus<void> |
| 44 | 55 | { |
| ... | ... | @@ -52,7 +63,7 @@ struct _LIBCPP_TEMPLATE_VIS plus<void> |
| 52 | 63 | }; |
| 53 | 64 | #endif |
| 54 | 65 | |
| 55 | #if _LIBCPP_STD_VER > 11 | |
| 66 | #if _LIBCPP_STD_VER >= 14 | |
| 56 | 67 | template <class _Tp = void> |
| 57 | 68 | #else |
| 58 | 69 | template <class _Tp> |
| ... | ... | @@ -67,7 +78,7 @@ struct _LIBCPP_TEMPLATE_VIS minus |
| 67 | 78 | }; |
| 68 | 79 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); |
| 69 | 80 | |
| 70 | #if _LIBCPP_STD_VER > 11 | |
| 81 | #if _LIBCPP_STD_VER >= 14 | |
| 71 | 82 | template <> |
| 72 | 83 | struct _LIBCPP_TEMPLATE_VIS minus<void> |
| 73 | 84 | { |
| ... | ... | @@ -81,7 +92,7 @@ struct _LIBCPP_TEMPLATE_VIS minus<void> |
| 81 | 92 | }; |
| 82 | 93 | #endif |
| 83 | 94 | |
| 84 | #if _LIBCPP_STD_VER > 11 | |
| 95 | #if _LIBCPP_STD_VER >= 14 | |
| 85 | 96 | template <class _Tp = void> |
| 86 | 97 | #else |
| 87 | 98 | template <class _Tp> |
| ... | ... | @@ -96,7 +107,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies |
| 96 | 107 | }; |
| 97 | 108 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); |
| 98 | 109 | |
| 99 | #if _LIBCPP_STD_VER > 11 | |
| 110 | #if _LIBCPP_STD_VER >= 14 | |
| 100 | 111 | template <> |
| 101 | 112 | struct _LIBCPP_TEMPLATE_VIS multiplies<void> |
| 102 | 113 | { |
| ... | ... | @@ -110,7 +121,7 @@ struct _LIBCPP_TEMPLATE_VIS multiplies<void> |
| 110 | 121 | }; |
| 111 | 122 | #endif |
| 112 | 123 | |
| 113 | #if _LIBCPP_STD_VER > 11 | |
| 124 | #if _LIBCPP_STD_VER >= 14 | |
| 114 | 125 | template <class _Tp = void> |
| 115 | 126 | #else |
| 116 | 127 | template <class _Tp> |
| ... | ... | @@ -125,7 +136,7 @@ struct _LIBCPP_TEMPLATE_VIS divides |
| 125 | 136 | }; |
| 126 | 137 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); |
| 127 | 138 | |
| 128 | #if _LIBCPP_STD_VER > 11 | |
| 139 | #if _LIBCPP_STD_VER >= 14 | |
| 129 | 140 | template <> |
| 130 | 141 | struct _LIBCPP_TEMPLATE_VIS divides<void> |
| 131 | 142 | { |
| ... | ... | @@ -139,7 +150,7 @@ struct _LIBCPP_TEMPLATE_VIS divides<void> |
| 139 | 150 | }; |
| 140 | 151 | #endif |
| 141 | 152 | |
| 142 | #if _LIBCPP_STD_VER > 11 | |
| 153 | #if _LIBCPP_STD_VER >= 14 | |
| 143 | 154 | template <class _Tp = void> |
| 144 | 155 | #else |
| 145 | 156 | template <class _Tp> |
| ... | ... | @@ -154,7 +165,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus |
| 154 | 165 | }; |
| 155 | 166 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); |
| 156 | 167 | |
| 157 | #if _LIBCPP_STD_VER > 11 | |
| 168 | #if _LIBCPP_STD_VER >= 14 | |
| 158 | 169 | template <> |
| 159 | 170 | struct _LIBCPP_TEMPLATE_VIS modulus<void> |
| 160 | 171 | { |
| ... | ... | @@ -168,7 +179,7 @@ struct _LIBCPP_TEMPLATE_VIS modulus<void> |
| 168 | 179 | }; |
| 169 | 180 | #endif |
| 170 | 181 | |
| 171 | #if _LIBCPP_STD_VER > 11 | |
| 182 | #if _LIBCPP_STD_VER >= 14 | |
| 172 | 183 | template <class _Tp = void> |
| 173 | 184 | #else |
| 174 | 185 | template <class _Tp> |
| ... | ... | @@ -183,7 +194,7 @@ struct _LIBCPP_TEMPLATE_VIS negate |
| 183 | 194 | }; |
| 184 | 195 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); |
| 185 | 196 | |
| 186 | #if _LIBCPP_STD_VER > 11 | |
| 197 | #if _LIBCPP_STD_VER >= 14 | |
| 187 | 198 | template <> |
| 188 | 199 | struct _LIBCPP_TEMPLATE_VIS negate<void> |
| 189 | 200 | { |
| ... | ... | @@ -199,7 +210,7 @@ struct _LIBCPP_TEMPLATE_VIS negate<void> |
| 199 | 210 | |
| 200 | 211 | // Bitwise operations |
| 201 | 212 | |
| 202 | #if _LIBCPP_STD_VER > 11 | |
| 213 | #if _LIBCPP_STD_VER >= 14 | |
| 203 | 214 | template <class _Tp = void> |
| 204 | 215 | #else |
| 205 | 216 | template <class _Tp> |
| ... | ... | @@ -214,7 +225,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and |
| 214 | 225 | }; |
| 215 | 226 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); |
| 216 | 227 | |
| 217 | #if _LIBCPP_STD_VER > 11 | |
| 228 | #if _LIBCPP_STD_VER >= 14 | |
| 218 | 229 | template <> |
| 219 | 230 | struct _LIBCPP_TEMPLATE_VIS bit_and<void> |
| 220 | 231 | { |
| ... | ... | @@ -228,7 +239,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_and<void> |
| 228 | 239 | }; |
| 229 | 240 | #endif |
| 230 | 241 | |
| 231 | #if _LIBCPP_STD_VER > 11 | |
| 242 | #if _LIBCPP_STD_VER >= 14 | |
| 232 | 243 | template <class _Tp = void> |
| 233 | 244 | struct _LIBCPP_TEMPLATE_VIS bit_not |
| 234 | 245 | : __unary_function<_Tp, _Tp> |
| ... | ... | @@ -252,7 +263,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_not<void> |
| 252 | 263 | }; |
| 253 | 264 | #endif |
| 254 | 265 | |
| 255 | #if _LIBCPP_STD_VER > 11 | |
| 266 | #if _LIBCPP_STD_VER >= 14 | |
| 256 | 267 | template <class _Tp = void> |
| 257 | 268 | #else |
| 258 | 269 | template <class _Tp> |
| ... | ... | @@ -267,7 +278,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or |
| 267 | 278 | }; |
| 268 | 279 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); |
| 269 | 280 | |
| 270 | #if _LIBCPP_STD_VER > 11 | |
| 281 | #if _LIBCPP_STD_VER >= 14 | |
| 271 | 282 | template <> |
| 272 | 283 | struct _LIBCPP_TEMPLATE_VIS bit_or<void> |
| 273 | 284 | { |
| ... | ... | @@ -281,7 +292,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_or<void> |
| 281 | 292 | }; |
| 282 | 293 | #endif |
| 283 | 294 | |
| 284 | #if _LIBCPP_STD_VER > 11 | |
| 295 | #if _LIBCPP_STD_VER >= 14 | |
| 285 | 296 | template <class _Tp = void> |
| 286 | 297 | #else |
| 287 | 298 | template <class _Tp> |
| ... | ... | @@ -296,7 +307,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor |
| 296 | 307 | }; |
| 297 | 308 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); |
| 298 | 309 | |
| 299 | #if _LIBCPP_STD_VER > 11 | |
| 310 | #if _LIBCPP_STD_VER >= 14 | |
| 300 | 311 | template <> |
| 301 | 312 | struct _LIBCPP_TEMPLATE_VIS bit_xor<void> |
| 302 | 313 | { |
| ... | ... | @@ -312,7 +323,7 @@ struct _LIBCPP_TEMPLATE_VIS bit_xor<void> |
| 312 | 323 | |
| 313 | 324 | // Comparison operations |
| 314 | 325 | |
| 315 | #if _LIBCPP_STD_VER > 11 | |
| 326 | #if _LIBCPP_STD_VER >= 14 | |
| 316 | 327 | template <class _Tp = void> |
| 317 | 328 | #else |
| 318 | 329 | template <class _Tp> |
| ... | ... | @@ -327,7 +338,7 @@ struct _LIBCPP_TEMPLATE_VIS equal_to |
| 327 | 338 | }; |
| 328 | 339 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); |
| 329 | 340 | |
| 330 | #if _LIBCPP_STD_VER > 11 | |
| 341 | #if _LIBCPP_STD_VER >= 14 | |
| 331 | 342 | template <> |
| 332 | 343 | struct _LIBCPP_TEMPLATE_VIS equal_to<void> |
| 333 | 344 | { |
| ... | ... | @@ -341,7 +352,15 @@ struct _LIBCPP_TEMPLATE_VIS equal_to<void> |
| 341 | 352 | }; |
| 342 | 353 | #endif |
| 343 | 354 | |
| 344 | #if _LIBCPP_STD_VER > 11 | |
| 355 | template <class _Tp> | |
| 356 | struct __is_trivial_equality_predicate<equal_to<_Tp>, _Tp, _Tp> : true_type {}; | |
| 357 | ||
| 358 | #if _LIBCPP_STD_VER >= 14 | |
| 359 | template <class _Tp> | |
| 360 | struct __is_trivial_equality_predicate<equal_to<>, _Tp, _Tp> : true_type {}; | |
| 361 | #endif | |
| 362 | ||
| 363 | #if _LIBCPP_STD_VER >= 14 | |
| 345 | 364 | template <class _Tp = void> |
| 346 | 365 | #else |
| 347 | 366 | template <class _Tp> |
| ... | ... | @@ -356,7 +375,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to |
| 356 | 375 | }; |
| 357 | 376 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); |
| 358 | 377 | |
| 359 | #if _LIBCPP_STD_VER > 11 | |
| 378 | #if _LIBCPP_STD_VER >= 14 | |
| 360 | 379 | template <> |
| 361 | 380 | struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> |
| 362 | 381 | { |
| ... | ... | @@ -370,7 +389,7 @@ struct _LIBCPP_TEMPLATE_VIS not_equal_to<void> |
| 370 | 389 | }; |
| 371 | 390 | #endif |
| 372 | 391 | |
| 373 | #if _LIBCPP_STD_VER > 11 | |
| 392 | #if _LIBCPP_STD_VER >= 14 | |
| 374 | 393 | template <class _Tp = void> |
| 375 | 394 | #else |
| 376 | 395 | template <class _Tp> |
| ... | ... | @@ -385,7 +404,7 @@ struct _LIBCPP_TEMPLATE_VIS less |
| 385 | 404 | }; |
| 386 | 405 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); |
| 387 | 406 | |
| 388 | #if _LIBCPP_STD_VER > 11 | |
| 407 | #if _LIBCPP_STD_VER >= 14 | |
| 389 | 408 | template <> |
| 390 | 409 | struct _LIBCPP_TEMPLATE_VIS less<void> |
| 391 | 410 | { |
| ... | ... | @@ -399,7 +418,7 @@ struct _LIBCPP_TEMPLATE_VIS less<void> |
| 399 | 418 | }; |
| 400 | 419 | #endif |
| 401 | 420 | |
| 402 | #if _LIBCPP_STD_VER > 11 | |
| 421 | #if _LIBCPP_STD_VER >= 14 | |
| 403 | 422 | template <class _Tp = void> |
| 404 | 423 | #else |
| 405 | 424 | template <class _Tp> |
| ... | ... | @@ -414,7 +433,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal |
| 414 | 433 | }; |
| 415 | 434 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); |
| 416 | 435 | |
| 417 | #if _LIBCPP_STD_VER > 11 | |
| 436 | #if _LIBCPP_STD_VER >= 14 | |
| 418 | 437 | template <> |
| 419 | 438 | struct _LIBCPP_TEMPLATE_VIS less_equal<void> |
| 420 | 439 | { |
| ... | ... | @@ -428,7 +447,7 @@ struct _LIBCPP_TEMPLATE_VIS less_equal<void> |
| 428 | 447 | }; |
| 429 | 448 | #endif |
| 430 | 449 | |
| 431 | #if _LIBCPP_STD_VER > 11 | |
| 450 | #if _LIBCPP_STD_VER >= 14 | |
| 432 | 451 | template <class _Tp = void> |
| 433 | 452 | #else |
| 434 | 453 | template <class _Tp> |
| ... | ... | @@ -443,7 +462,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal |
| 443 | 462 | }; |
| 444 | 463 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); |
| 445 | 464 | |
| 446 | #if _LIBCPP_STD_VER > 11 | |
| 465 | #if _LIBCPP_STD_VER >= 14 | |
| 447 | 466 | template <> |
| 448 | 467 | struct _LIBCPP_TEMPLATE_VIS greater_equal<void> |
| 449 | 468 | { |
| ... | ... | @@ -457,7 +476,7 @@ struct _LIBCPP_TEMPLATE_VIS greater_equal<void> |
| 457 | 476 | }; |
| 458 | 477 | #endif |
| 459 | 478 | |
| 460 | #if _LIBCPP_STD_VER > 11 | |
| 479 | #if _LIBCPP_STD_VER >= 14 | |
| 461 | 480 | template <class _Tp = void> |
| 462 | 481 | #else |
| 463 | 482 | template <class _Tp> |
| ... | ... | @@ -472,7 +491,7 @@ struct _LIBCPP_TEMPLATE_VIS greater |
| 472 | 491 | }; |
| 473 | 492 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); |
| 474 | 493 | |
| 475 | #if _LIBCPP_STD_VER > 11 | |
| 494 | #if _LIBCPP_STD_VER >= 14 | |
| 476 | 495 | template <> |
| 477 | 496 | struct _LIBCPP_TEMPLATE_VIS greater<void> |
| 478 | 497 | { |
| ... | ... | @@ -488,7 +507,7 @@ struct _LIBCPP_TEMPLATE_VIS greater<void> |
| 488 | 507 | |
| 489 | 508 | // Logical operations |
| 490 | 509 | |
| 491 | #if _LIBCPP_STD_VER > 11 | |
| 510 | #if _LIBCPP_STD_VER >= 14 | |
| 492 | 511 | template <class _Tp = void> |
| 493 | 512 | #else |
| 494 | 513 | template <class _Tp> |
| ... | ... | @@ -503,7 +522,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and |
| 503 | 522 | }; |
| 504 | 523 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); |
| 505 | 524 | |
| 506 | #if _LIBCPP_STD_VER > 11 | |
| 525 | #if _LIBCPP_STD_VER >= 14 | |
| 507 | 526 | template <> |
| 508 | 527 | struct _LIBCPP_TEMPLATE_VIS logical_and<void> |
| 509 | 528 | { |
| ... | ... | @@ -517,7 +536,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_and<void> |
| 517 | 536 | }; |
| 518 | 537 | #endif |
| 519 | 538 | |
| 520 | #if _LIBCPP_STD_VER > 11 | |
| 539 | #if _LIBCPP_STD_VER >= 14 | |
| 521 | 540 | template <class _Tp = void> |
| 522 | 541 | #else |
| 523 | 542 | template <class _Tp> |
| ... | ... | @@ -532,7 +551,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not |
| 532 | 551 | }; |
| 533 | 552 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); |
| 534 | 553 | |
| 535 | #if _LIBCPP_STD_VER > 11 | |
| 554 | #if _LIBCPP_STD_VER >= 14 | |
| 536 | 555 | template <> |
| 537 | 556 | struct _LIBCPP_TEMPLATE_VIS logical_not<void> |
| 538 | 557 | { |
| ... | ... | @@ -546,7 +565,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_not<void> |
| 546 | 565 | }; |
| 547 | 566 | #endif |
| 548 | 567 | |
| 549 | #if _LIBCPP_STD_VER > 11 | |
| 568 | #if _LIBCPP_STD_VER >= 14 | |
| 550 | 569 | template <class _Tp = void> |
| 551 | 570 | #else |
| 552 | 571 | template <class _Tp> |
| ... | ... | @@ -561,7 +580,7 @@ struct _LIBCPP_TEMPLATE_VIS logical_or |
| 561 | 580 | }; |
| 562 | 581 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); |
| 563 | 582 | |
| 564 | #if _LIBCPP_STD_VER > 11 | |
| 583 | #if _LIBCPP_STD_VER >= 14 | |
| 565 | 584 | template <> |
| 566 | 585 | struct _LIBCPP_TEMPLATE_VIS logical_or<void> |
| 567 | 586 | { |
lib/libcxx/include/__functional/perfect_forward.h+16-8| ... | ... | @@ -11,19 +11,25 @@ |
| 11 | 11 | #define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__type_traits/enable_if.h> | |
| 15 | #include <__type_traits/invoke.h> | |
| 16 | #include <__type_traits/is_constructible.h> | |
| 14 | 17 | #include <__utility/declval.h> |
| 15 | 18 | #include <__utility/forward.h> |
| 19 | #include <__utility/integer_sequence.h> | |
| 16 | 20 | #include <__utility/move.h> |
| 17 | 21 | #include <tuple> |
| 18 | #include <type_traits> | |
| 19 | 22 | |
| 20 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 24 | # pragma GCC system_header |
| 22 | 25 | #endif |
| 23 | 26 | |
| 27 | _LIBCPP_PUSH_MACROS | |
| 28 | #include <__undef_macros> | |
| 29 | ||
| 24 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 31 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 32 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 33 | |
| 28 | 34 | template <class _Op, class _Indices, class... _BoundArgs> |
| 29 | 35 | struct __perfect_forward_impl; |
| ... | ... | @@ -37,14 +43,14 @@ public: |
| 37 | 43 | template <class... _Args, class = enable_if_t< |
| 38 | 44 | is_constructible_v<tuple<_BoundArgs...>, _Args&&...> |
| 39 | 45 | >> |
| 40 | explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) | |
| 46 | _LIBCPP_HIDE_FROM_ABI explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) | |
| 41 | 47 | : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {} |
| 42 | 48 | |
| 43 | __perfect_forward_impl(__perfect_forward_impl const&) = default; | |
| 44 | __perfect_forward_impl(__perfect_forward_impl&&) = default; | |
| 49 | _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl const&) = default; | |
| 50 | _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default; | |
| 45 | 51 | |
| 46 | __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; | |
| 47 | __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; | |
| 52 | _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; | |
| 53 | _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; | |
| 48 | 54 | |
| 49 | 55 | template <class... _Args, class = enable_if_t<is_invocable_v<_Op, _BoundArgs&..., _Args...>>> |
| 50 | 56 | _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & |
| ... | ... | @@ -87,8 +93,10 @@ public: |
| 87 | 93 | template <class _Op, class ..._Args> |
| 88 | 94 | using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; |
| 89 | 95 | |
| 90 | #endif // _LIBCPP_STD_VER > 14 | |
| 96 | #endif // _LIBCPP_STD_VER >= 17 | |
| 91 | 97 | |
| 92 | 98 | _LIBCPP_END_NAMESPACE_STD |
| 93 | 99 | |
| 100 | _LIBCPP_POP_MACROS | |
| 101 | ||
| 94 | 102 | #endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H |
lib/libcxx/include/__functional/ranges_operations.h+13-8| ... | ... | @@ -13,6 +13,8 @@ |
| 13 | 13 | #include <__concepts/equality_comparable.h> |
| 14 | 14 | #include <__concepts/totally_ordered.h> |
| 15 | 15 | #include <__config> |
| 16 | #include <__type_traits/integral_constant.h> | |
| 17 | #include <__type_traits/predicate_traits.h> | |
| 16 | 18 | #include <__utility/forward.h> |
| 17 | 19 | |
| 18 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -21,14 +23,14 @@ |
| 21 | 23 | |
| 22 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 25 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 27 | |
| 26 | 28 | namespace ranges { |
| 27 | 29 | |
| 28 | 30 | struct equal_to { |
| 29 | 31 | template <class _Tp, class _Up> |
| 30 | 32 | requires equality_comparable_with<_Tp, _Up> |
| 31 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 33 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 32 | 34 | noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) { |
| 33 | 35 | return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u); |
| 34 | 36 | } |
| ... | ... | @@ -39,7 +41,7 @@ struct equal_to { |
| 39 | 41 | struct not_equal_to { |
| 40 | 42 | template <class _Tp, class _Up> |
| 41 | 43 | requires equality_comparable_with<_Tp, _Up> |
| 42 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 44 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 43 | 45 | noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) { |
| 44 | 46 | return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)); |
| 45 | 47 | } |
| ... | ... | @@ -50,7 +52,7 @@ struct not_equal_to { |
| 50 | 52 | struct less { |
| 51 | 53 | template <class _Tp, class _Up> |
| 52 | 54 | requires totally_ordered_with<_Tp, _Up> |
| 53 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 55 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 54 | 56 | noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) { |
| 55 | 57 | return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u); |
| 56 | 58 | } |
| ... | ... | @@ -61,7 +63,7 @@ struct less { |
| 61 | 63 | struct less_equal { |
| 62 | 64 | template <class _Tp, class _Up> |
| 63 | 65 | requires totally_ordered_with<_Tp, _Up> |
| 64 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 66 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 65 | 67 | noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) { |
| 66 | 68 | return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)); |
| 67 | 69 | } |
| ... | ... | @@ -72,7 +74,7 @@ struct less_equal { |
| 72 | 74 | struct greater { |
| 73 | 75 | template <class _Tp, class _Up> |
| 74 | 76 | requires totally_ordered_with<_Tp, _Up> |
| 75 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 77 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 76 | 78 | noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) { |
| 77 | 79 | return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t); |
| 78 | 80 | } |
| ... | ... | @@ -83,7 +85,7 @@ struct greater { |
| 83 | 85 | struct greater_equal { |
| 84 | 86 | template <class _Tp, class _Up> |
| 85 | 87 | requires totally_ordered_with<_Tp, _Up> |
| 86 | [[nodiscard]] constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 88 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const | |
| 87 | 89 | noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) { |
| 88 | 90 | return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)); |
| 89 | 91 | } |
| ... | ... | @@ -93,7 +95,10 @@ struct greater_equal { |
| 93 | 95 | |
| 94 | 96 | } // namespace ranges |
| 95 | 97 | |
| 96 | #endif // _LIBCPP_STD_VER > 17 | |
| 98 | template <class _Lhs, class _Rhs> | |
| 99 | struct __is_trivial_equality_predicate<ranges::equal_to, _Lhs, _Rhs> : true_type {}; | |
| 100 | ||
| 101 | #endif // _LIBCPP_STD_VER >= 20 | |
| 97 | 102 | |
| 98 | 103 | _LIBCPP_END_NAMESPACE_STD |
| 99 | 104 |
lib/libcxx/include/__functional/reference_wrapper.h+8-2| ... | ... | @@ -55,12 +55,18 @@ public: |
| 55 | 55 | template <class... _ArgTypes> |
| 56 | 56 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 57 | 57 | typename __invoke_of<type&, _ArgTypes...>::type |
| 58 | operator() (_ArgTypes&&... __args) const { | |
| 58 | operator() (_ArgTypes&&... __args) const | |
| 59 | #if _LIBCPP_STD_VER >= 17 | |
| 60 | // Since is_nothrow_invocable requires C++17 LWG3764 is not backported | |
| 61 | // to earlier versions. | |
| 62 | noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) | |
| 63 | #endif | |
| 64 | { | |
| 59 | 65 | return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); |
| 60 | 66 | } |
| 61 | 67 | }; |
| 62 | 68 | |
| 63 | #if _LIBCPP_STD_VER > 14 | |
| 69 | #if _LIBCPP_STD_VER >= 17 | |
| 64 | 70 | template <class _Tp> |
| 65 | 71 | reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; |
| 66 | 72 | #endif |
lib/libcxx/include/__functional/unwrap_ref.h deleted-58| ... | ... | @@ -1,58 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FUNCTIONAL_UNWRAP_REF_H | |
| 10 | #define _LIBCPP___FUNCTIONAL_UNWRAP_REF_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/decay.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _Tp> | |
| 22 | struct __unwrap_reference { typedef _LIBCPP_NODEBUG _Tp type; }; | |
| 23 | ||
| 24 | template <class _Tp> | |
| 25 | class reference_wrapper; | |
| 26 | ||
| 27 | template <class _Tp> | |
| 28 | struct __unwrap_reference<reference_wrapper<_Tp> > { typedef _LIBCPP_NODEBUG _Tp& type; }; | |
| 29 | ||
| 30 | template <class _Tp> | |
| 31 | struct decay; | |
| 32 | ||
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 34 | template <class _Tp> | |
| 35 | struct unwrap_reference : __unwrap_reference<_Tp> { }; | |
| 36 | ||
| 37 | template <class _Tp> | |
| 38 | using unwrap_reference_t = typename unwrap_reference<_Tp>::type; | |
| 39 | ||
| 40 | template <class _Tp> | |
| 41 | struct unwrap_ref_decay : unwrap_reference<typename decay<_Tp>::type> { }; | |
| 42 | ||
| 43 | template <class _Tp> | |
| 44 | using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; | |
| 45 | #endif // > C++17 | |
| 46 | ||
| 47 | template <class _Tp> | |
| 48 | struct __unwrap_ref_decay | |
| 49 | #if _LIBCPP_STD_VER > 17 | |
| 50 | : unwrap_ref_decay<_Tp> | |
| 51 | #else | |
| 52 | : __unwrap_reference<typename decay<_Tp>::type> | |
| 53 | #endif | |
| 54 | { }; | |
| 55 | ||
| 56 | _LIBCPP_END_NAMESPACE_STD | |
| 57 | ||
| 58 | #endif // _LIBCPP___FUNCTIONAL_UNWRAP_REF_H |
lib/libcxx/include/__fwd/fstream.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_FSTREAM_H | |
| 10 | #define _LIBCPP___FWD_FSTREAM_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_filebuf; | |
| 23 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 24 | class _LIBCPP_TEMPLATE_VIS basic_ifstream; | |
| 25 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 26 | class _LIBCPP_TEMPLATE_VIS basic_ofstream; | |
| 27 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 28 | class _LIBCPP_TEMPLATE_VIS basic_fstream; | |
| 29 | ||
| 30 | using filebuf = basic_filebuf<char>; | |
| 31 | using ifstream = basic_ifstream<char>; | |
| 32 | using ofstream = basic_ofstream<char>; | |
| 33 | using fstream = basic_fstream<char>; | |
| 34 | ||
| 35 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 36 | using wfilebuf = basic_filebuf<wchar_t>; | |
| 37 | using wifstream = basic_ifstream<wchar_t>; | |
| 38 | using wofstream = basic_ofstream<wchar_t>; | |
| 39 | using wfstream = basic_fstream<wchar_t>; | |
| 40 | #endif | |
| 41 | ||
| 42 | template <class _CharT, class _Traits> | |
| 43 | class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf; | |
| 44 | template <class _CharT, class _Traits> | |
| 45 | class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream; | |
| 46 | template <class _CharT, class _Traits> | |
| 47 | class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream; | |
| 48 | template <class _CharT, class _Traits> | |
| 49 | class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream; | |
| 50 | ||
| 51 | _LIBCPP_END_NAMESPACE_STD | |
| 52 | ||
| 53 | #endif // _LIBCPP___FWD_FSTREAM_H |
lib/libcxx/include/__fwd/get.h+1-1| ... | ... | @@ -15,7 +15,7 @@ |
| 15 | 15 | #include <__fwd/pair.h> |
| 16 | 16 | #include <__fwd/subrange.h> |
| 17 | 17 | #include <__fwd/tuple.h> |
| 18 | #include <__tuple_dir/tuple_element.h> | |
| 18 | #include <__tuple/tuple_element.h> | |
| 19 | 19 | #include <cstddef> |
| 20 | 20 | |
| 21 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
lib/libcxx/include/__fwd/ios.h created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_IOS_H | |
| 10 | #define _LIBCPP___FWD_IOS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_ios; | |
| 23 | ||
| 24 | using ios = basic_ios<char>; | |
| 25 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 26 | using wios = basic_ios<wchar_t>; | |
| 27 | #endif | |
| 28 | ||
| 29 | template <class _CharT, class _Traits> | |
| 30 | class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; | |
| 31 | ||
| 32 | #if defined(_NEWLIB_VERSION) | |
| 33 | // On newlib, off_t is 'long int' | |
| 34 | using streamoff = long int; // for char_traits in <string> | |
| 35 | #else | |
| 36 | using streamoff = long long; // for char_traits in <string> | |
| 37 | #endif | |
| 38 | ||
| 39 | _LIBCPP_END_NAMESPACE_STD | |
| 40 | ||
| 41 | #endif // _LIBCPP___FWD_IOS_H |
lib/libcxx/include/__fwd/istream.h created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_ISTREAM_H | |
| 10 | #define _LIBCPP___FWD_ISTREAM_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_istream; | |
| 23 | ||
| 24 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 25 | class _LIBCPP_TEMPLATE_VIS basic_iostream; | |
| 26 | ||
| 27 | using istream = basic_istream<char>; | |
| 28 | using iostream = basic_iostream<char>; | |
| 29 | ||
| 30 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 31 | using wistream = basic_istream<wchar_t>; | |
| 32 | using wiostream = basic_iostream<wchar_t>; | |
| 33 | #endif | |
| 34 | ||
| 35 | template <class _CharT, class _Traits> | |
| 36 | class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream; | |
| 37 | ||
| 38 | template <class _CharT, class _Traits> | |
| 39 | class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream; | |
| 40 | ||
| 41 | _LIBCPP_END_NAMESPACE_STD | |
| 42 | ||
| 43 | #endif // _LIBCPP___FWD_ISTREAM_H |
lib/libcxx/include/__fwd/mdspan.h created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_LAYOUTS_H | |
| 18 | #define _LIBCPP___MDSPAN_LAYOUTS_H | |
| 19 | ||
| 20 | #include <__config> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | #if _LIBCPP_STD_VER >= 23 | |
| 32 | ||
| 33 | // Layout policy with a mapping which corresponds to FORTRAN-style array layouts | |
| 34 | struct layout_left { | |
| 35 | template <class _Extents> | |
| 36 | class mapping; | |
| 37 | }; | |
| 38 | ||
| 39 | // Layout policy with a mapping which corresponds to C-style array layouts | |
| 40 | struct layout_right { | |
| 41 | template <class _Extents> | |
| 42 | class mapping; | |
| 43 | }; | |
| 44 | ||
| 45 | /* | |
| 46 | // Will be implemented with follow on revision | |
| 47 | // Layout policy with a unique mapping where strides are arbitrary | |
| 48 | struct layout_stride { | |
| 49 | template<class Extents> | |
| 50 | class mapping; | |
| 51 | }; | |
| 52 | */ | |
| 53 | ||
| 54 | #endif // _LIBCPP_STD_VER >= 23 | |
| 55 | ||
| 56 | _LIBCPP_END_NAMESPACE_STD | |
| 57 | ||
| 58 | _LIBCPP_POP_MACROS | |
| 59 | ||
| 60 | #endif // _LIBCPP___MDSPAN_LAYOUTS_H |
lib/libcxx/include/__fwd/memory_resource.h+2-1| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H |
| 10 | 10 | #define _LIBCPP___FWD_MEMORY_RESOURCE_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | |
| 14 | 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -19,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 20 | |
| 20 | 21 | namespace pmr { |
| 21 | 22 | template <class _ValueType> |
| 22 | class _LIBCPP_TEMPLATE_VIS polymorphic_allocator; | |
| 23 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator; | |
| 23 | 24 | } // namespace pmr |
| 24 | 25 | |
| 25 | 26 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__fwd/ostream.h created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_OSTREAM_H | |
| 10 | #define _LIBCPP___FWD_OSTREAM_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_ostream; | |
| 23 | ||
| 24 | using ostream = basic_ostream<char>; | |
| 25 | ||
| 26 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 27 | using wostream = basic_ostream<wchar_t>; | |
| 28 | #endif | |
| 29 | ||
| 30 | template <class _CharT, class _Traits> | |
| 31 | class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream; | |
| 32 | ||
| 33 | _LIBCPP_END_NAMESPACE_STD | |
| 34 | ||
| 35 | #endif // _LIBCPP___FWD_OSTREAM_H |
lib/libcxx/include/__fwd/span.h+1-1| ... | ... | @@ -23,7 +23,7 @@ _LIBCPP_PUSH_MACROS |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); |
| 29 | 29 | template <typename _Tp, size_t _Extent = dynamic_extent> class span; |
lib/libcxx/include/__fwd/sstream.h created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_SSTREAM_H | |
| 10 | #define _LIBCPP___FWD_SSTREAM_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_stringbuf; | |
| 23 | ||
| 24 | template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> > | |
| 25 | class _LIBCPP_TEMPLATE_VIS basic_istringstream; | |
| 26 | template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> > | |
| 27 | class _LIBCPP_TEMPLATE_VIS basic_ostringstream; | |
| 28 | template <class _CharT, class _Traits = char_traits<_CharT>, class _Allocator = allocator<_CharT> > | |
| 29 | class _LIBCPP_TEMPLATE_VIS basic_stringstream; | |
| 30 | ||
| 31 | using stringbuf = basic_stringbuf<char>; | |
| 32 | using istringstream = basic_istringstream<char>; | |
| 33 | using ostringstream = basic_ostringstream<char>; | |
| 34 | using stringstream = basic_stringstream<char>; | |
| 35 | ||
| 36 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 37 | using wstringbuf = basic_stringbuf<wchar_t>; | |
| 38 | using wistringstream = basic_istringstream<wchar_t>; | |
| 39 | using wostringstream = basic_ostringstream<wchar_t>; | |
| 40 | using wstringstream = basic_stringstream<wchar_t>; | |
| 41 | #endif | |
| 42 | ||
| 43 | template <class _CharT, class _Traits, class _Allocator> | |
| 44 | class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf; | |
| 45 | template <class _CharT, class _Traits, class _Allocator> | |
| 46 | class _LIBCPP_PREFERRED_NAME(istringstream) | |
| 47 | _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream; | |
| 48 | template <class _CharT, class _Traits, class _Allocator> | |
| 49 | class _LIBCPP_PREFERRED_NAME(ostringstream) | |
| 50 | _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream; | |
| 51 | template <class _CharT, class _Traits, class _Allocator> | |
| 52 | class _LIBCPP_PREFERRED_NAME(stringstream) | |
| 53 | _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream; | |
| 54 | ||
| 55 | _LIBCPP_END_NAMESPACE_STD | |
| 56 | ||
| 57 | #endif // _LIBCPP___FWD_SSTREAM_H |
lib/libcxx/include/__fwd/streambuf.h created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___FWD_STREAMBUF_H | |
| 10 | #define _LIBCPP___FWD_STREAMBUF_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/string.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 22 | class _LIBCPP_TEMPLATE_VIS basic_streambuf; | |
| 23 | ||
| 24 | using streambuf = basic_streambuf<char>; | |
| 25 | ||
| 26 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 27 | using wstreambuf = basic_streambuf<wchar_t>; | |
| 28 | #endif | |
| 29 | ||
| 30 | template <class _CharT, class _Traits> | |
| 31 | class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf; | |
| 32 | ||
| 33 | _LIBCPP_END_NAMESPACE_STD | |
| 34 | ||
| 35 | #endif // _LIBCPP___FWD_STREAMBUF_H |
lib/libcxx/include/__fwd/string.h+7-7| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef _LIBCPP___FWD_STRING_H |
| 10 | 10 | #define _LIBCPP___FWD_STRING_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | #include <__fwd/memory_resource.h> |
| 14 | 15 | |
| ... | ... | @@ -61,21 +62,20 @@ using u32string = basic_string<char32_t>; |
| 61 | 62 | |
| 62 | 63 | namespace pmr { |
| 63 | 64 | template <class _CharT, class _Traits = char_traits<_CharT>> |
| 64 | using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; | |
| 65 | using basic_string _LIBCPP_AVAILABILITY_PMR = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; | |
| 65 | 66 | |
| 66 | using string = basic_string<char>; | |
| 67 | using string _LIBCPP_AVAILABILITY_PMR = basic_string<char>; | |
| 67 | 68 | |
| 68 | 69 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 69 | using wstring = basic_string<wchar_t>; | |
| 70 | using wstring _LIBCPP_AVAILABILITY_PMR = basic_string<wchar_t>; | |
| 70 | 71 | # endif |
| 71 | 72 | |
| 72 | 73 | # ifndef _LIBCPP_HAS_NO_CHAR8_T |
| 73 | using u8string = basic_string<char8_t>; | |
| 74 | using u8string _LIBCPP_AVAILABILITY_PMR = basic_string<char8_t>; | |
| 74 | 75 | # endif |
| 75 | 76 | |
| 76 | using u16string = basic_string<char16_t>; | |
| 77 | using u32string = basic_string<char32_t>; | |
| 78 | ||
| 77 | using u16string _LIBCPP_AVAILABILITY_PMR = basic_string<char16_t>; | |
| 78 | using u32string _LIBCPP_AVAILABILITY_PMR = basic_string<char32_t>; | |
| 79 | 79 | } // namespace pmr |
| 80 | 80 | |
| 81 | 81 | #endif // _LIBCPP_STD_VER >= 17 |
lib/libcxx/include/__hash_table+112-344| ... | ... | @@ -15,8 +15,8 @@ |
| 15 | 15 | #include <__assert> |
| 16 | 16 | #include <__bit/countl.h> |
| 17 | 17 | #include <__config> |
| 18 | #include <__debug> | |
| 19 | 18 | #include <__functional/hash.h> |
| 19 | #include <__functional/invoke.h> | |
| 20 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | 21 | #include <__memory/addressof.h> |
| 22 | 22 | #include <__memory/allocator_traits.h> |
| ... | ... | @@ -25,6 +25,19 @@ |
| 25 | 25 | #include <__memory/swap_allocator.h> |
| 26 | 26 | #include <__memory/unique_ptr.h> |
| 27 | 27 | #include <__type_traits/can_extract_key.h> |
| 28 | #include <__type_traits/conditional.h> | |
| 29 | #include <__type_traits/is_const.h> | |
| 30 | #include <__type_traits/is_copy_constructible.h> | |
| 31 | #include <__type_traits/is_nothrow_constructible.h> | |
| 32 | #include <__type_traits/is_nothrow_copy_constructible.h> | |
| 33 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 34 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 35 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 36 | #include <__type_traits/is_pointer.h> | |
| 37 | #include <__type_traits/is_reference.h> | |
| 38 | #include <__type_traits/is_swappable.h> | |
| 39 | #include <__type_traits/remove_const.h> | |
| 40 | #include <__type_traits/remove_cvref.h> | |
| 28 | 41 | #include <__utility/forward.h> |
| 29 | 42 | #include <__utility/move.h> |
| 30 | 43 | #include <__utility/pair.h> |
| ... | ... | @@ -32,7 +45,6 @@ |
| 32 | 45 | #include <cmath> |
| 33 | 46 | #include <cstring> |
| 34 | 47 | #include <initializer_list> |
| 35 | #include <type_traits> | |
| 36 | 48 | |
| 37 | 49 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 38 | 50 | # pragma GCC system_header |
| ... | ... | @@ -59,8 +71,7 @@ struct __is_hash_value_type : false_type {}; |
| 59 | 71 | template <class _One> |
| 60 | 72 | struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {}; |
| 61 | 73 | |
| 62 | _LIBCPP_FUNC_VIS | |
| 63 | size_t __next_prime(size_t __n); | |
| 74 | _LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n); | |
| 64 | 75 | |
| 65 | 76 | template <class _NodePtr> |
| 66 | 77 | struct __hash_node_base |
| ... | ... | @@ -296,53 +307,20 @@ public: |
| 296 | 307 | typedef typename _NodeTypes::__node_value_type_pointer pointer; |
| 297 | 308 | |
| 298 | 309 | _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { |
| 299 | _VSTD::__debug_db_insert_i(this); | |
| 300 | 310 | } |
| 301 | 311 | |
| 302 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 303 | _LIBCPP_INLINE_VISIBILITY | |
| 304 | __hash_iterator(const __hash_iterator& __i) | |
| 305 | : __node_(__i.__node_) | |
| 306 | { | |
| 307 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 308 | } | |
| 309 | ||
| 310 | _LIBCPP_INLINE_VISIBILITY | |
| 311 | ~__hash_iterator() | |
| 312 | { | |
| 313 | __get_db()->__erase_i(this); | |
| 314 | } | |
| 315 | ||
| 316 | _LIBCPP_INLINE_VISIBILITY | |
| 317 | __hash_iterator& operator=(const __hash_iterator& __i) | |
| 318 | { | |
| 319 | if (this != _VSTD::addressof(__i)) | |
| 320 | { | |
| 321 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 322 | __node_ = __i.__node_; | |
| 323 | } | |
| 324 | return *this; | |
| 325 | } | |
| 326 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 327 | ||
| 328 | 312 | _LIBCPP_INLINE_VISIBILITY |
| 329 | 313 | reference operator*() const { |
| 330 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 331 | "Attempted to dereference a non-dereferenceable unordered container iterator"); | |
| 332 | 314 | return __node_->__upcast()->__value_; |
| 333 | 315 | } |
| 334 | 316 | |
| 335 | 317 | _LIBCPP_INLINE_VISIBILITY |
| 336 | 318 | pointer operator->() const { |
| 337 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 338 | "Attempted to dereference a non-dereferenceable unordered container iterator"); | |
| 339 | 319 | return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); |
| 340 | 320 | } |
| 341 | 321 | |
| 342 | 322 | _LIBCPP_INLINE_VISIBILITY |
| 343 | 323 | __hash_iterator& operator++() { |
| 344 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 345 | "Attempted to increment a non-incrementable unordered container iterator"); | |
| 346 | 324 | __node_ = __node_->__next_; |
| 347 | 325 | return *this; |
| 348 | 326 | } |
| ... | ... | @@ -366,14 +344,11 @@ public: |
| 366 | 344 | |
| 367 | 345 | private: |
| 368 | 346 | _LIBCPP_INLINE_VISIBILITY |
| 369 | explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT | |
| 347 | explicit __hash_iterator(__next_pointer __node) _NOEXCEPT | |
| 370 | 348 | : __node_(__node) |
| 371 | 349 | { |
| 372 | (void)__c; | |
| 373 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 374 | __get_db()->__insert_ic(this, __c); | |
| 375 | #endif | |
| 376 | 350 | } |
| 351 | ||
| 377 | 352 | template <class, class, class, class> friend class __hash_table; |
| 378 | 353 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; |
| 379 | 354 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; |
| ... | ... | @@ -402,61 +377,25 @@ public: |
| 402 | 377 | |
| 403 | 378 | |
| 404 | 379 | _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { |
| 405 | _VSTD::__debug_db_insert_i(this); | |
| 406 | 380 | } |
| 407 | 381 | |
| 408 | 382 | _LIBCPP_INLINE_VISIBILITY |
| 409 | 383 | __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT |
| 410 | 384 | : __node_(__x.__node_) |
| 411 | 385 | { |
| 412 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 413 | __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); | |
| 414 | #endif | |
| 415 | 386 | } |
| 416 | 387 | |
| 417 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 418 | _LIBCPP_INLINE_VISIBILITY | |
| 419 | __hash_const_iterator(const __hash_const_iterator& __i) | |
| 420 | : __node_(__i.__node_) | |
| 421 | { | |
| 422 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 423 | } | |
| 424 | ||
| 425 | _LIBCPP_INLINE_VISIBILITY | |
| 426 | ~__hash_const_iterator() | |
| 427 | { | |
| 428 | __get_db()->__erase_i(this); | |
| 429 | } | |
| 430 | ||
| 431 | _LIBCPP_INLINE_VISIBILITY | |
| 432 | __hash_const_iterator& operator=(const __hash_const_iterator& __i) | |
| 433 | { | |
| 434 | if (this != _VSTD::addressof(__i)) | |
| 435 | { | |
| 436 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 437 | __node_ = __i.__node_; | |
| 438 | } | |
| 439 | return *this; | |
| 440 | } | |
| 441 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 442 | ||
| 443 | 388 | _LIBCPP_INLINE_VISIBILITY |
| 444 | 389 | reference operator*() const { |
| 445 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 446 | "Attempted to dereference a non-dereferenceable unordered container const_iterator"); | |
| 447 | 390 | return __node_->__upcast()->__value_; |
| 448 | 391 | } |
| 449 | 392 | _LIBCPP_INLINE_VISIBILITY |
| 450 | 393 | pointer operator->() const { |
| 451 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 452 | "Attempted to dereference a non-dereferenceable unordered container const_iterator"); | |
| 453 | 394 | return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); |
| 454 | 395 | } |
| 455 | 396 | |
| 456 | 397 | _LIBCPP_INLINE_VISIBILITY |
| 457 | 398 | __hash_const_iterator& operator++() { |
| 458 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 459 | "Attempted to increment a non-incrementable unordered container const_iterator"); | |
| 460 | 399 | __node_ = __node_->__next_; |
| 461 | 400 | return *this; |
| 462 | 401 | } |
| ... | ... | @@ -480,14 +419,11 @@ public: |
| 480 | 419 | |
| 481 | 420 | private: |
| 482 | 421 | _LIBCPP_INLINE_VISIBILITY |
| 483 | explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT | |
| 422 | explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT | |
| 484 | 423 | : __node_(__node) |
| 485 | 424 | { |
| 486 | (void)__c; | |
| 487 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 488 | __get_db()->__insert_ic(this, __c); | |
| 489 | #endif | |
| 490 | 425 | } |
| 426 | ||
| 491 | 427 | template <class, class, class, class> friend class __hash_table; |
| 492 | 428 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; |
| 493 | 429 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; |
| ... | ... | @@ -513,57 +449,20 @@ public: |
| 513 | 449 | typedef typename _NodeTypes::__node_value_type_pointer pointer; |
| 514 | 450 | |
| 515 | 451 | _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { |
| 516 | _VSTD::__debug_db_insert_i(this); | |
| 517 | } | |
| 518 | ||
| 519 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 520 | _LIBCPP_INLINE_VISIBILITY | |
| 521 | __hash_local_iterator(const __hash_local_iterator& __i) | |
| 522 | : __node_(__i.__node_), | |
| 523 | __bucket_(__i.__bucket_), | |
| 524 | __bucket_count_(__i.__bucket_count_) | |
| 525 | { | |
| 526 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 527 | } | |
| 528 | ||
| 529 | _LIBCPP_INLINE_VISIBILITY | |
| 530 | ~__hash_local_iterator() | |
| 531 | { | |
| 532 | __get_db()->__erase_i(this); | |
| 533 | 452 | } |
| 534 | 453 | |
| 535 | _LIBCPP_INLINE_VISIBILITY | |
| 536 | __hash_local_iterator& operator=(const __hash_local_iterator& __i) | |
| 537 | { | |
| 538 | if (this != _VSTD::addressof(__i)) | |
| 539 | { | |
| 540 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 541 | __node_ = __i.__node_; | |
| 542 | __bucket_ = __i.__bucket_; | |
| 543 | __bucket_count_ = __i.__bucket_count_; | |
| 544 | } | |
| 545 | return *this; | |
| 546 | } | |
| 547 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 548 | ||
| 549 | 454 | _LIBCPP_INLINE_VISIBILITY |
| 550 | 455 | reference operator*() const { |
| 551 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 552 | "Attempted to dereference a non-dereferenceable unordered container local_iterator"); | |
| 553 | 456 | return __node_->__upcast()->__value_; |
| 554 | 457 | } |
| 555 | 458 | |
| 556 | 459 | _LIBCPP_INLINE_VISIBILITY |
| 557 | 460 | pointer operator->() const { |
| 558 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 559 | "Attempted to dereference a non-dereferenceable unordered container local_iterator"); | |
| 560 | 461 | return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); |
| 561 | 462 | } |
| 562 | 463 | |
| 563 | 464 | _LIBCPP_INLINE_VISIBILITY |
| 564 | 465 | __hash_local_iterator& operator++() { |
| 565 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 566 | "Attempted to increment a non-incrementable unordered container local_iterator"); | |
| 567 | 466 | __node_ = __node_->__next_; |
| 568 | 467 | if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) |
| 569 | 468 | __node_ = nullptr; |
| ... | ... | @@ -590,18 +489,15 @@ public: |
| 590 | 489 | private: |
| 591 | 490 | _LIBCPP_INLINE_VISIBILITY |
| 592 | 491 | explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, |
| 593 | size_t __bucket_count, const void* __c) _NOEXCEPT | |
| 492 | size_t __bucket_count) _NOEXCEPT | |
| 594 | 493 | : __node_(__node), |
| 595 | 494 | __bucket_(__bucket), |
| 596 | 495 | __bucket_count_(__bucket_count) |
| 597 | 496 | { |
| 598 | (void)__c; | |
| 599 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 600 | __get_db()->__insert_ic(this, __c); | |
| 601 | #endif | |
| 602 | 497 | if (__node_ != nullptr) |
| 603 | 498 | __node_ = __node_->__next_; |
| 604 | 499 | } |
| 500 | ||
| 605 | 501 | template <class, class, class, class> friend class __hash_table; |
| 606 | 502 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; |
| 607 | 503 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; |
| ... | ... | @@ -635,7 +531,6 @@ public: |
| 635 | 531 | |
| 636 | 532 | |
| 637 | 533 | _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { |
| 638 | _VSTD::__debug_db_insert_i(this); | |
| 639 | 534 | } |
| 640 | 535 | |
| 641 | 536 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -644,59 +539,20 @@ public: |
| 644 | 539 | __bucket_(__x.__bucket_), |
| 645 | 540 | __bucket_count_(__x.__bucket_count_) |
| 646 | 541 | { |
| 647 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 648 | __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); | |
| 649 | #endif | |
| 650 | 542 | } |
| 651 | 543 | |
| 652 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 653 | _LIBCPP_INLINE_VISIBILITY | |
| 654 | __hash_const_local_iterator(const __hash_const_local_iterator& __i) | |
| 655 | : __node_(__i.__node_), | |
| 656 | __bucket_(__i.__bucket_), | |
| 657 | __bucket_count_(__i.__bucket_count_) | |
| 658 | { | |
| 659 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 660 | } | |
| 661 | ||
| 662 | _LIBCPP_INLINE_VISIBILITY | |
| 663 | ~__hash_const_local_iterator() | |
| 664 | { | |
| 665 | __get_db()->__erase_i(this); | |
| 666 | } | |
| 667 | ||
| 668 | _LIBCPP_INLINE_VISIBILITY | |
| 669 | __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) | |
| 670 | { | |
| 671 | if (this != _VSTD::addressof(__i)) | |
| 672 | { | |
| 673 | __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); | |
| 674 | __node_ = __i.__node_; | |
| 675 | __bucket_ = __i.__bucket_; | |
| 676 | __bucket_count_ = __i.__bucket_count_; | |
| 677 | } | |
| 678 | return *this; | |
| 679 | } | |
| 680 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 681 | ||
| 682 | 544 | _LIBCPP_INLINE_VISIBILITY |
| 683 | 545 | reference operator*() const { |
| 684 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 685 | "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); | |
| 686 | 546 | return __node_->__upcast()->__value_; |
| 687 | 547 | } |
| 688 | 548 | |
| 689 | 549 | _LIBCPP_INLINE_VISIBILITY |
| 690 | 550 | pointer operator->() const { |
| 691 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 692 | "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); | |
| 693 | 551 | return pointer_traits<pointer>::pointer_to(__node_->__upcast()->__value_); |
| 694 | 552 | } |
| 695 | 553 | |
| 696 | 554 | _LIBCPP_INLINE_VISIBILITY |
| 697 | 555 | __hash_const_local_iterator& operator++() { |
| 698 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 699 | "Attempted to increment a non-incrementable unordered container const_local_iterator"); | |
| 700 | 556 | __node_ = __node_->__next_; |
| 701 | 557 | if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) |
| 702 | 558 | __node_ = nullptr; |
| ... | ... | @@ -723,18 +579,15 @@ public: |
| 723 | 579 | private: |
| 724 | 580 | _LIBCPP_INLINE_VISIBILITY |
| 725 | 581 | explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, |
| 726 | size_t __bucket_count, const void* __c) _NOEXCEPT | |
| 582 | size_t __bucket_count) _NOEXCEPT | |
| 727 | 583 | : __node_(__node_ptr), |
| 728 | 584 | __bucket_(__bucket), |
| 729 | 585 | __bucket_count_(__bucket_count) |
| 730 | 586 | { |
| 731 | (void)__c; | |
| 732 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 733 | __get_db()->__insert_ic(this, __c); | |
| 734 | #endif | |
| 735 | 587 | if (__node_ != nullptr) |
| 736 | 588 | __node_ = __node_->__next_; |
| 737 | 589 | } |
| 590 | ||
| 738 | 591 | template <class, class, class, class> friend class __hash_table; |
| 739 | 592 | template <class> friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; |
| 740 | 593 | }; |
| ... | ... | @@ -803,8 +656,8 @@ private: |
| 803 | 656 | public: |
| 804 | 657 | bool __value_constructed; |
| 805 | 658 | |
| 806 | __hash_node_destructor(__hash_node_destructor const&) = default; | |
| 807 | __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; | |
| 659 | _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default; | |
| 660 | _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; | |
| 808 | 661 | |
| 809 | 662 | |
| 810 | 663 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -826,7 +679,7 @@ public: |
| 826 | 679 | template <class> friend class __hash_map_node_destructor; |
| 827 | 680 | }; |
| 828 | 681 | |
| 829 | #if _LIBCPP_STD_VER > 14 | |
| 682 | #if _LIBCPP_STD_VER >= 17 | |
| 830 | 683 | template <class _NodeType, class _Alloc> |
| 831 | 684 | struct __generic_container_node_destructor; |
| 832 | 685 | |
| ... | ... | @@ -976,22 +829,22 @@ public: |
| 976 | 829 | is_nothrow_default_constructible<key_equal>::value); |
| 977 | 830 | _LIBCPP_INLINE_VISIBILITY |
| 978 | 831 | __hash_table(const hasher& __hf, const key_equal& __eql); |
| 979 | __hash_table(const hasher& __hf, const key_equal& __eql, | |
| 832 | _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, | |
| 980 | 833 | const allocator_type& __a); |
| 981 | explicit __hash_table(const allocator_type& __a); | |
| 982 | __hash_table(const __hash_table& __u); | |
| 983 | __hash_table(const __hash_table& __u, const allocator_type& __a); | |
| 984 | __hash_table(__hash_table&& __u) | |
| 834 | _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a); | |
| 835 | _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u); | |
| 836 | _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a); | |
| 837 | _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) | |
| 985 | 838 | _NOEXCEPT_( |
| 986 | 839 | is_nothrow_move_constructible<__bucket_list>::value && |
| 987 | 840 | is_nothrow_move_constructible<__first_node>::value && |
| 988 | 841 | is_nothrow_move_constructible<__node_allocator>::value && |
| 989 | 842 | is_nothrow_move_constructible<hasher>::value && |
| 990 | 843 | is_nothrow_move_constructible<key_equal>::value); |
| 991 | __hash_table(__hash_table&& __u, const allocator_type& __a); | |
| 992 | ~__hash_table(); | |
| 844 | _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a); | |
| 845 | _LIBCPP_HIDE_FROM_ABI ~__hash_table(); | |
| 993 | 846 | |
| 994 | __hash_table& operator=(const __hash_table& __u); | |
| 847 | _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u); | |
| 995 | 848 | _LIBCPP_INLINE_VISIBILITY |
| 996 | 849 | __hash_table& operator=(__hash_table&& __u) |
| 997 | 850 | _NOEXCEPT_( |
| ... | ... | @@ -1000,9 +853,9 @@ public: |
| 1000 | 853 | is_nothrow_move_assignable<hasher>::value && |
| 1001 | 854 | is_nothrow_move_assignable<key_equal>::value); |
| 1002 | 855 | template <class _InputIterator> |
| 1003 | void __assign_unique(_InputIterator __first, _InputIterator __last); | |
| 856 | _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last); | |
| 1004 | 857 | template <class _InputIterator> |
| 1005 | void __assign_multi(_InputIterator __first, _InputIterator __last); | |
| 858 | _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); | |
| 1006 | 859 | |
| 1007 | 860 | _LIBCPP_INLINE_VISIBILITY |
| 1008 | 861 | size_type max_size() const _NOEXCEPT |
| ... | ... | @@ -1121,7 +974,7 @@ public: |
| 1121 | 974 | return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); |
| 1122 | 975 | } |
| 1123 | 976 | |
| 1124 | #if _LIBCPP_STD_VER > 14 | |
| 977 | #if _LIBCPP_STD_VER >= 17 | |
| 1125 | 978 | template <class _NodeHandle, class _InsertReturnType> |
| 1126 | 979 | _LIBCPP_INLINE_VISIBILITY |
| 1127 | 980 | _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); |
| ... | ... | @@ -1151,7 +1004,7 @@ public: |
| 1151 | 1004 | _NodeHandle __node_handle_extract(const_iterator __it); |
| 1152 | 1005 | #endif |
| 1153 | 1006 | |
| 1154 | void clear() _NOEXCEPT; | |
| 1007 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; | |
| 1155 | 1008 | _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash<true>(__n); } |
| 1156 | 1009 | _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash<false>(__n); } |
| 1157 | 1010 | _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) |
| ... | ... | @@ -1182,48 +1035,48 @@ public: |
| 1182 | 1035 | _LIBCPP_INLINE_VISIBILITY |
| 1183 | 1036 | size_type bucket(const _Key& __k) const |
| 1184 | 1037 | { |
| 1185 | _LIBCPP_ASSERT(bucket_count() > 0, | |
| 1038 | _LIBCPP_ASSERT_UNCATEGORIZED(bucket_count() > 0, | |
| 1186 | 1039 | "unordered container::bucket(key) called when bucket_count() == 0"); |
| 1187 | 1040 | return std::__constrain_hash(hash_function()(__k), bucket_count()); |
| 1188 | 1041 | } |
| 1189 | 1042 | |
| 1190 | 1043 | template <class _Key> |
| 1191 | iterator find(const _Key& __x); | |
| 1044 | _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x); | |
| 1192 | 1045 | template <class _Key> |
| 1193 | const_iterator find(const _Key& __x) const; | |
| 1046 | _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const; | |
| 1194 | 1047 | |
| 1195 | 1048 | typedef __hash_node_destructor<__node_allocator> _Dp; |
| 1196 | 1049 | typedef unique_ptr<__node, _Dp> __node_holder; |
| 1197 | 1050 | |
| 1198 | iterator erase(const_iterator __p); | |
| 1199 | iterator erase(const_iterator __first, const_iterator __last); | |
| 1051 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); | |
| 1052 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); | |
| 1200 | 1053 | template <class _Key> |
| 1201 | size_type __erase_unique(const _Key& __k); | |
| 1054 | _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); | |
| 1202 | 1055 | template <class _Key> |
| 1203 | size_type __erase_multi(const _Key& __k); | |
| 1204 | __node_holder remove(const_iterator __p) _NOEXCEPT; | |
| 1056 | _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); | |
| 1057 | _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; | |
| 1205 | 1058 | |
| 1206 | 1059 | template <class _Key> |
| 1207 | 1060 | _LIBCPP_INLINE_VISIBILITY |
| 1208 | 1061 | size_type __count_unique(const _Key& __k) const; |
| 1209 | 1062 | template <class _Key> |
| 1210 | size_type __count_multi(const _Key& __k) const; | |
| 1063 | _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; | |
| 1211 | 1064 | |
| 1212 | 1065 | template <class _Key> |
| 1213 | pair<iterator, iterator> | |
| 1066 | _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> | |
| 1214 | 1067 | __equal_range_unique(const _Key& __k); |
| 1215 | 1068 | template <class _Key> |
| 1216 | pair<const_iterator, const_iterator> | |
| 1069 | _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> | |
| 1217 | 1070 | __equal_range_unique(const _Key& __k) const; |
| 1218 | 1071 | |
| 1219 | 1072 | template <class _Key> |
| 1220 | pair<iterator, iterator> | |
| 1073 | _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> | |
| 1221 | 1074 | __equal_range_multi(const _Key& __k); |
| 1222 | 1075 | template <class _Key> |
| 1223 | pair<const_iterator, const_iterator> | |
| 1076 | _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> | |
| 1224 | 1077 | __equal_range_multi(const _Key& __k) const; |
| 1225 | 1078 | |
| 1226 | void swap(__hash_table& __u) | |
| 1079 | _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u) | |
| 1227 | 1080 | #if _LIBCPP_STD_VER <= 11 |
| 1228 | 1081 | _NOEXCEPT_( |
| 1229 | 1082 | __is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value |
| ... | ... | @@ -1239,7 +1092,7 @@ public: |
| 1239 | 1092 | _LIBCPP_INLINE_VISIBILITY |
| 1240 | 1093 | size_type max_bucket_count() const _NOEXCEPT |
| 1241 | 1094 | {return max_size(); } |
| 1242 | size_type bucket_size(size_type __n) const; | |
| 1095 | _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const; | |
| 1243 | 1096 | _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT |
| 1244 | 1097 | { |
| 1245 | 1098 | size_type __bc = bucket_count(); |
| ... | ... | @@ -1247,7 +1100,7 @@ public: |
| 1247 | 1100 | } |
| 1248 | 1101 | _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT |
| 1249 | 1102 | { |
| 1250 | _LIBCPP_ASSERT(__mlf > 0, | |
| 1103 | _LIBCPP_ASSERT_UNCATEGORIZED(__mlf > 0, | |
| 1251 | 1104 | "unordered container::max_load_factor(lf) called with lf <= 0"); |
| 1252 | 1105 | max_load_factor() = _VSTD::max(__mlf, load_factor()); |
| 1253 | 1106 | } |
| ... | ... | @@ -1256,68 +1109,61 @@ public: |
| 1256 | 1109 | local_iterator |
| 1257 | 1110 | begin(size_type __n) |
| 1258 | 1111 | { |
| 1259 | _LIBCPP_ASSERT(__n < bucket_count(), | |
| 1112 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), | |
| 1260 | 1113 | "unordered container::begin(n) called with n >= bucket_count()"); |
| 1261 | return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); | |
| 1114 | return local_iterator(__bucket_list_[__n], __n, bucket_count()); | |
| 1262 | 1115 | } |
| 1263 | 1116 | |
| 1264 | 1117 | _LIBCPP_INLINE_VISIBILITY |
| 1265 | 1118 | local_iterator |
| 1266 | 1119 | end(size_type __n) |
| 1267 | 1120 | { |
| 1268 | _LIBCPP_ASSERT(__n < bucket_count(), | |
| 1121 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), | |
| 1269 | 1122 | "unordered container::end(n) called with n >= bucket_count()"); |
| 1270 | return local_iterator(nullptr, __n, bucket_count(), this); | |
| 1123 | return local_iterator(nullptr, __n, bucket_count()); | |
| 1271 | 1124 | } |
| 1272 | 1125 | |
| 1273 | 1126 | _LIBCPP_INLINE_VISIBILITY |
| 1274 | 1127 | const_local_iterator |
| 1275 | 1128 | cbegin(size_type __n) const |
| 1276 | 1129 | { |
| 1277 | _LIBCPP_ASSERT(__n < bucket_count(), | |
| 1130 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), | |
| 1278 | 1131 | "unordered container::cbegin(n) called with n >= bucket_count()"); |
| 1279 | return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); | |
| 1132 | return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); | |
| 1280 | 1133 | } |
| 1281 | 1134 | |
| 1282 | 1135 | _LIBCPP_INLINE_VISIBILITY |
| 1283 | 1136 | const_local_iterator |
| 1284 | 1137 | cend(size_type __n) const |
| 1285 | 1138 | { |
| 1286 | _LIBCPP_ASSERT(__n < bucket_count(), | |
| 1139 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), | |
| 1287 | 1140 | "unordered container::cend(n) called with n >= bucket_count()"); |
| 1288 | return const_local_iterator(nullptr, __n, bucket_count(), this); | |
| 1141 | return const_local_iterator(nullptr, __n, bucket_count()); | |
| 1289 | 1142 | } |
| 1290 | 1143 | |
| 1291 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1292 | ||
| 1293 | bool __dereferenceable(const const_iterator* __i) const; | |
| 1294 | bool __decrementable(const const_iterator* __i) const; | |
| 1295 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1296 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1297 | ||
| 1298 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 1299 | ||
| 1300 | 1144 | private: |
| 1301 | template <bool _UniqueKeys> void __rehash(size_type __n); | |
| 1302 | template <bool _UniqueKeys> void __do_rehash(size_type __n); | |
| 1145 | template <bool _UniqueKeys> | |
| 1146 | _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n); | |
| 1147 | template <bool _UniqueKeys> | |
| 1148 | _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n); | |
| 1303 | 1149 | |
| 1304 | 1150 | template <class ..._Args> |
| 1305 | __node_holder __construct_node(_Args&& ...__args); | |
| 1151 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args); | |
| 1306 | 1152 | |
| 1307 | 1153 | template <class _First, class ..._Rest> |
| 1308 | __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); | |
| 1154 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); | |
| 1309 | 1155 | |
| 1310 | 1156 | |
| 1311 | 1157 | _LIBCPP_INLINE_VISIBILITY |
| 1312 | 1158 | void __copy_assign_alloc(const __hash_table& __u) |
| 1313 | 1159 | {__copy_assign_alloc(__u, integral_constant<bool, |
| 1314 | 1160 | __node_traits::propagate_on_container_copy_assignment::value>());} |
| 1315 | void __copy_assign_alloc(const __hash_table& __u, true_type); | |
| 1161 | _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type); | |
| 1316 | 1162 | _LIBCPP_INLINE_VISIBILITY |
| 1317 | 1163 | void __copy_assign_alloc(const __hash_table&, false_type) {} |
| 1318 | 1164 | |
| 1319 | void __move_assign(__hash_table& __u, false_type); | |
| 1320 | void __move_assign(__hash_table& __u, true_type) | |
| 1165 | _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type); | |
| 1166 | _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type) | |
| 1321 | 1167 | _NOEXCEPT_( |
| 1322 | 1168 | is_nothrow_move_assignable<__node_allocator>::value && |
| 1323 | 1169 | is_nothrow_move_assignable<hasher>::value && |
| ... | ... | @@ -1343,8 +1189,8 @@ private: |
| 1343 | 1189 | _LIBCPP_INLINE_VISIBILITY |
| 1344 | 1190 | void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} |
| 1345 | 1191 | |
| 1346 | void __deallocate_node(__next_pointer __np) _NOEXCEPT; | |
| 1347 | __next_pointer __detach() _NOEXCEPT; | |
| 1192 | _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT; | |
| 1193 | _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT; | |
| 1348 | 1194 | |
| 1349 | 1195 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; |
| 1350 | 1196 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; |
| ... | ... | @@ -1476,7 +1322,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() |
| 1476 | 1322 | #endif |
| 1477 | 1323 | |
| 1478 | 1324 | __deallocate_node(__p1_.first().__next_); |
| 1479 | std::__debug_db_erase_c(this); | |
| 1480 | 1325 | } |
| 1481 | 1326 | |
| 1482 | 1327 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1518,21 +1363,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) |
| 1518 | 1363 | while (__np != nullptr) |
| 1519 | 1364 | { |
| 1520 | 1365 | __next_pointer __next = __np->__next_; |
| 1521 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1522 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 1523 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) | |
| 1524 | { | |
| 1525 | --__p; | |
| 1526 | iterator* __i = static_cast<iterator*>((*__p)->__i_); | |
| 1527 | if (__i->__node_ == __np) | |
| 1528 | { | |
| 1529 | (*__p)->__c_ = nullptr; | |
| 1530 | if (--__c->end_ != __p) | |
| 1531 | _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 1532 | } | |
| 1533 | } | |
| 1534 | __get_db()->unlock(); | |
| 1535 | #endif | |
| 1536 | 1366 | __node_pointer __real_np = __np->__upcast(); |
| 1537 | 1367 | __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); |
| 1538 | 1368 | __node_traits::deallocate(__na, __real_np, 1); |
| ... | ... | @@ -1579,7 +1409,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( |
| 1579 | 1409 | __u.__p1_.first().__next_ = nullptr; |
| 1580 | 1410 | __u.size() = 0; |
| 1581 | 1411 | } |
| 1582 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1583 | 1412 | } |
| 1584 | 1413 | |
| 1585 | 1414 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1597,10 +1426,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( |
| 1597 | 1426 | if (bucket_count() != 0) |
| 1598 | 1427 | { |
| 1599 | 1428 | __next_pointer __cache = __detach(); |
| 1600 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1429 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1601 | 1430 | try |
| 1602 | 1431 | { |
| 1603 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1432 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1604 | 1433 | const_iterator __i = __u.begin(); |
| 1605 | 1434 | while (__cache != nullptr && __u.size() != 0) |
| 1606 | 1435 | { |
| ... | ... | @@ -1610,14 +1439,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( |
| 1610 | 1439 | __node_insert_multi(__cache->__upcast()); |
| 1611 | 1440 | __cache = __next; |
| 1612 | 1441 | } |
| 1613 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1442 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1614 | 1443 | } |
| 1615 | 1444 | catch (...) |
| 1616 | 1445 | { |
| 1617 | 1446 | __deallocate_node(__cache); |
| 1618 | 1447 | throw; |
| 1619 | 1448 | } |
| 1620 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1449 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1621 | 1450 | __deallocate_node(__cache); |
| 1622 | 1451 | } |
| 1623 | 1452 | const_iterator __i = __u.begin(); |
| ... | ... | @@ -1659,10 +1488,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first |
| 1659 | 1488 | if (bucket_count() != 0) |
| 1660 | 1489 | { |
| 1661 | 1490 | __next_pointer __cache = __detach(); |
| 1662 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1491 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1663 | 1492 | try |
| 1664 | 1493 | { |
| 1665 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1494 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1666 | 1495 | for (; __cache != nullptr && __first != __last; ++__first) |
| 1667 | 1496 | { |
| 1668 | 1497 | __cache->__upcast()->__value_ = *__first; |
| ... | ... | @@ -1670,14 +1499,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first |
| 1670 | 1499 | __node_insert_unique(__cache->__upcast()); |
| 1671 | 1500 | __cache = __next; |
| 1672 | 1501 | } |
| 1673 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1502 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1674 | 1503 | } |
| 1675 | 1504 | catch (...) |
| 1676 | 1505 | { |
| 1677 | 1506 | __deallocate_node(__cache); |
| 1678 | 1507 | throw; |
| 1679 | 1508 | } |
| 1680 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1509 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1681 | 1510 | __deallocate_node(__cache); |
| 1682 | 1511 | } |
| 1683 | 1512 | for (; __first != __last; ++__first) |
| ... | ... | @@ -1699,10 +1528,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, |
| 1699 | 1528 | if (bucket_count() != 0) |
| 1700 | 1529 | { |
| 1701 | 1530 | __next_pointer __cache = __detach(); |
| 1702 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1531 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1703 | 1532 | try |
| 1704 | 1533 | { |
| 1705 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1534 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1706 | 1535 | for (; __cache != nullptr && __first != __last; ++__first) |
| 1707 | 1536 | { |
| 1708 | 1537 | __cache->__upcast()->__value_ = *__first; |
| ... | ... | @@ -1710,14 +1539,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, |
| 1710 | 1539 | __node_insert_multi(__cache->__upcast()); |
| 1711 | 1540 | __cache = __next; |
| 1712 | 1541 | } |
| 1713 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1542 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1714 | 1543 | } |
| 1715 | 1544 | catch (...) |
| 1716 | 1545 | { |
| 1717 | 1546 | __deallocate_node(__cache); |
| 1718 | 1547 | throw; |
| 1719 | 1548 | } |
| 1720 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1549 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1721 | 1550 | __deallocate_node(__cache); |
| 1722 | 1551 | } |
| 1723 | 1552 | for (; __first != __last; ++__first) |
| ... | ... | @@ -1729,7 +1558,7 @@ inline |
| 1729 | 1558 | typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 1730 | 1559 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT |
| 1731 | 1560 | { |
| 1732 | return iterator(__p1_.first().__next_, this); | |
| 1561 | return iterator(__p1_.first().__next_); | |
| 1733 | 1562 | } |
| 1734 | 1563 | |
| 1735 | 1564 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1737,7 +1566,7 @@ inline |
| 1737 | 1566 | typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 1738 | 1567 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT |
| 1739 | 1568 | { |
| 1740 | return iterator(nullptr, this); | |
| 1569 | return iterator(nullptr); | |
| 1741 | 1570 | } |
| 1742 | 1571 | |
| 1743 | 1572 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1745,7 +1574,7 @@ inline |
| 1745 | 1574 | typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator |
| 1746 | 1575 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT |
| 1747 | 1576 | { |
| 1748 | return const_iterator(__p1_.first().__next_, this); | |
| 1577 | return const_iterator(__p1_.first().__next_); | |
| 1749 | 1578 | } |
| 1750 | 1579 | |
| 1751 | 1580 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1753,7 +1582,7 @@ inline |
| 1753 | 1582 | typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator |
| 1754 | 1583 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT |
| 1755 | 1584 | { |
| 1756 | return const_iterator(nullptr, this); | |
| 1585 | return const_iterator(nullptr); | |
| 1757 | 1586 | } |
| 1758 | 1587 | |
| 1759 | 1588 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1794,10 +1623,12 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( |
| 1794 | 1623 | if (__ndptr != nullptr) |
| 1795 | 1624 | { |
| 1796 | 1625 | for (__ndptr = __ndptr->__next_; __ndptr != nullptr && |
| 1797 | std::__constrain_hash(__ndptr->__hash(), __bc) == __chash; | |
| 1626 | (__ndptr->__hash() == __hash || | |
| 1627 | std::__constrain_hash(__ndptr->__hash(), __bc) == __chash); | |
| 1798 | 1628 | __ndptr = __ndptr->__next_) |
| 1799 | 1629 | { |
| 1800 | if (key_eq()(__ndptr->__upcast()->__value_, __value)) | |
| 1630 | if ((__ndptr->__hash() == __hash) && | |
| 1631 | key_eq()(__ndptr->__upcast()->__value_, __value)) | |
| 1801 | 1632 | return __ndptr; |
| 1802 | 1633 | } |
| 1803 | 1634 | } |
| ... | ... | @@ -1858,7 +1689,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ |
| 1858 | 1689 | __existing_node = __nd->__ptr(); |
| 1859 | 1690 | __inserted = true; |
| 1860 | 1691 | } |
| 1861 | return pair<iterator, bool>(iterator(__existing_node, this), __inserted); | |
| 1692 | return pair<iterator, bool>(iterator(__existing_node), __inserted); | |
| 1862 | 1693 | } |
| 1863 | 1694 | |
| 1864 | 1695 | // Prepare the container for an insertion of the value __cp_val with the hash |
| ... | ... | @@ -1952,7 +1783,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __c |
| 1952 | 1783 | __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); |
| 1953 | 1784 | __node_insert_multi_perform(__cp, __pn); |
| 1954 | 1785 | |
| 1955 | return iterator(__cp->__ptr(), this); | |
| 1786 | return iterator(__cp->__ptr()); | |
| 1956 | 1787 | } |
| 1957 | 1788 | |
| 1958 | 1789 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -1960,9 +1791,6 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 1960 | 1791 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( |
| 1961 | 1792 | const_iterator __p, __node_pointer __cp) |
| 1962 | 1793 | { |
| 1963 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1964 | "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" | |
| 1965 | " referring to this unordered container"); | |
| 1966 | 1794 | if (__p != end() && key_eq()(*__p, __cp->__value_)) |
| 1967 | 1795 | { |
| 1968 | 1796 | __next_pointer __np = __p.__node_; |
| ... | ... | @@ -1981,7 +1809,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( |
| 1981 | 1809 | __cp->__next_ = __np; |
| 1982 | 1810 | __pp->__next_ = static_cast<__next_pointer>(__cp); |
| 1983 | 1811 | ++size(); |
| 1984 | return iterator(static_cast<__next_pointer>(__cp), this); | |
| 1812 | return iterator(static_cast<__next_pointer>(__cp)); | |
| 1985 | 1813 | } |
| 1986 | 1814 | return __node_insert_multi(__cp); |
| 1987 | 1815 | } |
| ... | ... | @@ -2009,7 +1837,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& |
| 2009 | 1837 | (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); |
| 2010 | 1838 | __nd = __nd->__next_) |
| 2011 | 1839 | { |
| 2012 | if (key_eq()(__nd->__upcast()->__value_, __k)) | |
| 1840 | if ((__nd->__hash() == __hash) && | |
| 1841 | key_eq()(__nd->__upcast()->__value_, __k)) | |
| 2013 | 1842 | goto __done; |
| 2014 | 1843 | } |
| 2015 | 1844 | } |
| ... | ... | @@ -2047,7 +1876,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& |
| 2047 | 1876 | __inserted = true; |
| 2048 | 1877 | } |
| 2049 | 1878 | __done: |
| 2050 | return pair<iterator, bool>(iterator(__nd, this), __inserted); | |
| 1879 | return pair<iterator, bool>(iterator(__nd), __inserted); | |
| 2051 | 1880 | } |
| 2052 | 1881 | |
| 2053 | 1882 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -2079,16 +1908,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 2079 | 1908 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( |
| 2080 | 1909 | const_iterator __p, _Args&&... __args) |
| 2081 | 1910 | { |
| 2082 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 2083 | "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" | |
| 2084 | " referring to this unordered container"); | |
| 2085 | 1911 | __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); |
| 2086 | 1912 | iterator __r = __node_insert_multi(__p, __h.get()); |
| 2087 | 1913 | __h.release(); |
| 2088 | 1914 | return __r; |
| 2089 | 1915 | } |
| 2090 | 1916 | |
| 2091 | #if _LIBCPP_STD_VER > 14 | |
| 1917 | #if _LIBCPP_STD_VER >= 17 | |
| 2092 | 1918 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| 2093 | 1919 | template <class _NodeHandle, class _InsertReturnType> |
| 2094 | 1920 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -2218,7 +2044,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( |
| 2218 | 2044 | __node_insert_multi_perform(__src_ptr, __pn); |
| 2219 | 2045 | } |
| 2220 | 2046 | } |
| 2221 | #endif // _LIBCPP_STD_VER > 14 | |
| 2047 | #endif // _LIBCPP_STD_VER >= 17 | |
| 2222 | 2048 | |
| 2223 | 2049 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| 2224 | 2050 | template <bool _UniqueKeys> |
| ... | ... | @@ -2251,7 +2077,6 @@ template <bool _UniqueKeys> |
| 2251 | 2077 | void |
| 2252 | 2078 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) |
| 2253 | 2079 | { |
| 2254 | std::__debug_db_invalidate_all(this); | |
| 2255 | 2080 | __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); |
| 2256 | 2081 | __bucket_list_.reset(__nbc > 0 ? |
| 2257 | 2082 | __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); |
| ... | ... | @@ -2323,7 +2148,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) |
| 2323 | 2148 | { |
| 2324 | 2149 | if ((__nd->__hash() == __hash) |
| 2325 | 2150 | && key_eq()(__nd->__upcast()->__value_, __k)) |
| 2326 | return iterator(__nd, this); | |
| 2151 | return iterator(__nd); | |
| 2327 | 2152 | } |
| 2328 | 2153 | } |
| 2329 | 2154 | } |
| ... | ... | @@ -2350,7 +2175,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const |
| 2350 | 2175 | { |
| 2351 | 2176 | if ((__nd->__hash() == __hash) |
| 2352 | 2177 | && key_eq()(__nd->__upcast()->__value_, __k)) |
| 2353 | return const_iterator(__nd, this); | |
| 2178 | return const_iterator(__nd); | |
| 2354 | 2179 | } |
| 2355 | 2180 | } |
| 2356 | 2181 | |
| ... | ... | @@ -2398,12 +2223,9 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 2398 | 2223 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) |
| 2399 | 2224 | { |
| 2400 | 2225 | __next_pointer __np = __p.__node_; |
| 2401 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 2402 | "unordered container erase(iterator) called with an iterator not" | |
| 2403 | " referring to this container"); | |
| 2404 | _LIBCPP_ASSERT(__p != end(), | |
| 2405 | "unordered container erase(iterator) called with a non-dereferenceable iterator"); | |
| 2406 | iterator __r(__np, this); | |
| 2226 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(), | |
| 2227 | "unordered container::erase(iterator) called with a non-dereferenceable iterator"); | |
| 2228 | iterator __r(__np); | |
| 2407 | 2229 | ++__r; |
| 2408 | 2230 | remove(__p); |
| 2409 | 2231 | return __r; |
| ... | ... | @@ -2414,19 +2236,13 @@ typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator |
| 2414 | 2236 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, |
| 2415 | 2237 | const_iterator __last) |
| 2416 | 2238 | { |
| 2417 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, | |
| 2418 | "unordered container::erase(iterator, iterator) called with an iterator not" | |
| 2419 | " referring to this container"); | |
| 2420 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, | |
| 2421 | "unordered container::erase(iterator, iterator) called with an iterator not" | |
| 2422 | " referring to this container"); | |
| 2423 | 2239 | for (const_iterator __p = __first; __first != __last; __p = __first) |
| 2424 | 2240 | { |
| 2425 | 2241 | ++__first; |
| 2426 | 2242 | erase(__p); |
| 2427 | 2243 | } |
| 2428 | 2244 | __next_pointer __np = __last.__node_; |
| 2429 | return iterator (__np, this); | |
| 2245 | return iterator (__np); | |
| 2430 | 2246 | } |
| 2431 | 2247 | |
| 2432 | 2248 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| ... | ... | @@ -2493,21 +2309,6 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT |
| 2493 | 2309 | __pn->__next_ = __cn->__next_; |
| 2494 | 2310 | __cn->__next_ = nullptr; |
| 2495 | 2311 | --size(); |
| 2496 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2497 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 2498 | for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) | |
| 2499 | { | |
| 2500 | --__dp; | |
| 2501 | iterator* __i = static_cast<iterator*>((*__dp)->__i_); | |
| 2502 | if (__i->__node_ == __cn) | |
| 2503 | { | |
| 2504 | (*__dp)->__c_ = nullptr; | |
| 2505 | if (--__c->end_ != __dp) | |
| 2506 | _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); | |
| 2507 | } | |
| 2508 | } | |
| 2509 | __get_db()->unlock(); | |
| 2510 | #endif | |
| 2511 | 2312 | return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); |
| 2512 | 2313 | } |
| 2513 | 2314 | |
| ... | ... | @@ -2622,10 +2423,10 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) |
| 2622 | 2423 | _NOEXCEPT_(__is_nothrow_swappable<hasher>::value && __is_nothrow_swappable<key_equal>::value) |
| 2623 | 2424 | #endif |
| 2624 | 2425 | { |
| 2625 | _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || | |
| 2626 | this->__node_alloc() == __u.__node_alloc(), | |
| 2627 | "list::swap: Either propagate_on_container_swap must be true" | |
| 2628 | " or the allocators must compare equal"); | |
| 2426 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__node_traits::propagate_on_container_swap::value || | |
| 2427 | this->__node_alloc() == __u.__node_alloc(), | |
| 2428 | "unordered container::swap: Either propagate_on_container_swap " | |
| 2429 | "must be true or the allocators must compare equal"); | |
| 2629 | 2430 | { |
| 2630 | 2431 | __node_pointer_pointer __npp = __bucket_list_.release(); |
| 2631 | 2432 | __bucket_list_.reset(__u.__bucket_list_.release()); |
| ... | ... | @@ -2644,14 +2445,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) |
| 2644 | 2445 | if (__u.size() > 0) |
| 2645 | 2446 | __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = |
| 2646 | 2447 | __u.__p1_.first().__ptr(); |
| 2647 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 2648 | 2448 | } |
| 2649 | 2449 | |
| 2650 | 2450 | template <class _Tp, class _Hash, class _Equal, class _Alloc> |
| 2651 | 2451 | typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type |
| 2652 | 2452 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const |
| 2653 | 2453 | { |
| 2654 | _LIBCPP_ASSERT(__n < bucket_count(), | |
| 2454 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < bucket_count(), | |
| 2655 | 2455 | "unordered container::bucket_size(n) called with n >= bucket_count()"); |
| 2656 | 2456 | __next_pointer __np = __bucket_list_[__n]; |
| 2657 | 2457 | size_type __bc = bucket_count(); |
| ... | ... | @@ -2676,38 +2476,6 @@ swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, |
| 2676 | 2476 | __x.swap(__y); |
| 2677 | 2477 | } |
| 2678 | 2478 | |
| 2679 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2680 | ||
| 2681 | template <class _Tp, class _Hash, class _Equal, class _Alloc> | |
| 2682 | bool | |
| 2683 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const | |
| 2684 | { | |
| 2685 | return __i->__node_ != nullptr; | |
| 2686 | } | |
| 2687 | ||
| 2688 | template <class _Tp, class _Hash, class _Equal, class _Alloc> | |
| 2689 | bool | |
| 2690 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const | |
| 2691 | { | |
| 2692 | return false; | |
| 2693 | } | |
| 2694 | ||
| 2695 | template <class _Tp, class _Hash, class _Equal, class _Alloc> | |
| 2696 | bool | |
| 2697 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const | |
| 2698 | { | |
| 2699 | return false; | |
| 2700 | } | |
| 2701 | ||
| 2702 | template <class _Tp, class _Hash, class _Equal, class _Alloc> | |
| 2703 | bool | |
| 2704 | __hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const | |
| 2705 | { | |
| 2706 | return false; | |
| 2707 | } | |
| 2708 | ||
| 2709 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 2710 | ||
| 2711 | 2479 | _LIBCPP_END_NAMESPACE_STD |
| 2712 | 2480 | |
| 2713 | 2481 | _LIBCPP_POP_MACROS |
lib/libcxx/include/__iterator/access.h+1-1| ... | ... | @@ -69,7 +69,7 @@ end(const _Cp& __c) -> decltype(__c.end()) |
| 69 | 69 | return __c.end(); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | #if _LIBCPP_STD_VER > 11 | |
| 72 | #if _LIBCPP_STD_VER >= 14 | |
| 73 | 73 | |
| 74 | 74 | template <class _Cp> |
| 75 | 75 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
lib/libcxx/include/__iterator/advance.h+15-11| ... | ... | @@ -23,13 +23,15 @@ |
| 23 | 23 | #include <__utility/declval.h> |
| 24 | 24 | #include <__utility/move.h> |
| 25 | 25 | #include <__utility/unreachable.h> |
| 26 | #include <cstdlib> | |
| 27 | 26 | #include <limits> |
| 28 | 27 | |
| 29 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 30 | 29 | # pragma GCC system_header |
| 31 | 30 | #endif |
| 32 | 31 | |
| 32 | _LIBCPP_PUSH_MACROS | |
| 33 | #include <__undef_macros> | |
| 34 | ||
| 33 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 36 | |
| 35 | 37 | template <class _InputIter> |
| ... | ... | @@ -64,12 +66,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 64 | 66 | void advance(_InputIter& __i, _Distance __orig_n) { |
| 65 | 67 | typedef typename iterator_traits<_InputIter>::difference_type _Difference; |
| 66 | 68 | _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); |
| 67 | _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, | |
| 68 | "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); | |
| 69 | _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, | |
| 70 | "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); | |
| 69 | 71 | _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); |
| 70 | 72 | } |
| 71 | 73 | |
| 72 | #if _LIBCPP_STD_VER > 17 | |
| 74 | #if _LIBCPP_STD_VER >= 20 | |
| 73 | 75 | |
| 74 | 76 | // [range.iter.op.advance] |
| 75 | 77 | |
| ... | ... | @@ -101,8 +103,8 @@ public: |
| 101 | 103 | template <input_or_output_iterator _Ip> |
| 102 | 104 | _LIBCPP_HIDE_FROM_ABI |
| 103 | 105 | constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { |
| 104 | _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>, | |
| 105 | "If `n < 0`, then `bidirectional_iterator<I>` must be true."); | |
| 106 | _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || bidirectional_iterator<_Ip>, | |
| 107 | "If `n < 0`, then `bidirectional_iterator<I>` must be true."); | |
| 106 | 108 | |
| 107 | 109 | // If `I` models `random_access_iterator`, equivalent to `i += n`. |
| 108 | 110 | if constexpr (random_access_iterator<_Ip>) { |
| ... | ... | @@ -148,8 +150,8 @@ public: |
| 148 | 150 | template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> |
| 149 | 151 | _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, |
| 150 | 152 | _Sp __bound_sentinel) const { |
| 151 | _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), | |
| 152 | "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true."); | |
| 153 | _LIBCPP_ASSERT_UNCATEGORIZED((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), | |
| 154 | "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true."); | |
| 153 | 155 | // If `S` and `I` model `sized_sentinel_for<S, I>`: |
| 154 | 156 | if constexpr (sized_sentinel_for<_Sp, _Ip>) { |
| 155 | 157 | // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. |
| ... | ... | @@ -159,9 +161,9 @@ public: |
| 159 | 161 | __a > 0 ? __a >= __b : |
| 160 | 162 | __a <= __b; |
| 161 | 163 | }; |
| 162 | if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) { | |
| 164 | if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) { | |
| 163 | 165 | (*this)(__i, __bound_sentinel); |
| 164 | return __n - __M; | |
| 166 | return __n - __m; | |
| 165 | 167 | } |
| 166 | 168 | |
| 167 | 169 | // Otherwise, equivalent to `ranges::advance(i, n)`. |
| ... | ... | @@ -196,8 +198,10 @@ inline namespace __cpo { |
| 196 | 198 | } // namespace __cpo |
| 197 | 199 | } // namespace ranges |
| 198 | 200 | |
| 199 | #endif // _LIBCPP_STD_VER > 17 | |
| 201 | #endif // _LIBCPP_STD_VER >= 20 | |
| 200 | 202 | |
| 201 | 203 | _LIBCPP_END_NAMESPACE_STD |
| 202 | 204 | |
| 205 | _LIBCPP_POP_MACROS | |
| 206 | ||
| 203 | 207 | #endif // _LIBCPP___ITERATOR_ADVANCE_H |
lib/libcxx/include/__iterator/back_insert_iterator.h+6-1| ... | ... | @@ -21,6 +21,9 @@ |
| 21 | 21 | # pragma GCC system_header |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | _LIBCPP_PUSH_MACROS | |
| 25 | #include <__undef_macros> | |
| 26 | ||
| 24 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 28 | |
| 26 | 29 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| ... | ... | @@ -36,7 +39,7 @@ protected: |
| 36 | 39 | public: |
| 37 | 40 | typedef output_iterator_tag iterator_category; |
| 38 | 41 | typedef void value_type; |
| 39 | #if _LIBCPP_STD_VER > 17 | |
| 42 | #if _LIBCPP_STD_VER >= 20 | |
| 40 | 43 | typedef ptrdiff_t difference_type; |
| 41 | 44 | #else |
| 42 | 45 | typedef void difference_type; |
| ... | ... | @@ -70,4 +73,6 @@ back_inserter(_Container& __x) |
| 70 | 73 | |
| 71 | 74 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 75 | |
| 76 | _LIBCPP_POP_MACROS | |
| 77 | ||
| 73 | 78 | #endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H |
lib/libcxx/include/__iterator/bounded_iter.h+12-7| ... | ... | @@ -23,6 +23,9 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 26 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 30 | |
| 28 | 31 | // Iterator wrapper that carries the valid range it is allowed to access. |
| ... | ... | @@ -35,14 +38,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 38 | // Arithmetic operations are allowed and the bounds of the resulting iterator |
| 36 | 39 | // are not checked. Hence, it is possible to create an iterator pointing outside |
| 37 | 40 | // its range, but it is not possible to dereference it. |
| 38 | template <class _Iterator, class = __enable_if_t< __is_cpp17_contiguous_iterator<_Iterator>::value > > | |
| 41 | template <class _Iterator, class = __enable_if_t< __libcpp_is_contiguous_iterator<_Iterator>::value > > | |
| 39 | 42 | struct __bounded_iter { |
| 40 | 43 | using value_type = typename iterator_traits<_Iterator>::value_type; |
| 41 | 44 | using difference_type = typename iterator_traits<_Iterator>::difference_type; |
| 42 | 45 | using pointer = typename iterator_traits<_Iterator>::pointer; |
| 43 | 46 | using reference = typename iterator_traits<_Iterator>::reference; |
| 44 | 47 | using iterator_category = typename iterator_traits<_Iterator>::iterator_category; |
| 45 | #if _LIBCPP_STD_VER > 17 | |
| 48 | #if _LIBCPP_STD_VER >= 20 | |
| 46 | 49 | using iterator_concept = contiguous_iterator_tag; |
| 47 | 50 | #endif |
| 48 | 51 | |
| ... | ... | @@ -78,7 +81,7 @@ private: |
| 78 | 81 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter( |
| 79 | 82 | _Iterator __current, _Iterator __begin, _Iterator __end) |
| 80 | 83 | : __current_(__current), __begin_(__begin), __end_(__end) { |
| 81 | _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); | |
| 84 | _LIBCPP_ASSERT_INTERNAL(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); | |
| 82 | 85 | } |
| 83 | 86 | |
| 84 | 87 | template <class _It> |
| ... | ... | @@ -89,19 +92,19 @@ public: |
| 89 | 92 | // |
| 90 | 93 | // These operations check that the iterator is dereferenceable, that is within [begin, end). |
| 91 | 94 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { |
| 92 | _LIBCPP_ASSERT( | |
| 95 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 93 | 96 | __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); |
| 94 | 97 | return *__current_; |
| 95 | 98 | } |
| 96 | 99 | |
| 97 | 100 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { |
| 98 | _LIBCPP_ASSERT( | |
| 101 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 99 | 102 | __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); |
| 100 | 103 | return std::__to_address(__current_); |
| 101 | 104 | } |
| 102 | 105 | |
| 103 | 106 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { |
| 104 | _LIBCPP_ASSERT( | |
| 107 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 105 | 108 | __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); |
| 106 | 109 | return __current_[__n]; |
| 107 | 110 | } |
| ... | ... | @@ -212,7 +215,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter( |
| 212 | 215 | |
| 213 | 216 | #if _LIBCPP_STD_VER <= 17 |
| 214 | 217 | template <class _Iterator> |
| 215 | struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; | |
| 218 | struct __libcpp_is_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; | |
| 216 | 219 | #endif |
| 217 | 220 | |
| 218 | 221 | template <class _Iterator> |
| ... | ... | @@ -228,4 +231,6 @@ struct pointer_traits<__bounded_iter<_Iterator> > { |
| 228 | 231 | |
| 229 | 232 | _LIBCPP_END_NAMESPACE_STD |
| 230 | 233 | |
| 234 | _LIBCPP_POP_MACROS | |
| 235 | ||
| 231 | 236 | #endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H |
lib/libcxx/include/__iterator/common_iterator.h+52-30| ... | ... | @@ -25,6 +25,7 @@ |
| 25 | 25 | #include <__iterator/iter_swap.h> |
| 26 | 26 | #include <__iterator/iterator_traits.h> |
| 27 | 27 | #include <__iterator/readable_traits.h> |
| 28 | #include <__memory/addressof.h> | |
| 28 | 29 | #include <__type_traits/is_pointer.h> |
| 29 | 30 | #include <__utility/declval.h> |
| 30 | 31 | #include <variant> |
| ... | ... | @@ -33,9 +34,12 @@ |
| 33 | 34 | # pragma GCC system_header |
| 34 | 35 | #endif |
| 35 | 36 | |
| 37 | _LIBCPP_PUSH_MACROS | |
| 38 | #include <__undef_macros> | |
| 39 | ||
| 36 | 40 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 37 | 41 | |
| 38 | #if _LIBCPP_STD_VER > 17 | |
| 42 | #if _LIBCPP_STD_VER >= 20 | |
| 39 | 43 | |
| 40 | 44 | template<class _Iter> |
| 41 | 45 | concept __can_use_postfix_proxy = |
| ... | ... | @@ -46,14 +50,14 @@ template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> |
| 46 | 50 | requires (!same_as<_Iter, _Sent> && copyable<_Iter>) |
| 47 | 51 | class common_iterator { |
| 48 | 52 | struct __proxy { |
| 49 | constexpr const iter_value_t<_Iter>* operator->() const noexcept { | |
| 53 | _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept { | |
| 50 | 54 | return _VSTD::addressof(__value_); |
| 51 | 55 | } |
| 52 | 56 | iter_value_t<_Iter> __value_; |
| 53 | 57 | }; |
| 54 | 58 | |
| 55 | 59 | struct __postfix_proxy { |
| 56 | constexpr const iter_value_t<_Iter>& operator*() const noexcept { | |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { | |
| 57 | 61 | return __value_; |
| 58 | 62 | } |
| 59 | 63 | iter_value_t<_Iter> __value_; |
| ... | ... | @@ -62,16 +66,17 @@ class common_iterator { |
| 62 | 66 | public: |
| 63 | 67 | variant<_Iter, _Sent> __hold_; |
| 64 | 68 | |
| 65 | common_iterator() requires default_initializable<_Iter> = default; | |
| 69 | _LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default; | |
| 66 | 70 | |
| 67 | constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {} | |
| 68 | constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {} | |
| 71 | _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {} | |
| 72 | _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {} | |
| 69 | 73 | |
| 70 | 74 | template<class _I2, class _S2> |
| 71 | 75 | requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> |
| 72 | constexpr common_iterator(const common_iterator<_I2, _S2>& __other) | |
| 76 | _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other) | |
| 73 | 77 | : __hold_([&]() -> variant<_Iter, _Sent> { |
| 74 | _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); | |
| 78 | _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(), | |
| 79 | "Attempted to construct from a valueless common_iterator"); | |
| 75 | 80 | if (__other.__hold_.index() == 0) |
| 76 | 81 | return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; |
| 77 | 82 | return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; |
| ... | ... | @@ -80,8 +85,9 @@ public: |
| 80 | 85 | template<class _I2, class _S2> |
| 81 | 86 | requires convertible_to<const _I2&, _Iter> && convertible_to<const _S2&, _Sent> && |
| 82 | 87 | assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> |
| 83 | common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { | |
| 84 | _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); | |
| 88 | _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { | |
| 89 | _LIBCPP_ASSERT_UNCATEGORIZED(!__other.__hold_.valueless_by_exception(), | |
| 90 | "Attempted to assign from a valueless common_iterator"); | |
| 85 | 91 | |
| 86 | 92 | auto __idx = __hold_.index(); |
| 87 | 93 | auto __other_idx = __other.__hold_.index(); |
| ... | ... | @@ -101,27 +107,30 @@ public: |
| 101 | 107 | return *this; |
| 102 | 108 | } |
| 103 | 109 | |
| 104 | constexpr decltype(auto) operator*() | |
| 110 | _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() | |
| 105 | 111 | { |
| 106 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 112 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), | |
| 113 | "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 107 | 114 | return *_VSTD::__unchecked_get<_Iter>(__hold_); |
| 108 | 115 | } |
| 109 | 116 | |
| 110 | constexpr decltype(auto) operator*() const | |
| 117 | _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const | |
| 111 | 118 | requires __dereferenceable<const _Iter> |
| 112 | 119 | { |
| 113 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 120 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), | |
| 121 | "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 114 | 122 | return *_VSTD::__unchecked_get<_Iter>(__hold_); |
| 115 | 123 | } |
| 116 | 124 | |
| 117 | 125 | template<class _I2 = _Iter> |
| 118 | decltype(auto) operator->() const | |
| 126 | _LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const | |
| 119 | 127 | requires indirectly_readable<const _I2> && |
| 120 | 128 | (requires(const _I2& __i) { __i.operator->(); } || |
| 121 | 129 | is_reference_v<iter_reference_t<_I2>> || |
| 122 | 130 | constructible_from<iter_value_t<_I2>, iter_reference_t<_I2>>) |
| 123 | 131 | { |
| 124 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 132 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), | |
| 133 | "Attempted to dereference a non-dereferenceable common_iterator"); | |
| 125 | 134 | if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { |
| 126 | 135 | return _VSTD::__unchecked_get<_Iter>(__hold_); |
| 127 | 136 | } else if constexpr (is_reference_v<iter_reference_t<_Iter>>) { |
| ... | ... | @@ -132,13 +141,15 @@ public: |
| 132 | 141 | } |
| 133 | 142 | } |
| 134 | 143 | |
| 135 | common_iterator& operator++() { | |
| 136 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); | |
| 144 | _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() { | |
| 145 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), | |
| 146 | "Attempted to increment a non-dereferenceable common_iterator"); | |
| 137 | 147 | ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; |
| 138 | 148 | } |
| 139 | 149 | |
| 140 | decltype(auto) operator++(int) { | |
| 141 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); | |
| 150 | _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) { | |
| 151 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__hold_), | |
| 152 | "Attempted to increment a non-dereferenceable common_iterator"); | |
| 142 | 153 | if constexpr (forward_iterator<_Iter>) { |
| 143 | 154 | auto __tmp = *this; |
| 144 | 155 | ++*this; |
| ... | ... | @@ -157,8 +168,10 @@ public: |
| 157 | 168 | requires sentinel_for<_Sent, _I2> |
| 158 | 169 | _LIBCPP_HIDE_FROM_ABI |
| 159 | 170 | friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { |
| 160 | _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); | |
| 161 | _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); | |
| 171 | _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), | |
| 172 | "Attempted to compare a valueless common_iterator"); | |
| 173 | _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), | |
| 174 | "Attempted to compare a valueless common_iterator"); | |
| 162 | 175 | |
| 163 | 176 | auto __x_index = __x.__hold_.index(); |
| 164 | 177 | auto __y_index = __y.__hold_.index(); |
| ... | ... | @@ -176,8 +189,10 @@ public: |
| 176 | 189 | requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> |
| 177 | 190 | _LIBCPP_HIDE_FROM_ABI |
| 178 | 191 | friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { |
| 179 | _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); | |
| 180 | _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); | |
| 192 | _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), | |
| 193 | "Attempted to compare a valueless common_iterator"); | |
| 194 | _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), | |
| 195 | "Attempted to compare a valueless common_iterator"); | |
| 181 | 196 | |
| 182 | 197 | auto __x_index = __x.__hold_.index(); |
| 183 | 198 | auto __y_index = __y.__hold_.index(); |
| ... | ... | @@ -198,8 +213,10 @@ public: |
| 198 | 213 | requires sized_sentinel_for<_Sent, _I2> |
| 199 | 214 | _LIBCPP_HIDE_FROM_ABI |
| 200 | 215 | friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { |
| 201 | _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); | |
| 202 | _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); | |
| 216 | _LIBCPP_ASSERT_UNCATEGORIZED(!__x.__hold_.valueless_by_exception(), | |
| 217 | "Attempted to subtract from a valueless common_iterator"); | |
| 218 | _LIBCPP_ASSERT_UNCATEGORIZED(!__y.__hold_.valueless_by_exception(), | |
| 219 | "Attempted to subtract a valueless common_iterator"); | |
| 203 | 220 | |
| 204 | 221 | auto __x_index = __x.__hold_.index(); |
| 205 | 222 | auto __y_index = __y.__hold_.index(); |
| ... | ... | @@ -220,7 +237,8 @@ public: |
| 220 | 237 | noexcept(noexcept(ranges::iter_move(std::declval<const _Iter&>()))) |
| 221 | 238 | requires input_iterator<_Iter> |
| 222 | 239 | { |
| 223 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); | |
| 240 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__i.__hold_), | |
| 241 | "Attempted to iter_move a non-dereferenceable common_iterator"); | |
| 224 | 242 | return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); |
| 225 | 243 | } |
| 226 | 244 | |
| ... | ... | @@ -228,8 +246,10 @@ public: |
| 228 | 246 | _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) |
| 229 | 247 | noexcept(noexcept(ranges::iter_swap(std::declval<const _Iter&>(), std::declval<const _I2&>()))) |
| 230 | 248 | { |
| 231 | _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); | |
| 232 | _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); | |
| 249 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_Iter>(__x.__hold_), | |
| 250 | "Attempted to iter_swap a non-dereferenceable common_iterator"); | |
| 251 | _LIBCPP_ASSERT_UNCATEGORIZED(std::holds_alternative<_I2>(__y.__hold_), | |
| 252 | "Attempted to iter_swap a non-dereferenceable common_iterator"); | |
| 233 | 253 | return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); |
| 234 | 254 | } |
| 235 | 255 | }; |
| ... | ... | @@ -274,8 +294,10 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> { |
| 274 | 294 | using reference = iter_reference_t<_Iter>; |
| 275 | 295 | }; |
| 276 | 296 | |
| 277 | #endif // _LIBCPP_STD_VER > 17 | |
| 297 | #endif // _LIBCPP_STD_VER >= 20 | |
| 278 | 298 | |
| 279 | 299 | _LIBCPP_END_NAMESPACE_STD |
| 280 | 300 | |
| 301 | _LIBCPP_POP_MACROS | |
| 302 | ||
| 281 | 303 | #endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H |
lib/libcxx/include/__iterator/concepts.h+2-2| ... | ... | @@ -46,7 +46,7 @@ |
| 46 | 46 | |
| 47 | 47 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 48 | 48 | |
| 49 | #if _LIBCPP_STD_VER > 17 | |
| 49 | #if _LIBCPP_STD_VER >= 20 | |
| 50 | 50 | |
| 51 | 51 | // [iterator.concept.readable] |
| 52 | 52 | template<class _In> |
| ... | ... | @@ -293,7 +293,7 @@ concept indirectly_copyable_storable = |
| 293 | 293 | // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle |
| 294 | 294 | // (both iter_swap and indirectly_swappable require indirectly_readable). |
| 295 | 295 | |
| 296 | #endif // _LIBCPP_STD_VER > 17 | |
| 296 | #endif // _LIBCPP_STD_VER >= 20 | |
| 297 | 297 | |
| 298 | 298 | _LIBCPP_END_NAMESPACE_STD |
| 299 | 299 |
lib/libcxx/include/__iterator/counted_iterator.h+24-18| ... | ... | @@ -34,9 +34,12 @@ |
| 34 | 34 | # pragma GCC system_header |
| 35 | 35 | #endif |
| 36 | 36 | |
| 37 | _LIBCPP_PUSH_MACROS | |
| 38 | #include <__undef_macros> | |
| 39 | ||
| 37 | 40 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 38 | 41 | |
| 39 | #if _LIBCPP_STD_VER > 17 | |
| 42 | #if _LIBCPP_STD_VER >= 20 | |
| 40 | 43 | |
| 41 | 44 | template<class> |
| 42 | 45 | struct __counted_iterator_concept {}; |
| ... | ... | @@ -83,7 +86,7 @@ public: |
| 83 | 86 | _LIBCPP_HIDE_FROM_ABI |
| 84 | 87 | constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) |
| 85 | 88 | : __current_(_VSTD::move(__iter)), __count_(__n) { |
| 86 | _LIBCPP_ASSERT(__n >= 0, "__n must not be negative."); | |
| 89 | _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "__n must not be negative."); | |
| 87 | 90 | } |
| 88 | 91 | |
| 89 | 92 | template<class _I2> |
| ... | ... | @@ -112,7 +115,7 @@ public: |
| 112 | 115 | |
| 113 | 116 | _LIBCPP_HIDE_FROM_ABI |
| 114 | 117 | constexpr decltype(auto) operator*() { |
| 115 | _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); | |
| 118 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end."); | |
| 116 | 119 | return *__current_; |
| 117 | 120 | } |
| 118 | 121 | |
| ... | ... | @@ -120,7 +123,7 @@ public: |
| 120 | 123 | constexpr decltype(auto) operator*() const |
| 121 | 124 | requires __dereferenceable<const _Iter> |
| 122 | 125 | { |
| 123 | _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); | |
| 126 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator is equal to or past end."); | |
| 124 | 127 | return *__current_; |
| 125 | 128 | } |
| 126 | 129 | |
| ... | ... | @@ -133,7 +136,7 @@ public: |
| 133 | 136 | |
| 134 | 137 | _LIBCPP_HIDE_FROM_ABI |
| 135 | 138 | constexpr counted_iterator& operator++() { |
| 136 | _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); | |
| 139 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); | |
| 137 | 140 | ++__current_; |
| 138 | 141 | --__count_; |
| 139 | 142 | return *this; |
| ... | ... | @@ -141,21 +144,21 @@ public: |
| 141 | 144 | |
| 142 | 145 | _LIBCPP_HIDE_FROM_ABI |
| 143 | 146 | decltype(auto) operator++(int) { |
| 144 | _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); | |
| 147 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); | |
| 145 | 148 | --__count_; |
| 146 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 149 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 147 | 150 | try { return __current_++; } |
| 148 | 151 | catch(...) { ++__count_; throw; } |
| 149 | 152 | #else |
| 150 | 153 | return __current_++; |
| 151 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 154 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 152 | 155 | } |
| 153 | 156 | |
| 154 | 157 | _LIBCPP_HIDE_FROM_ABI |
| 155 | 158 | constexpr counted_iterator operator++(int) |
| 156 | 159 | requires forward_iterator<_Iter> |
| 157 | 160 | { |
| 158 | _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); | |
| 161 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); | |
| 159 | 162 | counted_iterator __tmp = *this; |
| 160 | 163 | ++*this; |
| 161 | 164 | return __tmp; |
| ... | ... | @@ -198,7 +201,7 @@ public: |
| 198 | 201 | constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) |
| 199 | 202 | requires random_access_iterator<_Iter> |
| 200 | 203 | { |
| 201 | _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end."); | |
| 204 | _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __count_, "Cannot advance iterator past end."); | |
| 202 | 205 | __current_ += __n; |
| 203 | 206 | __count_ -= __n; |
| 204 | 207 | return *this; |
| ... | ... | @@ -237,9 +240,10 @@ public: |
| 237 | 240 | constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) |
| 238 | 241 | requires random_access_iterator<_Iter> |
| 239 | 242 | { |
| 240 | _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: " | |
| 241 | "counted_iterator would be decremented before the " | |
| 242 | "first element of its range."); | |
| 243 | _LIBCPP_ASSERT_UNCATEGORIZED(-__n <= __count_, | |
| 244 | "Attempt to subtract too large of a size: " | |
| 245 | "counted_iterator would be decremented before the " | |
| 246 | "first element of its range."); | |
| 243 | 247 | __current_ -= __n; |
| 244 | 248 | __count_ += __n; |
| 245 | 249 | return *this; |
| ... | ... | @@ -249,7 +253,7 @@ public: |
| 249 | 253 | constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const |
| 250 | 254 | requires random_access_iterator<_Iter> |
| 251 | 255 | { |
| 252 | _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size."); | |
| 256 | _LIBCPP_ASSERT_UNCATEGORIZED(__n < __count_, "Subscript argument must be less than size."); | |
| 253 | 257 | return __current_[__n]; |
| 254 | 258 | } |
| 255 | 259 | |
| ... | ... | @@ -280,7 +284,7 @@ public: |
| 280 | 284 | noexcept(noexcept(ranges::iter_move(__i.__current_))) |
| 281 | 285 | requires input_iterator<_Iter> |
| 282 | 286 | { |
| 283 | _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range."); | |
| 287 | _LIBCPP_ASSERT_UNCATEGORIZED(__i.__count_ > 0, "Iterator must not be past end of range."); | |
| 284 | 288 | return ranges::iter_move(__i.__current_); |
| 285 | 289 | } |
| 286 | 290 | |
| ... | ... | @@ -289,8 +293,8 @@ public: |
| 289 | 293 | friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y) |
| 290 | 294 | noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) |
| 291 | 295 | { |
| 292 | _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0, | |
| 293 | "Iterators must not be past end of range."); | |
| 296 | _LIBCPP_ASSERT_UNCATEGORIZED(__x.__count_ > 0 && __y.__count_ > 0, | |
| 297 | "Iterators must not be past end of range."); | |
| 294 | 298 | return ranges::iter_swap(__x.__current_, __y.__current_); |
| 295 | 299 | } |
| 296 | 300 | }; |
| ... | ... | @@ -303,8 +307,10 @@ struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> { |
| 303 | 307 | add_pointer_t<iter_reference_t<_Iter>>, void>; |
| 304 | 308 | }; |
| 305 | 309 | |
| 306 | #endif // _LIBCPP_STD_VER > 17 | |
| 310 | #endif // _LIBCPP_STD_VER >= 20 | |
| 307 | 311 | |
| 308 | 312 | _LIBCPP_END_NAMESPACE_STD |
| 309 | 313 | |
| 314 | _LIBCPP_POP_MACROS | |
| 315 | ||
| 310 | 316 | #endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H |
lib/libcxx/include/__iterator/cpp17_iterator_concepts.h created+185| ... | ... | @@ -0,0 +1,185 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H | |
| 10 | #define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H | |
| 11 | ||
| 12 | #include <__concepts/boolean_testable.h> | |
| 13 | #include <__concepts/convertible_to.h> | |
| 14 | #include <__concepts/same_as.h> | |
| 15 | #include <__config> | |
| 16 | #include <__iterator/iterator_traits.h> | |
| 17 | #include <__type_traits/is_convertible.h> | |
| 18 | #include <__type_traits/is_copy_constructible.h> | |
| 19 | #include <__type_traits/is_default_constructible.h> | |
| 20 | #include <__type_traits/is_move_constructible.h> | |
| 21 | #include <__type_traits/is_signed.h> | |
| 22 | #include <__type_traits/is_void.h> | |
| 23 | #include <__utility/as_const.h> | |
| 24 | #include <__utility/forward.h> | |
| 25 | #include <__utility/move.h> | |
| 26 | #include <__utility/swap.h> | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 29 | # pragma GCC system_header | |
| 30 | #endif | |
| 31 | ||
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | ||
| 34 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 35 | ||
| 36 | template <class _Tp> | |
| 37 | concept __cpp17_move_constructible = is_move_constructible_v<_Tp>; | |
| 38 | ||
| 39 | template <class _Tp> | |
| 40 | concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>; | |
| 41 | ||
| 42 | template <class _Tp> | |
| 43 | concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) { | |
| 44 | { __lhs = std::move(__rhs) } -> same_as<_Tp&>; | |
| 45 | }; | |
| 46 | ||
| 47 | template <class _Tp> | |
| 48 | concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) { | |
| 49 | { __lhs = __rhs } -> same_as<_Tp&>; | |
| 50 | { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>; | |
| 51 | }; | |
| 52 | ||
| 53 | template <class _Tp> | |
| 54 | concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); }; | |
| 55 | ||
| 56 | template <class _Tp> | |
| 57 | concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) { | |
| 58 | { __lhs == __rhs } -> __boolean_testable; | |
| 59 | { std::as_const(__lhs) == __rhs } -> __boolean_testable; | |
| 60 | { __lhs == std::as_const(__rhs) } -> __boolean_testable; | |
| 61 | { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable; | |
| 62 | }; | |
| 63 | ||
| 64 | template <class _Tp> | |
| 65 | concept __cpp17_default_constructible = is_default_constructible_v<_Tp>; | |
| 66 | ||
| 67 | template <class _Iter> | |
| 68 | concept __cpp17_iterator = | |
| 69 | __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> && | |
| 70 | (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>)&&requires(_Iter __iter) { | |
| 71 | { *__iter }; | |
| 72 | { ++__iter } -> same_as<_Iter&>; | |
| 73 | }; | |
| 74 | ||
| 75 | template <class _Iter> | |
| 76 | concept __cpp17_input_iterator = | |
| 77 | __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) { | |
| 78 | { __lhs != __rhs } -> __boolean_testable; | |
| 79 | { std::as_const(__lhs) != __rhs } -> __boolean_testable; | |
| 80 | { __lhs != std::as_const(__rhs) } -> __boolean_testable; | |
| 81 | { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable; | |
| 82 | ||
| 83 | { *__lhs } -> same_as<__iter_reference<_Iter>>; | |
| 84 | { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>; | |
| 85 | ||
| 86 | { ++__lhs } -> same_as<_Iter&>; | |
| 87 | { (void)__lhs++ }; | |
| 88 | { *__lhs++ }; | |
| 89 | }; | |
| 90 | ||
| 91 | template <class _Iter, class _WriteTo> | |
| 92 | concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) { | |
| 93 | { *__iter = std::forward<_WriteTo>(__write) }; | |
| 94 | { ++__iter } -> same_as<_Iter&>; | |
| 95 | { __iter++ } -> convertible_to<const _Iter&>; | |
| 96 | { *__iter++ = std::forward<_WriteTo>(__write) }; | |
| 97 | }; | |
| 98 | ||
| 99 | template <class _Iter> | |
| 100 | concept __cpp17_forward_iterator = | |
| 101 | __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) { | |
| 102 | { __iter++ } -> convertible_to<const _Iter&>; | |
| 103 | { *__iter++ } -> same_as<__iter_reference<_Iter>>; | |
| 104 | }; | |
| 105 | ||
| 106 | template <class _Iter> | |
| 107 | concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) { | |
| 108 | { --__iter } -> same_as<_Iter&>; | |
| 109 | { __iter-- } -> convertible_to<const _Iter&>; | |
| 110 | { *__iter-- } -> same_as<__iter_reference<_Iter>>; | |
| 111 | }; | |
| 112 | ||
| 113 | template <class _Iter> | |
| 114 | concept __cpp17_random_access_iterator = | |
| 115 | __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) { | |
| 116 | { __iter += __n } -> same_as<_Iter&>; | |
| 117 | ||
| 118 | { __iter + __n } -> same_as<_Iter>; | |
| 119 | { __n + __iter } -> same_as<_Iter>; | |
| 120 | { std::as_const(__iter) + __n } -> same_as<_Iter>; | |
| 121 | { __n + std::as_const(__iter) } -> same_as<_Iter>; | |
| 122 | ||
| 123 | { __iter -= __n } -> same_as<_Iter&>; | |
| 124 | { __iter - __n } -> same_as<_Iter>; | |
| 125 | { std::as_const(__iter) - __n } -> same_as<_Iter>; | |
| 126 | ||
| 127 | { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>; | |
| 128 | { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>; | |
| 129 | { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>; | |
| 130 | { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>; | |
| 131 | ||
| 132 | { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>; | |
| 133 | { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>; | |
| 134 | ||
| 135 | { __iter < __iter } -> __boolean_testable; | |
| 136 | { std::as_const(__iter) < __iter } -> __boolean_testable; | |
| 137 | { __iter < std::as_const(__iter) } -> __boolean_testable; | |
| 138 | { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable; | |
| 139 | ||
| 140 | { __iter > __iter } -> __boolean_testable; | |
| 141 | { std::as_const(__iter) > __iter } -> __boolean_testable; | |
| 142 | { __iter > std::as_const(__iter) } -> __boolean_testable; | |
| 143 | { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable; | |
| 144 | ||
| 145 | { __iter >= __iter } -> __boolean_testable; | |
| 146 | { std::as_const(__iter) >= __iter } -> __boolean_testable; | |
| 147 | { __iter >= std::as_const(__iter) } -> __boolean_testable; | |
| 148 | { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable; | |
| 149 | ||
| 150 | { __iter <= __iter } -> __boolean_testable; | |
| 151 | { std::as_const(__iter) <= __iter } -> __boolean_testable; | |
| 152 | { __iter <= std::as_const(__iter) } -> __boolean_testable; | |
| 153 | { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable; | |
| 154 | }; | |
| 155 | ||
| 156 | _LIBCPP_END_NAMESPACE_STD | |
| 157 | ||
| 158 | # ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS | |
| 159 | # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) static_assert(::std::__cpp17_input_iterator<iter_t>); | |
| 160 | # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t) \ | |
| 161 | static_assert(::std::__cpp17_output_iterator<iter_t, write_t>); | |
| 162 | # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) static_assert(::std::__cpp17_forward_iterator<iter_t>); | |
| 163 | # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t) \ | |
| 164 | static_assert(::std::__cpp17_bidirectional_iterator<iter_t>); | |
| 165 | # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t) \ | |
| 166 | static_assert(::std::__cpp17_random_access_iterator<iter_t>); | |
| 167 | # else | |
| 168 | # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) | |
| 169 | # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t) | |
| 170 | # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) | |
| 171 | # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t) | |
| 172 | # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t) | |
| 173 | # endif | |
| 174 | ||
| 175 | #else // _LIBCPP_STD_VER >= 20 | |
| 176 | ||
| 177 | # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t) | |
| 178 | # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t) | |
| 179 | # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t) | |
| 180 | # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t) | |
| 181 | # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t) | |
| 182 | ||
| 183 | #endif // _LIBCPP_STD_VER >= 20 | |
| 184 | ||
| 185 | #endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H |
lib/libcxx/include/__iterator/data.h+1-1| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 24 | |
| 25 | 25 | template <class _Cont> constexpr |
| 26 | 26 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__iterator/default_sentinel.h+2-2| ... | ... | @@ -18,12 +18,12 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | struct default_sentinel_t { }; |
| 24 | 24 | inline constexpr default_sentinel_t default_sentinel{}; |
| 25 | 25 | |
| 26 | #endif // _LIBCPP_STD_VER > 17 | |
| 26 | #endif // _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_END_NAMESPACE_STD |
| 29 | 29 |
lib/libcxx/include/__iterator/distance.h+2-2| ... | ... | @@ -53,7 +53,7 @@ distance(_InputIter __first, _InputIter __last) |
| 53 | 53 | return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | #if _LIBCPP_STD_VER > 17 | |
| 56 | #if _LIBCPP_STD_VER >= 20 | |
| 57 | 57 | |
| 58 | 58 | // [range.iter.op.distance] |
| 59 | 59 | |
| ... | ... | @@ -101,7 +101,7 @@ inline namespace __cpo { |
| 101 | 101 | } // namespace __cpo |
| 102 | 102 | } // namespace ranges |
| 103 | 103 | |
| 104 | #endif // _LIBCPP_STD_VER > 17 | |
| 104 | #endif // _LIBCPP_STD_VER >= 20 | |
| 105 | 105 | |
| 106 | 106 | _LIBCPP_END_NAMESPACE_STD |
| 107 | 107 |
lib/libcxx/include/__iterator/empty.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 24 | |
| 25 | 25 | template <class _Cont> |
| 26 | 26 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -37,7 +37,7 @@ template <class _Ep> |
| 37 | 37 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY |
| 38 | 38 | constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } |
| 39 | 39 | |
| 40 | #endif // _LIBCPP_STD_VER > 14 | |
| 40 | #endif // _LIBCPP_STD_VER >= 17 | |
| 41 | 41 | |
| 42 | 42 | _LIBCPP_END_NAMESPACE_STD |
| 43 | 43 |
lib/libcxx/include/__iterator/erase_if_container.h+5| ... | ... | @@ -16,6 +16,9 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | _LIBCPP_PUSH_MACROS | |
| 20 | #include <__undef_macros> | |
| 21 | ||
| 19 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 23 | |
| 21 | 24 | template <class _Container, class _Predicate> |
| ... | ... | @@ -37,4 +40,6 @@ __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { |
| 37 | 40 | |
| 38 | 41 | _LIBCPP_END_NAMESPACE_STD |
| 39 | 42 | |
| 43 | _LIBCPP_POP_MACROS | |
| 44 | ||
| 40 | 45 | #endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H |
lib/libcxx/include/__iterator/front_insert_iterator.h+6-1| ... | ... | @@ -21,6 +21,9 @@ |
| 21 | 21 | # pragma GCC system_header |
| 22 | 22 | #endif |
| 23 | 23 | |
| 24 | _LIBCPP_PUSH_MACROS | |
| 25 | #include <__undef_macros> | |
| 26 | ||
| 24 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 28 | |
| 26 | 29 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| ... | ... | @@ -36,7 +39,7 @@ protected: |
| 36 | 39 | public: |
| 37 | 40 | typedef output_iterator_tag iterator_category; |
| 38 | 41 | typedef void value_type; |
| 39 | #if _LIBCPP_STD_VER > 17 | |
| 42 | #if _LIBCPP_STD_VER >= 20 | |
| 40 | 43 | typedef ptrdiff_t difference_type; |
| 41 | 44 | #else |
| 42 | 45 | typedef void difference_type; |
| ... | ... | @@ -68,4 +71,6 @@ front_inserter(_Container& __x) |
| 68 | 71 | |
| 69 | 72 | _LIBCPP_END_NAMESPACE_STD |
| 70 | 73 | |
| 74 | _LIBCPP_POP_MACROS | |
| 75 | ||
| 71 | 76 | #endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H |
lib/libcxx/include/__iterator/incrementable_traits.h+2-2| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | // [incrementable.traits] |
| 32 | 32 | template<class> struct incrementable_traits {}; |
| ... | ... | @@ -71,7 +71,7 @@ using iter_difference_t = typename conditional_t<__is_primary_template<iterator_ |
| 71 | 71 | incrementable_traits<remove_cvref_t<_Ip> >, |
| 72 | 72 | iterator_traits<remove_cvref_t<_Ip> > >::difference_type; |
| 73 | 73 | |
| 74 | #endif // _LIBCPP_STD_VER > 17 | |
| 74 | #endif // _LIBCPP_STD_VER >= 20 | |
| 75 | 75 | |
| 76 | 76 | _LIBCPP_END_NAMESPACE_STD |
| 77 | 77 |
lib/libcxx/include/__iterator/indirectly_comparable.h+2-2| ... | ... | @@ -21,13 +21,13 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity> |
| 27 | 27 | concept indirectly_comparable = |
| 28 | 28 | indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; |
| 29 | 29 | |
| 30 | #endif // _LIBCPP_STD_VER > 17 | |
| 30 | #endif // _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 33 | 33 |
lib/libcxx/include/__iterator/insert_iterator.h+7-2| ... | ... | @@ -22,9 +22,12 @@ |
| 22 | 22 | # pragma GCC system_header |
| 23 | 23 | #endif |
| 24 | 24 | |
| 25 | _LIBCPP_PUSH_MACROS | |
| 26 | #include <__undef_macros> | |
| 27 | ||
| 25 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 29 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 31 | template <class _Container> |
| 29 | 32 | using __insert_iterator_iter_t = ranges::iterator_t<_Container>; |
| 30 | 33 | #else |
| ... | ... | @@ -46,7 +49,7 @@ protected: |
| 46 | 49 | public: |
| 47 | 50 | typedef output_iterator_tag iterator_category; |
| 48 | 51 | typedef void value_type; |
| 49 | #if _LIBCPP_STD_VER > 17 | |
| 52 | #if _LIBCPP_STD_VER >= 20 | |
| 50 | 53 | typedef ptrdiff_t difference_type; |
| 51 | 54 | #else |
| 52 | 55 | typedef void difference_type; |
| ... | ... | @@ -78,4 +81,6 @@ inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) |
| 78 | 81 | |
| 79 | 82 | _LIBCPP_END_NAMESPACE_STD |
| 80 | 83 | |
| 84 | _LIBCPP_POP_MACROS | |
| 85 | ||
| 81 | 86 | #endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H |
lib/libcxx/include/__iterator/istream_iterator.h+4-4| ... | ... | @@ -47,9 +47,9 @@ private: |
| 47 | 47 | _Tp __value_; |
| 48 | 48 | public: |
| 49 | 49 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} |
| 50 | #if _LIBCPP_STD_VER > 17 | |
| 50 | #if _LIBCPP_STD_VER >= 20 | |
| 51 | 51 | _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} |
| 52 | #endif // _LIBCPP_STD_VER > 17 | |
| 52 | #endif // _LIBCPP_STD_VER >= 20 | |
| 53 | 53 | _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) |
| 54 | 54 | { |
| 55 | 55 | if (!(*__in_stream_ >> __value_)) |
| ... | ... | @@ -73,11 +73,11 @@ public: |
| 73 | 73 | operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, |
| 74 | 74 | const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); |
| 75 | 75 | |
| 76 | #if _LIBCPP_STD_VER > 17 | |
| 76 | #if _LIBCPP_STD_VER >= 20 | |
| 77 | 77 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { |
| 78 | 78 | return __i.__in_stream_ == nullptr; |
| 79 | 79 | } |
| 80 | #endif // _LIBCPP_STD_VER > 17 | |
| 80 | #endif // _LIBCPP_STD_VER >= 20 | |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | 83 | template <class _Tp, class _CharT, class _Traits, class _Distance> |
lib/libcxx/include/__iterator/istreambuf_iterator.h+4-4| ... | ... | @@ -67,10 +67,10 @@ private: |
| 67 | 67 | } |
| 68 | 68 | public: |
| 69 | 69 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} |
| 70 | #if _LIBCPP_STD_VER > 17 | |
| 70 | #if _LIBCPP_STD_VER >= 20 | |
| 71 | 71 | _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept |
| 72 | 72 | : istreambuf_iterator() {} |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 73 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 74 | _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT |
| 75 | 75 | : __sbuf_(__s.rdbuf()) {} |
| 76 | 76 | _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT |
| ... | ... | @@ -93,11 +93,11 @@ public: |
| 93 | 93 | _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const |
| 94 | 94 | {return __test_for_eof() == __b.__test_for_eof();} |
| 95 | 95 | |
| 96 | #if _LIBCPP_STD_VER > 17 | |
| 96 | #if _LIBCPP_STD_VER >= 20 | |
| 97 | 97 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { |
| 98 | 98 | return __i.__test_for_eof(); |
| 99 | 99 | } |
| 100 | #endif // _LIBCPP_STD_VER > 17 | |
| 100 | #endif // _LIBCPP_STD_VER >= 20 | |
| 101 | 101 | }; |
| 102 | 102 | |
| 103 | 103 | template <class _CharT, class _Traits> |
lib/libcxx/include/__iterator/iter_move.h+7-2| ... | ... | @@ -23,9 +23,12 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 26 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 30 | |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 32 | |
| 30 | 33 | // [iterator.cust.move] |
| 31 | 34 | |
| ... | ... | @@ -97,8 +100,10 @@ template<__dereferenceable _Tp> |
| 97 | 100 | requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } |
| 98 | 101 | using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); |
| 99 | 102 | |
| 100 | #endif // _LIBCPP_STD_VER > 17 | |
| 103 | #endif // _LIBCPP_STD_VER >= 20 | |
| 101 | 104 | |
| 102 | 105 | _LIBCPP_END_NAMESPACE_STD |
| 103 | 106 | |
| 107 | _LIBCPP_POP_MACROS | |
| 108 | ||
| 104 | 109 | #endif // _LIBCPP___ITERATOR_ITER_MOVE_H |
lib/libcxx/include/__iterator/iter_swap.h+7-2| ... | ... | @@ -26,9 +26,12 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | _LIBCPP_PUSH_MACROS | |
| 30 | #include <__undef_macros> | |
| 31 | ||
| 29 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 33 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 35 | |
| 33 | 36 | // [iter.cust.swap] |
| 34 | 37 | |
| ... | ... | @@ -106,8 +109,10 @@ concept indirectly_swappable = |
| 106 | 109 | ranges::iter_swap(__i2, __i1); |
| 107 | 110 | }; |
| 108 | 111 | |
| 109 | #endif // _LIBCPP_STD_VER > 17 | |
| 112 | #endif // _LIBCPP_STD_VER >= 20 | |
| 110 | 113 | |
| 111 | 114 | _LIBCPP_END_NAMESPACE_STD |
| 112 | 115 | |
| 116 | _LIBCPP_POP_MACROS | |
| 117 | ||
| 113 | 118 | #endif // _LIBCPP___ITERATOR_ITER_SWAP_H |
lib/libcxx/include/__iterator/iterator_traits.h+44-29| ... | ... | @@ -43,7 +43,7 @@ |
| 43 | 43 | |
| 44 | 44 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 45 | 45 | |
| 46 | #if _LIBCPP_STD_VER > 17 | |
| 46 | #if _LIBCPP_STD_VER >= 20 | |
| 47 | 47 | |
| 48 | 48 | template <class _Tp> |
| 49 | 49 | using __with_reference = _Tp&; |
| ... | ... | @@ -62,7 +62,7 @@ concept __dereferenceable = requires(_Tp& __t) { |
| 62 | 62 | template<__dereferenceable _Tp> |
| 63 | 63 | using iter_reference_t = decltype(*std::declval<_Tp&>()); |
| 64 | 64 | |
| 65 | #endif // _LIBCPP_STD_VER > 17 | |
| 65 | #endif // _LIBCPP_STD_VER >= 20 | |
| 66 | 66 | |
| 67 | 67 | template <class _Iter> |
| 68 | 68 | struct _LIBCPP_TEMPLATE_VIS iterator_traits; |
| ... | ... | @@ -72,7 +72,7 @@ struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; |
| 72 | 72 | struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; |
| 73 | 73 | struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; |
| 74 | 74 | struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; |
| 75 | #if _LIBCPP_STD_VER > 17 | |
| 75 | #if _LIBCPP_STD_VER >= 20 | |
| 76 | 76 | struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; |
| 77 | 77 | #endif |
| 78 | 78 | |
| ... | ... | @@ -157,7 +157,7 @@ public: |
| 157 | 157 | static const bool value = decltype(__test<_Tp>(nullptr))::value; |
| 158 | 158 | }; |
| 159 | 159 | |
| 160 | #if _LIBCPP_STD_VER > 17 | |
| 160 | #if _LIBCPP_STD_VER >= 20 | |
| 161 | 161 | |
| 162 | 162 | // The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements |
| 163 | 163 | // from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to |
| ... | ... | @@ -190,7 +190,7 @@ template<class _Ip> |
| 190 | 190 | concept __cpp17_forward_iterator = |
| 191 | 191 | __cpp17_input_iterator<_Ip> && |
| 192 | 192 | constructible_from<_Ip> && |
| 193 | is_lvalue_reference_v<iter_reference_t<_Ip>> && | |
| 193 | is_reference_v<iter_reference_t<_Ip>> && | |
| 194 | 194 | same_as<remove_cvref_t<iter_reference_t<_Ip>>, |
| 195 | 195 | typename indirectly_readable_traits<_Ip>::value_type> && |
| 196 | 196 | requires(_Ip __i) { |
| ... | ... | @@ -381,7 +381,7 @@ struct iterator_traits : __iterator_traits<_Ip> { |
| 381 | 381 | using __primary_template = iterator_traits; |
| 382 | 382 | }; |
| 383 | 383 | |
| 384 | #else // _LIBCPP_STD_VER > 17 | |
| 384 | #else // _LIBCPP_STD_VER >= 20 | |
| 385 | 385 | |
| 386 | 386 | template <class _Iter, bool> struct __iterator_traits {}; |
| 387 | 387 | |
| ... | ... | @@ -418,10 +418,10 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits |
| 418 | 418 | |
| 419 | 419 | using __primary_template = iterator_traits; |
| 420 | 420 | }; |
| 421 | #endif // _LIBCPP_STD_VER > 17 | |
| 421 | #endif // _LIBCPP_STD_VER >= 20 | |
| 422 | 422 | |
| 423 | 423 | template<class _Tp> |
| 424 | #if _LIBCPP_STD_VER > 17 | |
| 424 | #if _LIBCPP_STD_VER >= 20 | |
| 425 | 425 | requires is_object_v<_Tp> |
| 426 | 426 | #endif |
| 427 | 427 | struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> |
| ... | ... | @@ -431,7 +431,7 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> |
| 431 | 431 | typedef _Tp* pointer; |
| 432 | 432 | typedef _Tp& reference; |
| 433 | 433 | typedef random_access_iterator_tag iterator_category; |
| 434 | #if _LIBCPP_STD_VER > 17 | |
| 434 | #if _LIBCPP_STD_VER >= 20 | |
| 435 | 435 | typedef contiguous_iterator_tag iterator_concept; |
| 436 | 436 | #endif |
| 437 | 437 | }; |
| ... | ... | @@ -453,60 +453,60 @@ template <class _Tp, class _Up> |
| 453 | 453 | struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; |
| 454 | 454 | |
| 455 | 455 | template <class _Tp> |
| 456 | struct __is_cpp17_input_iterator : public __has_iterator_category_convertible_to<_Tp, input_iterator_tag> {}; | |
| 456 | using __has_input_iterator_category = __has_iterator_category_convertible_to<_Tp, input_iterator_tag>; | |
| 457 | 457 | |
| 458 | 458 | template <class _Tp> |
| 459 | struct __is_cpp17_forward_iterator : public __has_iterator_category_convertible_to<_Tp, forward_iterator_tag> {}; | |
| 459 | using __has_forward_iterator_category = __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>; | |
| 460 | 460 | |
| 461 | 461 | template <class _Tp> |
| 462 | struct __is_cpp17_bidirectional_iterator : public __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag> {}; | |
| 462 | using __has_bidirectional_iterator_category = __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>; | |
| 463 | 463 | |
| 464 | 464 | template <class _Tp> |
| 465 | struct __is_cpp17_random_access_iterator : public __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag> {}; | |
| 465 | using __has_random_access_iterator_category = __has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>; | |
| 466 | 466 | |
| 467 | // __is_cpp17_contiguous_iterator determines if an iterator is known by | |
| 467 | // __libcpp_is_contiguous_iterator determines if an iterator is known by | |
| 468 | 468 | // libc++ to be contiguous, either because it advertises itself as such |
| 469 | 469 | // (in C++20) or because it is a pointer type or a known trivial wrapper |
| 470 | 470 | // around a (possibly fancy) pointer type, such as __wrap_iter<T*>. |
| 471 | 471 | // Such iterators receive special "contiguous" optimizations in |
| 472 | 472 | // std::copy and std::sort. |
| 473 | 473 | // |
| 474 | #if _LIBCPP_STD_VER > 17 | |
| 474 | #if _LIBCPP_STD_VER >= 20 | |
| 475 | 475 | template <class _Tp> |
| 476 | struct __is_cpp17_contiguous_iterator : _Or< | |
| 476 | struct __libcpp_is_contiguous_iterator : _Or< | |
| 477 | 477 | __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, |
| 478 | 478 | __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> |
| 479 | 479 | > {}; |
| 480 | 480 | #else |
| 481 | 481 | template <class _Tp> |
| 482 | struct __is_cpp17_contiguous_iterator : false_type {}; | |
| 482 | struct __libcpp_is_contiguous_iterator : false_type {}; | |
| 483 | 483 | #endif |
| 484 | 484 | |
| 485 | 485 | // Any native pointer which is an iterator is also a contiguous iterator. |
| 486 | 486 | template <class _Up> |
| 487 | struct __is_cpp17_contiguous_iterator<_Up*> : true_type {}; | |
| 487 | struct __libcpp_is_contiguous_iterator<_Up*> : true_type {}; | |
| 488 | 488 | |
| 489 | 489 | |
| 490 | 490 | template <class _Iter> |
| 491 | 491 | class __wrap_iter; |
| 492 | 492 | |
| 493 | 493 | template <class _Tp> |
| 494 | struct __is_exactly_cpp17_input_iterator | |
| 495 | : public integral_constant<bool, | |
| 494 | using __has_exactly_input_iterator_category | |
| 495 | = integral_constant<bool, | |
| 496 | 496 | __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && |
| 497 | !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; | |
| 497 | !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; | |
| 498 | 498 | |
| 499 | 499 | template <class _Tp> |
| 500 | struct __is_exactly_cpp17_forward_iterator | |
| 501 | : public integral_constant<bool, | |
| 500 | using __has_exactly_forward_iterator_category | |
| 501 | = integral_constant<bool, | |
| 502 | 502 | __has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value && |
| 503 | !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value> {}; | |
| 503 | !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; | |
| 504 | 504 | |
| 505 | 505 | template <class _Tp> |
| 506 | struct __is_exactly_cpp17_bidirectional_iterator | |
| 507 | : public integral_constant<bool, | |
| 506 | using __has_exactly_bidirectional_iterator_category | |
| 507 | = integral_constant<bool, | |
| 508 | 508 | __has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value && |
| 509 | !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value> {}; | |
| 509 | !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; | |
| 510 | 510 | |
| 511 | 511 | template<class _InputIterator> |
| 512 | 512 | using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; |
| ... | ... | @@ -531,8 +531,23 @@ using __iterator_pointer_type = typename iterator_traits<_Iter>::pointer; |
| 531 | 531 | template <class _Iter> |
| 532 | 532 | using __iter_diff_t = typename iterator_traits<_Iter>::difference_type; |
| 533 | 533 | |
| 534 | template<class _InputIterator> | |
| 535 | using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; | |
| 534 | template <class _Iter> | |
| 535 | using __iter_reference = typename iterator_traits<_Iter>::reference; | |
| 536 | ||
| 537 | #if _LIBCPP_STD_VER >= 20 | |
| 538 | ||
| 539 | // [readable.traits] | |
| 540 | ||
| 541 | // Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes | |
| 542 | // `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization | |
| 543 | // generated from the primary template, and `iterator_traits<RI>::value_type` otherwise. | |
| 544 | // This has to be in this file and not readable_traits.h to break the include cycle between the two. | |
| 545 | template <class _Ip> | |
| 546 | using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value, | |
| 547 | indirectly_readable_traits<remove_cvref_t<_Ip> >, | |
| 548 | iterator_traits<remove_cvref_t<_Ip> > >::value_type; | |
| 549 | ||
| 550 | #endif // _LIBCPP_STD_VER >= 20 | |
| 536 | 551 | |
| 537 | 552 | _LIBCPP_END_NAMESPACE_STD |
| 538 | 553 |
lib/libcxx/include/__iterator/mergeable.h+2-2| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | template <class _Input1, class _Input2, class _Output, |
| 28 | 28 | class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> |
| ... | ... | @@ -34,7 +34,7 @@ concept mergeable = |
| 34 | 34 | indirectly_copyable<_Input2, _Output> && |
| 35 | 35 | indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; |
| 36 | 36 | |
| 37 | #endif // _LIBCPP_STD_VER > 17 | |
| 37 | #endif // _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 40 | 40 |
lib/libcxx/include/__iterator/move_iterator.h+35-15| ... | ... | @@ -39,9 +39,12 @@ |
| 39 | 39 | # pragma GCC system_header |
| 40 | 40 | #endif |
| 41 | 41 | |
| 42 | _LIBCPP_PUSH_MACROS | |
| 43 | #include <__undef_macros> | |
| 44 | ||
| 42 | 45 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 43 | 46 | |
| 44 | #if _LIBCPP_STD_VER > 17 | |
| 47 | #if _LIBCPP_STD_VER >= 20 | |
| 45 | 48 | template<class _Iter, class = void> |
| 46 | 49 | struct __move_iter_category_base {}; |
| 47 | 50 | |
| ... | ... | @@ -59,18 +62,33 @@ template<class _Iter, class _Sent> |
| 59 | 62 | concept __move_iter_comparable = requires { |
| 60 | 63 | { std::declval<const _Iter&>() == std::declval<_Sent>() } -> convertible_to<bool>; |
| 61 | 64 | }; |
| 62 | #endif // _LIBCPP_STD_VER > 17 | |
| 65 | #endif // _LIBCPP_STD_VER >= 20 | |
| 63 | 66 | |
| 64 | 67 | template <class _Iter> |
| 65 | 68 | class _LIBCPP_TEMPLATE_VIS move_iterator |
| 66 | #if _LIBCPP_STD_VER > 17 | |
| 69 | #if _LIBCPP_STD_VER >= 20 | |
| 67 | 70 | : public __move_iter_category_base<_Iter> |
| 68 | 71 | #endif |
| 69 | 72 | { |
| 73 | #if _LIBCPP_STD_VER >= 20 | |
| 74 | private: | |
| 75 | _LIBCPP_HIDE_FROM_ABI | |
| 76 | static constexpr auto __get_iter_concept() { | |
| 77 | if constexpr (random_access_iterator<_Iter>) { | |
| 78 | return random_access_iterator_tag{}; | |
| 79 | } else if constexpr (bidirectional_iterator<_Iter>) { | |
| 80 | return bidirectional_iterator_tag{}; | |
| 81 | } else if constexpr (forward_iterator<_Iter>) { | |
| 82 | return forward_iterator_tag{}; | |
| 83 | } else { | |
| 84 | return input_iterator_tag{}; | |
| 85 | } | |
| 86 | } | |
| 87 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 88 | public: |
| 71 | #if _LIBCPP_STD_VER > 17 | |
| 89 | #if _LIBCPP_STD_VER >= 20 | |
| 72 | 90 | using iterator_type = _Iter; |
| 73 | using iterator_concept = input_iterator_tag; | |
| 91 | using iterator_concept = decltype(__get_iter_concept()); | |
| 74 | 92 | // iterator_category is inherited and not always present |
| 75 | 93 | using value_type = iter_value_t<_Iter>; |
| 76 | 94 | using difference_type = iter_difference_t<_Iter>; |
| ... | ... | @@ -79,7 +97,7 @@ public: |
| 79 | 97 | #else |
| 80 | 98 | typedef _Iter iterator_type; |
| 81 | 99 | typedef _If< |
| 82 | __is_cpp17_random_access_iterator<_Iter>::value, | |
| 100 | __has_random_access_iterator_category<_Iter>::value, | |
| 83 | 101 | random_access_iterator_tag, |
| 84 | 102 | typename iterator_traits<_Iter>::iterator_category |
| 85 | 103 | > iterator_category; |
| ... | ... | @@ -93,7 +111,7 @@ public: |
| 93 | 111 | __libcpp_remove_reference_t<__reference>&&, |
| 94 | 112 | __reference |
| 95 | 113 | >::type reference; |
| 96 | #endif // _LIBCPP_STD_VER > 17 | |
| 114 | #endif // _LIBCPP_STD_VER >= 20 | |
| 97 | 115 | |
| 98 | 116 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 99 | 117 | explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} |
| ... | ... | @@ -104,7 +122,7 @@ public: |
| 104 | 122 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 105 | 123 | pointer operator->() const { return __current_; } |
| 106 | 124 | |
| 107 | #if _LIBCPP_STD_VER > 17 | |
| 125 | #if _LIBCPP_STD_VER >= 20 | |
| 108 | 126 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 109 | 127 | move_iterator() requires is_constructible_v<_Iter> : __current_() {} |
| 110 | 128 | |
| ... | ... | @@ -171,7 +189,7 @@ public: |
| 171 | 189 | |
| 172 | 190 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 173 | 191 | move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } |
| 174 | #endif // _LIBCPP_STD_VER > 17 | |
| 192 | #endif // _LIBCPP_STD_VER >= 20 | |
| 175 | 193 | |
| 176 | 194 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 177 | 195 | move_iterator& operator--() { --__current_; return *this; } |
| ... | ... | @@ -186,7 +204,7 @@ public: |
| 186 | 204 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 187 | 205 | move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } |
| 188 | 206 | |
| 189 | #if _LIBCPP_STD_VER > 17 | |
| 207 | #if _LIBCPP_STD_VER >= 20 | |
| 190 | 208 | template<sentinel_for<_Iter> _Sent> |
| 191 | 209 | friend _LIBCPP_HIDE_FROM_ABI constexpr |
| 192 | 210 | bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) |
| ... | ... | @@ -223,7 +241,7 @@ public: |
| 223 | 241 | { |
| 224 | 242 | return ranges::iter_swap(__x.__current_, __y.__current_); |
| 225 | 243 | } |
| 226 | #endif // _LIBCPP_STD_VER > 17 | |
| 244 | #endif // _LIBCPP_STD_VER >= 20 | |
| 227 | 245 | |
| 228 | 246 | private: |
| 229 | 247 | template<class _It2> friend class move_iterator; |
| ... | ... | @@ -276,7 +294,7 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _ |
| 276 | 294 | return __x.base() >= __y.base(); |
| 277 | 295 | } |
| 278 | 296 | |
| 279 | #if _LIBCPP_STD_VER > 17 | |
| 297 | #if _LIBCPP_STD_VER >= 20 | |
| 280 | 298 | template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> |
| 281 | 299 | inline _LIBCPP_HIDE_FROM_ABI constexpr |
| 282 | 300 | auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) |
| ... | ... | @@ -284,7 +302,7 @@ auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& |
| 284 | 302 | { |
| 285 | 303 | return __x.base() <=> __y.base(); |
| 286 | 304 | } |
| 287 | #endif // _LIBCPP_STD_VER > 17 | |
| 305 | #endif // _LIBCPP_STD_VER >= 20 | |
| 288 | 306 | |
| 289 | 307 | #ifndef _LIBCPP_CXX03_LANG |
| 290 | 308 | template <class _Iter1, class _Iter2> |
| ... | ... | @@ -304,7 +322,7 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) |
| 304 | 322 | } |
| 305 | 323 | #endif // !_LIBCPP_CXX03_LANG |
| 306 | 324 | |
| 307 | #if _LIBCPP_STD_VER > 17 | |
| 325 | #if _LIBCPP_STD_VER >= 20 | |
| 308 | 326 | template <class _Iter> |
| 309 | 327 | inline _LIBCPP_HIDE_FROM_ABI constexpr |
| 310 | 328 | move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) |
| ... | ... | @@ -320,7 +338,7 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato |
| 320 | 338 | { |
| 321 | 339 | return move_iterator<_Iter>(__x.base() + __n); |
| 322 | 340 | } |
| 323 | #endif // _LIBCPP_STD_VER > 17 | |
| 341 | #endif // _LIBCPP_STD_VER >= 20 | |
| 324 | 342 | |
| 325 | 343 | template <class _Iter> |
| 326 | 344 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| ... | ... | @@ -332,4 +350,6 @@ make_move_iterator(_Iter __i) |
| 332 | 350 | |
| 333 | 351 | _LIBCPP_END_NAMESPACE_STD |
| 334 | 352 | |
| 353 | _LIBCPP_POP_MACROS | |
| 354 | ||
| 335 | 355 | #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H |
lib/libcxx/include/__iterator/move_sentinel.h+8-3| ... | ... | @@ -19,9 +19,12 @@ |
| 19 | 19 | # pragma GCC system_header |
| 20 | 20 | #endif |
| 21 | 21 | |
| 22 | _LIBCPP_PUSH_MACROS | |
| 23 | #include <__undef_macros> | |
| 24 | ||
| 22 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 26 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 28 | |
| 26 | 29 | template <semiregular _Sent> |
| 27 | 30 | class _LIBCPP_TEMPLATE_VIS move_sentinel |
| ... | ... | @@ -44,7 +47,7 @@ public: |
| 44 | 47 | move_sentinel& operator=(const move_sentinel<_S2>& __s) |
| 45 | 48 | { __last_ = __s.base(); return *this; } |
| 46 | 49 | |
| 47 | constexpr _Sent base() const { return __last_; } | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; } | |
| 48 | 51 | |
| 49 | 52 | private: |
| 50 | 53 | _Sent __last_ = _Sent(); |
| ... | ... | @@ -52,8 +55,10 @@ private: |
| 52 | 55 | |
| 53 | 56 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); |
| 54 | 57 | |
| 55 | #endif // _LIBCPP_STD_VER > 17 | |
| 58 | #endif // _LIBCPP_STD_VER >= 20 | |
| 56 | 59 | |
| 57 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 61 | |
| 62 | _LIBCPP_POP_MACROS | |
| 63 | ||
| 59 | 64 | #endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H |
lib/libcxx/include/__iterator/next.h+5-5| ... | ... | @@ -26,16 +26,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | 27 | template <class _InputIter> |
| 28 | 28 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 29 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type | |
| 29 | typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type | |
| 30 | 30 | next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { |
| 31 | _LIBCPP_ASSERT(__n >= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, | |
| 32 | "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); | |
| 31 | _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, | |
| 32 | "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); | |
| 33 | 33 | |
| 34 | 34 | _VSTD::advance(__x, __n); |
| 35 | 35 | return __x; |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | #if _LIBCPP_STD_VER > 17 | |
| 38 | #if _LIBCPP_STD_VER >= 20 | |
| 39 | 39 | |
| 40 | 40 | // [range.iter.op.next] |
| 41 | 41 | |
| ... | ... | @@ -77,7 +77,7 @@ inline namespace __cpo { |
| 77 | 77 | } // namespace __cpo |
| 78 | 78 | } // namespace ranges |
| 79 | 79 | |
| 80 | #endif // _LIBCPP_STD_VER > 17 | |
| 80 | #endif // _LIBCPP_STD_VER >= 20 | |
| 81 | 81 | |
| 82 | 82 | _LIBCPP_END_NAMESPACE_STD |
| 83 | 83 |
lib/libcxx/include/__iterator/ostream_iterator.h+1-1| ... | ... | @@ -34,7 +34,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 34 | 34 | public: |
| 35 | 35 | typedef output_iterator_tag iterator_category; |
| 36 | 36 | typedef void value_type; |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | typedef ptrdiff_t difference_type; |
| 39 | 39 | #else |
| 40 | 40 | typedef void difference_type; |
lib/libcxx/include/__iterator/ostreambuf_iterator.h+1-1| ... | ... | @@ -33,7 +33,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 33 | 33 | public: |
| 34 | 34 | typedef output_iterator_tag iterator_category; |
| 35 | 35 | typedef void value_type; |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | typedef ptrdiff_t difference_type; |
| 38 | 38 | #else |
| 39 | 39 | typedef void difference_type; |
lib/libcxx/include/__iterator/permutable.h+2-2| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 17 | |
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | 24 | |
| 25 | 25 | template <class _Iterator> |
| 26 | 26 | concept permutable = |
| ... | ... | @@ -28,7 +28,7 @@ concept permutable = |
| 28 | 28 | indirectly_movable_storable<_Iterator, _Iterator> && |
| 29 | 29 | indirectly_swappable<_Iterator, _Iterator>; |
| 30 | 30 | |
| 31 | #endif // _LIBCPP_STD_VER > 17 | |
| 31 | #endif // _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 34 |
lib/libcxx/include/__iterator/prev.h+5-5| ... | ... | @@ -26,15 +26,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | 27 | template <class _InputIter> |
| 28 | 28 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 29 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value, _InputIter>::type | |
| 29 | typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type | |
| 30 | 30 | prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { |
| 31 | _LIBCPP_ASSERT(__n <= 0 || __is_cpp17_bidirectional_iterator<_InputIter>::value, | |
| 32 | "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); | |
| 31 | _LIBCPP_ASSERT_UNCATEGORIZED(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value, | |
| 32 | "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); | |
| 33 | 33 | _VSTD::advance(__x, -__n); |
| 34 | 34 | return __x; |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | // [range.iter.op.prev] |
| 40 | 40 | |
| ... | ... | @@ -70,7 +70,7 @@ inline namespace __cpo { |
| 70 | 70 | } // namespace __cpo |
| 71 | 71 | } // namespace ranges |
| 72 | 72 | |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 73 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 74 | |
| 75 | 75 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 76 |
lib/libcxx/include/__iterator/projected.h+2-2| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj> |
| 27 | 27 | struct projected { |
| ... | ... | @@ -34,7 +34,7 @@ struct incrementable_traits<projected<_It, _Proj>> { |
| 34 | 34 | using difference_type = iter_difference_t<_It>; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | #endif // _LIBCPP_STD_VER > 17 | |
| 37 | #endif // _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | |
| 39 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 40 | 40 |
lib/libcxx/include/__iterator/ranges_iterator_traits.h created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H | |
| 11 | #define _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__fwd/pair.h> | |
| 15 | #include <__ranges/concepts.h> | |
| 16 | #include <__type_traits/add_const.h> | |
| 17 | #include <__type_traits/remove_const.h> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | #if _LIBCPP_STD_VER >= 23 | |
| 26 | ||
| 27 | template <ranges::input_range _Range> | |
| 28 | using __range_key_type = __remove_const_t<typename ranges::range_value_t<_Range>::first_type>; | |
| 29 | ||
| 30 | template <ranges::input_range _Range> | |
| 31 | using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type; | |
| 32 | ||
| 33 | template <ranges::input_range _Range> | |
| 34 | using __range_to_alloc_type = | |
| 35 | pair<add_const_t<typename ranges::range_value_t<_Range>::first_type>, | |
| 36 | typename ranges::range_value_t<_Range>::second_type>; | |
| 37 | ||
| 38 | #endif | |
| 39 | ||
| 40 | _LIBCPP_END_NAMESPACE_STD | |
| 41 | ||
| 42 | #endif // _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H |
lib/libcxx/include/__iterator/readable_traits.h+2-13| ... | ... | @@ -26,7 +26,7 @@ |
| 26 | 26 | |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 29 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 30 | |
| 31 | 31 | // [readable.traits] |
| 32 | 32 | template<class> struct __cond_value_type {}; |
| ... | ... | @@ -74,18 +74,7 @@ template<__has_member_value_type _Tp> |
| 74 | 74 | struct indirectly_readable_traits<_Tp> |
| 75 | 75 | : __cond_value_type<typename _Tp::value_type> {}; |
| 76 | 76 | |
| 77 | template <class> | |
| 78 | struct iterator_traits; | |
| 79 | ||
| 80 | // Let `RI` be `remove_cvref_t<I>`. The type `iter_value_t<I>` denotes | |
| 81 | // `indirectly_readable_traits<RI>::value_type` if `iterator_traits<RI>` names a specialization | |
| 82 | // generated from the primary template, and `iterator_traits<RI>::value_type` otherwise. | |
| 83 | template <class _Ip> | |
| 84 | using iter_value_t = typename conditional_t<__is_primary_template<iterator_traits<remove_cvref_t<_Ip> > >::value, | |
| 85 | indirectly_readable_traits<remove_cvref_t<_Ip> >, | |
| 86 | iterator_traits<remove_cvref_t<_Ip> > >::value_type; | |
| 87 | ||
| 88 | #endif // _LIBCPP_STD_VER > 17 | |
| 77 | #endif // _LIBCPP_STD_VER >= 20 | |
| 89 | 78 | |
| 90 | 79 | _LIBCPP_END_NAMESPACE_STD |
| 91 | 80 |
lib/libcxx/include/__iterator/reverse_access.h+2-2| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 24 | #if _LIBCPP_STD_VER >= 14 | |
| 25 | 25 | |
| 26 | 26 | template <class _Tp, size_t _Np> |
| 27 | 27 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| ... | ... | @@ -93,7 +93,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) |
| 93 | 93 | return _VSTD::rend(__c); |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | #endif // _LIBCPP_STD_VER > 11 | |
| 96 | #endif // _LIBCPP_STD_VER >= 14 | |
| 97 | 97 | |
| 98 | 98 | _LIBCPP_END_NAMESPACE_STD |
| 99 | 99 |
lib/libcxx/include/__iterator/reverse_iterator.h+31-31| ... | ... | @@ -63,21 +63,21 @@ private: |
| 63 | 63 | _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break |
| 64 | 64 | #endif |
| 65 | 65 | |
| 66 | #if _LIBCPP_STD_VER > 17 | |
| 67 | static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, | |
| 66 | #if _LIBCPP_STD_VER >= 20 | |
| 67 | static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>, | |
| 68 | 68 | "reverse_iterator<It> requires It to be a bidirectional iterator."); |
| 69 | #endif // _LIBCPP_STD_VER > 17 | |
| 69 | #endif // _LIBCPP_STD_VER >= 20 | |
| 70 | 70 | |
| 71 | 71 | protected: |
| 72 | 72 | _Iter current; |
| 73 | 73 | public: |
| 74 | 74 | using iterator_type = _Iter; |
| 75 | 75 | |
| 76 | using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, | |
| 76 | using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value, | |
| 77 | 77 | random_access_iterator_tag, |
| 78 | 78 | typename iterator_traits<_Iter>::iterator_category>; |
| 79 | 79 | using pointer = typename iterator_traits<_Iter>::pointer; |
| 80 | #if _LIBCPP_STD_VER > 17 | |
| 80 | #if _LIBCPP_STD_VER >= 20 | |
| 81 | 81 | using iterator_concept = _If<random_access_iterator<_Iter>, random_access_iterator_tag, bidirectional_iterator_tag>; |
| 82 | 82 | using value_type = iter_value_t<_Iter>; |
| 83 | 83 | using difference_type = iter_difference_t<_Iter>; |
| ... | ... | @@ -144,7 +144,7 @@ public: |
| 144 | 144 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 145 | 145 | reference operator*() const {_Iter __tmp = current; return *--__tmp;} |
| 146 | 146 | |
| 147 | #if _LIBCPP_STD_VER > 17 | |
| 147 | #if _LIBCPP_STD_VER >= 20 | |
| 148 | 148 | _LIBCPP_INLINE_VISIBILITY |
| 149 | 149 | constexpr pointer operator->() const |
| 150 | 150 | requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } |
| ... | ... | @@ -160,7 +160,7 @@ public: |
| 160 | 160 | pointer operator->() const { |
| 161 | 161 | return std::addressof(operator*()); |
| 162 | 162 | } |
| 163 | #endif // _LIBCPP_STD_VER > 17 | |
| 163 | #endif // _LIBCPP_STD_VER >= 20 | |
| 164 | 164 | |
| 165 | 165 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 166 | 166 | reverse_iterator& operator++() {--current; return *this;} |
| ... | ... | @@ -181,7 +181,7 @@ public: |
| 181 | 181 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 182 | 182 | reference operator[](difference_type __n) const {return *(*this + __n);} |
| 183 | 183 | |
| 184 | #if _LIBCPP_STD_VER > 17 | |
| 184 | #if _LIBCPP_STD_VER >= 20 | |
| 185 | 185 | _LIBCPP_HIDE_FROM_ABI friend constexpr |
| 186 | 186 | iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) |
| 187 | 187 | noexcept(is_nothrow_copy_constructible_v<_Iter> && |
| ... | ... | @@ -200,18 +200,18 @@ public: |
| 200 | 200 | auto __ytmp = __y.base(); |
| 201 | 201 | ranges::iter_swap(--__xtmp, --__ytmp); |
| 202 | 202 | } |
| 203 | #endif // _LIBCPP_STD_VER > 17 | |
| 203 | #endif // _LIBCPP_STD_VER >= 20 | |
| 204 | 204 | }; |
| 205 | 205 | |
| 206 | 206 | template <class _Iter1, class _Iter2> |
| 207 | 207 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 208 | 208 | bool |
| 209 | 209 | operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 210 | #if _LIBCPP_STD_VER > 17 | |
| 210 | #if _LIBCPP_STD_VER >= 20 | |
| 211 | 211 | requires requires { |
| 212 | 212 | { __x.base() == __y.base() } -> convertible_to<bool>; |
| 213 | 213 | } |
| 214 | #endif // _LIBCPP_STD_VER > 17 | |
| 214 | #endif // _LIBCPP_STD_VER >= 20 | |
| 215 | 215 | { |
| 216 | 216 | return __x.base() == __y.base(); |
| 217 | 217 | } |
| ... | ... | @@ -220,11 +220,11 @@ template <class _Iter1, class _Iter2> |
| 220 | 220 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 221 | 221 | bool |
| 222 | 222 | operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 223 | #if _LIBCPP_STD_VER > 17 | |
| 223 | #if _LIBCPP_STD_VER >= 20 | |
| 224 | 224 | requires requires { |
| 225 | 225 | { __x.base() > __y.base() } -> convertible_to<bool>; |
| 226 | 226 | } |
| 227 | #endif // _LIBCPP_STD_VER > 17 | |
| 227 | #endif // _LIBCPP_STD_VER >= 20 | |
| 228 | 228 | { |
| 229 | 229 | return __x.base() > __y.base(); |
| 230 | 230 | } |
| ... | ... | @@ -233,11 +233,11 @@ template <class _Iter1, class _Iter2> |
| 233 | 233 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 234 | 234 | bool |
| 235 | 235 | operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 236 | #if _LIBCPP_STD_VER > 17 | |
| 236 | #if _LIBCPP_STD_VER >= 20 | |
| 237 | 237 | requires requires { |
| 238 | 238 | { __x.base() != __y.base() } -> convertible_to<bool>; |
| 239 | 239 | } |
| 240 | #endif // _LIBCPP_STD_VER > 17 | |
| 240 | #endif // _LIBCPP_STD_VER >= 20 | |
| 241 | 241 | { |
| 242 | 242 | return __x.base() != __y.base(); |
| 243 | 243 | } |
| ... | ... | @@ -246,11 +246,11 @@ template <class _Iter1, class _Iter2> |
| 246 | 246 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 247 | 247 | bool |
| 248 | 248 | operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 249 | #if _LIBCPP_STD_VER > 17 | |
| 249 | #if _LIBCPP_STD_VER >= 20 | |
| 250 | 250 | requires requires { |
| 251 | 251 | { __x.base() < __y.base() } -> convertible_to<bool>; |
| 252 | 252 | } |
| 253 | #endif // _LIBCPP_STD_VER > 17 | |
| 253 | #endif // _LIBCPP_STD_VER >= 20 | |
| 254 | 254 | { |
| 255 | 255 | return __x.base() < __y.base(); |
| 256 | 256 | } |
| ... | ... | @@ -259,11 +259,11 @@ template <class _Iter1, class _Iter2> |
| 259 | 259 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 260 | 260 | bool |
| 261 | 261 | operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 262 | #if _LIBCPP_STD_VER > 17 | |
| 262 | #if _LIBCPP_STD_VER >= 20 | |
| 263 | 263 | requires requires { |
| 264 | 264 | { __x.base() <= __y.base() } -> convertible_to<bool>; |
| 265 | 265 | } |
| 266 | #endif // _LIBCPP_STD_VER > 17 | |
| 266 | #endif // _LIBCPP_STD_VER >= 20 | |
| 267 | 267 | { |
| 268 | 268 | return __x.base() <= __y.base(); |
| 269 | 269 | } |
| ... | ... | @@ -272,16 +272,16 @@ template <class _Iter1, class _Iter2> |
| 272 | 272 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 273 | 273 | bool |
| 274 | 274 | operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) |
| 275 | #if _LIBCPP_STD_VER > 17 | |
| 275 | #if _LIBCPP_STD_VER >= 20 | |
| 276 | 276 | requires requires { |
| 277 | 277 | { __x.base() >= __y.base() } -> convertible_to<bool>; |
| 278 | 278 | } |
| 279 | #endif // _LIBCPP_STD_VER > 17 | |
| 279 | #endif // _LIBCPP_STD_VER >= 20 | |
| 280 | 280 | { |
| 281 | 281 | return __x.base() >= __y.base(); |
| 282 | 282 | } |
| 283 | 283 | |
| 284 | #if _LIBCPP_STD_VER > 17 | |
| 284 | #if _LIBCPP_STD_VER >= 20 | |
| 285 | 285 | template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> |
| 286 | 286 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 287 | 287 | compare_three_way_result_t<_Iter1, _Iter2> |
| ... | ... | @@ -289,7 +289,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& |
| 289 | 289 | { |
| 290 | 290 | return __y.base() <=> __x.base(); |
| 291 | 291 | } |
| 292 | #endif // _LIBCPP_STD_VER > 17 | |
| 292 | #endif // _LIBCPP_STD_VER >= 20 | |
| 293 | 293 | |
| 294 | 294 | #ifndef _LIBCPP_CXX03_LANG |
| 295 | 295 | template <class _Iter1, class _Iter2> |
| ... | ... | @@ -318,13 +318,13 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i |
| 318 | 318 | return reverse_iterator<_Iter>(__x.base() - __n); |
| 319 | 319 | } |
| 320 | 320 | |
| 321 | #if _LIBCPP_STD_VER > 17 | |
| 321 | #if _LIBCPP_STD_VER >= 20 | |
| 322 | 322 | template <class _Iter1, class _Iter2> |
| 323 | 323 | requires (!sized_sentinel_for<_Iter1, _Iter2>) |
| 324 | 324 | inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true; |
| 325 | #endif // _LIBCPP_STD_VER > 17 | |
| 325 | #endif // _LIBCPP_STD_VER >= 20 | |
| 326 | 326 | |
| 327 | #if _LIBCPP_STD_VER > 11 | |
| 327 | #if _LIBCPP_STD_VER >= 14 | |
| 328 | 328 | template <class _Iter> |
| 329 | 329 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 330 | 330 | reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) |
| ... | ... | @@ -365,11 +365,11 @@ class __unconstrained_reverse_iterator { |
| 365 | 365 | _Iter __iter_; |
| 366 | 366 | |
| 367 | 367 | public: |
| 368 | static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>); | |
| 368 | static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>); | |
| 369 | 369 | |
| 370 | 370 | using iterator_type = _Iter; |
| 371 | 371 | using iterator_category = |
| 372 | _If<__is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; | |
| 372 | _If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; | |
| 373 | 373 | using pointer = __iterator_pointer_type<_Iter>; |
| 374 | 374 | using value_type = iter_value_t<_Iter>; |
| 375 | 375 | using difference_type = iter_difference_t<_Iter>; |
| ... | ... | @@ -498,7 +498,7 @@ struct __unwrap_reverse_iter_impl { |
| 498 | 498 | } |
| 499 | 499 | }; |
| 500 | 500 | |
| 501 | #if _LIBCPP_STD_VER > 17 | |
| 501 | #if _LIBCPP_STD_VER >= 20 | |
| 502 | 502 | template <ranges::bidirectional_range _Range> |
| 503 | 503 | _LIBCPP_HIDE_FROM_ABI constexpr ranges:: |
| 504 | 504 | subrange<reverse_iterator<ranges::iterator_t<_Range>>, reverse_iterator<ranges::iterator_t<_Range>>> |
| ... | ... | @@ -512,7 +512,7 @@ template <class _Iter, bool __b> |
| 512 | 512 | struct __unwrap_iter_impl<reverse_iterator<reverse_iterator<_Iter> >, __b> |
| 513 | 513 | : __unwrap_reverse_iter_impl<reverse_iterator, reverse_iterator, _Iter> {}; |
| 514 | 514 | |
| 515 | #if _LIBCPP_STD_VER > 17 | |
| 515 | #if _LIBCPP_STD_VER >= 20 | |
| 516 | 516 | |
| 517 | 517 | template <class _Iter, bool __b> |
| 518 | 518 | struct __unwrap_iter_impl<reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> |
| ... | ... | @@ -526,7 +526,7 @@ template <class _Iter, bool __b> |
| 526 | 526 | struct __unwrap_iter_impl<__unconstrained_reverse_iterator<__unconstrained_reverse_iterator<_Iter>>, __b> |
| 527 | 527 | : __unwrap_reverse_iter_impl<__unconstrained_reverse_iterator, __unconstrained_reverse_iterator, _Iter> {}; |
| 528 | 528 | |
| 529 | #endif // _LIBCPP_STD_VER > 17 | |
| 529 | #endif // _LIBCPP_STD_VER >= 20 | |
| 530 | 530 | |
| 531 | 531 | _LIBCPP_END_NAMESPACE_STD |
| 532 | 532 |
lib/libcxx/include/__iterator/size.h+3-3| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | |
| 26 | 26 | template <class _Cont> |
| 27 | 27 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -34,7 +34,7 @@ template <class _Tp, size_t _Sz> |
| 34 | 34 | _LIBCPP_INLINE_VISIBILITY |
| 35 | 35 | constexpr size_t size(const _Tp (&)[_Sz]) noexcept { return _Sz; } |
| 36 | 36 | |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | template <class _Cont> |
| 39 | 39 | _LIBCPP_INLINE_VISIBILITY |
| 40 | 40 | constexpr auto ssize(const _Cont& __c) |
| ... | ... | @@ -52,7 +52,7 @@ constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; } |
| 52 | 52 | _LIBCPP_DIAGNOSTIC_POP |
| 53 | 53 | #endif |
| 54 | 54 | |
| 55 | #endif // _LIBCPP_STD_VER > 14 | |
| 55 | #endif // _LIBCPP_STD_VER >= 17 | |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 58 |
lib/libcxx/include/__iterator/sortable.h+2-2| ... | ... | @@ -23,14 +23,14 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | template <class _Iter, class _Comp = ranges::less, class _Proj = identity> |
| 29 | 29 | concept sortable = |
| 30 | 30 | permutable<_Iter> && |
| 31 | 31 | indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>; |
| 32 | 32 | |
| 33 | #endif // _LIBCPP_STD_VER > 17 | |
| 33 | #endif // _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | _LIBCPP_END_NAMESPACE_STD |
| 36 | 36 |
lib/libcxx/include/__iterator/unreachable_sentinel.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 17 | |
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | 23 | |
| 24 | 24 | struct unreachable_sentinel_t { |
| 25 | 25 | template<weakly_incrementable _Iter> |
| ... | ... | @@ -31,7 +31,7 @@ struct unreachable_sentinel_t { |
| 31 | 31 | |
| 32 | 32 | inline constexpr unreachable_sentinel_t unreachable_sentinel{}; |
| 33 | 33 | |
| 34 | #endif // _LIBCPP_STD_VER > 17 | |
| 34 | #endif // _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | _LIBCPP_END_NAMESPACE_STD |
| 37 | 37 |
lib/libcxx/include/__iterator/wrap_iter.h+4-58| ... | ... | @@ -11,12 +11,12 @@ |
| 11 | 11 | #define _LIBCPP___ITERATOR_WRAP_ITER_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__debug> | |
| 15 | 14 | #include <__iterator/iterator_traits.h> |
| 16 | 15 | #include <__memory/addressof.h> |
| 17 | 16 | #include <__memory/pointer_traits.h> |
| 18 | 17 | #include <__type_traits/enable_if.h> |
| 19 | 18 | #include <__type_traits/is_convertible.h> |
| 19 | #include <cstddef> | |
| 20 | 20 | |
| 21 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 22 | # pragma GCC system_header |
| ... | ... | @@ -34,7 +34,7 @@ public: |
| 34 | 34 | typedef typename iterator_traits<iterator_type>::pointer pointer; |
| 35 | 35 | typedef typename iterator_traits<iterator_type>::reference reference; |
| 36 | 36 | typedef typename iterator_traits<iterator_type>::iterator_category iterator_category; |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 38 | typedef contiguous_iterator_tag iterator_concept; |
| 39 | 39 | #endif |
| 40 | 40 | |
| ... | ... | @@ -44,60 +44,23 @@ public: |
| 44 | 44 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter() _NOEXCEPT |
| 45 | 45 | : __i_() |
| 46 | 46 | { |
| 47 | _VSTD::__debug_db_insert_i(this); | |
| 48 | 47 | } |
| 49 | 48 | template <class _Up> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 50 | 49 | __wrap_iter(const __wrap_iter<_Up>& __u, |
| 51 | 50 | typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT |
| 52 | 51 | : __i_(__u.base()) |
| 53 | 52 | { |
| 54 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 55 | if (!__libcpp_is_constant_evaluated()) | |
| 56 | __get_db()->__iterator_copy(this, _VSTD::addressof(__u)); | |
| 57 | #endif | |
| 58 | } | |
| 59 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 60 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 61 | __wrap_iter(const __wrap_iter& __x) | |
| 62 | : __i_(__x.base()) | |
| 63 | { | |
| 64 | if (!__libcpp_is_constant_evaluated()) | |
| 65 | __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); | |
| 66 | } | |
| 67 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 68 | __wrap_iter& operator=(const __wrap_iter& __x) | |
| 69 | { | |
| 70 | if (this != _VSTD::addressof(__x)) | |
| 71 | { | |
| 72 | if (!__libcpp_is_constant_evaluated()) | |
| 73 | __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); | |
| 74 | __i_ = __x.__i_; | |
| 75 | } | |
| 76 | return *this; | |
| 77 | } | |
| 78 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 79 | ~__wrap_iter() | |
| 80 | { | |
| 81 | if (!__libcpp_is_constant_evaluated()) | |
| 82 | __get_db()->__erase_i(this); | |
| 83 | 53 | } |
| 84 | #endif | |
| 85 | 54 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT |
| 86 | 55 | { |
| 87 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 88 | "Attempted to dereference a non-dereferenceable iterator"); | |
| 89 | 56 | return *__i_; |
| 90 | 57 | } |
| 91 | 58 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT |
| 92 | 59 | { |
| 93 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 94 | "Attempted to dereference a non-dereferenceable iterator"); | |
| 95 | 60 | return _VSTD::__to_address(__i_); |
| 96 | 61 | } |
| 97 | 62 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator++() _NOEXCEPT |
| 98 | 63 | { |
| 99 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 100 | "Attempted to increment a non-incrementable iterator"); | |
| 101 | 64 | ++__i_; |
| 102 | 65 | return *this; |
| 103 | 66 | } |
| ... | ... | @@ -106,8 +69,6 @@ public: |
| 106 | 69 | |
| 107 | 70 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator--() _NOEXCEPT |
| 108 | 71 | { |
| 109 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), | |
| 110 | "Attempted to decrement a non-decrementable iterator"); | |
| 111 | 72 | --__i_; |
| 112 | 73 | return *this; |
| 113 | 74 | } |
| ... | ... | @@ -117,8 +78,6 @@ public: |
| 117 | 78 | {__wrap_iter __w(*this); __w += __n; return __w;} |
| 118 | 79 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __wrap_iter& operator+=(difference_type __n) _NOEXCEPT |
| 119 | 80 | { |
| 120 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__addable(this, __n), | |
| 121 | "Attempted to add/subtract an iterator outside its valid range"); | |
| 122 | 81 | __i_ += __n; |
| 123 | 82 | return *this; |
| 124 | 83 | } |
| ... | ... | @@ -128,8 +87,6 @@ public: |
| 128 | 87 | {*this += -__n; return *this;} |
| 129 | 88 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT |
| 130 | 89 | { |
| 131 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__subscriptable(this, __n), | |
| 132 | "Attempted to subscript an iterator outside its valid range"); | |
| 133 | 90 | return __i_[__n]; |
| 134 | 91 | } |
| 135 | 92 | |
| ... | ... | @@ -137,13 +94,8 @@ public: |
| 137 | 94 | |
| 138 | 95 | private: |
| 139 | 96 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 140 | explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i_(__x) | |
| 97 | explicit __wrap_iter(iterator_type __x) _NOEXCEPT : __i_(__x) | |
| 141 | 98 | { |
| 142 | (void)__p; | |
| 143 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 144 | if (!__libcpp_is_constant_evaluated()) | |
| 145 | __get_db()->__insert_ic(this, __p); | |
| 146 | #endif | |
| 147 | 99 | } |
| 148 | 100 | |
| 149 | 101 | template <class _Up> friend class __wrap_iter; |
| ... | ... | @@ -170,8 +122,6 @@ template <class _Iter1> |
| 170 | 122 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 171 | 123 | bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter1>& __y) _NOEXCEPT |
| 172 | 124 | { |
| 173 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), | |
| 174 | "Attempted to compare incomparable iterators"); | |
| 175 | 125 | return __x.base() < __y.base(); |
| 176 | 126 | } |
| 177 | 127 | |
| ... | ... | @@ -179,8 +129,6 @@ template <class _Iter1, class _Iter2> |
| 179 | 129 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 180 | 130 | bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT |
| 181 | 131 | { |
| 182 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(&__x, &__y), | |
| 183 | "Attempted to compare incomparable iterators"); | |
| 184 | 132 | return __x.base() < __y.base(); |
| 185 | 133 | } |
| 186 | 134 | |
| ... | ... | @@ -250,8 +198,6 @@ typename __wrap_iter<_Iter1>::difference_type |
| 250 | 198 | operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT |
| 251 | 199 | #endif // C++03 |
| 252 | 200 | { |
| 253 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__less_than_comparable(_VSTD::addressof(__x), _VSTD::addressof(__y)), | |
| 254 | "Attempted to subtract incompatible iterators"); | |
| 255 | 201 | return __x.base() - __y.base(); |
| 256 | 202 | } |
| 257 | 203 | |
| ... | ... | @@ -265,7 +211,7 @@ __wrap_iter<_Iter1> operator+(typename __wrap_iter<_Iter1>::difference_type __n, |
| 265 | 211 | |
| 266 | 212 | #if _LIBCPP_STD_VER <= 17 |
| 267 | 213 | template <class _It> |
| 268 | struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; | |
| 214 | struct __libcpp_is_contiguous_iterator<__wrap_iter<_It> > : true_type {}; | |
| 269 | 215 | #endif |
| 270 | 216 | |
| 271 | 217 | template <class _It> |
lib/libcxx/include/__locale+47-95| ... | ... | @@ -12,9 +12,12 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__availability> |
| 14 | 14 | #include <__config> |
| 15 | #include <__memory/shared_ptr.h> // __shared_count | |
| 16 | #include <__type_traits/make_unsigned.h> | |
| 15 | 17 | #include <cctype> |
| 18 | #include <clocale> | |
| 16 | 19 | #include <cstdint> |
| 17 | #include <locale.h> | |
| 20 | #include <cstdlib> | |
| 18 | 21 | #include <mutex> |
| 19 | 22 | #include <string> |
| 20 | 23 | |
| ... | ... | @@ -22,15 +25,18 @@ |
| 22 | 25 | #include <cstddef> |
| 23 | 26 | #include <cstring> |
| 24 | 27 | |
| 28 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 29 | # include <cwchar> | |
| 30 | #else | |
| 31 | # include <__std_mbstate_t.h> | |
| 32 | #endif | |
| 33 | ||
| 25 | 34 | #if defined(_LIBCPP_MSVCRT_LIKE) |
| 26 | 35 | # include <__support/win32/locale_win32.h> |
| 27 | 36 | #elif defined(_AIX) || defined(__MVS__) |
| 28 | 37 | # include <__support/ibm/xlocale.h> |
| 29 | 38 | #elif defined(__ANDROID__) |
| 30 | 39 | # include <__support/android/locale_bionic.h> |
| 31 | #elif defined(__sun__) | |
| 32 | # include <__support/solaris/xlocale.h> | |
| 33 | # include <xlocale.h> | |
| 34 | 40 | #elif defined(_NEWLIB_VERSION) |
| 35 | 41 | # include <__support/newlib/xlocale.h> |
| 36 | 42 | #elif defined(__OpenBSD__) |
| ... | ... | @@ -52,64 +58,7 @@ |
| 52 | 58 | |
| 53 | 59 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 54 | 60 | |
| 55 | #if !defined(_LIBCPP_LOCALE__L_EXTENSIONS) | |
| 56 | struct __libcpp_locale_guard { | |
| 57 | _LIBCPP_INLINE_VISIBILITY | |
| 58 | __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {} | |
| 59 | ||
| 60 | _LIBCPP_INLINE_VISIBILITY | |
| 61 | ~__libcpp_locale_guard() { | |
| 62 | if (__old_loc_) | |
| 63 | uselocale(__old_loc_); | |
| 64 | } | |
| 65 | ||
| 66 | locale_t __old_loc_; | |
| 67 | private: | |
| 68 | __libcpp_locale_guard(__libcpp_locale_guard const&); | |
| 69 | __libcpp_locale_guard& operator=(__libcpp_locale_guard const&); | |
| 70 | }; | |
| 71 | #elif defined(_LIBCPP_MSVCRT_LIKE) | |
| 72 | struct __libcpp_locale_guard { | |
| 73 | __libcpp_locale_guard(locale_t __l) : | |
| 74 | __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { | |
| 75 | // Setting the locale can be expensive even when the locale given is | |
| 76 | // already the current locale, so do an explicit check to see if the | |
| 77 | // current locale is already the one we want. | |
| 78 | const char* __lc = __setlocale(nullptr); | |
| 79 | // If every category is the same, the locale string will simply be the | |
| 80 | // locale name, otherwise it will be a semicolon-separated string listing | |
| 81 | // each category. In the second case, we know at least one category won't | |
| 82 | // be what we want, so we only have to check the first case. | |
| 83 | if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) { | |
| 84 | __locale_all = _strdup(__lc); | |
| 85 | if (__locale_all == nullptr) | |
| 86 | __throw_bad_alloc(); | |
| 87 | __setlocale(__l.__get_locale()); | |
| 88 | } | |
| 89 | } | |
| 90 | ~__libcpp_locale_guard() { | |
| 91 | // The CRT documentation doesn't explicitly say, but setlocale() does the | |
| 92 | // right thing when given a semicolon-separated list of locale settings | |
| 93 | // for the different categories in the same format as returned by | |
| 94 | // setlocale(LC_ALL, nullptr). | |
| 95 | if (__locale_all != nullptr) { | |
| 96 | __setlocale(__locale_all); | |
| 97 | free(__locale_all); | |
| 98 | } | |
| 99 | _configthreadlocale(__status); | |
| 100 | } | |
| 101 | static const char* __setlocale(const char* __locale) { | |
| 102 | const char* __new_locale = setlocale(LC_ALL, __locale); | |
| 103 | if (__new_locale == nullptr) | |
| 104 | __throw_bad_alloc(); | |
| 105 | return __new_locale; | |
| 106 | } | |
| 107 | int __status; | |
| 108 | char* __locale_all = nullptr; | |
| 109 | }; | |
| 110 | #endif | |
| 111 | ||
| 112 | class _LIBCPP_TYPE_VIS locale; | |
| 61 | class _LIBCPP_EXPORTED_FROM_ABI locale; | |
| 113 | 62 | |
| 114 | 63 | template <class _Facet> |
| 115 | 64 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -121,12 +70,12 @@ _LIBCPP_INLINE_VISIBILITY |
| 121 | 70 | const _Facet& |
| 122 | 71 | use_facet(const locale&); |
| 123 | 72 | |
| 124 | class _LIBCPP_TYPE_VIS locale | |
| 73 | class _LIBCPP_EXPORTED_FROM_ABI locale | |
| 125 | 74 | { |
| 126 | 75 | public: |
| 127 | 76 | // types: |
| 128 | class _LIBCPP_TYPE_VIS facet; | |
| 129 | class _LIBCPP_TYPE_VIS id; | |
| 77 | class _LIBCPP_EXPORTED_FROM_ABI facet; | |
| 78 | class _LIBCPP_EXPORTED_FROM_ABI id; | |
| 130 | 79 | |
| 131 | 80 | typedef int category; |
| 132 | 81 | _LIBCPP_AVAILABILITY_LOCALE_CATEGORY |
| ... | ... | @@ -162,7 +111,9 @@ public: |
| 162 | 111 | // locale operations: |
| 163 | 112 | string name() const; |
| 164 | 113 | bool operator==(const locale&) const; |
| 165 | bool operator!=(const locale& __y) const {return !(*this == __y);} | |
| 114 | #if _LIBCPP_STD_VER <= 17 | |
| 115 | _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const {return !(*this == __y);} | |
| 116 | #endif | |
| 166 | 117 | template <class _CharT, class _Traits, class _Allocator> |
| 167 | 118 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS |
| 168 | 119 | bool operator()(const basic_string<_CharT, _Traits, _Allocator>&, |
| ... | ... | @@ -185,7 +136,7 @@ private: |
| 185 | 136 | template <class _Facet> friend const _Facet& use_facet(const locale&); |
| 186 | 137 | }; |
| 187 | 138 | |
| 188 | class _LIBCPP_TYPE_VIS locale::facet | |
| 139 | class _LIBCPP_EXPORTED_FROM_ABI locale::facet | |
| 189 | 140 | : public __shared_count |
| 190 | 141 | { |
| 191 | 142 | protected: |
| ... | ... | @@ -201,7 +152,7 @@ private: |
| 201 | 152 | void __on_zero_shared() _NOEXCEPT override; |
| 202 | 153 | }; |
| 203 | 154 | |
| 204 | class _LIBCPP_TYPE_VIS locale::id | |
| 155 | class _LIBCPP_EXPORTED_FROM_ABI locale::id | |
| 205 | 156 | { |
| 206 | 157 | once_flag __flag_; |
| 207 | 158 | int32_t __id_; |
| ... | ... | @@ -349,7 +300,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>; |
| 349 | 300 | template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname; |
| 350 | 301 | |
| 351 | 302 | template <> |
| 352 | class _LIBCPP_TYPE_VIS collate_byname<char> | |
| 303 | class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char> | |
| 353 | 304 | : public collate<char> |
| 354 | 305 | { |
| 355 | 306 | locale_t __l_; |
| ... | ... | @@ -369,7 +320,7 @@ protected: |
| 369 | 320 | |
| 370 | 321 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 371 | 322 | template <> |
| 372 | class _LIBCPP_TYPE_VIS collate_byname<wchar_t> | |
| 323 | class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t> | |
| 373 | 324 | : public collate<wchar_t> |
| 374 | 325 | { |
| 375 | 326 | locale_t __l_; |
| ... | ... | @@ -401,7 +352,7 @@ locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x, |
| 401 | 352 | |
| 402 | 353 | // template <class charT> class ctype |
| 403 | 354 | |
| 404 | class _LIBCPP_TYPE_VIS ctype_base | |
| 355 | class _LIBCPP_EXPORTED_FROM_ABI ctype_base | |
| 405 | 356 | { |
| 406 | 357 | public: |
| 407 | 358 | #if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE) |
| ... | ... | @@ -482,7 +433,7 @@ public: |
| 482 | 433 | static const mask blank = _CTYPE_B; |
| 483 | 434 | static const mask __regex_word = 0x80; |
| 484 | 435 | # endif |
| 485 | #elif defined(__sun__) || defined(_AIX) | |
| 436 | #elif defined(_AIX) | |
| 486 | 437 | typedef unsigned int mask; |
| 487 | 438 | static const mask space = _ISSPACE; |
| 488 | 439 | static const mask print = _ISPRINT; |
| ... | ... | @@ -494,11 +445,7 @@ public: |
| 494 | 445 | static const mask punct = _ISPUNCT; |
| 495 | 446 | static const mask xdigit = _ISXDIGIT; |
| 496 | 447 | static const mask blank = _ISBLANK; |
| 497 | # if defined(_AIX) | |
| 498 | 448 | static const mask __regex_word = 0x8000; |
| 499 | # else | |
| 500 | static const mask __regex_word = 0x80; | |
| 501 | # endif | |
| 502 | 449 | #elif defined(_NEWLIB_VERSION) |
| 503 | 450 | // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. |
| 504 | 451 | typedef char mask; |
| ... | ... | @@ -561,7 +508,7 @@ template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; |
| 561 | 508 | |
| 562 | 509 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 563 | 510 | template <> |
| 564 | class _LIBCPP_TYPE_VIS ctype<wchar_t> | |
| 511 | class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t> | |
| 565 | 512 | : public locale::facet, |
| 566 | 513 | public ctype_base |
| 567 | 514 | { |
| ... | ... | @@ -664,7 +611,7 @@ protected: |
| 664 | 611 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 665 | 612 | |
| 666 | 613 | template <> |
| 667 | class _LIBCPP_TYPE_VIS ctype<char> | |
| 614 | class _LIBCPP_EXPORTED_FROM_ABI ctype<char> | |
| 668 | 615 | : public locale::facet, public ctype_base |
| 669 | 616 | { |
| 670 | 617 | const mask* __tab_; |
| ... | ... | @@ -793,7 +740,7 @@ protected: |
| 793 | 740 | template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname; |
| 794 | 741 | |
| 795 | 742 | template <> |
| 796 | class _LIBCPP_TYPE_VIS ctype_byname<char> | |
| 743 | class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char> | |
| 797 | 744 | : public ctype<char> |
| 798 | 745 | { |
| 799 | 746 | locale_t __l_; |
| ... | ... | @@ -812,7 +759,7 @@ protected: |
| 812 | 759 | |
| 813 | 760 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 814 | 761 | template <> |
| 815 | class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> | |
| 762 | class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t> | |
| 816 | 763 | : public ctype<wchar_t> |
| 817 | 764 | { |
| 818 | 765 | locale_t __l_; |
| ... | ... | @@ -926,6 +873,11 @@ isgraph(_CharT __c, const locale& __loc) |
| 926 | 873 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); |
| 927 | 874 | } |
| 928 | 875 | |
| 876 | template <class _CharT> | |
| 877 | _LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) { | |
| 878 | return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c); | |
| 879 | } | |
| 880 | ||
| 929 | 881 | template <class _CharT> |
| 930 | 882 | inline _LIBCPP_INLINE_VISIBILITY |
| 931 | 883 | _CharT |
| ... | ... | @@ -944,7 +896,7 @@ tolower(_CharT __c, const locale& __loc) |
| 944 | 896 | |
| 945 | 897 | // codecvt_base |
| 946 | 898 | |
| 947 | class _LIBCPP_TYPE_VIS codecvt_base | |
| 899 | class _LIBCPP_EXPORTED_FROM_ABI codecvt_base | |
| 948 | 900 | { |
| 949 | 901 | public: |
| 950 | 902 | _LIBCPP_INLINE_VISIBILITY codecvt_base() {} |
| ... | ... | @@ -958,7 +910,7 @@ template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_ |
| 958 | 910 | // template <> class codecvt<char, char, mbstate_t> |
| 959 | 911 | |
| 960 | 912 | template <> |
| 961 | class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t> | |
| 913 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t> | |
| 962 | 914 | : public locale::facet, |
| 963 | 915 | public codecvt_base |
| 964 | 916 | { |
| ... | ... | @@ -1045,7 +997,7 @@ protected: |
| 1045 | 997 | |
| 1046 | 998 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 1047 | 999 | template <> |
| 1048 | class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t> | |
| 1000 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t> | |
| 1049 | 1001 | : public locale::facet, |
| 1050 | 1002 | public codecvt_base |
| 1051 | 1003 | { |
| ... | ... | @@ -1129,7 +1081,7 @@ protected: |
| 1129 | 1081 | // template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20 |
| 1130 | 1082 | |
| 1131 | 1083 | template <> |
| 1132 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t> | |
| 1084 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t> | |
| 1133 | 1085 | : public locale::facet, |
| 1134 | 1086 | public codecvt_base |
| 1135 | 1087 | { |
| ... | ... | @@ -1217,7 +1169,7 @@ protected: |
| 1217 | 1169 | // template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20 |
| 1218 | 1170 | |
| 1219 | 1171 | template <> |
| 1220 | class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t> | |
| 1172 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t> | |
| 1221 | 1173 | : public locale::facet, |
| 1222 | 1174 | public codecvt_base |
| 1223 | 1175 | { |
| ... | ... | @@ -1305,7 +1257,7 @@ protected: |
| 1305 | 1257 | // template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20 |
| 1306 | 1258 | |
| 1307 | 1259 | template <> |
| 1308 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t> | |
| 1260 | class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t> | |
| 1309 | 1261 | : public locale::facet, |
| 1310 | 1262 | public codecvt_base |
| 1311 | 1263 | { |
| ... | ... | @@ -1393,7 +1345,7 @@ protected: |
| 1393 | 1345 | // template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20 |
| 1394 | 1346 | |
| 1395 | 1347 | template <> |
| 1396 | class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t> | |
| 1348 | class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t> | |
| 1397 | 1349 | : public locale::facet, |
| 1398 | 1350 | public codecvt_base |
| 1399 | 1351 | { |
| ... | ... | @@ -1537,7 +1489,7 @@ struct __narrow_to_utf8<8> |
| 1537 | 1489 | |
| 1538 | 1490 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 1539 | 1491 | template <> |
| 1540 | struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16> | |
| 1492 | struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16> | |
| 1541 | 1493 | : public codecvt<char16_t, char, mbstate_t> |
| 1542 | 1494 | { |
| 1543 | 1495 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1573,7 +1525,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 1573 | 1525 | |
| 1574 | 1526 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 1575 | 1527 | template <> |
| 1576 | struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32> | |
| 1528 | struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32> | |
| 1577 | 1529 | : public codecvt<char32_t, char, mbstate_t> |
| 1578 | 1530 | { |
| 1579 | 1531 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1631,7 +1583,7 @@ struct __widen_from_utf8<8> |
| 1631 | 1583 | |
| 1632 | 1584 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 1633 | 1585 | template <> |
| 1634 | struct _LIBCPP_TYPE_VIS __widen_from_utf8<16> | |
| 1586 | struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16> | |
| 1635 | 1587 | : public codecvt<char16_t, char, mbstate_t> |
| 1636 | 1588 | { |
| 1637 | 1589 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1667,7 +1619,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 1667 | 1619 | |
| 1668 | 1620 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 1669 | 1621 | template <> |
| 1670 | struct _LIBCPP_TYPE_VIS __widen_from_utf8<32> | |
| 1622 | struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> | |
| 1671 | 1623 | : public codecvt<char32_t, char, mbstate_t> |
| 1672 | 1624 | { |
| 1673 | 1625 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1706,7 +1658,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 1706 | 1658 | template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct; |
| 1707 | 1659 | |
| 1708 | 1660 | template <> |
| 1709 | class _LIBCPP_TYPE_VIS numpunct<char> | |
| 1661 | class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> | |
| 1710 | 1662 | : public locale::facet |
| 1711 | 1663 | { |
| 1712 | 1664 | public: |
| ... | ... | @@ -1738,7 +1690,7 @@ protected: |
| 1738 | 1690 | |
| 1739 | 1691 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 1740 | 1692 | template <> |
| 1741 | class _LIBCPP_TYPE_VIS numpunct<wchar_t> | |
| 1693 | class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> | |
| 1742 | 1694 | : public locale::facet |
| 1743 | 1695 | { |
| 1744 | 1696 | public: |
| ... | ... | @@ -1774,7 +1726,7 @@ protected: |
| 1774 | 1726 | template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname; |
| 1775 | 1727 | |
| 1776 | 1728 | template <> |
| 1777 | class _LIBCPP_TYPE_VIS numpunct_byname<char> | |
| 1729 | class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> | |
| 1778 | 1730 | : public numpunct<char> |
| 1779 | 1731 | { |
| 1780 | 1732 | public: |
| ... | ... | @@ -1793,7 +1745,7 @@ private: |
| 1793 | 1745 | |
| 1794 | 1746 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 1795 | 1747 | template <> |
| 1796 | class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> | |
| 1748 | class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> | |
| 1797 | 1749 | : public numpunct<wchar_t> |
| 1798 | 1750 | { |
| 1799 | 1751 | public: |
lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_defaults.h created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // The BSDs have lots of *_l functions. We don't want to define those symbols | |
| 10 | // on other platforms though, for fear of conflicts with user code. So here, | |
| 11 | // we will define the mapping from an internal macro to the real BSD symbol. | |
| 12 | //===----------------------------------------------------------------------===// | |
| 13 | ||
| 14 | #ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H | |
| 15 | #define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | #define __libcpp_mb_cur_max_l(loc) MB_CUR_MAX_L(loc) | |
| 22 | #define __libcpp_btowc_l(ch, loc) btowc_l(ch, loc) | |
| 23 | #define __libcpp_wctob_l(wch, loc) wctob_l(wch, loc) | |
| 24 | #define __libcpp_wcsnrtombs_l(dst, src, nwc, len, ps, loc) wcsnrtombs_l(dst, src, nwc, len, ps, loc) | |
| 25 | #define __libcpp_wcrtomb_l(src, wc, ps, loc) wcrtomb_l(src, wc, ps, loc) | |
| 26 | #define __libcpp_mbsnrtowcs_l(dst, src, nms, len, ps, loc) mbsnrtowcs_l(dst, src, nms, len, ps, loc) | |
| 27 | #define __libcpp_mbrtowc_l(pwc, s, n, ps, l) mbrtowc_l(pwc, s, n, ps, l) | |
| 28 | #define __libcpp_mbtowc_l(pwc, pmb, max, l) mbtowc_l(pwc, pmb, max, l) | |
| 29 | #define __libcpp_mbrlen_l(s, n, ps, l) mbrlen_l(s, n, ps, l) | |
| 30 | #define __libcpp_localeconv_l(l) localeconv_l(l) | |
| 31 | #define __libcpp_mbsrtowcs_l(dest, src, len, ps, l) mbsrtowcs_l(dest, src, len, ps, l) | |
| 32 | #define __libcpp_snprintf_l(...) snprintf_l(__VA_ARGS__) | |
| 33 | #define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) | |
| 34 | #define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) | |
| 35 | ||
| 36 | #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H |
lib/libcxx/include/__locale_dir/locale_base_api/bsd_locale_fallbacks.h created+148| ... | ... | @@ -0,0 +1,148 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | // The BSDs have lots of *_l functions. This file provides reimplementations | |
| 10 | // of those functions for non-BSD platforms. | |
| 11 | //===----------------------------------------------------------------------===// | |
| 12 | ||
| 13 | #ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H | |
| 14 | #define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H | |
| 15 | ||
| 16 | #include <__locale_dir/locale_base_api/locale_guard.h> | |
| 17 | #include <cstdio> | |
| 18 | #include <stdarg.h> | |
| 19 | #include <stdlib.h> | |
| 20 | ||
| 21 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 22 | # include <cwchar> | |
| 23 | #endif | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | inline _LIBCPP_INLINE_VISIBILITY | |
| 32 | decltype(MB_CUR_MAX) __libcpp_mb_cur_max_l(locale_t __l) | |
| 33 | { | |
| 34 | __libcpp_locale_guard __current(__l); | |
| 35 | return MB_CUR_MAX; | |
| 36 | } | |
| 37 | ||
| 38 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 39 | inline _LIBCPP_INLINE_VISIBILITY | |
| 40 | wint_t __libcpp_btowc_l(int __c, locale_t __l) | |
| 41 | { | |
| 42 | __libcpp_locale_guard __current(__l); | |
| 43 | return btowc(__c); | |
| 44 | } | |
| 45 | ||
| 46 | inline _LIBCPP_INLINE_VISIBILITY | |
| 47 | int __libcpp_wctob_l(wint_t __c, locale_t __l) | |
| 48 | { | |
| 49 | __libcpp_locale_guard __current(__l); | |
| 50 | return wctob(__c); | |
| 51 | } | |
| 52 | ||
| 53 | inline _LIBCPP_INLINE_VISIBILITY | |
| 54 | size_t __libcpp_wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, | |
| 55 | size_t __len, mbstate_t *__ps, locale_t __l) | |
| 56 | { | |
| 57 | __libcpp_locale_guard __current(__l); | |
| 58 | return wcsnrtombs(__dest, __src, __nwc, __len, __ps); | |
| 59 | } | |
| 60 | ||
| 61 | inline _LIBCPP_INLINE_VISIBILITY | |
| 62 | size_t __libcpp_wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) | |
| 63 | { | |
| 64 | __libcpp_locale_guard __current(__l); | |
| 65 | return wcrtomb(__s, __wc, __ps); | |
| 66 | } | |
| 67 | ||
| 68 | inline _LIBCPP_INLINE_VISIBILITY | |
| 69 | size_t __libcpp_mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, | |
| 70 | size_t __len, mbstate_t *__ps, locale_t __l) | |
| 71 | { | |
| 72 | __libcpp_locale_guard __current(__l); | |
| 73 | return mbsnrtowcs(__dest, __src, __nms, __len, __ps); | |
| 74 | } | |
| 75 | ||
| 76 | inline _LIBCPP_INLINE_VISIBILITY | |
| 77 | size_t __libcpp_mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, | |
| 78 | mbstate_t *__ps, locale_t __l) | |
| 79 | { | |
| 80 | __libcpp_locale_guard __current(__l); | |
| 81 | return mbrtowc(__pwc, __s, __n, __ps); | |
| 82 | } | |
| 83 | ||
| 84 | inline _LIBCPP_INLINE_VISIBILITY | |
| 85 | int __libcpp_mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) | |
| 86 | { | |
| 87 | __libcpp_locale_guard __current(__l); | |
| 88 | return mbtowc(__pwc, __pmb, __max); | |
| 89 | } | |
| 90 | ||
| 91 | inline _LIBCPP_INLINE_VISIBILITY | |
| 92 | size_t __libcpp_mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) | |
| 93 | { | |
| 94 | __libcpp_locale_guard __current(__l); | |
| 95 | return mbrlen(__s, __n, __ps); | |
| 96 | } | |
| 97 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 98 | ||
| 99 | inline _LIBCPP_INLINE_VISIBILITY | |
| 100 | lconv *__libcpp_localeconv_l(locale_t __l) | |
| 101 | { | |
| 102 | __libcpp_locale_guard __current(__l); | |
| 103 | return localeconv(); | |
| 104 | } | |
| 105 | ||
| 106 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 107 | inline _LIBCPP_INLINE_VISIBILITY | |
| 108 | size_t __libcpp_mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, | |
| 109 | mbstate_t *__ps, locale_t __l) | |
| 110 | { | |
| 111 | __libcpp_locale_guard __current(__l); | |
| 112 | return mbsrtowcs(__dest, __src, __len, __ps); | |
| 113 | } | |
| 114 | #endif | |
| 115 | ||
| 116 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 4, 5) | |
| 117 | int __libcpp_snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { | |
| 118 | va_list __va; | |
| 119 | va_start(__va, __format); | |
| 120 | __libcpp_locale_guard __current(__l); | |
| 121 | int __res = vsnprintf(__s, __n, __format, __va); | |
| 122 | va_end(__va); | |
| 123 | return __res; | |
| 124 | } | |
| 125 | ||
| 126 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 127 | int __libcpp_asprintf_l(char **__s, locale_t __l, const char *__format, ...) { | |
| 128 | va_list __va; | |
| 129 | va_start(__va, __format); | |
| 130 | __libcpp_locale_guard __current(__l); | |
| 131 | int __res = vasprintf(__s, __format, __va); | |
| 132 | va_end(__va); | |
| 133 | return __res; | |
| 134 | } | |
| 135 | ||
| 136 | inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) | |
| 137 | int __libcpp_sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { | |
| 138 | va_list __va; | |
| 139 | va_start(__va, __format); | |
| 140 | __libcpp_locale_guard __current(__l); | |
| 141 | int __res = vsscanf(__s, __format, __va); | |
| 142 | va_end(__va); | |
| 143 | return __res; | |
| 144 | } | |
| 145 | ||
| 146 | _LIBCPP_END_NAMESPACE_STD | |
| 147 | ||
| 148 | #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H |
lib/libcxx/include/__locale_dir/locale_base_api/locale_guard.h created+79| ... | ... | @@ -0,0 +1,79 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H | |
| 10 | #define _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <clocale> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_LOCALE__L_EXTENSIONS) | |
| 22 | struct __libcpp_locale_guard { | |
| 23 | _LIBCPP_INLINE_VISIBILITY __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {} | |
| 24 | ||
| 25 | _LIBCPP_INLINE_VISIBILITY ~__libcpp_locale_guard() { | |
| 26 | if (__old_loc_) | |
| 27 | uselocale(__old_loc_); | |
| 28 | } | |
| 29 | ||
| 30 | locale_t __old_loc_; | |
| 31 | ||
| 32 | private: | |
| 33 | __libcpp_locale_guard(__libcpp_locale_guard const&); | |
| 34 | __libcpp_locale_guard& operator=(__libcpp_locale_guard const&); | |
| 35 | }; | |
| 36 | #elif defined(_LIBCPP_MSVCRT_LIKE) | |
| 37 | struct __libcpp_locale_guard { | |
| 38 | __libcpp_locale_guard(locale_t __l) : | |
| 39 | __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)) { | |
| 40 | // Setting the locale can be expensive even when the locale given is | |
| 41 | // already the current locale, so do an explicit check to see if the | |
| 42 | // current locale is already the one we want. | |
| 43 | const char* __lc = __setlocale(nullptr); | |
| 44 | // If every category is the same, the locale string will simply be the | |
| 45 | // locale name, otherwise it will be a semicolon-separated string listing | |
| 46 | // each category. In the second case, we know at least one category won't | |
| 47 | // be what we want, so we only have to check the first case. | |
| 48 | if (_VSTD::strcmp(__l.__get_locale(), __lc) != 0) { | |
| 49 | __locale_all = _strdup(__lc); | |
| 50 | if (__locale_all == nullptr) | |
| 51 | __throw_bad_alloc(); | |
| 52 | __setlocale(__l.__get_locale()); | |
| 53 | } | |
| 54 | } | |
| 55 | ~__libcpp_locale_guard() { | |
| 56 | // The CRT documentation doesn't explicitly say, but setlocale() does the | |
| 57 | // right thing when given a semicolon-separated list of locale settings | |
| 58 | // for the different categories in the same format as returned by | |
| 59 | // setlocale(LC_ALL, nullptr). | |
| 60 | if (__locale_all != nullptr) { | |
| 61 | __setlocale(__locale_all); | |
| 62 | free(__locale_all); | |
| 63 | } | |
| 64 | _configthreadlocale(__status); | |
| 65 | } | |
| 66 | static const char* __setlocale(const char* __locale) { | |
| 67 | const char* __new_locale = setlocale(LC_ALL, __locale); | |
| 68 | if (__new_locale == nullptr) | |
| 69 | __throw_bad_alloc(); | |
| 70 | return __new_locale; | |
| 71 | } | |
| 72 | int __status; | |
| 73 | char* __locale_all = nullptr; | |
| 74 | }; | |
| 75 | #endif | |
| 76 | ||
| 77 | _LIBCPP_END_NAMESPACE_STD | |
| 78 | ||
| 79 | #endif // _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H |
lib/libcxx/include/__mbstate_t.h+26-16| ... | ... | @@ -16,29 +16,39 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | // TODO(ldionne): | |
| 20 | // The goal of this header is to provide mbstate_t without having to pull in | |
| 21 | // <wchar.h> or <uchar.h>. This is necessary because we need that type even | |
| 22 | // when we don't have (or try to provide) support for wchar_t, because several | |
| 23 | // types like std::fpos are defined in terms of mbstate_t. | |
| 19 | // The goal of this header is to provide mbstate_t without requiring all of | |
| 20 | // <uchar.h> or <wchar.h>. It's also used by the libc++ versions of <uchar.h> | |
| 21 | // and <wchar.h> to get mbstate_t when the C library doesn't provide <uchar.h> | |
| 22 | // or <wchar.h>, hence the #include_next of those headers instead of #include. | |
| 23 | // (e.g. if <wchar.h> isn't present in the C library, the libc++ <wchar.h> | |
| 24 | // will include this header. This header needs to not turn around and cyclically | |
| 25 | // include <wchar.h>, but fall through to <uchar.h>.) | |
| 24 | 26 | // |
| 25 | // This is a gruesome hack, but I don't know how to make it cleaner for | |
| 26 | // the time being. | |
| 27 | // This does not define std::mbstate_t -- this only brings in the declaration | |
| 28 | // in the global namespace. | |
| 29 | ||
| 30 | // We define this here to support older versions of glibc <wchar.h> that do | |
| 31 | // not define this for clang. This is also set in libc++'s <wchar.h> header, | |
| 32 | // and we need to do so here too to avoid a different function signature given | |
| 33 | // a different include order. | |
| 34 | #ifdef __cplusplus | |
| 35 | # define __CORRECT_ISO_CPP_WCHAR_H_PROTO | |
| 36 | #endif | |
| 27 | 37 | |
| 28 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 29 | # include <wchar.h> // for mbstate_t | |
| 38 | #if defined(_LIBCPP_HAS_MUSL_LIBC) | |
| 39 | # define __NEED_mbstate_t | |
| 40 | # include <bits/alltypes.h> | |
| 41 | # undef __NEED_mbstate_t | |
| 30 | 42 | #elif __has_include(<bits/types/mbstate_t.h>) |
| 31 | 43 | # include <bits/types/mbstate_t.h> // works on most Unixes |
| 32 | 44 | #elif __has_include(<sys/_types/_mbstate_t.h>) |
| 33 | 45 | # include <sys/_types/_mbstate_t.h> // works on Darwin |
| 46 | #elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) && __has_include_next(<wchar.h>) | |
| 47 | # include_next <wchar.h> // fall back to the C standard provider of mbstate_t | |
| 48 | #elif __has_include_next(<uchar.h>) | |
| 49 | # include_next <uchar.h> // <uchar.h> is also required to make mbstate_t visible | |
| 34 | 50 | #else |
| 35 | # error "The library was configured without support for wide-characters, but we don't know how to get the definition of mbstate_t without <wchar.h> on your platform." | |
| 51 | # error "We don't know how to get the definition of mbstate_t without <wchar.h> on your platform." | |
| 36 | 52 | #endif |
| 37 | 53 | |
| 38 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 39 | ||
| 40 | using ::mbstate_t _LIBCPP_USING_IF_EXISTS; | |
| 41 | ||
| 42 | _LIBCPP_END_NAMESPACE_STD | |
| 43 | ||
| 44 | 54 | #endif // _LIBCPP___MBSTATE_T_H |
lib/libcxx/include/__mdspan/default_accessor.h created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H | |
| 18 | #define _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H | |
| 19 | ||
| 20 | #include <__config> | |
| 21 | #include <__type_traits/is_abstract.h> | |
| 22 | #include <__type_traits/is_array.h> | |
| 23 | #include <__type_traits/is_convertible.h> | |
| 24 | #include <__type_traits/remove_const.h> | |
| 25 | #include <cinttypes> | |
| 26 | #include <cstddef> | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 29 | # pragma GCC system_header | |
| 30 | #endif | |
| 31 | ||
| 32 | _LIBCPP_PUSH_MACROS | |
| 33 | #include <__undef_macros> | |
| 34 | ||
| 35 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 36 | ||
| 37 | #if _LIBCPP_STD_VER >= 23 | |
| 38 | ||
| 39 | template <class _ElementType> | |
| 40 | struct default_accessor { | |
| 41 | static_assert(!is_array_v<_ElementType>, "default_accessor: template argument may not be an array type"); | |
| 42 | static_assert(!is_abstract_v<_ElementType>, "default_accessor: template argument may not be an abstract class"); | |
| 43 | ||
| 44 | using offset_policy = default_accessor; | |
| 45 | using element_type = _ElementType; | |
| 46 | using reference = _ElementType&; | |
| 47 | using data_handle_type = _ElementType*; | |
| 48 | ||
| 49 | _LIBCPP_HIDE_FROM_ABI constexpr default_accessor() noexcept = default; | |
| 50 | template <class _OtherElementType> | |
| 51 | requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]>) | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr default_accessor(default_accessor<_OtherElementType>) noexcept {} | |
| 53 | ||
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr reference access(data_handle_type __p, size_t __i) const noexcept { return __p[__i]; } | |
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr data_handle_type offset(data_handle_type __p, size_t __i) const noexcept { | |
| 56 | return __p + __i; | |
| 57 | } | |
| 58 | }; | |
| 59 | ||
| 60 | #endif // _LIBCPP_STD_VER >= 23 | |
| 61 | ||
| 62 | _LIBCPP_END_NAMESPACE_STD | |
| 63 | ||
| 64 | _LIBCPP_POP_MACROS | |
| 65 | ||
| 66 | #endif // _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H |
lib/libcxx/include/__mdspan/extents.h created+519| ... | ... | @@ -0,0 +1,519 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_EXTENTS_H | |
| 18 | #define _LIBCPP___MDSPAN_EXTENTS_H | |
| 19 | ||
| 20 | #include <__assert> | |
| 21 | #include <__config> | |
| 22 | #include <__type_traits/common_type.h> | |
| 23 | #include <__type_traits/is_convertible.h> | |
| 24 | #include <__type_traits/is_nothrow_constructible.h> | |
| 25 | #include <__type_traits/is_same.h> | |
| 26 | #include <__type_traits/make_unsigned.h> | |
| 27 | #include <__utility/integer_sequence.h> | |
| 28 | #include <__utility/unreachable.h> | |
| 29 | #include <array> | |
| 30 | #include <cinttypes> | |
| 31 | #include <concepts> | |
| 32 | #include <cstddef> | |
| 33 | #include <limits> | |
| 34 | #include <span> | |
| 35 | ||
| 36 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 37 | # pragma GCC system_header | |
| 38 | #endif | |
| 39 | ||
| 40 | _LIBCPP_PUSH_MACROS | |
| 41 | #include <__undef_macros> | |
| 42 | ||
| 43 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 44 | ||
| 45 | #if _LIBCPP_STD_VER >= 23 | |
| 46 | ||
| 47 | namespace __mdspan_detail { | |
| 48 | ||
| 49 | // ------------------------------------------------------------------ | |
| 50 | // ------------ __static_array -------------------------------------- | |
| 51 | // ------------------------------------------------------------------ | |
| 52 | // array like class which provides an array of static values with get | |
| 53 | template <class _Tp, _Tp... _Values> | |
| 54 | struct __static_array { | |
| 55 | static constexpr array<_Tp, sizeof...(_Values)> __array = {_Values...}; | |
| 56 | ||
| 57 | public: | |
| 58 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return sizeof...(_Values); } | |
| 59 | _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get(size_t __index) noexcept { return __array[__index]; } | |
| 60 | ||
| 61 | template <size_t _Index> | |
| 62 | _LIBCPP_HIDE_FROM_ABI static constexpr _Tp __get() { | |
| 63 | return __get(_Index); | |
| 64 | } | |
| 65 | }; | |
| 66 | ||
| 67 | // ------------------------------------------------------------------ | |
| 68 | // ------------ __possibly_empty_array ----------------------------- | |
| 69 | // ------------------------------------------------------------------ | |
| 70 | ||
| 71 | // array like class which provides get function and operator [], and | |
| 72 | // has a specialization for the size 0 case. | |
| 73 | // This is needed to make the __maybe_static_array be truly empty, for | |
| 74 | // all static values. | |
| 75 | ||
| 76 | template <class _Tp, size_t _Size> | |
| 77 | struct __possibly_empty_array { | |
| 78 | _Tp __vals_[_Size]; | |
| 79 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t __index) { return __vals_[__index]; } | |
| 80 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t __index) const { return __vals_[__index]; } | |
| 81 | }; | |
| 82 | ||
| 83 | template <class _Tp> | |
| 84 | struct __possibly_empty_array<_Tp, 0> { | |
| 85 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator[](size_t) { __libcpp_unreachable(); } | |
| 86 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](size_t) const { __libcpp_unreachable(); } | |
| 87 | }; | |
| 88 | ||
| 89 | // ------------------------------------------------------------------ | |
| 90 | // ------------ static_partial_sums --------------------------------- | |
| 91 | // ------------------------------------------------------------------ | |
| 92 | ||
| 93 | // Provides a compile time partial sum one can index into | |
| 94 | ||
| 95 | template <size_t... _Values> | |
| 96 | struct __static_partial_sums { | |
| 97 | _LIBCPP_HIDE_FROM_ABI static constexpr array<size_t, sizeof...(_Values)> __static_partial_sums_impl() { | |
| 98 | array<size_t, sizeof...(_Values)> __values{_Values...}; | |
| 99 | array<size_t, sizeof...(_Values)> __partial_sums{{}}; | |
| 100 | size_t __running_sum = 0; | |
| 101 | for (int __i = 0; __i != sizeof...(_Values); ++__i) { | |
| 102 | __partial_sums[__i] = __running_sum; | |
| 103 | __running_sum += __values[__i]; | |
| 104 | } | |
| 105 | return __partial_sums; | |
| 106 | } | |
| 107 | static constexpr array<size_t, sizeof...(_Values)> __result{__static_partial_sums_impl()}; | |
| 108 | ||
| 109 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t __get(size_t __index) { return __result[__index]; } | |
| 110 | }; | |
| 111 | ||
| 112 | // ------------------------------------------------------------------ | |
| 113 | // ------------ __maybe_static_array -------------------------------- | |
| 114 | // ------------------------------------------------------------------ | |
| 115 | ||
| 116 | // array like class which has a mix of static and runtime values but | |
| 117 | // only stores the runtime values. | |
| 118 | // The type of the static and the runtime values can be different. | |
| 119 | // The position of a dynamic value is indicated through a tag value. | |
| 120 | template <class _TDynamic, class _TStatic, _TStatic _DynTag, _TStatic... _Values> | |
| 121 | struct __maybe_static_array { | |
| 122 | static_assert(is_convertible<_TStatic, _TDynamic>::value, | |
| 123 | "__maybe_static_array: _TStatic must be convertible to _TDynamic"); | |
| 124 | static_assert(is_convertible<_TDynamic, _TStatic>::value, | |
| 125 | "__maybe_static_array: _TDynamic must be convertible to _TStatic"); | |
| 126 | ||
| 127 | private: | |
| 128 | // Static values member | |
| 129 | static constexpr size_t __size_ = sizeof...(_Values); | |
| 130 | static constexpr size_t __size_dynamic_ = ((_Values == _DynTag) + ... + 0); | |
| 131 | using _StaticValues = __static_array<_TStatic, _Values...>; | |
| 132 | using _DynamicValues = __possibly_empty_array<_TDynamic, __size_dynamic_>; | |
| 133 | ||
| 134 | // Dynamic values member | |
| 135 | _LIBCPP_NO_UNIQUE_ADDRESS _DynamicValues __dyn_vals_; | |
| 136 | ||
| 137 | // static mapping of indices to the position in the dynamic values array | |
| 138 | using _DynamicIdxMap = __static_partial_sums<static_cast<size_t>(_Values == _DynTag)...>; | |
| 139 | ||
| 140 | template <size_t... Indices> | |
| 141 | _LIBCPP_HIDE_FROM_ABI static constexpr _DynamicValues __zeros(index_sequence<Indices...>) noexcept { | |
| 142 | return _DynamicValues{((void)Indices, 0)...}; | |
| 143 | } | |
| 144 | ||
| 145 | public: | |
| 146 | _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array() noexcept | |
| 147 | : __dyn_vals_{__zeros(make_index_sequence<__size_dynamic_>())} {} | |
| 148 | ||
| 149 | // constructors from dynamic values only -- this covers the case for rank() == 0 | |
| 150 | template <class... _DynVals> | |
| 151 | requires(sizeof...(_DynVals) == __size_dynamic_) | |
| 152 | _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) | |
| 153 | : __dyn_vals_{static_cast<_TDynamic>(__vals)...} {} | |
| 154 | ||
| 155 | template <class _Tp, size_t _Size > | |
| 156 | requires(_Size == __size_dynamic_) | |
| 157 | _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array([[maybe_unused]] const span<_Tp, _Size>& __vals) { | |
| 158 | if constexpr (_Size > 0) { | |
| 159 | for (size_t __i = 0; __i < _Size; __i++) | |
| 160 | __dyn_vals_[__i] = static_cast<_TDynamic>(__vals[__i]); | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 164 | // constructors from all values -- here rank will be greater than 0 | |
| 165 | template <class... _DynVals> | |
| 166 | requires(sizeof...(_DynVals) != __size_dynamic_) | |
| 167 | _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(_DynVals... __vals) { | |
| 168 | static_assert((sizeof...(_DynVals) == __size_), "Invalid number of values."); | |
| 169 | _TDynamic __values[__size_] = {static_cast<_TDynamic>(__vals)...}; | |
| 170 | for (size_t __i = 0; __i < __size_; __i++) { | |
| 171 | _TStatic __static_val = _StaticValues::__get(__i); | |
| 172 | if (__static_val == _DynTag) { | |
| 173 | __dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i]; | |
| 174 | } else | |
| 175 | // Not catching this could lead to out of bounds errors later | |
| 176 | // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5); | |
| 177 | // Right-hand-side construction looks ok with allocation and size matching, | |
| 178 | // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5 | |
| 179 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 180 | __values[__i] == static_cast<_TDynamic>(__static_val), | |
| 181 | "extents construction: mismatch of provided arguments with static extents."); | |
| 182 | } | |
| 183 | } | |
| 184 | ||
| 185 | template <class _Tp, size_t _Size> | |
| 186 | requires(_Size != __size_dynamic_) | |
| 187 | _LIBCPP_HIDE_FROM_ABI constexpr __maybe_static_array(const span<_Tp, _Size>& __vals) { | |
| 188 | static_assert((_Size == __size_) || (__size_ == dynamic_extent)); | |
| 189 | for (size_t __i = 0; __i < __size_; __i++) { | |
| 190 | _TStatic __static_val = _StaticValues::__get(__i); | |
| 191 | if (__static_val == _DynTag) { | |
| 192 | __dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]); | |
| 193 | } else | |
| 194 | // Not catching this could lead to out of bounds errors later | |
| 195 | // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N)); | |
| 196 | // Right-hand-side construction looks ok with allocation and size matching, | |
| 197 | // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N | |
| 198 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 199 | static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val), | |
| 200 | "extents construction: mismatch of provided arguments with static extents."); | |
| 201 | } | |
| 202 | } | |
| 203 | ||
| 204 | // access functions | |
| 205 | _LIBCPP_HIDE_FROM_ABI static constexpr _TStatic __static_value(size_t __i) noexcept { | |
| 206 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank"); | |
| 207 | return _StaticValues::__get(__i); | |
| 208 | } | |
| 209 | ||
| 210 | _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic __value(size_t __i) const { | |
| 211 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank"); | |
| 212 | _TStatic __static_val = _StaticValues::__get(__i); | |
| 213 | return __static_val == _DynTag ? __dyn_vals_[_DynamicIdxMap::__get(__i)] : static_cast<_TDynamic>(__static_val); | |
| 214 | } | |
| 215 | _LIBCPP_HIDE_FROM_ABI constexpr _TDynamic operator[](size_t __i) const { | |
| 216 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < __size_, "extents access: index must be less than rank"); | |
| 217 | return __value(__i); | |
| 218 | } | |
| 219 | ||
| 220 | // observers | |
| 221 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size() { return __size_; } | |
| 222 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t __size_dynamic() { return __size_dynamic_; } | |
| 223 | }; | |
| 224 | ||
| 225 | // Function to check whether a value is representable as another type | |
| 226 | // value must be a positive integer otherwise returns false | |
| 227 | // if _From is not an integral, we just check positivity | |
| 228 | template <integral _To, class _From> | |
| 229 | requires(integral<_From>) | |
| 230 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) { | |
| 231 | using _To_u = make_unsigned_t<_To>; | |
| 232 | using _From_u = make_unsigned_t<_From>; | |
| 233 | if constexpr (is_signed_v<_From>) { | |
| 234 | if (__value < 0) | |
| 235 | return false; | |
| 236 | } | |
| 237 | if constexpr (static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(numeric_limits<_From>::max())) { | |
| 238 | return true; | |
| 239 | } else { | |
| 240 | return static_cast<_To_u>(numeric_limits<_To>::max()) >= static_cast<_From_u>(__value); | |
| 241 | } | |
| 242 | } | |
| 243 | ||
| 244 | template <integral _To, class _From> | |
| 245 | requires(!integral<_From>) | |
| 246 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_representable_as(_From __value) { | |
| 247 | if constexpr (is_signed_v<_To>) { | |
| 248 | if (static_cast<_To>(__value) < 0) | |
| 249 | return false; | |
| 250 | } | |
| 251 | return true; | |
| 252 | } | |
| 253 | ||
| 254 | template <integral _To, class... _From> | |
| 255 | _LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(_From... __values) { | |
| 256 | return (__mdspan_detail::__is_representable_as<_To>(__values) && ... && true); | |
| 257 | } | |
| 258 | ||
| 259 | template <integral _To, class _From, size_t _Size> | |
| 260 | _LIBCPP_HIDE_FROM_ABI constexpr bool __are_representable_as(span<_From, _Size> __values) { | |
| 261 | for (size_t __i = 0; __i < _Size; __i++) | |
| 262 | if (!__mdspan_detail::__is_representable_as<_To>(__values[__i])) | |
| 263 | return false; | |
| 264 | return true; | |
| 265 | } | |
| 266 | ||
| 267 | } // namespace __mdspan_detail | |
| 268 | ||
| 269 | // ------------------------------------------------------------------ | |
| 270 | // ------------ extents --------------------------------------------- | |
| 271 | // ------------------------------------------------------------------ | |
| 272 | ||
| 273 | // Class to describe the extents of a multi dimensional array. | |
| 274 | // Used by mdspan, mdarray and layout mappings. | |
| 275 | // See ISO C++ standard [mdspan.extents] | |
| 276 | ||
| 277 | template <class _IndexType, size_t... _Extents> | |
| 278 | class extents { | |
| 279 | public: | |
| 280 | // typedefs for integral types used | |
| 281 | using index_type = _IndexType; | |
| 282 | using size_type = make_unsigned_t<index_type>; | |
| 283 | using rank_type = size_t; | |
| 284 | ||
| 285 | static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value, | |
| 286 | "extents::index_type must be a signed or unsigned integer type"); | |
| 287 | static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...), | |
| 288 | "extents ctor: arguments must be representable as index_type and nonnegative"); | |
| 289 | ||
| 290 | private: | |
| 291 | static constexpr rank_type __rank_ = sizeof...(_Extents); | |
| 292 | static constexpr rank_type __rank_dynamic_ = ((_Extents == dynamic_extent) + ... + 0); | |
| 293 | ||
| 294 | // internal storage type using __maybe_static_array | |
| 295 | using _Values = __mdspan_detail::__maybe_static_array<_IndexType, size_t, dynamic_extent, _Extents...>; | |
| 296 | [[no_unique_address]] _Values __vals_; | |
| 297 | ||
| 298 | public: | |
| 299 | // [mdspan.extents.obs], observers of multidimensional index space | |
| 300 | _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return __rank_; } | |
| 301 | _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return __rank_dynamic_; } | |
| 302 | ||
| 303 | _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { return __vals_.__value(__r); } | |
| 304 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { | |
| 305 | return _Values::__static_value(__r); | |
| 306 | } | |
| 307 | ||
| 308 | // [mdspan.extents.cons], constructors | |
| 309 | _LIBCPP_HIDE_FROM_ABI constexpr extents() noexcept = default; | |
| 310 | ||
| 311 | // Construction from just dynamic or all values. | |
| 312 | // Precondition check is deferred to __maybe_static_array constructor | |
| 313 | template <class... _OtherIndexTypes> | |
| 314 | requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && | |
| 315 | (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && | |
| 316 | (sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_)) | |
| 317 | _LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept | |
| 318 | : __vals_(static_cast<index_type>(__dynvals)...) { | |
| 319 | // Not catching this could lead to out of bounds errors later | |
| 320 | // e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m | |
| 321 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...), | |
| 322 | "extents ctor: arguments must be representable as index_type and nonnegative"); | |
| 323 | } | |
| 324 | ||
| 325 | template <class _OtherIndexType, size_t _Size> | |
| 326 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 327 | is_nothrow_constructible_v<index_type, const _OtherIndexType&> && | |
| 328 | (_Size == __rank_ || _Size == __rank_dynamic_)) | |
| 329 | explicit(_Size != __rank_dynamic_) | |
| 330 | _LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept | |
| 331 | : __vals_(span(__exts)) { | |
| 332 | // Not catching this could lead to out of bounds errors later | |
| 333 | // e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m | |
| 334 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)), | |
| 335 | "extents ctor: arguments must be representable as index_type and nonnegative"); | |
| 336 | } | |
| 337 | ||
| 338 | template <class _OtherIndexType, size_t _Size> | |
| 339 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 340 | is_nothrow_constructible_v<index_type, const _OtherIndexType&> && | |
| 341 | (_Size == __rank_ || _Size == __rank_dynamic_)) | |
| 342 | explicit(_Size != __rank_dynamic_) | |
| 343 | _LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept | |
| 344 | : __vals_(__exts) { | |
| 345 | // Not catching this could lead to out of bounds errors later | |
| 346 | // e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56 | |
| 347 | // on m | |
| 348 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts), | |
| 349 | "extents ctor: arguments must be representable as index_type and nonnegative"); | |
| 350 | } | |
| 351 | ||
| 352 | private: | |
| 353 | // Function to construct extents storage from other extents. | |
| 354 | template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues> | |
| 355 | requires(_Idx < __rank_) | |
| 356 | _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents( | |
| 357 | integral_constant<size_t, _DynCount>, | |
| 358 | integral_constant<size_t, _Idx>, | |
| 359 | const _OtherExtents& __exts, | |
| 360 | _DynamicValues... __dynamic_values) noexcept { | |
| 361 | if constexpr (static_extent(_Idx) == dynamic_extent) | |
| 362 | return __construct_vals_from_extents( | |
| 363 | integral_constant<size_t, _DynCount + 1>(), | |
| 364 | integral_constant<size_t, _Idx + 1>(), | |
| 365 | __exts, | |
| 366 | __dynamic_values..., | |
| 367 | __exts.extent(_Idx)); | |
| 368 | else | |
| 369 | return __construct_vals_from_extents( | |
| 370 | integral_constant<size_t, _DynCount>(), integral_constant<size_t, _Idx + 1>(), __exts, __dynamic_values...); | |
| 371 | } | |
| 372 | ||
| 373 | template <size_t _DynCount, size_t _Idx, class _OtherExtents, class... _DynamicValues> | |
| 374 | requires((_Idx == __rank_) && (_DynCount == __rank_dynamic_)) | |
| 375 | _LIBCPP_HIDE_FROM_ABI constexpr _Values __construct_vals_from_extents( | |
| 376 | integral_constant<size_t, _DynCount>, | |
| 377 | integral_constant<size_t, _Idx>, | |
| 378 | const _OtherExtents&, | |
| 379 | _DynamicValues... __dynamic_values) noexcept { | |
| 380 | return _Values{static_cast<index_type>(__dynamic_values)...}; | |
| 381 | } | |
| 382 | ||
| 383 | public: | |
| 384 | // Converting constructor from other extents specializations | |
| 385 | template <class _OtherIndexType, size_t... _OtherExtents> | |
| 386 | requires((sizeof...(_OtherExtents) == sizeof...(_Extents)) && | |
| 387 | ((_OtherExtents == dynamic_extent || _Extents == dynamic_extent || _OtherExtents == _Extents) && ...)) | |
| 388 | explicit((((_Extents != dynamic_extent) && (_OtherExtents == dynamic_extent)) || ...) || | |
| 389 | (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) < | |
| 390 | static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max()))) | |
| 391 | _LIBCPP_HIDE_FROM_ABI constexpr extents(const extents<_OtherIndexType, _OtherExtents...>& __other) noexcept | |
| 392 | : __vals_( | |
| 393 | __construct_vals_from_extents(integral_constant<size_t, 0>(), integral_constant<size_t, 0>(), __other)) { | |
| 394 | if constexpr (rank() > 0) { | |
| 395 | for (size_t __r = 0; __r < rank(); __r++) { | |
| 396 | if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) < | |
| 397 | static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) { | |
| 398 | // Not catching this could lead to out of bounds errors later | |
| 399 | // e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e | |
| 400 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 401 | __mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)), | |
| 402 | "extents ctor: arguments must be representable as index_type and nonnegative"); | |
| 403 | } | |
| 404 | // Not catching this could lead to out of bounds errors later | |
| 405 | // e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5); | |
| 406 | // Right-hand-side construction was ok, but m now thinks its range is 10 not 5 | |
| 407 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 408 | (_Values::__static_value(__r) == dynamic_extent) || | |
| 409 | (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))), | |
| 410 | "extents construction: mismatch of provided arguments with static extents."); | |
| 411 | } | |
| 412 | } | |
| 413 | } | |
| 414 | ||
| 415 | // Comparison operator | |
| 416 | template <class _OtherIndexType, size_t... _OtherExtents> | |
| 417 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool | |
| 418 | operator==(const extents& __lhs, const extents<_OtherIndexType, _OtherExtents...>& __rhs) noexcept { | |
| 419 | if constexpr (rank() != sizeof...(_OtherExtents)) { | |
| 420 | return false; | |
| 421 | } else { | |
| 422 | for (rank_type __r = 0; __r < __rank_; __r++) { | |
| 423 | // avoid warning when comparing signed and unsigner integers and pick the wider of two types | |
| 424 | using _CommonType = common_type_t<index_type, _OtherIndexType>; | |
| 425 | if (static_cast<_CommonType>(__lhs.extent(__r)) != static_cast<_CommonType>(__rhs.extent(__r))) { | |
| 426 | return false; | |
| 427 | } | |
| 428 | } | |
| 429 | } | |
| 430 | return true; | |
| 431 | } | |
| 432 | }; | |
| 433 | ||
| 434 | // Recursive helper classes to implement dextents alias for extents | |
| 435 | namespace __mdspan_detail { | |
| 436 | ||
| 437 | template <class _IndexType, size_t _Rank, class _Extents = extents<_IndexType>> | |
| 438 | struct __make_dextents; | |
| 439 | ||
| 440 | template <class _IndexType, size_t _Rank, size_t... _ExtentsPack> | |
| 441 | struct __make_dextents< _IndexType, _Rank, extents<_IndexType, _ExtentsPack...>> { | |
| 442 | using type = | |
| 443 | typename __make_dextents< _IndexType, _Rank - 1, extents<_IndexType, dynamic_extent, _ExtentsPack...>>::type; | |
| 444 | }; | |
| 445 | ||
| 446 | template <class _IndexType, size_t... _ExtentsPack> | |
| 447 | struct __make_dextents< _IndexType, 0, extents<_IndexType, _ExtentsPack...>> { | |
| 448 | using type = extents<_IndexType, _ExtentsPack...>; | |
| 449 | }; | |
| 450 | ||
| 451 | } // end namespace __mdspan_detail | |
| 452 | ||
| 453 | // [mdspan.extents.dextents], alias template | |
| 454 | template <class _IndexType, size_t _Rank> | |
| 455 | using dextents = typename __mdspan_detail::__make_dextents<_IndexType, _Rank>::type; | |
| 456 | ||
| 457 | // Deduction guide for extents | |
| 458 | template <class... _IndexTypes> | |
| 459 | extents(_IndexTypes...) -> extents<size_t, size_t((_IndexTypes(), dynamic_extent))...>; | |
| 460 | ||
| 461 | namespace __mdspan_detail { | |
| 462 | ||
| 463 | // Helper type traits for identifying a class as extents. | |
| 464 | template <class _Tp> | |
| 465 | struct __is_extents : false_type {}; | |
| 466 | ||
| 467 | template <class _IndexType, size_t... _ExtentsPack> | |
| 468 | struct __is_extents<extents<_IndexType, _ExtentsPack...>> : true_type {}; | |
| 469 | ||
| 470 | template <class _Tp> | |
| 471 | inline constexpr bool __is_extents_v = __is_extents<_Tp>::value; | |
| 472 | ||
| 473 | // Function to check whether a set of indices are a multidimensional | |
| 474 | // index into extents. This is a word of power in the C++ standard | |
| 475 | // requiring that the indices are larger than 0 and smaller than | |
| 476 | // the respective extents. | |
| 477 | ||
| 478 | template <integral _IndexType, class _From> | |
| 479 | requires(integral<_From>) | |
| 480 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) { | |
| 481 | if constexpr (is_signed_v<_From>) { | |
| 482 | if (__value < 0) | |
| 483 | return false; | |
| 484 | } | |
| 485 | using _Tp = common_type_t<_IndexType, _From>; | |
| 486 | return static_cast<_Tp>(__value) < static_cast<_Tp>(__extent); | |
| 487 | } | |
| 488 | ||
| 489 | template <integral _IndexType, class _From> | |
| 490 | requires(!integral<_From>) | |
| 491 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_index_in_extent(_IndexType __extent, _From __value) { | |
| 492 | if constexpr (is_signed_v<_IndexType>) { | |
| 493 | if (static_cast<_IndexType>(__value) < 0) | |
| 494 | return false; | |
| 495 | } | |
| 496 | return static_cast<_IndexType>(__value) < __extent; | |
| 497 | } | |
| 498 | ||
| 499 | template <size_t... _Idxs, class _Extents, class... _From> | |
| 500 | _LIBCPP_HIDE_FROM_ABI constexpr bool | |
| 501 | __is_multidimensional_index_in_impl(index_sequence<_Idxs...>, const _Extents& __ext, _From... __values) { | |
| 502 | return (__mdspan_detail::__is_index_in_extent(__ext.extent(_Idxs), __values) && ...); | |
| 503 | } | |
| 504 | ||
| 505 | template <class _Extents, class... _From> | |
| 506 | _LIBCPP_HIDE_FROM_ABI constexpr bool __is_multidimensional_index_in(const _Extents& __ext, _From... __values) { | |
| 507 | return __mdspan_detail::__is_multidimensional_index_in_impl( | |
| 508 | make_index_sequence<_Extents::rank()>(), __ext, __values...); | |
| 509 | } | |
| 510 | ||
| 511 | } // namespace __mdspan_detail | |
| 512 | ||
| 513 | #endif // _LIBCPP_STD_VER >= 23 | |
| 514 | ||
| 515 | _LIBCPP_END_NAMESPACE_STD | |
| 516 | ||
| 517 | _LIBCPP_POP_MACROS | |
| 518 | ||
| 519 | #endif // _LIBCPP___MDSPAN_EXTENTS_H |
lib/libcxx/include/__mdspan/layout_left.h created+189| ... | ... | @@ -0,0 +1,189 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_LAYOUT_LEFT_H | |
| 18 | #define _LIBCPP___MDSPAN_LAYOUT_LEFT_H | |
| 19 | ||
| 20 | #include <__assert> | |
| 21 | #include <__config> | |
| 22 | #include <__fwd/mdspan.h> | |
| 23 | #include <__mdspan/extents.h> | |
| 24 | #include <__type_traits/is_constructible.h> | |
| 25 | #include <__type_traits/is_convertible.h> | |
| 26 | #include <__type_traits/is_nothrow_constructible.h> | |
| 27 | #include <__utility/integer_sequence.h> | |
| 28 | #include <array> | |
| 29 | #include <cinttypes> | |
| 30 | #include <cstddef> | |
| 31 | #include <limits> | |
| 32 | ||
| 33 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 34 | # pragma GCC system_header | |
| 35 | #endif | |
| 36 | ||
| 37 | _LIBCPP_PUSH_MACROS | |
| 38 | #include <__undef_macros> | |
| 39 | ||
| 40 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 41 | ||
| 42 | #if _LIBCPP_STD_VER >= 23 | |
| 43 | ||
| 44 | template <class _Extents> | |
| 45 | class layout_left::mapping { | |
| 46 | public: | |
| 47 | static_assert(__mdspan_detail::__is_extents<_Extents>::value, | |
| 48 | "layout_left::mapping template argument must be a specialization of extents."); | |
| 49 | ||
| 50 | using extents_type = _Extents; | |
| 51 | using index_type = typename extents_type::index_type; | |
| 52 | using size_type = typename extents_type::size_type; | |
| 53 | using rank_type = typename extents_type::rank_type; | |
| 54 | using layout_type = layout_left; | |
| 55 | ||
| 56 | private: | |
| 57 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) { | |
| 58 | if constexpr (extents_type::rank() == 0) | |
| 59 | return true; | |
| 60 | ||
| 61 | index_type __prod = __ext.extent(0); | |
| 62 | for (rank_type __r = 1; __r < extents_type::rank(); __r++) { | |
| 63 | bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod); | |
| 64 | if (__overflowed) | |
| 65 | return false; | |
| 66 | } | |
| 67 | return true; | |
| 68 | } | |
| 69 | ||
| 70 | static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()), | |
| 71 | "layout_left::mapping product of static extents must be representable as index_type."); | |
| 72 | ||
| 73 | public: | |
| 74 | // [mdspan.layout.left.cons], constructors | |
| 75 | _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default; | |
| 76 | _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default; | |
| 77 | _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) { | |
| 78 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 79 | // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(10, 3) == -126 | |
| 80 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 81 | __required_span_size_is_representable(__ext), | |
| 82 | "layout_left::mapping extents ctor: product of extents must be representable as index_type."); | |
| 83 | } | |
| 84 | ||
| 85 | template <class _OtherExtents> | |
| 86 | requires(is_constructible_v<extents_type, _OtherExtents>) | |
| 87 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) | |
| 88 | mapping(const mapping<_OtherExtents>& __other) noexcept | |
| 89 | : __extents_(__other.extents()) { | |
| 90 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 91 | // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(10, 3) == -126 | |
| 92 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 93 | __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()), | |
| 94 | "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type."); | |
| 95 | } | |
| 96 | ||
| 97 | template <class _OtherExtents> | |
| 98 | requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1) | |
| 99 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) | |
| 100 | mapping(const layout_right::mapping<_OtherExtents>& __other) noexcept | |
| 101 | : __extents_(__other.extents()) { | |
| 102 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 103 | // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first | |
| 104 | // and thus this assertion should never be triggered, but keeping it here for consistency | |
| 105 | // layout_left::mapping<dextents<char, 1>> map( | |
| 106 | // layout_right::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) == | |
| 107 | // -56 | |
| 108 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 109 | __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()), | |
| 110 | "layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type."); | |
| 111 | } | |
| 112 | ||
| 113 | // FIXME: add when we add other layouts | |
| 114 | # if 0 | |
| 115 | template<class _OtherExtents> | |
| 116 | constexpr explicit(extents_type::rank() > 0) | |
| 117 | mapping(const layout_stride::mapping_<OtherExtents>&) noexcept; | |
| 118 | # endif | |
| 119 | ||
| 120 | _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default; | |
| 121 | ||
| 122 | // [mdspan.layout.left.obs], observers | |
| 123 | _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; } | |
| 124 | ||
| 125 | _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept { | |
| 126 | index_type __size = 1; | |
| 127 | for (size_t __r = 0; __r < extents_type::rank(); __r++) | |
| 128 | __size *= __extents_.extent(__r); | |
| 129 | return __size; | |
| 130 | } | |
| 131 | ||
| 132 | template <class... _Indices> | |
| 133 | requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) && | |
| 134 | (is_nothrow_constructible_v<index_type, _Indices> && ...)) | |
| 135 | _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept { | |
| 136 | // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never | |
| 137 | // return a value exceeding required_span_size(), which is used to know how large an allocation one needs | |
| 138 | // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks | |
| 139 | // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode | |
| 140 | _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...), | |
| 141 | "layout_left::mapping: out of bounds indexing"); | |
| 142 | array<index_type, extents_type::rank()> __idx_a{static_cast<index_type>(__idx)...}; | |
| 143 | return [&]<size_t... _Pos>(index_sequence<_Pos...>) { | |
| 144 | index_type __res = 0; | |
| 145 | ((__res = __idx_a[extents_type::rank() - 1 - _Pos] + __extents_.extent(extents_type::rank() - 1 - _Pos) * __res), | |
| 146 | ...); | |
| 147 | return __res; | |
| 148 | }(make_index_sequence<sizeof...(_Indices)>()); | |
| 149 | } | |
| 150 | ||
| 151 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; } | |
| 152 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; } | |
| 153 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; } | |
| 154 | ||
| 155 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; } | |
| 156 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; } | |
| 157 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; } | |
| 158 | ||
| 159 | _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept | |
| 160 | requires(extents_type::rank() > 0) | |
| 161 | { | |
| 162 | // While it would be caught by extents itself too, using a too large __r | |
| 163 | // is functionally an out of bounds access on the stored information needed to compute strides | |
| 164 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 165 | __r < extents_type::rank(), "layout_left::mapping::stride(): invalid rank index"); | |
| 166 | index_type __s = 1; | |
| 167 | for (rank_type __i = 0; __i < __r; __i++) | |
| 168 | __s *= __extents_.extent(__i); | |
| 169 | return __s; | |
| 170 | } | |
| 171 | ||
| 172 | template <class _OtherExtents> | |
| 173 | requires(_OtherExtents::rank() == extents_type::rank()) | |
| 174 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool | |
| 175 | operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept { | |
| 176 | return __lhs.extents() == __rhs.extents(); | |
| 177 | } | |
| 178 | ||
| 179 | private: | |
| 180 | _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{}; | |
| 181 | }; | |
| 182 | ||
| 183 | #endif // _LIBCPP_STD_VER >= 23 | |
| 184 | ||
| 185 | _LIBCPP_END_NAMESPACE_STD | |
| 186 | ||
| 187 | _LIBCPP_POP_MACROS | |
| 188 | ||
| 189 | #endif // _LIBCPP___MDSPAN_LAYOUT_LEFT_H |
lib/libcxx/include/__mdspan/layout_right.h created+186| ... | ... | @@ -0,0 +1,186 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_LAYOUT_RIGHT_H | |
| 18 | #define _LIBCPP___MDSPAN_LAYOUT_RIGHT_H | |
| 19 | ||
| 20 | #include <__assert> | |
| 21 | #include <__config> | |
| 22 | #include <__fwd/mdspan.h> | |
| 23 | #include <__mdspan/extents.h> | |
| 24 | #include <__type_traits/is_constructible.h> | |
| 25 | #include <__type_traits/is_convertible.h> | |
| 26 | #include <__type_traits/is_nothrow_constructible.h> | |
| 27 | #include <__utility/integer_sequence.h> | |
| 28 | #include <cinttypes> | |
| 29 | #include <cstddef> | |
| 30 | #include <limits> | |
| 31 | ||
| 32 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 33 | # pragma GCC system_header | |
| 34 | #endif | |
| 35 | ||
| 36 | _LIBCPP_PUSH_MACROS | |
| 37 | #include <__undef_macros> | |
| 38 | ||
| 39 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 40 | ||
| 41 | #if _LIBCPP_STD_VER >= 23 | |
| 42 | ||
| 43 | template <class _Extents> | |
| 44 | class layout_right::mapping { | |
| 45 | public: | |
| 46 | static_assert(__mdspan_detail::__is_extents<_Extents>::value, | |
| 47 | "layout_right::mapping template argument must be a specialization of extents."); | |
| 48 | ||
| 49 | using extents_type = _Extents; | |
| 50 | using index_type = typename extents_type::index_type; | |
| 51 | using size_type = typename extents_type::size_type; | |
| 52 | using rank_type = typename extents_type::rank_type; | |
| 53 | using layout_type = layout_right; | |
| 54 | ||
| 55 | private: | |
| 56 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __required_span_size_is_representable(const extents_type& __ext) { | |
| 57 | if constexpr (extents_type::rank() == 0) | |
| 58 | return true; | |
| 59 | ||
| 60 | index_type __prod = __ext.extent(0); | |
| 61 | for (rank_type __r = 1; __r < extents_type::rank(); __r++) { | |
| 62 | bool __overflowed = __builtin_mul_overflow(__prod, __ext.extent(__r), &__prod); | |
| 63 | if (__overflowed) | |
| 64 | return false; | |
| 65 | } | |
| 66 | return true; | |
| 67 | } | |
| 68 | ||
| 69 | static_assert((extents_type::rank_dynamic() > 0) || __required_span_size_is_representable(extents_type()), | |
| 70 | "layout_right::mapping product of static extents must be representable as index_type."); | |
| 71 | ||
| 72 | public: | |
| 73 | // [mdspan.layout.right.cons], constructors | |
| 74 | _LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default; | |
| 75 | _LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default; | |
| 76 | _LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) { | |
| 77 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 78 | // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(3, 10) == -126 | |
| 79 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 80 | __required_span_size_is_representable(__ext), | |
| 81 | "layout_right::mapping extents ctor: product of extents must be representable as index_type."); | |
| 82 | } | |
| 83 | ||
| 84 | template <class _OtherExtents> | |
| 85 | requires(is_constructible_v<extents_type, _OtherExtents>) | |
| 86 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) | |
| 87 | mapping(const mapping<_OtherExtents>& __other) noexcept | |
| 88 | : __extents_(__other.extents()) { | |
| 89 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 90 | // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(3, 10) == -126 | |
| 91 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 92 | __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()), | |
| 93 | "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type."); | |
| 94 | } | |
| 95 | ||
| 96 | template <class _OtherExtents> | |
| 97 | requires(is_constructible_v<extents_type, _OtherExtents> && _OtherExtents::rank() <= 1) | |
| 98 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>) | |
| 99 | mapping(const layout_left::mapping<_OtherExtents>& __other) noexcept | |
| 100 | : __extents_(__other.extents()) { | |
| 101 | // not catching this could lead to out-of-bounds access later when used inside mdspan | |
| 102 | // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first | |
| 103 | // and thus this assertion should never be triggered, but keeping it here for consistency | |
| 104 | // layout_right::mapping<dextents<char, 1>> map( | |
| 105 | // layout_left::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) == | |
| 106 | // -56 | |
| 107 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 108 | __mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()), | |
| 109 | "layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type."); | |
| 110 | } | |
| 111 | ||
| 112 | // FIXME: add when we add other layouts | |
| 113 | # if 0 | |
| 114 | template<class _OtherExtents> | |
| 115 | constexpr explicit(extents_type::rank() > 0) | |
| 116 | mapping(const layout_stride::mapping_<OtherExtents>&) noexcept; | |
| 117 | # endif | |
| 118 | ||
| 119 | _LIBCPP_HIDE_FROM_ABI constexpr mapping& operator=(const mapping&) noexcept = default; | |
| 120 | ||
| 121 | // [mdspan.layout.right.obs], observers | |
| 122 | _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __extents_; } | |
| 123 | ||
| 124 | _LIBCPP_HIDE_FROM_ABI constexpr index_type required_span_size() const noexcept { | |
| 125 | index_type __size = 1; | |
| 126 | for (size_t __r = 0; __r < extents_type::rank(); __r++) | |
| 127 | __size *= __extents_.extent(__r); | |
| 128 | return __size; | |
| 129 | } | |
| 130 | ||
| 131 | template <class... _Indices> | |
| 132 | requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) && | |
| 133 | (is_nothrow_constructible_v<index_type, _Indices> && ...)) | |
| 134 | _LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept { | |
| 135 | // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never | |
| 136 | // return a value exceeding required_span_size(), which is used to know how large an allocation one needs | |
| 137 | // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks | |
| 138 | // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode | |
| 139 | _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...), | |
| 140 | "layout_right::mapping: out of bounds indexing"); | |
| 141 | return [&]<size_t... _Pos>(index_sequence<_Pos...>) { | |
| 142 | index_type __res = 0; | |
| 143 | ((__res = static_cast<index_type>(__idx) + __extents_.extent(_Pos) * __res), ...); | |
| 144 | return __res; | |
| 145 | }(make_index_sequence<sizeof...(_Indices)>()); | |
| 146 | } | |
| 147 | ||
| 148 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return true; } | |
| 149 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept { return true; } | |
| 150 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept { return true; } | |
| 151 | ||
| 152 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_unique() noexcept { return true; } | |
| 153 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_exhaustive() noexcept { return true; } | |
| 154 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_strided() noexcept { return true; } | |
| 155 | ||
| 156 | _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept | |
| 157 | requires(extents_type::rank() > 0) | |
| 158 | { | |
| 159 | // While it would be caught by extents itself too, using a too large __r | |
| 160 | // is functionally an out of bounds access on the stored information needed to compute strides | |
| 161 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 162 | __r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index"); | |
| 163 | index_type __s = 1; | |
| 164 | for (rank_type __i = extents_type::rank() - 1; __i > __r; __i--) | |
| 165 | __s *= __extents_.extent(__i); | |
| 166 | return __s; | |
| 167 | } | |
| 168 | ||
| 169 | template <class _OtherExtents> | |
| 170 | requires(_OtherExtents::rank() == extents_type::rank()) | |
| 171 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool | |
| 172 | operator==(const mapping& __lhs, const mapping<_OtherExtents>& __rhs) noexcept { | |
| 173 | return __lhs.extents() == __rhs.extents(); | |
| 174 | } | |
| 175 | ||
| 176 | private: | |
| 177 | _LIBCPP_NO_UNIQUE_ADDRESS extents_type __extents_{}; | |
| 178 | }; | |
| 179 | ||
| 180 | #endif // _LIBCPP_STD_VER >= 23 | |
| 181 | ||
| 182 | _LIBCPP_END_NAMESPACE_STD | |
| 183 | ||
| 184 | _LIBCPP_POP_MACROS | |
| 185 | ||
| 186 | #endif // _LIBCPP___MDSPAN_LAYOUT_RIGHT_H |
lib/libcxx/include/__mdspan/mdspan.h created+308| ... | ... | @@ -0,0 +1,308 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | // Kokkos v. 4.0 | |
| 9 | // Copyright (2022) National Technology & Engineering | |
| 10 | // Solutions of Sandia, LLC (NTESS). | |
| 11 | // | |
| 12 | // Under the terms of Contract DE-NA0003525 with NTESS, | |
| 13 | // the U.S. Government retains certain rights in this software. | |
| 14 | // | |
| 15 | //===---------------------------------------------------------------------===// | |
| 16 | ||
| 17 | #ifndef _LIBCPP___MDSPAN_MDSPAN_H | |
| 18 | #define _LIBCPP___MDSPAN_MDSPAN_H | |
| 19 | ||
| 20 | #include <__assert> | |
| 21 | #include <__config> | |
| 22 | #include <__fwd/mdspan.h> | |
| 23 | #include <__mdspan/default_accessor.h> | |
| 24 | #include <__mdspan/extents.h> | |
| 25 | #include <__type_traits/extent.h> | |
| 26 | #include <__type_traits/is_abstract.h> | |
| 27 | #include <__type_traits/is_array.h> | |
| 28 | #include <__type_traits/is_constructible.h> | |
| 29 | #include <__type_traits/is_convertible.h> | |
| 30 | #include <__type_traits/is_default_constructible.h> | |
| 31 | #include <__type_traits/is_nothrow_constructible.h> | |
| 32 | #include <__type_traits/is_pointer.h> | |
| 33 | #include <__type_traits/is_same.h> | |
| 34 | #include <__type_traits/rank.h> | |
| 35 | #include <__type_traits/remove_all_extents.h> | |
| 36 | #include <__type_traits/remove_cv.h> | |
| 37 | #include <__type_traits/remove_pointer.h> | |
| 38 | #include <__type_traits/remove_reference.h> | |
| 39 | #include <__utility/integer_sequence.h> | |
| 40 | #include <array> | |
| 41 | #include <cinttypes> | |
| 42 | #include <cstddef> | |
| 43 | #include <limits> | |
| 44 | #include <span> | |
| 45 | ||
| 46 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 47 | # pragma GCC system_header | |
| 48 | #endif | |
| 49 | ||
| 50 | _LIBCPP_PUSH_MACROS | |
| 51 | #include <__undef_macros> | |
| 52 | ||
| 53 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 54 | ||
| 55 | #if _LIBCPP_STD_VER >= 23 | |
| 56 | ||
| 57 | // Helper for lightweight test checking that one did pass a layout policy as LayoutPolicy template argument | |
| 58 | namespace __mdspan_detail { | |
| 59 | template <class _Layout, class _Extents> | |
| 60 | concept __has_invalid_mapping = !requires { typename _Layout::template mapping<_Extents>; }; | |
| 61 | } // namespace __mdspan_detail | |
| 62 | ||
| 63 | template <class _ElementType, | |
| 64 | class _Extents, | |
| 65 | class _LayoutPolicy = layout_right, | |
| 66 | class _AccessorPolicy = default_accessor<_ElementType> > | |
| 67 | class mdspan { | |
| 68 | private: | |
| 69 | static_assert(__mdspan_detail::__is_extents_v<_Extents>, | |
| 70 | "mdspan: Extents template parameter must be a specialization of extents."); | |
| 71 | static_assert(!is_array_v<_ElementType>, "mdspan: ElementType template parameter may not be an array type"); | |
| 72 | static_assert(!is_abstract_v<_ElementType>, "mdspan: ElementType template parameter may not be an abstract class"); | |
| 73 | static_assert(is_same_v<_ElementType, typename _AccessorPolicy::element_type>, | |
| 74 | "mdspan: ElementType template parameter must match AccessorPolicy::element_type"); | |
| 75 | static_assert(!__mdspan_detail::__has_invalid_mapping<_LayoutPolicy, _Extents>, | |
| 76 | "mdspan: LayoutPolicy template parameter is invalid. A common mistake is to pass a layout mapping " | |
| 77 | "instead of a layout policy"); | |
| 78 | ||
| 79 | public: | |
| 80 | using extents_type = _Extents; | |
| 81 | using layout_type = _LayoutPolicy; | |
| 82 | using accessor_type = _AccessorPolicy; | |
| 83 | using mapping_type = typename layout_type::template mapping<extents_type>; | |
| 84 | using element_type = _ElementType; | |
| 85 | using value_type = remove_cv_t<element_type>; | |
| 86 | using index_type = typename extents_type::index_type; | |
| 87 | using size_type = typename extents_type::size_type; | |
| 88 | using rank_type = typename extents_type::rank_type; | |
| 89 | using data_handle_type = typename accessor_type::data_handle_type; | |
| 90 | using reference = typename accessor_type::reference; | |
| 91 | ||
| 92 | _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank() noexcept { return extents_type::rank(); } | |
| 93 | _LIBCPP_HIDE_FROM_ABI static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } | |
| 94 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t static_extent(rank_type __r) noexcept { | |
| 95 | return extents_type::static_extent(__r); | |
| 96 | } | |
| 97 | _LIBCPP_HIDE_FROM_ABI constexpr index_type extent(rank_type __r) const noexcept { | |
| 98 | return __map_.extents().extent(__r); | |
| 99 | }; | |
| 100 | ||
| 101 | public: | |
| 102 | //-------------------------------------------------------------------------------- | |
| 103 | // [mdspan.mdspan.cons], mdspan constructors, assignment, and destructor | |
| 104 | ||
| 105 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan() | |
| 106 | requires((extents_type::rank_dynamic() > 0) && is_default_constructible_v<data_handle_type> && | |
| 107 | is_default_constructible_v<mapping_type> && is_default_constructible_v<accessor_type>) | |
| 108 | = default; | |
| 109 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(const mdspan&) = default; | |
| 110 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(mdspan&&) = default; | |
| 111 | ||
| 112 | template <class... _OtherIndexTypes> | |
| 113 | requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && | |
| 114 | (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && | |
| 115 | ((sizeof...(_OtherIndexTypes) == rank()) || (sizeof...(_OtherIndexTypes) == rank_dynamic())) && | |
| 116 | is_constructible_v<mapping_type, extents_type> && is_default_constructible_v<accessor_type>) | |
| 117 | _LIBCPP_HIDE_FROM_ABI explicit constexpr mdspan(data_handle_type __p, _OtherIndexTypes... __exts) | |
| 118 | : __ptr_(std::move(__p)), __map_(extents_type(static_cast<index_type>(std::move(__exts))...)), __acc_{} {} | |
| 119 | ||
| 120 | template <class _OtherIndexType, size_t _Size> | |
| 121 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 122 | is_nothrow_constructible_v<index_type, const _OtherIndexType&> && | |
| 123 | ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> && | |
| 124 | is_default_constructible_v<accessor_type>) | |
| 125 | explicit(_Size != rank_dynamic()) | |
| 126 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const array<_OtherIndexType, _Size>& __exts) | |
| 127 | : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {} | |
| 128 | ||
| 129 | template <class _OtherIndexType, size_t _Size> | |
| 130 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 131 | is_nothrow_constructible_v<index_type, const _OtherIndexType&> && | |
| 132 | ((_Size == rank()) || (_Size == rank_dynamic())) && is_constructible_v<mapping_type, extents_type> && | |
| 133 | is_default_constructible_v<accessor_type>) | |
| 134 | explicit(_Size != rank_dynamic()) | |
| 135 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, span<_OtherIndexType, _Size> __exts) | |
| 136 | : __ptr_(std::move(__p)), __map_(extents_type(__exts)), __acc_{} {} | |
| 137 | ||
| 138 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const extents_type& __exts) | |
| 139 | requires(is_default_constructible_v<accessor_type> && is_constructible_v<mapping_type, const extents_type&>) | |
| 140 | : __ptr_(std::move(__p)), __map_(__exts), __acc_{} {} | |
| 141 | ||
| 142 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m) | |
| 143 | requires(is_default_constructible_v<accessor_type>) | |
| 144 | : __ptr_(std::move(__p)), __map_(__m), __acc_{} {} | |
| 145 | ||
| 146 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan(data_handle_type __p, const mapping_type& __m, const accessor_type& __a) | |
| 147 | : __ptr_(std::move(__p)), __map_(__m), __acc_(__a) {} | |
| 148 | ||
| 149 | template <class _OtherElementType, class _OtherExtents, class _OtherLayoutPolicy, class _OtherAccessor> | |
| 150 | requires(is_constructible_v<mapping_type, const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&> && | |
| 151 | is_constructible_v<accessor_type, const _OtherAccessor&>) | |
| 152 | explicit(!is_convertible_v<const typename _OtherLayoutPolicy::template mapping<_OtherExtents>&, mapping_type> || | |
| 153 | !is_convertible_v<const _OtherAccessor&, accessor_type>) | |
| 154 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan( | |
| 155 | const mdspan<_OtherElementType, _OtherExtents, _OtherLayoutPolicy, _OtherAccessor>& __other) | |
| 156 | : __ptr_(__other.__ptr_), __map_(__other.__map_), __acc_(__other.__acc_) { | |
| 157 | static_assert(is_constructible_v<data_handle_type, const typename _OtherAccessor::data_handle_type&>, | |
| 158 | "mdspan: incompatible data_handle_type for mdspan construction"); | |
| 159 | static_assert( | |
| 160 | is_constructible_v<extents_type, _OtherExtents>, "mdspan: incompatible extents for mdspan construction"); | |
| 161 | ||
| 162 | // The following precondition is part of the standard, but is unlikely to be triggered. | |
| 163 | // The extents constructor checks this and the mapping must be storing the extents, since | |
| 164 | // its extents() function returns a const reference to extents_type. | |
| 165 | // The only way this can be triggered is if the mapping conversion constructor would for example | |
| 166 | // always construct its extents() only from the dynamic extents, instead of from the other extents. | |
| 167 | if constexpr (rank() > 0) { | |
| 168 | for (size_t __r = 0; __r < rank(); __r++) { | |
| 169 | // Not catching this could lead to out of bounds errors later | |
| 170 | // e.g. mdspan<int, dextents<char,1>, non_checking_layout> m = | |
| 171 | // mdspan<int, dextents<unsigned, 1>, non_checking_layout>(ptr, 200); leads to an extent of -56 on m | |
| 172 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 173 | (static_extent(__r) == dynamic_extent) || | |
| 174 | (static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(static_extent(__r))), | |
| 175 | "mdspan: conversion mismatch of source dynamic extents with static extents"); | |
| 176 | } | |
| 177 | } | |
| 178 | } | |
| 179 | ||
| 180 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(const mdspan&) = default; | |
| 181 | _LIBCPP_HIDE_FROM_ABI constexpr mdspan& operator=(mdspan&&) = default; | |
| 182 | ||
| 183 | //-------------------------------------------------------------------------------- | |
| 184 | // [mdspan.mdspan.members], members | |
| 185 | ||
| 186 | template <class... _OtherIndexTypes> | |
| 187 | requires((is_convertible_v<_OtherIndexTypes, index_type> && ...) && | |
| 188 | (is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) && | |
| 189 | (sizeof...(_OtherIndexTypes) == rank())) | |
| 190 | _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const { | |
| 191 | // Note the standard layouts would also check this, but user provided ones may not, so we | |
| 192 | // check the precondition here | |
| 193 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...), | |
| 194 | "mdspan: operator[] out of bounds access"); | |
| 195 | return __acc_.access(__ptr_, __map_(static_cast<index_type>(std::move(__indices))...)); | |
| 196 | } | |
| 197 | ||
| 198 | template <class _OtherIndexType> | |
| 199 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 200 | is_nothrow_constructible_v<index_type, const _OtherIndexType&>) | |
| 201 | _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](const array< _OtherIndexType, rank()>& __indices) const { | |
| 202 | return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { | |
| 203 | return __map_(__indices[_Idxs]...); | |
| 204 | }(make_index_sequence<rank()>())); | |
| 205 | } | |
| 206 | ||
| 207 | template <class _OtherIndexType> | |
| 208 | requires(is_convertible_v<const _OtherIndexType&, index_type> && | |
| 209 | is_nothrow_constructible_v<index_type, const _OtherIndexType&>) | |
| 210 | _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](span<_OtherIndexType, rank()> __indices) const { | |
| 211 | return __acc_.access(__ptr_, [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { | |
| 212 | return __map_(__indices[_Idxs]...); | |
| 213 | }(make_index_sequence<rank()>())); | |
| 214 | } | |
| 215 | ||
| 216 | _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { | |
| 217 | // Could leave this as only checked in debug mode: semantically size() is never | |
| 218 | // guaranteed to be related to any accessible range | |
| 219 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 220 | false == ([&]<size_t... _Idxs>(index_sequence<_Idxs...>) { | |
| 221 | size_type __prod = 1; | |
| 222 | return (__builtin_mul_overflow(__prod, extent(_Idxs), &__prod) || ... || false); | |
| 223 | }(make_index_sequence<rank()>())), | |
| 224 | "mdspan: size() is not representable as size_type"); | |
| 225 | return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { | |
| 226 | return ((static_cast<size_type>(__map_.extents().extent(_Idxs))) * ... * size_type(1)); | |
| 227 | }(make_index_sequence<rank()>()); | |
| 228 | } | |
| 229 | ||
| 230 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { | |
| 231 | return [&]<size_t... _Idxs>(index_sequence<_Idxs...>) { | |
| 232 | return (rank() > 0) && ((__map_.extents().extent(_Idxs) == index_type(0)) || ... || false); | |
| 233 | }(make_index_sequence<rank()>()); | |
| 234 | } | |
| 235 | ||
| 236 | _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(mdspan& __x, mdspan& __y) noexcept { | |
| 237 | swap(__x.__ptr_, __y.__ptr_); | |
| 238 | swap(__x.__map_, __y.__map_); | |
| 239 | swap(__x.__acc_, __y.__acc_); | |
| 240 | } | |
| 241 | ||
| 242 | _LIBCPP_HIDE_FROM_ABI constexpr const extents_type& extents() const noexcept { return __map_.extents(); }; | |
| 243 | _LIBCPP_HIDE_FROM_ABI constexpr const data_handle_type& data_handle() const noexcept { return __ptr_; }; | |
| 244 | _LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; }; | |
| 245 | _LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; }; | |
| 246 | ||
| 247 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); }; | |
| 248 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); }; | |
| 249 | _LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); }; | |
| 250 | ||
| 251 | _LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); }; | |
| 252 | _LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); }; | |
| 253 | _LIBCPP_HIDE_FROM_ABI constexpr bool is_strided() const { return __map_.is_strided(); }; | |
| 254 | _LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const { return __map_.stride(__r); }; | |
| 255 | ||
| 256 | private: | |
| 257 | _LIBCPP_NO_UNIQUE_ADDRESS data_handle_type __ptr_{}; | |
| 258 | _LIBCPP_NO_UNIQUE_ADDRESS mapping_type __map_{}; | |
| 259 | _LIBCPP_NO_UNIQUE_ADDRESS accessor_type __acc_{}; | |
| 260 | ||
| 261 | template <class, class, class, class> | |
| 262 | friend class mdspan; | |
| 263 | }; | |
| 264 | ||
| 265 | template <class _ElementType, class... _OtherIndexTypes> | |
| 266 | requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0)) | |
| 267 | explicit mdspan(_ElementType*, _OtherIndexTypes...) | |
| 268 | -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>; | |
| 269 | ||
| 270 | template <class _Pointer> | |
| 271 | requires(is_pointer_v<remove_reference_t<_Pointer>>) | |
| 272 | mdspan(_Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>; | |
| 273 | ||
| 274 | template <class _CArray> | |
| 275 | requires(is_array_v<_CArray> && (rank_v<_CArray> == 1)) | |
| 276 | mdspan(_CArray&) -> mdspan<remove_all_extents_t<_CArray>, extents<size_t, extent_v<_CArray, 0>>>; | |
| 277 | ||
| 278 | template <class _ElementType, class _OtherIndexType, size_t _Size> | |
| 279 | mdspan(_ElementType*, const array<_OtherIndexType, _Size>&) -> mdspan<_ElementType, dextents<size_t, _Size>>; | |
| 280 | ||
| 281 | template <class _ElementType, class _OtherIndexType, size_t _Size> | |
| 282 | mdspan(_ElementType*, span<_OtherIndexType, _Size>) -> mdspan<_ElementType, dextents<size_t, _Size>>; | |
| 283 | ||
| 284 | // This one is necessary because all the constructors take `data_handle_type`s, not | |
| 285 | // `_ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which | |
| 286 | // seems to throw off automatic deduction guides. | |
| 287 | template <class _ElementType, class _OtherIndexType, size_t... _ExtentsPack> | |
| 288 | mdspan(_ElementType*, const extents<_OtherIndexType, _ExtentsPack...>&) | |
| 289 | -> mdspan<_ElementType, extents<_OtherIndexType, _ExtentsPack...>>; | |
| 290 | ||
| 291 | template <class _ElementType, class _MappingType> | |
| 292 | mdspan(_ElementType*, const _MappingType&) | |
| 293 | -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>; | |
| 294 | ||
| 295 | template <class _MappingType, class _AccessorType> | |
| 296 | mdspan(const typename _AccessorType::data_handle_type, const _MappingType&, const _AccessorType&) | |
| 297 | -> mdspan<typename _AccessorType::element_type, | |
| 298 | typename _MappingType::extents_type, | |
| 299 | typename _MappingType::layout_type, | |
| 300 | _AccessorType>; | |
| 301 | ||
| 302 | #endif // _LIBCPP_STD_VER >= 23 | |
| 303 | ||
| 304 | _LIBCPP_END_NAMESPACE_STD | |
| 305 | ||
| 306 | _LIBCPP_POP_MACROS | |
| 307 | ||
| 308 | #endif // _LIBCPP___MDSPAN_MDSPAN_H |
lib/libcxx/include/__memory/align.h+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | _LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); | |
| 21 | _LIBCPP_EXPORTED_FROM_ABI void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space); | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_END_NAMESPACE_STD |
| 24 | 24 |
lib/libcxx/include/__memory/aligned_alloc.h created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H | |
| 10 | #define _LIBCPP___MEMORY_ALIGNED_ALLOC_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <cstddef> | |
| 14 | #include <cstdlib> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | #ifndef _LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION | |
| 23 | ||
| 24 | // Low-level helpers to call the aligned allocation and deallocation functions | |
| 25 | // on the target platform. This is used to implement libc++'s own memory | |
| 26 | // allocation routines -- if you need to allocate memory inside the library, | |
| 27 | // chances are that you want to use `__libcpp_allocate` instead. | |
| 28 | // | |
| 29 | // Returns the allocated memory, or `nullptr` on failure. | |
| 30 | inline _LIBCPP_HIDE_FROM_ABI | |
| 31 | void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) { | |
| 32 | # if defined(_LIBCPP_MSVCRT_LIKE) | |
| 33 | return ::_aligned_malloc(__size, __alignment); | |
| 34 | # elif _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC) | |
| 35 | // aligned_alloc() requires that __size is a multiple of __alignment, | |
| 36 | // but for C++ [new.delete.general], only states "if the value of an | |
| 37 | // alignment argument passed to any of these functions is not a valid | |
| 38 | // alignment value, the behavior is undefined". | |
| 39 | // To handle calls such as ::operator new(1, std::align_val_t(128)), we | |
| 40 | // round __size up to the next multiple of __alignment. | |
| 41 | size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1); | |
| 42 | // Rounding up could have wrapped around to zero, so we have to add another | |
| 43 | // max() ternary to the actual call site to avoid succeeded in that case. | |
| 44 | return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size); | |
| 45 | # else | |
| 46 | void* __result = nullptr; | |
| 47 | (void)::posix_memalign(&__result, __alignment, __size); | |
| 48 | // If posix_memalign fails, __result is unmodified so we still return `nullptr`. | |
| 49 | return __result; | |
| 50 | # endif | |
| 51 | } | |
| 52 | ||
| 53 | inline _LIBCPP_HIDE_FROM_ABI | |
| 54 | void __libcpp_aligned_free(void* __ptr) { | |
| 55 | #if defined(_LIBCPP_MSVCRT_LIKE) | |
| 56 | ::_aligned_free(__ptr); | |
| 57 | #else | |
| 58 | ::free(__ptr); | |
| 59 | #endif | |
| 60 | } | |
| 61 | ||
| 62 | #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION | |
| 63 | ||
| 64 | _LIBCPP_END_NAMESPACE_STD | |
| 65 | ||
| 66 | #endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H |
lib/libcxx/include/__memory/allocate_at_least.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 20 | |
| 22 | #if _LIBCPP_STD_VER >= 23 | |
| 23 | 23 | template <class _Pointer> |
| 24 | 24 | struct allocation_result { |
| 25 | 25 | _Pointer ptr; |
| ... | ... | @@ -55,7 +55,7 @@ __allocation_result<typename allocator_traits<_Alloc>::pointer> __allocate_at_le |
| 55 | 55 | return {__alloc.allocate(__n), __n}; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | #endif // _LIBCPP_STD_VER > 20 | |
| 58 | #endif // _LIBCPP_STD_VER >= 23 | |
| 59 | 59 | |
| 60 | 60 | _LIBCPP_END_NAMESPACE_STD |
| 61 | 61 |
lib/libcxx/include/__memory/allocation_guard.h+35-2| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___MEMORY_ALLOCATION_GUARD_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__memory/addressof.h> | |
| 14 | 15 | #include <__memory/allocator_traits.h> |
| 15 | 16 | #include <__utility/move.h> |
| 16 | 17 | #include <cstddef> |
| ... | ... | @@ -19,6 +20,9 @@ |
| 19 | 20 | # pragma GCC system_header |
| 20 | 21 | #endif |
| 21 | 22 | |
| 23 | _LIBCPP_PUSH_MACROS | |
| 24 | #include <__undef_macros> | |
| 25 | ||
| 22 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 27 | |
| 24 | 28 | // Helper class to allocate memory using an Allocator in an exception safe |
| ... | ... | @@ -55,9 +59,29 @@ struct __allocation_guard { |
| 55 | 59 | |
| 56 | 60 | _LIBCPP_HIDE_FROM_ABI |
| 57 | 61 | ~__allocation_guard() _NOEXCEPT { |
| 58 | if (__ptr_ != nullptr) { | |
| 59 | allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_); | |
| 62 | __destroy(); | |
| 63 | } | |
| 64 | ||
| 65 | _LIBCPP_HIDE_FROM_ABI __allocation_guard(const __allocation_guard&) = delete; | |
| 66 | _LIBCPP_HIDE_FROM_ABI __allocation_guard(__allocation_guard&& __other) _NOEXCEPT | |
| 67 | : __alloc_(std::move(__other.__alloc_)) | |
| 68 | , __n_(__other.__n_) | |
| 69 | , __ptr_(__other.__ptr_) { | |
| 70 | __other.__ptr_ = nullptr; | |
| 71 | } | |
| 72 | ||
| 73 | _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(const __allocation_guard& __other) = delete; | |
| 74 | _LIBCPP_HIDE_FROM_ABI __allocation_guard& operator=(__allocation_guard&& __other) _NOEXCEPT { | |
| 75 | if (std::addressof(__other) != this) { | |
| 76 | __destroy(); | |
| 77 | ||
| 78 | __alloc_ = std::move(__other.__alloc_); | |
| 79 | __n_ = __other.__n_; | |
| 80 | __ptr_ = __other.__ptr_; | |
| 81 | __other.__ptr_ = nullptr; | |
| 60 | 82 | } |
| 83 | ||
| 84 | return *this; | |
| 61 | 85 | } |
| 62 | 86 | |
| 63 | 87 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -73,6 +97,13 @@ struct __allocation_guard { |
| 73 | 97 | } |
| 74 | 98 | |
| 75 | 99 | private: |
| 100 | _LIBCPP_HIDE_FROM_ABI | |
| 101 | void __destroy() _NOEXCEPT { | |
| 102 | if (__ptr_ != nullptr) { | |
| 103 | allocator_traits<_Alloc>::deallocate(__alloc_, __ptr_, __n_); | |
| 104 | } | |
| 105 | } | |
| 106 | ||
| 76 | 107 | _Alloc __alloc_; |
| 77 | 108 | _Size __n_; |
| 78 | 109 | _Pointer __ptr_; |
| ... | ... | @@ -80,4 +111,6 @@ private: |
| 80 | 111 | |
| 81 | 112 | _LIBCPP_END_NAMESPACE_STD |
| 82 | 113 | |
| 114 | _LIBCPP_POP_MACROS | |
| 115 | ||
| 83 | 116 | #endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H |
lib/libcxx/include/__memory/allocator.h+10-8| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | #define _LIBCPP___MEMORY_ALLOCATOR_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__memory/addressof.h> | |
| 14 | 15 | #include <__memory/allocate_at_least.h> |
| 15 | 16 | #include <__memory/allocator_traits.h> |
| 16 | 17 | #include <__type_traits/is_constant_evaluated.h> |
| ... | ... | @@ -20,7 +21,6 @@ |
| 20 | 21 | #include <__utility/forward.h> |
| 21 | 22 | #include <cstddef> |
| 22 | 23 | #include <new> |
| 23 | #include <stdexcept> | |
| 24 | 24 | |
| 25 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 26 | # pragma GCC system_header |
| ... | ... | @@ -98,8 +98,7 @@ public: |
| 98 | 98 | typedef true_type propagate_on_container_move_assignment; |
| 99 | 99 | typedef true_type is_always_equal; |
| 100 | 100 | |
| 101 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 102 | allocator() _NOEXCEPT = default; | |
| 101 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default; | |
| 103 | 102 | |
| 104 | 103 | template <class _Up> |
| 105 | 104 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -116,7 +115,7 @@ public: |
| 116 | 115 | } |
| 117 | 116 | } |
| 118 | 117 | |
| 119 | #if _LIBCPP_STD_VER > 20 | |
| 118 | #if _LIBCPP_STD_VER >= 23 | |
| 120 | 119 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr |
| 121 | 120 | allocation_result<_Tp*> allocate_at_least(size_t __n) { |
| 122 | 121 | return {allocate(__n), __n}; |
| ... | ... | @@ -187,8 +186,7 @@ public: |
| 187 | 186 | typedef true_type propagate_on_container_move_assignment; |
| 188 | 187 | typedef true_type is_always_equal; |
| 189 | 188 | |
| 190 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 191 | allocator() _NOEXCEPT = default; | |
| 189 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 allocator() _NOEXCEPT = default; | |
| 192 | 190 | |
| 193 | 191 | template <class _Up> |
| 194 | 192 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -205,7 +203,7 @@ public: |
| 205 | 203 | } |
| 206 | 204 | } |
| 207 | 205 | |
| 208 | #if _LIBCPP_STD_VER > 20 | |
| 206 | #if _LIBCPP_STD_VER >= 23 | |
| 209 | 207 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr |
| 210 | 208 | allocation_result<const _Tp*> allocate_at_least(size_t __n) { |
| 211 | 209 | return {allocate(__n), __n}; |
| ... | ... | @@ -264,10 +262,14 @@ template <class _Tp, class _Up> |
| 264 | 262 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 265 | 263 | bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;} |
| 266 | 264 | |
| 265 | #if _LIBCPP_STD_VER <= 17 | |
| 266 | ||
| 267 | 267 | template <class _Tp, class _Up> |
| 268 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 268 | inline _LIBCPP_INLINE_VISIBILITY | |
| 269 | 269 | bool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;} |
| 270 | 270 | |
| 271 | #endif | |
| 272 | ||
| 271 | 273 | _LIBCPP_END_NAMESPACE_STD |
| 272 | 274 | |
| 273 | 275 | #endif // _LIBCPP___MEMORY_ALLOCATOR_H |
lib/libcxx/include/__memory/allocator_arg_t.h+4-4| ... | ... | @@ -25,10 +25,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | 26 | struct _LIBCPP_TEMPLATE_VIS allocator_arg_t { explicit allocator_arg_t() = default; }; |
| 27 | 27 | |
| 28 | #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 29 | extern _LIBCPP_EXPORTED_FROM_ABI const allocator_arg_t allocator_arg; | |
| 30 | #else | |
| 31 | /* inline */ constexpr allocator_arg_t allocator_arg = allocator_arg_t(); | |
| 28 | #if _LIBCPP_STD_VER >= 17 | |
| 29 | inline constexpr allocator_arg_t allocator_arg = allocator_arg_t(); | |
| 30 | #elif !defined(_LIBCPP_CXX03_LANG) | |
| 31 | constexpr allocator_arg_t allocator_arg = allocator_arg_t(); | |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | 34 | #ifndef _LIBCPP_CXX03_LANG |
lib/libcxx/include/__memory/allocator_traits.h+21-2| ... | ... | @@ -300,7 +300,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| 300 | 300 | __enable_if_t<!__has_construct<allocator_type, _Tp*, _Args...>::value> > |
| 301 | 301 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 302 | 302 | static void construct(allocator_type&, _Tp* __p, _Args&&... __args) { |
| 303 | #if _LIBCPP_STD_VER > 17 | |
| 303 | #if _LIBCPP_STD_VER >= 20 | |
| 304 | 304 | _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...); |
| 305 | 305 | #else |
| 306 | 306 | ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...); |
| ... | ... | @@ -319,7 +319,7 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits |
| 319 | 319 | __enable_if_t<!__has_destroy<allocator_type, _Tp*>::value> > |
| 320 | 320 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 321 | 321 | static void destroy(allocator_type&, _Tp* __p) { |
| 322 | #if _LIBCPP_STD_VER > 17 | |
| 322 | #if _LIBCPP_STD_VER >= 20 | |
| 323 | 323 | _VSTD::destroy_at(__p); |
| 324 | 324 | #else |
| 325 | 325 | __p->~_Tp(); |
| ... | ... | @@ -401,6 +401,25 @@ struct __is_cpp17_copy_insertable<_Alloc, __enable_if_t< |
| 401 | 401 | : __is_cpp17_move_insertable<_Alloc> |
| 402 | 402 | { }; |
| 403 | 403 | |
| 404 | // ASan choices | |
| 405 | #ifndef _LIBCPP_HAS_NO_ASAN | |
| 406 | # define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1 | |
| 407 | #endif | |
| 408 | ||
| 409 | #ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS | |
| 410 | template <class _Alloc> | |
| 411 | struct __asan_annotate_container_with_allocator | |
| 412 | # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1600 | |
| 413 | : true_type {}; | |
| 414 | # else | |
| 415 | // TODO(LLVM-18): Remove the special-casing | |
| 416 | : false_type {}; | |
| 417 | # endif | |
| 418 | ||
| 419 | template <class _Tp> | |
| 420 | struct __asan_annotate_container_with_allocator<allocator<_Tp> > : true_type {}; | |
| 421 | #endif | |
| 422 | ||
| 404 | 423 | #undef _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX |
| 405 | 424 | |
| 406 | 425 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__memory/assume_aligned.h+3-3| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | template <size_t _Np, class _Tp> |
| 28 | 28 | [[nodiscard]] |
| ... | ... | @@ -34,12 +34,12 @@ constexpr _Tp* assume_aligned(_Tp* __ptr) { |
| 34 | 34 | if (is_constant_evaluated()) { |
| 35 | 35 | return __ptr; |
| 36 | 36 | } else { |
| 37 | _LIBCPP_ASSERT(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated"); | |
| 37 | _LIBCPP_ASSERT_UNCATEGORIZED(reinterpret_cast<uintptr_t>(__ptr) % _Np == 0, "Alignment assumption is violated"); | |
| 38 | 38 | return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Np)); |
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | #endif // _LIBCPP_STD_VER > 17 | |
| 42 | #endif // _LIBCPP_STD_VER >= 20 | |
| 43 | 43 | |
| 44 | 44 | _LIBCPP_END_NAMESPACE_STD |
| 45 | 45 |
lib/libcxx/include/__memory/builtin_new_allocator.h+6-6| ... | ... | @@ -28,10 +28,10 @@ struct __builtin_new_allocator { |
| 28 | 28 | struct __builtin_new_deleter { |
| 29 | 29 | typedef void* pointer_type; |
| 30 | 30 | |
| 31 | _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) | |
| 31 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align) | |
| 32 | 32 | : __size_(__size), __align_(__align) {} |
| 33 | 33 | |
| 34 | void operator()(void* __p) const _NOEXCEPT { | |
| 34 | _LIBCPP_HIDE_FROM_ABI void operator()(void* __p) const _NOEXCEPT { | |
| 35 | 35 | _VSTD::__libcpp_deallocate(__p, __size_, __align_); |
| 36 | 36 | } |
| 37 | 37 | |
| ... | ... | @@ -42,25 +42,25 @@ struct __builtin_new_allocator { |
| 42 | 42 | |
| 43 | 43 | typedef unique_ptr<void, __builtin_new_deleter> __holder_t; |
| 44 | 44 | |
| 45 | static __holder_t __allocate_bytes(size_t __s, size_t __align) { | |
| 45 | _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_bytes(size_t __s, size_t __align) { | |
| 46 | 46 | return __holder_t(_VSTD::__libcpp_allocate(__s, __align), |
| 47 | 47 | __builtin_new_deleter(__s, __align)); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | static void __deallocate_bytes(void* __p, size_t __s, | |
| 50 | _LIBCPP_HIDE_FROM_ABI static void __deallocate_bytes(void* __p, size_t __s, | |
| 51 | 51 | size_t __align) _NOEXCEPT { |
| 52 | 52 | _VSTD::__libcpp_deallocate(__p, __s, __align); |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | template <class _Tp> |
| 56 | 56 | _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE |
| 57 | static __holder_t __allocate_type(size_t __n) { | |
| 57 | _LIBCPP_HIDE_FROM_ABI static __holder_t __allocate_type(size_t __n) { | |
| 58 | 58 | return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | 61 | template <class _Tp> |
| 62 | 62 | _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE |
| 63 | static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { | |
| 63 | _LIBCPP_HIDE_FROM_ABI static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT { | |
| 64 | 64 | __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); |
| 65 | 65 | } |
| 66 | 66 | }; |
lib/libcxx/include/__memory/compressed_pair.h+8-3| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__fwd/get.h> |
| 15 | 15 | #include <__fwd/tuple.h> |
| 16 | #include <__tuple_dir/tuple_indices.h> | |
| 16 | #include <__tuple/tuple_indices.h> | |
| 17 | 17 | #include <__type_traits/decay.h> |
| 18 | 18 | #include <__type_traits/dependent_type.h> |
| 19 | 19 | #include <__type_traits/enable_if.h> |
| ... | ... | @@ -31,6 +31,9 @@ |
| 31 | 31 | # pragma GCC system_header |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | _LIBCPP_PUSH_MACROS | |
| 35 | #include <__undef_macros> | |
| 36 | ||
| 34 | 37 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 38 | |
| 36 | 39 | // Tag used to default initialize one or both of the pair's elements. |
| ... | ... | @@ -46,7 +49,7 @@ struct __compressed_pair_elem { |
| 46 | 49 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {} |
| 47 | 50 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_() {} |
| 48 | 51 | |
| 49 | template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> > | |
| 52 | template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> > | |
| 50 | 53 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR |
| 51 | 54 | explicit __compressed_pair_elem(_Up&& __u) : __value_(std::forward<_Up>(__u)) {} |
| 52 | 55 | |
| ... | ... | @@ -75,7 +78,7 @@ struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { |
| 75 | 78 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__default_init_tag) {} |
| 76 | 79 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __compressed_pair_elem(__value_init_tag) : __value_type() {} |
| 77 | 80 | |
| 78 | template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value> > | |
| 81 | template <class _Up, class = __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value> > | |
| 79 | 82 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR |
| 80 | 83 | explicit __compressed_pair_elem(_Up&& __u) : __value_type(std::forward<_Up>(__u)) {} |
| 81 | 84 | |
| ... | ... | @@ -174,4 +177,6 @@ void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y) |
| 174 | 177 | |
| 175 | 178 | _LIBCPP_END_NAMESPACE_STD |
| 176 | 179 | |
| 180 | _LIBCPP_POP_MACROS | |
| 181 | ||
| 177 | 182 | #endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H |
lib/libcxx/include/__memory/concepts.h+3-2| ... | ... | @@ -19,6 +19,7 @@ |
| 19 | 19 | #include <__ranges/concepts.h> |
| 20 | 20 | #include <__type_traits/is_reference.h> |
| 21 | 21 | #include <__type_traits/remove_cvref.h> |
| 22 | #include <__type_traits/remove_reference.h> // TODO(modules): This should not be required | |
| 22 | 23 | |
| 23 | 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 25 | # pragma GCC system_header |
| ... | ... | @@ -26,7 +27,7 @@ |
| 26 | 27 | |
| 27 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 29 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 31 | |
| 31 | 32 | namespace ranges { |
| 32 | 33 | |
| ... | ... | @@ -62,7 +63,7 @@ concept __nothrow_forward_range = |
| 62 | 63 | |
| 63 | 64 | } // namespace ranges |
| 64 | 65 | |
| 65 | #endif // _LIBCPP_STD_VER > 17 | |
| 66 | #endif // _LIBCPP_STD_VER >= 20 | |
| 66 | 67 | |
| 67 | 68 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 69 |
lib/libcxx/include/__memory/construct_at.h+22-17| ... | ... | @@ -26,26 +26,29 @@ |
| 26 | 26 | # pragma GCC system_header |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | _LIBCPP_PUSH_MACROS | |
| 30 | #include <__undef_macros> | |
| 31 | ||
| 29 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 33 | |
| 31 | 34 | // construct_at |
| 32 | 35 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 37 | |
| 35 | 38 | template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))> |
| 36 | 39 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* construct_at(_Tp* __location, _Args&&... __args) { |
| 37 | _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at"); | |
| 38 | return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...); | |
| 40 | _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at"); | |
| 41 | return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...); | |
| 39 | 42 | } |
| 40 | 43 | |
| 41 | 44 | #endif |
| 42 | 45 | |
| 43 | 46 | template <class _Tp, class... _Args, class = decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))> |
| 44 | 47 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* __construct_at(_Tp* __location, _Args&&... __args) { |
| 45 | #if _LIBCPP_STD_VER > 17 | |
| 48 | #if _LIBCPP_STD_VER >= 20 | |
| 46 | 49 | return std::construct_at(__location, std::forward<_Args>(__args)...); |
| 47 | 50 | #else |
| 48 | return _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at"), | |
| 51 | return _LIBCPP_ASSERT_UNCATEGORIZED(__location != nullptr, "null pointer given to construct_at"), | |
| 49 | 52 | ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...); |
| 50 | 53 | #endif |
| 51 | 54 | } |
| ... | ... | @@ -62,16 +65,16 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator); |
| 62 | 65 | template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0> |
| 63 | 66 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 64 | 67 | void __destroy_at(_Tp* __loc) { |
| 65 | _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at"); | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at"); | |
| 66 | 69 | __loc->~_Tp(); |
| 67 | 70 | } |
| 68 | 71 | |
| 69 | #if _LIBCPP_STD_VER > 17 | |
| 72 | #if _LIBCPP_STD_VER >= 20 | |
| 70 | 73 | template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0> |
| 71 | 74 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 72 | 75 | void __destroy_at(_Tp* __loc) { |
| 73 | _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at"); | |
| 74 | _VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc)); | |
| 76 | _LIBCPP_ASSERT_UNCATEGORIZED(__loc != nullptr, "null pointer given to destroy_at"); | |
| 77 | std::__destroy(std::begin(*__loc), std::end(*__loc)); | |
| 75 | 78 | } |
| 76 | 79 | #endif |
| 77 | 80 | |
| ... | ... | @@ -79,7 +82,7 @@ template <class _ForwardIterator> |
| 79 | 82 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 80 | 83 | _ForwardIterator __destroy(_ForwardIterator __first, _ForwardIterator __last) { |
| 81 | 84 | for (; __first != __last; ++__first) |
| 82 | _VSTD::__destroy_at(_VSTD::addressof(*__first)); | |
| 85 | std::__destroy_at(std::addressof(*__first)); | |
| 83 | 86 | return __first; |
| 84 | 87 | } |
| 85 | 88 | |
| ... | ... | @@ -93,38 +96,40 @@ _BidirectionalIterator __reverse_destroy(_BidirectionalIterator __first, _Bidire |
| 93 | 96 | return __last; |
| 94 | 97 | } |
| 95 | 98 | |
| 96 | #if _LIBCPP_STD_VER > 14 | |
| 99 | #if _LIBCPP_STD_VER >= 17 | |
| 97 | 100 | |
| 98 | 101 | template <class _Tp, enable_if_t<!is_array_v<_Tp>, int> = 0> |
| 99 | 102 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 100 | 103 | void destroy_at(_Tp* __loc) { |
| 101 | _VSTD::__destroy_at(__loc); | |
| 104 | std::__destroy_at(__loc); | |
| 102 | 105 | } |
| 103 | 106 | |
| 104 | #if _LIBCPP_STD_VER > 17 | |
| 107 | #if _LIBCPP_STD_VER >= 20 | |
| 105 | 108 | template <class _Tp, enable_if_t<is_array_v<_Tp>, int> = 0> |
| 106 | 109 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 107 | 110 | void destroy_at(_Tp* __loc) { |
| 108 | _VSTD::__destroy_at(__loc); | |
| 111 | std::__destroy_at(__loc); | |
| 109 | 112 | } |
| 110 | 113 | #endif |
| 111 | 114 | |
| 112 | 115 | template <class _ForwardIterator> |
| 113 | 116 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 114 | 117 | void destroy(_ForwardIterator __first, _ForwardIterator __last) { |
| 115 | (void)_VSTD::__destroy(_VSTD::move(__first), _VSTD::move(__last)); | |
| 118 | (void)std::__destroy(std::move(__first), std::move(__last)); | |
| 116 | 119 | } |
| 117 | 120 | |
| 118 | 121 | template <class _ForwardIterator, class _Size> |
| 119 | 122 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 120 | 123 | _ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) { |
| 121 | 124 | for (; __n > 0; (void)++__first, --__n) |
| 122 | _VSTD::__destroy_at(_VSTD::addressof(*__first)); | |
| 125 | std::__destroy_at(std::addressof(*__first)); | |
| 123 | 126 | return __first; |
| 124 | 127 | } |
| 125 | 128 | |
| 126 | #endif // _LIBCPP_STD_VER > 14 | |
| 129 | #endif // _LIBCPP_STD_VER >= 17 | |
| 127 | 130 | |
| 128 | 131 | _LIBCPP_END_NAMESPACE_STD |
| 129 | 132 | |
| 133 | _LIBCPP_POP_MACROS | |
| 134 | ||
| 130 | 135 | #endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H |
lib/libcxx/include/__memory/pointer_traits.h+2-2| ... | ... | @@ -200,7 +200,7 @@ template <class _Pointer, class = __enable_if_t< |
| 200 | 200 | _And<is_class<_Pointer>, _IsFancyPointer<_Pointer> >::value |
| 201 | 201 | > > |
| 202 | 202 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 203 | typename decay<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))>::type | |
| 203 | __decay_t<decltype(__to_address_helper<_Pointer>::__call(std::declval<const _Pointer&>()))> | |
| 204 | 204 | __to_address(const _Pointer& __p) _NOEXCEPT { |
| 205 | 205 | return __to_address_helper<_Pointer>::__call(__p); |
| 206 | 206 | } |
| ... | ... | @@ -223,7 +223,7 @@ struct __to_address_helper<_Pointer, decltype((void)pointer_traits<_Pointer>::to |
| 223 | 223 | } |
| 224 | 224 | }; |
| 225 | 225 | |
| 226 | #if _LIBCPP_STD_VER > 17 | |
| 226 | #if _LIBCPP_STD_VER >= 20 | |
| 227 | 227 | template <class _Tp> |
| 228 | 228 | inline _LIBCPP_INLINE_VISIBILITY constexpr |
| 229 | 229 | auto to_address(_Tp *__p) noexcept { |
lib/libcxx/include/__memory/ranges_construct_at.h+8-3| ... | ... | @@ -13,7 +13,7 @@ |
| 13 | 13 | #include <__concepts/destructible.h> |
| 14 | 14 | #include <__config> |
| 15 | 15 | #include <__iterator/incrementable_traits.h> |
| 16 | #include <__iterator/readable_traits.h> | |
| 16 | #include <__iterator/iterator_traits.h> | |
| 17 | 17 | #include <__memory/concepts.h> |
| 18 | 18 | #include <__memory/construct_at.h> |
| 19 | 19 | #include <__ranges/access.h> |
| ... | ... | @@ -28,9 +28,12 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | _LIBCPP_PUSH_MACROS | |
| 32 | #include <__undef_macros> | |
| 33 | ||
| 31 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 35 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 37 | namespace ranges { |
| 35 | 38 | |
| 36 | 39 | // construct_at |
| ... | ... | @@ -118,8 +121,10 @@ inline namespace __cpo { |
| 118 | 121 | |
| 119 | 122 | } // namespace ranges |
| 120 | 123 | |
| 121 | #endif // _LIBCPP_STD_VER > 17 | |
| 124 | #endif // _LIBCPP_STD_VER >= 20 | |
| 122 | 125 | |
| 123 | 126 | _LIBCPP_END_NAMESPACE_STD |
| 124 | 127 | |
| 128 | _LIBCPP_POP_MACROS | |
| 129 | ||
| 125 | 130 | #endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H |
lib/libcxx/include/__memory/ranges_uninitialized_algorithms.h+17-17| ... | ... | @@ -33,7 +33,7 @@ |
| 33 | 33 | |
| 34 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 35 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | namespace ranges { |
| 39 | 39 | |
| ... | ... | @@ -45,7 +45,7 @@ struct __fn { |
| 45 | 45 | template <__nothrow_forward_iterator _ForwardIterator, |
| 46 | 46 | __nothrow_sentinel_for<_ForwardIterator> _Sentinel> |
| 47 | 47 | requires default_initializable<iter_value_t<_ForwardIterator>> |
| 48 | _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { | |
| 48 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { | |
| 49 | 49 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| 50 | 50 | return _VSTD::__uninitialized_default_construct<_ValueType>( |
| 51 | 51 | _VSTD::move(__first), _VSTD::move(__last)); |
| ... | ... | @@ -53,7 +53,7 @@ struct __fn { |
| 53 | 53 | |
| 54 | 54 | template <__nothrow_forward_range _ForwardRange> |
| 55 | 55 | requires default_initializable<range_value_t<_ForwardRange>> |
| 56 | borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { | |
| 56 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { | |
| 57 | 57 | return (*this)(ranges::begin(__range), ranges::end(__range)); |
| 58 | 58 | } |
| 59 | 59 | }; |
| ... | ... | @@ -71,7 +71,7 @@ namespace __uninitialized_default_construct_n { |
| 71 | 71 | struct __fn { |
| 72 | 72 | template <__nothrow_forward_iterator _ForwardIterator> |
| 73 | 73 | requires default_initializable<iter_value_t<_ForwardIterator>> |
| 74 | _ForwardIterator operator()(_ForwardIterator __first, | |
| 74 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, | |
| 75 | 75 | iter_difference_t<_ForwardIterator> __n) const { |
| 76 | 76 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| 77 | 77 | return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n); |
| ... | ... | @@ -92,7 +92,7 @@ struct __fn { |
| 92 | 92 | template <__nothrow_forward_iterator _ForwardIterator, |
| 93 | 93 | __nothrow_sentinel_for<_ForwardIterator> _Sentinel> |
| 94 | 94 | requires default_initializable<iter_value_t<_ForwardIterator>> |
| 95 | _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { | |
| 95 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { | |
| 96 | 96 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| 97 | 97 | return _VSTD::__uninitialized_value_construct<_ValueType>( |
| 98 | 98 | _VSTD::move(__first), _VSTD::move(__last)); |
| ... | ... | @@ -100,7 +100,7 @@ struct __fn { |
| 100 | 100 | |
| 101 | 101 | template <__nothrow_forward_range _ForwardRange> |
| 102 | 102 | requires default_initializable<range_value_t<_ForwardRange>> |
| 103 | borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { | |
| 103 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { | |
| 104 | 104 | return (*this)(ranges::begin(__range), ranges::end(__range)); |
| 105 | 105 | } |
| 106 | 106 | }; |
| ... | ... | @@ -118,7 +118,7 @@ namespace __uninitialized_value_construct_n { |
| 118 | 118 | struct __fn { |
| 119 | 119 | template <__nothrow_forward_iterator _ForwardIterator> |
| 120 | 120 | requires default_initializable<iter_value_t<_ForwardIterator>> |
| 121 | _ForwardIterator operator()(_ForwardIterator __first, | |
| 121 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, | |
| 122 | 122 | iter_difference_t<_ForwardIterator> __n) const { |
| 123 | 123 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| 124 | 124 | return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); |
| ... | ... | @@ -140,14 +140,14 @@ struct __fn { |
| 140 | 140 | __nothrow_sentinel_for<_ForwardIterator> _Sentinel, |
| 141 | 141 | class _Tp> |
| 142 | 142 | requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> |
| 143 | _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const { | |
| 143 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const { | |
| 144 | 144 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| 145 | 145 | return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x); |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | template <__nothrow_forward_range _ForwardRange, class _Tp> |
| 149 | 149 | requires constructible_from<range_value_t<_ForwardRange>, const _Tp&> |
| 150 | borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { | |
| 150 | _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { | |
| 151 | 151 | return (*this)(ranges::begin(__range), ranges::end(__range), __x); |
| 152 | 152 | } |
| 153 | 153 | }; |
| ... | ... | @@ -165,7 +165,7 @@ namespace __uninitialized_fill_n { |
| 165 | 165 | struct __fn { |
| 166 | 166 | template <__nothrow_forward_iterator _ForwardIterator, class _Tp> |
| 167 | 167 | requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> |
| 168 | _ForwardIterator operator()(_ForwardIterator __first, | |
| 168 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, | |
| 169 | 169 | iter_difference_t<_ForwardIterator> __n, |
| 170 | 170 | const _Tp& __x) const { |
| 171 | 171 | using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; |
| ... | ... | @@ -192,7 +192,7 @@ struct __fn { |
| 192 | 192 | __nothrow_forward_iterator _OutputIterator, |
| 193 | 193 | __nothrow_sentinel_for<_OutputIterator> _Sentinel2> |
| 194 | 194 | requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> |
| 195 | uninitialized_copy_result<_InputIterator, _OutputIterator> | |
| 195 | _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<_InputIterator, _OutputIterator> | |
| 196 | 196 | operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { |
| 197 | 197 | using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; |
| 198 | 198 | |
| ... | ... | @@ -203,7 +203,7 @@ struct __fn { |
| 203 | 203 | |
| 204 | 204 | template <input_range _InputRange, __nothrow_forward_range _OutputRange> |
| 205 | 205 | requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> |
| 206 | uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> | |
| 206 | _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> | |
| 207 | 207 | operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const { |
| 208 | 208 | return (*this)(ranges::begin(__in_range), ranges::end(__in_range), |
| 209 | 209 | ranges::begin(__out_range), ranges::end(__out_range)); |
| ... | ... | @@ -228,7 +228,7 @@ struct __fn { |
| 228 | 228 | __nothrow_forward_iterator _OutputIterator, |
| 229 | 229 | __nothrow_sentinel_for<_OutputIterator> _Sentinel> |
| 230 | 230 | requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> |
| 231 | uninitialized_copy_n_result<_InputIterator, _OutputIterator> | |
| 231 | _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator> | |
| 232 | 232 | operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, |
| 233 | 233 | _OutputIterator __ofirst, _Sentinel __olast) const { |
| 234 | 234 | using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; |
| ... | ... | @@ -257,7 +257,7 @@ struct __fn { |
| 257 | 257 | __nothrow_forward_iterator _OutputIterator, |
| 258 | 258 | __nothrow_sentinel_for<_OutputIterator> _Sentinel2> |
| 259 | 259 | requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>> |
| 260 | uninitialized_move_result<_InputIterator, _OutputIterator> | |
| 260 | _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<_InputIterator, _OutputIterator> | |
| 261 | 261 | operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { |
| 262 | 262 | using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; |
| 263 | 263 | auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; |
| ... | ... | @@ -268,7 +268,7 @@ struct __fn { |
| 268 | 268 | |
| 269 | 269 | template <input_range _InputRange, __nothrow_forward_range _OutputRange> |
| 270 | 270 | requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>> |
| 271 | uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> | |
| 271 | _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> | |
| 272 | 272 | operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { |
| 273 | 273 | return (*this)(ranges::begin(__in_range), ranges::end(__in_range), |
| 274 | 274 | ranges::begin(__out_range), ranges::end(__out_range)); |
| ... | ... | @@ -293,7 +293,7 @@ struct __fn { |
| 293 | 293 | __nothrow_forward_iterator _OutputIterator, |
| 294 | 294 | __nothrow_sentinel_for<_OutputIterator> _Sentinel> |
| 295 | 295 | requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>> |
| 296 | uninitialized_move_n_result<_InputIterator, _OutputIterator> | |
| 296 | _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator> | |
| 297 | 297 | operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, |
| 298 | 298 | _OutputIterator __ofirst, _Sentinel __olast) const { |
| 299 | 299 | using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; |
| ... | ... | @@ -312,7 +312,7 @@ inline namespace __cpo { |
| 312 | 312 | |
| 313 | 313 | } // namespace ranges |
| 314 | 314 | |
| 315 | #endif // _LIBCPP_STD_VER > 17 | |
| 315 | #endif // _LIBCPP_STD_VER >= 20 | |
| 316 | 316 | |
| 317 | 317 | _LIBCPP_END_NAMESPACE_STD |
| 318 | 318 |
lib/libcxx/include/__memory/raw_storage_iterator.h+1-1| ... | ... | @@ -39,7 +39,7 @@ private: |
| 39 | 39 | public: |
| 40 | 40 | typedef output_iterator_tag iterator_category; |
| 41 | 41 | typedef void value_type; |
| 42 | #if _LIBCPP_STD_VER > 17 | |
| 42 | #if _LIBCPP_STD_VER >= 20 | |
| 43 | 43 | typedef ptrdiff_t difference_type; |
| 44 | 44 | #else |
| 45 | 45 | typedef void difference_type; |
lib/libcxx/include/__memory/shared_ptr.h+127-63| ... | ... | @@ -29,17 +29,32 @@ |
| 29 | 29 | #include <__memory/pointer_traits.h> |
| 30 | 30 | #include <__memory/uninitialized_algorithms.h> |
| 31 | 31 | #include <__memory/unique_ptr.h> |
| 32 | #include <__type_traits/add_lvalue_reference.h> | |
| 33 | #include <__type_traits/conditional.h> | |
| 34 | #include <__type_traits/conjunction.h> | |
| 35 | #include <__type_traits/disjunction.h> | |
| 36 | #include <__type_traits/is_array.h> | |
| 37 | #include <__type_traits/is_bounded_array.h> | |
| 38 | #include <__type_traits/is_convertible.h> | |
| 39 | #include <__type_traits/is_move_constructible.h> | |
| 40 | #include <__type_traits/is_reference.h> | |
| 41 | #include <__type_traits/is_unbounded_array.h> | |
| 42 | #include <__type_traits/nat.h> | |
| 43 | #include <__type_traits/negation.h> | |
| 44 | #include <__type_traits/remove_extent.h> | |
| 45 | #include <__type_traits/remove_reference.h> | |
| 46 | #include <__utility/declval.h> | |
| 32 | 47 | #include <__utility/forward.h> |
| 33 | 48 | #include <__utility/move.h> |
| 34 | 49 | #include <__utility/swap.h> |
| 50 | #include <__verbose_abort> | |
| 35 | 51 | #include <cstddef> |
| 36 | #include <cstdlib> // abort | |
| 37 | 52 | #include <iosfwd> |
| 38 | 53 | #include <new> |
| 39 | 54 | #include <stdexcept> |
| 40 | 55 | #include <typeinfo> |
| 41 | 56 | #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
| 42 | # include <atomic> | |
| 57 | # include <__atomic/memory_order.h> | |
| 43 | 58 | #endif |
| 44 | 59 | |
| 45 | 60 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -105,12 +120,12 @@ __libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT |
| 105 | 120 | #endif |
| 106 | 121 | } |
| 107 | 122 | |
| 108 | class _LIBCPP_EXCEPTION_ABI bad_weak_ptr | |
| 123 | class _LIBCPP_EXPORTED_FROM_ABI bad_weak_ptr | |
| 109 | 124 | : public std::exception |
| 110 | 125 | { |
| 111 | 126 | public: |
| 112 | bad_weak_ptr() _NOEXCEPT = default; | |
| 113 | bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; | |
| 127 | _LIBCPP_HIDE_FROM_ABI bad_weak_ptr() _NOEXCEPT = default; | |
| 128 | _LIBCPP_HIDE_FROM_ABI bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default; | |
| 114 | 129 | ~bad_weak_ptr() _NOEXCEPT override; |
| 115 | 130 | const char* what() const _NOEXCEPT override; |
| 116 | 131 | }; |
| ... | ... | @@ -118,16 +133,16 @@ public: |
| 118 | 133 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 119 | 134 | void __throw_bad_weak_ptr() |
| 120 | 135 | { |
| 121 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 136 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 122 | 137 | throw bad_weak_ptr(); |
| 123 | 138 | #else |
| 124 | _VSTD::abort(); | |
| 139 | _LIBCPP_VERBOSE_ABORT("bad_weak_ptr was thrown in -fno-exceptions mode"); | |
| 125 | 140 | #endif |
| 126 | 141 | } |
| 127 | 142 | |
| 128 | 143 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr; |
| 129 | 144 | |
| 130 | class _LIBCPP_TYPE_VIS __shared_count | |
| 145 | class _LIBCPP_EXPORTED_FROM_ABI __shared_count | |
| 131 | 146 | { |
| 132 | 147 | __shared_count(const __shared_count&); |
| 133 | 148 | __shared_count& operator=(const __shared_count&); |
| ... | ... | @@ -166,7 +181,7 @@ public: |
| 166 | 181 | } |
| 167 | 182 | }; |
| 168 | 183 | |
| 169 | class _LIBCPP_TYPE_VIS __shared_weak_count | |
| 184 | class _LIBCPP_EXPORTED_FROM_ABI __shared_weak_count | |
| 170 | 185 | : private __shared_count |
| 171 | 186 | { |
| 172 | 187 | long __shared_weak_owners_; |
| ... | ... | @@ -220,12 +235,12 @@ public: |
| 220 | 235 | : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {} |
| 221 | 236 | |
| 222 | 237 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 223 | const void* __get_deleter(const type_info&) const _NOEXCEPT override; | |
| 238 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL const void* __get_deleter(const type_info&) const _NOEXCEPT override; | |
| 224 | 239 | #endif |
| 225 | 240 | |
| 226 | 241 | private: |
| 227 | void __on_zero_shared() _NOEXCEPT override; | |
| 228 | void __on_zero_shared_weak() _NOEXCEPT override; | |
| 242 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; | |
| 243 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override; | |
| 229 | 244 | }; |
| 230 | 245 | |
| 231 | 246 | #ifndef _LIBCPP_HAS_NO_RTTI |
| ... | ... | @@ -295,8 +310,8 @@ struct __shared_ptr_emplace |
| 295 | 310 | _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); } |
| 296 | 311 | |
| 297 | 312 | private: |
| 298 | void __on_zero_shared() _NOEXCEPT override { | |
| 299 | #if _LIBCPP_STD_VER > 17 | |
| 313 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { | |
| 314 | #if _LIBCPP_STD_VER >= 20 | |
| 300 | 315 | if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { |
| 301 | 316 | __get_elem()->~_Tp(); |
| 302 | 317 | } else { |
| ... | ... | @@ -309,7 +324,7 @@ private: |
| 309 | 324 | #endif |
| 310 | 325 | } |
| 311 | 326 | |
| 312 | void __on_zero_shared_weak() _NOEXCEPT override { | |
| 327 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { | |
| 313 | 328 | using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; |
| 314 | 329 | using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer; |
| 315 | 330 | _ControlBlockAlloc __tmp(*__get_alloc()); |
| ... | ... | @@ -336,13 +351,13 @@ private: |
| 336 | 351 | _LIBCPP_HIDE_FROM_ABI ~_Storage() { |
| 337 | 352 | __get_alloc()->~_Alloc(); |
| 338 | 353 | } |
| 339 | _Alloc* __get_alloc() _NOEXCEPT { | |
| 354 | _LIBCPP_HIDE_FROM_ABI _Alloc* __get_alloc() _NOEXCEPT { | |
| 340 | 355 | _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); |
| 341 | 356 | typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair); |
| 342 | 357 | _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first); |
| 343 | 358 | return __alloc; |
| 344 | 359 | } |
| 345 | _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT { | |
| 360 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT { | |
| 346 | 361 | _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_); |
| 347 | 362 | typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair); |
| 348 | 363 | _Tp *__elem = reinterpret_cast<_Tp*>(__second); |
| ... | ... | @@ -433,10 +448,10 @@ struct __is_array_deletable<_Ptr, decltype(delete[] std::declval<_Ptr>())> : tru |
| 433 | 448 | |
| 434 | 449 | template <class _Dp, class _Pt, |
| 435 | 450 | class = decltype(std::declval<_Dp>()(std::declval<_Pt>()))> |
| 436 | static true_type __well_formed_deleter_test(int); | |
| 451 | true_type __well_formed_deleter_test(int); | |
| 437 | 452 | |
| 438 | 453 | template <class, class> |
| 439 | static false_type __well_formed_deleter_test(...); | |
| 454 | false_type __well_formed_deleter_test(...); | |
| 440 | 455 | |
| 441 | 456 | template <class _Dp, class _Pt> |
| 442 | 457 | struct __well_formed_deleter : decltype(std::__well_formed_deleter_test<_Dp, _Pt>(0)) {}; |
| ... | ... | @@ -450,7 +465,7 @@ struct __shared_ptr_deleter_ctor_reqs |
| 450 | 465 | }; |
| 451 | 466 | |
| 452 | 467 | #if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI) |
| 453 | # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) | |
| 468 | # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) | |
| 454 | 469 | #else |
| 455 | 470 | # define _LIBCPP_SHARED_PTR_TRIVIAL_ABI |
| 456 | 471 | #endif |
| ... | ... | @@ -459,7 +474,7 @@ template<class _Tp> |
| 459 | 474 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr |
| 460 | 475 | { |
| 461 | 476 | public: |
| 462 | #if _LIBCPP_STD_VER > 14 | |
| 477 | #if _LIBCPP_STD_VER >= 17 | |
| 463 | 478 | typedef weak_ptr<_Tp> weak_type; |
| 464 | 479 | typedef remove_extent_t<_Tp> element_type; |
| 465 | 480 | #else |
| ... | ... | @@ -494,7 +509,7 @@ public: |
| 494 | 509 | #endif |
| 495 | 510 | >::value |
| 496 | 511 | > > |
| 497 | explicit shared_ptr(_Yp* __p) : __ptr_(__p) { | |
| 512 | _LIBCPP_HIDE_FROM_ABI explicit shared_ptr(_Yp* __p) : __ptr_(__p) { | |
| 498 | 513 | unique_ptr<_Yp> __hold(__p); |
| 499 | 514 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
| 500 | 515 | typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT> _CntrlBlk; |
| ... | ... | @@ -508,10 +523,10 @@ public: |
| 508 | 523 | shared_ptr(_Yp* __p, _Dp __d) |
| 509 | 524 | : __ptr_(__p) |
| 510 | 525 | { |
| 511 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 526 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 512 | 527 | try |
| 513 | 528 | { |
| 514 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 529 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 515 | 530 | typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT; |
| 516 | 531 | typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT> _CntrlBlk; |
| 517 | 532 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -520,14 +535,14 @@ public: |
| 520 | 535 | __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); |
| 521 | 536 | #endif // not _LIBCPP_CXX03_LANG |
| 522 | 537 | __enable_weak_this(__p, __p); |
| 523 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 538 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 524 | 539 | } |
| 525 | 540 | catch (...) |
| 526 | 541 | { |
| 527 | 542 | __d(__p); |
| 528 | 543 | throw; |
| 529 | 544 | } |
| 530 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 545 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 531 | 546 | } |
| 532 | 547 | |
| 533 | 548 | template<class _Yp, class _Dp, class _Alloc, class = __enable_if_t<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, _Tp>::value> > |
| ... | ... | @@ -535,10 +550,10 @@ public: |
| 535 | 550 | shared_ptr(_Yp* __p, _Dp __d, _Alloc __a) |
| 536 | 551 | : __ptr_(__p) |
| 537 | 552 | { |
| 538 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 553 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 539 | 554 | try |
| 540 | 555 | { |
| 541 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 556 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 542 | 557 | typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk; |
| 543 | 558 | typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; |
| 544 | 559 | typedef __allocator_destructor<_A2> _D2; |
| ... | ... | @@ -552,14 +567,14 @@ public: |
| 552 | 567 | #endif // not _LIBCPP_CXX03_LANG |
| 553 | 568 | __cntrl_ = _VSTD::addressof(*__hold2.release()); |
| 554 | 569 | __enable_weak_this(__p, __p); |
| 555 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 570 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 556 | 571 | } |
| 557 | 572 | catch (...) |
| 558 | 573 | { |
| 559 | 574 | __d(__p); |
| 560 | 575 | throw; |
| 561 | 576 | } |
| 562 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 577 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 563 | 578 | } |
| 564 | 579 | |
| 565 | 580 | template<class _Dp> |
| ... | ... | @@ -567,10 +582,10 @@ public: |
| 567 | 582 | shared_ptr(nullptr_t __p, _Dp __d) |
| 568 | 583 | : __ptr_(nullptr) |
| 569 | 584 | { |
| 570 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 585 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 571 | 586 | try |
| 572 | 587 | { |
| 573 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 588 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 574 | 589 | typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT; |
| 575 | 590 | typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT> _CntrlBlk; |
| 576 | 591 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -578,14 +593,14 @@ public: |
| 578 | 593 | #else |
| 579 | 594 | __cntrl_ = new _CntrlBlk(__p, __d, _AllocT()); |
| 580 | 595 | #endif // not _LIBCPP_CXX03_LANG |
| 581 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 596 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 582 | 597 | } |
| 583 | 598 | catch (...) |
| 584 | 599 | { |
| 585 | 600 | __d(__p); |
| 586 | 601 | throw; |
| 587 | 602 | } |
| 588 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 603 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 589 | 604 | } |
| 590 | 605 | |
| 591 | 606 | template<class _Dp, class _Alloc> |
| ... | ... | @@ -593,10 +608,10 @@ public: |
| 593 | 608 | shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a) |
| 594 | 609 | : __ptr_(nullptr) |
| 595 | 610 | { |
| 596 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 611 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 597 | 612 | try |
| 598 | 613 | { |
| 599 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 614 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 600 | 615 | typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk; |
| 601 | 616 | typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2; |
| 602 | 617 | typedef __allocator_destructor<_A2> _D2; |
| ... | ... | @@ -609,14 +624,14 @@ public: |
| 609 | 624 | _CntrlBlk(__p, __d, __a); |
| 610 | 625 | #endif // not _LIBCPP_CXX03_LANG |
| 611 | 626 | __cntrl_ = _VSTD::addressof(*__hold2.release()); |
| 612 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 627 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 613 | 628 | } |
| 614 | 629 | catch (...) |
| 615 | 630 | { |
| 616 | 631 | __d(__p); |
| 617 | 632 | throw; |
| 618 | 633 | } |
| 619 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 634 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 620 | 635 | } |
| 621 | 636 | |
| 622 | 637 | template<class _Yp> |
| ... | ... | @@ -629,6 +644,18 @@ public: |
| 629 | 644 | __cntrl_->__add_shared(); |
| 630 | 645 | } |
| 631 | 646 | |
| 647 | // LWG-2996 | |
| 648 | // We don't backport because it is an evolutionary change. | |
| 649 | #if _LIBCPP_STD_VER >= 20 | |
| 650 | template <class _Yp> | |
| 651 | _LIBCPP_HIDE_FROM_ABI shared_ptr(shared_ptr<_Yp>&& __r, element_type* __p) noexcept | |
| 652 | : __ptr_(__p), | |
| 653 | __cntrl_(__r.__cntrl_) { | |
| 654 | __r.__ptr_ = nullptr; | |
| 655 | __r.__cntrl_ = nullptr; | |
| 656 | } | |
| 657 | #endif | |
| 658 | ||
| 632 | 659 | _LIBCPP_HIDE_FROM_ABI |
| 633 | 660 | shared_ptr(const shared_ptr& __r) _NOEXCEPT |
| 634 | 661 | : __ptr_(__r.__ptr_), |
| ... | ... | @@ -699,7 +726,7 @@ public: |
| 699 | 726 | shared_ptr(unique_ptr<_Yp, _Dp>&& __r) |
| 700 | 727 | : __ptr_(__r.get()) |
| 701 | 728 | { |
| 702 | #if _LIBCPP_STD_VER > 11 | |
| 729 | #if _LIBCPP_STD_VER >= 14 | |
| 703 | 730 | if (__ptr_ == nullptr) |
| 704 | 731 | __cntrl_ = nullptr; |
| 705 | 732 | else |
| ... | ... | @@ -722,7 +749,7 @@ public: |
| 722 | 749 | shared_ptr(unique_ptr<_Yp, _Dp>&& __r) |
| 723 | 750 | : __ptr_(__r.get()) |
| 724 | 751 | { |
| 725 | #if _LIBCPP_STD_VER > 11 | |
| 752 | #if _LIBCPP_STD_VER >= 14 | |
| 726 | 753 | if (__ptr_ == nullptr) |
| 727 | 754 | __cntrl_ = nullptr; |
| 728 | 755 | else |
| ... | ... | @@ -895,7 +922,7 @@ public: |
| 895 | 922 | return __cntrl_ == __p.__cntrl_; |
| 896 | 923 | } |
| 897 | 924 | |
| 898 | #if _LIBCPP_STD_VER > 14 | |
| 925 | #if _LIBCPP_STD_VER >= 17 | |
| 899 | 926 | _LIBCPP_HIDE_FROM_ABI |
| 900 | 927 | __add_lvalue_reference_t<element_type> operator[](ptrdiff_t __i) const |
| 901 | 928 | { |
| ... | ... | @@ -975,7 +1002,7 @@ private: |
| 975 | 1002 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr; |
| 976 | 1003 | }; |
| 977 | 1004 | |
| 978 | #if _LIBCPP_STD_VER > 14 | |
| 1005 | #if _LIBCPP_STD_VER >= 17 | |
| 979 | 1006 | template<class _Tp> |
| 980 | 1007 | shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; |
| 981 | 1008 | template<class _Tp, class _Dp> |
| ... | ... | @@ -1024,7 +1051,7 @@ shared_ptr<_Tp> make_shared_for_overwrite() |
| 1024 | 1051 | |
| 1025 | 1052 | #endif // _LIBCPP_STD_VER >= 20 |
| 1026 | 1053 | |
| 1027 | #if _LIBCPP_STD_VER > 14 | |
| 1054 | #if _LIBCPP_STD_VER >= 17 | |
| 1028 | 1055 | |
| 1029 | 1056 | template <size_t _Alignment> |
| 1030 | 1057 | struct __sp_aligned_storage { |
| ... | ... | @@ -1084,7 +1111,7 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count |
| 1084 | 1111 | ~__unbounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_ |
| 1085 | 1112 | |
| 1086 | 1113 | private: |
| 1087 | void __on_zero_shared() _NOEXCEPT override { | |
| 1114 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { | |
| 1088 | 1115 | #if _LIBCPP_STD_VER >= 20 |
| 1089 | 1116 | if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { |
| 1090 | 1117 | std::__reverse_destroy(__data_, __data_ + __count_); |
| ... | ... | @@ -1098,7 +1125,7 @@ private: |
| 1098 | 1125 | #endif |
| 1099 | 1126 | } |
| 1100 | 1127 | |
| 1101 | void __on_zero_shared_weak() _NOEXCEPT override { | |
| 1128 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { | |
| 1102 | 1129 | using _AlignedStorage = __sp_aligned_storage<alignof(__unbounded_array_control_block)>; |
| 1103 | 1130 | using _StorageAlloc = __allocator_traits_rebind_t<_Alloc, _AlignedStorage>; |
| 1104 | 1131 | using _PointerTraits = pointer_traits<typename allocator_traits<_StorageAlloc>::pointer>; |
| ... | ... | @@ -1170,7 +1197,7 @@ struct __bounded_array_control_block<_Tp[_Count], _Alloc> |
| 1170 | 1197 | ~__bounded_array_control_block() override { } // can't be `= default` because of the sometimes-non-trivial union member __data_ |
| 1171 | 1198 | |
| 1172 | 1199 | private: |
| 1173 | void __on_zero_shared() _NOEXCEPT override { | |
| 1200 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override { | |
| 1174 | 1201 | #if _LIBCPP_STD_VER >= 20 |
| 1175 | 1202 | if constexpr (is_same_v<typename _Alloc::value_type, __for_overwrite_tag>) { |
| 1176 | 1203 | std::__reverse_destroy(__data_, __data_ + _Count); |
| ... | ... | @@ -1184,7 +1211,7 @@ private: |
| 1184 | 1211 | #endif |
| 1185 | 1212 | } |
| 1186 | 1213 | |
| 1187 | void __on_zero_shared_weak() _NOEXCEPT override { | |
| 1214 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared_weak() _NOEXCEPT override { | |
| 1188 | 1215 | using _ControlBlockAlloc = __allocator_traits_rebind_t<_Alloc, __bounded_array_control_block>; |
| 1189 | 1216 | using _PointerTraits = pointer_traits<typename allocator_traits<_ControlBlockAlloc>::pointer>; |
| 1190 | 1217 | |
| ... | ... | @@ -1214,9 +1241,9 @@ shared_ptr<_Array> __allocate_shared_bounded_array(const _Alloc& __a, _Arg&& ... |
| 1214 | 1241 | return shared_ptr<_Array>::__create_with_control_block(__control_block->__get_data(), __control_block); |
| 1215 | 1242 | } |
| 1216 | 1243 | |
| 1217 | #endif // _LIBCPP_STD_VER > 14 | |
| 1244 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1218 | 1245 | |
| 1219 | #if _LIBCPP_STD_VER > 17 | |
| 1246 | #if _LIBCPP_STD_VER >= 20 | |
| 1220 | 1247 | |
| 1221 | 1248 | // bounded array variants |
| 1222 | 1249 | template<class _Tp, class _Alloc, class = __enable_if_t<is_bounded_array<_Tp>::value>> |
| ... | ... | @@ -1308,7 +1335,7 @@ shared_ptr<_Tp> make_shared_for_overwrite(size_t __n) |
| 1308 | 1335 | return std::__allocate_shared_unbounded_array<_Tp>(allocator<__for_overwrite_tag>(), __n); |
| 1309 | 1336 | } |
| 1310 | 1337 | |
| 1311 | #endif // _LIBCPP_STD_VER > 17 | |
| 1338 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1312 | 1339 | |
| 1313 | 1340 | template<class _Tp, class _Up> |
| 1314 | 1341 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1368,7 +1395,7 @@ operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT |
| 1368 | 1395 | |
| 1369 | 1396 | #endif // _LIBCPP_STD_VER <= 17 |
| 1370 | 1397 | |
| 1371 | #if _LIBCPP_STD_VER > 17 | |
| 1398 | #if _LIBCPP_STD_VER >= 20 | |
| 1372 | 1399 | template<class _Tp, class _Up> |
| 1373 | 1400 | _LIBCPP_HIDE_FROM_ABI strong_ordering |
| 1374 | 1401 | operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept |
| ... | ... | @@ -1477,7 +1504,7 @@ operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT |
| 1477 | 1504 | |
| 1478 | 1505 | #endif // _LIBCPP_STD_VER <= 17 |
| 1479 | 1506 | |
| 1480 | #if _LIBCPP_STD_VER > 17 | |
| 1507 | #if _LIBCPP_STD_VER >= 20 | |
| 1481 | 1508 | template<class _Tp> |
| 1482 | 1509 | _LIBCPP_HIDE_FROM_ABI strong_ordering |
| 1483 | 1510 | operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept |
| ... | ... | @@ -1504,6 +1531,15 @@ static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| 1504 | 1531 | typename shared_ptr<_Tp>::element_type*>(__r.get())); |
| 1505 | 1532 | } |
| 1506 | 1533 | |
| 1534 | // LWG-2996 | |
| 1535 | // We don't backport because it is an evolutionary change. | |
| 1536 | #if _LIBCPP_STD_VER >= 20 | |
| 1537 | template <class _Tp, class _Up> | |
| 1538 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> static_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |
| 1539 | return shared_ptr<_Tp>(std::move(__r), static_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |
| 1540 | } | |
| 1541 | #endif | |
| 1542 | ||
| 1507 | 1543 | template<class _Tp, class _Up> |
| 1508 | 1544 | inline _LIBCPP_INLINE_VISIBILITY |
| 1509 | 1545 | shared_ptr<_Tp> |
| ... | ... | @@ -1514,6 +1550,16 @@ dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| 1514 | 1550 | return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>(); |
| 1515 | 1551 | } |
| 1516 | 1552 | |
| 1553 | // LWG-2996 | |
| 1554 | // We don't backport because it is an evolutionary change. | |
| 1555 | #if _LIBCPP_STD_VER >= 20 | |
| 1556 | template <class _Tp, class _Up> | |
| 1557 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> dynamic_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |
| 1558 | auto* __p = dynamic_cast<typename shared_ptr<_Tp>::element_type*>(__r.get()); | |
| 1559 | return __p ? shared_ptr<_Tp>(std::move(__r), __p) : shared_ptr<_Tp>(); | |
| 1560 | } | |
| 1561 | #endif | |
| 1562 | ||
| 1517 | 1563 | template<class _Tp, class _Up> |
| 1518 | 1564 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> |
| 1519 | 1565 | const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| ... | ... | @@ -1522,6 +1568,15 @@ const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| 1522 | 1568 | return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get())); |
| 1523 | 1569 | } |
| 1524 | 1570 | |
| 1571 | // LWG-2996 | |
| 1572 | // We don't backport because it is an evolutionary change. | |
| 1573 | #if _LIBCPP_STD_VER >= 20 | |
| 1574 | template <class _Tp, class _Up> | |
| 1575 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> const_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |
| 1576 | return shared_ptr<_Tp>(std::move(__r), const_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |
| 1577 | } | |
| 1578 | #endif | |
| 1579 | ||
| 1525 | 1580 | template<class _Tp, class _Up> |
| 1526 | 1581 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> |
| 1527 | 1582 | reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| ... | ... | @@ -1531,6 +1586,15 @@ reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT |
| 1531 | 1586 | typename shared_ptr<_Tp>::element_type*>(__r.get())); |
| 1532 | 1587 | } |
| 1533 | 1588 | |
| 1589 | // LWG-2996 | |
| 1590 | // We don't backport because it is an evolutionary change. | |
| 1591 | #if _LIBCPP_STD_VER >= 20 | |
| 1592 | template <class _Tp, class _Up> | |
| 1593 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> reinterpret_pointer_cast(shared_ptr<_Up>&& __r) noexcept { | |
| 1594 | return shared_ptr<_Tp>(std::move(__r), reinterpret_cast<typename shared_ptr<_Tp>::element_type*>(__r.get())); | |
| 1595 | } | |
| 1596 | #endif | |
| 1597 | ||
| 1534 | 1598 | #ifndef _LIBCPP_HAS_NO_RTTI |
| 1535 | 1599 | |
| 1536 | 1600 | template<class _Dp, class _Tp> |
| ... | ... | @@ -1547,7 +1611,7 @@ template<class _Tp> |
| 1547 | 1611 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr |
| 1548 | 1612 | { |
| 1549 | 1613 | public: |
| 1550 | #if _LIBCPP_STD_VER > 14 | |
| 1614 | #if _LIBCPP_STD_VER >= 17 | |
| 1551 | 1615 | typedef remove_extent_t<_Tp> element_type; |
| 1552 | 1616 | #else |
| 1553 | 1617 | typedef _Tp element_type; |
| ... | ... | @@ -1574,7 +1638,7 @@ public: |
| 1574 | 1638 | template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r, |
| 1575 | 1639 | typename enable_if<__compatible_with<_Yp, _Tp>::value, __nat*>::type = 0) |
| 1576 | 1640 | _NOEXCEPT; |
| 1577 | ~weak_ptr(); | |
| 1641 | _LIBCPP_HIDE_FROM_ABI ~weak_ptr(); | |
| 1578 | 1642 | |
| 1579 | 1643 | _LIBCPP_INLINE_VISIBILITY |
| 1580 | 1644 | weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT; |
| ... | ... | @@ -1618,7 +1682,7 @@ public: |
| 1618 | 1682 | _LIBCPP_INLINE_VISIBILITY |
| 1619 | 1683 | bool expired() const _NOEXCEPT |
| 1620 | 1684 | {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;} |
| 1621 | shared_ptr<_Tp> lock() const _NOEXCEPT; | |
| 1685 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> lock() const _NOEXCEPT; | |
| 1622 | 1686 | template<class _Up> |
| 1623 | 1687 | _LIBCPP_INLINE_VISIBILITY |
| 1624 | 1688 | bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT |
| ... | ... | @@ -1632,7 +1696,7 @@ public: |
| 1632 | 1696 | template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr; |
| 1633 | 1697 | }; |
| 1634 | 1698 | |
| 1635 | #if _LIBCPP_STD_VER > 14 | |
| 1699 | #if _LIBCPP_STD_VER >= 17 | |
| 1636 | 1700 | template<class _Tp> |
| 1637 | 1701 | weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; |
| 1638 | 1702 | #endif |
| ... | ... | @@ -1808,7 +1872,7 @@ weak_ptr<_Tp>::lock() const _NOEXCEPT |
| 1808 | 1872 | return __r; |
| 1809 | 1873 | } |
| 1810 | 1874 | |
| 1811 | #if _LIBCPP_STD_VER > 14 | |
| 1875 | #if _LIBCPP_STD_VER >= 17 | |
| 1812 | 1876 | template <class _Tp = void> struct owner_less; |
| 1813 | 1877 | #else |
| 1814 | 1878 | template <class _Tp> struct owner_less; |
| ... | ... | @@ -1845,7 +1909,7 @@ struct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> > |
| 1845 | 1909 | {return __x.owner_before(__y);} |
| 1846 | 1910 | }; |
| 1847 | 1911 | |
| 1848 | #if _LIBCPP_STD_VER > 14 | |
| 1912 | #if _LIBCPP_STD_VER >= 17 | |
| 1849 | 1913 | template <> |
| 1850 | 1914 | struct _LIBCPP_TEMPLATE_VIS owner_less<void> |
| 1851 | 1915 | { |
| ... | ... | @@ -1891,7 +1955,7 @@ public: |
| 1891 | 1955 | shared_ptr<_Tp const> shared_from_this() const |
| 1892 | 1956 | {return shared_ptr<const _Tp>(__weak_this_);} |
| 1893 | 1957 | |
| 1894 | #if _LIBCPP_STD_VER > 14 | |
| 1958 | #if _LIBCPP_STD_VER >= 17 | |
| 1895 | 1959 | _LIBCPP_INLINE_VISIBILITY |
| 1896 | 1960 | weak_ptr<_Tp> weak_from_this() _NOEXCEPT |
| 1897 | 1961 | { return __weak_this_; } |
| ... | ... | @@ -1899,7 +1963,7 @@ public: |
| 1899 | 1963 | _LIBCPP_INLINE_VISIBILITY |
| 1900 | 1964 | weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT |
| 1901 | 1965 | { return __weak_this_; } |
| 1902 | #endif // _LIBCPP_STD_VER > 14 | |
| 1966 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1903 | 1967 | |
| 1904 | 1968 | template <class _Up> friend class shared_ptr; |
| 1905 | 1969 | }; |
| ... | ... | @@ -1929,7 +1993,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); |
| 1929 | 1993 | |
| 1930 | 1994 | #if !defined(_LIBCPP_HAS_NO_THREADS) |
| 1931 | 1995 | |
| 1932 | class _LIBCPP_TYPE_VIS __sp_mut | |
| 1996 | class _LIBCPP_EXPORTED_FROM_ABI __sp_mut | |
| 1933 | 1997 | { |
| 1934 | 1998 | void* __lx_; |
| 1935 | 1999 | public: |
| ... | ... | @@ -1941,10 +2005,10 @@ private: |
| 1941 | 2005 | __sp_mut(const __sp_mut&); |
| 1942 | 2006 | __sp_mut& operator=(const __sp_mut&); |
| 1943 | 2007 | |
| 1944 | friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*); | |
| 2008 | friend _LIBCPP_EXPORTED_FROM_ABI __sp_mut& __get_sp_mut(const void*); | |
| 1945 | 2009 | }; |
| 1946 | 2010 | |
| 1947 | _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR | |
| 2011 | _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR | |
| 1948 | 2012 | __sp_mut& __get_sp_mut(const void*); |
| 1949 | 2013 | |
| 1950 | 2014 | template <class _Tp> |
lib/libcxx/include/__memory/swap_allocator.h+2-2| ... | ... | @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | 24 | template <typename _Alloc> |
| 25 | 25 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2, true_type) |
| 26 | #if _LIBCPP_STD_VER > 11 | |
| 26 | #if _LIBCPP_STD_VER >= 14 | |
| 27 | 27 | _NOEXCEPT |
| 28 | 28 | #else |
| 29 | 29 | _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) |
| ... | ... | @@ -39,7 +39,7 @@ __swap_allocator(_Alloc&, _Alloc&, false_type) _NOEXCEPT {} |
| 39 | 39 | |
| 40 | 40 | template <typename _Alloc> |
| 41 | 41 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator(_Alloc& __a1, _Alloc& __a2) |
| 42 | #if _LIBCPP_STD_VER > 11 | |
| 42 | #if _LIBCPP_STD_VER >= 14 | |
| 43 | 43 | _NOEXCEPT |
| 44 | 44 | #else |
| 45 | 45 | _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value) |
lib/libcxx/include/__memory/temp_value.h+4-4| ... | ... | @@ -32,7 +32,7 @@ struct __temp_value { |
| 32 | 32 | #endif |
| 33 | 33 | _Alloc &__a; |
| 34 | 34 | |
| 35 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() { | |
| 35 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp *__addr() { | |
| 36 | 36 | #ifdef _LIBCPP_CXX03_LANG |
| 37 | 37 | return reinterpret_cast<_Tp*>(std::addressof(__v)); |
| 38 | 38 | #else |
| ... | ... | @@ -40,15 +40,15 @@ struct __temp_value { |
| 40 | 40 | #endif |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & get() { return *__addr(); } | |
| 43 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp & get() { return *__addr(); } | |
| 44 | 44 | |
| 45 | 45 | template<class... _Args> |
| 46 | _LIBCPP_NO_CFI | |
| 46 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI | |
| 47 | 47 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) { |
| 48 | 48 | _Traits::construct(__a, __addr(), std::forward<_Args>(__args)...); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); } | |
| 51 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~__temp_value() { _Traits::destroy(__a, __addr()); } | |
| 52 | 52 | }; |
| 53 | 53 | |
| 54 | 54 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__memory/uninitialized_algorithms.h+44-33| ... | ... | @@ -12,6 +12,8 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/copy.h> |
| 14 | 14 | #include <__algorithm/move.h> |
| 15 | #include <__algorithm/unwrap_iter.h> | |
| 16 | #include <__algorithm/unwrap_range.h> | |
| 15 | 17 | #include <__config> |
| 16 | 18 | #include <__iterator/iterator_traits.h> |
| 17 | 19 | #include <__iterator/reverse_iterator.h> |
| ... | ... | @@ -58,12 +60,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> |
| 58 | 60 | __uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast, |
| 59 | 61 | _ForwardIterator __ofirst, _Sentinel2 __olast) { |
| 60 | 62 | _ForwardIterator __idx = __ofirst; |
| 61 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 63 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 62 | 64 | try { |
| 63 | 65 | #endif |
| 64 | 66 | for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx) |
| 65 | 67 | ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); |
| 66 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 68 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 67 | 69 | } catch (...) { |
| 68 | 70 | _VSTD::__destroy(__ofirst, __idx); |
| 69 | 71 | throw; |
| ... | ... | @@ -90,12 +92,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> |
| 90 | 92 | __uninitialized_copy_n(_InputIterator __ifirst, _Size __n, |
| 91 | 93 | _ForwardIterator __ofirst, _Sentinel __olast) { |
| 92 | 94 | _ForwardIterator __idx = __ofirst; |
| 93 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 95 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 94 | 96 | try { |
| 95 | 97 | #endif |
| 96 | 98 | for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n) |
| 97 | 99 | ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); |
| 98 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 100 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 99 | 101 | } catch (...) { |
| 100 | 102 | _VSTD::__destroy(__ofirst, __idx); |
| 101 | 103 | throw; |
| ... | ... | @@ -121,13 +123,13 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 121 | 123 | _ForwardIterator __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) |
| 122 | 124 | { |
| 123 | 125 | _ForwardIterator __idx = __first; |
| 124 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 126 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 125 | 127 | try |
| 126 | 128 | { |
| 127 | 129 | #endif |
| 128 | 130 | for (; __idx != __last; ++__idx) |
| 129 | 131 | ::new (_VSTD::__voidify(*__idx)) _ValueType(__x); |
| 130 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 132 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 131 | 133 | } |
| 132 | 134 | catch (...) |
| 133 | 135 | { |
| ... | ... | @@ -154,13 +156,13 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 154 | 156 | _ForwardIterator __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) |
| 155 | 157 | { |
| 156 | 158 | _ForwardIterator __idx = __first; |
| 157 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 159 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 158 | 160 | try |
| 159 | 161 | { |
| 160 | 162 | #endif |
| 161 | 163 | for (; __n > 0; ++__idx, (void) --__n) |
| 162 | 164 | ::new (_VSTD::__voidify(*__idx)) _ValueType(__x); |
| 163 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 165 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 164 | 166 | } |
| 165 | 167 | catch (...) |
| 166 | 168 | { |
| ... | ... | @@ -180,7 +182,7 @@ _ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const |
| 180 | 182 | return _VSTD::__uninitialized_fill_n<_ValueType>(__first, __n, __x); |
| 181 | 183 | } |
| 182 | 184 | |
| 183 | #if _LIBCPP_STD_VER > 14 | |
| 185 | #if _LIBCPP_STD_VER >= 17 | |
| 184 | 186 | |
| 185 | 187 | // uninitialized_default_construct |
| 186 | 188 | |
| ... | ... | @@ -188,12 +190,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel> |
| 188 | 190 | inline _LIBCPP_HIDE_FROM_ABI |
| 189 | 191 | _ForwardIterator __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) { |
| 190 | 192 | auto __idx = __first; |
| 191 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 193 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 192 | 194 | try { |
| 193 | 195 | #endif |
| 194 | 196 | for (; __idx != __last; ++__idx) |
| 195 | 197 | ::new (_VSTD::__voidify(*__idx)) _ValueType; |
| 196 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 198 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 197 | 199 | } catch (...) { |
| 198 | 200 | _VSTD::__destroy(__first, __idx); |
| 199 | 201 | throw; |
| ... | ... | @@ -217,12 +219,12 @@ template <class _ValueType, class _ForwardIterator, class _Size> |
| 217 | 219 | inline _LIBCPP_HIDE_FROM_ABI |
| 218 | 220 | _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { |
| 219 | 221 | auto __idx = __first; |
| 220 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 222 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 221 | 223 | try { |
| 222 | 224 | #endif |
| 223 | 225 | for (; __n > 0; ++__idx, (void) --__n) |
| 224 | 226 | ::new (_VSTD::__voidify(*__idx)) _ValueType; |
| 225 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 227 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 226 | 228 | } catch (...) { |
| 227 | 229 | _VSTD::__destroy(__first, __idx); |
| 228 | 230 | throw; |
| ... | ... | @@ -245,12 +247,12 @@ template <class _ValueType, class _ForwardIterator, class _Sentinel> |
| 245 | 247 | inline _LIBCPP_HIDE_FROM_ABI |
| 246 | 248 | _ForwardIterator __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) { |
| 247 | 249 | auto __idx = __first; |
| 248 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 250 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 249 | 251 | try { |
| 250 | 252 | #endif |
| 251 | 253 | for (; __idx != __last; ++__idx) |
| 252 | 254 | ::new (_VSTD::__voidify(*__idx)) _ValueType(); |
| 253 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 255 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 254 | 256 | } catch (...) { |
| 255 | 257 | _VSTD::__destroy(__first, __idx); |
| 256 | 258 | throw; |
| ... | ... | @@ -274,12 +276,12 @@ template <class _ValueType, class _ForwardIterator, class _Size> |
| 274 | 276 | inline _LIBCPP_HIDE_FROM_ABI |
| 275 | 277 | _ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { |
| 276 | 278 | auto __idx = __first; |
| 277 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 279 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 278 | 280 | try { |
| 279 | 281 | #endif |
| 280 | 282 | for (; __n > 0; ++__idx, (void) --__n) |
| 281 | 283 | ::new (_VSTD::__voidify(*__idx)) _ValueType(); |
| 282 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 284 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 283 | 285 | } catch (...) { |
| 284 | 286 | _VSTD::__destroy(__first, __idx); |
| 285 | 287 | throw; |
| ... | ... | @@ -304,13 +306,13 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> |
| 304 | 306 | __uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast, |
| 305 | 307 | _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) { |
| 306 | 308 | auto __idx = __ofirst; |
| 307 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 309 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 308 | 310 | try { |
| 309 | 311 | #endif |
| 310 | 312 | for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) { |
| 311 | 313 | ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); |
| 312 | 314 | } |
| 313 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 315 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 314 | 316 | } catch (...) { |
| 315 | 317 | _VSTD::__destroy(__ofirst, __idx); |
| 316 | 318 | throw; |
| ... | ... | @@ -338,12 +340,12 @@ inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> |
| 338 | 340 | __uninitialized_move_n(_InputIterator __ifirst, _Size __n, |
| 339 | 341 | _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) { |
| 340 | 342 | auto __idx = __ofirst; |
| 341 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 343 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 342 | 344 | try { |
| 343 | 345 | #endif |
| 344 | 346 | for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n) |
| 345 | 347 | ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); |
| 346 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 348 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 347 | 349 | } catch (...) { |
| 348 | 350 | _VSTD::__destroy(__ofirst, __idx); |
| 349 | 351 | throw; |
| ... | ... | @@ -371,7 +373,7 @@ uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofir |
| 371 | 373 | // This function assumes that destructors do not throw, and that the allocator is bound to |
| 372 | 374 | // the correct type. |
| 373 | 375 | template<class _Alloc, class _BidirIter, class = __enable_if_t< |
| 374 | __is_cpp17_bidirectional_iterator<_BidirIter>::value | |
| 376 | __has_bidirectional_iterator_category<_BidirIter>::value | |
| 375 | 377 | >> |
| 376 | 378 | _LIBCPP_HIDE_FROM_ABI |
| 377 | 379 | constexpr void __allocator_destroy_multidimensional(_Alloc& __alloc, _BidirIter __first, _BidirIter __last) noexcept { |
| ... | ... | @@ -512,7 +514,7 @@ __uninitialized_allocator_value_construct_n_multidimensional(_Alloc& __alloc, _B |
| 512 | 514 | __guard.__complete(); |
| 513 | 515 | } |
| 514 | 516 | |
| 515 | #endif // _LIBCPP_STD_VER > 14 | |
| 517 | #endif // _LIBCPP_STD_VER >= 17 | |
| 516 | 518 | |
| 517 | 519 | // Destroy all elements in [__first, __last) from left to right using allocator destruction. |
| 518 | 520 | template <class _Alloc, class _Iter, class _Sent> |
| ... | ... | @@ -545,7 +547,7 @@ private: |
| 545 | 547 | // already copied elements are destroyed in reverse order of their construction. |
| 546 | 548 | template <class _Alloc, class _Iter1, class _Sent1, class _Iter2> |
| 547 | 549 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 |
| 548 | __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) { | |
| 550 | __uninitialized_allocator_copy_impl(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) { | |
| 549 | 551 | auto __destruct_first = __first2; |
| 550 | 552 | auto __guard = |
| 551 | 553 | std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); |
| ... | ... | @@ -565,14 +567,16 @@ template <class _Type> |
| 565 | 567 | struct __allocator_has_trivial_copy_construct<allocator<_Type>, _Type> : true_type {}; |
| 566 | 568 | |
| 567 | 569 | template <class _Alloc, |
| 568 | class _Type, | |
| 569 | class _RawType = __remove_const_t<_Type>, | |
| 570 | class _In, | |
| 571 | class _RawTypeIn = __remove_const_t<_In>, | |
| 572 | class _Out, | |
| 570 | 573 | __enable_if_t< |
| 571 | // using _RawType because of the allocator<T const> extension | |
| 572 | is_trivially_copy_constructible<_RawType>::value && is_trivially_copy_assignable<_RawType>::value && | |
| 573 | __allocator_has_trivial_copy_construct<_Alloc, _RawType>::value>* = nullptr> | |
| 574 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Type* | |
| 575 | __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __last1, _Type* __first2) { | |
| 574 | // using _RawTypeIn because of the allocator<T const> extension | |
| 575 | is_trivially_copy_constructible<_RawTypeIn>::value && is_trivially_copy_assignable<_RawTypeIn>::value && | |
| 576 | is_same<__remove_const_t<_In>, __remove_const_t<_Out> >::value && | |
| 577 | __allocator_has_trivial_copy_construct<_Alloc, _RawTypeIn>::value>* = nullptr> | |
| 578 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Out* | |
| 579 | __uninitialized_allocator_copy_impl(_Alloc&, _In* __first1, _In* __last1, _Out* __first2) { | |
| 576 | 580 | // TODO: Remove the const_cast once we drop support for std::allocator<T const> |
| 577 | 581 | if (__libcpp_is_constant_evaluated()) { |
| 578 | 582 | while (__first1 != __last1) { |
| ... | ... | @@ -582,10 +586,17 @@ __uninitialized_allocator_copy(_Alloc&, const _Type* __first1, const _Type* __la |
| 582 | 586 | } |
| 583 | 587 | return __first2; |
| 584 | 588 | } else { |
| 585 | return std::copy(__first1, __last1, const_cast<_RawType*>(__first2)); | |
| 589 | return std::copy(__first1, __last1, const_cast<_RawTypeIn*>(__first2)); | |
| 586 | 590 | } |
| 587 | 591 | } |
| 588 | 592 | |
| 593 | template <class _Alloc, class _Iter1, class _Sent1, class _Iter2> | |
| 594 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_allocator_copy(_Alloc& __alloc, _Iter1 __first1, _Sent1 __last1, _Iter2 __first2) { | |
| 595 | auto __unwrapped_range = std::__unwrap_range(__first1, __last1); | |
| 596 | auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2)); | |
| 597 | return std::__rewrap_iter(__first2, __result); | |
| 598 | } | |
| 599 | ||
| 589 | 600 | // Move-construct the elements [__first1, __last1) into [__first2, __first2 + N) |
| 590 | 601 | // if the move constructor is noexcept, where N is distance(__first1, __last1). |
| 591 | 602 | // |
| ... | ... | @@ -600,7 +611,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter2 __uninitialized_alloc |
| 600 | 611 | auto __guard = |
| 601 | 612 | std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); |
| 602 | 613 | while (__first1 != __last1) { |
| 603 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 614 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 604 | 615 | allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move_if_noexcept(*__first1)); |
| 605 | 616 | #else |
| 606 | 617 | allocator_traits<_Alloc>::construct(__alloc, std::__to_address(__first2), std::move(*__first1)); |
lib/libcxx/include/__memory/unique_ptr.h+10-5| ... | ... | @@ -44,6 +44,9 @@ |
| 44 | 44 | # pragma GCC system_header |
| 45 | 45 | #endif |
| 46 | 46 | |
| 47 | _LIBCPP_PUSH_MACROS | |
| 48 | #include <__undef_macros> | |
| 49 | ||
| 47 | 50 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 48 | 51 | |
| 49 | 52 | template <class _Tp> |
| ... | ... | @@ -115,7 +118,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> { |
| 115 | 118 | }; |
| 116 | 119 | |
| 117 | 120 | #if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI) |
| 118 | # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi)) | |
| 121 | # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__)) | |
| 119 | 122 | #else |
| 120 | 123 | # define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI |
| 121 | 124 | #endif |
| ... | ... | @@ -556,7 +559,7 @@ bool |
| 556 | 559 | operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} |
| 557 | 560 | |
| 558 | 561 | |
| 559 | #if _LIBCPP_STD_VER > 17 | |
| 562 | #if _LIBCPP_STD_VER >= 20 | |
| 560 | 563 | template <class _T1, class _D1, class _T2, class _D2> |
| 561 | 564 | requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer, |
| 562 | 565 | typename unique_ptr<_T2, _D2>::pointer> |
| ... | ... | @@ -650,7 +653,7 @@ operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) { |
| 650 | 653 | return !(nullptr < __x); |
| 651 | 654 | } |
| 652 | 655 | |
| 653 | #if _LIBCPP_STD_VER > 17 | |
| 656 | #if _LIBCPP_STD_VER >= 20 | |
| 654 | 657 | template <class _T1, class _D1> |
| 655 | 658 | requires three_way_comparable< |
| 656 | 659 | typename unique_ptr<_T1, _D1>::pointer> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| ... | ... | @@ -660,7 +663,7 @@ operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) { |
| 660 | 663 | } |
| 661 | 664 | #endif |
| 662 | 665 | |
| 663 | #if _LIBCPP_STD_VER > 11 | |
| 666 | #if _LIBCPP_STD_VER >= 14 | |
| 664 | 667 | |
| 665 | 668 | template<class _Tp> |
| 666 | 669 | struct __unique_if |
| ... | ... | @@ -697,7 +700,7 @@ template<class _Tp, class... _Args> |
| 697 | 700 | typename __unique_if<_Tp>::__unique_array_known_bound |
| 698 | 701 | make_unique(_Args&&...) = delete; |
| 699 | 702 | |
| 700 | #endif // _LIBCPP_STD_VER > 11 | |
| 703 | #endif // _LIBCPP_STD_VER >= 14 | |
| 701 | 704 | |
| 702 | 705 | #if _LIBCPP_STD_VER >= 20 |
| 703 | 706 | |
| ... | ... | @@ -743,4 +746,6 @@ struct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper< |
| 743 | 746 | |
| 744 | 747 | _LIBCPP_END_NAMESPACE_STD |
| 745 | 748 | |
| 749 | _LIBCPP_POP_MACROS | |
| 750 | ||
| 746 | 751 | #endif // _LIBCPP___MEMORY_UNIQUE_PTR_H |
lib/libcxx/include/__memory/uses_allocator.h+2-2| ... | ... | @@ -49,9 +49,9 @@ struct _LIBCPP_TEMPLATE_VIS uses_allocator |
| 49 | 49 | { |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | #if _LIBCPP_STD_VER > 14 | |
| 52 | #if _LIBCPP_STD_VER >= 17 | |
| 53 | 53 | template <class _Tp, class _Alloc> |
| 54 | inline constexpr size_t uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; | |
| 54 | inline constexpr bool uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; | |
| 55 | 55 | #endif |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__memory/uses_allocator_construction.h+7-2| ... | ... | @@ -23,6 +23,9 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 26 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 30 | |
| 28 | 31 | #if _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -83,7 +86,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, _Up&& __u, _Vp&& __v) |
| 83 | 86 | std::forward_as_tuple(std::forward<_Vp>(__v))); |
| 84 | 87 | } |
| 85 | 88 | |
| 86 | # if _LIBCPP_STD_VER > 20 | |
| 89 | # if _LIBCPP_STD_VER >= 23 | |
| 87 | 90 | template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0> |
| 88 | 91 | _LIBCPP_HIDE_FROM_ABI constexpr auto |
| 89 | 92 | __uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>& __pair) noexcept { |
| ... | ... | @@ -109,7 +112,7 @@ __uses_allocator_construction_args(const _Alloc& __alloc, pair<_Up, _Vp>&& __pai |
| 109 | 112 | std::forward_as_tuple(std::get<1>(std::move(__pair)))); |
| 110 | 113 | } |
| 111 | 114 | |
| 112 | # if _LIBCPP_STD_VER > 20 | |
| 115 | # if _LIBCPP_STD_VER >= 23 | |
| 113 | 116 | template <class _Pair, class _Alloc, class _Up, class _Vp, __enable_if_t<__is_std_pair<_Pair>, int> = 0> |
| 114 | 117 | _LIBCPP_HIDE_FROM_ABI constexpr auto |
| 115 | 118 | __uses_allocator_construction_args(const _Alloc& __alloc, const pair<_Up, _Vp>&& __pair) noexcept { |
| ... | ... | @@ -218,4 +221,6 @@ uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Ar |
| 218 | 221 | |
| 219 | 222 | _LIBCPP_END_NAMESPACE_STD |
| 220 | 223 | |
| 224 | _LIBCPP_POP_MACROS | |
| 225 | ||
| 221 | 226 | #endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H |
lib/libcxx/include/__memory_resource/memory_resource.h+24-9| ... | ... | @@ -9,14 +9,16 @@ |
| 9 | 9 | #ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H |
| 10 | 10 | #define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 14 | #include <__fwd/memory_resource.h> | |
| 13 | 15 | #include <cstddef> |
| 14 | 16 | |
| 15 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 16 | 18 | # pragma GCC system_header |
| 17 | 19 | #endif |
| 18 | 20 | |
| 19 | #if _LIBCPP_STD_VER > 14 | |
| 21 | #if _LIBCPP_STD_VER >= 17 | |
| 20 | 22 | |
| 21 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 24 | |
| ... | ... | @@ -24,7 +26,7 @@ namespace pmr { |
| 24 | 26 | |
| 25 | 27 | // [mem.res.class] |
| 26 | 28 | |
| 27 | class _LIBCPP_TYPE_VIS memory_resource { | |
| 29 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource { | |
| 28 | 30 | static const size_t __max_align = alignof(max_align_t); |
| 29 | 31 | |
| 30 | 32 | public: |
| ... | ... | @@ -51,25 +53,38 @@ private: |
| 51 | 53 | |
| 52 | 54 | // [mem.res.eq] |
| 53 | 55 | |
| 54 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | |
| 56 | inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool | |
| 57 | operator==(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | |
| 55 | 58 | return &__lhs == &__rhs || __lhs.is_equal(__rhs); |
| 56 | 59 | } |
| 57 | 60 | |
| 58 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | |
| 61 | # if _LIBCPP_STD_VER <= 17 | |
| 62 | ||
| 63 | inline _LIBCPP_AVAILABILITY_PMR _LIBCPP_HIDE_FROM_ABI bool | |
| 64 | operator!=(const memory_resource& __lhs, const memory_resource& __rhs) noexcept { | |
| 59 | 65 | return !(__lhs == __rhs); |
| 60 | 66 | } |
| 61 | 67 | |
| 68 | # endif | |
| 69 | ||
| 62 | 70 | // [mem.res.global] |
| 63 | 71 | |
| 64 | [[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* get_default_resource() noexcept; | |
| 65 | [[__gnu__::__returns_nonnull__]] _LIBCPP_FUNC_VIS memory_resource* set_default_resource(memory_resource*) noexcept; | |
| 66 | [[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* new_delete_resource() noexcept; | |
| 67 | [[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_FUNC_VIS memory_resource* null_memory_resource() noexcept; | |
| 72 | [[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource* | |
| 73 | get_default_resource() noexcept; | |
| 74 | ||
| 75 | [[__gnu__::__returns_nonnull__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource* | |
| 76 | set_default_resource(memory_resource*) noexcept; | |
| 77 | ||
| 78 | [[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource* | |
| 79 | new_delete_resource() noexcept; | |
| 80 | ||
| 81 | [[using __gnu__: __returns_nonnull__, __const__]] _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource* | |
| 82 | null_memory_resource() noexcept; | |
| 68 | 83 | |
| 69 | 84 | } // namespace pmr |
| 70 | 85 | |
| 71 | 86 | _LIBCPP_END_NAMESPACE_STD |
| 72 | 87 | |
| 73 | #endif // _LIBCPP_STD_VER > 14 | |
| 88 | #endif // _LIBCPP_STD_VER >= 17 | |
| 74 | 89 | |
| 75 | 90 | #endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H |
lib/libcxx/include/__memory_resource/monotonic_buffer_resource.h+7-4| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H |
| 10 | 10 | #define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | #include <__memory/addressof.h> |
| 14 | 15 | #include <__memory_resource/memory_resource.h> |
| ... | ... | @@ -18,7 +19,7 @@ |
| 18 | 19 | # pragma GCC system_header |
| 19 | 20 | #endif |
| 20 | 21 | |
| 21 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 22 | 23 | |
| 23 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 25 | |
| ... | ... | @@ -26,7 +27,7 @@ namespace pmr { |
| 26 | 27 | |
| 27 | 28 | // [mem.res.monotonic.buffer] |
| 28 | 29 | |
| 29 | class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource { | |
| 30 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI monotonic_buffer_resource : public memory_resource { | |
| 30 | 31 | static const size_t __default_buffer_capacity = 1024; |
| 31 | 32 | static const size_t __default_buffer_alignment = 16; |
| 32 | 33 | |
| ... | ... | @@ -35,7 +36,9 @@ class _LIBCPP_TYPE_VIS monotonic_buffer_resource : public memory_resource { |
| 35 | 36 | char* __start_; |
| 36 | 37 | char* __cur_; |
| 37 | 38 | size_t __align_; |
| 38 | size_t __allocation_size() { return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); } | |
| 39 | _LIBCPP_HIDE_FROM_ABI size_t __allocation_size() { | |
| 40 | return (reinterpret_cast<char*>(this) - __start_) + sizeof(*this); | |
| 41 | } | |
| 39 | 42 | void* __try_allocate_from_chunk(size_t, size_t); |
| 40 | 43 | }; |
| 41 | 44 | |
| ... | ... | @@ -115,6 +118,6 @@ private: |
| 115 | 118 | |
| 116 | 119 | _LIBCPP_END_NAMESPACE_STD |
| 117 | 120 | |
| 118 | #endif // _LIBCPP_STD_VER > 14 | |
| 121 | #endif // _LIBCPP_STD_VER >= 17 | |
| 119 | 122 | |
| 120 | 123 | #endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H |
lib/libcxx/include/__memory_resource/polymorphic_allocator.h+16-11| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #define _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H |
| 11 | 11 | |
| 12 | 12 | #include <__assert> |
| 13 | #include <__availability> | |
| 13 | 14 | #include <__config> |
| 14 | 15 | #include <__memory_resource/memory_resource.h> |
| 15 | 16 | #include <__utility/exception_guard.h> |
| ... | ... | @@ -26,7 +27,7 @@ |
| 26 | 27 | _LIBCPP_PUSH_MACROS |
| 27 | 28 | #include <__undef_macros> |
| 28 | 29 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 30 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | 31 | |
| 31 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 33 | |
| ... | ... | @@ -39,7 +40,7 @@ template <class _ValueType |
| 39 | 40 | = byte |
| 40 | 41 | # endif |
| 41 | 42 | > |
| 42 | class _LIBCPP_TEMPLATE_VIS polymorphic_allocator { | |
| 43 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator { | |
| 43 | 44 | |
| 44 | 45 | public: |
| 45 | 46 | using value_type = _ValueType; |
| ... | ... | @@ -50,7 +51,7 @@ public: |
| 50 | 51 | |
| 51 | 52 | _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(memory_resource* __r) noexcept : __res_(__r) {} |
| 52 | 53 | |
| 53 | polymorphic_allocator(const polymorphic_allocator&) = default; | |
| 54 | _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator&) = default; | |
| 54 | 55 | |
| 55 | 56 | template <class _Tp> |
| 56 | 57 | _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(const polymorphic_allocator<_Tp>& __other) noexcept |
| ... | ... | @@ -68,35 +69,35 @@ public: |
| 68 | 69 | } |
| 69 | 70 | |
| 70 | 71 | _LIBCPP_HIDE_FROM_ABI void deallocate(_ValueType* __p, size_t __n) { |
| 71 | _LIBCPP_ASSERT(__n <= __max_size(), "deallocate called for size which exceeds max_size()"); | |
| 72 | _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(), "deallocate called for size which exceeds max_size()"); | |
| 72 | 73 | __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType)); |
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | # if _LIBCPP_STD_VER >= 20 |
| 76 | 77 | |
| 77 | [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] void* | |
| 78 | [[nodiscard]] [[using __gnu__: __alloc_size__(2), __alloc_align__(3)]] _LIBCPP_HIDE_FROM_ABI void* | |
| 78 | 79 | allocate_bytes(size_t __nbytes, size_t __alignment = alignof(max_align_t)) { |
| 79 | 80 | return __res_->allocate(__nbytes, __alignment); |
| 80 | 81 | } |
| 81 | 82 | |
| 82 | void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) { | |
| 83 | _LIBCPP_HIDE_FROM_ABI void deallocate_bytes(void* __ptr, size_t __nbytes, size_t __alignment = alignof(max_align_t)) { | |
| 83 | 84 | __res_->deallocate(__ptr, __nbytes, __alignment); |
| 84 | 85 | } |
| 85 | 86 | |
| 86 | 87 | template <class _Type> |
| 87 | [[nodiscard]] _Type* allocate_object(size_t __n = 1) { | |
| 88 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* allocate_object(size_t __n = 1) { | |
| 88 | 89 | if (numeric_limits<size_t>::max() / sizeof(_Type) < __n) |
| 89 | 90 | std::__throw_bad_array_new_length(); |
| 90 | 91 | return static_cast<_Type*>(allocate_bytes(__n * sizeof(_Type), alignof(_Type))); |
| 91 | 92 | } |
| 92 | 93 | |
| 93 | 94 | template <class _Type> |
| 94 | void deallocate_object(_Type* __ptr, size_t __n = 1) { | |
| 95 | _LIBCPP_HIDE_FROM_ABI void deallocate_object(_Type* __ptr, size_t __n = 1) { | |
| 95 | 96 | deallocate_bytes(__ptr, __n * sizeof(_Type), alignof(_Type)); |
| 96 | 97 | } |
| 97 | 98 | |
| 98 | 99 | template <class _Type, class... _CtorArgs> |
| 99 | [[nodiscard]] _Type* new_object(_CtorArgs&&... __ctor_args) { | |
| 100 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _Type* new_object(_CtorArgs&&... __ctor_args) { | |
| 100 | 101 | _Type* __ptr = allocate_object<_Type>(); |
| 101 | 102 | auto __guard = std::__make_exception_guard([&] { deallocate_object(__ptr); }); |
| 102 | 103 | construct(__ptr, std::forward<_CtorArgs>(__ctor_args)...); |
| ... | ... | @@ -105,7 +106,7 @@ public: |
| 105 | 106 | } |
| 106 | 107 | |
| 107 | 108 | template <class _Type> |
| 108 | void delete_object(_Type* __ptr) { | |
| 109 | _LIBCPP_HIDE_FROM_ABI void delete_object(_Type* __ptr) { | |
| 109 | 110 | destroy(__ptr); |
| 110 | 111 | deallocate_object(__ptr); |
| 111 | 112 | } |
| ... | ... | @@ -207,17 +208,21 @@ operator==(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator< |
| 207 | 208 | return *__lhs.resource() == *__rhs.resource(); |
| 208 | 209 | } |
| 209 | 210 | |
| 211 | # if _LIBCPP_STD_VER <= 17 | |
| 212 | ||
| 210 | 213 | template <class _Tp, class _Up> |
| 211 | 214 | inline _LIBCPP_HIDE_FROM_ABI bool |
| 212 | 215 | operator!=(const polymorphic_allocator<_Tp>& __lhs, const polymorphic_allocator<_Up>& __rhs) noexcept { |
| 213 | 216 | return !(__lhs == __rhs); |
| 214 | 217 | } |
| 215 | 218 | |
| 219 | # endif | |
| 220 | ||
| 216 | 221 | } // namespace pmr |
| 217 | 222 | |
| 218 | 223 | _LIBCPP_END_NAMESPACE_STD |
| 219 | 224 | |
| 220 | #endif // _LIBCPP_STD_VER > 14 | |
| 225 | #endif // _LIBCPP_STD_VER >= 17 | |
| 221 | 226 | |
| 222 | 227 | _LIBCPP_POP_MACROS |
| 223 | 228 |
lib/libcxx/include/__memory_resource/pool_options.h+3-3| ... | ... | @@ -16,7 +16,7 @@ |
| 16 | 16 | # pragma GCC system_header |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | #if _LIBCPP_STD_VER > 14 | |
| 19 | #if _LIBCPP_STD_VER >= 17 | |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| ... | ... | @@ -24,7 +24,7 @@ namespace pmr { |
| 24 | 24 | |
| 25 | 25 | // [mem.res.pool.options] |
| 26 | 26 | |
| 27 | struct _LIBCPP_TYPE_VIS pool_options { | |
| 27 | struct _LIBCPP_EXPORTED_FROM_ABI pool_options { | |
| 28 | 28 | size_t max_blocks_per_chunk = 0; |
| 29 | 29 | size_t largest_required_pool_block = 0; |
| 30 | 30 | }; |
| ... | ... | @@ -33,6 +33,6 @@ struct _LIBCPP_TYPE_VIS pool_options { |
| 33 | 33 | |
| 34 | 34 | _LIBCPP_END_NAMESPACE_STD |
| 35 | 35 | |
| 36 | #endif // _LIBCPP_STD_VER > 14 | |
| 36 | #endif // _LIBCPP_STD_VER >= 17 | |
| 37 | 37 | |
| 38 | 38 | #endif // _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H |
lib/libcxx/include/__memory_resource/synchronized_pool_resource.h+6-7| ... | ... | @@ -9,20 +9,19 @@ |
| 9 | 9 | #ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H |
| 10 | 10 | #define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | #include <__memory_resource/memory_resource.h> |
| 14 | 15 | #include <__memory_resource/pool_options.h> |
| 15 | 16 | #include <__memory_resource/unsynchronized_pool_resource.h> |
| 16 | 17 | #include <cstddef> |
| 17 | #if !defined(_LIBCPP_HAS_NO_THREADS) | |
| 18 | # include <mutex> | |
| 19 | #endif | |
| 18 | #include <mutex> | |
| 20 | 19 | |
| 21 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 21 | # pragma GCC system_header |
| 23 | 22 | #endif |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | |
| 27 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 27 | |
| ... | ... | @@ -30,7 +29,7 @@ namespace pmr { |
| 30 | 29 | |
| 31 | 30 | // [mem.res.pool.overview] |
| 32 | 31 | |
| 33 | class _LIBCPP_TYPE_VIS synchronized_pool_resource : public memory_resource { | |
| 32 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI synchronized_pool_resource : public memory_resource { | |
| 34 | 33 | public: |
| 35 | 34 | _LIBCPP_HIDE_FROM_ABI synchronized_pool_resource(const pool_options& __opts, memory_resource* __upstream) |
| 36 | 35 | : __unsync_(__opts, __upstream) {} |
| ... | ... | @@ -46,7 +45,7 @@ public: |
| 46 | 45 | |
| 47 | 46 | synchronized_pool_resource(const synchronized_pool_resource&) = delete; |
| 48 | 47 | |
| 49 | ~synchronized_pool_resource() override = default; | |
| 48 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~synchronized_pool_resource() override = default; | |
| 50 | 49 | |
| 51 | 50 | synchronized_pool_resource& operator=(const synchronized_pool_resource&) = delete; |
| 52 | 51 | |
| ... | ... | @@ -89,6 +88,6 @@ private: |
| 89 | 88 | |
| 90 | 89 | _LIBCPP_END_NAMESPACE_STD |
| 91 | 90 | |
| 92 | #endif // _LIBCPP_STD_VER > 14 | |
| 91 | #endif // _LIBCPP_STD_VER >= 17 | |
| 93 | 92 | |
| 94 | 93 | #endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H |
lib/libcxx/include/__memory_resource/unsynchronized_pool_resource.h+4-3| ... | ... | @@ -9,6 +9,7 @@ |
| 9 | 9 | #ifndef _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H |
| 10 | 10 | #define _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H |
| 11 | 11 | |
| 12 | #include <__availability> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | #include <__memory_resource/memory_resource.h> |
| 14 | 15 | #include <__memory_resource/pool_options.h> |
| ... | ... | @@ -19,7 +20,7 @@ |
| 19 | 20 | # pragma GCC system_header |
| 20 | 21 | #endif |
| 21 | 22 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 24 | |
| 24 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 26 | |
| ... | ... | @@ -27,7 +28,7 @@ namespace pmr { |
| 27 | 28 | |
| 28 | 29 | // [mem.res.pool.overview] |
| 29 | 30 | |
| 30 | class _LIBCPP_TYPE_VIS unsynchronized_pool_resource : public memory_resource { | |
| 31 | class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI unsynchronized_pool_resource : public memory_resource { | |
| 31 | 32 | class __fixed_pool; |
| 32 | 33 | |
| 33 | 34 | class __adhoc_pool { |
| ... | ... | @@ -101,6 +102,6 @@ private: |
| 101 | 102 | |
| 102 | 103 | _LIBCPP_END_NAMESPACE_STD |
| 103 | 104 | |
| 104 | #endif // _LIBCPP_STD_VER > 14 | |
| 105 | #endif // _LIBCPP_STD_VER >= 17 | |
| 105 | 106 | |
| 106 | 107 | #endif // _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H |
lib/libcxx/include/__mutex/lock_guard.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___MUTEX_LOCK_GUARD_H | |
| 10 | #define _LIBCPP___MUTEX_LOCK_GUARD_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__mutex/tag_types.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | template <class _Mutex> | |
| 24 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) lock_guard { | |
| 25 | public: | |
| 26 | typedef _Mutex mutex_type; | |
| 27 | ||
| 28 | private: | |
| 29 | mutex_type& __m_; | |
| 30 | ||
| 31 | public: | |
| 32 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI explicit lock_guard(mutex_type& __m) | |
| 33 | _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) | |
| 34 | : __m_(__m) { | |
| 35 | __m_.lock(); | |
| 36 | } | |
| 37 | ||
| 38 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI lock_guard(mutex_type& __m, adopt_lock_t) | |
| 39 | _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) | |
| 40 | : __m_(__m) {} | |
| 41 | _LIBCPP_HIDE_FROM_ABI ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) { __m_.unlock(); } | |
| 42 | ||
| 43 | private: | |
| 44 | lock_guard(lock_guard const&) = delete; | |
| 45 | lock_guard& operator=(lock_guard const&) = delete; | |
| 46 | }; | |
| 47 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard); | |
| 48 | ||
| 49 | _LIBCPP_END_NAMESPACE_STD | |
| 50 | ||
| 51 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 52 | ||
| 53 | #endif // _LIBCPP___MUTEX_LOCK_GUARD_H |
lib/libcxx/include/__mutex/mutex.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___MUTEX_MUTEX_H | |
| 10 | #define _LIBCPP___MUTEX_MUTEX_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__threading_support> | |
| 14 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex { | |
| 25 | __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; | |
| 26 | ||
| 27 | public: | |
| 28 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR mutex() = default; | |
| 29 | ||
| 30 | mutex(const mutex&) = delete; | |
| 31 | mutex& operator=(const mutex&) = delete; | |
| 32 | ||
| 33 | # if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION) | |
| 34 | _LIBCPP_HIDE_FROM_ABI ~mutex() = default; | |
| 35 | # else | |
| 36 | ~mutex() _NOEXCEPT; | |
| 37 | # endif | |
| 38 | ||
| 39 | void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); | |
| 40 | bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); | |
| 41 | void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); | |
| 42 | ||
| 43 | typedef __libcpp_mutex_t* native_handle_type; | |
| 44 | _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return &__m_; } | |
| 45 | }; | |
| 46 | ||
| 47 | static_assert(is_nothrow_default_constructible<mutex>::value, "the default constructor for std::mutex must be nothrow"); | |
| 48 | ||
| 49 | _LIBCPP_END_NAMESPACE_STD | |
| 50 | ||
| 51 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 52 | ||
| 53 | #endif // _LIBCPP___MUTEX_MUTEX_H |
lib/libcxx/include/__mutex/tag_types.h created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___MUTEX_TAG_TYPES_H | |
| 10 | #define _LIBCPP___MUTEX_TAG_TYPES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t { | |
| 23 | explicit defer_lock_t() = default; | |
| 24 | }; | |
| 25 | ||
| 26 | struct _LIBCPP_EXPORTED_FROM_ABI try_to_lock_t { | |
| 27 | explicit try_to_lock_t() = default; | |
| 28 | }; | |
| 29 | ||
| 30 | struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t { | |
| 31 | explicit adopt_lock_t() = default; | |
| 32 | }; | |
| 33 | ||
| 34 | # if _LIBCPP_STD_VER >= 17 | |
| 35 | inline constexpr defer_lock_t defer_lock = defer_lock_t(); | |
| 36 | inline constexpr try_to_lock_t try_to_lock = try_to_lock_t(); | |
| 37 | inline constexpr adopt_lock_t adopt_lock = adopt_lock_t(); | |
| 38 | # elif !defined(_LIBCPP_CXX03_LANG) | |
| 39 | constexpr defer_lock_t defer_lock = defer_lock_t(); | |
| 40 | constexpr try_to_lock_t try_to_lock = try_to_lock_t(); | |
| 41 | constexpr adopt_lock_t adopt_lock = adopt_lock_t(); | |
| 42 | # endif | |
| 43 | ||
| 44 | _LIBCPP_END_NAMESPACE_STD | |
| 45 | ||
| 46 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 47 | ||
| 48 | #endif // _LIBCPP___MUTEX_TAG_TYPES_H |
lib/libcxx/include/__mutex/unique_lock.h created+173| ... | ... | @@ -0,0 +1,173 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___MUTEX_UNIQUE_LOCK_H | |
| 10 | #define _LIBCPP___MUTEX_UNIQUE_LOCK_H | |
| 11 | ||
| 12 | #include <__chrono/duration.h> | |
| 13 | #include <__chrono/time_point.h> | |
| 14 | #include <__config> | |
| 15 | #include <__memory/addressof.h> | |
| 16 | #include <__mutex/tag_types.h> | |
| 17 | #include <__system_error/system_error.h> | |
| 18 | #include <__utility/swap.h> | |
| 19 | #include <cerrno> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Mutex> | |
| 30 | class _LIBCPP_TEMPLATE_VIS unique_lock { | |
| 31 | public: | |
| 32 | typedef _Mutex mutex_type; | |
| 33 | ||
| 34 | private: | |
| 35 | mutex_type* __m_; | |
| 36 | bool __owns_; | |
| 37 | ||
| 38 | public: | |
| 39 | _LIBCPP_HIDE_FROM_ABI unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} | |
| 40 | _LIBCPP_HIDE_FROM_ABI explicit unique_lock(mutex_type& __m) : __m_(std::addressof(__m)), __owns_(true) { | |
| 41 | __m_->lock(); | |
| 42 | } | |
| 43 | ||
| 44 | _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT | |
| 45 | : __m_(std::addressof(__m)), | |
| 46 | __owns_(false) {} | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, try_to_lock_t) | |
| 49 | : __m_(std::addressof(__m)), __owns_(__m.try_lock()) {} | |
| 50 | ||
| 51 | _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, adopt_lock_t) : __m_(std::addressof(__m)), __owns_(true) {} | |
| 52 | ||
| 53 | template <class _Clock, class _Duration> | |
| 54 | _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) | |
| 55 | : __m_(std::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} | |
| 56 | ||
| 57 | template <class _Rep, class _Period> | |
| 58 | _LIBCPP_HIDE_FROM_ABI unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) | |
| 59 | : __m_(std::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} | |
| 60 | ||
| 61 | _LIBCPP_HIDE_FROM_ABI ~unique_lock() { | |
| 62 | if (__owns_) | |
| 63 | __m_->unlock(); | |
| 64 | } | |
| 65 | ||
| 66 | unique_lock(unique_lock const&) = delete; | |
| 67 | unique_lock& operator=(unique_lock const&) = delete; | |
| 68 | ||
| 69 | _LIBCPP_HIDE_FROM_ABI unique_lock(unique_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) { | |
| 70 | __u.__m_ = nullptr; | |
| 71 | __u.__owns_ = false; | |
| 72 | } | |
| 73 | ||
| 74 | _LIBCPP_HIDE_FROM_ABI unique_lock& operator=(unique_lock&& __u) _NOEXCEPT { | |
| 75 | if (__owns_) | |
| 76 | __m_->unlock(); | |
| 77 | ||
| 78 | __m_ = __u.__m_; | |
| 79 | __owns_ = __u.__owns_; | |
| 80 | __u.__m_ = nullptr; | |
| 81 | __u.__owns_ = false; | |
| 82 | return *this; | |
| 83 | } | |
| 84 | ||
| 85 | void lock(); | |
| 86 | bool try_lock(); | |
| 87 | ||
| 88 | template <class _Rep, class _Period> | |
| 89 | bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); | |
| 90 | ||
| 91 | template <class _Clock, class _Duration> | |
| 92 | bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | |
| 93 | ||
| 94 | void unlock(); | |
| 95 | ||
| 96 | _LIBCPP_HIDE_FROM_ABI void swap(unique_lock& __u) _NOEXCEPT { | |
| 97 | std::swap(__m_, __u.__m_); | |
| 98 | std::swap(__owns_, __u.__owns_); | |
| 99 | } | |
| 100 | ||
| 101 | _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT { | |
| 102 | mutex_type* __m = __m_; | |
| 103 | __m_ = nullptr; | |
| 104 | __owns_ = false; | |
| 105 | return __m; | |
| 106 | } | |
| 107 | ||
| 108 | _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; } | |
| 109 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; } | |
| 110 | _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; } | |
| 111 | }; | |
| 112 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock); | |
| 113 | ||
| 114 | template <class _Mutex> | |
| 115 | void unique_lock<_Mutex>::lock() { | |
| 116 | if (__m_ == nullptr) | |
| 117 | __throw_system_error(EPERM, "unique_lock::lock: references null mutex"); | |
| 118 | if (__owns_) | |
| 119 | __throw_system_error(EDEADLK, "unique_lock::lock: already locked"); | |
| 120 | __m_->lock(); | |
| 121 | __owns_ = true; | |
| 122 | } | |
| 123 | ||
| 124 | template <class _Mutex> | |
| 125 | bool unique_lock<_Mutex>::try_lock() { | |
| 126 | if (__m_ == nullptr) | |
| 127 | __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); | |
| 128 | if (__owns_) | |
| 129 | __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); | |
| 130 | __owns_ = __m_->try_lock(); | |
| 131 | return __owns_; | |
| 132 | } | |
| 133 | ||
| 134 | template <class _Mutex> | |
| 135 | template <class _Rep, class _Period> | |
| 136 | bool unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) { | |
| 137 | if (__m_ == nullptr) | |
| 138 | __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); | |
| 139 | if (__owns_) | |
| 140 | __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); | |
| 141 | __owns_ = __m_->try_lock_for(__d); | |
| 142 | return __owns_; | |
| 143 | } | |
| 144 | ||
| 145 | template <class _Mutex> | |
| 146 | template <class _Clock, class _Duration> | |
| 147 | bool unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { | |
| 148 | if (__m_ == nullptr) | |
| 149 | __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); | |
| 150 | if (__owns_) | |
| 151 | __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); | |
| 152 | __owns_ = __m_->try_lock_until(__t); | |
| 153 | return __owns_; | |
| 154 | } | |
| 155 | ||
| 156 | template <class _Mutex> | |
| 157 | void unique_lock<_Mutex>::unlock() { | |
| 158 | if (!__owns_) | |
| 159 | __throw_system_error(EPERM, "unique_lock::unlock: not locked"); | |
| 160 | __m_->unlock(); | |
| 161 | __owns_ = false; | |
| 162 | } | |
| 163 | ||
| 164 | template <class _Mutex> | |
| 165 | inline _LIBCPP_HIDE_FROM_ABI void swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT { | |
| 166 | __x.swap(__y); | |
| 167 | } | |
| 168 | ||
| 169 | _LIBCPP_END_NAMESPACE_STD | |
| 170 | ||
| 171 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 172 | ||
| 173 | #endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H |
lib/libcxx/include/__mutex_base deleted-523| ... | ... | @@ -1,523 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___MUTEX_BASE | |
| 11 | #define _LIBCPP___MUTEX_BASE | |
| 12 | ||
| 13 | #include <__chrono/duration.h> | |
| 14 | #include <__chrono/steady_clock.h> | |
| 15 | #include <__chrono/system_clock.h> | |
| 16 | #include <__chrono/time_point.h> | |
| 17 | #include <__config> | |
| 18 | #include <__threading_support> | |
| 19 | #include <ratio> | |
| 20 | #include <system_error> | |
| 21 | #include <time.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_PUSH_MACROS | |
| 28 | #include <__undef_macros> | |
| 29 | ||
| 30 | ||
| 31 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 32 | ||
| 33 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 34 | ||
| 35 | class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex | |
| 36 | { | |
| 37 | __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; | |
| 38 | ||
| 39 | public: | |
| 40 | _LIBCPP_INLINE_VISIBILITY | |
| 41 | _LIBCPP_CONSTEXPR mutex() = default; | |
| 42 | ||
| 43 | mutex(const mutex&) = delete; | |
| 44 | mutex& operator=(const mutex&) = delete; | |
| 45 | ||
| 46 | #if defined(_LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION) | |
| 47 | ~mutex() = default; | |
| 48 | #else | |
| 49 | ~mutex() _NOEXCEPT; | |
| 50 | #endif | |
| 51 | ||
| 52 | void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); | |
| 53 | bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); | |
| 54 | void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); | |
| 55 | ||
| 56 | typedef __libcpp_mutex_t* native_handle_type; | |
| 57 | _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} | |
| 58 | }; | |
| 59 | ||
| 60 | static_assert(is_nothrow_default_constructible<mutex>::value, | |
| 61 | "the default constructor for std::mutex must be nothrow"); | |
| 62 | ||
| 63 | struct _LIBCPP_TYPE_VIS defer_lock_t { explicit defer_lock_t() = default; }; | |
| 64 | struct _LIBCPP_TYPE_VIS try_to_lock_t { explicit try_to_lock_t() = default; }; | |
| 65 | struct _LIBCPP_TYPE_VIS adopt_lock_t { explicit adopt_lock_t() = default; }; | |
| 66 | ||
| 67 | #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 68 | ||
| 69 | extern _LIBCPP_EXPORTED_FROM_ABI const defer_lock_t defer_lock; | |
| 70 | extern _LIBCPP_EXPORTED_FROM_ABI const try_to_lock_t try_to_lock; | |
| 71 | extern _LIBCPP_EXPORTED_FROM_ABI const adopt_lock_t adopt_lock; | |
| 72 | ||
| 73 | #else | |
| 74 | ||
| 75 | /* inline */ constexpr defer_lock_t defer_lock = defer_lock_t(); | |
| 76 | /* inline */ constexpr try_to_lock_t try_to_lock = try_to_lock_t(); | |
| 77 | /* inline */ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); | |
| 78 | ||
| 79 | #endif | |
| 80 | ||
| 81 | template <class _Mutex> | |
| 82 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(scoped_lockable) | |
| 83 | lock_guard | |
| 84 | { | |
| 85 | public: | |
| 86 | typedef _Mutex mutex_type; | |
| 87 | ||
| 88 | private: | |
| 89 | mutex_type& __m_; | |
| 90 | public: | |
| 91 | ||
| 92 | _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY | |
| 93 | explicit lock_guard(mutex_type& __m) _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability(__m)) | |
| 94 | : __m_(__m) {__m_.lock();} | |
| 95 | ||
| 96 | _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY | |
| 97 | lock_guard(mutex_type& __m, adopt_lock_t) _LIBCPP_THREAD_SAFETY_ANNOTATION(requires_capability(__m)) | |
| 98 | : __m_(__m) {} | |
| 99 | _LIBCPP_INLINE_VISIBILITY | |
| 100 | ~lock_guard() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()) {__m_.unlock();} | |
| 101 | ||
| 102 | private: | |
| 103 | lock_guard(lock_guard const&) = delete; | |
| 104 | lock_guard& operator=(lock_guard const&) = delete; | |
| 105 | }; | |
| 106 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard); | |
| 107 | ||
| 108 | template <class _Mutex> | |
| 109 | class _LIBCPP_TEMPLATE_VIS unique_lock | |
| 110 | { | |
| 111 | public: | |
| 112 | typedef _Mutex mutex_type; | |
| 113 | ||
| 114 | private: | |
| 115 | mutex_type* __m_; | |
| 116 | bool __owns_; | |
| 117 | ||
| 118 | public: | |
| 119 | _LIBCPP_INLINE_VISIBILITY | |
| 120 | unique_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} | |
| 121 | _LIBCPP_INLINE_VISIBILITY | |
| 122 | explicit unique_lock(mutex_type& __m) | |
| 123 | : __m_(_VSTD::addressof(__m)), __owns_(true) {__m_->lock();} | |
| 124 | _LIBCPP_INLINE_VISIBILITY | |
| 125 | unique_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT | |
| 126 | : __m_(_VSTD::addressof(__m)), __owns_(false) {} | |
| 127 | _LIBCPP_INLINE_VISIBILITY | |
| 128 | unique_lock(mutex_type& __m, try_to_lock_t) | |
| 129 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock()) {} | |
| 130 | _LIBCPP_INLINE_VISIBILITY | |
| 131 | unique_lock(mutex_type& __m, adopt_lock_t) | |
| 132 | : __m_(_VSTD::addressof(__m)), __owns_(true) {} | |
| 133 | template <class _Clock, class _Duration> | |
| 134 | _LIBCPP_INLINE_VISIBILITY | |
| 135 | unique_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __t) | |
| 136 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_until(__t)) {} | |
| 137 | template <class _Rep, class _Period> | |
| 138 | _LIBCPP_INLINE_VISIBILITY | |
| 139 | unique_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __d) | |
| 140 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_for(__d)) {} | |
| 141 | _LIBCPP_INLINE_VISIBILITY | |
| 142 | ~unique_lock() | |
| 143 | { | |
| 144 | if (__owns_) | |
| 145 | __m_->unlock(); | |
| 146 | } | |
| 147 | ||
| 148 | unique_lock(unique_lock const&) = delete; | |
| 149 | unique_lock& operator=(unique_lock const&) = delete; | |
| 150 | ||
| 151 | _LIBCPP_INLINE_VISIBILITY | |
| 152 | unique_lock(unique_lock&& __u) _NOEXCEPT | |
| 153 | : __m_(__u.__m_), __owns_(__u.__owns_) | |
| 154 | {__u.__m_ = nullptr; __u.__owns_ = false;} | |
| 155 | _LIBCPP_INLINE_VISIBILITY | |
| 156 | unique_lock& operator=(unique_lock&& __u) _NOEXCEPT | |
| 157 | { | |
| 158 | if (__owns_) | |
| 159 | __m_->unlock(); | |
| 160 | __m_ = __u.__m_; | |
| 161 | __owns_ = __u.__owns_; | |
| 162 | __u.__m_ = nullptr; | |
| 163 | __u.__owns_ = false; | |
| 164 | return *this; | |
| 165 | } | |
| 166 | ||
| 167 | void lock(); | |
| 168 | bool try_lock(); | |
| 169 | ||
| 170 | template <class _Rep, class _Period> | |
| 171 | bool try_lock_for(const chrono::duration<_Rep, _Period>& __d); | |
| 172 | template <class _Clock, class _Duration> | |
| 173 | bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); | |
| 174 | ||
| 175 | void unlock(); | |
| 176 | ||
| 177 | _LIBCPP_INLINE_VISIBILITY | |
| 178 | void swap(unique_lock& __u) _NOEXCEPT | |
| 179 | { | |
| 180 | _VSTD::swap(__m_, __u.__m_); | |
| 181 | _VSTD::swap(__owns_, __u.__owns_); | |
| 182 | } | |
| 183 | _LIBCPP_INLINE_VISIBILITY | |
| 184 | mutex_type* release() _NOEXCEPT | |
| 185 | { | |
| 186 | mutex_type* __m = __m_; | |
| 187 | __m_ = nullptr; | |
| 188 | __owns_ = false; | |
| 189 | return __m; | |
| 190 | } | |
| 191 | ||
| 192 | _LIBCPP_INLINE_VISIBILITY | |
| 193 | bool owns_lock() const _NOEXCEPT {return __owns_;} | |
| 194 | _LIBCPP_INLINE_VISIBILITY | |
| 195 | explicit operator bool() const _NOEXCEPT {return __owns_;} | |
| 196 | _LIBCPP_INLINE_VISIBILITY | |
| 197 | mutex_type* mutex() const _NOEXCEPT {return __m_;} | |
| 198 | }; | |
| 199 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(unique_lock); | |
| 200 | ||
| 201 | template <class _Mutex> | |
| 202 | void | |
| 203 | unique_lock<_Mutex>::lock() | |
| 204 | { | |
| 205 | if (__m_ == nullptr) | |
| 206 | __throw_system_error(EPERM, "unique_lock::lock: references null mutex"); | |
| 207 | if (__owns_) | |
| 208 | __throw_system_error(EDEADLK, "unique_lock::lock: already locked"); | |
| 209 | __m_->lock(); | |
| 210 | __owns_ = true; | |
| 211 | } | |
| 212 | ||
| 213 | template <class _Mutex> | |
| 214 | bool | |
| 215 | unique_lock<_Mutex>::try_lock() | |
| 216 | { | |
| 217 | if (__m_ == nullptr) | |
| 218 | __throw_system_error(EPERM, "unique_lock::try_lock: references null mutex"); | |
| 219 | if (__owns_) | |
| 220 | __throw_system_error(EDEADLK, "unique_lock::try_lock: already locked"); | |
| 221 | __owns_ = __m_->try_lock(); | |
| 222 | return __owns_; | |
| 223 | } | |
| 224 | ||
| 225 | template <class _Mutex> | |
| 226 | template <class _Rep, class _Period> | |
| 227 | bool | |
| 228 | unique_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) | |
| 229 | { | |
| 230 | if (__m_ == nullptr) | |
| 231 | __throw_system_error(EPERM, "unique_lock::try_lock_for: references null mutex"); | |
| 232 | if (__owns_) | |
| 233 | __throw_system_error(EDEADLK, "unique_lock::try_lock_for: already locked"); | |
| 234 | __owns_ = __m_->try_lock_for(__d); | |
| 235 | return __owns_; | |
| 236 | } | |
| 237 | ||
| 238 | template <class _Mutex> | |
| 239 | template <class _Clock, class _Duration> | |
| 240 | bool | |
| 241 | unique_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
| 242 | { | |
| 243 | if (__m_ == nullptr) | |
| 244 | __throw_system_error(EPERM, "unique_lock::try_lock_until: references null mutex"); | |
| 245 | if (__owns_) | |
| 246 | __throw_system_error(EDEADLK, "unique_lock::try_lock_until: already locked"); | |
| 247 | __owns_ = __m_->try_lock_until(__t); | |
| 248 | return __owns_; | |
| 249 | } | |
| 250 | ||
| 251 | template <class _Mutex> | |
| 252 | void | |
| 253 | unique_lock<_Mutex>::unlock() | |
| 254 | { | |
| 255 | if (!__owns_) | |
| 256 | __throw_system_error(EPERM, "unique_lock::unlock: not locked"); | |
| 257 | __m_->unlock(); | |
| 258 | __owns_ = false; | |
| 259 | } | |
| 260 | ||
| 261 | template <class _Mutex> | |
| 262 | inline _LIBCPP_INLINE_VISIBILITY | |
| 263 | void | |
| 264 | swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) _NOEXCEPT | |
| 265 | {__x.swap(__y);} | |
| 266 | ||
| 267 | //enum class cv_status | |
| 268 | _LIBCPP_DECLARE_STRONG_ENUM(cv_status) | |
| 269 | { | |
| 270 | no_timeout, | |
| 271 | timeout | |
| 272 | }; | |
| 273 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) | |
| 274 | ||
| 275 | class _LIBCPP_TYPE_VIS condition_variable | |
| 276 | { | |
| 277 | __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; | |
| 278 | public: | |
| 279 | _LIBCPP_INLINE_VISIBILITY | |
| 280 | _LIBCPP_CONSTEXPR condition_variable() _NOEXCEPT = default; | |
| 281 | ||
| 282 | #ifdef _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION | |
| 283 | ~condition_variable() = default; | |
| 284 | #else | |
| 285 | ~condition_variable(); | |
| 286 | #endif | |
| 287 | ||
| 288 | condition_variable(const condition_variable&) = delete; | |
| 289 | condition_variable& operator=(const condition_variable&) = delete; | |
| 290 | ||
| 291 | void notify_one() _NOEXCEPT; | |
| 292 | void notify_all() _NOEXCEPT; | |
| 293 | ||
| 294 | void wait(unique_lock<mutex>& __lk) _NOEXCEPT; | |
| 295 | template <class _Predicate> | |
| 296 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 297 | void wait(unique_lock<mutex>& __lk, _Predicate __pred); | |
| 298 | ||
| 299 | template <class _Clock, class _Duration> | |
| 300 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 301 | cv_status | |
| 302 | wait_until(unique_lock<mutex>& __lk, | |
| 303 | const chrono::time_point<_Clock, _Duration>& __t); | |
| 304 | ||
| 305 | template <class _Clock, class _Duration, class _Predicate> | |
| 306 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 307 | bool | |
| 308 | wait_until(unique_lock<mutex>& __lk, | |
| 309 | const chrono::time_point<_Clock, _Duration>& __t, | |
| 310 | _Predicate __pred); | |
| 311 | ||
| 312 | template <class _Rep, class _Period> | |
| 313 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 314 | cv_status | |
| 315 | wait_for(unique_lock<mutex>& __lk, | |
| 316 | const chrono::duration<_Rep, _Period>& __d); | |
| 317 | ||
| 318 | template <class _Rep, class _Period, class _Predicate> | |
| 319 | bool | |
| 320 | _LIBCPP_INLINE_VISIBILITY | |
| 321 | wait_for(unique_lock<mutex>& __lk, | |
| 322 | const chrono::duration<_Rep, _Period>& __d, | |
| 323 | _Predicate __pred); | |
| 324 | ||
| 325 | typedef __libcpp_condvar_t* native_handle_type; | |
| 326 | _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} | |
| 327 | ||
| 328 | private: | |
| 329 | void __do_timed_wait(unique_lock<mutex>& __lk, | |
| 330 | chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 331 | #if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 332 | void __do_timed_wait(unique_lock<mutex>& __lk, | |
| 333 | chrono::time_point<chrono::steady_clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 334 | #endif | |
| 335 | template <class _Clock> | |
| 336 | void __do_timed_wait(unique_lock<mutex>& __lk, | |
| 337 | chrono::time_point<_Clock, chrono::nanoseconds>) _NOEXCEPT; | |
| 338 | }; | |
| 339 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 340 | ||
| 341 | template <class _Rep, class _Period> | |
| 342 | inline _LIBCPP_INLINE_VISIBILITY | |
| 343 | __enable_if_t<is_floating_point<_Rep>::value, chrono::nanoseconds> | |
| 344 | __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) | |
| 345 | { | |
| 346 | using namespace chrono; | |
| 347 | using __ratio = ratio_divide<_Period, nano>; | |
| 348 | using __ns_rep = nanoseconds::rep; | |
| 349 | _Rep __result_float = __d.count() * __ratio::num / __ratio::den; | |
| 350 | ||
| 351 | _Rep __result_max = numeric_limits<__ns_rep>::max(); | |
| 352 | if (__result_float >= __result_max) { | |
| 353 | return nanoseconds::max(); | |
| 354 | } | |
| 355 | ||
| 356 | _Rep __result_min = numeric_limits<__ns_rep>::min(); | |
| 357 | if (__result_float <= __result_min) { | |
| 358 | return nanoseconds::min(); | |
| 359 | } | |
| 360 | ||
| 361 | return nanoseconds(static_cast<__ns_rep>(__result_float)); | |
| 362 | } | |
| 363 | ||
| 364 | template <class _Rep, class _Period> | |
| 365 | inline _LIBCPP_INLINE_VISIBILITY | |
| 366 | __enable_if_t<!is_floating_point<_Rep>::value, chrono::nanoseconds> | |
| 367 | __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) | |
| 368 | { | |
| 369 | using namespace chrono; | |
| 370 | if (__d.count() == 0) { | |
| 371 | return nanoseconds(0); | |
| 372 | } | |
| 373 | ||
| 374 | using __ratio = ratio_divide<_Period, nano>; | |
| 375 | using __ns_rep = nanoseconds::rep; | |
| 376 | __ns_rep __result_max = numeric_limits<__ns_rep>::max(); | |
| 377 | if (__d.count() > 0 && __d.count() > __result_max / __ratio::num) { | |
| 378 | return nanoseconds::max(); | |
| 379 | } | |
| 380 | ||
| 381 | __ns_rep __result_min = numeric_limits<__ns_rep>::min(); | |
| 382 | if (__d.count() < 0 && __d.count() < __result_min / __ratio::num) { | |
| 383 | return nanoseconds::min(); | |
| 384 | } | |
| 385 | ||
| 386 | __ns_rep __result = __d.count() * __ratio::num / __ratio::den; | |
| 387 | if (__result == 0) { | |
| 388 | return nanoseconds(1); | |
| 389 | } | |
| 390 | ||
| 391 | return nanoseconds(__result); | |
| 392 | } | |
| 393 | ||
| 394 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 395 | template <class _Predicate> | |
| 396 | void | |
| 397 | condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred) | |
| 398 | { | |
| 399 | while (!__pred()) | |
| 400 | wait(__lk); | |
| 401 | } | |
| 402 | ||
| 403 | template <class _Clock, class _Duration> | |
| 404 | cv_status | |
| 405 | condition_variable::wait_until(unique_lock<mutex>& __lk, | |
| 406 | const chrono::time_point<_Clock, _Duration>& __t) | |
| 407 | { | |
| 408 | using namespace chrono; | |
| 409 | using __clock_tp_ns = time_point<_Clock, nanoseconds>; | |
| 410 | ||
| 411 | typename _Clock::time_point __now = _Clock::now(); | |
| 412 | if (__t <= __now) | |
| 413 | return cv_status::timeout; | |
| 414 | ||
| 415 | __clock_tp_ns __t_ns = __clock_tp_ns(_VSTD::__safe_nanosecond_cast(__t.time_since_epoch())); | |
| 416 | ||
| 417 | __do_timed_wait(__lk, __t_ns); | |
| 418 | return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout; | |
| 419 | } | |
| 420 | ||
| 421 | template <class _Clock, class _Duration, class _Predicate> | |
| 422 | bool | |
| 423 | condition_variable::wait_until(unique_lock<mutex>& __lk, | |
| 424 | const chrono::time_point<_Clock, _Duration>& __t, | |
| 425 | _Predicate __pred) | |
| 426 | { | |
| 427 | while (!__pred()) | |
| 428 | { | |
| 429 | if (wait_until(__lk, __t) == cv_status::timeout) | |
| 430 | return __pred(); | |
| 431 | } | |
| 432 | return true; | |
| 433 | } | |
| 434 | ||
| 435 | template <class _Rep, class _Period> | |
| 436 | cv_status | |
| 437 | condition_variable::wait_for(unique_lock<mutex>& __lk, | |
| 438 | const chrono::duration<_Rep, _Period>& __d) | |
| 439 | { | |
| 440 | using namespace chrono; | |
| 441 | if (__d <= __d.zero()) | |
| 442 | return cv_status::timeout; | |
| 443 | using __ns_rep = nanoseconds::rep; | |
| 444 | steady_clock::time_point __c_now = steady_clock::now(); | |
| 445 | ||
| 446 | #if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 447 | using __clock_tp_ns = time_point<steady_clock, nanoseconds>; | |
| 448 | __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(__c_now.time_since_epoch()).count(); | |
| 449 | #else | |
| 450 | using __clock_tp_ns = time_point<system_clock, nanoseconds>; | |
| 451 | __ns_rep __now_count_ns = _VSTD::__safe_nanosecond_cast(system_clock::now().time_since_epoch()).count(); | |
| 452 | #endif | |
| 453 | ||
| 454 | __ns_rep __d_ns_count = _VSTD::__safe_nanosecond_cast(__d).count(); | |
| 455 | ||
| 456 | if (__now_count_ns > numeric_limits<__ns_rep>::max() - __d_ns_count) { | |
| 457 | __do_timed_wait(__lk, __clock_tp_ns::max()); | |
| 458 | } else { | |
| 459 | __do_timed_wait(__lk, __clock_tp_ns(nanoseconds(__now_count_ns + __d_ns_count))); | |
| 460 | } | |
| 461 | ||
| 462 | return steady_clock::now() - __c_now < __d ? cv_status::no_timeout : | |
| 463 | cv_status::timeout; | |
| 464 | } | |
| 465 | ||
| 466 | template <class _Rep, class _Period, class _Predicate> | |
| 467 | inline | |
| 468 | bool | |
| 469 | condition_variable::wait_for(unique_lock<mutex>& __lk, | |
| 470 | const chrono::duration<_Rep, _Period>& __d, | |
| 471 | _Predicate __pred) | |
| 472 | { | |
| 473 | return wait_until(__lk, chrono::steady_clock::now() + __d, | |
| 474 | _VSTD::move(__pred)); | |
| 475 | } | |
| 476 | ||
| 477 | #if defined(_LIBCPP_HAS_COND_CLOCKWAIT) | |
| 478 | inline | |
| 479 | void | |
| 480 | condition_variable::__do_timed_wait(unique_lock<mutex>& __lk, | |
| 481 | chrono::time_point<chrono::steady_clock, chrono::nanoseconds> __tp) _NOEXCEPT | |
| 482 | { | |
| 483 | using namespace chrono; | |
| 484 | if (!__lk.owns_lock()) | |
| 485 | __throw_system_error(EPERM, | |
| 486 | "condition_variable::timed wait: mutex not locked"); | |
| 487 | nanoseconds __d = __tp.time_since_epoch(); | |
| 488 | timespec __ts; | |
| 489 | seconds __s = duration_cast<seconds>(__d); | |
| 490 | using __ts_sec = decltype(__ts.tv_sec); | |
| 491 | const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); | |
| 492 | if (__s.count() < __ts_sec_max) | |
| 493 | { | |
| 494 | __ts.tv_sec = static_cast<__ts_sec>(__s.count()); | |
| 495 | __ts.tv_nsec = (__d - __s).count(); | |
| 496 | } | |
| 497 | else | |
| 498 | { | |
| 499 | __ts.tv_sec = __ts_sec_max; | |
| 500 | __ts.tv_nsec = giga::num - 1; | |
| 501 | } | |
| 502 | int __ec = pthread_cond_clockwait(&__cv_, __lk.mutex()->native_handle(), CLOCK_MONOTONIC, &__ts); | |
| 503 | if (__ec != 0 && __ec != ETIMEDOUT) | |
| 504 | __throw_system_error(__ec, "condition_variable timed_wait failed"); | |
| 505 | } | |
| 506 | #endif // _LIBCPP_HAS_COND_CLOCKWAIT | |
| 507 | ||
| 508 | template <class _Clock> | |
| 509 | inline | |
| 510 | void | |
| 511 | condition_variable::__do_timed_wait(unique_lock<mutex>& __lk, | |
| 512 | chrono::time_point<_Clock, chrono::nanoseconds> __tp) _NOEXCEPT | |
| 513 | { | |
| 514 | wait_for(__lk, __tp - _Clock::now()); | |
| 515 | } | |
| 516 | ||
| 517 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 518 | ||
| 519 | _LIBCPP_END_NAMESPACE_STD | |
| 520 | ||
| 521 | _LIBCPP_POP_MACROS | |
| 522 | ||
| 523 | #endif // _LIBCPP___MUTEX_BASE |
lib/libcxx/include/__node_handle+8-3| ... | ... | @@ -68,9 +68,12 @@ public: |
| 68 | 68 | # pragma GCC system_header |
| 69 | 69 | #endif |
| 70 | 70 | |
| 71 | _LIBCPP_PUSH_MACROS | |
| 72 | #include <__undef_macros> | |
| 73 | ||
| 71 | 74 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 72 | 75 | |
| 73 | #if _LIBCPP_STD_VER > 14 | |
| 76 | #if _LIBCPP_STD_VER >= 17 | |
| 74 | 77 | |
| 75 | 78 | // Specialized in __tree & __hash_table for their _NodeType. |
| 76 | 79 | template <class _NodeType, class _Alloc> |
| ... | ... | @@ -146,7 +149,7 @@ public: |
| 146 | 149 | _LIBCPP_INLINE_VISIBILITY |
| 147 | 150 | __basic_node_handle& operator=(__basic_node_handle&& __other) |
| 148 | 151 | { |
| 149 | _LIBCPP_ASSERT( | |
| 152 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( | |
| 150 | 153 | __alloc_ == _VSTD::nullopt || |
| 151 | 154 | __alloc_traits::propagate_on_container_move_assignment::value || |
| 152 | 155 | __alloc_ == __other.__alloc_, |
| ... | ... | @@ -247,8 +250,10 @@ struct _LIBCPP_TEMPLATE_VIS __insert_return_type |
| 247 | 250 | _NodeType node; |
| 248 | 251 | }; |
| 249 | 252 | |
| 250 | #endif // _LIBCPP_STD_VER > 14 | |
| 253 | #endif // _LIBCPP_STD_VER >= 17 | |
| 251 | 254 | |
| 252 | 255 | _LIBCPP_END_NAMESPACE_STD |
| 253 | 256 | |
| 257 | _LIBCPP_POP_MACROS | |
| 258 | ||
| 254 | 259 | #endif // _LIBCPP___NODE_HANDLE |
lib/libcxx/include/__numeric/accumulate.h+7-2| ... | ... | @@ -17,6 +17,9 @@ |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | _LIBCPP_PUSH_MACROS | |
| 21 | #include <__undef_macros> | |
| 22 | ||
| 20 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 24 | |
| 22 | 25 | template <class _InputIterator, class _Tp> |
| ... | ... | @@ -25,7 +28,7 @@ _Tp |
| 25 | 28 | accumulate(_InputIterator __first, _InputIterator __last, _Tp __init) |
| 26 | 29 | { |
| 27 | 30 | for (; __first != __last; ++__first) |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 32 | __init = _VSTD::move(__init) + *__first; |
| 30 | 33 | #else |
| 31 | 34 | __init = __init + *__first; |
| ... | ... | @@ -39,7 +42,7 @@ _Tp |
| 39 | 42 | accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op) |
| 40 | 43 | { |
| 41 | 44 | for (; __first != __last; ++__first) |
| 42 | #if _LIBCPP_STD_VER > 17 | |
| 45 | #if _LIBCPP_STD_VER >= 20 | |
| 43 | 46 | __init = __binary_op(_VSTD::move(__init), *__first); |
| 44 | 47 | #else |
| 45 | 48 | __init = __binary_op(__init, *__first); |
| ... | ... | @@ -49,4 +52,6 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe |
| 49 | 52 | |
| 50 | 53 | _LIBCPP_END_NAMESPACE_STD |
| 51 | 54 | |
| 55 | _LIBCPP_POP_MACROS | |
| 56 | ||
| 52 | 57 | #endif // _LIBCPP___NUMERIC_ACCUMULATE_H |
lib/libcxx/include/__numeric/adjacent_difference.h+7-2| ... | ... | @@ -18,6 +18,9 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | _LIBCPP_PUSH_MACROS | |
| 22 | #include <__undef_macros> | |
| 23 | ||
| 21 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 25 | |
| 23 | 26 | template <class _InputIterator, class _OutputIterator> |
| ... | ... | @@ -32,7 +35,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat |
| 32 | 35 | for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) |
| 33 | 36 | { |
| 34 | 37 | typename iterator_traits<_InputIterator>::value_type __val(*__first); |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 38 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 39 | *__result = __val - _VSTD::move(__acc); |
| 37 | 40 | #else |
| 38 | 41 | *__result = __val - __acc; |
| ... | ... | @@ -56,7 +59,7 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat |
| 56 | 59 | for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) |
| 57 | 60 | { |
| 58 | 61 | typename iterator_traits<_InputIterator>::value_type __val(*__first); |
| 59 | #if _LIBCPP_STD_VER > 17 | |
| 62 | #if _LIBCPP_STD_VER >= 20 | |
| 60 | 63 | *__result = __binary_op(__val, _VSTD::move(__acc)); |
| 61 | 64 | #else |
| 62 | 65 | *__result = __binary_op(__val, __acc); |
| ... | ... | @@ -69,4 +72,6 @@ adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterat |
| 69 | 72 | |
| 70 | 73 | _LIBCPP_END_NAMESPACE_STD |
| 71 | 74 | |
| 75 | _LIBCPP_POP_MACROS | |
| 76 | ||
| 72 | 77 | #endif // _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H |
lib/libcxx/include/__numeric/exclusive_scan.h+7-2| ... | ... | @@ -18,9 +18,12 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | _LIBCPP_PUSH_MACROS | |
| 22 | #include <__undef_macros> | |
| 23 | ||
| 21 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 25 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 26 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 27 | |
| 25 | 28 | template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> |
| 26 | 29 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator |
| ... | ... | @@ -46,8 +49,10 @@ exclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __ |
| 46 | 49 | return _VSTD::exclusive_scan(__first, __last, __result, __init, _VSTD::plus<>()); |
| 47 | 50 | } |
| 48 | 51 | |
| 49 | #endif // _LIBCPP_STD_VER > 14 | |
| 52 | #endif // _LIBCPP_STD_VER >= 17 | |
| 50 | 53 | |
| 51 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 55 | |
| 56 | _LIBCPP_POP_MACROS | |
| 57 | ||
| 53 | 58 | #endif // _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H |
lib/libcxx/include/__numeric/gcd_lcm.h+2-2| ... | ... | @@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 14 | |
| 31 | #if _LIBCPP_STD_VER >= 17 | |
| 32 | 32 | |
| 33 | 33 | template <typename _Result, typename _Source, bool _IsSigned = is_signed<_Source>::value> struct __ct_abs; |
| 34 | 34 | |
| ... | ... | @@ -87,7 +87,7 @@ lcm(_Tp __m, _Up __n) |
| 87 | 87 | using _Rp = common_type_t<_Tp,_Up>; |
| 88 | 88 | _Rp __val1 = __ct_abs<_Rp, _Tp>()(__m) / _VSTD::gcd(__m, __n); |
| 89 | 89 | _Rp __val2 = __ct_abs<_Rp, _Up>()(__n); |
| 90 | _LIBCPP_ASSERT((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); | |
| 90 | _LIBCPP_ASSERT_UNCATEGORIZED((numeric_limits<_Rp>::max() / __val1 > __val2), "Overflow in lcm"); | |
| 91 | 91 | return __val1 * __val2; |
| 92 | 92 | } |
| 93 | 93 |
lib/libcxx/include/__numeric/inclusive_scan.h+2-2| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | |
| 26 | 26 | template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp> |
| 27 | 27 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator |
| ... | ... | @@ -53,7 +53,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator inclusiv |
| 53 | 53 | return _VSTD::inclusive_scan(__first, __last, __result, _VSTD::plus<>()); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | #endif // _LIBCPP_STD_VER > 14 | |
| 56 | #endif // _LIBCPP_STD_VER >= 17 | |
| 57 | 57 | |
| 58 | 58 | _LIBCPP_END_NAMESPACE_STD |
| 59 | 59 |
lib/libcxx/include/__numeric/inner_product.h+7-2| ... | ... | @@ -17,6 +17,9 @@ |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | _LIBCPP_PUSH_MACROS | |
| 21 | #include <__undef_macros> | |
| 22 | ||
| 20 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 24 | |
| 22 | 25 | template <class _InputIterator1, class _InputIterator2, class _Tp> |
| ... | ... | @@ -25,7 +28,7 @@ _Tp |
| 25 | 28 | inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) |
| 26 | 29 | { |
| 27 | 30 | for (; __first1 != __last1; ++__first1, (void) ++__first2) |
| 28 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | 32 | __init = _VSTD::move(__init) + *__first1 * *__first2; |
| 30 | 33 | #else |
| 31 | 34 | __init = __init + *__first1 * *__first2; |
| ... | ... | @@ -40,7 +43,7 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 |
| 40 | 43 | _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) |
| 41 | 44 | { |
| 42 | 45 | for (; __first1 != __last1; ++__first1, (void) ++__first2) |
| 43 | #if _LIBCPP_STD_VER > 17 | |
| 46 | #if _LIBCPP_STD_VER >= 20 | |
| 44 | 47 | __init = __binary_op1(_VSTD::move(__init), __binary_op2(*__first1, *__first2)); |
| 45 | 48 | #else |
| 46 | 49 | __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); |
| ... | ... | @@ -50,4 +53,6 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 |
| 50 | 53 | |
| 51 | 54 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 55 | |
| 56 | _LIBCPP_POP_MACROS | |
| 57 | ||
| 53 | 58 | #endif // _LIBCPP___NUMERIC_INNER_PRODUCT_H |
lib/libcxx/include/__numeric/midpoint.h+2-2| ... | ... | @@ -33,7 +33,7 @@ _LIBCPP_PUSH_MACROS |
| 33 | 33 | |
| 34 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 35 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | template <class _Tp> |
| 38 | 38 | _LIBCPP_INLINE_VISIBILITY constexpr |
| 39 | 39 | enable_if_t<is_integral_v<_Tp> && !is_same_v<bool, _Tp> && !is_null_pointer_v<_Tp>, _Tp> |
| ... | ... | @@ -86,7 +86,7 @@ midpoint(_Fp __a, _Fp __b) noexcept |
| 86 | 86 | __a/2 + __b/2; // otherwise correctly rounded |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | #endif // _LIBCPP_STD_VER > 17 | |
| 89 | #endif // _LIBCPP_STD_VER >= 20 | |
| 90 | 90 | |
| 91 | 91 | _LIBCPP_END_NAMESPACE_STD |
| 92 | 92 |
lib/libcxx/include/__numeric/partial_sum.h+7-2| ... | ... | @@ -18,6 +18,9 @@ |
| 18 | 18 | # pragma GCC system_header |
| 19 | 19 | #endif |
| 20 | 20 | |
| 21 | _LIBCPP_PUSH_MACROS | |
| 22 | #include <__undef_macros> | |
| 23 | ||
| 21 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 25 | |
| 23 | 26 | template <class _InputIterator, class _OutputIterator> |
| ... | ... | @@ -31,7 +34,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res |
| 31 | 34 | *__result = __t; |
| 32 | 35 | for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) |
| 33 | 36 | { |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 38 | __t = _VSTD::move(__t) + *__first; |
| 36 | 39 | #else |
| 37 | 40 | __t = __t + *__first; |
| ... | ... | @@ -54,7 +57,7 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res |
| 54 | 57 | *__result = __t; |
| 55 | 58 | for (++__first, (void) ++__result; __first != __last; ++__first, (void) ++__result) |
| 56 | 59 | { |
| 57 | #if _LIBCPP_STD_VER > 17 | |
| 60 | #if _LIBCPP_STD_VER >= 20 | |
| 58 | 61 | __t = __binary_op(_VSTD::move(__t), *__first); |
| 59 | 62 | #else |
| 60 | 63 | __t = __binary_op(__t, *__first); |
| ... | ... | @@ -67,4 +70,6 @@ partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __res |
| 67 | 70 | |
| 68 | 71 | _LIBCPP_END_NAMESPACE_STD |
| 69 | 72 | |
| 73 | _LIBCPP_POP_MACROS | |
| 74 | ||
| 70 | 75 | #endif // _LIBCPP___NUMERIC_PARTIAL_SUM_H |
lib/libcxx/include/__numeric/pstl_reduce.h created+73| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___NUMERIC_PSTL_REDUCE_H | |
| 10 | #define _LIBCPP___NUMERIC_PSTL_REDUCE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 13 | #include <__config> | |
| 14 | #include <__functional/identity.h> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__numeric/pstl_transform_reduce.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | template <class> | |
| 28 | void __pstl_reduce(); | |
| 29 | ||
| 30 | template <class _ExecutionPolicy, | |
| 31 | class _ForwardIterator, | |
| 32 | class _Tp, | |
| 33 | class _BinaryOperation = plus<>, | |
| 34 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 35 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 36 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 37 | reduce(_ExecutionPolicy&& __policy, | |
| 38 | _ForwardIterator __first, | |
| 39 | _ForwardIterator __last, | |
| 40 | _Tp __init, | |
| 41 | _BinaryOperation __op = {}) { | |
| 42 | return std::__pstl_frontend_dispatch( | |
| 43 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce), | |
| 44 | [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last, _Tp __g_init, _BinaryOperation __g_op) { | |
| 45 | return std::transform_reduce( | |
| 46 | __policy, std::move(__g_first), std::move(__g_last), std::move(__g_init), std::move(__g_op), __identity{}); | |
| 47 | }, | |
| 48 | std::move(__first), | |
| 49 | std::move(__last), | |
| 50 | std::move(__init), | |
| 51 | std::move(__op)); | |
| 52 | } | |
| 53 | ||
| 54 | template <class _ExecutionPolicy, | |
| 55 | class _ForwardIterator, | |
| 56 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 57 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 58 | _LIBCPP_HIDE_FROM_ABI __iter_value_type<_ForwardIterator> | |
| 59 | reduce(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) { | |
| 60 | return std::__pstl_frontend_dispatch( | |
| 61 | _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_reduce), | |
| 62 | [&__policy](_ForwardIterator __g_first, _ForwardIterator __g_last) { | |
| 63 | return std::reduce(__policy, __g_first, __g_last, __iter_value_type<_ForwardIterator>()); | |
| 64 | }, | |
| 65 | std::move(__first), | |
| 66 | std::move(__last)); | |
| 67 | } | |
| 68 | ||
| 69 | _LIBCPP_END_NAMESPACE_STD | |
| 70 | ||
| 71 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 72 | ||
| 73 | #endif // _LIBCPP___NUMERIC_PSTL_REDUCE_H |
lib/libcxx/include/__numeric/pstl_transform_reduce.h created+100| ... | ... | @@ -0,0 +1,100 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H | |
| 10 | #define _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H | |
| 11 | ||
| 12 | #include <__algorithm/pstl_backend.h> | |
| 13 | #include <__algorithm/pstl_frontend_dispatch.h> | |
| 14 | #include <__config> | |
| 15 | #include <__functional/operations.h> | |
| 16 | #include <__numeric/transform_reduce.h> | |
| 17 | #include <__type_traits/is_execution_policy.h> | |
| 18 | #include <__utility/move.h> | |
| 19 | #include <__utility/terminate_on_exception.h> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _ExecutionPolicy, | |
| 30 | class _ForwardIterator1, | |
| 31 | class _ForwardIterator2, | |
| 32 | class _Tp, | |
| 33 | class _BinaryOperation1, | |
| 34 | class _BinaryOperation2, | |
| 35 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 36 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 37 | _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( | |
| 38 | _ExecutionPolicy&&, | |
| 39 | _ForwardIterator1 __first1, | |
| 40 | _ForwardIterator1 __last1, | |
| 41 | _ForwardIterator2 __first2, | |
| 42 | _Tp __init, | |
| 43 | _BinaryOperation1 __reduce, | |
| 44 | _BinaryOperation2 __transform) { | |
| 45 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 46 | return std::__pstl_transform_reduce<_RawPolicy>( | |
| 47 | _Backend{}, | |
| 48 | std::move(__first1), | |
| 49 | std::move(__last1), | |
| 50 | std::move(__first2), | |
| 51 | std::move(__init), | |
| 52 | std::move(__reduce), | |
| 53 | std::move(__transform)); | |
| 54 | } | |
| 55 | ||
| 56 | // This overload doesn't get a customization point because it's trivial to detect (through e.g. | |
| 57 | // __is_trivial_plus_operation) when specializing the more general variant, which should always be preferred | |
| 58 | template <class _ExecutionPolicy, | |
| 59 | class _ForwardIterator1, | |
| 60 | class _ForwardIterator2, | |
| 61 | class _Tp, | |
| 62 | enable_if_t<is_execution_policy_v<__remove_cvref_t<_ExecutionPolicy>>, int> = 0> | |
| 63 | _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( | |
| 64 | _ExecutionPolicy&& __policy, | |
| 65 | _ForwardIterator1 __first1, | |
| 66 | _ForwardIterator1 __last1, | |
| 67 | _ForwardIterator2 __first2, | |
| 68 | _Tp __init) { | |
| 69 | return std::transform_reduce(__policy, __first1, __last1, __first2, __init, plus{}, multiplies{}); | |
| 70 | } | |
| 71 | ||
| 72 | template <class _ExecutionPolicy, | |
| 73 | class _ForwardIterator, | |
| 74 | class _Tp, | |
| 75 | class _BinaryOperation, | |
| 76 | class _UnaryOperation, | |
| 77 | class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, | |
| 78 | enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0> | |
| 79 | _LIBCPP_HIDE_FROM_ABI _Tp transform_reduce( | |
| 80 | _ExecutionPolicy&&, | |
| 81 | _ForwardIterator __first, | |
| 82 | _ForwardIterator __last, | |
| 83 | _Tp __init, | |
| 84 | _BinaryOperation __reduce, | |
| 85 | _UnaryOperation __transform) { | |
| 86 | using _Backend = typename __select_backend<_RawPolicy>::type; | |
| 87 | return std::__pstl_transform_reduce<_RawPolicy>( | |
| 88 | _Backend{}, | |
| 89 | std::move(__first), | |
| 90 | std::move(__last), | |
| 91 | std::move(__init), | |
| 92 | std::move(__reduce), | |
| 93 | std::move(__transform)); | |
| 94 | } | |
| 95 | ||
| 96 | _LIBCPP_END_NAMESPACE_STD | |
| 97 | ||
| 98 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 99 | ||
| 100 | #endif // _LIBCPP___NUMERIC_PSTL_TRANSFORM_REDUCE_H |
lib/libcxx/include/__numeric/reduce.h+3-2| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__functional/operations.h> |
| 15 | 15 | #include <__iterator/iterator_traits.h> |
| 16 | #include <__utility/move.h> | |
| 16 | 17 | |
| 17 | 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 19 | # pragma GCC system_header |
| ... | ... | @@ -20,12 +21,12 @@ |
| 20 | 21 | |
| 21 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 23 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 25 | template <class _InputIterator, class _Tp, class _BinaryOp> |
| 25 | 26 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp reduce(_InputIterator __first, _InputIterator __last, |
| 26 | 27 | _Tp __init, _BinaryOp __b) { |
| 27 | 28 | for (; __first != __last; ++__first) |
| 28 | __init = __b(__init, *__first); | |
| 29 | __init = __b(std::move(__init), *__first); | |
| 29 | 30 | return __init; |
| 30 | 31 | } |
| 31 | 32 |
lib/libcxx/include/__numeric/transform_exclusive_scan.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 14 | |
| 21 | #if _LIBCPP_STD_VER >= 17 | |
| 22 | 22 | |
| 23 | 23 | template <class _InputIterator, class _OutputIterator, class _Tp, |
| 24 | 24 | class _BinaryOp, class _UnaryOp> |
| ... | ... | @@ -42,7 +42,7 @@ transform_exclusive_scan(_InputIterator __first, _InputIterator __last, |
| 42 | 42 | return __result; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | #endif // _LIBCPP_STD_VER > 14 | |
| 45 | #endif // _LIBCPP_STD_VER >= 17 | |
| 46 | 46 | |
| 47 | 47 | _LIBCPP_END_NAMESPACE_STD |
| 48 | 48 |
lib/libcxx/include/__numeric/transform_inclusive_scan.h+2-2| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | |
| 24 | 24 | template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOp, class _UnaryOp> |
| 25 | 25 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -51,7 +51,7 @@ transform_inclusive_scan(_InputIterator __first, _InputIterator __last, |
| 51 | 51 | return __result; |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | #endif // _LIBCPP_STD_VER > 14 | |
| 54 | #endif // _LIBCPP_STD_VER >= 17 | |
| 55 | 55 | |
| 56 | 56 | _LIBCPP_END_NAMESPACE_STD |
| 57 | 57 |
lib/libcxx/include/__numeric/transform_reduce.h+3-3| ... | ... | @@ -20,13 +20,13 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 24 | template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp> |
| 25 | 25 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_InputIterator __first, |
| 26 | 26 | _InputIterator __last, _Tp __init, |
| 27 | 27 | _BinaryOp __b, _UnaryOp __u) { |
| 28 | 28 | for (; __first != __last; ++__first) |
| 29 | __init = __b(__init, __u(*__first)); | |
| 29 | __init = __b(std::move(__init), __u(*__first)); | |
| 30 | 30 | return __init; |
| 31 | 31 | } |
| 32 | 32 | |
| ... | ... | @@ -36,7 +36,7 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp transform_reduce(_In |
| 36 | 36 | _InputIterator2 __first2, _Tp __init, |
| 37 | 37 | _BinaryOp1 __b1, _BinaryOp2 __b2) { |
| 38 | 38 | for (; __first1 != __last1; ++__first1, (void)++__first2) |
| 39 | __init = __b1(__init, __b2(*__first1, *__first2)); | |
| 39 | __init = __b1(std::move(__init), __b2(*__first1, *__first2)); | |
| 40 | 40 | return __init; |
| 41 | 41 | } |
| 42 | 42 |
lib/libcxx/include/__pstl/internal/algorithm_fwd.h created+1768| ... | ... | @@ -0,0 +1,1768 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_ALGORITHM_FWD_H | |
| 11 | #define _PSTL_ALGORITHM_FWD_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <iterator> | |
| 15 | #include <type_traits> | |
| 16 | #include <utility> | |
| 17 | ||
| 18 | namespace __pstl { | |
| 19 | namespace __internal { | |
| 20 | ||
| 21 | //------------------------------------------------------------------------ | |
| 22 | // walk1 (pseudo) | |
| 23 | // | |
| 24 | // walk1 evaluates f(x) for each dereferenced value x drawn from [first,last) | |
| 25 | //------------------------------------------------------------------------ | |
| 26 | ||
| 27 | template <class _ForwardIterator, class _Function> | |
| 28 | void __brick_walk1(_ForwardIterator, | |
| 29 | _ForwardIterator, | |
| 30 | _Function, | |
| 31 | /*vector=*/std::false_type) noexcept; | |
| 32 | ||
| 33 | template <class _RandomAccessIterator, class _Function> | |
| 34 | void __brick_walk1(_RandomAccessIterator, | |
| 35 | _RandomAccessIterator, | |
| 36 | _Function, | |
| 37 | /*vector=*/std::true_type) noexcept; | |
| 38 | ||
| 39 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function> | |
| 40 | void __pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept; | |
| 41 | ||
| 42 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function> | |
| 43 | void __pattern_walk1( | |
| 44 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function); | |
| 45 | ||
| 46 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick> | |
| 47 | void __pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept; | |
| 48 | ||
| 49 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick> | |
| 50 | void __pattern_walk_brick( | |
| 51 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Brick); | |
| 52 | ||
| 53 | //------------------------------------------------------------------------ | |
| 54 | // walk1_n | |
| 55 | //------------------------------------------------------------------------ | |
| 56 | ||
| 57 | template <class _ForwardIterator, class _Size, class _Function> | |
| 58 | _ForwardIterator __brick_walk1_n( | |
| 59 | _ForwardIterator, | |
| 60 | _Size, | |
| 61 | _Function, | |
| 62 | /*_IsVectorTag=*/std::false_type); | |
| 63 | ||
| 64 | template <class _RandomAccessIterator, class _DifferenceType, class _Function> | |
| 65 | _RandomAccessIterator __brick_walk1_n( | |
| 66 | _RandomAccessIterator, | |
| 67 | _DifferenceType, | |
| 68 | _Function, | |
| 69 | /*vectorTag=*/std::true_type) noexcept; | |
| 70 | ||
| 71 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function> | |
| 72 | _ForwardIterator __pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept; | |
| 73 | ||
| 74 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function> | |
| 75 | _RandomAccessIterator | |
| 76 | __pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function); | |
| 77 | ||
| 78 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick> | |
| 79 | _ForwardIterator __pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept; | |
| 80 | ||
| 81 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick> | |
| 82 | _RandomAccessIterator | |
| 83 | __pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick); | |
| 84 | ||
| 85 | //------------------------------------------------------------------------ | |
| 86 | // walk2 (pseudo) | |
| 87 | // | |
| 88 | // walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...) | |
| 89 | //------------------------------------------------------------------------ | |
| 90 | ||
| 91 | template <class _ForwardIterator1, class _ForwardIterator2, class _Function> | |
| 92 | _ForwardIterator2 __brick_walk2( | |
| 93 | _ForwardIterator1, | |
| 94 | _ForwardIterator1, | |
| 95 | _ForwardIterator2, | |
| 96 | _Function, | |
| 97 | /*vector=*/std::false_type) noexcept; | |
| 98 | ||
| 99 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function> | |
| 100 | _RandomAccessIterator2 __brick_walk2( | |
| 101 | _RandomAccessIterator1, | |
| 102 | _RandomAccessIterator1, | |
| 103 | _RandomAccessIterator2, | |
| 104 | _Function, | |
| 105 | /*vector=*/std::true_type) noexcept; | |
| 106 | ||
| 107 | template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function> | |
| 108 | _ForwardIterator2 __brick_walk2_n( | |
| 109 | _ForwardIterator1, | |
| 110 | _Size, | |
| 111 | _ForwardIterator2, | |
| 112 | _Function, | |
| 113 | /*vector=*/std::false_type) noexcept; | |
| 114 | ||
| 115 | template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function> | |
| 116 | _RandomAccessIterator2 __brick_walk2_n( | |
| 117 | _RandomAccessIterator1, | |
| 118 | _Size, | |
| 119 | _RandomAccessIterator2, | |
| 120 | _Function, | |
| 121 | /*vector=*/std::true_type) noexcept; | |
| 122 | ||
| 123 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function> | |
| 124 | _ForwardIterator2 | |
| 125 | __pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept; | |
| 126 | ||
| 127 | template <class _IsVector, | |
| 128 | class _ExecutionPolicy, | |
| 129 | class _RandomAccessIterator1, | |
| 130 | class _RandomAccessIterator2, | |
| 131 | class _Function> | |
| 132 | _RandomAccessIterator2 __pattern_walk2( | |
| 133 | __parallel_tag<_IsVector>, | |
| 134 | _ExecutionPolicy&&, | |
| 135 | _RandomAccessIterator1, | |
| 136 | _RandomAccessIterator1, | |
| 137 | _RandomAccessIterator2, | |
| 138 | _Function); | |
| 139 | ||
| 140 | template <class _Tag, | |
| 141 | class _ExecutionPolicy, | |
| 142 | class _ForwardIterator1, | |
| 143 | class _Size, | |
| 144 | class _ForwardIterator2, | |
| 145 | class _Function> | |
| 146 | _ForwardIterator2 | |
| 147 | __pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept; | |
| 148 | ||
| 149 | template <class _IsVector, | |
| 150 | class _ExecutionPolicy, | |
| 151 | class _RandomAccessIterator1, | |
| 152 | class _Size, | |
| 153 | class _RandomAccessIterator2, | |
| 154 | class _Function> | |
| 155 | _RandomAccessIterator2 __pattern_walk2_n( | |
| 156 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function); | |
| 157 | ||
| 158 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick> | |
| 159 | _ForwardIterator2 __pattern_walk2_brick( | |
| 160 | _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick) noexcept; | |
| 161 | ||
| 162 | template <class _IsVector, | |
| 163 | class _ExecutionPolicy, | |
| 164 | class _RandomAccessIterator1, | |
| 165 | class _RandomAccessIterator2, | |
| 166 | class _Brick> | |
| 167 | _RandomAccessIterator2 __pattern_walk2_brick( | |
| 168 | __parallel_tag<_IsVector>, | |
| 169 | _ExecutionPolicy&&, | |
| 170 | _RandomAccessIterator1, | |
| 171 | _RandomAccessIterator1, | |
| 172 | _RandomAccessIterator2, | |
| 173 | _Brick); | |
| 174 | ||
| 175 | template <class _Tag, | |
| 176 | class _ExecutionPolicy, | |
| 177 | class _ForwardIterator1, | |
| 178 | class _Size, | |
| 179 | class _ForwardIterator2, | |
| 180 | class _Brick> | |
| 181 | _ForwardIterator2 | |
| 182 | __pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept; | |
| 183 | ||
| 184 | template <class _IsVector, | |
| 185 | class _ExecutionPolicy, | |
| 186 | class _RandomAccessIterator1, | |
| 187 | class _Size, | |
| 188 | class _RandomAccessIterator2, | |
| 189 | class _Brick> | |
| 190 | _RandomAccessIterator2 __pattern_walk2_brick_n( | |
| 191 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick); | |
| 192 | ||
| 193 | //------------------------------------------------------------------------ | |
| 194 | // walk3 (pseudo) | |
| 195 | // | |
| 196 | // walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...) | |
| 197 | //------------------------------------------------------------------------ | |
| 198 | ||
| 199 | template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function> | |
| 200 | _ForwardIterator3 __brick_walk3( | |
| 201 | _ForwardIterator1, | |
| 202 | _ForwardIterator1, | |
| 203 | _ForwardIterator2, | |
| 204 | _ForwardIterator3, | |
| 205 | _Function, | |
| 206 | /*vector=*/std::false_type) noexcept; | |
| 207 | ||
| 208 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function> | |
| 209 | _RandomAccessIterator3 __brick_walk3( | |
| 210 | _RandomAccessIterator1, | |
| 211 | _RandomAccessIterator1, | |
| 212 | _RandomAccessIterator2, | |
| 213 | _RandomAccessIterator3, | |
| 214 | _Function, | |
| 215 | /*vector=*/std::true_type) noexcept; | |
| 216 | ||
| 217 | template <class _Tag, | |
| 218 | class _ExecutionPolicy, | |
| 219 | class _ForwardIterator1, | |
| 220 | class _ForwardIterator2, | |
| 221 | class _ForwardIterator3, | |
| 222 | class _Function> | |
| 223 | _ForwardIterator3 __pattern_walk3( | |
| 224 | _Tag, | |
| 225 | _ExecutionPolicy&&, | |
| 226 | _ForwardIterator1, | |
| 227 | _ForwardIterator1, | |
| 228 | _ForwardIterator2, | |
| 229 | _ForwardIterator3, | |
| 230 | _Function) noexcept; | |
| 231 | ||
| 232 | template <class _IsVector, | |
| 233 | class _ExecutionPolicy, | |
| 234 | class _RandomAccessIterator1, | |
| 235 | class _RandomAccessIterator2, | |
| 236 | class _RandomAccessIterator3, | |
| 237 | class _Function> | |
| 238 | _RandomAccessIterator3 __pattern_walk3( | |
| 239 | __parallel_tag<_IsVector>, | |
| 240 | _ExecutionPolicy&&, | |
| 241 | _RandomAccessIterator1, | |
| 242 | _RandomAccessIterator1, | |
| 243 | _RandomAccessIterator2, | |
| 244 | _RandomAccessIterator3, | |
| 245 | _Function); | |
| 246 | ||
| 247 | //------------------------------------------------------------------------ | |
| 248 | // equal | |
| 249 | //------------------------------------------------------------------------ | |
| 250 | ||
| 251 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 252 | bool __brick_equal(_ForwardIterator1, | |
| 253 | _ForwardIterator1, | |
| 254 | _ForwardIterator2, | |
| 255 | _BinaryPredicate, | |
| 256 | /* is_vector = */ std::false_type) noexcept; | |
| 257 | ||
| 258 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 259 | bool __brick_equal(_RandomAccessIterator1, | |
| 260 | _RandomAccessIterator1, | |
| 261 | _RandomAccessIterator2, | |
| 262 | _BinaryPredicate, | |
| 263 | /* is_vector = */ std::true_type) noexcept; | |
| 264 | ||
| 265 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 266 | bool __pattern_equal( | |
| 267 | _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate) noexcept; | |
| 268 | ||
| 269 | template <class _IsVector, | |
| 270 | class _ExecutionPolicy, | |
| 271 | class _RandomAccessIterator1, | |
| 272 | class _RandomAccessIterator2, | |
| 273 | class _BinaryPredicate> | |
| 274 | bool __pattern_equal( | |
| 275 | __parallel_tag<_IsVector>, | |
| 276 | _ExecutionPolicy&&, | |
| 277 | _RandomAccessIterator1, | |
| 278 | _RandomAccessIterator1, | |
| 279 | _RandomAccessIterator2, | |
| 280 | _BinaryPredicate); | |
| 281 | ||
| 282 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 283 | bool __brick_equal(_ForwardIterator1, | |
| 284 | _ForwardIterator1, | |
| 285 | _ForwardIterator2, | |
| 286 | _ForwardIterator2, | |
| 287 | _BinaryPredicate, | |
| 288 | /* is_vector = */ std::false_type) noexcept; | |
| 289 | ||
| 290 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 291 | bool __brick_equal(_RandomAccessIterator1, | |
| 292 | _RandomAccessIterator1, | |
| 293 | _RandomAccessIterator2, | |
| 294 | _RandomAccessIterator2, | |
| 295 | _BinaryPredicate, | |
| 296 | /* is_vector = */ std::true_type) noexcept; | |
| 297 | ||
| 298 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 299 | bool __pattern_equal( | |
| 300 | _Tag, | |
| 301 | _ExecutionPolicy&&, | |
| 302 | _ForwardIterator1, | |
| 303 | _ForwardIterator1, | |
| 304 | _ForwardIterator2, | |
| 305 | _ForwardIterator2, | |
| 306 | _BinaryPredicate) noexcept; | |
| 307 | ||
| 308 | template <class _IsVector, | |
| 309 | class _ExecutionPolicy, | |
| 310 | class _RandomAccessIterator1, | |
| 311 | class _RandomAccessIterator2, | |
| 312 | class _BinaryPredicate> | |
| 313 | bool __pattern_equal( | |
| 314 | __parallel_tag<_IsVector>, | |
| 315 | _ExecutionPolicy&&, | |
| 316 | _RandomAccessIterator1, | |
| 317 | _RandomAccessIterator1, | |
| 318 | _RandomAccessIterator2, | |
| 319 | _RandomAccessIterator2, | |
| 320 | _BinaryPredicate); | |
| 321 | ||
| 322 | //------------------------------------------------------------------------ | |
| 323 | // find_end | |
| 324 | //------------------------------------------------------------------------ | |
| 325 | ||
| 326 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 327 | _ForwardIterator1 __brick_find_end( | |
| 328 | _ForwardIterator1, | |
| 329 | _ForwardIterator1, | |
| 330 | _ForwardIterator2, | |
| 331 | _ForwardIterator2, | |
| 332 | _BinaryPredicate, | |
| 333 | /*__is_vector=*/std::false_type) noexcept; | |
| 334 | ||
| 335 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 336 | _RandomAccessIterator1 __brick_find_end( | |
| 337 | _RandomAccessIterator1, | |
| 338 | _RandomAccessIterator1, | |
| 339 | _RandomAccessIterator2, | |
| 340 | _RandomAccessIterator2, | |
| 341 | _BinaryPredicate, | |
| 342 | /*__is_vector=*/std::true_type) noexcept; | |
| 343 | ||
| 344 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 345 | _ForwardIterator1 __pattern_find_end( | |
| 346 | _Tag, | |
| 347 | _ExecutionPolicy&&, | |
| 348 | _ForwardIterator1, | |
| 349 | _ForwardIterator1, | |
| 350 | _ForwardIterator2, | |
| 351 | _ForwardIterator2, | |
| 352 | _BinaryPredicate) noexcept; | |
| 353 | ||
| 354 | template <class _IsVector, | |
| 355 | class _ExecutionPolicy, | |
| 356 | class _RandomAccessIterator1, | |
| 357 | class _RandomAccessIterator2, | |
| 358 | class _BinaryPredicate> | |
| 359 | _RandomAccessIterator1 __pattern_find_end( | |
| 360 | __parallel_tag<_IsVector>, | |
| 361 | _ExecutionPolicy&&, | |
| 362 | _RandomAccessIterator1, | |
| 363 | _RandomAccessIterator1, | |
| 364 | _RandomAccessIterator2, | |
| 365 | _RandomAccessIterator2, | |
| 366 | _BinaryPredicate) noexcept; | |
| 367 | ||
| 368 | //------------------------------------------------------------------------ | |
| 369 | // find_first_of | |
| 370 | //------------------------------------------------------------------------ | |
| 371 | ||
| 372 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 373 | _ForwardIterator1 __brick_find_first_of( | |
| 374 | _ForwardIterator1, | |
| 375 | _ForwardIterator1, | |
| 376 | _ForwardIterator2, | |
| 377 | _ForwardIterator2, | |
| 378 | _BinaryPredicate, | |
| 379 | /*__is_vector=*/std::false_type) noexcept; | |
| 380 | ||
| 381 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 382 | _RandomAccessIterator1 __brick_find_first_of( | |
| 383 | _RandomAccessIterator1, | |
| 384 | _RandomAccessIterator1, | |
| 385 | _RandomAccessIterator2, | |
| 386 | _RandomAccessIterator2, | |
| 387 | _BinaryPredicate, | |
| 388 | /*__is_vector=*/std::true_type) noexcept; | |
| 389 | ||
| 390 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 391 | _ForwardIterator1 __pattern_find_first_of( | |
| 392 | _Tag, | |
| 393 | _ExecutionPolicy&&, | |
| 394 | _ForwardIterator1, | |
| 395 | _ForwardIterator1, | |
| 396 | _ForwardIterator2, | |
| 397 | _ForwardIterator2, | |
| 398 | _BinaryPredicate) noexcept; | |
| 399 | ||
| 400 | template <class _IsVector, | |
| 401 | class _ExecutionPolicy, | |
| 402 | class _RandomAccessIterator1, | |
| 403 | class _RandomAccessIterator2, | |
| 404 | class _BinaryPredicate> | |
| 405 | _RandomAccessIterator1 __pattern_find_first_of( | |
| 406 | __parallel_tag<_IsVector>, | |
| 407 | _ExecutionPolicy&&, | |
| 408 | _RandomAccessIterator1, | |
| 409 | _RandomAccessIterator1, | |
| 410 | _RandomAccessIterator2, | |
| 411 | _RandomAccessIterator2, | |
| 412 | _BinaryPredicate) noexcept; | |
| 413 | ||
| 414 | //------------------------------------------------------------------------ | |
| 415 | // search | |
| 416 | //------------------------------------------------------------------------ | |
| 417 | ||
| 418 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 419 | _ForwardIterator1 __brick_search( | |
| 420 | _ForwardIterator1, | |
| 421 | _ForwardIterator1, | |
| 422 | _ForwardIterator2, | |
| 423 | _ForwardIterator2, | |
| 424 | _BinaryPredicate, | |
| 425 | /*vector=*/std::false_type) noexcept; | |
| 426 | ||
| 427 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 428 | _RandomAccessIterator1 __brick_search( | |
| 429 | _RandomAccessIterator1, | |
| 430 | _RandomAccessIterator1, | |
| 431 | _RandomAccessIterator2, | |
| 432 | _RandomAccessIterator2, | |
| 433 | _BinaryPredicate, | |
| 434 | /*vector=*/std::true_type) noexcept; | |
| 435 | ||
| 436 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 437 | _ForwardIterator1 __pattern_search( | |
| 438 | _Tag, | |
| 439 | _ExecutionPolicy&&, | |
| 440 | _ForwardIterator1, | |
| 441 | _ForwardIterator1, | |
| 442 | _ForwardIterator2, | |
| 443 | _ForwardIterator2, | |
| 444 | _BinaryPredicate) noexcept; | |
| 445 | ||
| 446 | template <class _IsVector, | |
| 447 | class _ExecutionPolicy, | |
| 448 | class _RandomAccessIterator1, | |
| 449 | class _RandomAccessIterator2, | |
| 450 | class _BinaryPredicate> | |
| 451 | _RandomAccessIterator1 __pattern_search( | |
| 452 | __parallel_tag<_IsVector>, | |
| 453 | _ExecutionPolicy&&, | |
| 454 | _RandomAccessIterator1, | |
| 455 | _RandomAccessIterator1, | |
| 456 | _RandomAccessIterator2, | |
| 457 | _RandomAccessIterator2, | |
| 458 | _BinaryPredicate) noexcept; | |
| 459 | ||
| 460 | //------------------------------------------------------------------------ | |
| 461 | // search_n | |
| 462 | //------------------------------------------------------------------------ | |
| 463 | ||
| 464 | template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 465 | _ForwardIterator __brick_search_n( | |
| 466 | _ForwardIterator, | |
| 467 | _ForwardIterator, | |
| 468 | _Size, | |
| 469 | const _Tp&, | |
| 470 | _BinaryPredicate, | |
| 471 | /*vector=*/std::false_type) noexcept; | |
| 472 | ||
| 473 | template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 474 | _RandomAccessIterator __brick_search_n( | |
| 475 | _RandomAccessIterator, | |
| 476 | _RandomAccessIterator, | |
| 477 | _Size, | |
| 478 | const _Tp&, | |
| 479 | _BinaryPredicate, | |
| 480 | /*vector=*/std::true_type) noexcept; | |
| 481 | ||
| 482 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 483 | _ForwardIterator __pattern_search_n( | |
| 484 | _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate) noexcept; | |
| 485 | ||
| 486 | template <class _IsVector, | |
| 487 | class _ExecutionPolicy, | |
| 488 | class _RandomAccessIterator, | |
| 489 | class _Size, | |
| 490 | class _Tp, | |
| 491 | class _BinaryPredicate> | |
| 492 | _RandomAccessIterator __pattern_search_n( | |
| 493 | __parallel_tag<_IsVector>, | |
| 494 | _ExecutionPolicy&&, | |
| 495 | _RandomAccessIterator, | |
| 496 | _RandomAccessIterator, | |
| 497 | _Size, | |
| 498 | const _Tp&, | |
| 499 | _BinaryPredicate) noexcept; | |
| 500 | ||
| 501 | //------------------------------------------------------------------------ | |
| 502 | // copy_n | |
| 503 | //------------------------------------------------------------------------ | |
| 504 | ||
| 505 | template <class _ForwardIterator, class _Size, class _OutputIterator> | |
| 506 | _OutputIterator __brick_copy_n(_ForwardIterator, | |
| 507 | _Size, | |
| 508 | _OutputIterator, | |
| 509 | /*vector=*/std::false_type) noexcept; | |
| 510 | ||
| 511 | template <class _RandomAccessIterator, class _Size, class _OutputIterator> | |
| 512 | _OutputIterator __brick_copy_n(_RandomAccessIterator, | |
| 513 | _Size, | |
| 514 | _OutputIterator, | |
| 515 | /*vector=*/std::true_type) noexcept; | |
| 516 | ||
| 517 | //------------------------------------------------------------------------ | |
| 518 | // copy | |
| 519 | //------------------------------------------------------------------------ | |
| 520 | ||
| 521 | template <class _ForwardIterator, class _OutputIterator> | |
| 522 | _OutputIterator __brick_copy(_ForwardIterator, | |
| 523 | _ForwardIterator, | |
| 524 | _OutputIterator, | |
| 525 | /*vector=*/std::false_type) noexcept; | |
| 526 | ||
| 527 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 528 | _OutputIterator __brick_copy(_RandomAccessIterator, | |
| 529 | _RandomAccessIterator, | |
| 530 | _OutputIterator, | |
| 531 | /*vector=*/std::true_type) noexcept; | |
| 532 | ||
| 533 | //------------------------------------------------------------------------ | |
| 534 | // move | |
| 535 | //------------------------------------------------------------------------ | |
| 536 | ||
| 537 | template <class _ForwardIterator, class _OutputIterator> | |
| 538 | _OutputIterator __brick_move(_ForwardIterator, | |
| 539 | _ForwardIterator, | |
| 540 | _OutputIterator, | |
| 541 | /*vector=*/std::false_type) noexcept; | |
| 542 | ||
| 543 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 544 | _OutputIterator __brick_move(_RandomAccessIterator, | |
| 545 | _RandomAccessIterator, | |
| 546 | _OutputIterator, | |
| 547 | /*vector=*/std::true_type) noexcept; | |
| 548 | ||
| 549 | //------------------------------------------------------------------------ | |
| 550 | // swap_ranges | |
| 551 | //------------------------------------------------------------------------ | |
| 552 | template <class _ForwardIterator, class _OutputIterator> | |
| 553 | _OutputIterator __brick_swap_ranges( | |
| 554 | _ForwardIterator, | |
| 555 | _ForwardIterator, | |
| 556 | _OutputIterator, | |
| 557 | /*vector=*/std::false_type) noexcept; | |
| 558 | ||
| 559 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 560 | _OutputIterator __brick_swap_ranges( | |
| 561 | _RandomAccessIterator, | |
| 562 | _RandomAccessIterator, | |
| 563 | _OutputIterator, | |
| 564 | /*vector=*/std::true_type) noexcept; | |
| 565 | ||
| 566 | //------------------------------------------------------------------------ | |
| 567 | // copy_if | |
| 568 | //------------------------------------------------------------------------ | |
| 569 | ||
| 570 | template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate> | |
| 571 | _OutputIterator __brick_copy_if( | |
| 572 | _ForwardIterator, | |
| 573 | _ForwardIterator, | |
| 574 | _OutputIterator, | |
| 575 | _UnaryPredicate, | |
| 576 | /*vector=*/std::false_type) noexcept; | |
| 577 | ||
| 578 | template <class _RandomAccessIterator, class _OutputIterator, class _UnaryPredicate> | |
| 579 | _OutputIterator __brick_copy_if( | |
| 580 | _RandomAccessIterator, | |
| 581 | _RandomAccessIterator, | |
| 582 | _OutputIterator, | |
| 583 | _UnaryPredicate, | |
| 584 | /*vector=*/std::true_type) noexcept; | |
| 585 | ||
| 586 | template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate> | |
| 587 | std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( | |
| 588 | _ForwardIterator, | |
| 589 | _ForwardIterator, | |
| 590 | bool* __restrict, | |
| 591 | _UnaryPredicate, | |
| 592 | /*vector=*/std::false_type) noexcept; | |
| 593 | template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate> | |
| 594 | std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( | |
| 595 | _RandomAccessIterator, | |
| 596 | _RandomAccessIterator, | |
| 597 | bool* __restrict, | |
| 598 | _UnaryPredicate, | |
| 599 | /*vector=*/std::true_type) noexcept; | |
| 600 | ||
| 601 | template <class _ForwardIterator, class _OutputIterator> | |
| 602 | void __brick_copy_by_mask( | |
| 603 | _ForwardIterator, | |
| 604 | _ForwardIterator, | |
| 605 | _OutputIterator, | |
| 606 | bool*, | |
| 607 | /*vector=*/std::false_type) noexcept; | |
| 608 | ||
| 609 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 610 | void __brick_copy_by_mask( | |
| 611 | _RandomAccessIterator, | |
| 612 | _RandomAccessIterator, | |
| 613 | _OutputIterator, | |
| 614 | bool* __restrict, | |
| 615 | /*vector=*/std::true_type) noexcept; | |
| 616 | ||
| 617 | template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2> | |
| 618 | void __brick_partition_by_mask( | |
| 619 | _ForwardIterator, | |
| 620 | _ForwardIterator, | |
| 621 | _OutputIterator1, | |
| 622 | _OutputIterator2, | |
| 623 | bool*, | |
| 624 | /*vector=*/std::false_type) noexcept; | |
| 625 | ||
| 626 | template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2> | |
| 627 | void __brick_partition_by_mask( | |
| 628 | _RandomAccessIterator, | |
| 629 | _RandomAccessIterator, | |
| 630 | _OutputIterator1, | |
| 631 | _OutputIterator2, | |
| 632 | bool*, | |
| 633 | /*vector=*/std::true_type) noexcept; | |
| 634 | ||
| 635 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate> | |
| 636 | _OutputIterator __pattern_copy_if( | |
| 637 | _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate) noexcept; | |
| 638 | ||
| 639 | template <class _IsVector, | |
| 640 | class _ExecutionPolicy, | |
| 641 | class _RandomAccessIterator, | |
| 642 | class _OutputIterator, | |
| 643 | class _UnaryPredicate> | |
| 644 | _OutputIterator __pattern_copy_if( | |
| 645 | __parallel_tag<_IsVector>, | |
| 646 | _ExecutionPolicy&&, | |
| 647 | _RandomAccessIterator, | |
| 648 | _RandomAccessIterator, | |
| 649 | _OutputIterator, | |
| 650 | _UnaryPredicate); | |
| 651 | ||
| 652 | //------------------------------------------------------------------------ | |
| 653 | // count | |
| 654 | //------------------------------------------------------------------------ | |
| 655 | ||
| 656 | template <class _RandomAccessIterator, class _Predicate> | |
| 657 | typename std::iterator_traits<_RandomAccessIterator>::difference_type __brick_count( | |
| 658 | _RandomAccessIterator, | |
| 659 | _RandomAccessIterator, | |
| 660 | _Predicate, | |
| 661 | /* is_vector = */ std::true_type) noexcept; | |
| 662 | ||
| 663 | template <class _ForwardIterator, class _Predicate> | |
| 664 | typename std::iterator_traits<_ForwardIterator>::difference_type __brick_count( | |
| 665 | _ForwardIterator, | |
| 666 | _ForwardIterator, | |
| 667 | _Predicate, | |
| 668 | /* is_vector = */ std::false_type) noexcept; | |
| 669 | ||
| 670 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 671 | typename std::iterator_traits<_ForwardIterator>::difference_type | |
| 672 | __pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; | |
| 673 | ||
| 674 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate> | |
| 675 | typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count( | |
| 676 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate); | |
| 677 | ||
| 678 | //------------------------------------------------------------------------ | |
| 679 | // unique | |
| 680 | //------------------------------------------------------------------------ | |
| 681 | ||
| 682 | template <class _ForwardIterator, class _BinaryPredicate> | |
| 683 | _ForwardIterator __brick_unique( | |
| 684 | _ForwardIterator, | |
| 685 | _ForwardIterator, | |
| 686 | _BinaryPredicate, | |
| 687 | /*is_vector=*/std::false_type) noexcept; | |
| 688 | ||
| 689 | template <class _RandomAccessIterator, class _BinaryPredicate> | |
| 690 | _RandomAccessIterator __brick_unique( | |
| 691 | _RandomAccessIterator, | |
| 692 | _RandomAccessIterator, | |
| 693 | _BinaryPredicate, | |
| 694 | /*is_vector=*/std::true_type) noexcept; | |
| 695 | ||
| 696 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 697 | _ForwardIterator | |
| 698 | __pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept; | |
| 699 | ||
| 700 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate> | |
| 701 | _RandomAccessIterator __pattern_unique( | |
| 702 | __parallel_tag<_IsVector>, | |
| 703 | _ExecutionPolicy&&, | |
| 704 | _RandomAccessIterator, | |
| 705 | _RandomAccessIterator, | |
| 706 | _BinaryPredicate) noexcept; | |
| 707 | ||
| 708 | //------------------------------------------------------------------------ | |
| 709 | // unique_copy | |
| 710 | //------------------------------------------------------------------------ | |
| 711 | ||
| 712 | template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate> | |
| 713 | OutputIterator __brick_unique_copy( | |
| 714 | _ForwardIterator, | |
| 715 | _ForwardIterator, | |
| 716 | OutputIterator, | |
| 717 | _BinaryPredicate, | |
| 718 | /*vector=*/std::false_type) noexcept; | |
| 719 | ||
| 720 | template <class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate> | |
| 721 | _OutputIterator __brick_unique_copy( | |
| 722 | _RandomAccessIterator, | |
| 723 | _RandomAccessIterator, | |
| 724 | _OutputIterator, | |
| 725 | _BinaryPredicate, | |
| 726 | /*vector=*/std::true_type) noexcept; | |
| 727 | ||
| 728 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate> | |
| 729 | _OutputIterator __pattern_unique_copy( | |
| 730 | _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate) noexcept; | |
| 731 | ||
| 732 | template <class _ExecutionPolicy, class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate> | |
| 733 | _DifferenceType __brick_calc_mask_2( | |
| 734 | _RandomAccessIterator, | |
| 735 | _RandomAccessIterator, | |
| 736 | bool* __restrict, | |
| 737 | _BinaryPredicate, | |
| 738 | /*vector=*/std::false_type) noexcept; | |
| 739 | ||
| 740 | template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate> | |
| 741 | _DifferenceType __brick_calc_mask_2( | |
| 742 | _RandomAccessIterator, | |
| 743 | _RandomAccessIterator, | |
| 744 | bool* __restrict, | |
| 745 | _BinaryPredicate, | |
| 746 | /*vector=*/std::true_type) noexcept; | |
| 747 | ||
| 748 | template <class _IsVector, | |
| 749 | class _ExecutionPolicy, | |
| 750 | class _RandomAccessIterator, | |
| 751 | class _OutputIterator, | |
| 752 | class _BinaryPredicate> | |
| 753 | _OutputIterator __pattern_unique_copy( | |
| 754 | __parallel_tag<_IsVector>, | |
| 755 | _ExecutionPolicy&&, | |
| 756 | _RandomAccessIterator, | |
| 757 | _RandomAccessIterator, | |
| 758 | _OutputIterator, | |
| 759 | _BinaryPredicate); | |
| 760 | ||
| 761 | //------------------------------------------------------------------------ | |
| 762 | // reverse | |
| 763 | //------------------------------------------------------------------------ | |
| 764 | ||
| 765 | template <class _BidirectionalIterator> | |
| 766 | void __brick_reverse(_BidirectionalIterator, | |
| 767 | _BidirectionalIterator, | |
| 768 | /*__is_vector=*/std::false_type) noexcept; | |
| 769 | ||
| 770 | template <class _RandomAccessIterator> | |
| 771 | void __brick_reverse(_RandomAccessIterator, | |
| 772 | _RandomAccessIterator, | |
| 773 | /*__is_vector=*/std::true_type) noexcept; | |
| 774 | ||
| 775 | template <class _BidirectionalIterator> | |
| 776 | void __brick_reverse(_BidirectionalIterator, | |
| 777 | _BidirectionalIterator, | |
| 778 | _BidirectionalIterator, | |
| 779 | /*is_vector=*/std::false_type) noexcept; | |
| 780 | ||
| 781 | template <class _RandomAccessIterator> | |
| 782 | void __brick_reverse(_RandomAccessIterator, | |
| 783 | _RandomAccessIterator, | |
| 784 | _RandomAccessIterator, | |
| 785 | /*is_vector=*/std::true_type) noexcept; | |
| 786 | ||
| 787 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator> | |
| 788 | void __pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept; | |
| 789 | ||
| 790 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator> | |
| 791 | void __pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator); | |
| 792 | ||
| 793 | //------------------------------------------------------------------------ | |
| 794 | // reverse_copy | |
| 795 | //------------------------------------------------------------------------ | |
| 796 | ||
| 797 | template <class _BidirectionalIterator, class _OutputIterator> | |
| 798 | _OutputIterator __brick_reverse_copy( | |
| 799 | _BidirectionalIterator, | |
| 800 | _BidirectionalIterator, | |
| 801 | _OutputIterator, | |
| 802 | /*is_vector=*/std::false_type) noexcept; | |
| 803 | ||
| 804 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 805 | _OutputIterator __brick_reverse_copy( | |
| 806 | _RandomAccessIterator, | |
| 807 | _RandomAccessIterator, | |
| 808 | _OutputIterator, | |
| 809 | /*is_vector=*/std::true_type) noexcept; | |
| 810 | ||
| 811 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator> | |
| 812 | _OutputIterator __pattern_reverse_copy( | |
| 813 | _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator) noexcept; | |
| 814 | ||
| 815 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator> | |
| 816 | _OutputIterator __pattern_reverse_copy( | |
| 817 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator); | |
| 818 | ||
| 819 | //------------------------------------------------------------------------ | |
| 820 | // rotate | |
| 821 | //------------------------------------------------------------------------ | |
| 822 | ||
| 823 | template <class _ForwardIterator> | |
| 824 | _ForwardIterator __brick_rotate( | |
| 825 | _ForwardIterator, | |
| 826 | _ForwardIterator, | |
| 827 | _ForwardIterator, | |
| 828 | /*is_vector=*/std::false_type) noexcept; | |
| 829 | ||
| 830 | template <class _RandomAccessIterator> | |
| 831 | _RandomAccessIterator __brick_rotate( | |
| 832 | _RandomAccessIterator, | |
| 833 | _RandomAccessIterator, | |
| 834 | _RandomAccessIterator, | |
| 835 | /*is_vector=*/std::true_type) noexcept; | |
| 836 | ||
| 837 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator> | |
| 838 | _ForwardIterator | |
| 839 | __pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept; | |
| 840 | ||
| 841 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator> | |
| 842 | _RandomAccessIterator __pattern_rotate( | |
| 843 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator); | |
| 844 | ||
| 845 | //------------------------------------------------------------------------ | |
| 846 | // rotate_copy | |
| 847 | //------------------------------------------------------------------------ | |
| 848 | ||
| 849 | template <class _ForwardIterator, class _OutputIterator> | |
| 850 | _OutputIterator __brick_rotate_copy( | |
| 851 | _ForwardIterator, | |
| 852 | _ForwardIterator, | |
| 853 | _ForwardIterator, | |
| 854 | _OutputIterator, | |
| 855 | /*__is_vector=*/std::false_type) noexcept; | |
| 856 | ||
| 857 | template <class _RandomAccessIterator, class _OutputIterator> | |
| 858 | _OutputIterator __brick_rotate_copy( | |
| 859 | _RandomAccessIterator, | |
| 860 | _RandomAccessIterator, | |
| 861 | _RandomAccessIterator, | |
| 862 | _OutputIterator, | |
| 863 | /*__is_vector=*/std::true_type) noexcept; | |
| 864 | ||
| 865 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator> | |
| 866 | _OutputIterator __pattern_rotate_copy( | |
| 867 | _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator) noexcept; | |
| 868 | ||
| 869 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator> | |
| 870 | _OutputIterator __pattern_rotate_copy( | |
| 871 | __parallel_tag<_IsVector>, | |
| 872 | _ExecutionPolicy&&, | |
| 873 | _RandomAccessIterator, | |
| 874 | _RandomAccessIterator, | |
| 875 | _RandomAccessIterator, | |
| 876 | _OutputIterator); | |
| 877 | ||
| 878 | //------------------------------------------------------------------------ | |
| 879 | // is_partitioned | |
| 880 | //------------------------------------------------------------------------ | |
| 881 | ||
| 882 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 883 | bool __brick_is_partitioned(_ForwardIterator, | |
| 884 | _ForwardIterator, | |
| 885 | _UnaryPredicate, | |
| 886 | /*is_vector=*/std::false_type) noexcept; | |
| 887 | ||
| 888 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 889 | bool __brick_is_partitioned(_RandomAccessIterator, | |
| 890 | _RandomAccessIterator, | |
| 891 | _UnaryPredicate, | |
| 892 | /*is_vector=*/std::true_type) noexcept; | |
| 893 | ||
| 894 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 895 | bool __pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; | |
| 896 | ||
| 897 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 898 | bool __pattern_is_partitioned( | |
| 899 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate); | |
| 900 | ||
| 901 | //------------------------------------------------------------------------ | |
| 902 | // partition | |
| 903 | //------------------------------------------------------------------------ | |
| 904 | ||
| 905 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 906 | _ForwardIterator __brick_partition( | |
| 907 | _ForwardIterator, | |
| 908 | _ForwardIterator, | |
| 909 | _UnaryPredicate, | |
| 910 | /*is_vector=*/std::false_type) noexcept; | |
| 911 | ||
| 912 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 913 | _RandomAccessIterator __brick_partition( | |
| 914 | _RandomAccessIterator, | |
| 915 | _RandomAccessIterator, | |
| 916 | _UnaryPredicate, | |
| 917 | /*is_vector=*/std::true_type) noexcept; | |
| 918 | ||
| 919 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 920 | _ForwardIterator | |
| 921 | __pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; | |
| 922 | ||
| 923 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 924 | _RandomAccessIterator __pattern_partition( | |
| 925 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate); | |
| 926 | ||
| 927 | //------------------------------------------------------------------------ | |
| 928 | // stable_partition | |
| 929 | //------------------------------------------------------------------------ | |
| 930 | ||
| 931 | template <class _BidirectionalIterator, class _UnaryPredicate> | |
| 932 | _BidirectionalIterator __brick_stable_partition( | |
| 933 | _BidirectionalIterator, | |
| 934 | _BidirectionalIterator, | |
| 935 | _UnaryPredicate, | |
| 936 | /*__is_vector=*/std::false_type) noexcept; | |
| 937 | ||
| 938 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 939 | _RandomAccessIterator __brick_stable_partition( | |
| 940 | _RandomAccessIterator, | |
| 941 | _RandomAccessIterator, | |
| 942 | _UnaryPredicate, | |
| 943 | /*__is_vector=*/std::true_type) noexcept; | |
| 944 | ||
| 945 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> | |
| 946 | _BidirectionalIterator __pattern_stable_partition( | |
| 947 | _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate) noexcept; | |
| 948 | ||
| 949 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 950 | _RandomAccessIterator __pattern_stable_partition( | |
| 951 | __parallel_tag<_IsVector>, | |
| 952 | _ExecutionPolicy&&, | |
| 953 | _RandomAccessIterator, | |
| 954 | _RandomAccessIterator, | |
| 955 | _UnaryPredicate) noexcept; | |
| 956 | ||
| 957 | //------------------------------------------------------------------------ | |
| 958 | // partition_copy | |
| 959 | //------------------------------------------------------------------------ | |
| 960 | ||
| 961 | template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate> | |
| 962 | std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy( | |
| 963 | _ForwardIterator, | |
| 964 | _ForwardIterator, | |
| 965 | _OutputIterator1, | |
| 966 | _OutputIterator2, | |
| 967 | _UnaryPredicate, | |
| 968 | /*is_vector=*/std::false_type) noexcept; | |
| 969 | ||
| 970 | template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate> | |
| 971 | std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy( | |
| 972 | _RandomAccessIterator, | |
| 973 | _RandomAccessIterator, | |
| 974 | _OutputIterator1, | |
| 975 | _OutputIterator2, | |
| 976 | _UnaryPredicate, | |
| 977 | /*is_vector=*/std::true_type) noexcept; | |
| 978 | ||
| 979 | template <class _Tag, | |
| 980 | class _ExecutionPolicy, | |
| 981 | class _ForwardIterator, | |
| 982 | class _OutputIterator1, | |
| 983 | class _OutputIterator2, | |
| 984 | class _UnaryPredicate> | |
| 985 | std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( | |
| 986 | _Tag, | |
| 987 | _ExecutionPolicy&&, | |
| 988 | _ForwardIterator, | |
| 989 | _ForwardIterator, | |
| 990 | _OutputIterator1, | |
| 991 | _OutputIterator2, | |
| 992 | _UnaryPredicate) noexcept; | |
| 993 | ||
| 994 | template <class _IsVector, | |
| 995 | class _ExecutionPolicy, | |
| 996 | class _RandomAccessIterator, | |
| 997 | class _OutputIterator1, | |
| 998 | class _OutputIterator2, | |
| 999 | class _UnaryPredicate> | |
| 1000 | std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( | |
| 1001 | __parallel_tag<_IsVector>, | |
| 1002 | _ExecutionPolicy&&, | |
| 1003 | _RandomAccessIterator, | |
| 1004 | _RandomAccessIterator, | |
| 1005 | _OutputIterator1, | |
| 1006 | _OutputIterator2, | |
| 1007 | _UnaryPredicate); | |
| 1008 | ||
| 1009 | //------------------------------------------------------------------------ | |
| 1010 | // sort | |
| 1011 | //------------------------------------------------------------------------ | |
| 1012 | ||
| 1013 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible> | |
| 1014 | void __pattern_sort( | |
| 1015 | _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsMoveConstructible) noexcept; | |
| 1016 | ||
| 1017 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1018 | void __pattern_sort(__parallel_tag<_IsVector>, | |
| 1019 | _ExecutionPolicy&&, | |
| 1020 | _RandomAccessIterator, | |
| 1021 | _RandomAccessIterator, | |
| 1022 | _Compare, | |
| 1023 | /*is_move_constructible=*/std::true_type); | |
| 1024 | ||
| 1025 | //------------------------------------------------------------------------ | |
| 1026 | // stable_sort | |
| 1027 | //------------------------------------------------------------------------ | |
| 1028 | ||
| 1029 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1030 | void __pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; | |
| 1031 | ||
| 1032 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1033 | void __pattern_stable_sort( | |
| 1034 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); | |
| 1035 | ||
| 1036 | //------------------------------------------------------------------------ | |
| 1037 | // partial_sort | |
| 1038 | //------------------------------------------------------------------------ | |
| 1039 | ||
| 1040 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1041 | void __pattern_partial_sort( | |
| 1042 | _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; | |
| 1043 | ||
| 1044 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1045 | void __pattern_partial_sort( | |
| 1046 | __parallel_tag<_IsVector>, | |
| 1047 | _ExecutionPolicy&&, | |
| 1048 | _RandomAccessIterator, | |
| 1049 | _RandomAccessIterator, | |
| 1050 | _RandomAccessIterator, | |
| 1051 | _Compare); | |
| 1052 | ||
| 1053 | //------------------------------------------------------------------------ | |
| 1054 | // partial_sort_copy | |
| 1055 | //------------------------------------------------------------------------ | |
| 1056 | ||
| 1057 | template <class _Tag, | |
| 1058 | class _ExecutionPolicy, | |
| 1059 | class _RandomAccessIterator1, | |
| 1060 | class _RandomAccessIterator2, | |
| 1061 | class _Compare> | |
| 1062 | _RandomAccessIterator2 __pattern_partial_sort_copy( | |
| 1063 | _Tag, | |
| 1064 | _ExecutionPolicy&&, | |
| 1065 | _RandomAccessIterator1, | |
| 1066 | _RandomAccessIterator1, | |
| 1067 | _RandomAccessIterator2, | |
| 1068 | _RandomAccessIterator2, | |
| 1069 | _Compare) noexcept; | |
| 1070 | ||
| 1071 | template <class _IsVector, | |
| 1072 | class _ExecutionPolicy, | |
| 1073 | class _RandomAccessIterator1, | |
| 1074 | class _RandomAccessIterator2, | |
| 1075 | class _Compare> | |
| 1076 | _RandomAccessIterator2 __pattern_partial_sort_copy( | |
| 1077 | __parallel_tag<_IsVector>, | |
| 1078 | _ExecutionPolicy&&, | |
| 1079 | _RandomAccessIterator1, | |
| 1080 | _RandomAccessIterator1, | |
| 1081 | _RandomAccessIterator2, | |
| 1082 | _RandomAccessIterator2, | |
| 1083 | _Compare); | |
| 1084 | ||
| 1085 | //------------------------------------------------------------------------ | |
| 1086 | // adjacent_find | |
| 1087 | //------------------------------------------------------------------------ | |
| 1088 | ||
| 1089 | template <class _RandomAccessIterator, class _BinaryPredicate> | |
| 1090 | _RandomAccessIterator __brick_adjacent_find( | |
| 1091 | _RandomAccessIterator, | |
| 1092 | _RandomAccessIterator, | |
| 1093 | _BinaryPredicate, | |
| 1094 | /* IsVector = */ std::true_type, | |
| 1095 | bool) noexcept; | |
| 1096 | ||
| 1097 | template <class _ForwardIterator, class _BinaryPredicate> | |
| 1098 | _ForwardIterator __brick_adjacent_find( | |
| 1099 | _ForwardIterator, | |
| 1100 | _ForwardIterator, | |
| 1101 | _BinaryPredicate, | |
| 1102 | /* IsVector = */ std::false_type, | |
| 1103 | bool) noexcept; | |
| 1104 | ||
| 1105 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 1106 | _ForwardIterator | |
| 1107 | __pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, bool) noexcept; | |
| 1108 | ||
| 1109 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate> | |
| 1110 | _RandomAccessIterator __pattern_adjacent_find( | |
| 1111 | __parallel_tag<_IsVector>, | |
| 1112 | _ExecutionPolicy&&, | |
| 1113 | _RandomAccessIterator, | |
| 1114 | _RandomAccessIterator, | |
| 1115 | _BinaryPredicate, | |
| 1116 | bool); | |
| 1117 | ||
| 1118 | //------------------------------------------------------------------------ | |
| 1119 | // nth_element | |
| 1120 | //------------------------------------------------------------------------ | |
| 1121 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1122 | void __pattern_nth_element( | |
| 1123 | _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; | |
| 1124 | ||
| 1125 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1126 | void __pattern_nth_element( | |
| 1127 | __parallel_tag<_IsVector>, | |
| 1128 | _ExecutionPolicy&&, | |
| 1129 | _RandomAccessIterator, | |
| 1130 | _RandomAccessIterator, | |
| 1131 | _RandomAccessIterator, | |
| 1132 | _Compare) noexcept; | |
| 1133 | ||
| 1134 | //------------------------------------------------------------------------ | |
| 1135 | // fill, fill_n | |
| 1136 | //------------------------------------------------------------------------ | |
| 1137 | template <class _RandomAccessIterator, class _Tp> | |
| 1138 | void __brick_fill(_RandomAccessIterator, | |
| 1139 | _RandomAccessIterator, | |
| 1140 | const _Tp&, | |
| 1141 | /* __is_vector = */ std::true_type) noexcept; | |
| 1142 | ||
| 1143 | template <class _ForwardIterator, class _Tp> | |
| 1144 | void __brick_fill(_ForwardIterator, | |
| 1145 | _ForwardIterator, | |
| 1146 | const _Tp&, | |
| 1147 | /* __is_vector = */ std::false_type) noexcept; | |
| 1148 | ||
| 1149 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 1150 | void __pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept; | |
| 1151 | ||
| 1152 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp> | |
| 1153 | _RandomAccessIterator | |
| 1154 | __pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&); | |
| 1155 | ||
| 1156 | template <class _RandomAccessIterator, class _Size, class _Tp> | |
| 1157 | _RandomAccessIterator | |
| 1158 | __brick_fill_n(_RandomAccessIterator, | |
| 1159 | _Size, | |
| 1160 | const _Tp&, | |
| 1161 | /* __is_vector = */ std::true_type) noexcept; | |
| 1162 | ||
| 1163 | template <class _OutputIterator, class _Size, class _Tp> | |
| 1164 | _OutputIterator | |
| 1165 | __brick_fill_n(_OutputIterator, | |
| 1166 | _Size, | |
| 1167 | const _Tp&, | |
| 1168 | /* __is_vector = */ std::false_type) noexcept; | |
| 1169 | ||
| 1170 | template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp> | |
| 1171 | _OutputIterator __pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept; | |
| 1172 | ||
| 1173 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Tp> | |
| 1174 | _RandomAccessIterator | |
| 1175 | __pattern_fill_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&); | |
| 1176 | ||
| 1177 | //------------------------------------------------------------------------ | |
| 1178 | // generate, generate_n | |
| 1179 | //------------------------------------------------------------------------ | |
| 1180 | ||
| 1181 | template <class _RandomAccessIterator, class _Generator> | |
| 1182 | void __brick_generate(_RandomAccessIterator, | |
| 1183 | _RandomAccessIterator, | |
| 1184 | _Generator, | |
| 1185 | /* is_vector = */ std::true_type) noexcept; | |
| 1186 | ||
| 1187 | template <class _ForwardIterator, class _Generator> | |
| 1188 | void __brick_generate(_ForwardIterator, | |
| 1189 | _ForwardIterator, | |
| 1190 | _Generator, | |
| 1191 | /* is_vector = */ std::false_type) noexcept; | |
| 1192 | ||
| 1193 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator> | |
| 1194 | void __pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept; | |
| 1195 | ||
| 1196 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator> | |
| 1197 | _RandomAccessIterator __pattern_generate( | |
| 1198 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Generator); | |
| 1199 | ||
| 1200 | template <class _RandomAccessIterator, class Size, class _Generator> | |
| 1201 | _RandomAccessIterator __brick_generate_n( | |
| 1202 | _RandomAccessIterator, | |
| 1203 | Size, | |
| 1204 | _Generator, | |
| 1205 | /* is_vector = */ std::true_type) noexcept; | |
| 1206 | ||
| 1207 | template <class OutputIterator, class Size, class _Generator> | |
| 1208 | OutputIterator __brick_generate_n( | |
| 1209 | OutputIterator, | |
| 1210 | Size, | |
| 1211 | _Generator, | |
| 1212 | /* is_vector = */ std::false_type) noexcept; | |
| 1213 | ||
| 1214 | template <class _Tag, class _ExecutionPolicy, class OutputIterator, class Size, class _Generator> | |
| 1215 | OutputIterator __pattern_generate_n(_Tag, _ExecutionPolicy&&, OutputIterator, Size, _Generator) noexcept; | |
| 1216 | ||
| 1217 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class Size, class _Generator> | |
| 1218 | _RandomAccessIterator | |
| 1219 | __pattern_generate_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, Size, _Generator); | |
| 1220 | ||
| 1221 | //------------------------------------------------------------------------ | |
| 1222 | // remove | |
| 1223 | //------------------------------------------------------------------------ | |
| 1224 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 1225 | _ForwardIterator __brick_remove_if( | |
| 1226 | _ForwardIterator, | |
| 1227 | _ForwardIterator, | |
| 1228 | _UnaryPredicate, | |
| 1229 | /* __is_vector = */ std::false_type) noexcept; | |
| 1230 | ||
| 1231 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 1232 | _RandomAccessIterator __brick_remove_if( | |
| 1233 | _RandomAccessIterator, | |
| 1234 | _RandomAccessIterator, | |
| 1235 | _UnaryPredicate, | |
| 1236 | /* __is_vector = */ std::true_type) noexcept; | |
| 1237 | ||
| 1238 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 1239 | _ForwardIterator | |
| 1240 | __pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; | |
| 1241 | ||
| 1242 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 1243 | _RandomAccessIterator __pattern_remove_if( | |
| 1244 | __parallel_tag<_IsVector>, | |
| 1245 | _ExecutionPolicy&&, | |
| 1246 | _RandomAccessIterator, | |
| 1247 | _RandomAccessIterator, | |
| 1248 | _UnaryPredicate) noexcept; | |
| 1249 | ||
| 1250 | //------------------------------------------------------------------------ | |
| 1251 | // merge | |
| 1252 | //------------------------------------------------------------------------ | |
| 1253 | ||
| 1254 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 1255 | _OutputIterator __brick_merge( | |
| 1256 | _ForwardIterator1, | |
| 1257 | _ForwardIterator1, | |
| 1258 | _ForwardIterator2, | |
| 1259 | _ForwardIterator2, | |
| 1260 | _OutputIterator, | |
| 1261 | _Compare, | |
| 1262 | /* __is_vector = */ std::false_type) noexcept; | |
| 1263 | ||
| 1264 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 1265 | _OutputIterator __brick_merge( | |
| 1266 | _RandomAccessIterator1, | |
| 1267 | _RandomAccessIterator1, | |
| 1268 | _RandomAccessIterator2, | |
| 1269 | _RandomAccessIterator2, | |
| 1270 | _OutputIterator, | |
| 1271 | _Compare, | |
| 1272 | /* __is_vector = */ std::true_type) noexcept; | |
| 1273 | ||
| 1274 | template <class _Tag, | |
| 1275 | class _ExecutionPolicy, | |
| 1276 | class _ForwardIterator1, | |
| 1277 | class _ForwardIterator2, | |
| 1278 | class _OutputIterator, | |
| 1279 | class _Compare> | |
| 1280 | _OutputIterator __pattern_merge( | |
| 1281 | _Tag, | |
| 1282 | _ExecutionPolicy&&, | |
| 1283 | _ForwardIterator1, | |
| 1284 | _ForwardIterator1, | |
| 1285 | _ForwardIterator2, | |
| 1286 | _ForwardIterator2, | |
| 1287 | _OutputIterator, | |
| 1288 | _Compare) noexcept; | |
| 1289 | ||
| 1290 | template <class _IsVector, | |
| 1291 | class _ExecutionPolicy, | |
| 1292 | class _RandomAccessIterator1, | |
| 1293 | class _RandomAccessIterator2, | |
| 1294 | class _OutputIterator, | |
| 1295 | class _Compare> | |
| 1296 | _OutputIterator __pattern_merge( | |
| 1297 | __parallel_tag<_IsVector>, | |
| 1298 | _ExecutionPolicy&&, | |
| 1299 | _RandomAccessIterator1, | |
| 1300 | _RandomAccessIterator1, | |
| 1301 | _RandomAccessIterator2, | |
| 1302 | _RandomAccessIterator2, | |
| 1303 | _OutputIterator, | |
| 1304 | _Compare); | |
| 1305 | ||
| 1306 | //------------------------------------------------------------------------ | |
| 1307 | // inplace_merge | |
| 1308 | //------------------------------------------------------------------------ | |
| 1309 | ||
| 1310 | template <class _BidirectionalIterator, class _Compare> | |
| 1311 | void __brick_inplace_merge( | |
| 1312 | _BidirectionalIterator, | |
| 1313 | _BidirectionalIterator, | |
| 1314 | _BidirectionalIterator, | |
| 1315 | _Compare, | |
| 1316 | /* __is_vector = */ std::false_type) noexcept; | |
| 1317 | ||
| 1318 | template <class _RandomAccessIterator, class _Compare> | |
| 1319 | void __brick_inplace_merge( | |
| 1320 | _RandomAccessIterator, | |
| 1321 | _RandomAccessIterator, | |
| 1322 | _RandomAccessIterator, | |
| 1323 | _Compare, | |
| 1324 | /* __is_vector = */ std::true_type) noexcept; | |
| 1325 | ||
| 1326 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare> | |
| 1327 | void __pattern_inplace_merge( | |
| 1328 | _Tag, | |
| 1329 | _ExecutionPolicy&&, | |
| 1330 | _BidirectionalIterator, | |
| 1331 | _BidirectionalIterator, | |
| 1332 | _BidirectionalIterator, | |
| 1333 | _Compare) noexcept; | |
| 1334 | ||
| 1335 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1336 | void __pattern_inplace_merge( | |
| 1337 | __parallel_tag<_IsVector>, | |
| 1338 | _ExecutionPolicy&&, | |
| 1339 | _RandomAccessIterator, | |
| 1340 | _RandomAccessIterator, | |
| 1341 | _RandomAccessIterator, | |
| 1342 | _Compare); | |
| 1343 | ||
| 1344 | //------------------------------------------------------------------------ | |
| 1345 | // includes | |
| 1346 | //------------------------------------------------------------------------ | |
| 1347 | ||
| 1348 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 1349 | bool __pattern_includes( | |
| 1350 | _Tag, | |
| 1351 | _ExecutionPolicy&&, | |
| 1352 | _ForwardIterator1, | |
| 1353 | _ForwardIterator1, | |
| 1354 | _ForwardIterator2, | |
| 1355 | _ForwardIterator2, | |
| 1356 | _Compare) noexcept; | |
| 1357 | ||
| 1358 | template <class _IsVector, | |
| 1359 | class _ExecutionPolicy, | |
| 1360 | class _RandomAccessIterator1, | |
| 1361 | class _RandomAccessIterator2, | |
| 1362 | class _Compare> | |
| 1363 | bool __pattern_includes( | |
| 1364 | __parallel_tag<_IsVector>, | |
| 1365 | _ExecutionPolicy&&, | |
| 1366 | _RandomAccessIterator1, | |
| 1367 | _RandomAccessIterator1, | |
| 1368 | _RandomAccessIterator2, | |
| 1369 | _RandomAccessIterator2, | |
| 1370 | _Compare); | |
| 1371 | ||
| 1372 | //------------------------------------------------------------------------ | |
| 1373 | // set_union | |
| 1374 | //------------------------------------------------------------------------ | |
| 1375 | ||
| 1376 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 1377 | _OutputIterator __brick_set_union( | |
| 1378 | _ForwardIterator1, | |
| 1379 | _ForwardIterator1, | |
| 1380 | _ForwardIterator2, | |
| 1381 | _ForwardIterator2, | |
| 1382 | _OutputIterator, | |
| 1383 | _Compare, | |
| 1384 | /*__is_vector=*/std::false_type) noexcept; | |
| 1385 | ||
| 1386 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 1387 | _OutputIterator __brick_set_union( | |
| 1388 | _RandomAccessIterator1, | |
| 1389 | _RandomAccessIterator1, | |
| 1390 | _RandomAccessIterator2, | |
| 1391 | _RandomAccessIterator2, | |
| 1392 | _OutputIterator, | |
| 1393 | _Compare, | |
| 1394 | /*__is_vector=*/std::true_type) noexcept; | |
| 1395 | ||
| 1396 | template <class _Tag, | |
| 1397 | class _ExecutionPolicy, | |
| 1398 | class _ForwardIterator1, | |
| 1399 | class _ForwardIterator2, | |
| 1400 | class _OutputIterator, | |
| 1401 | class _Compare> | |
| 1402 | _OutputIterator __pattern_set_union( | |
| 1403 | _Tag, | |
| 1404 | _ExecutionPolicy&&, | |
| 1405 | _ForwardIterator1, | |
| 1406 | _ForwardIterator1, | |
| 1407 | _ForwardIterator2, | |
| 1408 | _ForwardIterator2, | |
| 1409 | _OutputIterator, | |
| 1410 | _Compare) noexcept; | |
| 1411 | ||
| 1412 | template <class _IsVector, | |
| 1413 | class _ExecutionPolicy, | |
| 1414 | class _RandomAccessIterator1, | |
| 1415 | class _RandomAccessIterator2, | |
| 1416 | class _OutputIterator, | |
| 1417 | class _Compare> | |
| 1418 | _OutputIterator __pattern_set_union( | |
| 1419 | __parallel_tag<_IsVector>, | |
| 1420 | _ExecutionPolicy&&, | |
| 1421 | _RandomAccessIterator1, | |
| 1422 | _RandomAccessIterator1, | |
| 1423 | _RandomAccessIterator2, | |
| 1424 | _RandomAccessIterator2, | |
| 1425 | _OutputIterator, | |
| 1426 | _Compare); | |
| 1427 | ||
| 1428 | //------------------------------------------------------------------------ | |
| 1429 | // set_intersection | |
| 1430 | //------------------------------------------------------------------------ | |
| 1431 | ||
| 1432 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 1433 | _OutputIterator __brick_set_intersection( | |
| 1434 | _ForwardIterator1, | |
| 1435 | _ForwardIterator1, | |
| 1436 | _ForwardIterator2, | |
| 1437 | _ForwardIterator2, | |
| 1438 | _OutputIterator, | |
| 1439 | _Compare, | |
| 1440 | /*__is_vector=*/std::false_type) noexcept; | |
| 1441 | ||
| 1442 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 1443 | _OutputIterator __brick_set_intersection( | |
| 1444 | _RandomAccessIterator1, | |
| 1445 | _RandomAccessIterator1, | |
| 1446 | _RandomAccessIterator2, | |
| 1447 | _RandomAccessIterator2, | |
| 1448 | _OutputIterator, | |
| 1449 | _Compare, | |
| 1450 | /*__is_vector=*/std::true_type) noexcept; | |
| 1451 | ||
| 1452 | template <class _Tag, | |
| 1453 | class _ExecutionPolicy, | |
| 1454 | class _ForwardIterator1, | |
| 1455 | class _ForwardIterator2, | |
| 1456 | class _OutputIterator, | |
| 1457 | class _Compare> | |
| 1458 | _OutputIterator __pattern_set_intersection( | |
| 1459 | _Tag, | |
| 1460 | _ExecutionPolicy&&, | |
| 1461 | _ForwardIterator1, | |
| 1462 | _ForwardIterator1, | |
| 1463 | _ForwardIterator2, | |
| 1464 | _ForwardIterator2, | |
| 1465 | _OutputIterator, | |
| 1466 | _Compare) noexcept; | |
| 1467 | ||
| 1468 | template <class _IsVector, | |
| 1469 | class _ExecutionPolicy, | |
| 1470 | class _RandomAccessIterator1, | |
| 1471 | class _RandomAccessIterator2, | |
| 1472 | class _OutputIterator, | |
| 1473 | class _Compare> | |
| 1474 | _OutputIterator __pattern_set_intersection( | |
| 1475 | __parallel_tag<_IsVector>, | |
| 1476 | _ExecutionPolicy&&, | |
| 1477 | _RandomAccessIterator1, | |
| 1478 | _RandomAccessIterator1, | |
| 1479 | _RandomAccessIterator2, | |
| 1480 | _RandomAccessIterator2, | |
| 1481 | _OutputIterator, | |
| 1482 | _Compare); | |
| 1483 | ||
| 1484 | //------------------------------------------------------------------------ | |
| 1485 | // set_difference | |
| 1486 | //------------------------------------------------------------------------ | |
| 1487 | ||
| 1488 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 1489 | _OutputIterator __brick_set_difference( | |
| 1490 | _ForwardIterator1, | |
| 1491 | _ForwardIterator1, | |
| 1492 | _ForwardIterator2, | |
| 1493 | _ForwardIterator2, | |
| 1494 | _OutputIterator, | |
| 1495 | _Compare, | |
| 1496 | /*__is_vector=*/std::false_type) noexcept; | |
| 1497 | ||
| 1498 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 1499 | _OutputIterator __brick_set_difference( | |
| 1500 | _RandomAccessIterator1, | |
| 1501 | _RandomAccessIterator1, | |
| 1502 | _RandomAccessIterator2, | |
| 1503 | _RandomAccessIterator2, | |
| 1504 | _OutputIterator, | |
| 1505 | _Compare, | |
| 1506 | /*__is_vector=*/std::true_type) noexcept; | |
| 1507 | ||
| 1508 | template <class _Tag, | |
| 1509 | class _ExecutionPolicy, | |
| 1510 | class _ForwardIterator1, | |
| 1511 | class _ForwardIterator2, | |
| 1512 | class _OutputIterator, | |
| 1513 | class _Compare> | |
| 1514 | _OutputIterator __pattern_set_difference( | |
| 1515 | _Tag, | |
| 1516 | _ExecutionPolicy&&, | |
| 1517 | _ForwardIterator1, | |
| 1518 | _ForwardIterator1, | |
| 1519 | _ForwardIterator2, | |
| 1520 | _ForwardIterator2, | |
| 1521 | _OutputIterator, | |
| 1522 | _Compare) noexcept; | |
| 1523 | ||
| 1524 | template <class _IsVector, | |
| 1525 | class _ExecutionPolicy, | |
| 1526 | class _RandomAccessIterator1, | |
| 1527 | class _RandomAccessIterator2, | |
| 1528 | class _OutputIterator, | |
| 1529 | class _Compare> | |
| 1530 | _OutputIterator __pattern_set_difference( | |
| 1531 | __parallel_tag<_IsVector>, | |
| 1532 | _ExecutionPolicy&&, | |
| 1533 | _RandomAccessIterator1, | |
| 1534 | _RandomAccessIterator1, | |
| 1535 | _RandomAccessIterator2, | |
| 1536 | _RandomAccessIterator2, | |
| 1537 | _OutputIterator, | |
| 1538 | _Compare); | |
| 1539 | ||
| 1540 | //------------------------------------------------------------------------ | |
| 1541 | // set_symmetric_difference | |
| 1542 | //------------------------------------------------------------------------ | |
| 1543 | ||
| 1544 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 1545 | _OutputIterator __brick_set_symmetric_difference( | |
| 1546 | _ForwardIterator1, | |
| 1547 | _ForwardIterator1, | |
| 1548 | _ForwardIterator2, | |
| 1549 | _ForwardIterator2, | |
| 1550 | _OutputIterator, | |
| 1551 | _Compare, | |
| 1552 | /*__is_vector=*/std::false_type) noexcept; | |
| 1553 | ||
| 1554 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 1555 | _OutputIterator __brick_set_symmetric_difference( | |
| 1556 | _RandomAccessIterator1, | |
| 1557 | _RandomAccessIterator1, | |
| 1558 | _RandomAccessIterator2, | |
| 1559 | _RandomAccessIterator2, | |
| 1560 | _OutputIterator, | |
| 1561 | _Compare, | |
| 1562 | /*__is_vector=*/std::true_type) noexcept; | |
| 1563 | ||
| 1564 | template <class _Tag, | |
| 1565 | class _ExecutionPolicy, | |
| 1566 | class _ForwardIterator1, | |
| 1567 | class _ForwardIterator2, | |
| 1568 | class _OutputIterator, | |
| 1569 | class _Compare> | |
| 1570 | _OutputIterator __pattern_set_symmetric_difference( | |
| 1571 | _Tag, | |
| 1572 | _ExecutionPolicy&&, | |
| 1573 | _ForwardIterator1, | |
| 1574 | _ForwardIterator1, | |
| 1575 | _ForwardIterator2, | |
| 1576 | _ForwardIterator2, | |
| 1577 | _OutputIterator, | |
| 1578 | _Compare) noexcept; | |
| 1579 | ||
| 1580 | template <class _IsVector, | |
| 1581 | class _ExecutionPolicy, | |
| 1582 | class _RandomAccessIterator1, | |
| 1583 | class _RandomAccessIterator2, | |
| 1584 | class _OutputIterator, | |
| 1585 | class _Compare> | |
| 1586 | _OutputIterator __pattern_set_symmetric_difference( | |
| 1587 | __parallel_tag<_IsVector>, | |
| 1588 | _ExecutionPolicy&&, | |
| 1589 | _RandomAccessIterator1, | |
| 1590 | _RandomAccessIterator1, | |
| 1591 | _RandomAccessIterator2, | |
| 1592 | _RandomAccessIterator2, | |
| 1593 | _OutputIterator, | |
| 1594 | _Compare); | |
| 1595 | ||
| 1596 | //------------------------------------------------------------------------ | |
| 1597 | // is_heap_until | |
| 1598 | //------------------------------------------------------------------------ | |
| 1599 | ||
| 1600 | template <class _RandomAccessIterator, class _Compare> | |
| 1601 | _RandomAccessIterator __brick_is_heap_until( | |
| 1602 | _RandomAccessIterator, | |
| 1603 | _RandomAccessIterator, | |
| 1604 | _Compare, | |
| 1605 | /* __is_vector = */ std::false_type) noexcept; | |
| 1606 | ||
| 1607 | template <class _RandomAccessIterator, class _Compare> | |
| 1608 | _RandomAccessIterator __brick_is_heap_until( | |
| 1609 | _RandomAccessIterator, | |
| 1610 | _RandomAccessIterator, | |
| 1611 | _Compare, | |
| 1612 | /* __is_vector = */ std::true_type) noexcept; | |
| 1613 | ||
| 1614 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1615 | _RandomAccessIterator | |
| 1616 | __pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; | |
| 1617 | ||
| 1618 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 1619 | _RandomAccessIterator __pattern_is_heap_until( | |
| 1620 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; | |
| 1621 | ||
| 1622 | //------------------------------------------------------------------------ | |
| 1623 | // min_element | |
| 1624 | //------------------------------------------------------------------------ | |
| 1625 | ||
| 1626 | template <typename _ForwardIterator, typename _Compare> | |
| 1627 | _ForwardIterator __brick_min_element( | |
| 1628 | _ForwardIterator, | |
| 1629 | _ForwardIterator, | |
| 1630 | _Compare, | |
| 1631 | /* __is_vector = */ std::false_type) noexcept; | |
| 1632 | ||
| 1633 | template <typename _RandomAccessIterator, typename _Compare> | |
| 1634 | _RandomAccessIterator __brick_min_element( | |
| 1635 | _RandomAccessIterator, | |
| 1636 | _RandomAccessIterator, | |
| 1637 | _Compare, | |
| 1638 | /* __is_vector = */ std::true_type) noexcept; | |
| 1639 | ||
| 1640 | template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare> | |
| 1641 | _ForwardIterator __pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; | |
| 1642 | ||
| 1643 | template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare> | |
| 1644 | _RandomAccessIterator __pattern_min_element( | |
| 1645 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); | |
| 1646 | ||
| 1647 | //------------------------------------------------------------------------ | |
| 1648 | // minmax_element | |
| 1649 | //------------------------------------------------------------------------ | |
| 1650 | ||
| 1651 | template <typename _ForwardIterator, typename _Compare> | |
| 1652 | std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element( | |
| 1653 | _ForwardIterator, | |
| 1654 | _ForwardIterator, | |
| 1655 | _Compare, | |
| 1656 | /* __is_vector = */ std::false_type) noexcept; | |
| 1657 | ||
| 1658 | template <typename _RandomAccessIterator, typename _Compare> | |
| 1659 | std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element( | |
| 1660 | _RandomAccessIterator, | |
| 1661 | _RandomAccessIterator, | |
| 1662 | _Compare, | |
| 1663 | /* __is_vector = */ std::true_type) noexcept; | |
| 1664 | ||
| 1665 | template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare> | |
| 1666 | std::pair<_ForwardIterator, _ForwardIterator> | |
| 1667 | __pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; | |
| 1668 | ||
| 1669 | template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare> | |
| 1670 | std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element( | |
| 1671 | __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); | |
| 1672 | ||
| 1673 | //------------------------------------------------------------------------ | |
| 1674 | // mismatch | |
| 1675 | //------------------------------------------------------------------------ | |
| 1676 | ||
| 1677 | template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 1678 | std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch( | |
| 1679 | _ForwardIterator1, | |
| 1680 | _ForwardIterator1, | |
| 1681 | _ForwardIterator2, | |
| 1682 | _ForwardIterator2, | |
| 1683 | _Predicate, | |
| 1684 | /* __is_vector = */ std::false_type) noexcept; | |
| 1685 | ||
| 1686 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate> | |
| 1687 | std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch( | |
| 1688 | _RandomAccessIterator1, | |
| 1689 | _RandomAccessIterator1, | |
| 1690 | _RandomAccessIterator2, | |
| 1691 | _RandomAccessIterator2, | |
| 1692 | _Predicate, | |
| 1693 | /* __is_vector = */ std::true_type) noexcept; | |
| 1694 | ||
| 1695 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 1696 | std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch( | |
| 1697 | _Tag, | |
| 1698 | _ExecutionPolicy&&, | |
| 1699 | _ForwardIterator1, | |
| 1700 | _ForwardIterator1, | |
| 1701 | _ForwardIterator2, | |
| 1702 | _ForwardIterator2, | |
| 1703 | _Predicate) noexcept; | |
| 1704 | ||
| 1705 | template <class _IsVector, | |
| 1706 | class _ExecutionPolicy, | |
| 1707 | class _RandomAccessIterator1, | |
| 1708 | class _RandomAccessIterator2, | |
| 1709 | class _Predicate> | |
| 1710 | std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch( | |
| 1711 | __parallel_tag<_IsVector>, | |
| 1712 | _ExecutionPolicy&&, | |
| 1713 | _RandomAccessIterator1, | |
| 1714 | _RandomAccessIterator1, | |
| 1715 | _RandomAccessIterator2, | |
| 1716 | _RandomAccessIterator2, | |
| 1717 | _Predicate) noexcept; | |
| 1718 | ||
| 1719 | //------------------------------------------------------------------------ | |
| 1720 | // lexicographical_compare | |
| 1721 | //------------------------------------------------------------------------ | |
| 1722 | ||
| 1723 | template <class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 1724 | bool __brick_lexicographical_compare( | |
| 1725 | _ForwardIterator1, | |
| 1726 | _ForwardIterator1, | |
| 1727 | _ForwardIterator2, | |
| 1728 | _ForwardIterator2, | |
| 1729 | _Compare, | |
| 1730 | /* __is_vector = */ std::false_type) noexcept; | |
| 1731 | ||
| 1732 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare> | |
| 1733 | bool __brick_lexicographical_compare( | |
| 1734 | _RandomAccessIterator1, | |
| 1735 | _RandomAccessIterator1, | |
| 1736 | _RandomAccessIterator2, | |
| 1737 | _RandomAccessIterator2, | |
| 1738 | _Compare, | |
| 1739 | /* __is_vector = */ std::true_type) noexcept; | |
| 1740 | ||
| 1741 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 1742 | bool __pattern_lexicographical_compare( | |
| 1743 | _Tag, | |
| 1744 | _ExecutionPolicy&&, | |
| 1745 | _ForwardIterator1, | |
| 1746 | _ForwardIterator1, | |
| 1747 | _ForwardIterator2, | |
| 1748 | _ForwardIterator2, | |
| 1749 | _Compare) noexcept; | |
| 1750 | ||
| 1751 | template <class _IsVector, | |
| 1752 | class _ExecutionPolicy, | |
| 1753 | class _RandomAccessIterator1, | |
| 1754 | class _RandomAccessIterator2, | |
| 1755 | class _Compare> | |
| 1756 | bool __pattern_lexicographical_compare( | |
| 1757 | __parallel_tag<_IsVector>, | |
| 1758 | _ExecutionPolicy&&, | |
| 1759 | _RandomAccessIterator1, | |
| 1760 | _RandomAccessIterator1, | |
| 1761 | _RandomAccessIterator2, | |
| 1762 | _RandomAccessIterator2, | |
| 1763 | _Compare) noexcept; | |
| 1764 | ||
| 1765 | } // namespace __internal | |
| 1766 | } // namespace __pstl | |
| 1767 | ||
| 1768 | #endif /* _PSTL_ALGORITHM_FWD_H */ |
lib/libcxx/include/__pstl/internal/algorithm_impl.h created+4174| ... | ... | @@ -0,0 +1,4174 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_ALGORITHM_IMPL_H | |
| 11 | #define _PSTL_ALGORITHM_IMPL_H | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <algorithm> | |
| 16 | #include <functional> | |
| 17 | #include <iterator> | |
| 18 | #include <type_traits> | |
| 19 | #include <utility> | |
| 20 | ||
| 21 | #include "execution_impl.h" | |
| 22 | #include "memory_impl.h" | |
| 23 | #include "parallel_backend.h" | |
| 24 | #include "parallel_backend_utils.h" | |
| 25 | #include "parallel_impl.h" | |
| 26 | #include "unseq_backend_simd.h" | |
| 27 | ||
| 28 | namespace __pstl { | |
| 29 | namespace __internal { | |
| 30 | ||
| 31 | // [alg.foreach] | |
| 32 | // for_each_n with no policy | |
| 33 | ||
| 34 | template <class _ForwardIterator, class _Size, class _Function> | |
| 35 | _ForwardIterator __for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) { | |
| 36 | for (; __n > 0; ++__first, --__n) | |
| 37 | __f(__first); | |
| 38 | return __first; | |
| 39 | } | |
| 40 | ||
| 41 | //------------------------------------------------------------------------ | |
| 42 | // walk1 (pseudo) | |
| 43 | // | |
| 44 | // walk1 evaluates f(x) for each dereferenced value x drawn from [first,last) | |
| 45 | //------------------------------------------------------------------------ | |
| 46 | template <class _ForwardIterator, class _Function> | |
| 47 | void __brick_walk1( | |
| 48 | _ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept { | |
| 49 | std::for_each(__first, __last, __f); | |
| 50 | } | |
| 51 | ||
| 52 | template <class _RandomAccessIterator, class _Function> | |
| 53 | void __brick_walk1(_RandomAccessIterator __first, | |
| 54 | _RandomAccessIterator __last, | |
| 55 | _Function __f, | |
| 56 | /*vector=*/std::true_type) noexcept { | |
| 57 | __unseq_backend::__simd_walk_1(__first, __last - __first, __f); | |
| 58 | } | |
| 59 | ||
| 60 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Function> | |
| 61 | void __pattern_walk1( | |
| 62 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept { | |
| 63 | __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{}); | |
| 64 | } | |
| 65 | ||
| 66 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Function> | |
| 67 | void __pattern_walk1(__parallel_tag<_IsVector> __tag, | |
| 68 | _ExecutionPolicy&& __exec, | |
| 69 | _RandomAccessIterator __first, | |
| 70 | _RandomAccessIterator __last, | |
| 71 | _Function __f) { | |
| 72 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 73 | ||
| 74 | __internal::__except_handler([&]() { | |
| 75 | __par_backend::__parallel_for( | |
| 76 | __backend_tag{}, | |
| 77 | std::forward<_ExecutionPolicy>(__exec), | |
| 78 | __first, | |
| 79 | __last, | |
| 80 | [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) { | |
| 81 | __internal::__brick_walk1(__i, __j, __f, _IsVector{}); | |
| 82 | }); | |
| 83 | }); | |
| 84 | } | |
| 85 | ||
| 86 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Brick> | |
| 87 | void __pattern_walk_brick( | |
| 88 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick) noexcept { | |
| 89 | __brick(__first, __last); | |
| 90 | } | |
| 91 | ||
| 92 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Brick> | |
| 93 | void __pattern_walk_brick( | |
| 94 | __parallel_tag<_IsVector> __tag, | |
| 95 | _ExecutionPolicy&& __exec, | |
| 96 | _RandomAccessIterator __first, | |
| 97 | _RandomAccessIterator __last, | |
| 98 | _Brick __brick) { | |
| 99 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 100 | ||
| 101 | __internal::__except_handler([&]() { | |
| 102 | __par_backend::__parallel_for( | |
| 103 | __backend_tag{}, | |
| 104 | std::forward<_ExecutionPolicy>(__exec), | |
| 105 | __first, | |
| 106 | __last, | |
| 107 | [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j); }); | |
| 108 | }); | |
| 109 | } | |
| 110 | ||
| 111 | //------------------------------------------------------------------------ | |
| 112 | // walk1_n | |
| 113 | //------------------------------------------------------------------------ | |
| 114 | template <class _ForwardIterator, class _Size, class _Function> | |
| 115 | _ForwardIterator __brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type) { | |
| 116 | return __internal::__for_each_n_it_serial(__first, __n, [&__f](_ForwardIterator __it) { | |
| 117 | __f(*__it); | |
| 118 | }); // calling serial version | |
| 119 | } | |
| 120 | ||
| 121 | template <class _RandomAccessIterator, class _DifferenceType, class _Function> | |
| 122 | _RandomAccessIterator | |
| 123 | __brick_walk1_n(_RandomAccessIterator __first, | |
| 124 | _DifferenceType __n, | |
| 125 | _Function __f, | |
| 126 | /*vectorTag=*/std::true_type) noexcept { | |
| 127 | return __unseq_backend::__simd_walk_1(__first, __n, __f); | |
| 128 | } | |
| 129 | ||
| 130 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function> | |
| 131 | _ForwardIterator | |
| 132 | __pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept { | |
| 133 | return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{}); | |
| 134 | } | |
| 135 | ||
| 136 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function> | |
| 137 | _RandomAccessIterator __pattern_walk1_n( | |
| 138 | __parallel_tag<_IsVector> __tag, | |
| 139 | _ExecutionPolicy&& __exec, | |
| 140 | _RandomAccessIterator __first, | |
| 141 | _Size __n, | |
| 142 | _Function __f) { | |
| 143 | __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f); | |
| 144 | ||
| 145 | return __first + __n; | |
| 146 | } | |
| 147 | ||
| 148 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick> | |
| 149 | _ForwardIterator | |
| 150 | __pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept { | |
| 151 | return __brick(__first, __n); | |
| 152 | } | |
| 153 | ||
| 154 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick> | |
| 155 | _RandomAccessIterator __pattern_walk_brick_n( | |
| 156 | __parallel_tag<_IsVector> __tag, | |
| 157 | _ExecutionPolicy&& __exec, | |
| 158 | _RandomAccessIterator __first, | |
| 159 | _Size __n, | |
| 160 | _Brick __brick) { | |
| 161 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 162 | ||
| 163 | return __internal::__except_handler([&]() { | |
| 164 | __par_backend::__parallel_for( | |
| 165 | __backend_tag{}, | |
| 166 | std::forward<_ExecutionPolicy>(__exec), | |
| 167 | __first, | |
| 168 | __first + __n, | |
| 169 | [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); }); | |
| 170 | return __first + __n; | |
| 171 | }); | |
| 172 | } | |
| 173 | ||
| 174 | //------------------------------------------------------------------------ | |
| 175 | // walk2 (pseudo) | |
| 176 | // | |
| 177 | // walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...) | |
| 178 | //------------------------------------------------------------------------ | |
| 179 | template <class _ForwardIterator1, class _ForwardIterator2, class _Function> | |
| 180 | _ForwardIterator2 | |
| 181 | __brick_walk2(_ForwardIterator1 __first1, | |
| 182 | _ForwardIterator1 __last1, | |
| 183 | _ForwardIterator2 __first2, | |
| 184 | _Function __f, | |
| 185 | /*vector=*/std::false_type) noexcept { | |
| 186 | for (; __first1 != __last1; ++__first1, ++__first2) | |
| 187 | __f(*__first1, *__first2); | |
| 188 | return __first2; | |
| 189 | } | |
| 190 | ||
| 191 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Function> | |
| 192 | _RandomAccessIterator2 | |
| 193 | __brick_walk2(_RandomAccessIterator1 __first1, | |
| 194 | _RandomAccessIterator1 __last1, | |
| 195 | _RandomAccessIterator2 __first2, | |
| 196 | _Function __f, | |
| 197 | /*vector=*/std::true_type) noexcept { | |
| 198 | return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f); | |
| 199 | } | |
| 200 | ||
| 201 | template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function> | |
| 202 | _ForwardIterator2 __brick_walk2_n( | |
| 203 | _ForwardIterator1 __first1, | |
| 204 | _Size __n, | |
| 205 | _ForwardIterator2 __first2, | |
| 206 | _Function __f, | |
| 207 | /*vector=*/std::false_type) noexcept { | |
| 208 | for (; __n > 0; --__n, ++__first1, ++__first2) | |
| 209 | __f(*__first1, *__first2); | |
| 210 | return __first2; | |
| 211 | } | |
| 212 | ||
| 213 | template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Function> | |
| 214 | _RandomAccessIterator2 __brick_walk2_n( | |
| 215 | _RandomAccessIterator1 __first1, | |
| 216 | _Size __n, | |
| 217 | _RandomAccessIterator2 __first2, | |
| 218 | _Function __f, | |
| 219 | /*vector=*/std::true_type) noexcept { | |
| 220 | return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f); | |
| 221 | } | |
| 222 | ||
| 223 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function> | |
| 224 | _ForwardIterator2 __pattern_walk2( | |
| 225 | _Tag, | |
| 226 | _ExecutionPolicy&&, | |
| 227 | _ForwardIterator1 __first1, | |
| 228 | _ForwardIterator1 __last1, | |
| 229 | _ForwardIterator2 __first2, | |
| 230 | _Function __f) noexcept { | |
| 231 | return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{}); | |
| 232 | } | |
| 233 | ||
| 234 | template <class _IsVector, | |
| 235 | class _ExecutionPolicy, | |
| 236 | class _RandomAccessIterator1, | |
| 237 | class _RandomAccessIterator2, | |
| 238 | class _Function> | |
| 239 | _RandomAccessIterator2 __pattern_walk2( | |
| 240 | __parallel_tag<_IsVector> __tag, | |
| 241 | _ExecutionPolicy&& __exec, | |
| 242 | _RandomAccessIterator1 __first1, | |
| 243 | _RandomAccessIterator1 __last1, | |
| 244 | _RandomAccessIterator2 __first2, | |
| 245 | _Function __f) { | |
| 246 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 247 | ||
| 248 | return __internal::__except_handler([&]() { | |
| 249 | __par_backend::__parallel_for( | |
| 250 | __backend_tag{}, | |
| 251 | std::forward<_ExecutionPolicy>(__exec), | |
| 252 | __first1, | |
| 253 | __last1, | |
| 254 | [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 255 | __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{}); | |
| 256 | }); | |
| 257 | return __first2 + (__last1 - __first1); | |
| 258 | }); | |
| 259 | } | |
| 260 | ||
| 261 | template <class _Tag, | |
| 262 | class _ExecutionPolicy, | |
| 263 | class _ForwardIterator1, | |
| 264 | class _Size, | |
| 265 | class _ForwardIterator2, | |
| 266 | class _Function> | |
| 267 | _ForwardIterator2 __pattern_walk2_n( | |
| 268 | _Tag, | |
| 269 | _ExecutionPolicy&&, | |
| 270 | _ForwardIterator1 __first1, | |
| 271 | _Size __n, | |
| 272 | _ForwardIterator2 __first2, | |
| 273 | _Function __f) noexcept { | |
| 274 | return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{}); | |
| 275 | } | |
| 276 | ||
| 277 | template <class _IsVector, | |
| 278 | class _ExecutionPolicy, | |
| 279 | class _RandomAccessIterator1, | |
| 280 | class _Size, | |
| 281 | class _RandomAccessIterator2, | |
| 282 | class _Function> | |
| 283 | _RandomAccessIterator2 __pattern_walk2_n( | |
| 284 | __parallel_tag<_IsVector> __tag, | |
| 285 | _ExecutionPolicy&& __exec, | |
| 286 | _RandomAccessIterator1 __first1, | |
| 287 | _Size __n, | |
| 288 | _RandomAccessIterator2 __first2, | |
| 289 | _Function __f) { | |
| 290 | return __internal::__pattern_walk2( | |
| 291 | __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f); | |
| 292 | } | |
| 293 | ||
| 294 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick> | |
| 295 | _ForwardIterator2 __pattern_walk2_brick( | |
| 296 | _Tag, | |
| 297 | _ExecutionPolicy&&, | |
| 298 | _ForwardIterator1 __first1, | |
| 299 | _ForwardIterator1 __last1, | |
| 300 | _ForwardIterator2 __first2, | |
| 301 | _Brick __brick) noexcept { | |
| 302 | return __brick(__first1, __last1, __first2); | |
| 303 | } | |
| 304 | ||
| 305 | template <class _IsVector, | |
| 306 | class _ExecutionPolicy, | |
| 307 | class _RandomAccessIterator1, | |
| 308 | class _RandomAccessIterator2, | |
| 309 | class _Brick> | |
| 310 | _RandomAccessIterator2 __pattern_walk2_brick( | |
| 311 | __parallel_tag<_IsVector> __tag, | |
| 312 | _ExecutionPolicy&& __exec, | |
| 313 | _RandomAccessIterator1 __first1, | |
| 314 | _RandomAccessIterator1 __last1, | |
| 315 | _RandomAccessIterator2 __first2, | |
| 316 | _Brick __brick) { | |
| 317 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 318 | ||
| 319 | return __internal::__except_handler([&]() { | |
| 320 | __par_backend::__parallel_for( | |
| 321 | __backend_tag{}, | |
| 322 | std::forward<_ExecutionPolicy>(__exec), | |
| 323 | __first1, | |
| 324 | __last1, | |
| 325 | [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 326 | __brick(__i, __j, __first2 + (__i - __first1)); | |
| 327 | }); | |
| 328 | return __first2 + (__last1 - __first1); | |
| 329 | }); | |
| 330 | } | |
| 331 | ||
| 332 | template <class _Tag, | |
| 333 | class _ExecutionPolicy, | |
| 334 | class _ForwardIterator1, | |
| 335 | class _Size, | |
| 336 | class _ForwardIterator2, | |
| 337 | class _Brick> | |
| 338 | _ForwardIterator2 __pattern_walk2_brick_n( | |
| 339 | _Tag, | |
| 340 | _ExecutionPolicy&&, | |
| 341 | _ForwardIterator1 __first1, | |
| 342 | _Size __n, | |
| 343 | _ForwardIterator2 __first2, | |
| 344 | _Brick __brick) noexcept { | |
| 345 | return __brick(__first1, __n, __first2); | |
| 346 | } | |
| 347 | ||
| 348 | template <class _IsVector, | |
| 349 | class _ExecutionPolicy, | |
| 350 | class _RandomAccessIterator1, | |
| 351 | class _Size, | |
| 352 | class _RandomAccessIterator2, | |
| 353 | class _Brick> | |
| 354 | _RandomAccessIterator2 __pattern_walk2_brick_n( | |
| 355 | __parallel_tag<_IsVector> __tag, | |
| 356 | _ExecutionPolicy&& __exec, | |
| 357 | _RandomAccessIterator1 __first1, | |
| 358 | _Size __n, | |
| 359 | _RandomAccessIterator2 __first2, | |
| 360 | _Brick __brick) { | |
| 361 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 362 | ||
| 363 | return __internal::__except_handler([&]() { | |
| 364 | __par_backend::__parallel_for( | |
| 365 | __backend_tag{}, | |
| 366 | std::forward<_ExecutionPolicy>(__exec), | |
| 367 | __first1, | |
| 368 | __first1 + __n, | |
| 369 | [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 370 | __brick(__i, __j - __i, __first2 + (__i - __first1)); | |
| 371 | }); | |
| 372 | return __first2 + __n; | |
| 373 | }); | |
| 374 | } | |
| 375 | ||
| 376 | //------------------------------------------------------------------------ | |
| 377 | // walk3 (pseudo) | |
| 378 | // | |
| 379 | // walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...) | |
| 380 | //------------------------------------------------------------------------ | |
| 381 | template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function> | |
| 382 | _ForwardIterator3 __brick_walk3( | |
| 383 | _ForwardIterator1 __first1, | |
| 384 | _ForwardIterator1 __last1, | |
| 385 | _ForwardIterator2 __first2, | |
| 386 | _ForwardIterator3 __first3, | |
| 387 | _Function __f, | |
| 388 | /*vector=*/std::false_type) noexcept { | |
| 389 | for (; __first1 != __last1; ++__first1, ++__first2, ++__first3) | |
| 390 | __f(*__first1, *__first2, *__first3); | |
| 391 | return __first3; | |
| 392 | } | |
| 393 | ||
| 394 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function> | |
| 395 | _RandomAccessIterator3 __brick_walk3( | |
| 396 | _RandomAccessIterator1 __first1, | |
| 397 | _RandomAccessIterator1 __last1, | |
| 398 | _RandomAccessIterator2 __first2, | |
| 399 | _RandomAccessIterator3 __first3, | |
| 400 | _Function __f, | |
| 401 | /*vector=*/std::true_type) noexcept { | |
| 402 | return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f); | |
| 403 | } | |
| 404 | ||
| 405 | template <class _Tag, | |
| 406 | class _ExecutionPolicy, | |
| 407 | class _ForwardIterator1, | |
| 408 | class _ForwardIterator2, | |
| 409 | class _ForwardIterator3, | |
| 410 | class _Function> | |
| 411 | _ForwardIterator3 __pattern_walk3( | |
| 412 | _Tag, | |
| 413 | _ExecutionPolicy&&, | |
| 414 | _ForwardIterator1 __first1, | |
| 415 | _ForwardIterator1 __last1, | |
| 416 | _ForwardIterator2 __first2, | |
| 417 | _ForwardIterator3 __first3, | |
| 418 | _Function __f) noexcept { | |
| 419 | return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{}); | |
| 420 | } | |
| 421 | ||
| 422 | template <class _IsVector, | |
| 423 | class _ExecutionPolicy, | |
| 424 | class _RandomAccessIterator1, | |
| 425 | class _RandomAccessIterator2, | |
| 426 | class _RandomAccessIterator3, | |
| 427 | class _Function> | |
| 428 | _RandomAccessIterator3 __pattern_walk3( | |
| 429 | __parallel_tag<_IsVector> __tag, | |
| 430 | _ExecutionPolicy&& __exec, | |
| 431 | _RandomAccessIterator1 __first1, | |
| 432 | _RandomAccessIterator1 __last1, | |
| 433 | _RandomAccessIterator2 __first2, | |
| 434 | _RandomAccessIterator3 __first3, | |
| 435 | _Function __f) { | |
| 436 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 437 | ||
| 438 | return __internal::__except_handler([&]() { | |
| 439 | __par_backend::__parallel_for( | |
| 440 | __backend_tag{}, | |
| 441 | std::forward<_ExecutionPolicy>(__exec), | |
| 442 | __first1, | |
| 443 | __last1, | |
| 444 | [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 445 | __internal::__brick_walk3( | |
| 446 | __i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, _IsVector{}); | |
| 447 | }); | |
| 448 | return __first3 + (__last1 - __first1); | |
| 449 | }); | |
| 450 | } | |
| 451 | ||
| 452 | //------------------------------------------------------------------------ | |
| 453 | // equal | |
| 454 | //------------------------------------------------------------------------ | |
| 455 | ||
| 456 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 457 | bool __brick_equal(_ForwardIterator1 __first1, | |
| 458 | _ForwardIterator1 __last1, | |
| 459 | _ForwardIterator2 __first2, | |
| 460 | _ForwardIterator2 __last2, | |
| 461 | _BinaryPredicate __p, | |
| 462 | /* IsVector = */ std::false_type) noexcept { | |
| 463 | return std::equal(__first1, __last1, __first2, __last2, __p); | |
| 464 | } | |
| 465 | ||
| 466 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 467 | bool __brick_equal(_RandomAccessIterator1 __first1, | |
| 468 | _RandomAccessIterator1 __last1, | |
| 469 | _RandomAccessIterator2 __first2, | |
| 470 | _RandomAccessIterator2 __last2, | |
| 471 | _BinaryPredicate __p, | |
| 472 | /* is_vector = */ std::true_type) noexcept { | |
| 473 | if (__last1 - __first1 != __last2 - __first2) | |
| 474 | return false; | |
| 475 | ||
| 476 | return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; | |
| 477 | } | |
| 478 | ||
| 479 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 480 | bool __pattern_equal( | |
| 481 | _Tag, | |
| 482 | _ExecutionPolicy&&, | |
| 483 | _ForwardIterator1 __first1, | |
| 484 | _ForwardIterator1 __last1, | |
| 485 | _ForwardIterator2 __first2, | |
| 486 | _ForwardIterator2 __last2, | |
| 487 | _BinaryPredicate __p) noexcept { | |
| 488 | return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{}); | |
| 489 | } | |
| 490 | ||
| 491 | template <class _IsVector, | |
| 492 | class _ExecutionPolicy, | |
| 493 | class _RandomAccessIterator1, | |
| 494 | class _RandomAccessIterator2, | |
| 495 | class _BinaryPredicate> | |
| 496 | bool __pattern_equal( | |
| 497 | __parallel_tag<_IsVector> __tag, | |
| 498 | _ExecutionPolicy&& __exec, | |
| 499 | _RandomAccessIterator1 __first1, | |
| 500 | _RandomAccessIterator1 __last1, | |
| 501 | _RandomAccessIterator2 __first2, | |
| 502 | _RandomAccessIterator2 __last2, | |
| 503 | _BinaryPredicate __p) { | |
| 504 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 505 | ||
| 506 | if (__last1 - __first1 != __last2 - __first2) | |
| 507 | return false; | |
| 508 | ||
| 509 | return __internal::__except_handler([&]() { | |
| 510 | return !__internal::__parallel_or( | |
| 511 | __backend_tag{}, | |
| 512 | std::forward<_ExecutionPolicy>(__exec), | |
| 513 | __first1, | |
| 514 | __last1, | |
| 515 | [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 516 | return !__internal::__brick_equal( | |
| 517 | __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __p, _IsVector{}); | |
| 518 | }); | |
| 519 | }); | |
| 520 | } | |
| 521 | ||
| 522 | //------------------------------------------------------------------------ | |
| 523 | // equal version for sequences with equal length | |
| 524 | //------------------------------------------------------------------------ | |
| 525 | ||
| 526 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 527 | bool __brick_equal(_ForwardIterator1 __first1, | |
| 528 | _ForwardIterator1 __last1, | |
| 529 | _ForwardIterator2 __first2, | |
| 530 | _BinaryPredicate __p, | |
| 531 | /* IsVector = */ std::false_type) noexcept { | |
| 532 | return std::equal(__first1, __last1, __first2, __p); | |
| 533 | } | |
| 534 | ||
| 535 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 536 | bool __brick_equal(_RandomAccessIterator1 __first1, | |
| 537 | _RandomAccessIterator1 __last1, | |
| 538 | _RandomAccessIterator2 __first2, | |
| 539 | _BinaryPredicate __p, | |
| 540 | /* is_vector = */ std::true_type) noexcept { | |
| 541 | return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; | |
| 542 | } | |
| 543 | ||
| 544 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 545 | bool __pattern_equal( | |
| 546 | _Tag, | |
| 547 | _ExecutionPolicy&&, | |
| 548 | _ForwardIterator1 __first1, | |
| 549 | _ForwardIterator1 __last1, | |
| 550 | _ForwardIterator2 __first2, | |
| 551 | _BinaryPredicate __p) noexcept { | |
| 552 | return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{}); | |
| 553 | } | |
| 554 | ||
| 555 | template <class _IsVector, | |
| 556 | class _ExecutionPolicy, | |
| 557 | class _RandomAccessIterator1, | |
| 558 | class _RandomAccessIterator2, | |
| 559 | class _BinaryPredicate> | |
| 560 | bool __pattern_equal( | |
| 561 | __parallel_tag<_IsVector> __tag, | |
| 562 | _ExecutionPolicy&& __exec, | |
| 563 | _RandomAccessIterator1 __first1, | |
| 564 | _RandomAccessIterator1 __last1, | |
| 565 | _RandomAccessIterator2 __first2, | |
| 566 | _BinaryPredicate __p) { | |
| 567 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 568 | ||
| 569 | return __internal::__except_handler([&]() { | |
| 570 | return !__internal::__parallel_or( | |
| 571 | __backend_tag{}, | |
| 572 | std::forward<_ExecutionPolicy>(__exec), | |
| 573 | __first1, | |
| 574 | __last1, | |
| 575 | [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 576 | return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{}); | |
| 577 | }); | |
| 578 | }); | |
| 579 | } | |
| 580 | ||
| 581 | //------------------------------------------------------------------------ | |
| 582 | // find_end | |
| 583 | //------------------------------------------------------------------------ | |
| 584 | ||
| 585 | // find the first occurrence of the subsequence [s_first, s_last) | |
| 586 | // or the last occurrence of the subsequence in the range [first, last) | |
| 587 | // b_first determines what occurrence we want to find (first or last) | |
| 588 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate, class _IsVector> | |
| 589 | _RandomAccessIterator1 __find_subrange( | |
| 590 | _RandomAccessIterator1 __first, | |
| 591 | _RandomAccessIterator1 __last, | |
| 592 | _RandomAccessIterator1 __global_last, | |
| 593 | _RandomAccessIterator2 __s_first, | |
| 594 | _RandomAccessIterator2 __s_last, | |
| 595 | _BinaryPredicate __pred, | |
| 596 | bool __b_first, | |
| 597 | _IsVector __is_vector) noexcept { | |
| 598 | typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType; | |
| 599 | auto __n2 = __s_last - __s_first; | |
| 600 | if (__n2 < 1) { | |
| 601 | return __b_first ? __first : __last; | |
| 602 | } | |
| 603 | ||
| 604 | auto __n1 = __global_last - __first; | |
| 605 | if (__n1 < __n2) { | |
| 606 | return __last; | |
| 607 | } | |
| 608 | ||
| 609 | auto __cur = __last; | |
| 610 | while (__first != __last && (__global_last - __first >= __n2)) { | |
| 611 | // find position of *s_first in [first, last) (it can be start of subsequence) | |
| 612 | __first = __internal::__brick_find_if( | |
| 613 | __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector); | |
| 614 | ||
| 615 | // if position that was found previously is the start of subsequence | |
| 616 | // then we can exit the loop (b_first == true) or keep the position | |
| 617 | // (b_first == false) | |
| 618 | if (__first != __last && (__global_last - __first >= __n2) && | |
| 619 | __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector)) { | |
| 620 | if (__b_first) { | |
| 621 | return __first; | |
| 622 | } else { | |
| 623 | __cur = __first; | |
| 624 | } | |
| 625 | } else if (__first == __last) { | |
| 626 | break; | |
| 627 | } else { | |
| 628 | } | |
| 629 | ||
| 630 | // in case of b_first == false we try to find new start position | |
| 631 | // for the next subsequence | |
| 632 | ++__first; | |
| 633 | } | |
| 634 | return __cur; | |
| 635 | } | |
| 636 | ||
| 637 | template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate, class _IsVector> | |
| 638 | _RandomAccessIterator __find_subrange( | |
| 639 | _RandomAccessIterator __first, | |
| 640 | _RandomAccessIterator __last, | |
| 641 | _RandomAccessIterator __global_last, | |
| 642 | _Size __count, | |
| 643 | const _Tp& __value, | |
| 644 | _BinaryPredicate __pred, | |
| 645 | _IsVector __is_vector) noexcept { | |
| 646 | if (static_cast<_Size>(__global_last - __first) < __count || __count < 1) { | |
| 647 | return __last; // According to the standard last shall be returned when count < 1 | |
| 648 | } | |
| 649 | ||
| 650 | auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred); | |
| 651 | while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count)) { | |
| 652 | __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector); | |
| 653 | ||
| 654 | // check that all of elements in [first+1, first+count) equal to value | |
| 655 | if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) && | |
| 656 | !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector)) { | |
| 657 | return __first; | |
| 658 | } else if (__first == __last) { | |
| 659 | break; | |
| 660 | } else { | |
| 661 | ++__first; | |
| 662 | } | |
| 663 | } | |
| 664 | return __last; | |
| 665 | } | |
| 666 | ||
| 667 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 668 | _ForwardIterator1 __brick_find_end( | |
| 669 | _ForwardIterator1 __first, | |
| 670 | _ForwardIterator1 __last, | |
| 671 | _ForwardIterator2 __s_first, | |
| 672 | _ForwardIterator2 __s_last, | |
| 673 | _BinaryPredicate __pred, | |
| 674 | /*__is_vector=*/std::false_type) noexcept { | |
| 675 | return std::find_end(__first, __last, __s_first, __s_last, __pred); | |
| 676 | } | |
| 677 | ||
| 678 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 679 | _RandomAccessIterator1 __brick_find_end( | |
| 680 | _RandomAccessIterator1 __first, | |
| 681 | _RandomAccessIterator1 __last, | |
| 682 | _RandomAccessIterator2 __s_first, | |
| 683 | _RandomAccessIterator2 __s_last, | |
| 684 | _BinaryPredicate __pred, | |
| 685 | /*__is_vector=*/std::true_type) noexcept { | |
| 686 | return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type()); | |
| 687 | } | |
| 688 | ||
| 689 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 690 | _ForwardIterator1 __pattern_find_end( | |
| 691 | _Tag, | |
| 692 | _ExecutionPolicy&&, | |
| 693 | _ForwardIterator1 __first, | |
| 694 | _ForwardIterator1 __last, | |
| 695 | _ForwardIterator2 __s_first, | |
| 696 | _ForwardIterator2 __s_last, | |
| 697 | _BinaryPredicate __pred) noexcept { | |
| 698 | return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); | |
| 699 | } | |
| 700 | ||
| 701 | template <class _IsVector, | |
| 702 | class _ExecutionPolicy, | |
| 703 | class _RandomAccessIterator1, | |
| 704 | class _RandomAccessIterator2, | |
| 705 | class _BinaryPredicate> | |
| 706 | _RandomAccessIterator1 __pattern_find_end( | |
| 707 | __parallel_tag<_IsVector> __tag, | |
| 708 | _ExecutionPolicy&& __exec, | |
| 709 | _RandomAccessIterator1 __first, | |
| 710 | _RandomAccessIterator1 __last, | |
| 711 | _RandomAccessIterator2 __s_first, | |
| 712 | _RandomAccessIterator2 __s_last, | |
| 713 | _BinaryPredicate __pred) noexcept { | |
| 714 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 715 | ||
| 716 | if (__last - __first == __s_last - __s_first) { | |
| 717 | const bool __res = | |
| 718 | __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred); | |
| 719 | return __res ? __first : __last; | |
| 720 | } else { | |
| 721 | return __internal::__except_handler([&]() { | |
| 722 | return __internal::__parallel_find( | |
| 723 | __backend_tag{}, | |
| 724 | std::forward<_ExecutionPolicy>(__exec), | |
| 725 | __first, | |
| 726 | __last, | |
| 727 | [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 728 | return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, _IsVector{}); | |
| 729 | }, | |
| 730 | std::greater<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), | |
| 731 | /*is_first=*/false); | |
| 732 | }); | |
| 733 | } | |
| 734 | } | |
| 735 | ||
| 736 | //------------------------------------------------------------------------ | |
| 737 | // find_first_of | |
| 738 | //------------------------------------------------------------------------ | |
| 739 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 740 | _ForwardIterator1 __brick_find_first_of( | |
| 741 | _ForwardIterator1 __first, | |
| 742 | _ForwardIterator1 __last, | |
| 743 | _ForwardIterator2 __s_first, | |
| 744 | _ForwardIterator2 __s_last, | |
| 745 | _BinaryPredicate __pred, | |
| 746 | /*__is_vector=*/std::false_type) noexcept { | |
| 747 | return std::find_first_of(__first, __last, __s_first, __s_last, __pred); | |
| 748 | } | |
| 749 | ||
| 750 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 751 | _RandomAccessIterator1 __brick_find_first_of( | |
| 752 | _RandomAccessIterator1 __first, | |
| 753 | _RandomAccessIterator1 __last, | |
| 754 | _RandomAccessIterator2 __s_first, | |
| 755 | _RandomAccessIterator2 __s_last, | |
| 756 | _BinaryPredicate __pred, | |
| 757 | /*__is_vector=*/std::true_type) noexcept { | |
| 758 | return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred); | |
| 759 | } | |
| 760 | ||
| 761 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 762 | _ForwardIterator1 __pattern_find_first_of( | |
| 763 | _Tag, | |
| 764 | _ExecutionPolicy&&, | |
| 765 | _ForwardIterator1 __first, | |
| 766 | _ForwardIterator1 __last, | |
| 767 | _ForwardIterator2 __s_first, | |
| 768 | _ForwardIterator2 __s_last, | |
| 769 | _BinaryPredicate __pred) noexcept { | |
| 770 | return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); | |
| 771 | } | |
| 772 | ||
| 773 | template <class _IsVector, | |
| 774 | class _ExecutionPolicy, | |
| 775 | class _RandomAccessIterator1, | |
| 776 | class _RandomAccessIterator2, | |
| 777 | class _BinaryPredicate> | |
| 778 | _RandomAccessIterator1 __pattern_find_first_of( | |
| 779 | __parallel_tag<_IsVector> __tag, | |
| 780 | _ExecutionPolicy&& __exec, | |
| 781 | _RandomAccessIterator1 __first, | |
| 782 | _RandomAccessIterator1 __last, | |
| 783 | _RandomAccessIterator2 __s_first, | |
| 784 | _RandomAccessIterator2 __s_last, | |
| 785 | _BinaryPredicate __pred) noexcept { | |
| 786 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 787 | ||
| 788 | return __internal::__except_handler([&]() { | |
| 789 | return __internal::__parallel_find( | |
| 790 | __backend_tag{}, | |
| 791 | std::forward<_ExecutionPolicy>(__exec), | |
| 792 | __first, | |
| 793 | __last, | |
| 794 | [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 795 | return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{}); | |
| 796 | }, | |
| 797 | std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), | |
| 798 | /*is_first=*/true); | |
| 799 | }); | |
| 800 | } | |
| 801 | ||
| 802 | //------------------------------------------------------------------------ | |
| 803 | // search | |
| 804 | //------------------------------------------------------------------------ | |
| 805 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 806 | _RandomAccessIterator1 __brick_search( | |
| 807 | _RandomAccessIterator1 __first, | |
| 808 | _RandomAccessIterator1 __last, | |
| 809 | _RandomAccessIterator2 __s_first, | |
| 810 | _RandomAccessIterator2 __s_last, | |
| 811 | _BinaryPredicate __pred, | |
| 812 | /*vector=*/std::false_type) noexcept { | |
| 813 | return std::search(__first, __last, __s_first, __s_last, __pred); | |
| 814 | } | |
| 815 | ||
| 816 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 817 | _RandomAccessIterator1 __brick_search( | |
| 818 | _RandomAccessIterator1 __first, | |
| 819 | _RandomAccessIterator1 __last, | |
| 820 | _RandomAccessIterator2 __s_first, | |
| 821 | _RandomAccessIterator2 __s_last, | |
| 822 | _BinaryPredicate __pred, | |
| 823 | /*vector=*/std::true_type) noexcept { | |
| 824 | return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type()); | |
| 825 | } | |
| 826 | ||
| 827 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 828 | _ForwardIterator1 __pattern_search( | |
| 829 | _Tag, | |
| 830 | _ExecutionPolicy&&, | |
| 831 | _ForwardIterator1 __first, | |
| 832 | _ForwardIterator1 __last, | |
| 833 | _ForwardIterator2 __s_first, | |
| 834 | _ForwardIterator2 __s_last, | |
| 835 | _BinaryPredicate __pred) noexcept { | |
| 836 | return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); | |
| 837 | } | |
| 838 | ||
| 839 | template <class _IsVector, | |
| 840 | class _ExecutionPolicy, | |
| 841 | class _RandomAccessIterator1, | |
| 842 | class _RandomAccessIterator2, | |
| 843 | class _BinaryPredicate> | |
| 844 | _RandomAccessIterator1 __pattern_search( | |
| 845 | __parallel_tag<_IsVector> __tag, | |
| 846 | _ExecutionPolicy&& __exec, | |
| 847 | _RandomAccessIterator1 __first, | |
| 848 | _RandomAccessIterator1 __last, | |
| 849 | _RandomAccessIterator2 __s_first, | |
| 850 | _RandomAccessIterator2 __s_last, | |
| 851 | _BinaryPredicate __pred) noexcept { | |
| 852 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 853 | ||
| 854 | if (__last - __first == __s_last - __s_first) { | |
| 855 | const bool __res = | |
| 856 | __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred); | |
| 857 | return __res ? __first : __last; | |
| 858 | } else { | |
| 859 | return __internal::__except_handler([&]() { | |
| 860 | return __internal::__parallel_find( | |
| 861 | __backend_tag{}, | |
| 862 | std::forward<_ExecutionPolicy>(__exec), | |
| 863 | __first, | |
| 864 | __last, | |
| 865 | [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 866 | return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, _IsVector{}); | |
| 867 | }, | |
| 868 | std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), | |
| 869 | /*is_first=*/true); | |
| 870 | }); | |
| 871 | } | |
| 872 | } | |
| 873 | ||
| 874 | //------------------------------------------------------------------------ | |
| 875 | // search_n | |
| 876 | //------------------------------------------------------------------------ | |
| 877 | template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 878 | _ForwardIterator __brick_search_n( | |
| 879 | _ForwardIterator __first, | |
| 880 | _ForwardIterator __last, | |
| 881 | _Size __count, | |
| 882 | const _Tp& __value, | |
| 883 | _BinaryPredicate __pred, | |
| 884 | /*vector=*/std::false_type) noexcept { | |
| 885 | return std::search_n(__first, __last, __count, __value, __pred); | |
| 886 | } | |
| 887 | ||
| 888 | template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 889 | _RandomAccessIterator __brick_search_n( | |
| 890 | _RandomAccessIterator __first, | |
| 891 | _RandomAccessIterator __last, | |
| 892 | _Size __count, | |
| 893 | const _Tp& __value, | |
| 894 | _BinaryPredicate __pred, | |
| 895 | /*vector=*/std::true_type) noexcept { | |
| 896 | return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type()); | |
| 897 | } | |
| 898 | ||
| 899 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 900 | _ForwardIterator __pattern_search_n( | |
| 901 | _Tag, | |
| 902 | _ExecutionPolicy&&, | |
| 903 | _ForwardIterator __first, | |
| 904 | _ForwardIterator __last, | |
| 905 | _Size __count, | |
| 906 | const _Tp& __value, | |
| 907 | _BinaryPredicate __pred) noexcept { | |
| 908 | return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{}); | |
| 909 | } | |
| 910 | ||
| 911 | template <class _IsVector, | |
| 912 | class _ExecutionPolicy, | |
| 913 | class _RandomAccessIterator, | |
| 914 | class _Size, | |
| 915 | class _Tp, | |
| 916 | class _BinaryPredicate> | |
| 917 | _RandomAccessIterator __pattern_search_n( | |
| 918 | __parallel_tag<_IsVector> __tag, | |
| 919 | _ExecutionPolicy&& __exec, | |
| 920 | _RandomAccessIterator __first, | |
| 921 | _RandomAccessIterator __last, | |
| 922 | _Size __count, | |
| 923 | const _Tp& __value, | |
| 924 | _BinaryPredicate __pred) noexcept { | |
| 925 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 926 | ||
| 927 | if (static_cast<_Size>(__last - __first) == __count) { | |
| 928 | const bool __result = !__internal::__pattern_any_of( | |
| 929 | __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value, &__pred](const _Tp& __val) { | |
| 930 | return !__pred(__val, __value); | |
| 931 | }); | |
| 932 | return __result ? __first : __last; | |
| 933 | } else { | |
| 934 | return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred]() { | |
| 935 | return __internal::__parallel_find( | |
| 936 | __backend_tag{}, | |
| 937 | std::forward<_ExecutionPolicy>(__exec), | |
| 938 | __first, | |
| 939 | __last, | |
| 940 | [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { | |
| 941 | return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{}); | |
| 942 | }, | |
| 943 | std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(), | |
| 944 | /*is_first=*/true); | |
| 945 | }); | |
| 946 | } | |
| 947 | } | |
| 948 | ||
| 949 | //------------------------------------------------------------------------ | |
| 950 | // copy_n | |
| 951 | //------------------------------------------------------------------------ | |
| 952 | ||
| 953 | template <class _ForwardIterator, class _Size, class _OutputIterator> | |
| 954 | _OutputIterator | |
| 955 | __brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept { | |
| 956 | return std::copy_n(__first, __n, __result); | |
| 957 | } | |
| 958 | ||
| 959 | template <class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2> | |
| 960 | _RandomAccessIterator2 | |
| 961 | __brick_copy_n(_RandomAccessIterator1 __first, | |
| 962 | _Size __n, | |
| 963 | _RandomAccessIterator2 __result, | |
| 964 | /*vector=*/std::true_type) noexcept { | |
| 965 | return __unseq_backend::__simd_assign( | |
| 966 | __first, __n, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { | |
| 967 | *__result = *__first; | |
| 968 | }); | |
| 969 | } | |
| 970 | ||
| 971 | //------------------------------------------------------------------------ | |
| 972 | // copy | |
| 973 | //------------------------------------------------------------------------ | |
| 974 | template <class _ForwardIterator, class _OutputIterator> | |
| 975 | _OutputIterator | |
| 976 | __brick_copy(_ForwardIterator __first, | |
| 977 | _ForwardIterator __last, | |
| 978 | _OutputIterator __result, | |
| 979 | /*vector=*/std::false_type) noexcept { | |
| 980 | return std::copy(__first, __last, __result); | |
| 981 | } | |
| 982 | ||
| 983 | template <class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 984 | _RandomAccessIterator2 | |
| 985 | __brick_copy(_RandomAccessIterator1 __first, | |
| 986 | _RandomAccessIterator1 __last, | |
| 987 | _RandomAccessIterator2 __result, | |
| 988 | /*vector=*/std::true_type) noexcept { | |
| 989 | return __unseq_backend::__simd_assign( | |
| 990 | __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { | |
| 991 | *__result = *__first; | |
| 992 | }); | |
| 993 | } | |
| 994 | ||
| 995 | //------------------------------------------------------------------------ | |
| 996 | // move | |
| 997 | //------------------------------------------------------------------------ | |
| 998 | template <class _ForwardIterator, class _OutputIterator> | |
| 999 | _OutputIterator | |
| 1000 | __brick_move(_ForwardIterator __first, | |
| 1001 | _ForwardIterator __last, | |
| 1002 | _OutputIterator __result, | |
| 1003 | /*vector=*/std::false_type) noexcept { | |
| 1004 | return std::move(__first, __last, __result); | |
| 1005 | } | |
| 1006 | ||
| 1007 | template <class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1008 | _RandomAccessIterator2 | |
| 1009 | __brick_move(_RandomAccessIterator1 __first, | |
| 1010 | _RandomAccessIterator1 __last, | |
| 1011 | _RandomAccessIterator2 __result, | |
| 1012 | /*vector=*/std::true_type) noexcept { | |
| 1013 | return __unseq_backend::__simd_assign( | |
| 1014 | __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { | |
| 1015 | *__result = std::move(*__first); | |
| 1016 | }); | |
| 1017 | } | |
| 1018 | ||
| 1019 | struct __brick_move_destroy { | |
| 1020 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2> | |
| 1021 | _RandomAccessIterator2 | |
| 1022 | operator()(_RandomAccessIterator1 __first, | |
| 1023 | _RandomAccessIterator1 __last, | |
| 1024 | _RandomAccessIterator2 __result, | |
| 1025 | /*vec*/ std::true_type) const { | |
| 1026 | using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; | |
| 1027 | ||
| 1028 | return __unseq_backend::__simd_assign( | |
| 1029 | __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { | |
| 1030 | *__result = std::move(*__first); | |
| 1031 | (*__first).~_IteratorValueType(); | |
| 1032 | }); | |
| 1033 | } | |
| 1034 | ||
| 1035 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2> | |
| 1036 | _RandomAccessIterator2 | |
| 1037 | operator()(_RandomAccessIterator1 __first, | |
| 1038 | _RandomAccessIterator1 __last, | |
| 1039 | _RandomAccessIterator2 __result, | |
| 1040 | /*vec*/ std::false_type) const { | |
| 1041 | using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; | |
| 1042 | ||
| 1043 | for (; __first != __last; ++__first, ++__result) { | |
| 1044 | *__result = std::move(*__first); | |
| 1045 | (*__first).~_IteratorValueType(); | |
| 1046 | } | |
| 1047 | return __result; | |
| 1048 | } | |
| 1049 | }; | |
| 1050 | ||
| 1051 | //------------------------------------------------------------------------ | |
| 1052 | // swap_ranges | |
| 1053 | //------------------------------------------------------------------------ | |
| 1054 | template <class _ForwardIterator, class _OutputIterator> | |
| 1055 | _OutputIterator __brick_swap_ranges( | |
| 1056 | _ForwardIterator __first, | |
| 1057 | _ForwardIterator __last, | |
| 1058 | _OutputIterator __result, | |
| 1059 | /*vector=*/std::false_type) noexcept { | |
| 1060 | return std::swap_ranges(__first, __last, __result); | |
| 1061 | } | |
| 1062 | ||
| 1063 | template <class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1064 | _RandomAccessIterator2 __brick_swap_ranges( | |
| 1065 | _RandomAccessIterator1 __first, | |
| 1066 | _RandomAccessIterator1 __last, | |
| 1067 | _RandomAccessIterator2 __result, | |
| 1068 | /*vector=*/std::true_type) noexcept { | |
| 1069 | using std::iter_swap; | |
| 1070 | return __unseq_backend::__simd_assign( | |
| 1071 | __first, __last - __first, __result, iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>); | |
| 1072 | } | |
| 1073 | ||
| 1074 | //------------------------------------------------------------------------ | |
| 1075 | // copy_if | |
| 1076 | //------------------------------------------------------------------------ | |
| 1077 | template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate> | |
| 1078 | _OutputIterator __brick_copy_if( | |
| 1079 | _ForwardIterator __first, | |
| 1080 | _ForwardIterator __last, | |
| 1081 | _OutputIterator __result, | |
| 1082 | _UnaryPredicate __pred, | |
| 1083 | /*vector=*/std::false_type) noexcept { | |
| 1084 | return std::copy_if(__first, __last, __result, __pred); | |
| 1085 | } | |
| 1086 | ||
| 1087 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _UnaryPredicate> | |
| 1088 | _RandomAccessIterator2 __brick_copy_if( | |
| 1089 | _RandomAccessIterator1 __first, | |
| 1090 | _RandomAccessIterator1 __last, | |
| 1091 | _RandomAccessIterator2 __result, | |
| 1092 | _UnaryPredicate __pred, | |
| 1093 | /*vector=*/std::true_type) noexcept { | |
| 1094 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 1095 | return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred); | |
| 1096 | #else | |
| 1097 | return std::copy_if(__first, __last, __result, __pred); | |
| 1098 | #endif | |
| 1099 | } | |
| 1100 | ||
| 1101 | // TODO: Try to use transform_reduce for combining __brick_copy_if_phase1 on IsVector. | |
| 1102 | template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate> | |
| 1103 | std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( | |
| 1104 | _ForwardIterator __first, | |
| 1105 | _ForwardIterator __last, | |
| 1106 | bool* __restrict __mask, | |
| 1107 | _UnaryPredicate __pred, | |
| 1108 | /*vector=*/std::false_type) noexcept { | |
| 1109 | auto __count_true = _DifferenceType(0); | |
| 1110 | auto __size = __last - __first; | |
| 1111 | ||
| 1112 | static_assert(__are_random_access_iterators<_ForwardIterator>::value, | |
| 1113 | "Pattern-brick error. Should be a random access iterator."); | |
| 1114 | ||
| 1115 | for (; __first != __last; ++__first, ++__mask) { | |
| 1116 | *__mask = __pred(*__first); | |
| 1117 | if (*__mask) { | |
| 1118 | ++__count_true; | |
| 1119 | } | |
| 1120 | } | |
| 1121 | return std::make_pair(__count_true, __size - __count_true); | |
| 1122 | } | |
| 1123 | ||
| 1124 | template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate> | |
| 1125 | std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( | |
| 1126 | _RandomAccessIterator __first, | |
| 1127 | _RandomAccessIterator __last, | |
| 1128 | bool* __mask, | |
| 1129 | _UnaryPredicate __pred, | |
| 1130 | /*vector=*/std::true_type) noexcept { | |
| 1131 | auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred); | |
| 1132 | return std::make_pair(__result, (__last - __first) - __result); | |
| 1133 | } | |
| 1134 | ||
| 1135 | template <class _ForwardIterator, class _OutputIterator, class _Assigner> | |
| 1136 | void __brick_copy_by_mask( | |
| 1137 | _ForwardIterator __first, | |
| 1138 | _ForwardIterator __last, | |
| 1139 | _OutputIterator __result, | |
| 1140 | bool* __mask, | |
| 1141 | _Assigner __assigner, | |
| 1142 | /*vector=*/std::false_type) noexcept { | |
| 1143 | for (; __first != __last; ++__first, ++__mask) { | |
| 1144 | if (*__mask) { | |
| 1145 | __assigner(__first, __result); | |
| 1146 | ++__result; | |
| 1147 | } | |
| 1148 | } | |
| 1149 | } | |
| 1150 | ||
| 1151 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Assigner> | |
| 1152 | void __brick_copy_by_mask( | |
| 1153 | _RandomAccessIterator1 __first, | |
| 1154 | _RandomAccessIterator1 __last, | |
| 1155 | _RandomAccessIterator2 __result, | |
| 1156 | bool* __restrict __mask, | |
| 1157 | _Assigner __assigner, | |
| 1158 | /*vector=*/std::true_type) noexcept { | |
| 1159 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 1160 | __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner); | |
| 1161 | #else | |
| 1162 | __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type()); | |
| 1163 | #endif | |
| 1164 | } | |
| 1165 | ||
| 1166 | template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2> | |
| 1167 | void __brick_partition_by_mask( | |
| 1168 | _ForwardIterator __first, | |
| 1169 | _ForwardIterator __last, | |
| 1170 | _OutputIterator1 __out_true, | |
| 1171 | _OutputIterator2 __out_false, | |
| 1172 | bool* __mask, | |
| 1173 | /*vector=*/std::false_type) noexcept { | |
| 1174 | for (; __first != __last; ++__first, ++__mask) { | |
| 1175 | if (*__mask) { | |
| 1176 | *__out_true = *__first; | |
| 1177 | ++__out_true; | |
| 1178 | } else { | |
| 1179 | *__out_false = *__first; | |
| 1180 | ++__out_false; | |
| 1181 | } | |
| 1182 | } | |
| 1183 | } | |
| 1184 | ||
| 1185 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3> | |
| 1186 | void __brick_partition_by_mask( | |
| 1187 | _RandomAccessIterator1 __first, | |
| 1188 | _RandomAccessIterator1 __last, | |
| 1189 | _RandomAccessIterator2 __out_true, | |
| 1190 | _RandomAccessIterator3 __out_false, | |
| 1191 | bool* __mask, | |
| 1192 | /*vector=*/std::true_type) noexcept { | |
| 1193 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 1194 | __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask); | |
| 1195 | #else | |
| 1196 | __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type()); | |
| 1197 | #endif | |
| 1198 | } | |
| 1199 | ||
| 1200 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate> | |
| 1201 | _OutputIterator __pattern_copy_if( | |
| 1202 | _Tag, | |
| 1203 | _ExecutionPolicy&&, | |
| 1204 | _ForwardIterator __first, | |
| 1205 | _ForwardIterator __last, | |
| 1206 | _OutputIterator __result, | |
| 1207 | _UnaryPredicate __pred) noexcept { | |
| 1208 | return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{}); | |
| 1209 | } | |
| 1210 | ||
| 1211 | template <class _IsVector, | |
| 1212 | class _ExecutionPolicy, | |
| 1213 | class _RandomAccessIterator1, | |
| 1214 | class _RandomAccessIterator2, | |
| 1215 | class _UnaryPredicate> | |
| 1216 | _RandomAccessIterator2 __pattern_copy_if( | |
| 1217 | __parallel_tag<_IsVector> __tag, | |
| 1218 | _ExecutionPolicy&& __exec, | |
| 1219 | _RandomAccessIterator1 __first, | |
| 1220 | _RandomAccessIterator1 __last, | |
| 1221 | _RandomAccessIterator2 __result, | |
| 1222 | _UnaryPredicate __pred) { | |
| 1223 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1224 | ||
| 1225 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; | |
| 1226 | const _DifferenceType __n = __last - __first; | |
| 1227 | if (_DifferenceType(1) < __n) { | |
| 1228 | __par_backend::__buffer<bool> __mask_buf(__n); | |
| 1229 | return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { | |
| 1230 | bool* __mask = __mask_buf.get(); | |
| 1231 | _DifferenceType __m{}; | |
| 1232 | __par_backend::__parallel_strict_scan( | |
| 1233 | __backend_tag{}, | |
| 1234 | std::forward<_ExecutionPolicy>(__exec), | |
| 1235 | __n, | |
| 1236 | _DifferenceType(0), | |
| 1237 | [=](_DifferenceType __i, _DifferenceType __len) { // Reduce | |
| 1238 | return __internal::__brick_calc_mask_1<_DifferenceType>( | |
| 1239 | __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) | |
| 1240 | .first; | |
| 1241 | }, | |
| 1242 | std::plus<_DifferenceType>(), // Combine | |
| 1243 | [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan | |
| 1244 | __internal::__brick_copy_by_mask( | |
| 1245 | __first + __i, | |
| 1246 | __first + (__i + __len), | |
| 1247 | __result + __initial, | |
| 1248 | __mask + __i, | |
| 1249 | [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, | |
| 1250 | _IsVector{}); | |
| 1251 | }, | |
| 1252 | [&__m](_DifferenceType __total) { __m = __total; }); | |
| 1253 | return __result + __m; | |
| 1254 | }); | |
| 1255 | } | |
| 1256 | // trivial sequence - use serial algorithm | |
| 1257 | return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{}); | |
| 1258 | } | |
| 1259 | ||
| 1260 | //------------------------------------------------------------------------ | |
| 1261 | // count | |
| 1262 | //------------------------------------------------------------------------ | |
| 1263 | template <class _RandomAccessIterator, class _Predicate> | |
| 1264 | typename std::iterator_traits<_RandomAccessIterator>::difference_type | |
| 1265 | __brick_count(_RandomAccessIterator __first, | |
| 1266 | _RandomAccessIterator __last, | |
| 1267 | _Predicate __pred, | |
| 1268 | /* is_vector = */ std::true_type) noexcept { | |
| 1269 | return __unseq_backend::__simd_count(__first, __last - __first, __pred); | |
| 1270 | } | |
| 1271 | ||
| 1272 | template <class _ForwardIterator, class _Predicate> | |
| 1273 | typename std::iterator_traits<_ForwardIterator>::difference_type | |
| 1274 | __brick_count(_ForwardIterator __first, | |
| 1275 | _ForwardIterator __last, | |
| 1276 | _Predicate __pred, | |
| 1277 | /* is_vector = */ std::false_type) noexcept { | |
| 1278 | return std::count_if(__first, __last, __pred); | |
| 1279 | } | |
| 1280 | ||
| 1281 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 1282 | typename std::iterator_traits<_ForwardIterator>::difference_type __pattern_count( | |
| 1283 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept { | |
| 1284 | return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 1285 | } | |
| 1286 | ||
| 1287 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Predicate> | |
| 1288 | typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count( | |
| 1289 | __parallel_tag<_IsVector> __tag, | |
| 1290 | _ExecutionPolicy&& __exec, | |
| 1291 | _RandomAccessIterator __first, | |
| 1292 | _RandomAccessIterator __last, | |
| 1293 | _Predicate __pred) { | |
| 1294 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1295 | ||
| 1296 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; | |
| 1297 | return __internal::__except_handler([&]() { | |
| 1298 | return __par_backend::__parallel_reduce( | |
| 1299 | __backend_tag{}, | |
| 1300 | std::forward<_ExecutionPolicy>(__exec), | |
| 1301 | __first, | |
| 1302 | __last, | |
| 1303 | _SizeType(0), | |
| 1304 | [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType { | |
| 1305 | return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{}); | |
| 1306 | }, | |
| 1307 | std::plus<_SizeType>()); | |
| 1308 | }); | |
| 1309 | } | |
| 1310 | ||
| 1311 | //------------------------------------------------------------------------ | |
| 1312 | // unique | |
| 1313 | //------------------------------------------------------------------------ | |
| 1314 | ||
| 1315 | template <class _RandomAccessIterator, class _BinaryPredicate> | |
| 1316 | _RandomAccessIterator | |
| 1317 | __brick_unique(_RandomAccessIterator __first, | |
| 1318 | _RandomAccessIterator __last, | |
| 1319 | _BinaryPredicate __pred, | |
| 1320 | /*is_vector=*/std::false_type) noexcept { | |
| 1321 | return std::unique(__first, __last, __pred); | |
| 1322 | } | |
| 1323 | ||
| 1324 | template <class _RandomAccessIterator, class _BinaryPredicate> | |
| 1325 | _RandomAccessIterator | |
| 1326 | __brick_unique(_RandomAccessIterator __first, | |
| 1327 | _RandomAccessIterator __last, | |
| 1328 | _BinaryPredicate __pred, | |
| 1329 | /*is_vector=*/std::true_type) noexcept { | |
| 1330 | // TODO: vectorize | |
| 1331 | return std::unique(__first, __last, __pred); | |
| 1332 | } | |
| 1333 | ||
| 1334 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 1335 | _ForwardIterator __pattern_unique( | |
| 1336 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) noexcept { | |
| 1337 | return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 1338 | } | |
| 1339 | ||
| 1340 | // That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a | |
| 1341 | // mask calculation is different. So, a caller passes _CalcMask brick into remove_elements. | |
| 1342 | template <class _IsVector, class _ExecutionPolicy, class _ForwardIterator, class _CalcMask> | |
| 1343 | _ForwardIterator __remove_elements( | |
| 1344 | __parallel_tag<_IsVector> __tag, | |
| 1345 | _ExecutionPolicy&& __exec, | |
| 1346 | _ForwardIterator __first, | |
| 1347 | _ForwardIterator __last, | |
| 1348 | _CalcMask __calc_mask) { | |
| 1349 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1350 | ||
| 1351 | typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType; | |
| 1352 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp; | |
| 1353 | _DifferenceType __n = __last - __first; | |
| 1354 | __par_backend::__buffer<bool> __mask_buf(__n); | |
| 1355 | // 1. find a first iterator that should be removed | |
| 1356 | return __internal::__except_handler([&]() { | |
| 1357 | bool* __mask = __mask_buf.get(); | |
| 1358 | _DifferenceType __min = __par_backend::__parallel_reduce( | |
| 1359 | __backend_tag{}, | |
| 1360 | std::forward<_ExecutionPolicy>(__exec), | |
| 1361 | _DifferenceType(0), | |
| 1362 | __n, | |
| 1363 | __n, | |
| 1364 | [__first, __mask, &__calc_mask]( | |
| 1365 | _DifferenceType __i, _DifferenceType __j, _DifferenceType __local_min) -> _DifferenceType { | |
| 1366 | // Create mask | |
| 1367 | __calc_mask(__mask + __i, __mask + __j, __first + __i); | |
| 1368 | ||
| 1369 | // if minimum was found in a previous range we shouldn't do anymore | |
| 1370 | if (__local_min < __i) { | |
| 1371 | return __local_min; | |
| 1372 | } | |
| 1373 | // find first iterator that should be removed | |
| 1374 | bool* __result = __internal::__brick_find_if( | |
| 1375 | __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{}); | |
| 1376 | if (__result - __mask == __j) { | |
| 1377 | return __local_min; | |
| 1378 | } | |
| 1379 | return std::min(__local_min, _DifferenceType(__result - __mask)); | |
| 1380 | }, | |
| 1381 | [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType { | |
| 1382 | return std::min(__local_min1, __local_min2); | |
| 1383 | }); | |
| 1384 | ||
| 1385 | // No elements to remove - exit | |
| 1386 | if (__min == __n) { | |
| 1387 | return __last; | |
| 1388 | } | |
| 1389 | __n -= __min; | |
| 1390 | __first += __min; | |
| 1391 | ||
| 1392 | __par_backend::__buffer<_Tp> __buf(__n); | |
| 1393 | _Tp* __result = __buf.get(); | |
| 1394 | __mask += __min; | |
| 1395 | _DifferenceType __m{}; | |
| 1396 | // 2. Elements that doesn't satisfy pred are moved to result | |
| 1397 | __par_backend::__parallel_strict_scan( | |
| 1398 | __backend_tag{}, | |
| 1399 | std::forward<_ExecutionPolicy>(__exec), | |
| 1400 | __n, | |
| 1401 | _DifferenceType(0), | |
| 1402 | [__mask](_DifferenceType __i, _DifferenceType __len) { | |
| 1403 | return __internal::__brick_count( | |
| 1404 | __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{}); | |
| 1405 | }, | |
| 1406 | std::plus<_DifferenceType>(), | |
| 1407 | [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { | |
| 1408 | __internal::__brick_copy_by_mask( | |
| 1409 | __first + __i, | |
| 1410 | __first + __i + __len, | |
| 1411 | __result + __initial, | |
| 1412 | __mask + __i, | |
| 1413 | [](_ForwardIterator __x, _Tp* __z) { | |
| 1414 | __internal::__invoke_if_else( | |
| 1415 | std::is_trivial<_Tp>(), | |
| 1416 | [&]() { *__z = std::move(*__x); }, | |
| 1417 | [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); | |
| 1418 | }, | |
| 1419 | _IsVector{}); | |
| 1420 | }, | |
| 1421 | [&__m](_DifferenceType __total) { __m = __total; }); | |
| 1422 | ||
| 1423 | // 3. Elements from result are moved to [first, last) | |
| 1424 | __par_backend::__parallel_for( | |
| 1425 | __backend_tag{}, | |
| 1426 | std::forward<_ExecutionPolicy>(__exec), | |
| 1427 | __result, | |
| 1428 | __result + __m, | |
| 1429 | [__result, __first](_Tp* __i, _Tp* __j) { | |
| 1430 | __invoke_if_else( | |
| 1431 | std::is_trivial<_Tp>(), | |
| 1432 | [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); }, | |
| 1433 | [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); }); | |
| 1434 | }); | |
| 1435 | return __first + __m; | |
| 1436 | }); | |
| 1437 | } | |
| 1438 | ||
| 1439 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate> | |
| 1440 | _RandomAccessIterator __pattern_unique( | |
| 1441 | __parallel_tag<_IsVector> __tag, | |
| 1442 | _ExecutionPolicy&& __exec, | |
| 1443 | _RandomAccessIterator __first, | |
| 1444 | _RandomAccessIterator __last, | |
| 1445 | _BinaryPredicate __pred) noexcept { | |
| 1446 | typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; | |
| 1447 | ||
| 1448 | if (__first == __last) { | |
| 1449 | return __last; | |
| 1450 | } | |
| 1451 | if (__first + 1 == __last || __first + 2 == __last) { | |
| 1452 | // Trivial sequence - use serial algorithm | |
| 1453 | return __internal::__brick_unique(__first, __last, __pred, _IsVector{}); | |
| 1454 | } | |
| 1455 | return __internal::__remove_elements( | |
| 1456 | __tag, | |
| 1457 | std::forward<_ExecutionPolicy>(__exec), | |
| 1458 | ++__first, | |
| 1459 | __last, | |
| 1460 | [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { | |
| 1461 | __internal::__brick_walk3( | |
| 1462 | __b, | |
| 1463 | __e, | |
| 1464 | __it - 1, | |
| 1465 | __it, | |
| 1466 | [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, | |
| 1467 | _IsVector{}); | |
| 1468 | }); | |
| 1469 | } | |
| 1470 | ||
| 1471 | //------------------------------------------------------------------------ | |
| 1472 | // unique_copy | |
| 1473 | //------------------------------------------------------------------------ | |
| 1474 | ||
| 1475 | template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate> | |
| 1476 | OutputIterator __brick_unique_copy( | |
| 1477 | _ForwardIterator __first, | |
| 1478 | _ForwardIterator __last, | |
| 1479 | OutputIterator __result, | |
| 1480 | _BinaryPredicate __pred, | |
| 1481 | /*vector=*/std::false_type) noexcept { | |
| 1482 | return std::unique_copy(__first, __last, __result, __pred); | |
| 1483 | } | |
| 1484 | ||
| 1485 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> | |
| 1486 | _RandomAccessIterator2 __brick_unique_copy( | |
| 1487 | _RandomAccessIterator1 __first, | |
| 1488 | _RandomAccessIterator1 __last, | |
| 1489 | _RandomAccessIterator2 __result, | |
| 1490 | _BinaryPredicate __pred, | |
| 1491 | /*vector=*/std::true_type) noexcept { | |
| 1492 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 1493 | return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred); | |
| 1494 | #else | |
| 1495 | return std::unique_copy(__first, __last, __result, __pred); | |
| 1496 | #endif | |
| 1497 | } | |
| 1498 | ||
| 1499 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate> | |
| 1500 | _OutputIterator __pattern_unique_copy( | |
| 1501 | _Tag, | |
| 1502 | _ExecutionPolicy&&, | |
| 1503 | _ForwardIterator __first, | |
| 1504 | _ForwardIterator __last, | |
| 1505 | _OutputIterator __result, | |
| 1506 | _BinaryPredicate __pred) noexcept { | |
| 1507 | return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{}); | |
| 1508 | } | |
| 1509 | ||
| 1510 | template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate> | |
| 1511 | _DifferenceType __brick_calc_mask_2( | |
| 1512 | _RandomAccessIterator __first, | |
| 1513 | _RandomAccessIterator __last, | |
| 1514 | bool* __restrict __mask, | |
| 1515 | _BinaryPredicate __pred, | |
| 1516 | /*vector=*/std::false_type) noexcept { | |
| 1517 | _DifferenceType __count = 0; | |
| 1518 | for (; __first != __last; ++__first, ++__mask) { | |
| 1519 | *__mask = !__pred(*__first, *(__first - 1)); | |
| 1520 | __count += *__mask; | |
| 1521 | } | |
| 1522 | return __count; | |
| 1523 | } | |
| 1524 | ||
| 1525 | template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate> | |
| 1526 | _DifferenceType __brick_calc_mask_2( | |
| 1527 | _RandomAccessIterator __first, | |
| 1528 | _RandomAccessIterator __last, | |
| 1529 | bool* __restrict __mask, | |
| 1530 | _BinaryPredicate __pred, | |
| 1531 | /*vector=*/std::true_type) noexcept { | |
| 1532 | return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred); | |
| 1533 | } | |
| 1534 | ||
| 1535 | template <class _IsVector, | |
| 1536 | class _ExecutionPolicy, | |
| 1537 | class _RandomAccessIterator1, | |
| 1538 | class _RandomAccessIterator2, | |
| 1539 | class _BinaryPredicate> | |
| 1540 | _RandomAccessIterator2 __pattern_unique_copy( | |
| 1541 | __parallel_tag<_IsVector> __tag, | |
| 1542 | _ExecutionPolicy&& __exec, | |
| 1543 | _RandomAccessIterator1 __first, | |
| 1544 | _RandomAccessIterator1 __last, | |
| 1545 | _RandomAccessIterator2 __result, | |
| 1546 | _BinaryPredicate __pred) { | |
| 1547 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1548 | ||
| 1549 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; | |
| 1550 | const _DifferenceType __n = __last - __first; | |
| 1551 | if (_DifferenceType(2) < __n) { | |
| 1552 | __par_backend::__buffer<bool> __mask_buf(__n); | |
| 1553 | if (_DifferenceType(2) < __n) { | |
| 1554 | return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { | |
| 1555 | bool* __mask = __mask_buf.get(); | |
| 1556 | _DifferenceType __m{}; | |
| 1557 | __par_backend::__parallel_strict_scan( | |
| 1558 | __backend_tag{}, | |
| 1559 | std::forward<_ExecutionPolicy>(__exec), | |
| 1560 | __n, | |
| 1561 | _DifferenceType(0), | |
| 1562 | [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce | |
| 1563 | _DifferenceType __extra = 0; | |
| 1564 | if (__i == 0) { | |
| 1565 | // Special boundary case | |
| 1566 | __mask[__i] = true; | |
| 1567 | if (--__len == 0) | |
| 1568 | return 1; | |
| 1569 | ++__i; | |
| 1570 | ++__extra; | |
| 1571 | } | |
| 1572 | return __internal::__brick_calc_mask_2<_DifferenceType>( | |
| 1573 | __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) + | |
| 1574 | __extra; | |
| 1575 | }, | |
| 1576 | std::plus<_DifferenceType>(), // Combine | |
| 1577 | [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan | |
| 1578 | // Phase 2 is same as for __pattern_copy_if | |
| 1579 | __internal::__brick_copy_by_mask( | |
| 1580 | __first + __i, | |
| 1581 | __first + (__i + __len), | |
| 1582 | __result + __initial, | |
| 1583 | __mask + __i, | |
| 1584 | [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, | |
| 1585 | _IsVector{}); | |
| 1586 | }, | |
| 1587 | [&__m](_DifferenceType __total) { __m = __total; }); | |
| 1588 | return __result + __m; | |
| 1589 | }); | |
| 1590 | } | |
| 1591 | } | |
| 1592 | // trivial sequence - use serial algorithm | |
| 1593 | return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{}); | |
| 1594 | } | |
| 1595 | ||
| 1596 | //------------------------------------------------------------------------ | |
| 1597 | // reverse | |
| 1598 | //------------------------------------------------------------------------ | |
| 1599 | template <class _BidirectionalIterator> | |
| 1600 | void __brick_reverse( | |
| 1601 | _BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept { | |
| 1602 | std::reverse(__first, __last); | |
| 1603 | } | |
| 1604 | ||
| 1605 | template <class _RandomAccessIterator> | |
| 1606 | void __brick_reverse( | |
| 1607 | _RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept { | |
| 1608 | typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; | |
| 1609 | ||
| 1610 | const auto __n = (__last - __first) / 2; | |
| 1611 | __unseq_backend::__simd_walk_2( | |
| 1612 | __first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), [](_ReferenceType __x, _ReferenceType __y) { | |
| 1613 | using std::swap; | |
| 1614 | swap(__x, __y); | |
| 1615 | }); | |
| 1616 | } | |
| 1617 | ||
| 1618 | // this brick is called in parallel version, so we can use iterator arithmetic | |
| 1619 | template <class _BidirectionalIterator> | |
| 1620 | void __brick_reverse(_BidirectionalIterator __first, | |
| 1621 | _BidirectionalIterator __last, | |
| 1622 | _BidirectionalIterator __d_last, | |
| 1623 | /*is_vector=*/std::false_type) noexcept { | |
| 1624 | for (--__d_last; __first != __last; ++__first, --__d_last) { | |
| 1625 | using std::iter_swap; | |
| 1626 | iter_swap(__first, __d_last); | |
| 1627 | } | |
| 1628 | } | |
| 1629 | ||
| 1630 | // this brick is called in parallel version, so we can use iterator arithmetic | |
| 1631 | template <class _RandomAccessIterator> | |
| 1632 | void __brick_reverse(_RandomAccessIterator __first, | |
| 1633 | _RandomAccessIterator __last, | |
| 1634 | _RandomAccessIterator __d_last, | |
| 1635 | /*is_vector=*/std::true_type) noexcept { | |
| 1636 | typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; | |
| 1637 | ||
| 1638 | __unseq_backend::__simd_walk_2( | |
| 1639 | __first, | |
| 1640 | __last - __first, | |
| 1641 | std::reverse_iterator<_RandomAccessIterator>(__d_last), | |
| 1642 | [](_ReferenceType __x, _ReferenceType __y) { | |
| 1643 | using std::swap; | |
| 1644 | swap(__x, __y); | |
| 1645 | }); | |
| 1646 | } | |
| 1647 | ||
| 1648 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator> | |
| 1649 | void __pattern_reverse( | |
| 1650 | _Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept { | |
| 1651 | __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{}); | |
| 1652 | } | |
| 1653 | ||
| 1654 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator> | |
| 1655 | void __pattern_reverse(__parallel_tag<_IsVector> __tag, | |
| 1656 | _ExecutionPolicy&& __exec, | |
| 1657 | _RandomAccessIterator __first, | |
| 1658 | _RandomAccessIterator __last) { | |
| 1659 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1660 | ||
| 1661 | __par_backend::__parallel_for( | |
| 1662 | __backend_tag{}, | |
| 1663 | std::forward<_ExecutionPolicy>(__exec), | |
| 1664 | __first, | |
| 1665 | __first + (__last - __first) / 2, | |
| 1666 | [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) { | |
| 1667 | __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{}); | |
| 1668 | }); | |
| 1669 | } | |
| 1670 | ||
| 1671 | //------------------------------------------------------------------------ | |
| 1672 | // reverse_copy | |
| 1673 | //------------------------------------------------------------------------ | |
| 1674 | ||
| 1675 | template <class _BidirectionalIterator, class _OutputIterator> | |
| 1676 | _OutputIterator __brick_reverse_copy( | |
| 1677 | _BidirectionalIterator __first, | |
| 1678 | _BidirectionalIterator __last, | |
| 1679 | _OutputIterator __d_first, | |
| 1680 | /*is_vector=*/std::false_type) noexcept { | |
| 1681 | return std::reverse_copy(__first, __last, __d_first); | |
| 1682 | } | |
| 1683 | ||
| 1684 | template <class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1685 | _RandomAccessIterator2 __brick_reverse_copy( | |
| 1686 | _RandomAccessIterator1 __first, | |
| 1687 | _RandomAccessIterator1 __last, | |
| 1688 | _RandomAccessIterator2 __d_first, | |
| 1689 | /*is_vector=*/std::true_type) noexcept { | |
| 1690 | typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; | |
| 1691 | typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; | |
| 1692 | ||
| 1693 | return __unseq_backend::__simd_walk_2( | |
| 1694 | std::reverse_iterator<_RandomAccessIterator1>(__last), | |
| 1695 | __last - __first, | |
| 1696 | __d_first, | |
| 1697 | [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; }); | |
| 1698 | } | |
| 1699 | ||
| 1700 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator> | |
| 1701 | _OutputIterator __pattern_reverse_copy( | |
| 1702 | _Tag, | |
| 1703 | _ExecutionPolicy&&, | |
| 1704 | _BidirectionalIterator __first, | |
| 1705 | _BidirectionalIterator __last, | |
| 1706 | _OutputIterator __d_first) noexcept { | |
| 1707 | return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{}); | |
| 1708 | } | |
| 1709 | ||
| 1710 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1711 | _RandomAccessIterator2 __pattern_reverse_copy( | |
| 1712 | __parallel_tag<_IsVector> __tag, | |
| 1713 | _ExecutionPolicy&& __exec, | |
| 1714 | _RandomAccessIterator1 __first, | |
| 1715 | _RandomAccessIterator1 __last, | |
| 1716 | _RandomAccessIterator2 __d_first) { | |
| 1717 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1718 | ||
| 1719 | auto __len = __last - __first; | |
| 1720 | __par_backend::__parallel_for( | |
| 1721 | __backend_tag{}, | |
| 1722 | std::forward<_ExecutionPolicy>(__exec), | |
| 1723 | __first, | |
| 1724 | __last, | |
| 1725 | [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) { | |
| 1726 | __internal::__brick_reverse_copy( | |
| 1727 | __inner_first, __inner_last, __d_first + (__len - (__inner_last - __first)), _IsVector{}); | |
| 1728 | }); | |
| 1729 | return __d_first + __len; | |
| 1730 | } | |
| 1731 | ||
| 1732 | //------------------------------------------------------------------------ | |
| 1733 | // rotate | |
| 1734 | //------------------------------------------------------------------------ | |
| 1735 | template <class _ForwardIterator> | |
| 1736 | _ForwardIterator | |
| 1737 | __brick_rotate(_ForwardIterator __first, | |
| 1738 | _ForwardIterator __middle, | |
| 1739 | _ForwardIterator __last, | |
| 1740 | /*is_vector=*/std::false_type) noexcept { | |
| 1741 | #if defined(_PSTL_CPP11_STD_ROTATE_BROKEN) | |
| 1742 | std::rotate(__first, __middle, __last); | |
| 1743 | return std::next(__first, std::distance(__middle, __last)); | |
| 1744 | #else | |
| 1745 | return std::rotate(__first, __middle, __last); | |
| 1746 | #endif | |
| 1747 | } | |
| 1748 | ||
| 1749 | template <class _RandomAccessIterator> | |
| 1750 | _RandomAccessIterator | |
| 1751 | __brick_rotate(_RandomAccessIterator __first, | |
| 1752 | _RandomAccessIterator __middle, | |
| 1753 | _RandomAccessIterator __last, | |
| 1754 | /*is_vector=*/std::true_type) noexcept { | |
| 1755 | auto __n = __last - __first; | |
| 1756 | auto __m = __middle - __first; | |
| 1757 | const _RandomAccessIterator __ret = __first + (__last - __middle); | |
| 1758 | ||
| 1759 | bool __is_left = (__m <= __n / 2); | |
| 1760 | if (!__is_left) | |
| 1761 | __m = __n - __m; | |
| 1762 | ||
| 1763 | while (__n > 1 && __m > 0) { | |
| 1764 | using std::iter_swap; | |
| 1765 | const auto __m_2 = __m * 2; | |
| 1766 | if (__is_left) { | |
| 1767 | for (; __last - __first >= __m_2; __first += __m) { | |
| 1768 | __unseq_backend::__simd_assign( | |
| 1769 | __first, __m, __first + __m, iter_swap<_RandomAccessIterator, _RandomAccessIterator>); | |
| 1770 | } | |
| 1771 | } else { | |
| 1772 | for (; __last - __first >= __m_2; __last -= __m) { | |
| 1773 | __unseq_backend::__simd_assign( | |
| 1774 | __last - __m, __m, __last - __m_2, iter_swap<_RandomAccessIterator, _RandomAccessIterator>); | |
| 1775 | } | |
| 1776 | } | |
| 1777 | __is_left = !__is_left; | |
| 1778 | __m = __n % __m; | |
| 1779 | __n = __last - __first; | |
| 1780 | } | |
| 1781 | ||
| 1782 | return __ret; | |
| 1783 | } | |
| 1784 | ||
| 1785 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator> | |
| 1786 | _ForwardIterator __pattern_rotate( | |
| 1787 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) noexcept { | |
| 1788 | return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{}); | |
| 1789 | } | |
| 1790 | ||
| 1791 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator> | |
| 1792 | _RandomAccessIterator __pattern_rotate( | |
| 1793 | __parallel_tag<_IsVector> __tag, | |
| 1794 | _ExecutionPolicy&& __exec, | |
| 1795 | _RandomAccessIterator __first, | |
| 1796 | _RandomAccessIterator __middle, | |
| 1797 | _RandomAccessIterator __last) { | |
| 1798 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1799 | ||
| 1800 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; | |
| 1801 | auto __n = __last - __first; | |
| 1802 | auto __m = __middle - __first; | |
| 1803 | if (__m <= __n / 2) { | |
| 1804 | __par_backend::__buffer<_Tp> __buf(__n - __m); | |
| 1805 | return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { | |
| 1806 | _Tp* __result = __buf.get(); | |
| 1807 | __par_backend::__parallel_for( | |
| 1808 | __backend_tag{}, | |
| 1809 | std::forward<_ExecutionPolicy>(__exec), | |
| 1810 | __middle, | |
| 1811 | __last, | |
| 1812 | [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { | |
| 1813 | __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{}); | |
| 1814 | }); | |
| 1815 | ||
| 1816 | __par_backend::__parallel_for( | |
| 1817 | __backend_tag{}, | |
| 1818 | std::forward<_ExecutionPolicy>(__exec), | |
| 1819 | __first, | |
| 1820 | __middle, | |
| 1821 | [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { | |
| 1822 | __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{}); | |
| 1823 | }); | |
| 1824 | ||
| 1825 | __par_backend::__parallel_for( | |
| 1826 | __backend_tag{}, | |
| 1827 | std::forward<_ExecutionPolicy>(__exec), | |
| 1828 | __result, | |
| 1829 | __result + (__n - __m), | |
| 1830 | [__first, __result](_Tp* __b, _Tp* __e) { | |
| 1831 | __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{}); | |
| 1832 | }); | |
| 1833 | ||
| 1834 | return __first + (__last - __middle); | |
| 1835 | }); | |
| 1836 | } else { | |
| 1837 | __par_backend::__buffer<_Tp> __buf(__m); | |
| 1838 | return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { | |
| 1839 | _Tp* __result = __buf.get(); | |
| 1840 | __par_backend::__parallel_for( | |
| 1841 | __backend_tag{}, | |
| 1842 | std::forward<_ExecutionPolicy>(__exec), | |
| 1843 | __first, | |
| 1844 | __middle, | |
| 1845 | [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { | |
| 1846 | __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{}); | |
| 1847 | }); | |
| 1848 | ||
| 1849 | __par_backend::__parallel_for( | |
| 1850 | __backend_tag{}, | |
| 1851 | std::forward<_ExecutionPolicy>(__exec), | |
| 1852 | __middle, | |
| 1853 | __last, | |
| 1854 | [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { | |
| 1855 | __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{}); | |
| 1856 | }); | |
| 1857 | ||
| 1858 | __par_backend::__parallel_for( | |
| 1859 | __backend_tag{}, | |
| 1860 | std::forward<_ExecutionPolicy>(__exec), | |
| 1861 | __result, | |
| 1862 | __result + __m, | |
| 1863 | [__n, __m, __first, __result](_Tp* __b, _Tp* __e) { | |
| 1864 | __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{}); | |
| 1865 | }); | |
| 1866 | ||
| 1867 | return __first + (__last - __middle); | |
| 1868 | }); | |
| 1869 | } | |
| 1870 | } | |
| 1871 | ||
| 1872 | //------------------------------------------------------------------------ | |
| 1873 | // rotate_copy | |
| 1874 | //------------------------------------------------------------------------ | |
| 1875 | ||
| 1876 | template <class _ForwardIterator, class _OutputIterator> | |
| 1877 | _OutputIterator __brick_rotate_copy( | |
| 1878 | _ForwardIterator __first, | |
| 1879 | _ForwardIterator __middle, | |
| 1880 | _ForwardIterator __last, | |
| 1881 | _OutputIterator __result, | |
| 1882 | /*__is_vector=*/std::false_type) noexcept { | |
| 1883 | return std::rotate_copy(__first, __middle, __last, __result); | |
| 1884 | } | |
| 1885 | ||
| 1886 | template <class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1887 | _RandomAccessIterator2 __brick_rotate_copy( | |
| 1888 | _RandomAccessIterator1 __first, | |
| 1889 | _RandomAccessIterator1 __middle, | |
| 1890 | _RandomAccessIterator1 __last, | |
| 1891 | _RandomAccessIterator2 __result, | |
| 1892 | /*__is_vector=*/std::true_type) noexcept { | |
| 1893 | _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type()); | |
| 1894 | return __internal::__brick_copy(__first, __middle, __res, std::true_type()); | |
| 1895 | } | |
| 1896 | ||
| 1897 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator> | |
| 1898 | _OutputIterator __pattern_rotate_copy( | |
| 1899 | _Tag, | |
| 1900 | _ExecutionPolicy&&, | |
| 1901 | _ForwardIterator __first, | |
| 1902 | _ForwardIterator __middle, | |
| 1903 | _ForwardIterator __last, | |
| 1904 | _OutputIterator __result) noexcept { | |
| 1905 | return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{}); | |
| 1906 | } | |
| 1907 | ||
| 1908 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2> | |
| 1909 | _RandomAccessIterator2 __pattern_rotate_copy( | |
| 1910 | __parallel_tag<_IsVector> __tag, | |
| 1911 | _ExecutionPolicy&& __exec, | |
| 1912 | _RandomAccessIterator1 __first, | |
| 1913 | _RandomAccessIterator1 __middle, | |
| 1914 | _RandomAccessIterator1 __last, | |
| 1915 | _RandomAccessIterator2 __result) { | |
| 1916 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1917 | ||
| 1918 | __par_backend::__parallel_for( | |
| 1919 | __backend_tag{}, | |
| 1920 | std::forward<_ExecutionPolicy>(__exec), | |
| 1921 | __first, | |
| 1922 | __last, | |
| 1923 | [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { | |
| 1924 | if (__b > __middle) { | |
| 1925 | __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{}); | |
| 1926 | } else { | |
| 1927 | _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first)); | |
| 1928 | if (__e < __middle) { | |
| 1929 | __internal::__brick_copy(__b, __e, __new_result, _IsVector{}); | |
| 1930 | } else { | |
| 1931 | __internal::__brick_copy(__b, __middle, __new_result, _IsVector{}); | |
| 1932 | __internal::__brick_copy(__middle, __e, __result, _IsVector{}); | |
| 1933 | } | |
| 1934 | } | |
| 1935 | }); | |
| 1936 | return __result + (__last - __first); | |
| 1937 | } | |
| 1938 | ||
| 1939 | //------------------------------------------------------------------------ | |
| 1940 | // is_partitioned | |
| 1941 | //------------------------------------------------------------------------ | |
| 1942 | ||
| 1943 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 1944 | bool __brick_is_partitioned(_ForwardIterator __first, | |
| 1945 | _ForwardIterator __last, | |
| 1946 | _UnaryPredicate __pred, | |
| 1947 | /*is_vector=*/std::false_type) noexcept { | |
| 1948 | return std::is_partitioned(__first, __last, __pred); | |
| 1949 | } | |
| 1950 | ||
| 1951 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 1952 | bool __brick_is_partitioned(_RandomAccessIterator __first, | |
| 1953 | _RandomAccessIterator __last, | |
| 1954 | _UnaryPredicate __pred, | |
| 1955 | /*is_vector=*/std::true_type) noexcept { | |
| 1956 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; | |
| 1957 | if (__first == __last) { | |
| 1958 | return true; | |
| 1959 | } else { | |
| 1960 | _RandomAccessIterator __result = __unseq_backend::__simd_first( | |
| 1961 | __first, _SizeType(0), __last - __first, [&__pred](_RandomAccessIterator __it, _SizeType __i) { | |
| 1962 | return !__pred(__it[__i]); | |
| 1963 | }); | |
| 1964 | if (__result == __last) { | |
| 1965 | return true; | |
| 1966 | } else { | |
| 1967 | ++__result; | |
| 1968 | return !__unseq_backend::__simd_or(__result, __last - __result, __pred); | |
| 1969 | } | |
| 1970 | } | |
| 1971 | } | |
| 1972 | ||
| 1973 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 1974 | bool __pattern_is_partitioned( | |
| 1975 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { | |
| 1976 | return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 1977 | } | |
| 1978 | ||
| 1979 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 1980 | bool __pattern_is_partitioned( | |
| 1981 | __parallel_tag<_IsVector> __tag, | |
| 1982 | _ExecutionPolicy&& __exec, | |
| 1983 | _RandomAccessIterator __first, | |
| 1984 | _RandomAccessIterator __last, | |
| 1985 | _UnaryPredicate __pred) { | |
| 1986 | if (__first == __last) { | |
| 1987 | return true; | |
| 1988 | } else { | |
| 1989 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 1990 | ||
| 1991 | return __internal::__except_handler([&]() { | |
| 1992 | // State of current range: | |
| 1993 | // broken - current range is not partitioned by pred | |
| 1994 | // all_true - all elements in current range satisfy pred | |
| 1995 | // all_false - all elements in current range don't satisfy pred | |
| 1996 | // true_false - elements satisfy pred are placed before elements that don't satisfy pred | |
| 1997 | enum _ReduceType { __not_init = -1, __broken, __all_true, __all_false, __true_false }; | |
| 1998 | _ReduceType __init = __not_init; | |
| 1999 | ||
| 2000 | // Array with states that we'll have when state from the left branch is merged with state from the right branch. | |
| 2001 | // State is calculated by formula: new_state = table[left_state * 4 + right_state] | |
| 2002 | _ReduceType __table[] = { | |
| 2003 | __broken, | |
| 2004 | __broken, | |
| 2005 | __broken, | |
| 2006 | __broken, | |
| 2007 | __broken, | |
| 2008 | __all_true, | |
| 2009 | __true_false, | |
| 2010 | __true_false, | |
| 2011 | __broken, | |
| 2012 | __broken, | |
| 2013 | __all_false, | |
| 2014 | __broken, | |
| 2015 | __broken, | |
| 2016 | __broken, | |
| 2017 | __true_false, | |
| 2018 | __broken}; | |
| 2019 | ||
| 2020 | __init = __par_backend::__parallel_reduce( | |
| 2021 | __backend_tag{}, | |
| 2022 | std::forward<_ExecutionPolicy>(__exec), | |
| 2023 | __first, | |
| 2024 | __last, | |
| 2025 | __init, | |
| 2026 | [&__pred, | |
| 2027 | &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, _ReduceType __value) -> _ReduceType { | |
| 2028 | if (__value == __broken) { | |
| 2029 | return __broken; | |
| 2030 | } | |
| 2031 | _ReduceType __res = __not_init; | |
| 2032 | // if first element satisfy pred | |
| 2033 | if (__pred(*__i)) { | |
| 2034 | // find first element that don't satisfy pred | |
| 2035 | _RandomAccessIterator __x = __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{}); | |
| 2036 | if (__x != __j) { | |
| 2037 | // find first element after "x" that satisfy pred | |
| 2038 | _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{}); | |
| 2039 | // if it was found then range isn't partitioned by pred | |
| 2040 | if (__y != __j) { | |
| 2041 | return __broken; | |
| 2042 | } else { | |
| 2043 | __res = __true_false; | |
| 2044 | } | |
| 2045 | } else { | |
| 2046 | __res = __all_true; | |
| 2047 | } | |
| 2048 | } else { // if first element doesn't satisfy pred | |
| 2049 | // then we should find the first element that satisfy pred. | |
| 2050 | // If we found it then range isn't partitioned by pred | |
| 2051 | if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) { | |
| 2052 | return __broken; | |
| 2053 | } else { | |
| 2054 | __res = __all_false; | |
| 2055 | } | |
| 2056 | } | |
| 2057 | // if we have value from left range then we should calculate the result | |
| 2058 | return (__value == -1) ? __res : __table[__value * 4 + __res]; | |
| 2059 | }, | |
| 2060 | ||
| 2061 | [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType { | |
| 2062 | if (__val1 == __broken || __val2 == __broken) { | |
| 2063 | return __broken; | |
| 2064 | } | |
| 2065 | // calculate the result for new big range | |
| 2066 | return __table[__val1 * 4 + __val2]; | |
| 2067 | }); | |
| 2068 | return __init != __broken; | |
| 2069 | }); | |
| 2070 | } | |
| 2071 | } | |
| 2072 | ||
| 2073 | //------------------------------------------------------------------------ | |
| 2074 | // partition | |
| 2075 | //------------------------------------------------------------------------ | |
| 2076 | ||
| 2077 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 2078 | _ForwardIterator __brick_partition( | |
| 2079 | _ForwardIterator __first, | |
| 2080 | _ForwardIterator __last, | |
| 2081 | _UnaryPredicate __pred, | |
| 2082 | /*is_vector=*/std::false_type) noexcept { | |
| 2083 | return std::partition(__first, __last, __pred); | |
| 2084 | } | |
| 2085 | ||
| 2086 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 2087 | _RandomAccessIterator __brick_partition( | |
| 2088 | _RandomAccessIterator __first, | |
| 2089 | _RandomAccessIterator __last, | |
| 2090 | _UnaryPredicate __pred, | |
| 2091 | /*is_vector=*/std::true_type) noexcept { | |
| 2092 | // TODO: vectorize | |
| 2093 | return std::partition(__first, __last, __pred); | |
| 2094 | } | |
| 2095 | ||
| 2096 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 2097 | _ForwardIterator __pattern_partition( | |
| 2098 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { | |
| 2099 | return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 2100 | } | |
| 2101 | ||
| 2102 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 2103 | _RandomAccessIterator __pattern_partition( | |
| 2104 | __parallel_tag<_IsVector> __tag, | |
| 2105 | _ExecutionPolicy&& __exec, | |
| 2106 | _RandomAccessIterator __first, | |
| 2107 | _RandomAccessIterator __last, | |
| 2108 | _UnaryPredicate __pred) { | |
| 2109 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2110 | ||
| 2111 | // partitioned range: elements before pivot satisfy pred (true part), | |
| 2112 | // elements after pivot don't satisfy pred (false part) | |
| 2113 | struct _PartitionRange { | |
| 2114 | _RandomAccessIterator __begin; | |
| 2115 | _RandomAccessIterator __pivot; | |
| 2116 | _RandomAccessIterator __end; | |
| 2117 | }; | |
| 2118 | ||
| 2119 | return __internal::__except_handler([&]() { | |
| 2120 | _PartitionRange __init{__last, __last, __last}; | |
| 2121 | ||
| 2122 | // lambda for merging two partitioned ranges to one partitioned range | |
| 2123 | auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { | |
| 2124 | auto __size1 = __val1.__end - __val1.__pivot; | |
| 2125 | auto __size2 = __val2.__pivot - __val2.__begin; | |
| 2126 | auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); | |
| 2127 | ||
| 2128 | // if all elements in left range satisfy pred then we can move new pivot to pivot of right range | |
| 2129 | if (__val1.__end == __val1.__pivot) { | |
| 2130 | return {__new_begin, __val2.__pivot, __val2.__end}; | |
| 2131 | } | |
| 2132 | // if true part of right range greater than false part of left range | |
| 2133 | // then we should swap the false part of left range and last part of true part of right range | |
| 2134 | else if (__size2 > __size1) { | |
| 2135 | __par_backend::__parallel_for( | |
| 2136 | __backend_tag{}, | |
| 2137 | std::forward<_ExecutionPolicy>(__exec), | |
| 2138 | __val1.__pivot, | |
| 2139 | __val1.__pivot + __size1, | |
| 2140 | [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) { | |
| 2141 | __internal::__brick_swap_ranges( | |
| 2142 | __i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), _IsVector{}); | |
| 2143 | }); | |
| 2144 | return {__new_begin, __val2.__pivot - __size1, __val2.__end}; | |
| 2145 | } | |
| 2146 | // else we should swap the first part of false part of left range and true part of right range | |
| 2147 | else { | |
| 2148 | __par_backend::__parallel_for( | |
| 2149 | __backend_tag{}, | |
| 2150 | std::forward<_ExecutionPolicy>(__exec), | |
| 2151 | __val1.__pivot, | |
| 2152 | __val1.__pivot + __size2, | |
| 2153 | [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) { | |
| 2154 | __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{}); | |
| 2155 | }); | |
| 2156 | return {__new_begin, __val1.__pivot + __size2, __val2.__end}; | |
| 2157 | } | |
| 2158 | }; | |
| 2159 | ||
| 2160 | _PartitionRange __result = __par_backend::__parallel_reduce( | |
| 2161 | __backend_tag{}, | |
| 2162 | std::forward<_ExecutionPolicy>(__exec), | |
| 2163 | __first, | |
| 2164 | __last, | |
| 2165 | __init, | |
| 2166 | [__pred, | |
| 2167 | __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange { | |
| 2168 | // 1. serial partition | |
| 2169 | _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{}); | |
| 2170 | ||
| 2171 | // 2. merging of two ranges (left and right respectively) | |
| 2172 | return __reductor(__value, {__i, __pivot, __j}); | |
| 2173 | }, | |
| 2174 | __reductor); | |
| 2175 | return __result.__pivot; | |
| 2176 | }); | |
| 2177 | } | |
| 2178 | ||
| 2179 | //------------------------------------------------------------------------ | |
| 2180 | // stable_partition | |
| 2181 | //------------------------------------------------------------------------ | |
| 2182 | ||
| 2183 | template <class _BidirectionalIterator, class _UnaryPredicate> | |
| 2184 | _BidirectionalIterator __brick_stable_partition( | |
| 2185 | _BidirectionalIterator __first, | |
| 2186 | _BidirectionalIterator __last, | |
| 2187 | _UnaryPredicate __pred, | |
| 2188 | /*__is_vector=*/std::false_type) noexcept { | |
| 2189 | return std::stable_partition(__first, __last, __pred); | |
| 2190 | } | |
| 2191 | ||
| 2192 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 2193 | _RandomAccessIterator __brick_stable_partition( | |
| 2194 | _RandomAccessIterator __first, | |
| 2195 | _RandomAccessIterator __last, | |
| 2196 | _UnaryPredicate __pred, | |
| 2197 | /*__is_vector=*/std::true_type) noexcept { | |
| 2198 | // TODO: vectorize | |
| 2199 | return std::stable_partition(__first, __last, __pred); | |
| 2200 | } | |
| 2201 | ||
| 2202 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> | |
| 2203 | _BidirectionalIterator __pattern_stable_partition( | |
| 2204 | _Tag, | |
| 2205 | _ExecutionPolicy&&, | |
| 2206 | _BidirectionalIterator __first, | |
| 2207 | _BidirectionalIterator __last, | |
| 2208 | _UnaryPredicate __pred) noexcept { | |
| 2209 | return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 2210 | } | |
| 2211 | ||
| 2212 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 2213 | _RandomAccessIterator __pattern_stable_partition( | |
| 2214 | __parallel_tag<_IsVector> __tag, | |
| 2215 | _ExecutionPolicy&& __exec, | |
| 2216 | _RandomAccessIterator __first, | |
| 2217 | _RandomAccessIterator __last, | |
| 2218 | _UnaryPredicate __pred) noexcept { | |
| 2219 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2220 | ||
| 2221 | // partitioned range: elements before pivot satisfy pred (true part), | |
| 2222 | // elements after pivot don't satisfy pred (false part) | |
| 2223 | struct _PartitionRange { | |
| 2224 | _RandomAccessIterator __begin; | |
| 2225 | _RandomAccessIterator __pivot; | |
| 2226 | _RandomAccessIterator __end; | |
| 2227 | }; | |
| 2228 | ||
| 2229 | return __internal::__except_handler([&]() { | |
| 2230 | _PartitionRange __init{__last, __last, __last}; | |
| 2231 | ||
| 2232 | // lambda for merging two partitioned ranges to one partitioned range | |
| 2233 | auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { | |
| 2234 | auto __size1 = __val1.__end - __val1.__pivot; | |
| 2235 | auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); | |
| 2236 | ||
| 2237 | // if all elements in left range satisfy pred then we can move new pivot to pivot of right range | |
| 2238 | if (__val1.__end == __val1.__pivot) { | |
| 2239 | return {__new_begin, __val2.__pivot, __val2.__end}; | |
| 2240 | } | |
| 2241 | // if true part of right range greater than false part of left range | |
| 2242 | // then we should swap the false part of left range and last part of true part of right range | |
| 2243 | else { | |
| 2244 | __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{}); | |
| 2245 | return {__new_begin, __val2.__pivot - __size1, __val2.__end}; | |
| 2246 | } | |
| 2247 | }; | |
| 2248 | ||
| 2249 | _PartitionRange __result = __par_backend::__parallel_reduce( | |
| 2250 | __backend_tag{}, | |
| 2251 | std::forward<_ExecutionPolicy>(__exec), | |
| 2252 | __first, | |
| 2253 | __last, | |
| 2254 | __init, | |
| 2255 | [&__pred, | |
| 2256 | __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange { | |
| 2257 | // 1. serial stable_partition | |
| 2258 | _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{}); | |
| 2259 | ||
| 2260 | // 2. merging of two ranges (left and right respectively) | |
| 2261 | return __reductor(__value, {__i, __pivot, __j}); | |
| 2262 | }, | |
| 2263 | __reductor); | |
| 2264 | return __result.__pivot; | |
| 2265 | }); | |
| 2266 | } | |
| 2267 | ||
| 2268 | //------------------------------------------------------------------------ | |
| 2269 | // partition_copy | |
| 2270 | //------------------------------------------------------------------------ | |
| 2271 | ||
| 2272 | template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate> | |
| 2273 | std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy( | |
| 2274 | _ForwardIterator __first, | |
| 2275 | _ForwardIterator __last, | |
| 2276 | _OutputIterator1 __out_true, | |
| 2277 | _OutputIterator2 __out_false, | |
| 2278 | _UnaryPredicate __pred, | |
| 2279 | /*is_vector=*/std::false_type) noexcept { | |
| 2280 | return std::partition_copy(__first, __last, __out_true, __out_false, __pred); | |
| 2281 | } | |
| 2282 | ||
| 2283 | template <class _RandomAccessIterator1, | |
| 2284 | class _RandomAccessIterator2, | |
| 2285 | class _RandomAccessIterator3, | |
| 2286 | class _UnaryPredicate> | |
| 2287 | std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __brick_partition_copy( | |
| 2288 | _RandomAccessIterator1 __first, | |
| 2289 | _RandomAccessIterator1 __last, | |
| 2290 | _RandomAccessIterator2 __out_true, | |
| 2291 | _RandomAccessIterator3 __out_false, | |
| 2292 | _UnaryPredicate __pred, | |
| 2293 | /*is_vector=*/std::true_type) noexcept { | |
| 2294 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 2295 | return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred); | |
| 2296 | #else | |
| 2297 | return std::partition_copy(__first, __last, __out_true, __out_false, __pred); | |
| 2298 | #endif | |
| 2299 | } | |
| 2300 | ||
| 2301 | template <class _Tag, | |
| 2302 | class _ExecutionPolicy, | |
| 2303 | class _ForwardIterator, | |
| 2304 | class _OutputIterator1, | |
| 2305 | class _OutputIterator2, | |
| 2306 | class _UnaryPredicate> | |
| 2307 | std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( | |
| 2308 | _Tag, | |
| 2309 | _ExecutionPolicy&&, | |
| 2310 | _ForwardIterator __first, | |
| 2311 | _ForwardIterator __last, | |
| 2312 | _OutputIterator1 __out_true, | |
| 2313 | _OutputIterator2 __out_false, | |
| 2314 | _UnaryPredicate __pred) noexcept { | |
| 2315 | return __internal::__brick_partition_copy( | |
| 2316 | __first, __last, __out_true, __out_false, __pred, typename _Tag::__is_vector{}); | |
| 2317 | } | |
| 2318 | ||
| 2319 | template <class _IsVector, | |
| 2320 | class _ExecutionPolicy, | |
| 2321 | class _RandomAccessIterator1, | |
| 2322 | class _RandomAccessIterator2, | |
| 2323 | class _RandomAccessIterator3, | |
| 2324 | class _UnaryPredicate> | |
| 2325 | std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __pattern_partition_copy( | |
| 2326 | __parallel_tag<_IsVector> __tag, | |
| 2327 | _ExecutionPolicy&& __exec, | |
| 2328 | _RandomAccessIterator1 __first, | |
| 2329 | _RandomAccessIterator1 __last, | |
| 2330 | _RandomAccessIterator2 __out_true, | |
| 2331 | _RandomAccessIterator3 __out_false, | |
| 2332 | _UnaryPredicate __pred) { | |
| 2333 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2334 | ||
| 2335 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; | |
| 2336 | typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType; | |
| 2337 | const _DifferenceType __n = __last - __first; | |
| 2338 | if (_DifferenceType(1) < __n) { | |
| 2339 | __par_backend::__buffer<bool> __mask_buf(__n); | |
| 2340 | return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() { | |
| 2341 | bool* __mask = __mask_buf.get(); | |
| 2342 | _ReturnType __m{}; | |
| 2343 | __par_backend::__parallel_strict_scan( | |
| 2344 | __backend_tag{}, | |
| 2345 | std::forward<_ExecutionPolicy>(__exec), | |
| 2346 | __n, | |
| 2347 | std::make_pair(_DifferenceType(0), _DifferenceType(0)), | |
| 2348 | [=](_DifferenceType __i, _DifferenceType __len) { // Reduce | |
| 2349 | return __internal::__brick_calc_mask_1<_DifferenceType>( | |
| 2350 | __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}); | |
| 2351 | }, | |
| 2352 | [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType { | |
| 2353 | return std::make_pair(__x.first + __y.first, __x.second + __y.second); | |
| 2354 | }, // Combine | |
| 2355 | [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan | |
| 2356 | __internal::__brick_partition_by_mask( | |
| 2357 | __first + __i, | |
| 2358 | __first + (__i + __len), | |
| 2359 | __out_true + __initial.first, | |
| 2360 | __out_false + __initial.second, | |
| 2361 | __mask + __i, | |
| 2362 | _IsVector{}); | |
| 2363 | }, | |
| 2364 | [&__m](_ReturnType __total) { __m = __total; }); | |
| 2365 | return std::make_pair(__out_true + __m.first, __out_false + __m.second); | |
| 2366 | }); | |
| 2367 | } | |
| 2368 | // trivial sequence - use serial algorithm | |
| 2369 | return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{}); | |
| 2370 | } | |
| 2371 | ||
| 2372 | //------------------------------------------------------------------------ | |
| 2373 | // sort | |
| 2374 | //------------------------------------------------------------------------ | |
| 2375 | ||
| 2376 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsMoveConstructible> | |
| 2377 | void __pattern_sort(_Tag, | |
| 2378 | _ExecutionPolicy&&, | |
| 2379 | _RandomAccessIterator __first, | |
| 2380 | _RandomAccessIterator __last, | |
| 2381 | _Compare __comp, | |
| 2382 | _IsMoveConstructible) noexcept { | |
| 2383 | std::sort(__first, __last, __comp); | |
| 2384 | } | |
| 2385 | ||
| 2386 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2387 | void __pattern_sort(__parallel_tag<_IsVector> __tag, | |
| 2388 | _ExecutionPolicy&& __exec, | |
| 2389 | _RandomAccessIterator __first, | |
| 2390 | _RandomAccessIterator __last, | |
| 2391 | _Compare __comp, | |
| 2392 | /*is_move_constructible=*/std::true_type) { | |
| 2393 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2394 | ||
| 2395 | __internal::__except_handler([&]() { | |
| 2396 | __par_backend::__parallel_stable_sort( | |
| 2397 | __backend_tag{}, | |
| 2398 | std::forward<_ExecutionPolicy>(__exec), | |
| 2399 | __first, | |
| 2400 | __last, | |
| 2401 | __comp, | |
| 2402 | [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 2403 | std::sort(__first, __last, __comp); | |
| 2404 | }); | |
| 2405 | }); | |
| 2406 | } | |
| 2407 | ||
| 2408 | //------------------------------------------------------------------------ | |
| 2409 | // stable_sort | |
| 2410 | //------------------------------------------------------------------------ | |
| 2411 | ||
| 2412 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2413 | void __pattern_stable_sort( | |
| 2414 | _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept { | |
| 2415 | std::stable_sort(__first, __last, __comp); | |
| 2416 | } | |
| 2417 | ||
| 2418 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2419 | void __pattern_stable_sort( | |
| 2420 | __parallel_tag<_IsVector> __tag, | |
| 2421 | _ExecutionPolicy&& __exec, | |
| 2422 | _RandomAccessIterator __first, | |
| 2423 | _RandomAccessIterator __last, | |
| 2424 | _Compare __comp) { | |
| 2425 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2426 | ||
| 2427 | __internal::__except_handler([&]() { | |
| 2428 | __par_backend::__parallel_stable_sort( | |
| 2429 | __backend_tag{}, | |
| 2430 | std::forward<_ExecutionPolicy>(__exec), | |
| 2431 | __first, | |
| 2432 | __last, | |
| 2433 | __comp, | |
| 2434 | [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 2435 | std::stable_sort(__first, __last, __comp); | |
| 2436 | }); | |
| 2437 | }); | |
| 2438 | } | |
| 2439 | ||
| 2440 | //------------------------------------------------------------------------ | |
| 2441 | // partial_sort | |
| 2442 | //------------------------------------------------------------------------ | |
| 2443 | ||
| 2444 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2445 | void __pattern_partial_sort( | |
| 2446 | _Tag, | |
| 2447 | _ExecutionPolicy&&, | |
| 2448 | _RandomAccessIterator __first, | |
| 2449 | _RandomAccessIterator __middle, | |
| 2450 | _RandomAccessIterator __last, | |
| 2451 | _Compare __comp) noexcept { | |
| 2452 | std::partial_sort(__first, __middle, __last, __comp); | |
| 2453 | } | |
| 2454 | ||
| 2455 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2456 | void __pattern_partial_sort( | |
| 2457 | __parallel_tag<_IsVector> __tag, | |
| 2458 | _ExecutionPolicy&& __exec, | |
| 2459 | _RandomAccessIterator __first, | |
| 2460 | _RandomAccessIterator __middle, | |
| 2461 | _RandomAccessIterator __last, | |
| 2462 | _Compare __comp) { | |
| 2463 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2464 | ||
| 2465 | const auto __n = __middle - __first; | |
| 2466 | if (__n == 0) | |
| 2467 | return; | |
| 2468 | ||
| 2469 | __internal::__except_handler([&]() { | |
| 2470 | __par_backend::__parallel_stable_sort( | |
| 2471 | __backend_tag{}, | |
| 2472 | std::forward<_ExecutionPolicy>(__exec), | |
| 2473 | __first, | |
| 2474 | __last, | |
| 2475 | __comp, | |
| 2476 | [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) { | |
| 2477 | if (__n < __end - __begin) | |
| 2478 | std::partial_sort(__begin, __begin + __n, __end, __comp); | |
| 2479 | else | |
| 2480 | std::sort(__begin, __end, __comp); | |
| 2481 | }, | |
| 2482 | __n); | |
| 2483 | }); | |
| 2484 | } | |
| 2485 | ||
| 2486 | //------------------------------------------------------------------------ | |
| 2487 | // partial_sort_copy | |
| 2488 | //------------------------------------------------------------------------ | |
| 2489 | ||
| 2490 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare> | |
| 2491 | _RandomAccessIterator __pattern_partial_sort_copy( | |
| 2492 | _Tag, | |
| 2493 | _ExecutionPolicy&&, | |
| 2494 | _ForwardIterator __first, | |
| 2495 | _ForwardIterator __last, | |
| 2496 | _RandomAccessIterator __d_first, | |
| 2497 | _RandomAccessIterator __d_last, | |
| 2498 | _Compare __comp) noexcept { | |
| 2499 | return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp); | |
| 2500 | } | |
| 2501 | ||
| 2502 | template <class _IsVector, | |
| 2503 | class _ExecutionPolicy, | |
| 2504 | class _RandomAccessIterator1, | |
| 2505 | class _RandomAccessIterator2, | |
| 2506 | class _Compare> | |
| 2507 | _RandomAccessIterator2 __pattern_partial_sort_copy( | |
| 2508 | __parallel_tag<_IsVector> __tag, | |
| 2509 | _ExecutionPolicy&& __exec, | |
| 2510 | _RandomAccessIterator1 __first, | |
| 2511 | _RandomAccessIterator1 __last, | |
| 2512 | _RandomAccessIterator2 __d_first, | |
| 2513 | _RandomAccessIterator2 __d_last, | |
| 2514 | _Compare __comp) { | |
| 2515 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2516 | ||
| 2517 | if (__last == __first || __d_last == __d_first) { | |
| 2518 | return __d_first; | |
| 2519 | } | |
| 2520 | auto __n1 = __last - __first; | |
| 2521 | auto __n2 = __d_last - __d_first; | |
| 2522 | return __internal::__except_handler([&]() { | |
| 2523 | if (__n2 >= __n1) { | |
| 2524 | __par_backend::__parallel_stable_sort( | |
| 2525 | __backend_tag{}, | |
| 2526 | std::forward<_ExecutionPolicy>(__exec), | |
| 2527 | __d_first, | |
| 2528 | __d_first + __n1, | |
| 2529 | __comp, | |
| 2530 | [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) { | |
| 2531 | _RandomAccessIterator1 __i1 = __first + (__i - __d_first); | |
| 2532 | _RandomAccessIterator1 __j1 = __first + (__j - __d_first); | |
| 2533 | ||
| 2534 | // 1. Copy elements from input to output | |
| 2535 | #if !defined(_PSTL_ICC_18_OMP_SIMD_BROKEN) | |
| 2536 | __internal::__brick_copy(__i1, __j1, __i, _IsVector{}); | |
| 2537 | #else | |
| 2538 | std::copy(__i1, __j1, __i); | |
| 2539 | #endif | |
| 2540 | // 2. Sort elements in output sequence | |
| 2541 | std::sort(__i, __j, __comp); | |
| 2542 | }, | |
| 2543 | __n1); | |
| 2544 | return __d_first + __n1; | |
| 2545 | } else { | |
| 2546 | typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1; | |
| 2547 | typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2; | |
| 2548 | __par_backend::__buffer<_T1> __buf(__n1); | |
| 2549 | _T1* __r = __buf.get(); | |
| 2550 | ||
| 2551 | __par_backend::__parallel_stable_sort( | |
| 2552 | __backend_tag{}, | |
| 2553 | std::forward<_ExecutionPolicy>(__exec), | |
| 2554 | __r, | |
| 2555 | __r + __n1, | |
| 2556 | __comp, | |
| 2557 | [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) { | |
| 2558 | _RandomAccessIterator1 __it = __first + (__i - __r); | |
| 2559 | ||
| 2560 | // 1. Copy elements from input to raw memory | |
| 2561 | for (_T1* __k = __i; __k != __j; ++__k, ++__it) { | |
| 2562 | ::new (__k) _T2(*__it); | |
| 2563 | } | |
| 2564 | ||
| 2565 | // 2. Sort elements in temporary __buffer | |
| 2566 | if (__n2 < __j - __i) | |
| 2567 | std::partial_sort(__i, __i + __n2, __j, __comp); | |
| 2568 | else | |
| 2569 | std::sort(__i, __j, __comp); | |
| 2570 | }, | |
| 2571 | __n2); | |
| 2572 | ||
| 2573 | // 3. Move elements from temporary __buffer to output | |
| 2574 | __par_backend::__parallel_for( | |
| 2575 | __backend_tag{}, | |
| 2576 | std::forward<_ExecutionPolicy>(__exec), | |
| 2577 | __r, | |
| 2578 | __r + __n2, | |
| 2579 | [__r, __d_first](_T1* __i, _T1* __j) { | |
| 2580 | __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{}); | |
| 2581 | }); | |
| 2582 | __par_backend::__parallel_for( | |
| 2583 | __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1, [](_T1* __i, _T1* __j) { | |
| 2584 | __brick_destroy(__i, __j, _IsVector{}); | |
| 2585 | }); | |
| 2586 | ||
| 2587 | return __d_first + __n2; | |
| 2588 | } | |
| 2589 | }); | |
| 2590 | } | |
| 2591 | ||
| 2592 | //------------------------------------------------------------------------ | |
| 2593 | // adjacent_find | |
| 2594 | //------------------------------------------------------------------------ | |
| 2595 | template <class _RandomAccessIterator, class _BinaryPredicate> | |
| 2596 | _RandomAccessIterator __brick_adjacent_find( | |
| 2597 | _RandomAccessIterator __first, | |
| 2598 | _RandomAccessIterator __last, | |
| 2599 | _BinaryPredicate __pred, | |
| 2600 | /* IsVector = */ std::true_type, | |
| 2601 | bool __or_semantic) noexcept { | |
| 2602 | return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic); | |
| 2603 | } | |
| 2604 | ||
| 2605 | template <class _ForwardIterator, class _BinaryPredicate> | |
| 2606 | _ForwardIterator __brick_adjacent_find( | |
| 2607 | _ForwardIterator __first, | |
| 2608 | _ForwardIterator __last, | |
| 2609 | _BinaryPredicate __pred, | |
| 2610 | /* IsVector = */ std::false_type, | |
| 2611 | bool) noexcept { | |
| 2612 | return std::adjacent_find(__first, __last, __pred); | |
| 2613 | } | |
| 2614 | ||
| 2615 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 2616 | _ForwardIterator __pattern_adjacent_find( | |
| 2617 | _Tag, | |
| 2618 | _ExecutionPolicy&&, | |
| 2619 | _ForwardIterator __first, | |
| 2620 | _ForwardIterator __last, | |
| 2621 | _BinaryPredicate __pred, | |
| 2622 | bool __or_semantic) noexcept { | |
| 2623 | return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic); | |
| 2624 | } | |
| 2625 | ||
| 2626 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate> | |
| 2627 | _RandomAccessIterator __pattern_adjacent_find( | |
| 2628 | __parallel_tag<_IsVector> __tag, | |
| 2629 | _ExecutionPolicy&& __exec, | |
| 2630 | _RandomAccessIterator __first, | |
| 2631 | _RandomAccessIterator __last, | |
| 2632 | _BinaryPredicate __pred, | |
| 2633 | bool __or_semantic) { | |
| 2634 | if (__last - __first < 2) | |
| 2635 | return __last; | |
| 2636 | ||
| 2637 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2638 | ||
| 2639 | return __internal::__except_handler([&]() { | |
| 2640 | return __par_backend::__parallel_reduce( | |
| 2641 | __backend_tag{}, | |
| 2642 | std::forward<_ExecutionPolicy>(__exec), | |
| 2643 | __first, | |
| 2644 | __last, | |
| 2645 | __last, | |
| 2646 | [__last, __pred, __or_semantic]( | |
| 2647 | _RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __value) | |
| 2648 | -> _RandomAccessIterator { | |
| 2649 | // TODO: investigate performance benefits from the use of shared variable for the result, | |
| 2650 | // checking (compare_and_swap idiom) its __value at __first. | |
| 2651 | if (__or_semantic && __value < __last) { // found | |
| 2652 | __par_backend::__cancel_execution(); | |
| 2653 | return __value; | |
| 2654 | } | |
| 2655 | ||
| 2656 | if (__value > __begin) { | |
| 2657 | // modify __end to check the predicate on the boundary __values; | |
| 2658 | // TODO: to use a custom range with boundaries overlapping | |
| 2659 | // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1) | |
| 2660 | // then check the pair [__last-1, __last) | |
| 2661 | if (__end != __last) | |
| 2662 | ++__end; | |
| 2663 | ||
| 2664 | // correct the global result iterator if the "brick" returns a local "__last" | |
| 2665 | const _RandomAccessIterator __res = | |
| 2666 | __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic); | |
| 2667 | if (__res < __end) | |
| 2668 | __value = __res; | |
| 2669 | } | |
| 2670 | return __value; | |
| 2671 | }, | |
| 2672 | [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator { | |
| 2673 | return __x < __y ? __x : __y; | |
| 2674 | } // reduce a __value | |
| 2675 | ); | |
| 2676 | }); | |
| 2677 | } | |
| 2678 | ||
| 2679 | //------------------------------------------------------------------------ | |
| 2680 | // nth_element | |
| 2681 | //------------------------------------------------------------------------ | |
| 2682 | ||
| 2683 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2684 | void __pattern_nth_element( | |
| 2685 | _Tag, | |
| 2686 | _ExecutionPolicy&&, | |
| 2687 | _RandomAccessIterator __first, | |
| 2688 | _RandomAccessIterator __nth, | |
| 2689 | _RandomAccessIterator __last, | |
| 2690 | _Compare __comp) noexcept { | |
| 2691 | std::nth_element(__first, __nth, __last, __comp); | |
| 2692 | } | |
| 2693 | ||
| 2694 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2695 | void __pattern_nth_element( | |
| 2696 | __parallel_tag<_IsVector> __tag, | |
| 2697 | _ExecutionPolicy&& __exec, | |
| 2698 | _RandomAccessIterator __first, | |
| 2699 | _RandomAccessIterator __nth, | |
| 2700 | _RandomAccessIterator __last, | |
| 2701 | _Compare __comp) noexcept { | |
| 2702 | if (__first == __last || __nth == __last) { | |
| 2703 | return; | |
| 2704 | } | |
| 2705 | ||
| 2706 | using std::iter_swap; | |
| 2707 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; | |
| 2708 | _RandomAccessIterator __x; | |
| 2709 | do { | |
| 2710 | __x = __internal::__pattern_partition( | |
| 2711 | __tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, [&__comp, __first](const _Tp& __x) { | |
| 2712 | return __comp(__x, *__first); | |
| 2713 | }); | |
| 2714 | --__x; | |
| 2715 | if (__x != __first) { | |
| 2716 | iter_swap(__first, __x); | |
| 2717 | } | |
| 2718 | // if x > nth then our new range for partition is [first, x) | |
| 2719 | if (__x - __nth > 0) { | |
| 2720 | __last = __x; | |
| 2721 | } | |
| 2722 | // if x < nth then our new range for partition is [x, last) | |
| 2723 | else if (__x - __nth < 0) { | |
| 2724 | // if *x == *nth then we can start new partition with x+1 | |
| 2725 | if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth)) { | |
| 2726 | ++__x; | |
| 2727 | } else { | |
| 2728 | iter_swap(__nth, __x); | |
| 2729 | } | |
| 2730 | __first = __x; | |
| 2731 | } | |
| 2732 | } while (__x != __nth); | |
| 2733 | } | |
| 2734 | ||
| 2735 | //------------------------------------------------------------------------ | |
| 2736 | // generate, generate_n | |
| 2737 | //------------------------------------------------------------------------ | |
| 2738 | template <class _RandomAccessIterator, class _Generator> | |
| 2739 | void __brick_generate(_RandomAccessIterator __first, | |
| 2740 | _RandomAccessIterator __last, | |
| 2741 | _Generator __g, | |
| 2742 | /* is_vector = */ std::true_type) noexcept { | |
| 2743 | __unseq_backend::__simd_generate_n(__first, __last - __first, __g); | |
| 2744 | } | |
| 2745 | ||
| 2746 | template <class _ForwardIterator, class _Generator> | |
| 2747 | void __brick_generate(_ForwardIterator __first, | |
| 2748 | _ForwardIterator __last, | |
| 2749 | _Generator __g, | |
| 2750 | /* is_vector = */ std::false_type) noexcept { | |
| 2751 | std::generate(__first, __last, __g); | |
| 2752 | } | |
| 2753 | ||
| 2754 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Generator> | |
| 2755 | void __pattern_generate( | |
| 2756 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept { | |
| 2757 | __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{}); | |
| 2758 | } | |
| 2759 | ||
| 2760 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Generator> | |
| 2761 | _RandomAccessIterator __pattern_generate( | |
| 2762 | __parallel_tag<_IsVector> __tag, | |
| 2763 | _ExecutionPolicy&& __exec, | |
| 2764 | _RandomAccessIterator __first, | |
| 2765 | _RandomAccessIterator __last, | |
| 2766 | _Generator __g) { | |
| 2767 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2768 | ||
| 2769 | return __internal::__except_handler([&]() { | |
| 2770 | __par_backend::__parallel_for( | |
| 2771 | __backend_tag{}, | |
| 2772 | std::forward<_ExecutionPolicy>(__exec), | |
| 2773 | __first, | |
| 2774 | __last, | |
| 2775 | [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) { | |
| 2776 | __internal::__brick_generate(__begin, __end, __g, _IsVector{}); | |
| 2777 | }); | |
| 2778 | return __last; | |
| 2779 | }); | |
| 2780 | } | |
| 2781 | ||
| 2782 | template <class _RandomAccessIterator, class Size, class _Generator> | |
| 2783 | _RandomAccessIterator __brick_generate_n( | |
| 2784 | _RandomAccessIterator __first, | |
| 2785 | Size __count, | |
| 2786 | _Generator __g, | |
| 2787 | /* is_vector = */ std::true_type) noexcept { | |
| 2788 | return __unseq_backend::__simd_generate_n(__first, __count, __g); | |
| 2789 | } | |
| 2790 | ||
| 2791 | template <class OutputIterator, class Size, class _Generator> | |
| 2792 | OutputIterator | |
| 2793 | __brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept { | |
| 2794 | return std::generate_n(__first, __count, __g); | |
| 2795 | } | |
| 2796 | ||
| 2797 | template <class _Tag, class _ExecutionPolicy, class _OutputIterator, class _Size, class _Generator> | |
| 2798 | _OutputIterator | |
| 2799 | __pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept { | |
| 2800 | return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{}); | |
| 2801 | } | |
| 2802 | ||
| 2803 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Generator> | |
| 2804 | _RandomAccessIterator __pattern_generate_n( | |
| 2805 | __parallel_tag<_IsVector> __tag, | |
| 2806 | _ExecutionPolicy&& __exec, | |
| 2807 | _RandomAccessIterator __first, | |
| 2808 | _Size __count, | |
| 2809 | _Generator __g) { | |
| 2810 | static_assert(__are_random_access_iterators<_RandomAccessIterator>::value, | |
| 2811 | "Pattern-brick error. Should be a random access iterator."); | |
| 2812 | return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g); | |
| 2813 | } | |
| 2814 | ||
| 2815 | //------------------------------------------------------------------------ | |
| 2816 | // remove | |
| 2817 | //------------------------------------------------------------------------ | |
| 2818 | ||
| 2819 | template <class _ForwardIterator, class _UnaryPredicate> | |
| 2820 | _ForwardIterator __brick_remove_if( | |
| 2821 | _ForwardIterator __first, | |
| 2822 | _ForwardIterator __last, | |
| 2823 | _UnaryPredicate __pred, | |
| 2824 | /* __is_vector = */ std::false_type) noexcept { | |
| 2825 | return std::remove_if(__first, __last, __pred); | |
| 2826 | } | |
| 2827 | ||
| 2828 | template <class _RandomAccessIterator, class _UnaryPredicate> | |
| 2829 | _RandomAccessIterator __brick_remove_if( | |
| 2830 | _RandomAccessIterator __first, | |
| 2831 | _RandomAccessIterator __last, | |
| 2832 | _UnaryPredicate __pred, | |
| 2833 | /* __is_vector = */ std::true_type) noexcept { | |
| 2834 | #if defined(_PSTL_MONOTONIC_PRESENT) | |
| 2835 | return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred); | |
| 2836 | #else | |
| 2837 | return std::remove_if(__first, __last, __pred); | |
| 2838 | #endif | |
| 2839 | } | |
| 2840 | ||
| 2841 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 2842 | _ForwardIterator __pattern_remove_if( | |
| 2843 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { | |
| 2844 | return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{}); | |
| 2845 | } | |
| 2846 | ||
| 2847 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryPredicate> | |
| 2848 | _RandomAccessIterator __pattern_remove_if( | |
| 2849 | __parallel_tag<_IsVector> __tag, | |
| 2850 | _ExecutionPolicy&& __exec, | |
| 2851 | _RandomAccessIterator __first, | |
| 2852 | _RandomAccessIterator __last, | |
| 2853 | _UnaryPredicate __pred) noexcept { | |
| 2854 | typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; | |
| 2855 | ||
| 2856 | if (__first == __last || __first + 1 == __last) { | |
| 2857 | // Trivial sequence - use serial algorithm | |
| 2858 | return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{}); | |
| 2859 | } | |
| 2860 | ||
| 2861 | return __internal::__remove_elements( | |
| 2862 | __tag, | |
| 2863 | std::forward<_ExecutionPolicy>(__exec), | |
| 2864 | __first, | |
| 2865 | __last, | |
| 2866 | [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { | |
| 2867 | __internal::__brick_walk2( | |
| 2868 | __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{}); | |
| 2869 | }); | |
| 2870 | } | |
| 2871 | ||
| 2872 | //------------------------------------------------------------------------ | |
| 2873 | // inplace_merge | |
| 2874 | //------------------------------------------------------------------------ | |
| 2875 | template <class _BidirectionalIterator, class _Compare> | |
| 2876 | void __brick_inplace_merge( | |
| 2877 | _BidirectionalIterator __first, | |
| 2878 | _BidirectionalIterator __middle, | |
| 2879 | _BidirectionalIterator __last, | |
| 2880 | _Compare __comp, | |
| 2881 | /* __is_vector = */ std::false_type) noexcept { | |
| 2882 | std::inplace_merge(__first, __middle, __last, __comp); | |
| 2883 | } | |
| 2884 | ||
| 2885 | template <class _RandomAccessIterator, class _Compare> | |
| 2886 | void __brick_inplace_merge( | |
| 2887 | _RandomAccessIterator __first, | |
| 2888 | _RandomAccessIterator __middle, | |
| 2889 | _RandomAccessIterator __last, | |
| 2890 | _Compare __comp, | |
| 2891 | /* __is_vector = */ std::true_type) noexcept { | |
| 2892 | // TODO: vectorize | |
| 2893 | std::inplace_merge(__first, __middle, __last, __comp); | |
| 2894 | } | |
| 2895 | ||
| 2896 | template <class _Tag, class _ExecutionPolicy, class _BidirectionalIterator, class _Compare> | |
| 2897 | void __pattern_inplace_merge( | |
| 2898 | _Tag, | |
| 2899 | _ExecutionPolicy&&, | |
| 2900 | _BidirectionalIterator __first, | |
| 2901 | _BidirectionalIterator __middle, | |
| 2902 | _BidirectionalIterator __last, | |
| 2903 | _Compare __comp) noexcept { | |
| 2904 | __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{}); | |
| 2905 | } | |
| 2906 | ||
| 2907 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 2908 | void __pattern_inplace_merge( | |
| 2909 | __parallel_tag<_IsVector> __tag, | |
| 2910 | _ExecutionPolicy&& __exec, | |
| 2911 | _RandomAccessIterator __first, | |
| 2912 | _RandomAccessIterator __middle, | |
| 2913 | _RandomAccessIterator __last, | |
| 2914 | _Compare __comp) { | |
| 2915 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2916 | ||
| 2917 | if (__first == __last || __first == __middle || __middle == __last) { | |
| 2918 | return; | |
| 2919 | } | |
| 2920 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; | |
| 2921 | auto __n = __last - __first; | |
| 2922 | __par_backend::__buffer<_Tp> __buf(__n); | |
| 2923 | _Tp* __r = __buf.get(); | |
| 2924 | __internal::__except_handler([&]() { | |
| 2925 | auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) { | |
| 2926 | __internal::__invoke_if_else( | |
| 2927 | std::is_trivial<_Tp>(), | |
| 2928 | [&]() { *__z = std::move(*__x); }, | |
| 2929 | [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); | |
| 2930 | }; | |
| 2931 | ||
| 2932 | auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) { | |
| 2933 | return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); | |
| 2934 | }; | |
| 2935 | ||
| 2936 | __par_backend::__parallel_merge( | |
| 2937 | __backend_tag{}, | |
| 2938 | std::forward<_ExecutionPolicy>(__exec), | |
| 2939 | __first, | |
| 2940 | __middle, | |
| 2941 | __middle, | |
| 2942 | __last, | |
| 2943 | __r, | |
| 2944 | __comp, | |
| 2945 | [__n, __move_values, __move_sequences]( | |
| 2946 | _RandomAccessIterator __f1, | |
| 2947 | _RandomAccessIterator __l1, | |
| 2948 | _RandomAccessIterator __f2, | |
| 2949 | _RandomAccessIterator __l2, | |
| 2950 | _Tp* __f3, | |
| 2951 | _Compare __comp) { | |
| 2952 | (__utils::__serial_move_merge(__n))( | |
| 2953 | __f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values, __move_sequences, __move_sequences); | |
| 2954 | return __f3 + (__l1 - __f1) + (__l2 - __f2); | |
| 2955 | }); | |
| 2956 | __par_backend::__parallel_for( | |
| 2957 | __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first](_Tp* __i, _Tp* __j) { | |
| 2958 | __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{}); | |
| 2959 | }); | |
| 2960 | }); | |
| 2961 | } | |
| 2962 | ||
| 2963 | //------------------------------------------------------------------------ | |
| 2964 | // includes | |
| 2965 | //------------------------------------------------------------------------ | |
| 2966 | ||
| 2967 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 2968 | bool __pattern_includes( | |
| 2969 | _Tag, | |
| 2970 | _ExecutionPolicy&&, | |
| 2971 | _ForwardIterator1 __first1, | |
| 2972 | _ForwardIterator1 __last1, | |
| 2973 | _ForwardIterator2 __first2, | |
| 2974 | _ForwardIterator2 __last2, | |
| 2975 | _Compare __comp) noexcept { | |
| 2976 | return std::includes(__first1, __last1, __first2, __last2, __comp); | |
| 2977 | } | |
| 2978 | ||
| 2979 | template <class _IsVector, | |
| 2980 | class _ExecutionPolicy, | |
| 2981 | class _RandomAccessIterator1, | |
| 2982 | class _RandomAccessIterator2, | |
| 2983 | class _Compare> | |
| 2984 | bool __pattern_includes( | |
| 2985 | __parallel_tag<_IsVector> __tag, | |
| 2986 | _ExecutionPolicy&& __exec, | |
| 2987 | _RandomAccessIterator1 __first1, | |
| 2988 | _RandomAccessIterator1 __last1, | |
| 2989 | _RandomAccessIterator2 __first2, | |
| 2990 | _RandomAccessIterator2 __last2, | |
| 2991 | _Compare __comp) { | |
| 2992 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 2993 | ||
| 2994 | if (__first2 >= __last2) | |
| 2995 | return true; | |
| 2996 | ||
| 2997 | if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1))) | |
| 2998 | return false; | |
| 2999 | ||
| 3000 | __first1 = std::lower_bound(__first1, __last1, *__first2, __comp); | |
| 3001 | if (__first1 == __last1) | |
| 3002 | return false; | |
| 3003 | ||
| 3004 | if (__last2 - __first2 == 1) | |
| 3005 | return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1); | |
| 3006 | ||
| 3007 | return __internal::__except_handler([&]() { | |
| 3008 | return !__internal::__parallel_or( | |
| 3009 | __backend_tag{}, | |
| 3010 | std::forward<_ExecutionPolicy>(__exec), | |
| 3011 | __first2, | |
| 3012 | __last2, | |
| 3013 | [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) { | |
| 3014 | _LIBCPP_ASSERT_UNCATEGORIZED(__j > __i, ""); | |
| 3015 | //_LIBCPP_ASSERT_UNCATEGORIZED(__j - __i > 1, ""); | |
| 3016 | ||
| 3017 | // 1. moving boundaries to "consume" subsequence of equal elements | |
| 3018 | auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool { | |
| 3019 | return !__comp(*__a, *__b) && !__comp(*__b, *__a); | |
| 3020 | }; | |
| 3021 | ||
| 3022 | // 1.1 left bound, case "aaa[aaaxyz...]" - searching "x" | |
| 3023 | if (__i > __first2 && __is_equal(__i, __i - 1)) { | |
| 3024 | // whole subrange continues to content equal elements - return "no op" | |
| 3025 | if (__is_equal(__i, __j - 1)) | |
| 3026 | return false; | |
| 3027 | ||
| 3028 | __i = std::upper_bound(__i, __last2, *__i, __comp); | |
| 3029 | } | |
| 3030 | ||
| 3031 | // 1.2 right bound, case "[...aaa]aaaxyz" - searching "x" | |
| 3032 | if (__j < __last2 && __is_equal(__j - 1, __j)) | |
| 3033 | __j = std::upper_bound(__j, __last2, *__j, __comp); | |
| 3034 | ||
| 3035 | // 2. testing is __a subsequence of the second range included into the first range | |
| 3036 | auto __b = std::lower_bound(__first1, __last1, *__i, __comp); | |
| 3037 | ||
| 3038 | _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__last1 - 1), *__b), ""); | |
| 3039 | _LIBCPP_ASSERT_UNCATEGORIZED(!__comp(*(__j - 1), *__i), ""); | |
| 3040 | return !std::includes(__b, __last1, __i, __j, __comp); | |
| 3041 | }); | |
| 3042 | }); | |
| 3043 | } | |
| 3044 | ||
| 3045 | constexpr auto __set_algo_cut_off = 1000; | |
| 3046 | ||
| 3047 | template <class _IsVector, | |
| 3048 | class _ExecutionPolicy, | |
| 3049 | class _ForwardIterator1, | |
| 3050 | class _ForwardIterator2, | |
| 3051 | class _OutputIterator, | |
| 3052 | class _Compare, | |
| 3053 | class _SizeFunction, | |
| 3054 | class _SetOP> | |
| 3055 | _OutputIterator __parallel_set_op( | |
| 3056 | __parallel_tag<_IsVector> __tag, | |
| 3057 | _ExecutionPolicy&& __exec, | |
| 3058 | _ForwardIterator1 __first1, | |
| 3059 | _ForwardIterator1 __last1, | |
| 3060 | _ForwardIterator2 __first2, | |
| 3061 | _ForwardIterator2 __last2, | |
| 3062 | _OutputIterator __result, | |
| 3063 | _Compare __comp, | |
| 3064 | _SizeFunction __size_func, | |
| 3065 | _SetOP __set_op) { | |
| 3066 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 3067 | ||
| 3068 | typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; | |
| 3069 | typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; | |
| 3070 | ||
| 3071 | struct _SetRange { | |
| 3072 | _DifferenceType __pos, __len, __buf_pos; | |
| 3073 | bool empty() const { return __len == 0; } | |
| 3074 | }; | |
| 3075 | ||
| 3076 | const _DifferenceType __n1 = __last1 - __first1; | |
| 3077 | const _DifferenceType __n2 = __last2 - __first2; | |
| 3078 | ||
| 3079 | __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2)); | |
| 3080 | ||
| 3081 | return __internal::__except_handler( | |
| 3082 | [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() { | |
| 3083 | auto __buffer = __buf.get(); | |
| 3084 | _DifferenceType __m{}; | |
| 3085 | auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan | |
| 3086 | if (!__s.empty()) | |
| 3087 | __brick_move_destroy()( | |
| 3088 | __buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos, _IsVector{}); | |
| 3089 | }; | |
| 3090 | __par_backend::__parallel_strict_scan( | |
| 3091 | __backend_tag{}, | |
| 3092 | std::forward<_ExecutionPolicy>(__exec), | |
| 3093 | __n1, | |
| 3094 | _SetRange{0, 0, 0}, //-1, 0}, | |
| 3095 | [=](_DifferenceType __i, _DifferenceType __len) { // Reduce | |
| 3096 | //[__b; __e) - a subrange of the first sequence, to reduce | |
| 3097 | _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); | |
| 3098 | ||
| 3099 | // try searching for the first element which not equal to *__b | |
| 3100 | if (__b != __first1) | |
| 3101 | __b = std::upper_bound(__b, __last1, *__b, __comp); | |
| 3102 | ||
| 3103 | // try searching for the first element which not equal to *__e | |
| 3104 | if (__e != __last1) | |
| 3105 | __e = std::upper_bound(__e, __last1, *__e, __comp); | |
| 3106 | ||
| 3107 | // check is [__b; __e) empty | |
| 3108 | if (__e - __b < 1) { | |
| 3109 | _ForwardIterator2 __bb = __last2; | |
| 3110 | if (__b != __last1) | |
| 3111 | __bb = std::lower_bound(__first2, __last2, *__b, __comp); | |
| 3112 | ||
| 3113 | const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); | |
| 3114 | return _SetRange{0, 0, __buf_pos}; | |
| 3115 | } | |
| 3116 | ||
| 3117 | // try searching for "corresponding" subrange [__bb; __ee) in the second sequence | |
| 3118 | _ForwardIterator2 __bb = __first2; | |
| 3119 | if (__b != __first1) | |
| 3120 | __bb = std::lower_bound(__first2, __last2, *__b, __comp); | |
| 3121 | ||
| 3122 | _ForwardIterator2 __ee = __last2; | |
| 3123 | if (__e != __last1) | |
| 3124 | __ee = std::lower_bound(__bb, __last2, *__e, __comp); | |
| 3125 | ||
| 3126 | const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); | |
| 3127 | auto __buffer_b = __buffer + __buf_pos; | |
| 3128 | auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp); | |
| 3129 | ||
| 3130 | return _SetRange{0, __res - __buffer_b, __buf_pos}; | |
| 3131 | }, | |
| 3132 | [](const _SetRange& __a, const _SetRange& __b) { // Combine | |
| 3133 | if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty())) | |
| 3134 | return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos}; | |
| 3135 | return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos}; | |
| 3136 | }, | |
| 3137 | __scan, // Scan | |
| 3138 | [&__m, &__scan](const _SetRange& __total) { // Apex | |
| 3139 | // final scan | |
| 3140 | __scan(0, 0, __total); | |
| 3141 | __m = __total.__pos + __total.__len; | |
| 3142 | }); | |
| 3143 | return __result + __m; | |
| 3144 | }); | |
| 3145 | } | |
| 3146 | ||
| 3147 | // a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference' | |
| 3148 | template <class _Tag, | |
| 3149 | class _ExecutionPolicy, | |
| 3150 | class _ForwardIterator1, | |
| 3151 | class _ForwardIterator2, | |
| 3152 | class _OutputIterator, | |
| 3153 | class _Compare, | |
| 3154 | class _SetUnionOp> | |
| 3155 | _OutputIterator __parallel_set_union_op( | |
| 3156 | _Tag __tag, | |
| 3157 | _ExecutionPolicy&& __exec, | |
| 3158 | _ForwardIterator1 __first1, | |
| 3159 | _ForwardIterator1 __last1, | |
| 3160 | _ForwardIterator2 __first2, | |
| 3161 | _ForwardIterator2 __last2, | |
| 3162 | _OutputIterator __result, | |
| 3163 | _Compare __comp, | |
| 3164 | _SetUnionOp __set_union_op) { | |
| 3165 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 3166 | ||
| 3167 | typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; | |
| 3168 | ||
| 3169 | const auto __n1 = __last1 - __first1; | |
| 3170 | const auto __n2 = __last2 - __first2; | |
| 3171 | ||
| 3172 | auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { | |
| 3173 | return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); | |
| 3174 | }; | |
| 3175 | auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) { | |
| 3176 | return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); | |
| 3177 | }; | |
| 3178 | ||
| 3179 | // {1} {}: parallel copying just first sequence | |
| 3180 | if (__n2 == 0) | |
| 3181 | return __internal::__pattern_walk2_brick( | |
| 3182 | __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1); | |
| 3183 | ||
| 3184 | // {} {2}: parallel copying justmake second sequence | |
| 3185 | if (__n1 == 0) | |
| 3186 | return __internal::__pattern_walk2_brick( | |
| 3187 | __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2); | |
| 3188 | ||
| 3189 | // testing whether the sequences are intersected | |
| 3190 | _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); | |
| 3191 | ||
| 3192 | if (__left_bound_seq_1 == __last1) { | |
| 3193 | //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 | |
| 3194 | __par_backend::__parallel_invoke( | |
| 3195 | __backend_tag{}, | |
| 3196 | std::forward<_ExecutionPolicy>(__exec), | |
| 3197 | [=] { | |
| 3198 | __internal::__pattern_walk2_brick( | |
| 3199 | __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1); | |
| 3200 | }, | |
| 3201 | [=] { | |
| 3202 | __internal::__pattern_walk2_brick( | |
| 3203 | __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result + __n1, copy_range2); | |
| 3204 | }); | |
| 3205 | return __result + __n1 + __n2; | |
| 3206 | } | |
| 3207 | ||
| 3208 | // testing whether the sequences are intersected | |
| 3209 | _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); | |
| 3210 | ||
| 3211 | if (__left_bound_seq_2 == __last2) { | |
| 3212 | //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 | |
| 3213 | __par_backend::__parallel_invoke( | |
| 3214 | __backend_tag{}, | |
| 3215 | std::forward<_ExecutionPolicy>(__exec), | |
| 3216 | [=] { | |
| 3217 | __internal::__pattern_walk2_brick( | |
| 3218 | __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2); | |
| 3219 | }, | |
| 3220 | [=] { | |
| 3221 | __internal::__pattern_walk2_brick( | |
| 3222 | __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result + __n2, copy_range1); | |
| 3223 | }); | |
| 3224 | return __result + __n1 + __n2; | |
| 3225 | } | |
| 3226 | ||
| 3227 | const auto __m1 = __left_bound_seq_1 - __first1; | |
| 3228 | if (__m1 > __set_algo_cut_off) { | |
| 3229 | auto __res_or = __result; | |
| 3230 | __result += __m1; // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) | |
| 3231 | __par_backend::__parallel_invoke( | |
| 3232 | __backend_tag{}, | |
| 3233 | std::forward<_ExecutionPolicy>(__exec), | |
| 3234 | // do parallel copying of [first1; left_bound_seq_1) | |
| 3235 | [=] { | |
| 3236 | __internal::__pattern_walk2_brick( | |
| 3237 | __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1, __res_or, copy_range1); | |
| 3238 | }, | |
| 3239 | [=, &__result] { | |
| 3240 | __result = __internal::__parallel_set_op( | |
| 3241 | __tag, | |
| 3242 | std::forward<_ExecutionPolicy>(__exec), | |
| 3243 | __left_bound_seq_1, | |
| 3244 | __last1, | |
| 3245 | __first2, | |
| 3246 | __last2, | |
| 3247 | __result, | |
| 3248 | __comp, | |
| 3249 | [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, | |
| 3250 | __set_union_op); | |
| 3251 | }); | |
| 3252 | return __result; | |
| 3253 | } | |
| 3254 | ||
| 3255 | const auto __m2 = __left_bound_seq_2 - __first2; | |
| 3256 | _LIBCPP_ASSERT_UNCATEGORIZED(__m1 == 0 || __m2 == 0, ""); | |
| 3257 | if (__m2 > __set_algo_cut_off) { | |
| 3258 | auto __res_or = __result; | |
| 3259 | __result += __m2; // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) | |
| 3260 | __par_backend::__parallel_invoke( | |
| 3261 | __backend_tag{}, | |
| 3262 | std::forward<_ExecutionPolicy>(__exec), | |
| 3263 | // do parallel copying of [first2; left_bound_seq_2) | |
| 3264 | [=] { | |
| 3265 | __internal::__pattern_walk2_brick( | |
| 3266 | __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2, __res_or, copy_range2); | |
| 3267 | }, | |
| 3268 | [=, &__result] { | |
| 3269 | __result = __internal::__parallel_set_op( | |
| 3270 | __tag, | |
| 3271 | std::forward<_ExecutionPolicy>(__exec), | |
| 3272 | __first1, | |
| 3273 | __last1, | |
| 3274 | __left_bound_seq_2, | |
| 3275 | __last2, | |
| 3276 | __result, | |
| 3277 | __comp, | |
| 3278 | [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, | |
| 3279 | __set_union_op); | |
| 3280 | }); | |
| 3281 | return __result; | |
| 3282 | } | |
| 3283 | ||
| 3284 | return __internal::__parallel_set_op( | |
| 3285 | __tag, | |
| 3286 | std::forward<_ExecutionPolicy>(__exec), | |
| 3287 | __first1, | |
| 3288 | __last1, | |
| 3289 | __first2, | |
| 3290 | __last2, | |
| 3291 | __result, | |
| 3292 | __comp, | |
| 3293 | [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, | |
| 3294 | __set_union_op); | |
| 3295 | } | |
| 3296 | ||
| 3297 | //------------------------------------------------------------------------ | |
| 3298 | // set_union | |
| 3299 | //------------------------------------------------------------------------ | |
| 3300 | ||
| 3301 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 3302 | _OutputIterator __brick_set_union( | |
| 3303 | _ForwardIterator1 __first1, | |
| 3304 | _ForwardIterator1 __last1, | |
| 3305 | _ForwardIterator2 __first2, | |
| 3306 | _ForwardIterator2 __last2, | |
| 3307 | _OutputIterator __result, | |
| 3308 | _Compare __comp, | |
| 3309 | /*__is_vector=*/std::false_type) noexcept { | |
| 3310 | return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3311 | } | |
| 3312 | ||
| 3313 | template <typename _IsVector> | |
| 3314 | struct __BrickCopyConstruct { | |
| 3315 | template <typename _ForwardIterator, typename _OutputIterator> | |
| 3316 | _OutputIterator operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result) { | |
| 3317 | return __brick_uninitialized_copy(__first, __last, __result, _IsVector()); | |
| 3318 | } | |
| 3319 | }; | |
| 3320 | ||
| 3321 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator, class _Compare> | |
| 3322 | _OutputIterator __brick_set_union( | |
| 3323 | _RandomAccessIterator1 __first1, | |
| 3324 | _RandomAccessIterator1 __last1, | |
| 3325 | _RandomAccessIterator2 __first2, | |
| 3326 | _RandomAccessIterator2 __last2, | |
| 3327 | _OutputIterator __result, | |
| 3328 | _Compare __comp, | |
| 3329 | /*__is_vector=*/std::true_type) noexcept { | |
| 3330 | // TODO: vectorize | |
| 3331 | return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3332 | } | |
| 3333 | ||
| 3334 | template <class _Tag, | |
| 3335 | class _ExecutionPolicy, | |
| 3336 | class _ForwardIterator1, | |
| 3337 | class _ForwardIterator2, | |
| 3338 | class _OutputIterator, | |
| 3339 | class _Compare> | |
| 3340 | _OutputIterator __pattern_set_union( | |
| 3341 | _Tag, | |
| 3342 | _ExecutionPolicy&&, | |
| 3343 | _ForwardIterator1 __first1, | |
| 3344 | _ForwardIterator1 __last1, | |
| 3345 | _ForwardIterator2 __first2, | |
| 3346 | _ForwardIterator2 __last2, | |
| 3347 | _OutputIterator __result, | |
| 3348 | _Compare __comp) noexcept { | |
| 3349 | return __internal::__brick_set_union( | |
| 3350 | __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); | |
| 3351 | } | |
| 3352 | ||
| 3353 | template <class _IsVector, | |
| 3354 | class _ExecutionPolicy, | |
| 3355 | class _RandomAccessIterator1, | |
| 3356 | class _RandomAccessIterator2, | |
| 3357 | class _OutputIterator, | |
| 3358 | class _Compare> | |
| 3359 | _OutputIterator __pattern_set_union( | |
| 3360 | __parallel_tag<_IsVector> __tag, | |
| 3361 | _ExecutionPolicy&& __exec, | |
| 3362 | _RandomAccessIterator1 __first1, | |
| 3363 | _RandomAccessIterator1 __last1, | |
| 3364 | _RandomAccessIterator2 __first2, | |
| 3365 | _RandomAccessIterator2 __last2, | |
| 3366 | _OutputIterator __result, | |
| 3367 | _Compare __comp) { | |
| 3368 | const auto __n1 = __last1 - __first1; | |
| 3369 | const auto __n2 = __last2 - __first2; | |
| 3370 | ||
| 3371 | // use serial algorithm | |
| 3372 | if (__n1 + __n2 <= __set_algo_cut_off) | |
| 3373 | return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3374 | ||
| 3375 | typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; | |
| 3376 | return __parallel_set_union_op( | |
| 3377 | __tag, | |
| 3378 | std::forward<_ExecutionPolicy>(__exec), | |
| 3379 | __first1, | |
| 3380 | __last1, | |
| 3381 | __first2, | |
| 3382 | __last2, | |
| 3383 | __result, | |
| 3384 | __comp, | |
| 3385 | [](_RandomAccessIterator1 __first1, | |
| 3386 | _RandomAccessIterator1 __last1, | |
| 3387 | _RandomAccessIterator2 __first2, | |
| 3388 | _RandomAccessIterator2 __last2, | |
| 3389 | _Tp* __result, | |
| 3390 | _Compare __comp) { | |
| 3391 | return __pstl::__utils::__set_union_construct( | |
| 3392 | __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); | |
| 3393 | }); | |
| 3394 | } | |
| 3395 | ||
| 3396 | //------------------------------------------------------------------------ | |
| 3397 | // set_intersection | |
| 3398 | //------------------------------------------------------------------------ | |
| 3399 | ||
| 3400 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 3401 | _OutputIterator __brick_set_intersection( | |
| 3402 | _ForwardIterator1 __first1, | |
| 3403 | _ForwardIterator1 __last1, | |
| 3404 | _ForwardIterator2 __first2, | |
| 3405 | _ForwardIterator2 __last2, | |
| 3406 | _OutputIterator __result, | |
| 3407 | _Compare __comp, | |
| 3408 | /*__is_vector=*/std::false_type) noexcept { | |
| 3409 | return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3410 | } | |
| 3411 | ||
| 3412 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare> | |
| 3413 | _RandomAccessIterator3 __brick_set_intersection( | |
| 3414 | _RandomAccessIterator1 __first1, | |
| 3415 | _RandomAccessIterator1 __last1, | |
| 3416 | _RandomAccessIterator2 __first2, | |
| 3417 | _RandomAccessIterator2 __last2, | |
| 3418 | _RandomAccessIterator3 __result, | |
| 3419 | _Compare __comp, | |
| 3420 | /*__is_vector=*/std::true_type) noexcept { | |
| 3421 | // TODO: vectorize | |
| 3422 | return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3423 | } | |
| 3424 | ||
| 3425 | template <class _Tag, | |
| 3426 | class _ExecutionPolicy, | |
| 3427 | class _ForwardIterator1, | |
| 3428 | class _ForwardIterator2, | |
| 3429 | class _OutputIterator, | |
| 3430 | class _Compare> | |
| 3431 | _OutputIterator __pattern_set_intersection( | |
| 3432 | _Tag, | |
| 3433 | _ExecutionPolicy&&, | |
| 3434 | _ForwardIterator1 __first1, | |
| 3435 | _ForwardIterator1 __last1, | |
| 3436 | _ForwardIterator2 __first2, | |
| 3437 | _ForwardIterator2 __last2, | |
| 3438 | _OutputIterator __result, | |
| 3439 | _Compare __comp) noexcept { | |
| 3440 | return __internal::__brick_set_intersection( | |
| 3441 | __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); | |
| 3442 | } | |
| 3443 | ||
| 3444 | template <class _IsVector, | |
| 3445 | class _ExecutionPolicy, | |
| 3446 | class _RandomAccessIterator1, | |
| 3447 | class _RandomAccessIterator2, | |
| 3448 | class _RandomAccessIterator3, | |
| 3449 | class _Compare> | |
| 3450 | _RandomAccessIterator3 __pattern_set_intersection( | |
| 3451 | __parallel_tag<_IsVector> __tag, | |
| 3452 | _ExecutionPolicy&& __exec, | |
| 3453 | _RandomAccessIterator1 __first1, | |
| 3454 | _RandomAccessIterator1 __last1, | |
| 3455 | _RandomAccessIterator2 __first2, | |
| 3456 | _RandomAccessIterator2 __last2, | |
| 3457 | _RandomAccessIterator3 __result, | |
| 3458 | _Compare __comp) { | |
| 3459 | typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; | |
| 3460 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; | |
| 3461 | ||
| 3462 | const auto __n1 = __last1 - __first1; | |
| 3463 | const auto __n2 = __last2 - __first2; | |
| 3464 | ||
| 3465 | // intersection is empty | |
| 3466 | if (__n1 == 0 || __n2 == 0) | |
| 3467 | return __result; | |
| 3468 | ||
| 3469 | // testing whether the sequences are intersected | |
| 3470 | _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); | |
| 3471 | //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty | |
| 3472 | if (__left_bound_seq_1 == __last1) | |
| 3473 | return __result; | |
| 3474 | ||
| 3475 | // testing whether the sequences are intersected | |
| 3476 | _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); | |
| 3477 | //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty | |
| 3478 | if (__left_bound_seq_2 == __last2) | |
| 3479 | return __result; | |
| 3480 | ||
| 3481 | const auto __m1 = __last1 - __left_bound_seq_1 + __n2; | |
| 3482 | if (__m1 > __set_algo_cut_off) { | |
| 3483 | // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) | |
| 3484 | return __internal::__parallel_set_op( | |
| 3485 | __tag, | |
| 3486 | std::forward<_ExecutionPolicy>(__exec), | |
| 3487 | __left_bound_seq_1, | |
| 3488 | __last1, | |
| 3489 | __first2, | |
| 3490 | __last2, | |
| 3491 | __result, | |
| 3492 | __comp, | |
| 3493 | [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, | |
| 3494 | [](_RandomAccessIterator1 __first1, | |
| 3495 | _RandomAccessIterator1 __last1, | |
| 3496 | _RandomAccessIterator2 __first2, | |
| 3497 | _RandomAccessIterator2 __last2, | |
| 3498 | _Tp* __result, | |
| 3499 | _Compare __comp) { | |
| 3500 | return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3501 | }); | |
| 3502 | } | |
| 3503 | ||
| 3504 | const auto __m2 = __last2 - __left_bound_seq_2 + __n1; | |
| 3505 | if (__m2 > __set_algo_cut_off) { | |
| 3506 | // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) | |
| 3507 | __result = __internal::__parallel_set_op( | |
| 3508 | __tag, | |
| 3509 | std::forward<_ExecutionPolicy>(__exec), | |
| 3510 | __first1, | |
| 3511 | __last1, | |
| 3512 | __left_bound_seq_2, | |
| 3513 | __last2, | |
| 3514 | __result, | |
| 3515 | __comp, | |
| 3516 | [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, | |
| 3517 | [](_RandomAccessIterator1 __first1, | |
| 3518 | _RandomAccessIterator1 __last1, | |
| 3519 | _RandomAccessIterator2 __first2, | |
| 3520 | _RandomAccessIterator2 __last2, | |
| 3521 | _Tp* __result, | |
| 3522 | _Compare __comp) { | |
| 3523 | return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp); | |
| 3524 | }); | |
| 3525 | return __result; | |
| 3526 | } | |
| 3527 | ||
| 3528 | // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm | |
| 3529 | return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp); | |
| 3530 | } | |
| 3531 | ||
| 3532 | //------------------------------------------------------------------------ | |
| 3533 | // set_difference | |
| 3534 | //------------------------------------------------------------------------ | |
| 3535 | ||
| 3536 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 3537 | _OutputIterator __brick_set_difference( | |
| 3538 | _ForwardIterator1 __first1, | |
| 3539 | _ForwardIterator1 __last1, | |
| 3540 | _ForwardIterator2 __first2, | |
| 3541 | _ForwardIterator2 __last2, | |
| 3542 | _OutputIterator __result, | |
| 3543 | _Compare __comp, | |
| 3544 | /*__is_vector=*/std::false_type) noexcept { | |
| 3545 | return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3546 | } | |
| 3547 | ||
| 3548 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare> | |
| 3549 | _RandomAccessIterator3 __brick_set_difference( | |
| 3550 | _RandomAccessIterator1 __first1, | |
| 3551 | _RandomAccessIterator1 __last1, | |
| 3552 | _RandomAccessIterator2 __first2, | |
| 3553 | _RandomAccessIterator2 __last2, | |
| 3554 | _RandomAccessIterator3 __result, | |
| 3555 | _Compare __comp, | |
| 3556 | /*__is_vector=*/std::true_type) noexcept { | |
| 3557 | // TODO: vectorize | |
| 3558 | return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3559 | } | |
| 3560 | ||
| 3561 | template <class _Tag, | |
| 3562 | class _ExecutionPolicy, | |
| 3563 | class _ForwardIterator1, | |
| 3564 | class _ForwardIterator2, | |
| 3565 | class _OutputIterator, | |
| 3566 | class _Compare> | |
| 3567 | _OutputIterator __pattern_set_difference( | |
| 3568 | _Tag, | |
| 3569 | _ExecutionPolicy&&, | |
| 3570 | _ForwardIterator1 __first1, | |
| 3571 | _ForwardIterator1 __last1, | |
| 3572 | _ForwardIterator2 __first2, | |
| 3573 | _ForwardIterator2 __last2, | |
| 3574 | _OutputIterator __result, | |
| 3575 | _Compare __comp) noexcept { | |
| 3576 | return __internal::__brick_set_difference( | |
| 3577 | __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); | |
| 3578 | } | |
| 3579 | ||
| 3580 | template <class _IsVector, | |
| 3581 | class _ExecutionPolicy, | |
| 3582 | class _RandomAccessIterator1, | |
| 3583 | class _RandomAccessIterator2, | |
| 3584 | class _RandomAccessIterator3, | |
| 3585 | class _Compare> | |
| 3586 | _RandomAccessIterator3 __pattern_set_difference( | |
| 3587 | __parallel_tag<_IsVector> __tag, | |
| 3588 | _ExecutionPolicy&& __exec, | |
| 3589 | _RandomAccessIterator1 __first1, | |
| 3590 | _RandomAccessIterator1 __last1, | |
| 3591 | _RandomAccessIterator2 __first2, | |
| 3592 | _RandomAccessIterator2 __last2, | |
| 3593 | _RandomAccessIterator3 __result, | |
| 3594 | _Compare __comp) { | |
| 3595 | typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; | |
| 3596 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; | |
| 3597 | ||
| 3598 | const auto __n1 = __last1 - __first1; | |
| 3599 | const auto __n2 = __last2 - __first2; | |
| 3600 | ||
| 3601 | // {} \ {2}: the difference is empty | |
| 3602 | if (__n1 == 0) | |
| 3603 | return __result; | |
| 3604 | ||
| 3605 | // {1} \ {}: parallel copying just first sequence | |
| 3606 | if (__n2 == 0) | |
| 3607 | return __internal::__pattern_walk2_brick( | |
| 3608 | __tag, | |
| 3609 | std::forward<_ExecutionPolicy>(__exec), | |
| 3610 | __first1, | |
| 3611 | __last1, | |
| 3612 | __result, | |
| 3613 | [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { | |
| 3614 | return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); | |
| 3615 | }); | |
| 3616 | ||
| 3617 | // testing whether the sequences are intersected | |
| 3618 | _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); | |
| 3619 | //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence | |
| 3620 | if (__left_bound_seq_1 == __last1) | |
| 3621 | return __internal::__pattern_walk2_brick( | |
| 3622 | __tag, | |
| 3623 | std::forward<_ExecutionPolicy>(__exec), | |
| 3624 | __first1, | |
| 3625 | __last1, | |
| 3626 | __result, | |
| 3627 | [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { | |
| 3628 | return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); | |
| 3629 | }); | |
| 3630 | ||
| 3631 | // testing whether the sequences are intersected | |
| 3632 | _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); | |
| 3633 | //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence | |
| 3634 | if (__left_bound_seq_2 == __last2) | |
| 3635 | return __internal::__pattern_walk2_brick( | |
| 3636 | __tag, | |
| 3637 | std::forward<_ExecutionPolicy>(__exec), | |
| 3638 | __first1, | |
| 3639 | __last1, | |
| 3640 | __result, | |
| 3641 | [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { | |
| 3642 | return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); | |
| 3643 | }); | |
| 3644 | ||
| 3645 | if (__n1 + __n2 > __set_algo_cut_off) | |
| 3646 | return __parallel_set_op( | |
| 3647 | __tag, | |
| 3648 | std::forward<_ExecutionPolicy>(__exec), | |
| 3649 | __first1, | |
| 3650 | __last1, | |
| 3651 | __first2, | |
| 3652 | __last2, | |
| 3653 | __result, | |
| 3654 | __comp, | |
| 3655 | [](_DifferenceType __n, _DifferenceType) { return __n; }, | |
| 3656 | [](_RandomAccessIterator1 __first1, | |
| 3657 | _RandomAccessIterator1 __last1, | |
| 3658 | _RandomAccessIterator2 __first2, | |
| 3659 | _RandomAccessIterator2 __last2, | |
| 3660 | _Tp* __result, | |
| 3661 | _Compare __comp) { | |
| 3662 | return __pstl::__utils::__set_difference_construct( | |
| 3663 | __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); | |
| 3664 | }); | |
| 3665 | ||
| 3666 | // use serial algorithm | |
| 3667 | return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3668 | } | |
| 3669 | ||
| 3670 | //------------------------------------------------------------------------ | |
| 3671 | // set_symmetric_difference | |
| 3672 | //------------------------------------------------------------------------ | |
| 3673 | ||
| 3674 | template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare> | |
| 3675 | _OutputIterator __brick_set_symmetric_difference( | |
| 3676 | _ForwardIterator1 __first1, | |
| 3677 | _ForwardIterator1 __last1, | |
| 3678 | _ForwardIterator2 __first2, | |
| 3679 | _ForwardIterator2 __last2, | |
| 3680 | _OutputIterator __result, | |
| 3681 | _Compare __comp, | |
| 3682 | /*__is_vector=*/std::false_type) noexcept { | |
| 3683 | return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3684 | } | |
| 3685 | ||
| 3686 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare> | |
| 3687 | _RandomAccessIterator3 __brick_set_symmetric_difference( | |
| 3688 | _RandomAccessIterator1 __first1, | |
| 3689 | _RandomAccessIterator1 __last1, | |
| 3690 | _RandomAccessIterator2 __first2, | |
| 3691 | _RandomAccessIterator2 __last2, | |
| 3692 | _RandomAccessIterator3 __result, | |
| 3693 | _Compare __comp, | |
| 3694 | /*__is_vector=*/std::true_type) noexcept { | |
| 3695 | // TODO: vectorize | |
| 3696 | return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3697 | } | |
| 3698 | ||
| 3699 | template <class _Tag, | |
| 3700 | class _ExecutionPolicy, | |
| 3701 | class _ForwardIterator1, | |
| 3702 | class _ForwardIterator2, | |
| 3703 | class _OutputIterator, | |
| 3704 | class _Compare> | |
| 3705 | _OutputIterator __pattern_set_symmetric_difference( | |
| 3706 | _Tag, | |
| 3707 | _ExecutionPolicy&&, | |
| 3708 | _ForwardIterator1 __first1, | |
| 3709 | _ForwardIterator1 __last1, | |
| 3710 | _ForwardIterator2 __first2, | |
| 3711 | _ForwardIterator2 __last2, | |
| 3712 | _OutputIterator __result, | |
| 3713 | _Compare __comp) noexcept { | |
| 3714 | return __internal::__brick_set_symmetric_difference( | |
| 3715 | __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); | |
| 3716 | } | |
| 3717 | ||
| 3718 | template <class _IsVector, | |
| 3719 | class _ExecutionPolicy, | |
| 3720 | class _RandomAccessIterator1, | |
| 3721 | class _RandomAccessIterator2, | |
| 3722 | class _RandomAccessIterator3, | |
| 3723 | class _Compare> | |
| 3724 | _RandomAccessIterator3 __pattern_set_symmetric_difference( | |
| 3725 | __parallel_tag<_IsVector> __tag, | |
| 3726 | _ExecutionPolicy&& __exec, | |
| 3727 | _RandomAccessIterator1 __first1, | |
| 3728 | _RandomAccessIterator1 __last1, | |
| 3729 | _RandomAccessIterator2 __first2, | |
| 3730 | _RandomAccessIterator2 __last2, | |
| 3731 | _RandomAccessIterator3 __result, | |
| 3732 | _Compare __comp) { | |
| 3733 | const auto __n1 = __last1 - __first1; | |
| 3734 | const auto __n2 = __last2 - __first2; | |
| 3735 | ||
| 3736 | // use serial algorithm | |
| 3737 | if (__n1 + __n2 <= __set_algo_cut_off) | |
| 3738 | return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); | |
| 3739 | ||
| 3740 | typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; | |
| 3741 | return __internal::__parallel_set_union_op( | |
| 3742 | __tag, | |
| 3743 | std::forward<_ExecutionPolicy>(__exec), | |
| 3744 | __first1, | |
| 3745 | __last1, | |
| 3746 | __first2, | |
| 3747 | __last2, | |
| 3748 | __result, | |
| 3749 | __comp, | |
| 3750 | [](_RandomAccessIterator1 __first1, | |
| 3751 | _RandomAccessIterator1 __last1, | |
| 3752 | _RandomAccessIterator2 __first2, | |
| 3753 | _RandomAccessIterator2 __last2, | |
| 3754 | _Tp* __result, | |
| 3755 | _Compare __comp) { | |
| 3756 | return __pstl::__utils::__set_symmetric_difference_construct( | |
| 3757 | __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); | |
| 3758 | }); | |
| 3759 | } | |
| 3760 | ||
| 3761 | //------------------------------------------------------------------------ | |
| 3762 | // is_heap_until | |
| 3763 | //------------------------------------------------------------------------ | |
| 3764 | ||
| 3765 | template <class _RandomAccessIterator, class _Compare> | |
| 3766 | _RandomAccessIterator __brick_is_heap_until( | |
| 3767 | _RandomAccessIterator __first, | |
| 3768 | _RandomAccessIterator __last, | |
| 3769 | _Compare __comp, | |
| 3770 | /* __is_vector = */ std::false_type) noexcept { | |
| 3771 | return std::is_heap_until(__first, __last, __comp); | |
| 3772 | } | |
| 3773 | ||
| 3774 | template <class _RandomAccessIterator, class _Compare> | |
| 3775 | _RandomAccessIterator __brick_is_heap_until( | |
| 3776 | _RandomAccessIterator __first, | |
| 3777 | _RandomAccessIterator __last, | |
| 3778 | _Compare __comp, | |
| 3779 | /* __is_vector = */ std::true_type) noexcept { | |
| 3780 | if (__last - __first < 2) | |
| 3781 | return __last; | |
| 3782 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; | |
| 3783 | return __unseq_backend::__simd_first( | |
| 3784 | __first, _SizeType(0), __last - __first, [&__comp](_RandomAccessIterator __it, _SizeType __i) { | |
| 3785 | return __comp(__it[(__i - 1) / 2], __it[__i]); | |
| 3786 | }); | |
| 3787 | } | |
| 3788 | ||
| 3789 | template <class _Tag, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 3790 | _RandomAccessIterator __pattern_is_heap_until( | |
| 3791 | _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept { | |
| 3792 | return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{}); | |
| 3793 | } | |
| 3794 | ||
| 3795 | template <class _RandomAccessIterator, class _DifferenceType, class _Compare> | |
| 3796 | _RandomAccessIterator __is_heap_until_local( | |
| 3797 | _RandomAccessIterator __first, | |
| 3798 | _DifferenceType __begin, | |
| 3799 | _DifferenceType __end, | |
| 3800 | _Compare __comp, | |
| 3801 | /* __is_vector = */ std::false_type) noexcept { | |
| 3802 | _DifferenceType __i = __begin; | |
| 3803 | for (; __i < __end; ++__i) { | |
| 3804 | if (__comp(__first[(__i - 1) / 2], __first[__i])) { | |
| 3805 | break; | |
| 3806 | } | |
| 3807 | } | |
| 3808 | return __first + __i; | |
| 3809 | } | |
| 3810 | ||
| 3811 | template <class _RandomAccessIterator, class _DifferenceType, class _Compare> | |
| 3812 | _RandomAccessIterator __is_heap_until_local( | |
| 3813 | _RandomAccessIterator __first, | |
| 3814 | _DifferenceType __begin, | |
| 3815 | _DifferenceType __end, | |
| 3816 | _Compare __comp, | |
| 3817 | /* __is_vector = */ std::true_type) noexcept { | |
| 3818 | return __unseq_backend::__simd_first( | |
| 3819 | __first, __begin, __end, [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { | |
| 3820 | return __comp(__it[(__i - 1) / 2], __it[__i]); | |
| 3821 | }); | |
| 3822 | } | |
| 3823 | ||
| 3824 | template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 3825 | _RandomAccessIterator __pattern_is_heap_until( | |
| 3826 | __parallel_tag<_IsVector> __tag, | |
| 3827 | _ExecutionPolicy&& __exec, | |
| 3828 | _RandomAccessIterator __first, | |
| 3829 | _RandomAccessIterator __last, | |
| 3830 | _Compare __comp) noexcept { | |
| 3831 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 3832 | ||
| 3833 | if (__last - __first < 2) | |
| 3834 | return __last; | |
| 3835 | ||
| 3836 | return __internal::__except_handler([&]() { | |
| 3837 | return __parallel_find( | |
| 3838 | __backend_tag{}, | |
| 3839 | std::forward<_ExecutionPolicy>(__exec), | |
| 3840 | __first, | |
| 3841 | __last, | |
| 3842 | [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { | |
| 3843 | return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, _IsVector{}); | |
| 3844 | }, | |
| 3845 | std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(), | |
| 3846 | /*is_first=*/true); | |
| 3847 | }); | |
| 3848 | } | |
| 3849 | ||
| 3850 | //------------------------------------------------------------------------ | |
| 3851 | // min_element | |
| 3852 | //------------------------------------------------------------------------ | |
| 3853 | ||
| 3854 | template <typename _ForwardIterator, typename _Compare> | |
| 3855 | _ForwardIterator __brick_min_element( | |
| 3856 | _ForwardIterator __first, | |
| 3857 | _ForwardIterator __last, | |
| 3858 | _Compare __comp, | |
| 3859 | /* __is_vector = */ std::false_type) noexcept { | |
| 3860 | return std::min_element(__first, __last, __comp); | |
| 3861 | } | |
| 3862 | ||
| 3863 | template <typename _RandomAccessIterator, typename _Compare> | |
| 3864 | _RandomAccessIterator __brick_min_element( | |
| 3865 | _RandomAccessIterator __first, | |
| 3866 | _RandomAccessIterator __last, | |
| 3867 | _Compare __comp, | |
| 3868 | /* __is_vector = */ std::true_type) noexcept { | |
| 3869 | #if defined(_PSTL_UDR_PRESENT) | |
| 3870 | return __unseq_backend::__simd_min_element(__first, __last - __first, __comp); | |
| 3871 | #else | |
| 3872 | return std::min_element(__first, __last, __comp); | |
| 3873 | #endif | |
| 3874 | } | |
| 3875 | ||
| 3876 | template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare> | |
| 3877 | _ForwardIterator __pattern_min_element( | |
| 3878 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept { | |
| 3879 | return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{}); | |
| 3880 | } | |
| 3881 | ||
| 3882 | template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare> | |
| 3883 | _RandomAccessIterator __pattern_min_element( | |
| 3884 | __parallel_tag<_IsVector> __tag, | |
| 3885 | _ExecutionPolicy&& __exec, | |
| 3886 | _RandomAccessIterator __first, | |
| 3887 | _RandomAccessIterator __last, | |
| 3888 | _Compare __comp) { | |
| 3889 | if (__first == __last) | |
| 3890 | return __last; | |
| 3891 | ||
| 3892 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 3893 | ||
| 3894 | return __internal::__except_handler([&]() { | |
| 3895 | return __par_backend::__parallel_reduce( | |
| 3896 | __backend_tag{}, | |
| 3897 | std::forward<_ExecutionPolicy>(__exec), | |
| 3898 | __first + 1, | |
| 3899 | __last, | |
| 3900 | __first, | |
| 3901 | [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __init) | |
| 3902 | -> _RandomAccessIterator { | |
| 3903 | const _RandomAccessIterator subresult = __internal::__brick_min_element(__begin, __end, __comp, _IsVector{}); | |
| 3904 | return __internal::__cmp_iterators_by_values(__init, subresult, __comp); | |
| 3905 | }, | |
| 3906 | [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator { | |
| 3907 | return __internal::__cmp_iterators_by_values(__it1, __it2, __comp); | |
| 3908 | }); | |
| 3909 | }); | |
| 3910 | } | |
| 3911 | ||
| 3912 | //------------------------------------------------------------------------ | |
| 3913 | // minmax_element | |
| 3914 | //------------------------------------------------------------------------ | |
| 3915 | ||
| 3916 | template <typename _ForwardIterator, typename _Compare> | |
| 3917 | std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element( | |
| 3918 | _ForwardIterator __first, | |
| 3919 | _ForwardIterator __last, | |
| 3920 | _Compare __comp, | |
| 3921 | /* __is_vector = */ std::false_type) noexcept { | |
| 3922 | return std::minmax_element(__first, __last, __comp); | |
| 3923 | } | |
| 3924 | ||
| 3925 | template <typename _RandomAccessIterator, typename _Compare> | |
| 3926 | std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element( | |
| 3927 | _RandomAccessIterator __first, | |
| 3928 | _RandomAccessIterator __last, | |
| 3929 | _Compare __comp, | |
| 3930 | /* __is_vector = */ std::true_type) noexcept { | |
| 3931 | #if defined(_PSTL_UDR_PRESENT) | |
| 3932 | return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp); | |
| 3933 | #else | |
| 3934 | return std::minmax_element(__first, __last, __comp); | |
| 3935 | #endif | |
| 3936 | } | |
| 3937 | ||
| 3938 | template <typename _Tag, typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare> | |
| 3939 | std::pair<_ForwardIterator, _ForwardIterator> __pattern_minmax_element( | |
| 3940 | _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept { | |
| 3941 | return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{}); | |
| 3942 | } | |
| 3943 | ||
| 3944 | template <typename _IsVector, typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare> | |
| 3945 | std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element( | |
| 3946 | __parallel_tag<_IsVector> __tag, | |
| 3947 | _ExecutionPolicy&& __exec, | |
| 3948 | _RandomAccessIterator __first, | |
| 3949 | _RandomAccessIterator __last, | |
| 3950 | _Compare __comp) { | |
| 3951 | if (__first == __last) | |
| 3952 | return std::make_pair(__first, __first); | |
| 3953 | ||
| 3954 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 3955 | ||
| 3956 | return __internal::__except_handler([&]() { | |
| 3957 | typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result; | |
| 3958 | ||
| 3959 | return __par_backend::__parallel_reduce( | |
| 3960 | __backend_tag{}, | |
| 3961 | std::forward<_ExecutionPolicy>(__exec), | |
| 3962 | __first + 1, | |
| 3963 | __last, | |
| 3964 | std::make_pair(__first, __first), | |
| 3965 | [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result { | |
| 3966 | const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{}); | |
| 3967 | return std::make_pair( | |
| 3968 | __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp), | |
| 3969 | __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp))); | |
| 3970 | }, | |
| 3971 | [=](_Result __p1, _Result __p2) -> _Result { | |
| 3972 | return std::make_pair(__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp), | |
| 3973 | __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp))); | |
| 3974 | }); | |
| 3975 | }); | |
| 3976 | } | |
| 3977 | ||
| 3978 | //------------------------------------------------------------------------ | |
| 3979 | // mismatch | |
| 3980 | //------------------------------------------------------------------------ | |
| 3981 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 3982 | std::pair<_ForwardIterator1, _ForwardIterator2> __mismatch_serial( | |
| 3983 | _ForwardIterator1 __first1, | |
| 3984 | _ForwardIterator1 __last1, | |
| 3985 | _ForwardIterator2 __first2, | |
| 3986 | _ForwardIterator2 __last2, | |
| 3987 | _BinaryPredicate __pred) { | |
| 3988 | return std::mismatch(__first1, __last1, __first2, __last2, __pred); | |
| 3989 | } | |
| 3990 | ||
| 3991 | template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 3992 | std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch( | |
| 3993 | _ForwardIterator1 __first1, | |
| 3994 | _ForwardIterator1 __last1, | |
| 3995 | _ForwardIterator2 __first2, | |
| 3996 | _ForwardIterator2 __last2, | |
| 3997 | _Predicate __pred, | |
| 3998 | /* __is_vector = */ std::false_type) noexcept { | |
| 3999 | return __mismatch_serial(__first1, __last1, __first2, __last2, __pred); | |
| 4000 | } | |
| 4001 | ||
| 4002 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate> | |
| 4003 | std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch( | |
| 4004 | _RandomAccessIterator1 __first1, | |
| 4005 | _RandomAccessIterator1 __last1, | |
| 4006 | _RandomAccessIterator2 __first2, | |
| 4007 | _RandomAccessIterator2 __last2, | |
| 4008 | _Predicate __pred, | |
| 4009 | /* __is_vector = */ std::true_type) noexcept { | |
| 4010 | auto __n = std::min(__last1 - __first1, __last2 - __first2); | |
| 4011 | return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred)); | |
| 4012 | } | |
| 4013 | ||
| 4014 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 4015 | std::pair<_ForwardIterator1, _ForwardIterator2> __pattern_mismatch( | |
| 4016 | _Tag, | |
| 4017 | _ExecutionPolicy&&, | |
| 4018 | _ForwardIterator1 __first1, | |
| 4019 | _ForwardIterator1 __last1, | |
| 4020 | _ForwardIterator2 __first2, | |
| 4021 | _ForwardIterator2 __last2, | |
| 4022 | _Predicate __pred) noexcept { | |
| 4023 | return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{}); | |
| 4024 | } | |
| 4025 | ||
| 4026 | template <class _IsVector, | |
| 4027 | class _ExecutionPolicy, | |
| 4028 | class _RandomAccessIterator1, | |
| 4029 | class _RandomAccessIterator2, | |
| 4030 | class _Predicate> | |
| 4031 | std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch( | |
| 4032 | __parallel_tag<_IsVector> __tag, | |
| 4033 | _ExecutionPolicy&& __exec, | |
| 4034 | _RandomAccessIterator1 __first1, | |
| 4035 | _RandomAccessIterator1 __last1, | |
| 4036 | _RandomAccessIterator2 __first2, | |
| 4037 | _RandomAccessIterator2 __last2, | |
| 4038 | _Predicate __pred) noexcept { | |
| 4039 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 4040 | ||
| 4041 | return __internal::__except_handler([&]() { | |
| 4042 | auto __n = std::min(__last1 - __first1, __last2 - __first2); | |
| 4043 | auto __result = __internal::__parallel_find( | |
| 4044 | __backend_tag{}, | |
| 4045 | std::forward<_ExecutionPolicy>(__exec), | |
| 4046 | __first1, | |
| 4047 | __first1 + __n, | |
| 4048 | [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 4049 | return __internal::__brick_mismatch( | |
| 4050 | __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __pred, _IsVector{}) | |
| 4051 | .first; | |
| 4052 | }, | |
| 4053 | std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), | |
| 4054 | /*is_first=*/true); | |
| 4055 | return std::make_pair(__result, __first2 + (__result - __first1)); | |
| 4056 | }); | |
| 4057 | } | |
| 4058 | ||
| 4059 | //------------------------------------------------------------------------ | |
| 4060 | // lexicographical_compare | |
| 4061 | //------------------------------------------------------------------------ | |
| 4062 | ||
| 4063 | template <class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 4064 | bool __brick_lexicographical_compare( | |
| 4065 | _ForwardIterator1 __first1, | |
| 4066 | _ForwardIterator1 __last1, | |
| 4067 | _ForwardIterator2 __first2, | |
| 4068 | _ForwardIterator2 __last2, | |
| 4069 | _Compare __comp, | |
| 4070 | /* __is_vector = */ std::false_type) noexcept { | |
| 4071 | return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp); | |
| 4072 | } | |
| 4073 | ||
| 4074 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Compare> | |
| 4075 | bool __brick_lexicographical_compare( | |
| 4076 | _RandomAccessIterator1 __first1, | |
| 4077 | _RandomAccessIterator1 __last1, | |
| 4078 | _RandomAccessIterator2 __first2, | |
| 4079 | _RandomAccessIterator2 __last2, | |
| 4080 | _Compare __comp, | |
| 4081 | /* __is_vector = */ std::true_type) noexcept { | |
| 4082 | if (__first2 == __last2) { // if second sequence is empty | |
| 4083 | return false; | |
| 4084 | } else if (__first1 == __last1) { // if first sequence is empty | |
| 4085 | return true; | |
| 4086 | } else { | |
| 4087 | typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1; | |
| 4088 | typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2; | |
| 4089 | --__last1; | |
| 4090 | --__last2; | |
| 4091 | auto __n = std::min(__last1 - __first1, __last2 - __first2); | |
| 4092 | std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first( | |
| 4093 | __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable { | |
| 4094 | return __comp(__x, __y) || __comp(__y, __x); | |
| 4095 | }); | |
| 4096 | ||
| 4097 | if (__result.first == __last1 && __result.second != __last2) { // if first sequence shorter than second | |
| 4098 | return !__comp(*__result.second, *__result.first); | |
| 4099 | } else { // if second sequence shorter than first or both have the same number of elements | |
| 4100 | return __comp(*__result.first, *__result.second); | |
| 4101 | } | |
| 4102 | } | |
| 4103 | } | |
| 4104 | ||
| 4105 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 4106 | bool __pattern_lexicographical_compare( | |
| 4107 | _Tag, | |
| 4108 | _ExecutionPolicy&&, | |
| 4109 | _ForwardIterator1 __first1, | |
| 4110 | _ForwardIterator1 __last1, | |
| 4111 | _ForwardIterator2 __first2, | |
| 4112 | _ForwardIterator2 __last2, | |
| 4113 | _Compare __comp) noexcept { | |
| 4114 | return __internal::__brick_lexicographical_compare( | |
| 4115 | __first1, __last1, __first2, __last2, __comp, typename _Tag::__is_vector{}); | |
| 4116 | } | |
| 4117 | ||
| 4118 | template <class _IsVector, | |
| 4119 | class _ExecutionPolicy, | |
| 4120 | class _RandomAccessIterator1, | |
| 4121 | class _RandomAccessIterator2, | |
| 4122 | class _Compare> | |
| 4123 | bool __pattern_lexicographical_compare( | |
| 4124 | __parallel_tag<_IsVector> __tag, | |
| 4125 | _ExecutionPolicy&& __exec, | |
| 4126 | _RandomAccessIterator1 __first1, | |
| 4127 | _RandomAccessIterator1 __last1, | |
| 4128 | _RandomAccessIterator2 __first2, | |
| 4129 | _RandomAccessIterator2 __last2, | |
| 4130 | _Compare __comp) noexcept { | |
| 4131 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 4132 | ||
| 4133 | if (__first2 == __last2) { // if second sequence is empty | |
| 4134 | return false; | |
| 4135 | } else if (__first1 == __last1) { // if first sequence is empty | |
| 4136 | return true; | |
| 4137 | } else { | |
| 4138 | typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1; | |
| 4139 | typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2; | |
| 4140 | --__last1; | |
| 4141 | --__last2; | |
| 4142 | auto __n = std::min(__last1 - __first1, __last2 - __first2); | |
| 4143 | auto __result = __internal::__parallel_find( | |
| 4144 | __backend_tag{}, | |
| 4145 | std::forward<_ExecutionPolicy>(__exec), | |
| 4146 | __first1, | |
| 4147 | __first1 + __n, | |
| 4148 | [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { | |
| 4149 | return __internal::__brick_mismatch( | |
| 4150 | __i, | |
| 4151 | __j, | |
| 4152 | __first2 + (__i - __first1), | |
| 4153 | __first2 + (__j - __first1), | |
| 4154 | [&__comp](const _RefType1 __x, const _RefType2 __y) { | |
| 4155 | return !__comp(__x, __y) && !__comp(__y, __x); | |
| 4156 | }, | |
| 4157 | _IsVector{}) | |
| 4158 | .first; | |
| 4159 | }, | |
| 4160 | std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), | |
| 4161 | /*is_first=*/true); | |
| 4162 | ||
| 4163 | if (__result == __last1 && __first2 + (__result - __first1) != __last2) { // if first sequence shorter than second | |
| 4164 | return !__comp(*(__first2 + (__result - __first1)), *__result); | |
| 4165 | } else { // if second sequence shorter than first or both have the same number of elements | |
| 4166 | return __comp(*__result, *(__first2 + (__result - __first1))); | |
| 4167 | } | |
| 4168 | } | |
| 4169 | } | |
| 4170 | ||
| 4171 | } // namespace __internal | |
| 4172 | } // namespace __pstl | |
| 4173 | ||
| 4174 | #endif /* _PSTL_ALGORITHM_IMPL_H */ |
lib/libcxx/include/__pstl/internal/execution_defs.h created+76| ... | ... | @@ -0,0 +1,76 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_EXECUTION_POLICY_DEFS_H | |
| 11 | #define _PSTL_EXECUTION_POLICY_DEFS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__type_traits/decay.h> | |
| 15 | #include <__type_traits/enable_if.h> | |
| 16 | #include <__type_traits/integral_constant.h> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 19 | ||
| 20 | namespace __pstl { | |
| 21 | namespace execution { | |
| 22 | inline namespace v1 { | |
| 23 | ||
| 24 | // 2.4, Sequential execution policy | |
| 25 | class sequenced_policy {}; | |
| 26 | ||
| 27 | // 2.5, Parallel execution policy | |
| 28 | class parallel_policy {}; | |
| 29 | ||
| 30 | // 2.6, Parallel+Vector execution policy | |
| 31 | class parallel_unsequenced_policy {}; | |
| 32 | ||
| 33 | class unsequenced_policy {}; | |
| 34 | ||
| 35 | // 2.8, Execution policy objects | |
| 36 | constexpr sequenced_policy seq{}; | |
| 37 | constexpr parallel_policy par{}; | |
| 38 | constexpr parallel_unsequenced_policy par_unseq{}; | |
| 39 | constexpr unsequenced_policy unseq{}; | |
| 40 | ||
| 41 | // 2.3, Execution policy type trait | |
| 42 | template <class> | |
| 43 | struct is_execution_policy : std::false_type {}; | |
| 44 | ||
| 45 | template <> | |
| 46 | struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type {}; | |
| 47 | template <> | |
| 48 | struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type {}; | |
| 49 | template <> | |
| 50 | struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type {}; | |
| 51 | template <> | |
| 52 | struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type {}; | |
| 53 | ||
| 54 | template <class _Tp> | |
| 55 | constexpr bool is_execution_policy_v = __pstl::execution::is_execution_policy<_Tp>::value; | |
| 56 | } // namespace v1 | |
| 57 | } // namespace execution | |
| 58 | ||
| 59 | namespace __internal { | |
| 60 | template <class _ExecPolicy, class _Tp> | |
| 61 | using __enable_if_execution_policy = | |
| 62 | typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<_ExecPolicy>::type>::value, | |
| 63 | _Tp>::type; | |
| 64 | ||
| 65 | template <class _IsVector> | |
| 66 | struct __serial_tag; | |
| 67 | template <class _IsVector> | |
| 68 | struct __parallel_tag; | |
| 69 | ||
| 70 | } // namespace __internal | |
| 71 | ||
| 72 | } // namespace __pstl | |
| 73 | ||
| 74 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 75 | ||
| 76 | #endif /* _PSTL_EXECUTION_POLICY_DEFS_H */ |
lib/libcxx/include/__pstl/internal/execution_impl.h created+97| ... | ... | @@ -0,0 +1,97 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_EXECUTION_IMPL_H | |
| 11 | #define _PSTL_EXECUTION_IMPL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__iterator/iterator_traits.h> | |
| 15 | #include <__type_traits/conditional.h> | |
| 16 | #include <__type_traits/conjunction.h> | |
| 17 | #include <__type_traits/decay.h> | |
| 18 | #include <__type_traits/integral_constant.h> | |
| 19 | #include <__type_traits/is_base_of.h> | |
| 20 | ||
| 21 | #include <__pstl/internal/execution_defs.h> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 24 | ||
| 25 | namespace __pstl { | |
| 26 | namespace __internal { | |
| 27 | ||
| 28 | template <typename _IteratorTag, typename... _IteratorTypes> | |
| 29 | using __are_iterators_of = std::conjunction< | |
| 30 | std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>; | |
| 31 | ||
| 32 | template <typename... _IteratorTypes> | |
| 33 | using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>; | |
| 34 | ||
| 35 | struct __serial_backend_tag {}; | |
| 36 | struct __tbb_backend_tag {}; | |
| 37 | struct __openmp_backend_tag {}; | |
| 38 | ||
| 39 | # if defined(_PSTL_PAR_BACKEND_TBB) | |
| 40 | using __par_backend_tag = __tbb_backend_tag; | |
| 41 | # elif defined(_PSTL_PAR_BACKEND_OPENMP) | |
| 42 | using __par_backend_tag = __openmp_backend_tag; | |
| 43 | # elif defined(_PSTL_PAR_BACKEND_SERIAL) | |
| 44 | using __par_backend_tag = __serial_backend_tag; | |
| 45 | # else | |
| 46 | # error "A parallel backend must be specified"; | |
| 47 | # endif | |
| 48 | ||
| 49 | template <class _IsVector> | |
| 50 | struct __serial_tag { | |
| 51 | using __is_vector = _IsVector; | |
| 52 | }; | |
| 53 | ||
| 54 | template <class _IsVector> | |
| 55 | struct __parallel_tag { | |
| 56 | using __is_vector = _IsVector; | |
| 57 | // backend tag can be change depending on | |
| 58 | // TBB availability in the environment | |
| 59 | using __backend_tag = __par_backend_tag; | |
| 60 | }; | |
| 61 | ||
| 62 | template <class _IsVector, class... _IteratorTypes> | |
| 63 | using __tag_type = | |
| 64 | typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value, | |
| 65 | __parallel_tag<_IsVector>, | |
| 66 | __serial_tag<_IsVector>>::type; | |
| 67 | ||
| 68 | template <class... _IteratorTypes> | |
| 69 | _LIBCPP_HIDE_FROM_ABI __serial_tag</*_IsVector = */ std::false_type> | |
| 70 | __select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) { | |
| 71 | return {}; | |
| 72 | } | |
| 73 | ||
| 74 | template <class... _IteratorTypes> | |
| 75 | _LIBCPP_HIDE_FROM_ABI __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>> | |
| 76 | __select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) { | |
| 77 | return {}; | |
| 78 | } | |
| 79 | ||
| 80 | template <class... _IteratorTypes> | |
| 81 | _LIBCPP_HIDE_FROM_ABI __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...> | |
| 82 | __select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) { | |
| 83 | return {}; | |
| 84 | } | |
| 85 | ||
| 86 | template <class... _IteratorTypes> | |
| 87 | _LIBCPP_HIDE_FROM_ABI __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...> | |
| 88 | __select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) { | |
| 89 | return {}; | |
| 90 | } | |
| 91 | ||
| 92 | } // namespace __internal | |
| 93 | } // namespace __pstl | |
| 94 | ||
| 95 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 96 | ||
| 97 | #endif /* _PSTL_EXECUTION_IMPL_H */ |
lib/libcxx/include/__pstl/internal/glue_algorithm_defs.h created+655| ... | ... | @@ -0,0 +1,655 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_ALGORITHM_DEFS_H | |
| 11 | #define _PSTL_GLUE_ALGORITHM_DEFS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <functional> | |
| 15 | #include <iterator> | |
| 16 | ||
| 17 | #include "execution_defs.h" | |
| 18 | ||
| 19 | namespace std { | |
| 20 | ||
| 21 | // [alg.find.end] | |
| 22 | ||
| 23 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 24 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 25 | find_end(_ExecutionPolicy&& __exec, | |
| 26 | _ForwardIterator1 __first, | |
| 27 | _ForwardIterator1 __last, | |
| 28 | _ForwardIterator2 __s_first, | |
| 29 | _ForwardIterator2 __s_last, | |
| 30 | _BinaryPredicate __pred); | |
| 31 | ||
| 32 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 33 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 34 | find_end(_ExecutionPolicy&& __exec, | |
| 35 | _ForwardIterator1 __first, | |
| 36 | _ForwardIterator1 __last, | |
| 37 | _ForwardIterator2 __s_first, | |
| 38 | _ForwardIterator2 __s_last); | |
| 39 | ||
| 40 | // [alg.find_first_of] | |
| 41 | ||
| 42 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 43 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of( | |
| 44 | _ExecutionPolicy&& __exec, | |
| 45 | _ForwardIterator1 __first, | |
| 46 | _ForwardIterator1 __last, | |
| 47 | _ForwardIterator2 __s_first, | |
| 48 | _ForwardIterator2 __s_last, | |
| 49 | _BinaryPredicate __pred); | |
| 50 | ||
| 51 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 52 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 53 | find_first_of(_ExecutionPolicy&& __exec, | |
| 54 | _ForwardIterator1 __first, | |
| 55 | _ForwardIterator1 __last, | |
| 56 | _ForwardIterator2 __s_first, | |
| 57 | _ForwardIterator2 __s_last); | |
| 58 | ||
| 59 | // [alg.adjacent_find] | |
| 60 | ||
| 61 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 62 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 63 | adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 64 | ||
| 65 | template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 66 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 67 | adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred); | |
| 68 | ||
| 69 | // [alg.count] | |
| 70 | ||
| 71 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 72 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, | |
| 73 | typename iterator_traits<_ForwardIterator>::difference_type> | |
| 74 | count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value); | |
| 75 | ||
| 76 | template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 77 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, | |
| 78 | typename iterator_traits<_ForwardIterator>::difference_type> | |
| 79 | count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred); | |
| 80 | ||
| 81 | // [alg.search] | |
| 82 | ||
| 83 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 84 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 85 | search(_ExecutionPolicy&& __exec, | |
| 86 | _ForwardIterator1 __first, | |
| 87 | _ForwardIterator1 __last, | |
| 88 | _ForwardIterator2 __s_first, | |
| 89 | _ForwardIterator2 __s_last, | |
| 90 | _BinaryPredicate __pred); | |
| 91 | ||
| 92 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 93 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 94 | search(_ExecutionPolicy&& __exec, | |
| 95 | _ForwardIterator1 __first, | |
| 96 | _ForwardIterator1 __last, | |
| 97 | _ForwardIterator2 __s_first, | |
| 98 | _ForwardIterator2 __s_last); | |
| 99 | ||
| 100 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 101 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 102 | search_n(_ExecutionPolicy&& __exec, | |
| 103 | _ForwardIterator __first, | |
| 104 | _ForwardIterator __last, | |
| 105 | _Size __count, | |
| 106 | const _Tp& __value, | |
| 107 | _BinaryPredicate __pred); | |
| 108 | ||
| 109 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> | |
| 110 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n( | |
| 111 | _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value); | |
| 112 | ||
| 113 | // [alg.copy] | |
| 114 | ||
| 115 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 116 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 117 | copy_if(_ExecutionPolicy&& __exec, | |
| 118 | _ForwardIterator1 __first, | |
| 119 | _ForwardIterator1 __last, | |
| 120 | _ForwardIterator2 result, | |
| 121 | _Predicate __pred); | |
| 122 | ||
| 123 | // [alg.swap] | |
| 124 | ||
| 125 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 126 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges( | |
| 127 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); | |
| 128 | ||
| 129 | // [alg.replace] | |
| 130 | ||
| 131 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp> | |
| 132 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 133 | replace_if(_ExecutionPolicy&& __exec, | |
| 134 | _ForwardIterator __first, | |
| 135 | _ForwardIterator __last, | |
| 136 | _UnaryPredicate __pred, | |
| 137 | const _Tp& __new_value); | |
| 138 | ||
| 139 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 140 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 141 | replace(_ExecutionPolicy&& __exec, | |
| 142 | _ForwardIterator __first, | |
| 143 | _ForwardIterator __last, | |
| 144 | const _Tp& __old_value, | |
| 145 | const _Tp& __new_value); | |
| 146 | ||
| 147 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp> | |
| 148 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy_if( | |
| 149 | _ExecutionPolicy&& __exec, | |
| 150 | _ForwardIterator1 __first, | |
| 151 | _ForwardIterator1 __last, | |
| 152 | _ForwardIterator2 __result, | |
| 153 | _UnaryPredicate __pred, | |
| 154 | const _Tp& __new_value); | |
| 155 | ||
| 156 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> | |
| 157 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy( | |
| 158 | _ExecutionPolicy&& __exec, | |
| 159 | _ForwardIterator1 __first, | |
| 160 | _ForwardIterator1 __last, | |
| 161 | _ForwardIterator2 __result, | |
| 162 | const _Tp& __old_value, | |
| 163 | const _Tp& __new_value); | |
| 164 | ||
| 165 | // [alg.generate] | |
| 166 | template <class _ExecutionPolicy, class _ForwardIterator, class _Generator> | |
| 167 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 168 | generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g); | |
| 169 | ||
| 170 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator> | |
| 171 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 172 | generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size count, _Generator __g); | |
| 173 | ||
| 174 | // [alg.remove] | |
| 175 | ||
| 176 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 177 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if( | |
| 178 | _ExecutionPolicy&& __exec, | |
| 179 | _ForwardIterator1 __first, | |
| 180 | _ForwardIterator1 __last, | |
| 181 | _ForwardIterator2 __result, | |
| 182 | _Predicate __pred); | |
| 183 | ||
| 184 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> | |
| 185 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 186 | remove_copy(_ExecutionPolicy&& __exec, | |
| 187 | _ForwardIterator1 __first, | |
| 188 | _ForwardIterator1 __last, | |
| 189 | _ForwardIterator2 __result, | |
| 190 | const _Tp& __value); | |
| 191 | ||
| 192 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 193 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 194 | remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred); | |
| 195 | ||
| 196 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 197 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 198 | remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value); | |
| 199 | ||
| 200 | // [alg.unique] | |
| 201 | ||
| 202 | template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 203 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 204 | unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred); | |
| 205 | ||
| 206 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 207 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 208 | unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 209 | ||
| 210 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 211 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 212 | unique_copy(_ExecutionPolicy&& __exec, | |
| 213 | _ForwardIterator1 __first, | |
| 214 | _ForwardIterator1 __last, | |
| 215 | _ForwardIterator2 __result, | |
| 216 | _BinaryPredicate __pred); | |
| 217 | ||
| 218 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 219 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 220 | unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result); | |
| 221 | ||
| 222 | // [alg.reverse] | |
| 223 | ||
| 224 | template <class _ExecutionPolicy, class _BidirectionalIterator> | |
| 225 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 226 | reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last); | |
| 227 | ||
| 228 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator> | |
| 229 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 230 | reverse_copy(_ExecutionPolicy&& __exec, | |
| 231 | _BidirectionalIterator __first, | |
| 232 | _BidirectionalIterator __last, | |
| 233 | _ForwardIterator __d_first); | |
| 234 | ||
| 235 | // [alg.rotate] | |
| 236 | ||
| 237 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 238 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 239 | rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last); | |
| 240 | ||
| 241 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 242 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 243 | rotate_copy(_ExecutionPolicy&& __exec, | |
| 244 | _ForwardIterator1 __first, | |
| 245 | _ForwardIterator1 __middle, | |
| 246 | _ForwardIterator1 __last, | |
| 247 | _ForwardIterator2 __result); | |
| 248 | ||
| 249 | // [alg.partitions] | |
| 250 | ||
| 251 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 252 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 253 | is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred); | |
| 254 | ||
| 255 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 256 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 257 | partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred); | |
| 258 | ||
| 259 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> | |
| 260 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition( | |
| 261 | _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred); | |
| 262 | ||
| 263 | template <class _ExecutionPolicy, | |
| 264 | class _ForwardIterator, | |
| 265 | class _ForwardIterator1, | |
| 266 | class _ForwardIterator2, | |
| 267 | class _UnaryPredicate> | |
| 268 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 269 | partition_copy(_ExecutionPolicy&& __exec, | |
| 270 | _ForwardIterator __first, | |
| 271 | _ForwardIterator __last, | |
| 272 | _ForwardIterator1 __out_true, | |
| 273 | _ForwardIterator2 __out_false, | |
| 274 | _UnaryPredicate __pred); | |
| 275 | ||
| 276 | // [alg.sort] | |
| 277 | ||
| 278 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 279 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 280 | sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp); | |
| 281 | ||
| 282 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 283 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 284 | sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 285 | ||
| 286 | // [stable.sort] | |
| 287 | ||
| 288 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 289 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 290 | stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp); | |
| 291 | ||
| 292 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 293 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 294 | stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 295 | ||
| 296 | // [mismatch] | |
| 297 | ||
| 298 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 299 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 300 | mismatch(_ExecutionPolicy&& __exec, | |
| 301 | _ForwardIterator1 __first1, | |
| 302 | _ForwardIterator1 __last1, | |
| 303 | _ForwardIterator2 __first2, | |
| 304 | _ForwardIterator2 __last2, | |
| 305 | _BinaryPredicate __pred); | |
| 306 | ||
| 307 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 308 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 309 | mismatch(_ExecutionPolicy&& __exec, | |
| 310 | _ForwardIterator1 __first1, | |
| 311 | _ForwardIterator1 __last1, | |
| 312 | _ForwardIterator2 __first2, | |
| 313 | _BinaryPredicate __pred); | |
| 314 | ||
| 315 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 316 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 317 | mismatch(_ExecutionPolicy&& __exec, | |
| 318 | _ForwardIterator1 __first1, | |
| 319 | _ForwardIterator1 __last1, | |
| 320 | _ForwardIterator2 __first2, | |
| 321 | _ForwardIterator2 __last2); | |
| 322 | ||
| 323 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 324 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 325 | mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); | |
| 326 | ||
| 327 | // [alg.equal] | |
| 328 | ||
| 329 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 330 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 331 | equal(_ExecutionPolicy&& __exec, | |
| 332 | _ForwardIterator1 __first1, | |
| 333 | _ForwardIterator1 __last1, | |
| 334 | _ForwardIterator2 __first2, | |
| 335 | _BinaryPredicate __p); | |
| 336 | ||
| 337 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 338 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 339 | equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); | |
| 340 | ||
| 341 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 342 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 343 | equal(_ExecutionPolicy&& __exec, | |
| 344 | _ForwardIterator1 __first1, | |
| 345 | _ForwardIterator1 __last1, | |
| 346 | _ForwardIterator2 __first2, | |
| 347 | _ForwardIterator2 __last2, | |
| 348 | _BinaryPredicate __p); | |
| 349 | ||
| 350 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 351 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 352 | equal(_ExecutionPolicy&& __exec, | |
| 353 | _ForwardIterator1 __first1, | |
| 354 | _ForwardIterator1 __last1, | |
| 355 | _ForwardIterator2 __first2, | |
| 356 | _ForwardIterator2 __last2); | |
| 357 | ||
| 358 | // [alg.move] | |
| 359 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 360 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 361 | move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first); | |
| 362 | ||
| 363 | // [partial.sort] | |
| 364 | ||
| 365 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 366 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 367 | partial_sort(_ExecutionPolicy&& __exec, | |
| 368 | _RandomAccessIterator __first, | |
| 369 | _RandomAccessIterator __middle, | |
| 370 | _RandomAccessIterator __last, | |
| 371 | _Compare __comp); | |
| 372 | ||
| 373 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 374 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 375 | partial_sort(_ExecutionPolicy&& __exec, | |
| 376 | _RandomAccessIterator __first, | |
| 377 | _RandomAccessIterator __middle, | |
| 378 | _RandomAccessIterator __last); | |
| 379 | ||
| 380 | // [partial.sort.copy] | |
| 381 | ||
| 382 | template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare> | |
| 383 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( | |
| 384 | _ExecutionPolicy&& __exec, | |
| 385 | _ForwardIterator __first, | |
| 386 | _ForwardIterator __last, | |
| 387 | _RandomAccessIterator __d_first, | |
| 388 | _RandomAccessIterator __d_last, | |
| 389 | _Compare __comp); | |
| 390 | ||
| 391 | template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator> | |
| 392 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( | |
| 393 | _ExecutionPolicy&& __exec, | |
| 394 | _ForwardIterator __first, | |
| 395 | _ForwardIterator __last, | |
| 396 | _RandomAccessIterator __d_first, | |
| 397 | _RandomAccessIterator __d_last); | |
| 398 | ||
| 399 | // [is.sorted] | |
| 400 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 401 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 402 | is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp); | |
| 403 | ||
| 404 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 405 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 406 | is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 407 | ||
| 408 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 409 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 410 | is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp); | |
| 411 | ||
| 412 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 413 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 414 | is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 415 | ||
| 416 | // [alg.nth.element] | |
| 417 | ||
| 418 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 419 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 420 | nth_element(_ExecutionPolicy&& __exec, | |
| 421 | _RandomAccessIterator __first, | |
| 422 | _RandomAccessIterator __nth, | |
| 423 | _RandomAccessIterator __last, | |
| 424 | _Compare __comp); | |
| 425 | ||
| 426 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 427 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 428 | nth_element(_ExecutionPolicy&& __exec, | |
| 429 | _RandomAccessIterator __first, | |
| 430 | _RandomAccessIterator __nth, | |
| 431 | _RandomAccessIterator __last); | |
| 432 | ||
| 433 | // [alg.merge] | |
| 434 | template <class _ExecutionPolicy, | |
| 435 | class _ForwardIterator1, | |
| 436 | class _ForwardIterator2, | |
| 437 | class _ForwardIterator, | |
| 438 | class _Compare> | |
| 439 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 440 | merge(_ExecutionPolicy&& __exec, | |
| 441 | _ForwardIterator1 __first1, | |
| 442 | _ForwardIterator1 __last1, | |
| 443 | _ForwardIterator2 __first2, | |
| 444 | _ForwardIterator2 __last2, | |
| 445 | _ForwardIterator __d_first, | |
| 446 | _Compare __comp); | |
| 447 | ||
| 448 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 449 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 450 | merge(_ExecutionPolicy&& __exec, | |
| 451 | _ForwardIterator1 __first1, | |
| 452 | _ForwardIterator1 __last1, | |
| 453 | _ForwardIterator2 __first2, | |
| 454 | _ForwardIterator2 __last2, | |
| 455 | _ForwardIterator __d_first); | |
| 456 | ||
| 457 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare> | |
| 458 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 459 | inplace_merge(_ExecutionPolicy&& __exec, | |
| 460 | _BidirectionalIterator __first, | |
| 461 | _BidirectionalIterator __middle, | |
| 462 | _BidirectionalIterator __last, | |
| 463 | _Compare __comp); | |
| 464 | ||
| 465 | template <class _ExecutionPolicy, class _BidirectionalIterator> | |
| 466 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 467 | inplace_merge(_ExecutionPolicy&& __exec, | |
| 468 | _BidirectionalIterator __first, | |
| 469 | _BidirectionalIterator __middle, | |
| 470 | _BidirectionalIterator __last); | |
| 471 | ||
| 472 | // [includes] | |
| 473 | ||
| 474 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 475 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 476 | includes(_ExecutionPolicy&& __exec, | |
| 477 | _ForwardIterator1 __first1, | |
| 478 | _ForwardIterator1 __last1, | |
| 479 | _ForwardIterator2 __first2, | |
| 480 | _ForwardIterator2 __last2, | |
| 481 | _Compare __comp); | |
| 482 | ||
| 483 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 484 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 485 | includes(_ExecutionPolicy&& __exec, | |
| 486 | _ForwardIterator1 __first1, | |
| 487 | _ForwardIterator1 __last1, | |
| 488 | _ForwardIterator2 __first2, | |
| 489 | _ForwardIterator2 __last2); | |
| 490 | ||
| 491 | // [set.union] | |
| 492 | ||
| 493 | template <class _ExecutionPolicy, | |
| 494 | class _ForwardIterator1, | |
| 495 | class _ForwardIterator2, | |
| 496 | class _ForwardIterator, | |
| 497 | class _Compare> | |
| 498 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 499 | set_union(_ExecutionPolicy&& __exec, | |
| 500 | _ForwardIterator1 __first1, | |
| 501 | _ForwardIterator1 __last1, | |
| 502 | _ForwardIterator2 __first2, | |
| 503 | _ForwardIterator2 __last2, | |
| 504 | _ForwardIterator __result, | |
| 505 | _Compare __comp); | |
| 506 | ||
| 507 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 508 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 509 | set_union(_ExecutionPolicy&& __exec, | |
| 510 | _ForwardIterator1 __first1, | |
| 511 | _ForwardIterator1 __last1, | |
| 512 | _ForwardIterator2 __first2, | |
| 513 | _ForwardIterator2 __last2, | |
| 514 | _ForwardIterator __result); | |
| 515 | ||
| 516 | // [set.intersection] | |
| 517 | ||
| 518 | template <class _ExecutionPolicy, | |
| 519 | class _ForwardIterator1, | |
| 520 | class _ForwardIterator2, | |
| 521 | class _ForwardIterator, | |
| 522 | class _Compare> | |
| 523 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( | |
| 524 | _ExecutionPolicy&& __exec, | |
| 525 | _ForwardIterator1 __first1, | |
| 526 | _ForwardIterator1 __last1, | |
| 527 | _ForwardIterator2 __first2, | |
| 528 | _ForwardIterator2 __last2, | |
| 529 | _ForwardIterator __result, | |
| 530 | _Compare __comp); | |
| 531 | ||
| 532 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 533 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( | |
| 534 | _ExecutionPolicy&& __exec, | |
| 535 | _ForwardIterator1 __first1, | |
| 536 | _ForwardIterator1 __last1, | |
| 537 | _ForwardIterator2 __first2, | |
| 538 | _ForwardIterator2 __last2, | |
| 539 | _ForwardIterator __result); | |
| 540 | ||
| 541 | // [set.difference] | |
| 542 | ||
| 543 | template <class _ExecutionPolicy, | |
| 544 | class _ForwardIterator1, | |
| 545 | class _ForwardIterator2, | |
| 546 | class _ForwardIterator, | |
| 547 | class _Compare> | |
| 548 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( | |
| 549 | _ExecutionPolicy&& __exec, | |
| 550 | _ForwardIterator1 __first1, | |
| 551 | _ForwardIterator1 __last1, | |
| 552 | _ForwardIterator2 __first2, | |
| 553 | _ForwardIterator2 __last2, | |
| 554 | _ForwardIterator __result, | |
| 555 | _Compare __comp); | |
| 556 | ||
| 557 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 558 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( | |
| 559 | _ExecutionPolicy&& __exec, | |
| 560 | _ForwardIterator1 __first1, | |
| 561 | _ForwardIterator1 __last1, | |
| 562 | _ForwardIterator2 __first2, | |
| 563 | _ForwardIterator2 __last2, | |
| 564 | _ForwardIterator __result); | |
| 565 | ||
| 566 | // [set.symmetric.difference] | |
| 567 | ||
| 568 | template <class _ExecutionPolicy, | |
| 569 | class _ForwardIterator1, | |
| 570 | class _ForwardIterator2, | |
| 571 | class _ForwardIterator, | |
| 572 | class _Compare> | |
| 573 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( | |
| 574 | _ExecutionPolicy&& __exec, | |
| 575 | _ForwardIterator1 __first1, | |
| 576 | _ForwardIterator1 __last1, | |
| 577 | _ForwardIterator2 __first2, | |
| 578 | _ForwardIterator2 __last2, | |
| 579 | _ForwardIterator result, | |
| 580 | _Compare __comp); | |
| 581 | ||
| 582 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 583 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( | |
| 584 | _ExecutionPolicy&& __exec, | |
| 585 | _ForwardIterator1 __first1, | |
| 586 | _ForwardIterator1 __last1, | |
| 587 | _ForwardIterator2 __first2, | |
| 588 | _ForwardIterator2 __last2, | |
| 589 | _ForwardIterator __result); | |
| 590 | ||
| 591 | // [is.heap] | |
| 592 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 593 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> | |
| 594 | is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp); | |
| 595 | ||
| 596 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 597 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> | |
| 598 | is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 599 | ||
| 600 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 601 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 602 | is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp); | |
| 603 | ||
| 604 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 605 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 606 | is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 607 | ||
| 608 | // [alg.min.max] | |
| 609 | ||
| 610 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 611 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 612 | min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp); | |
| 613 | ||
| 614 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 615 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 616 | min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 617 | ||
| 618 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 619 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 620 | max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp); | |
| 621 | ||
| 622 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 623 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 624 | max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 625 | ||
| 626 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 627 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> | |
| 628 | minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp); | |
| 629 | ||
| 630 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 631 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> | |
| 632 | minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 633 | ||
| 634 | // [alg.lex.comparison] | |
| 635 | ||
| 636 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 637 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( | |
| 638 | _ExecutionPolicy&& __exec, | |
| 639 | _ForwardIterator1 __first1, | |
| 640 | _ForwardIterator1 __last1, | |
| 641 | _ForwardIterator2 __first2, | |
| 642 | _ForwardIterator2 __last2, | |
| 643 | _Compare __comp); | |
| 644 | ||
| 645 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 646 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( | |
| 647 | _ExecutionPolicy&& __exec, | |
| 648 | _ForwardIterator1 __first1, | |
| 649 | _ForwardIterator1 __last1, | |
| 650 | _ForwardIterator2 __first2, | |
| 651 | _ForwardIterator2 __last2); | |
| 652 | ||
| 653 | } // namespace std | |
| 654 | ||
| 655 | #endif /* _PSTL_GLUE_ALGORITHM_DEFS_H */ |
lib/libcxx/include/__pstl/internal/glue_algorithm_impl.h created+972| ... | ... | @@ -0,0 +1,972 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_ALGORITHM_IMPL_H | |
| 11 | #define _PSTL_GLUE_ALGORITHM_IMPL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <functional> | |
| 15 | ||
| 16 | #include "algorithm_fwd.h" | |
| 17 | #include "execution_defs.h" | |
| 18 | #include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */ | |
| 19 | #include "utils.h" | |
| 20 | ||
| 21 | #include "execution_impl.h" | |
| 22 | ||
| 23 | namespace std { | |
| 24 | ||
| 25 | // [alg.find.end] | |
| 26 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 27 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 28 | find_end(_ExecutionPolicy&& __exec, | |
| 29 | _ForwardIterator1 __first, | |
| 30 | _ForwardIterator1 __last, | |
| 31 | _ForwardIterator2 __s_first, | |
| 32 | _ForwardIterator2 __s_last, | |
| 33 | _BinaryPredicate __pred) { | |
| 34 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); | |
| 35 | ||
| 36 | return __pstl::__internal::__pattern_find_end( | |
| 37 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); | |
| 38 | } | |
| 39 | ||
| 40 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 41 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 42 | find_end(_ExecutionPolicy&& __exec, | |
| 43 | _ForwardIterator1 __first, | |
| 44 | _ForwardIterator1 __last, | |
| 45 | _ForwardIterator2 __s_first, | |
| 46 | _ForwardIterator2 __s_last) { | |
| 47 | return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); | |
| 48 | } | |
| 49 | ||
| 50 | // [alg.find_first_of] | |
| 51 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 52 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of( | |
| 53 | _ExecutionPolicy&& __exec, | |
| 54 | _ForwardIterator1 __first, | |
| 55 | _ForwardIterator1 __last, | |
| 56 | _ForwardIterator2 __s_first, | |
| 57 | _ForwardIterator2 __s_last, | |
| 58 | _BinaryPredicate __pred) { | |
| 59 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); | |
| 60 | ||
| 61 | return __pstl::__internal::__pattern_find_first_of( | |
| 62 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); | |
| 63 | } | |
| 64 | ||
| 65 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 66 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 67 | find_first_of(_ExecutionPolicy&& __exec, | |
| 68 | _ForwardIterator1 __first, | |
| 69 | _ForwardIterator1 __last, | |
| 70 | _ForwardIterator2 __s_first, | |
| 71 | _ForwardIterator2 __s_last) { | |
| 72 | return std::find_first_of( | |
| 73 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); | |
| 74 | } | |
| 75 | ||
| 76 | // [alg.adjacent_find] | |
| 77 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 78 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 79 | adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 80 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 81 | ||
| 82 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 83 | return __pstl::__internal::__pattern_adjacent_find( | |
| 84 | __dispatch_tag, | |
| 85 | std::forward<_ExecutionPolicy>(__exec), | |
| 86 | __first, | |
| 87 | __last, | |
| 88 | std::equal_to<_ValueType>(), | |
| 89 | /*first_semantic*/ false); | |
| 90 | } | |
| 91 | ||
| 92 | template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 93 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 94 | adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { | |
| 95 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 96 | return __pstl::__internal::__pattern_adjacent_find( | |
| 97 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, /*first_semantic*/ false); | |
| 98 | } | |
| 99 | ||
| 100 | // [alg.count] | |
| 101 | ||
| 102 | // Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce | |
| 103 | // so that we do not have to include <numeric>. | |
| 104 | ||
| 105 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 106 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, | |
| 107 | typename iterator_traits<_ForwardIterator>::difference_type> | |
| 108 | count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 109 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 110 | ||
| 111 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 112 | return __pstl::__internal::__pattern_count( | |
| 113 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](const _ValueType& __x) { | |
| 114 | return __value == __x; | |
| 115 | }); | |
| 116 | } | |
| 117 | ||
| 118 | template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> | |
| 119 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, | |
| 120 | typename iterator_traits<_ForwardIterator>::difference_type> | |
| 121 | count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { | |
| 122 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 123 | return __pstl::__internal::__pattern_count( | |
| 124 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 125 | } | |
| 126 | ||
| 127 | // [alg.search] | |
| 128 | ||
| 129 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 130 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 131 | search(_ExecutionPolicy&& __exec, | |
| 132 | _ForwardIterator1 __first, | |
| 133 | _ForwardIterator1 __last, | |
| 134 | _ForwardIterator2 __s_first, | |
| 135 | _ForwardIterator2 __s_last, | |
| 136 | _BinaryPredicate __pred) { | |
| 137 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); | |
| 138 | ||
| 139 | return __pstl::__internal::__pattern_search( | |
| 140 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); | |
| 141 | } | |
| 142 | ||
| 143 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 144 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> | |
| 145 | search(_ExecutionPolicy&& __exec, | |
| 146 | _ForwardIterator1 __first, | |
| 147 | _ForwardIterator1 __last, | |
| 148 | _ForwardIterator2 __s_first, | |
| 149 | _ForwardIterator2 __s_last) { | |
| 150 | return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); | |
| 151 | } | |
| 152 | ||
| 153 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> | |
| 154 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 155 | search_n(_ExecutionPolicy&& __exec, | |
| 156 | _ForwardIterator __first, | |
| 157 | _ForwardIterator __last, | |
| 158 | _Size __count, | |
| 159 | const _Tp& __value, | |
| 160 | _BinaryPredicate __pred) { | |
| 161 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 162 | ||
| 163 | return __pstl::__internal::__pattern_search_n( | |
| 164 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred); | |
| 165 | } | |
| 166 | ||
| 167 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> | |
| 168 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n( | |
| 169 | _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { | |
| 170 | return std::search_n( | |
| 171 | std::forward<_ExecutionPolicy>(__exec), | |
| 172 | __first, | |
| 173 | __last, | |
| 174 | __count, | |
| 175 | __value, | |
| 176 | std::equal_to<typename iterator_traits<_ForwardIterator>::value_type>()); | |
| 177 | } | |
| 178 | ||
| 179 | // [alg.copy] | |
| 180 | ||
| 181 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 182 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 183 | copy_if(_ExecutionPolicy&& __exec, | |
| 184 | _ForwardIterator1 __first, | |
| 185 | _ForwardIterator1 __last, | |
| 186 | _ForwardIterator2 __result, | |
| 187 | _Predicate __pred) { | |
| 188 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 189 | ||
| 190 | return __pstl::__internal::__pattern_copy_if( | |
| 191 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred); | |
| 192 | } | |
| 193 | ||
| 194 | // [alg.swap] | |
| 195 | ||
| 196 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 197 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges( | |
| 198 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { | |
| 199 | typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; | |
| 200 | typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; | |
| 201 | ||
| 202 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 203 | ||
| 204 | return __pstl::__internal::__pattern_walk2( | |
| 205 | __dispatch_tag, | |
| 206 | std::forward<_ExecutionPolicy>(__exec), | |
| 207 | __first1, | |
| 208 | __last1, | |
| 209 | __first2, | |
| 210 | [](_ReferenceType1 __x, _ReferenceType2 __y) { | |
| 211 | using std::swap; | |
| 212 | swap(__x, __y); | |
| 213 | }); | |
| 214 | } | |
| 215 | ||
| 216 | // [alg.generate] | |
| 217 | template <class _ExecutionPolicy, class _ForwardIterator, class _Generator> | |
| 218 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 219 | generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) { | |
| 220 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 221 | ||
| 222 | __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __g); | |
| 223 | } | |
| 224 | ||
| 225 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator> | |
| 226 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 227 | generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) { | |
| 228 | if (__count <= 0) | |
| 229 | return __first; | |
| 230 | ||
| 231 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 232 | ||
| 233 | return __pstl::__internal::__pattern_generate_n( | |
| 234 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __count, __g); | |
| 235 | } | |
| 236 | ||
| 237 | // [alg.remove] | |
| 238 | ||
| 239 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> | |
| 240 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if( | |
| 241 | _ExecutionPolicy&& __exec, | |
| 242 | _ForwardIterator1 __first, | |
| 243 | _ForwardIterator1 __last, | |
| 244 | _ForwardIterator2 __result, | |
| 245 | _Predicate __pred) { | |
| 246 | return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred)); | |
| 247 | } | |
| 248 | ||
| 249 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> | |
| 250 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 251 | remove_copy(_ExecutionPolicy&& __exec, | |
| 252 | _ForwardIterator1 __first, | |
| 253 | _ForwardIterator1 __last, | |
| 254 | _ForwardIterator2 __result, | |
| 255 | const _Tp& __value) { | |
| 256 | return std::copy_if( | |
| 257 | std::forward<_ExecutionPolicy>(__exec), | |
| 258 | __first, | |
| 259 | __last, | |
| 260 | __result, | |
| 261 | __pstl::__internal::__not_equal_value<_Tp>(__value)); | |
| 262 | } | |
| 263 | ||
| 264 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 265 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 266 | remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { | |
| 267 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 268 | ||
| 269 | return __pstl::__internal::__pattern_remove_if( | |
| 270 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 271 | } | |
| 272 | ||
| 273 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 274 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 275 | remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 276 | return std::remove_if( | |
| 277 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__equal_value<_Tp>(__value)); | |
| 278 | } | |
| 279 | ||
| 280 | // [alg.unique] | |
| 281 | ||
| 282 | template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> | |
| 283 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 284 | unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { | |
| 285 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 286 | ||
| 287 | return __pstl::__internal::__pattern_unique( | |
| 288 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 289 | } | |
| 290 | ||
| 291 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 292 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 293 | unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 294 | return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>()); | |
| 295 | } | |
| 296 | ||
| 297 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 298 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 299 | unique_copy(_ExecutionPolicy&& __exec, | |
| 300 | _ForwardIterator1 __first, | |
| 301 | _ForwardIterator1 __last, | |
| 302 | _ForwardIterator2 __result, | |
| 303 | _BinaryPredicate __pred) { | |
| 304 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 305 | ||
| 306 | return __pstl::__internal::__pattern_unique_copy( | |
| 307 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred); | |
| 308 | } | |
| 309 | ||
| 310 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 311 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> unique_copy( | |
| 312 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { | |
| 313 | return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>()); | |
| 314 | } | |
| 315 | ||
| 316 | // [alg.reverse] | |
| 317 | ||
| 318 | template <class _ExecutionPolicy, class _BidirectionalIterator> | |
| 319 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 320 | reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) { | |
| 321 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 322 | ||
| 323 | __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last); | |
| 324 | } | |
| 325 | ||
| 326 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator> | |
| 327 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 328 | reverse_copy(_ExecutionPolicy&& __exec, | |
| 329 | _BidirectionalIterator __first, | |
| 330 | _BidirectionalIterator __last, | |
| 331 | _ForwardIterator __d_first) { | |
| 332 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); | |
| 333 | ||
| 334 | return __pstl::__internal::__pattern_reverse_copy( | |
| 335 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first); | |
| 336 | } | |
| 337 | ||
| 338 | // [alg.rotate] | |
| 339 | ||
| 340 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 341 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 342 | rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { | |
| 343 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 344 | ||
| 345 | return __pstl::__internal::__pattern_rotate( | |
| 346 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last); | |
| 347 | } | |
| 348 | ||
| 349 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 350 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 351 | rotate_copy(_ExecutionPolicy&& __exec, | |
| 352 | _ForwardIterator1 __first, | |
| 353 | _ForwardIterator1 __middle, | |
| 354 | _ForwardIterator1 __last, | |
| 355 | _ForwardIterator2 __result) { | |
| 356 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 357 | ||
| 358 | return __pstl::__internal::__pattern_rotate_copy( | |
| 359 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result); | |
| 360 | } | |
| 361 | ||
| 362 | // [alg.partitions] | |
| 363 | ||
| 364 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 365 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 366 | is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { | |
| 367 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 368 | return __pstl::__internal::__pattern_is_partitioned( | |
| 369 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 370 | } | |
| 371 | ||
| 372 | template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> | |
| 373 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 374 | partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { | |
| 375 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 376 | ||
| 377 | return __pstl::__internal::__pattern_partition( | |
| 378 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 379 | } | |
| 380 | ||
| 381 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> | |
| 382 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition( | |
| 383 | _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred) { | |
| 384 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 385 | return __pstl::__internal::__pattern_stable_partition( | |
| 386 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); | |
| 387 | } | |
| 388 | ||
| 389 | template <class _ExecutionPolicy, | |
| 390 | class _ForwardIterator, | |
| 391 | class _ForwardIterator1, | |
| 392 | class _ForwardIterator2, | |
| 393 | class _UnaryPredicate> | |
| 394 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 395 | partition_copy(_ExecutionPolicy&& __exec, | |
| 396 | _ForwardIterator __first, | |
| 397 | _ForwardIterator __last, | |
| 398 | _ForwardIterator1 __out_true, | |
| 399 | _ForwardIterator2 __out_false, | |
| 400 | _UnaryPredicate __pred) { | |
| 401 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false); | |
| 402 | ||
| 403 | return __pstl::__internal::__pattern_partition_copy( | |
| 404 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred); | |
| 405 | } | |
| 406 | ||
| 407 | // [alg.sort] | |
| 408 | ||
| 409 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 410 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 411 | sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 412 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 413 | ||
| 414 | typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 415 | return __pstl::__internal::__pattern_sort( | |
| 416 | __dispatch_tag, | |
| 417 | std::forward<_ExecutionPolicy>(__exec), | |
| 418 | __first, | |
| 419 | __last, | |
| 420 | __comp, | |
| 421 | typename std::is_move_constructible<_InputType>::type()); | |
| 422 | } | |
| 423 | ||
| 424 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 425 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 426 | sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { | |
| 427 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 428 | std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 429 | } | |
| 430 | ||
| 431 | // [stable.sort] | |
| 432 | ||
| 433 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 434 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 435 | stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 436 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 437 | ||
| 438 | return __pstl::__internal::__pattern_stable_sort( | |
| 439 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); | |
| 440 | } | |
| 441 | ||
| 442 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 443 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 444 | stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { | |
| 445 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 446 | std::stable_sort(__exec, __first, __last, std::less<_InputType>()); | |
| 447 | } | |
| 448 | ||
| 449 | // [mismatch] | |
| 450 | ||
| 451 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 452 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 453 | mismatch(_ExecutionPolicy&& __exec, | |
| 454 | _ForwardIterator1 __first1, | |
| 455 | _ForwardIterator1 __last1, | |
| 456 | _ForwardIterator2 __first2, | |
| 457 | _ForwardIterator2 __last2, | |
| 458 | _BinaryPredicate __pred) { | |
| 459 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 460 | ||
| 461 | return __pstl::__internal::__pattern_mismatch( | |
| 462 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred); | |
| 463 | } | |
| 464 | ||
| 465 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 466 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 467 | mismatch(_ExecutionPolicy&& __exec, | |
| 468 | _ForwardIterator1 __first1, | |
| 469 | _ForwardIterator1 __last1, | |
| 470 | _ForwardIterator2 __first2, | |
| 471 | _BinaryPredicate __pred) { | |
| 472 | return std::mismatch( | |
| 473 | __exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)), __pred); | |
| 474 | } | |
| 475 | ||
| 476 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 477 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 478 | mismatch(_ExecutionPolicy&& __exec, | |
| 479 | _ForwardIterator1 __first1, | |
| 480 | _ForwardIterator1 __last1, | |
| 481 | _ForwardIterator2 __first2, | |
| 482 | _ForwardIterator2 __last2) { | |
| 483 | return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>()); | |
| 484 | } | |
| 485 | ||
| 486 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 487 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> | |
| 488 | mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { | |
| 489 | // TODO: to get rid of "distance" | |
| 490 | return std::mismatch( | |
| 491 | std::forward<_ExecutionPolicy>(__exec), | |
| 492 | __first1, | |
| 493 | __last1, | |
| 494 | __first2, | |
| 495 | std::next(__first2, std::distance(__first1, __last1))); | |
| 496 | } | |
| 497 | ||
| 498 | // [alg.equal] | |
| 499 | ||
| 500 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 501 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 502 | equal(_ExecutionPolicy&& __exec, | |
| 503 | _ForwardIterator1 __first1, | |
| 504 | _ForwardIterator1 __last1, | |
| 505 | _ForwardIterator2 __first2, | |
| 506 | _BinaryPredicate __p) { | |
| 507 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 508 | ||
| 509 | return __pstl::__internal::__pattern_equal( | |
| 510 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p); | |
| 511 | } | |
| 512 | ||
| 513 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 514 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 515 | equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { | |
| 516 | return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>()); | |
| 517 | } | |
| 518 | ||
| 519 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 520 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 521 | equal(_ExecutionPolicy&& __exec, | |
| 522 | _ForwardIterator1 __first1, | |
| 523 | _ForwardIterator1 __last1, | |
| 524 | _ForwardIterator2 __first2, | |
| 525 | _ForwardIterator2 __last2, | |
| 526 | _BinaryPredicate __p) { | |
| 527 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 528 | ||
| 529 | return __pstl::__internal::__pattern_equal( | |
| 530 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p); | |
| 531 | } | |
| 532 | ||
| 533 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 534 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 535 | equal(_ExecutionPolicy&& __exec, | |
| 536 | _ForwardIterator1 __first1, | |
| 537 | _ForwardIterator1 __last1, | |
| 538 | _ForwardIterator2 __first2, | |
| 539 | _ForwardIterator2 __last2) { | |
| 540 | return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>()); | |
| 541 | } | |
| 542 | ||
| 543 | // [alg.move] | |
| 544 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 545 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> | |
| 546 | move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) { | |
| 547 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); | |
| 548 | ||
| 549 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 550 | ||
| 551 | return __pstl::__internal::__pattern_walk2_brick( | |
| 552 | __dispatch_tag, | |
| 553 | std::forward<_ExecutionPolicy>(__exec), | |
| 554 | __first, | |
| 555 | __last, | |
| 556 | __d_first, | |
| 557 | [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { | |
| 558 | return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{}); | |
| 559 | }); | |
| 560 | } | |
| 561 | ||
| 562 | // [partial.sort] | |
| 563 | ||
| 564 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 565 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 566 | partial_sort(_ExecutionPolicy&& __exec, | |
| 567 | _RandomAccessIterator __first, | |
| 568 | _RandomAccessIterator __middle, | |
| 569 | _RandomAccessIterator __last, | |
| 570 | _Compare __comp) { | |
| 571 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 572 | ||
| 573 | __pstl::__internal::__pattern_partial_sort( | |
| 574 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp); | |
| 575 | } | |
| 576 | ||
| 577 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 578 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 579 | partial_sort(_ExecutionPolicy&& __exec, | |
| 580 | _RandomAccessIterator __first, | |
| 581 | _RandomAccessIterator __middle, | |
| 582 | _RandomAccessIterator __last) { | |
| 583 | typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 584 | std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>()); | |
| 585 | } | |
| 586 | ||
| 587 | // [partial.sort.copy] | |
| 588 | ||
| 589 | template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare> | |
| 590 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( | |
| 591 | _ExecutionPolicy&& __exec, | |
| 592 | _ForwardIterator __first, | |
| 593 | _ForwardIterator __last, | |
| 594 | _RandomAccessIterator __d_first, | |
| 595 | _RandomAccessIterator __d_last, | |
| 596 | _Compare __comp) { | |
| 597 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); | |
| 598 | ||
| 599 | return __pstl::__internal::__pattern_partial_sort_copy( | |
| 600 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp); | |
| 601 | } | |
| 602 | ||
| 603 | template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator> | |
| 604 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( | |
| 605 | _ExecutionPolicy&& __exec, | |
| 606 | _ForwardIterator __first, | |
| 607 | _ForwardIterator __last, | |
| 608 | _RandomAccessIterator __d_first, | |
| 609 | _RandomAccessIterator __d_last) { | |
| 610 | return std::partial_sort_copy( | |
| 611 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, std::less<>()); | |
| 612 | } | |
| 613 | ||
| 614 | // [is.sorted] | |
| 615 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 616 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 617 | is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { | |
| 618 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 619 | const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find( | |
| 620 | __dispatch_tag, | |
| 621 | std::forward<_ExecutionPolicy>(__exec), | |
| 622 | __first, | |
| 623 | __last, | |
| 624 | __pstl::__internal::__reorder_pred<_Compare>(__comp), | |
| 625 | /*first_semantic*/ false); | |
| 626 | return __res == __last ? __last : std::next(__res); | |
| 627 | } | |
| 628 | ||
| 629 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 630 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 631 | is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 632 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; | |
| 633 | return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 634 | } | |
| 635 | ||
| 636 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 637 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 638 | is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { | |
| 639 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 640 | return __pstl::__internal::__pattern_adjacent_find( | |
| 641 | __dispatch_tag, | |
| 642 | std::forward<_ExecutionPolicy>(__exec), | |
| 643 | __first, | |
| 644 | __last, | |
| 645 | __pstl::__internal::__reorder_pred<_Compare>(__comp), | |
| 646 | /*or_semantic*/ true) == __last; | |
| 647 | } | |
| 648 | ||
| 649 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 650 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 651 | is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 652 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; | |
| 653 | return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 654 | } | |
| 655 | ||
| 656 | // [alg.merge] | |
| 657 | template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare> | |
| 658 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 659 | inplace_merge(_ExecutionPolicy&& __exec, | |
| 660 | _BidirectionalIterator __first, | |
| 661 | _BidirectionalIterator __middle, | |
| 662 | _BidirectionalIterator __last, | |
| 663 | _Compare __comp) { | |
| 664 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 665 | ||
| 666 | __pstl::__internal::__pattern_inplace_merge( | |
| 667 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp); | |
| 668 | } | |
| 669 | ||
| 670 | template <class _ExecutionPolicy, class _BidirectionalIterator> | |
| 671 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 672 | inplace_merge(_ExecutionPolicy&& __exec, | |
| 673 | _BidirectionalIterator __first, | |
| 674 | _BidirectionalIterator __middle, | |
| 675 | _BidirectionalIterator __last) { | |
| 676 | typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType; | |
| 677 | std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>()); | |
| 678 | } | |
| 679 | ||
| 680 | // [includes] | |
| 681 | ||
| 682 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 683 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 684 | includes(_ExecutionPolicy&& __exec, | |
| 685 | _ForwardIterator1 __first1, | |
| 686 | _ForwardIterator1 __last1, | |
| 687 | _ForwardIterator2 __first2, | |
| 688 | _ForwardIterator2 __last2, | |
| 689 | _Compare __comp) { | |
| 690 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 691 | ||
| 692 | return __pstl::__internal::__pattern_includes( | |
| 693 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp); | |
| 694 | } | |
| 695 | ||
| 696 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 697 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 698 | includes(_ExecutionPolicy&& __exec, | |
| 699 | _ForwardIterator1 __first1, | |
| 700 | _ForwardIterator1 __last1, | |
| 701 | _ForwardIterator2 __first2, | |
| 702 | _ForwardIterator2 __last2) { | |
| 703 | return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>()); | |
| 704 | } | |
| 705 | ||
| 706 | // [set.union] | |
| 707 | ||
| 708 | template <class _ExecutionPolicy, | |
| 709 | class _ForwardIterator1, | |
| 710 | class _ForwardIterator2, | |
| 711 | class _ForwardIterator, | |
| 712 | class _Compare> | |
| 713 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 714 | set_union(_ExecutionPolicy&& __exec, | |
| 715 | _ForwardIterator1 __first1, | |
| 716 | _ForwardIterator1 __last1, | |
| 717 | _ForwardIterator2 __first2, | |
| 718 | _ForwardIterator2 __last2, | |
| 719 | _ForwardIterator __result, | |
| 720 | _Compare __comp) { | |
| 721 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); | |
| 722 | ||
| 723 | return __pstl::__internal::__pattern_set_union( | |
| 724 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); | |
| 725 | } | |
| 726 | ||
| 727 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 728 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 729 | set_union(_ExecutionPolicy&& __exec, | |
| 730 | _ForwardIterator1 __first1, | |
| 731 | _ForwardIterator1 __last1, | |
| 732 | _ForwardIterator2 __first2, | |
| 733 | _ForwardIterator2 __last2, | |
| 734 | _ForwardIterator __result) { | |
| 735 | return std::set_union( | |
| 736 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); | |
| 737 | } | |
| 738 | ||
| 739 | // [set.intersection] | |
| 740 | ||
| 741 | template <class _ExecutionPolicy, | |
| 742 | class _ForwardIterator1, | |
| 743 | class _ForwardIterator2, | |
| 744 | class _ForwardIterator, | |
| 745 | class _Compare> | |
| 746 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( | |
| 747 | _ExecutionPolicy&& __exec, | |
| 748 | _ForwardIterator1 __first1, | |
| 749 | _ForwardIterator1 __last1, | |
| 750 | _ForwardIterator2 __first2, | |
| 751 | _ForwardIterator2 __last2, | |
| 752 | _ForwardIterator __result, | |
| 753 | _Compare __comp) { | |
| 754 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); | |
| 755 | ||
| 756 | return __pstl::__internal::__pattern_set_intersection( | |
| 757 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); | |
| 758 | } | |
| 759 | ||
| 760 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 761 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( | |
| 762 | _ExecutionPolicy&& __exec, | |
| 763 | _ForwardIterator1 __first1, | |
| 764 | _ForwardIterator1 __last1, | |
| 765 | _ForwardIterator2 __first2, | |
| 766 | _ForwardIterator2 __last2, | |
| 767 | _ForwardIterator __result) { | |
| 768 | return std::set_intersection( | |
| 769 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); | |
| 770 | } | |
| 771 | ||
| 772 | // [set.difference] | |
| 773 | ||
| 774 | template <class _ExecutionPolicy, | |
| 775 | class _ForwardIterator1, | |
| 776 | class _ForwardIterator2, | |
| 777 | class _ForwardIterator, | |
| 778 | class _Compare> | |
| 779 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( | |
| 780 | _ExecutionPolicy&& __exec, | |
| 781 | _ForwardIterator1 __first1, | |
| 782 | _ForwardIterator1 __last1, | |
| 783 | _ForwardIterator2 __first2, | |
| 784 | _ForwardIterator2 __last2, | |
| 785 | _ForwardIterator __result, | |
| 786 | _Compare __comp) { | |
| 787 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); | |
| 788 | ||
| 789 | return __pstl::__internal::__pattern_set_difference( | |
| 790 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); | |
| 791 | } | |
| 792 | ||
| 793 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 794 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( | |
| 795 | _ExecutionPolicy&& __exec, | |
| 796 | _ForwardIterator1 __first1, | |
| 797 | _ForwardIterator1 __last1, | |
| 798 | _ForwardIterator2 __first2, | |
| 799 | _ForwardIterator2 __last2, | |
| 800 | _ForwardIterator __result) { | |
| 801 | return std::set_difference( | |
| 802 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); | |
| 803 | } | |
| 804 | ||
| 805 | // [set.symmetric.difference] | |
| 806 | ||
| 807 | template <class _ExecutionPolicy, | |
| 808 | class _ForwardIterator1, | |
| 809 | class _ForwardIterator2, | |
| 810 | class _ForwardIterator, | |
| 811 | class _Compare> | |
| 812 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( | |
| 813 | _ExecutionPolicy&& __exec, | |
| 814 | _ForwardIterator1 __first1, | |
| 815 | _ForwardIterator1 __last1, | |
| 816 | _ForwardIterator2 __first2, | |
| 817 | _ForwardIterator2 __last2, | |
| 818 | _ForwardIterator __result, | |
| 819 | _Compare __comp) { | |
| 820 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); | |
| 821 | ||
| 822 | return __pstl::__internal::__pattern_set_symmetric_difference( | |
| 823 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); | |
| 824 | } | |
| 825 | ||
| 826 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> | |
| 827 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( | |
| 828 | _ExecutionPolicy&& __exec, | |
| 829 | _ForwardIterator1 __first1, | |
| 830 | _ForwardIterator1 __last1, | |
| 831 | _ForwardIterator2 __first2, | |
| 832 | _ForwardIterator2 __last2, | |
| 833 | _ForwardIterator __result) { | |
| 834 | return std::set_symmetric_difference( | |
| 835 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); | |
| 836 | } | |
| 837 | ||
| 838 | // [is.heap] | |
| 839 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 840 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> | |
| 841 | is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 842 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 843 | ||
| 844 | return __pstl::__internal::__pattern_is_heap_until( | |
| 845 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); | |
| 846 | } | |
| 847 | ||
| 848 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 849 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> | |
| 850 | is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { | |
| 851 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 852 | return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 853 | } | |
| 854 | ||
| 855 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 856 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 857 | is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { | |
| 858 | return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last; | |
| 859 | } | |
| 860 | ||
| 861 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 862 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> | |
| 863 | is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { | |
| 864 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 865 | return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 866 | } | |
| 867 | ||
| 868 | // [alg.min.max] | |
| 869 | ||
| 870 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 871 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 872 | min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { | |
| 873 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 874 | return __pstl::__internal::__pattern_min_element( | |
| 875 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); | |
| 876 | } | |
| 877 | ||
| 878 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 879 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 880 | min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 881 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; | |
| 882 | return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); | |
| 883 | } | |
| 884 | ||
| 885 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 886 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 887 | max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { | |
| 888 | return min_element( | |
| 889 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp)); | |
| 890 | } | |
| 891 | ||
| 892 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 893 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 894 | max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 895 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; | |
| 896 | return std::min_element( | |
| 897 | std::forward<_ExecutionPolicy>(__exec), | |
| 898 | __first, | |
| 899 | __last, | |
| 900 | __pstl::__internal::__reorder_pred<std::less<_InputType>>(std::less<_InputType>())); | |
| 901 | } | |
| 902 | ||
| 903 | template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> | |
| 904 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> | |
| 905 | minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { | |
| 906 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 907 | return __pstl::__internal::__pattern_minmax_element( | |
| 908 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); | |
| 909 | } | |
| 910 | ||
| 911 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 912 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> | |
| 913 | minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 914 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 915 | return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>()); | |
| 916 | } | |
| 917 | ||
| 918 | // [alg.nth.element] | |
| 919 | ||
| 920 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> | |
| 921 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 922 | nth_element(_ExecutionPolicy&& __exec, | |
| 923 | _RandomAccessIterator __first, | |
| 924 | _RandomAccessIterator __nth, | |
| 925 | _RandomAccessIterator __last, | |
| 926 | _Compare __comp) { | |
| 927 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 928 | ||
| 929 | __pstl::__internal::__pattern_nth_element( | |
| 930 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp); | |
| 931 | } | |
| 932 | ||
| 933 | template <class _ExecutionPolicy, class _RandomAccessIterator> | |
| 934 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 935 | nth_element(_ExecutionPolicy&& __exec, | |
| 936 | _RandomAccessIterator __first, | |
| 937 | _RandomAccessIterator __nth, | |
| 938 | _RandomAccessIterator __last) { | |
| 939 | typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; | |
| 940 | std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>()); | |
| 941 | } | |
| 942 | ||
| 943 | // [alg.lex.comparison] | |
| 944 | ||
| 945 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> | |
| 946 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( | |
| 947 | _ExecutionPolicy&& __exec, | |
| 948 | _ForwardIterator1 __first1, | |
| 949 | _ForwardIterator1 __last1, | |
| 950 | _ForwardIterator2 __first2, | |
| 951 | _ForwardIterator2 __last2, | |
| 952 | _Compare __comp) { | |
| 953 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); | |
| 954 | ||
| 955 | return __pstl::__internal::__pattern_lexicographical_compare( | |
| 956 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp); | |
| 957 | } | |
| 958 | ||
| 959 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 960 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( | |
| 961 | _ExecutionPolicy&& __exec, | |
| 962 | _ForwardIterator1 __first1, | |
| 963 | _ForwardIterator1 __last1, | |
| 964 | _ForwardIterator2 __first2, | |
| 965 | _ForwardIterator2 __last2) { | |
| 966 | return std::lexicographical_compare( | |
| 967 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>()); | |
| 968 | } | |
| 969 | ||
| 970 | } // namespace std | |
| 971 | ||
| 972 | #endif /* _PSTL_GLUE_ALGORITHM_IMPL_H */ |
lib/libcxx/include/__pstl/internal/glue_memory_defs.h created+81| ... | ... | @@ -0,0 +1,81 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_MEMORY_DEFS_H | |
| 11 | #define _PSTL_GLUE_MEMORY_DEFS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | ||
| 15 | #include "execution_defs.h" | |
| 16 | ||
| 17 | namespace std { | |
| 18 | ||
| 19 | // [uninitialized.copy] | |
| 20 | ||
| 21 | template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> | |
| 22 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 23 | uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result); | |
| 24 | ||
| 25 | template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> | |
| 26 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 27 | uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result); | |
| 28 | ||
| 29 | // [uninitialized.move] | |
| 30 | ||
| 31 | template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> | |
| 32 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 33 | uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result); | |
| 34 | ||
| 35 | template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> | |
| 36 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 37 | uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result); | |
| 38 | ||
| 39 | // [uninitialized.fill] | |
| 40 | ||
| 41 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 42 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 43 | uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value); | |
| 44 | ||
| 45 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> | |
| 46 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 47 | uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value); | |
| 48 | ||
| 49 | // [specialized.destroy] | |
| 50 | ||
| 51 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 52 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 53 | destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 54 | ||
| 55 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 56 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 57 | destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n); | |
| 58 | ||
| 59 | // [uninitialized.construct.default] | |
| 60 | ||
| 61 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 62 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 63 | uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 64 | ||
| 65 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 66 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 67 | uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n); | |
| 68 | ||
| 69 | // [uninitialized.construct.value] | |
| 70 | ||
| 71 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 72 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 73 | uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); | |
| 74 | ||
| 75 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 76 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 77 | uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n); | |
| 78 | ||
| 79 | } // namespace std | |
| 80 | ||
| 81 | #endif /* _PSTL_GLUE_MEMORY_DEFS_H */ |
lib/libcxx/include/__pstl/internal/glue_memory_impl.h created+379| ... | ... | @@ -0,0 +1,379 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_MEMORY_IMPL_H | |
| 11 | #define _PSTL_GLUE_MEMORY_IMPL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | ||
| 15 | #include "algorithm_fwd.h" | |
| 16 | #include "execution_defs.h" | |
| 17 | #include "utils.h" | |
| 18 | ||
| 19 | #include "execution_impl.h" | |
| 20 | ||
| 21 | namespace std { | |
| 22 | ||
| 23 | // [uninitialized.copy] | |
| 24 | ||
| 25 | template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> | |
| 26 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_copy( | |
| 27 | _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) { | |
| 28 | typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; | |
| 29 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; | |
| 30 | typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; | |
| 31 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; | |
| 32 | ||
| 33 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 34 | ||
| 35 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 36 | ||
| 37 | return __pstl::__internal::__invoke_if_else( | |
| 38 | std::integral_constant < bool, | |
| 39 | std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), | |
| 40 | [&]() { | |
| 41 | return __pstl::__internal::__pattern_walk2_brick( | |
| 42 | __dispatch_tag, | |
| 43 | std::forward<_ExecutionPolicy>(__exec), | |
| 44 | __first, | |
| 45 | __last, | |
| 46 | __result, | |
| 47 | [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { | |
| 48 | return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); | |
| 49 | }); | |
| 50 | }, | |
| 51 | [&]() { | |
| 52 | return __pstl::__internal::__pattern_walk2( | |
| 53 | __dispatch_tag, | |
| 54 | std::forward<_ExecutionPolicy>(__exec), | |
| 55 | __first, | |
| 56 | __last, | |
| 57 | __result, | |
| 58 | [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); }); | |
| 59 | }); | |
| 60 | } | |
| 61 | ||
| 62 | template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> | |
| 63 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 64 | uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) { | |
| 65 | typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; | |
| 66 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; | |
| 67 | typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; | |
| 68 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; | |
| 69 | ||
| 70 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 71 | ||
| 72 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 73 | ||
| 74 | return __pstl::__internal::__invoke_if_else( | |
| 75 | std::integral_constant < bool, | |
| 76 | std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), | |
| 77 | [&]() { | |
| 78 | return __pstl::__internal::__pattern_walk2_brick_n( | |
| 79 | __dispatch_tag, | |
| 80 | std::forward<_ExecutionPolicy>(__exec), | |
| 81 | __first, | |
| 82 | __n, | |
| 83 | __result, | |
| 84 | [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { | |
| 85 | return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); | |
| 86 | }); | |
| 87 | }, | |
| 88 | [&]() { | |
| 89 | return __pstl::__internal::__pattern_walk2_n( | |
| 90 | __dispatch_tag, | |
| 91 | std::forward<_ExecutionPolicy>(__exec), | |
| 92 | __first, | |
| 93 | __n, | |
| 94 | __result, | |
| 95 | [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); }); | |
| 96 | }); | |
| 97 | } | |
| 98 | ||
| 99 | // [uninitialized.move] | |
| 100 | ||
| 101 | template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator> | |
| 102 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_move( | |
| 103 | _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) { | |
| 104 | typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; | |
| 105 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; | |
| 106 | typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; | |
| 107 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; | |
| 108 | ||
| 109 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 110 | ||
| 111 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 112 | ||
| 113 | return __pstl::__internal::__invoke_if_else( | |
| 114 | std::integral_constant < bool, | |
| 115 | std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), | |
| 116 | [&]() { | |
| 117 | return __pstl::__internal::__pattern_walk2_brick( | |
| 118 | __dispatch_tag, | |
| 119 | std::forward<_ExecutionPolicy>(__exec), | |
| 120 | __first, | |
| 121 | __last, | |
| 122 | __result, | |
| 123 | [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { | |
| 124 | return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); | |
| 125 | }); | |
| 126 | }, | |
| 127 | [&]() { | |
| 128 | return __pstl::__internal::__pattern_walk2( | |
| 129 | __dispatch_tag, | |
| 130 | std::forward<_ExecutionPolicy>(__exec), | |
| 131 | __first, | |
| 132 | __last, | |
| 133 | __result, | |
| 134 | [](_ReferenceType1 __val1, _ReferenceType2 __val2) { | |
| 135 | ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); | |
| 136 | }); | |
| 137 | }); | |
| 138 | } | |
| 139 | ||
| 140 | template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator> | |
| 141 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 142 | uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) { | |
| 143 | typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; | |
| 144 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; | |
| 145 | typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; | |
| 146 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; | |
| 147 | ||
| 148 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 149 | ||
| 150 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 151 | ||
| 152 | return __pstl::__internal::__invoke_if_else( | |
| 153 | std::integral_constant < bool, | |
| 154 | std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), | |
| 155 | [&]() { | |
| 156 | return __pstl::__internal::__pattern_walk2_brick_n( | |
| 157 | __dispatch_tag, | |
| 158 | std::forward<_ExecutionPolicy>(__exec), | |
| 159 | __first, | |
| 160 | __n, | |
| 161 | __result, | |
| 162 | [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { | |
| 163 | return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); | |
| 164 | }); | |
| 165 | }, | |
| 166 | [&]() { | |
| 167 | return __pstl::__internal::__pattern_walk2_n( | |
| 168 | __dispatch_tag, | |
| 169 | std::forward<_ExecutionPolicy>(__exec), | |
| 170 | __first, | |
| 171 | __n, | |
| 172 | __result, | |
| 173 | [](_ReferenceType1 __val1, _ReferenceType2 __val2) { | |
| 174 | ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); | |
| 175 | }); | |
| 176 | }); | |
| 177 | } | |
| 178 | ||
| 179 | // [uninitialized.fill] | |
| 180 | ||
| 181 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> | |
| 182 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 183 | uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { | |
| 184 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 185 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 186 | ||
| 187 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 188 | ||
| 189 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 190 | ||
| 191 | __pstl::__internal::__invoke_if_else( | |
| 192 | std::is_arithmetic<_ValueType>(), | |
| 193 | [&]() { | |
| 194 | __pstl::__internal::__pattern_walk_brick( | |
| 195 | __dispatch_tag, | |
| 196 | std::forward<_ExecutionPolicy>(__exec), | |
| 197 | __first, | |
| 198 | __last, | |
| 199 | [&__value](_ForwardIterator __begin, _ForwardIterator __end) { | |
| 200 | __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); | |
| 201 | }); | |
| 202 | }, | |
| 203 | [&]() { | |
| 204 | __pstl::__internal::__pattern_walk1( | |
| 205 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](_ReferenceType __val) { | |
| 206 | ::new (std::addressof(__val)) _ValueType(__value); | |
| 207 | }); | |
| 208 | }); | |
| 209 | } | |
| 210 | ||
| 211 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> | |
| 212 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 213 | uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) { | |
| 214 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 215 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 216 | ||
| 217 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 218 | ||
| 219 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 220 | ||
| 221 | return __pstl::__internal::__invoke_if_else( | |
| 222 | std::is_arithmetic<_ValueType>(), | |
| 223 | [&]() { | |
| 224 | return __pstl::__internal::__pattern_walk_brick_n( | |
| 225 | __dispatch_tag, | |
| 226 | std::forward<_ExecutionPolicy>(__exec), | |
| 227 | __first, | |
| 228 | __n, | |
| 229 | [&__value](_ForwardIterator __begin, _Size __count) { | |
| 230 | return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{}); | |
| 231 | }); | |
| 232 | }, | |
| 233 | [&]() { | |
| 234 | return __pstl::__internal::__pattern_walk1_n( | |
| 235 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [&__value](_ReferenceType __val) { | |
| 236 | ::new (std::addressof(__val)) _ValueType(__value); | |
| 237 | }); | |
| 238 | }); | |
| 239 | } | |
| 240 | ||
| 241 | // [specialized.destroy] | |
| 242 | ||
| 243 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 244 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 245 | destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 246 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 247 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 248 | ||
| 249 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 250 | ||
| 251 | __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() { | |
| 252 | __pstl::__internal::__pattern_walk1( | |
| 253 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { | |
| 254 | __val.~_ValueType(); | |
| 255 | }); | |
| 256 | }); | |
| 257 | } | |
| 258 | ||
| 259 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 260 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 261 | destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { | |
| 262 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 263 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 264 | ||
| 265 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 266 | ||
| 267 | return __pstl::__internal::__invoke_if_else( | |
| 268 | std::is_trivially_destructible<_ValueType>(), | |
| 269 | [&]() { return std::next(__first, __n); }, | |
| 270 | [&]() { | |
| 271 | return __pstl::__internal::__pattern_walk1_n( | |
| 272 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { | |
| 273 | __val.~_ValueType(); | |
| 274 | }); | |
| 275 | }); | |
| 276 | } | |
| 277 | ||
| 278 | // [uninitialized.construct.default] | |
| 279 | ||
| 280 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 281 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 282 | uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 283 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 284 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 285 | ||
| 286 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 287 | ||
| 288 | __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() { | |
| 289 | __pstl::__internal::__pattern_walk1( | |
| 290 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { | |
| 291 | ::new (std::addressof(__val)) _ValueType; | |
| 292 | }); | |
| 293 | }); | |
| 294 | } | |
| 295 | ||
| 296 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 297 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 298 | uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { | |
| 299 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 300 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 301 | ||
| 302 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 303 | ||
| 304 | return __pstl::__internal::__invoke_if_else( | |
| 305 | std::is_trivial<_ValueType>(), | |
| 306 | [&]() { return std::next(__first, __n); }, | |
| 307 | [&]() { | |
| 308 | return __pstl::__internal::__pattern_walk1_n( | |
| 309 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { | |
| 310 | ::new (std::addressof(__val)) _ValueType; | |
| 311 | }); | |
| 312 | }); | |
| 313 | } | |
| 314 | ||
| 315 | // [uninitialized.construct.value] | |
| 316 | ||
| 317 | template <class _ExecutionPolicy, class _ForwardIterator> | |
| 318 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> | |
| 319 | uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { | |
| 320 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 321 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 322 | ||
| 323 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 324 | ||
| 325 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 326 | ||
| 327 | __pstl::__internal::__invoke_if_else( | |
| 328 | std::is_trivial<_ValueType>(), | |
| 329 | [&]() { | |
| 330 | __pstl::__internal::__pattern_walk_brick( | |
| 331 | __dispatch_tag, | |
| 332 | std::forward<_ExecutionPolicy>(__exec), | |
| 333 | __first, | |
| 334 | __last, | |
| 335 | [](_ForwardIterator __begin, _ForwardIterator __end) { | |
| 336 | __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); | |
| 337 | }); | |
| 338 | }, | |
| 339 | [&]() { | |
| 340 | __pstl::__internal::__pattern_walk1( | |
| 341 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { | |
| 342 | ::new (std::addressof(__val)) _ValueType(); | |
| 343 | }); | |
| 344 | }); | |
| 345 | } | |
| 346 | ||
| 347 | template <class _ExecutionPolicy, class _ForwardIterator, class _Size> | |
| 348 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> | |
| 349 | uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { | |
| 350 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 351 | typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; | |
| 352 | ||
| 353 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); | |
| 354 | ||
| 355 | using __is_vector = typename decltype(__dispatch_tag)::__is_vector; | |
| 356 | ||
| 357 | return __pstl::__internal::__invoke_if_else( | |
| 358 | std::is_trivial<_ValueType>(), | |
| 359 | [&]() { | |
| 360 | return __pstl::__internal::__pattern_walk_brick_n( | |
| 361 | __dispatch_tag, | |
| 362 | std::forward<_ExecutionPolicy>(__exec), | |
| 363 | __first, | |
| 364 | __n, | |
| 365 | [](_ForwardIterator __begin, _Size __count) { | |
| 366 | return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); | |
| 367 | }); | |
| 368 | }, | |
| 369 | [&]() { | |
| 370 | return __pstl::__internal::__pattern_walk1_n( | |
| 371 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { | |
| 372 | ::new (std::addressof(__val)) _ValueType(); | |
| 373 | }); | |
| 374 | }); | |
| 375 | } | |
| 376 | ||
| 377 | } // namespace std | |
| 378 | ||
| 379 | #endif /* _PSTL_GLUE_MEMORY_IMPL_H */ |
lib/libcxx/include/__pstl/internal/glue_numeric_defs.h created+124| ... | ... | @@ -0,0 +1,124 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_NUMERIC_DEFS_H | |
| 11 | #define _PSTL_GLUE_NUMERIC_DEFS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <iterator> | |
| 15 | ||
| 16 | #include "execution_defs.h" | |
| 17 | ||
| 18 | namespace std { | |
| 19 | // [exclusive.scan] | |
| 20 | ||
| 21 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> | |
| 22 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( | |
| 23 | _ExecutionPolicy&& __exec, | |
| 24 | _ForwardIterator1 __first, | |
| 25 | _ForwardIterator1 __last, | |
| 26 | _ForwardIterator2 __result, | |
| 27 | _Tp __init); | |
| 28 | ||
| 29 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> | |
| 30 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( | |
| 31 | _ExecutionPolicy&& __exec, | |
| 32 | _ForwardIterator1 __first, | |
| 33 | _ForwardIterator1 __last, | |
| 34 | _ForwardIterator2 __result, | |
| 35 | _Tp __init, | |
| 36 | _BinaryOperation __binary_op); | |
| 37 | ||
| 38 | // [inclusive.scan] | |
| 39 | ||
| 40 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 41 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 42 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result); | |
| 43 | ||
| 44 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> | |
| 45 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 46 | _ExecutionPolicy&& __exec, | |
| 47 | _ForwardIterator1 __first, | |
| 48 | _ForwardIterator1 __last, | |
| 49 | _ForwardIterator2 __result, | |
| 50 | _BinaryOperation __binary_op); | |
| 51 | ||
| 52 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> | |
| 53 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 54 | _ExecutionPolicy&& __exec, | |
| 55 | _ForwardIterator1 __first, | |
| 56 | _ForwardIterator1 __last, | |
| 57 | _ForwardIterator2 __result, | |
| 58 | _BinaryOperation __binary_op, | |
| 59 | _Tp __init); | |
| 60 | ||
| 61 | // [transform.exclusive.scan] | |
| 62 | ||
| 63 | template <class _ExecutionPolicy, | |
| 64 | class _ForwardIterator1, | |
| 65 | class _ForwardIterator2, | |
| 66 | class _Tp, | |
| 67 | class _BinaryOperation, | |
| 68 | class _UnaryOperation> | |
| 69 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan( | |
| 70 | _ExecutionPolicy&& __exec, | |
| 71 | _ForwardIterator1 __first, | |
| 72 | _ForwardIterator1 __last, | |
| 73 | _ForwardIterator2 __result, | |
| 74 | _Tp __init, | |
| 75 | _BinaryOperation __binary_op, | |
| 76 | _UnaryOperation __unary_op); | |
| 77 | ||
| 78 | // [transform.inclusive.scan] | |
| 79 | ||
| 80 | template <class _ExecutionPolicy, | |
| 81 | class _ForwardIterator1, | |
| 82 | class _ForwardIterator2, | |
| 83 | class _BinaryOperation, | |
| 84 | class _UnaryOperation, | |
| 85 | class _Tp> | |
| 86 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( | |
| 87 | _ExecutionPolicy&& __exec, | |
| 88 | _ForwardIterator1 __first, | |
| 89 | _ForwardIterator1 __last, | |
| 90 | _ForwardIterator2 __result, | |
| 91 | _BinaryOperation __binary_op, | |
| 92 | _UnaryOperation __unary_op, | |
| 93 | _Tp __init); | |
| 94 | ||
| 95 | template <class _ExecutionPolicy, | |
| 96 | class _ForwardIterator1, | |
| 97 | class _ForwardIterator2, | |
| 98 | class _UnaryOperation, | |
| 99 | class _BinaryOperation> | |
| 100 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( | |
| 101 | _ExecutionPolicy&& __exec, | |
| 102 | _ForwardIterator1 __first, | |
| 103 | _ForwardIterator1 __last, | |
| 104 | _ForwardIterator2 __result, | |
| 105 | _BinaryOperation __binary_op, | |
| 106 | _UnaryOperation __unary_op); | |
| 107 | ||
| 108 | // [adjacent.difference] | |
| 109 | ||
| 110 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> | |
| 111 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( | |
| 112 | _ExecutionPolicy&& __exec, | |
| 113 | _ForwardIterator1 __first, | |
| 114 | _ForwardIterator1 __last, | |
| 115 | _ForwardIterator2 __d_first, | |
| 116 | _BinaryOperation op); | |
| 117 | ||
| 118 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 119 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( | |
| 120 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first); | |
| 121 | ||
| 122 | } // namespace std | |
| 123 | ||
| 124 | #endif /* _PSTL_GLUE_NUMERIC_DEFS_H */ |
lib/libcxx/include/__pstl/internal/glue_numeric_impl.h created+223| ... | ... | @@ -0,0 +1,223 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_GLUE_NUMERIC_IMPL_H | |
| 11 | #define _PSTL_GLUE_NUMERIC_IMPL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <functional> | |
| 15 | ||
| 16 | #include "execution_impl.h" | |
| 17 | #include "numeric_fwd.h" | |
| 18 | #include "utils.h" | |
| 19 | ||
| 20 | namespace std { | |
| 21 | ||
| 22 | // [exclusive.scan] | |
| 23 | ||
| 24 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> | |
| 25 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( | |
| 26 | _ExecutionPolicy&& __exec, | |
| 27 | _ForwardIterator1 __first, | |
| 28 | _ForwardIterator1 __last, | |
| 29 | _ForwardIterator2 __result, | |
| 30 | _Tp __init) { | |
| 31 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 32 | ||
| 33 | using namespace __pstl; | |
| 34 | return __internal::__pattern_transform_scan( | |
| 35 | __dispatch_tag, | |
| 36 | std::forward<_ExecutionPolicy>(__exec), | |
| 37 | __first, | |
| 38 | __last, | |
| 39 | __result, | |
| 40 | __pstl::__internal::__no_op(), | |
| 41 | __init, | |
| 42 | std::plus<_Tp>(), | |
| 43 | /*inclusive=*/std::false_type()); | |
| 44 | } | |
| 45 | ||
| 46 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> | |
| 47 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( | |
| 48 | _ExecutionPolicy&& __exec, | |
| 49 | _ForwardIterator1 __first, | |
| 50 | _ForwardIterator1 __last, | |
| 51 | _ForwardIterator2 __result, | |
| 52 | _Tp __init, | |
| 53 | _BinaryOperation __binary_op) { | |
| 54 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 55 | ||
| 56 | using namespace __pstl; | |
| 57 | return __internal::__pattern_transform_scan( | |
| 58 | __dispatch_tag, | |
| 59 | std::forward<_ExecutionPolicy>(__exec), | |
| 60 | __first, | |
| 61 | __last, | |
| 62 | __result, | |
| 63 | __pstl::__internal::__no_op(), | |
| 64 | __init, | |
| 65 | __binary_op, | |
| 66 | /*inclusive=*/std::false_type()); | |
| 67 | } | |
| 68 | ||
| 69 | // [inclusive.scan] | |
| 70 | ||
| 71 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 72 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 73 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { | |
| 74 | typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; | |
| 75 | return transform_inclusive_scan( | |
| 76 | std::forward<_ExecutionPolicy>(__exec), | |
| 77 | __first, | |
| 78 | __last, | |
| 79 | __result, | |
| 80 | std::plus<_InputType>(), | |
| 81 | __pstl::__internal::__no_op()); | |
| 82 | } | |
| 83 | ||
| 84 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> | |
| 85 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 86 | _ExecutionPolicy&& __exec, | |
| 87 | _ForwardIterator1 __first, | |
| 88 | _ForwardIterator1 __last, | |
| 89 | _ForwardIterator2 __result, | |
| 90 | _BinaryOperation __binary_op) { | |
| 91 | return transform_inclusive_scan( | |
| 92 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, __pstl::__internal::__no_op()); | |
| 93 | } | |
| 94 | ||
| 95 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> | |
| 96 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( | |
| 97 | _ExecutionPolicy&& __exec, | |
| 98 | _ForwardIterator1 __first, | |
| 99 | _ForwardIterator1 __last, | |
| 100 | _ForwardIterator2 __result, | |
| 101 | _BinaryOperation __binary_op, | |
| 102 | _Tp __init) { | |
| 103 | return transform_inclusive_scan( | |
| 104 | std::forward<_ExecutionPolicy>(__exec), | |
| 105 | __first, | |
| 106 | __last, | |
| 107 | __result, | |
| 108 | __binary_op, | |
| 109 | __pstl::__internal::__no_op(), | |
| 110 | __init); | |
| 111 | } | |
| 112 | ||
| 113 | // [transform.exclusive.scan] | |
| 114 | ||
| 115 | template <class _ExecutionPolicy, | |
| 116 | class _ForwardIterator1, | |
| 117 | class _ForwardIterator2, | |
| 118 | class _Tp, | |
| 119 | class _BinaryOperation, | |
| 120 | class _UnaryOperation> | |
| 121 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan( | |
| 122 | _ExecutionPolicy&& __exec, | |
| 123 | _ForwardIterator1 __first, | |
| 124 | _ForwardIterator1 __last, | |
| 125 | _ForwardIterator2 __result, | |
| 126 | _Tp __init, | |
| 127 | _BinaryOperation __binary_op, | |
| 128 | _UnaryOperation __unary_op) { | |
| 129 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 130 | ||
| 131 | return __pstl::__internal::__pattern_transform_scan( | |
| 132 | __dispatch_tag, | |
| 133 | std::forward<_ExecutionPolicy>(__exec), | |
| 134 | __first, | |
| 135 | __last, | |
| 136 | __result, | |
| 137 | __unary_op, | |
| 138 | __init, | |
| 139 | __binary_op, | |
| 140 | /*inclusive=*/std::false_type()); | |
| 141 | } | |
| 142 | ||
| 143 | // [transform.inclusive.scan] | |
| 144 | ||
| 145 | template <class _ExecutionPolicy, | |
| 146 | class _ForwardIterator1, | |
| 147 | class _ForwardIterator2, | |
| 148 | class _BinaryOperation, | |
| 149 | class _UnaryOperation, | |
| 150 | class _Tp> | |
| 151 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( | |
| 152 | _ExecutionPolicy&& __exec, | |
| 153 | _ForwardIterator1 __first, | |
| 154 | _ForwardIterator1 __last, | |
| 155 | _ForwardIterator2 __result, | |
| 156 | _BinaryOperation __binary_op, | |
| 157 | _UnaryOperation __unary_op, | |
| 158 | _Tp __init) { | |
| 159 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); | |
| 160 | ||
| 161 | return __pstl::__internal::__pattern_transform_scan( | |
| 162 | __dispatch_tag, | |
| 163 | std::forward<_ExecutionPolicy>(__exec), | |
| 164 | __first, | |
| 165 | __last, | |
| 166 | __result, | |
| 167 | __unary_op, | |
| 168 | __init, | |
| 169 | __binary_op, | |
| 170 | /*inclusive=*/std::true_type()); | |
| 171 | } | |
| 172 | ||
| 173 | template <class _ExecutionPolicy, | |
| 174 | class _ForwardIterator1, | |
| 175 | class _ForwardIterator2, | |
| 176 | class _UnaryOperation, | |
| 177 | class _BinaryOperation> | |
| 178 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( | |
| 179 | _ExecutionPolicy&& __exec, | |
| 180 | _ForwardIterator1 __first, | |
| 181 | _ForwardIterator1 __last, | |
| 182 | _ForwardIterator2 __result, | |
| 183 | _BinaryOperation __binary_op, | |
| 184 | _UnaryOperation __unary_op) { | |
| 185 | if (__first != __last) { | |
| 186 | auto __tmp = __unary_op(*__first); | |
| 187 | *__result = __tmp; | |
| 188 | return transform_inclusive_scan( | |
| 189 | std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, __binary_op, __unary_op, __tmp); | |
| 190 | } else { | |
| 191 | return __result; | |
| 192 | } | |
| 193 | } | |
| 194 | ||
| 195 | // [adjacent.difference] | |
| 196 | ||
| 197 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> | |
| 198 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( | |
| 199 | _ExecutionPolicy&& __exec, | |
| 200 | _ForwardIterator1 __first, | |
| 201 | _ForwardIterator1 __last, | |
| 202 | _ForwardIterator2 __d_first, | |
| 203 | _BinaryOperation __op) { | |
| 204 | if (__first == __last) | |
| 205 | return __d_first; | |
| 206 | ||
| 207 | auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); | |
| 208 | ||
| 209 | return __pstl::__internal::__pattern_adjacent_difference( | |
| 210 | __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op); | |
| 211 | } | |
| 212 | ||
| 213 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> | |
| 214 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( | |
| 215 | _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) { | |
| 216 | typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType; | |
| 217 | return adjacent_difference( | |
| 218 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, std::minus<_ValueType>()); | |
| 219 | } | |
| 220 | ||
| 221 | } // namespace std | |
| 222 | ||
| 223 | #endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */ |
lib/libcxx/include/__pstl/internal/memory_impl.h created+106| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_MEMORY_IMPL_H | |
| 11 | #define _PSTL_MEMORY_IMPL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <iterator> | |
| 15 | ||
| 16 | #include "unseq_backend_simd.h" | |
| 17 | ||
| 18 | namespace __pstl { | |
| 19 | namespace __internal { | |
| 20 | ||
| 21 | //------------------------------------------------------------------------ | |
| 22 | // uninitialized_move | |
| 23 | //------------------------------------------------------------------------ | |
| 24 | ||
| 25 | template <typename _ForwardIterator, typename _OutputIterator> | |
| 26 | _OutputIterator __brick_uninitialized_move( | |
| 27 | _ForwardIterator __first, | |
| 28 | _ForwardIterator __last, | |
| 29 | _OutputIterator __result, | |
| 30 | /*vector=*/std::false_type) noexcept { | |
| 31 | using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 32 | for (; __first != __last; ++__first, ++__result) { | |
| 33 | ::new (std::addressof(*__result)) _ValueType(std::move(*__first)); | |
| 34 | } | |
| 35 | return __result; | |
| 36 | } | |
| 37 | ||
| 38 | template <typename _RandomAccessIterator, typename _OutputIterator> | |
| 39 | _OutputIterator __brick_uninitialized_move( | |
| 40 | _RandomAccessIterator __first, | |
| 41 | _RandomAccessIterator __last, | |
| 42 | _OutputIterator __result, | |
| 43 | /*vector=*/std::true_type) noexcept { | |
| 44 | using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 45 | using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; | |
| 46 | using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; | |
| 47 | ||
| 48 | return __unseq_backend::__simd_walk_2( | |
| 49 | __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) { | |
| 50 | ::new (std::addressof(__y)) __ValueType(std::move(__x)); | |
| 51 | }); | |
| 52 | } | |
| 53 | ||
| 54 | template <typename _Iterator> | |
| 55 | void __brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept { | |
| 56 | using _ValueType = typename std::iterator_traits<_Iterator>::value_type; | |
| 57 | ||
| 58 | for (; __first != __last; ++__first) | |
| 59 | __first->~_ValueType(); | |
| 60 | } | |
| 61 | ||
| 62 | template <typename _RandomAccessIterator> | |
| 63 | void __brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept { | |
| 64 | using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type; | |
| 65 | using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference; | |
| 66 | ||
| 67 | __unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); }); | |
| 68 | } | |
| 69 | ||
| 70 | //------------------------------------------------------------------------ | |
| 71 | // uninitialized copy | |
| 72 | //------------------------------------------------------------------------ | |
| 73 | ||
| 74 | template <typename _ForwardIterator, typename _OutputIterator> | |
| 75 | _OutputIterator __brick_uninitialized_copy( | |
| 76 | _ForwardIterator __first, | |
| 77 | _ForwardIterator __last, | |
| 78 | _OutputIterator __result, | |
| 79 | /*vector=*/std::false_type) noexcept { | |
| 80 | using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 81 | for (; __first != __last; ++__first, ++__result) { | |
| 82 | ::new (std::addressof(*__result)) _ValueType(*__first); | |
| 83 | } | |
| 84 | return __result; | |
| 85 | } | |
| 86 | ||
| 87 | template <typename _RandomAccessIterator, typename _OutputIterator> | |
| 88 | _OutputIterator __brick_uninitialized_copy( | |
| 89 | _RandomAccessIterator __first, | |
| 90 | _RandomAccessIterator __last, | |
| 91 | _OutputIterator __result, | |
| 92 | /*vector=*/std::true_type) noexcept { | |
| 93 | using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 94 | using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; | |
| 95 | using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; | |
| 96 | ||
| 97 | return __unseq_backend::__simd_walk_2( | |
| 98 | __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) { | |
| 99 | ::new (std::addressof(__y)) __ValueType(__x); | |
| 100 | }); | |
| 101 | } | |
| 102 | ||
| 103 | } // namespace __internal | |
| 104 | } // namespace __pstl | |
| 105 | ||
| 106 | #endif /* _PSTL_MEMORY_IMPL_H */ |
lib/libcxx/include/__pstl/internal/numeric_fwd.h created+143| ... | ... | @@ -0,0 +1,143 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_NUMERIC_FWD_H | |
| 11 | #define _PSTL_NUMERIC_FWD_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <type_traits> | |
| 15 | #include <utility> | |
| 16 | ||
| 17 | namespace __pstl { | |
| 18 | namespace __internal { | |
| 19 | ||
| 20 | //------------------------------------------------------------------------ | |
| 21 | // transform_exclusive_scan | |
| 22 | // | |
| 23 | // walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...) | |
| 24 | //------------------------------------------------------------------------ | |
| 25 | ||
| 26 | template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation> | |
| 27 | std::pair<_OutputIterator, _Tp> __brick_transform_scan( | |
| 28 | _ForwardIterator, | |
| 29 | _ForwardIterator, | |
| 30 | _OutputIterator, | |
| 31 | _UnaryOperation, | |
| 32 | _Tp, | |
| 33 | _BinaryOperation, | |
| 34 | /*Inclusive*/ std::false_type) noexcept; | |
| 35 | ||
| 36 | template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation> | |
| 37 | std::pair<_OutputIterator, _Tp> __brick_transform_scan( | |
| 38 | _RandomAccessIterator, | |
| 39 | _RandomAccessIterator, | |
| 40 | _OutputIterator, | |
| 41 | _UnaryOperation, | |
| 42 | _Tp, | |
| 43 | _BinaryOperation, | |
| 44 | /*Inclusive*/ std::true_type) noexcept; | |
| 45 | ||
| 46 | template <class _Tag, | |
| 47 | class _ExecutionPolicy, | |
| 48 | class _ForwardIterator, | |
| 49 | class _OutputIterator, | |
| 50 | class _UnaryOperation, | |
| 51 | class _Tp, | |
| 52 | class _BinaryOperation, | |
| 53 | class _Inclusive> | |
| 54 | _OutputIterator __pattern_transform_scan( | |
| 55 | _Tag, | |
| 56 | _ExecutionPolicy&&, | |
| 57 | _ForwardIterator, | |
| 58 | _ForwardIterator, | |
| 59 | _OutputIterator, | |
| 60 | _UnaryOperation, | |
| 61 | _Tp, | |
| 62 | _BinaryOperation, | |
| 63 | _Inclusive) noexcept; | |
| 64 | ||
| 65 | template <class _IsVector, | |
| 66 | class _ExecutionPolicy, | |
| 67 | class _RandomAccessIterator, | |
| 68 | class _OutputIterator, | |
| 69 | class _UnaryOperation, | |
| 70 | class _Tp, | |
| 71 | class _BinaryOperation, | |
| 72 | class _Inclusive> | |
| 73 | typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan( | |
| 74 | __parallel_tag<_IsVector> __tag, | |
| 75 | _ExecutionPolicy&&, | |
| 76 | _RandomAccessIterator, | |
| 77 | _RandomAccessIterator, | |
| 78 | _OutputIterator, | |
| 79 | _UnaryOperation, | |
| 80 | _Tp, | |
| 81 | _BinaryOperation, | |
| 82 | _Inclusive); | |
| 83 | ||
| 84 | template <class _IsVector, | |
| 85 | class _ExecutionPolicy, | |
| 86 | class _RandomAccessIterator, | |
| 87 | class _OutputIterator, | |
| 88 | class _UnaryOperation, | |
| 89 | class _Tp, | |
| 90 | class _BinaryOperation, | |
| 91 | class _Inclusive> | |
| 92 | typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan( | |
| 93 | __parallel_tag<_IsVector>, | |
| 94 | _ExecutionPolicy&&, | |
| 95 | _RandomAccessIterator, | |
| 96 | _RandomAccessIterator, | |
| 97 | _OutputIterator, | |
| 98 | _UnaryOperation, | |
| 99 | _Tp, | |
| 100 | _BinaryOperation, | |
| 101 | _Inclusive); | |
| 102 | ||
| 103 | //------------------------------------------------------------------------ | |
| 104 | // adjacent_difference | |
| 105 | //------------------------------------------------------------------------ | |
| 106 | ||
| 107 | template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation> | |
| 108 | _OutputIterator __brick_adjacent_difference( | |
| 109 | _ForwardIterator, | |
| 110 | _ForwardIterator, | |
| 111 | _OutputIterator, | |
| 112 | _BinaryOperation, | |
| 113 | /*is_vector*/ std::false_type) noexcept; | |
| 114 | ||
| 115 | template <class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation> | |
| 116 | _OutputIterator __brick_adjacent_difference( | |
| 117 | _RandomAccessIterator, | |
| 118 | _RandomAccessIterator, | |
| 119 | _OutputIterator, | |
| 120 | _BinaryOperation, | |
| 121 | /*is_vector*/ std::true_type) noexcept; | |
| 122 | ||
| 123 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation> | |
| 124 | _OutputIterator __pattern_adjacent_difference( | |
| 125 | _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation) noexcept; | |
| 126 | ||
| 127 | template <class _IsVector, | |
| 128 | class _ExecutionPolicy, | |
| 129 | class _RandomAccessIterator, | |
| 130 | class _OutputIterator, | |
| 131 | class _BinaryOperation> | |
| 132 | _OutputIterator __pattern_adjacent_difference( | |
| 133 | __parallel_tag<_IsVector>, | |
| 134 | _ExecutionPolicy&&, | |
| 135 | _RandomAccessIterator, | |
| 136 | _RandomAccessIterator, | |
| 137 | _OutputIterator, | |
| 138 | _BinaryOperation); | |
| 139 | ||
| 140 | } // namespace __internal | |
| 141 | } // namespace __pstl | |
| 142 | ||
| 143 | #endif /* _PSTL_NUMERIC_FWD_H */ |
lib/libcxx/include/__pstl/internal/numeric_impl.h created+364| ... | ... | @@ -0,0 +1,364 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_NUMERIC_IMPL_H | |
| 11 | #define _PSTL_NUMERIC_IMPL_H | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <iterator> | |
| 16 | #include <type_traits> | |
| 17 | #include <numeric> | |
| 18 | ||
| 19 | #include "parallel_backend.h" | |
| 20 | #include "execution_impl.h" | |
| 21 | #include "unseq_backend_simd.h" | |
| 22 | #include "algorithm_fwd.h" | |
| 23 | ||
| 24 | namespace __pstl { | |
| 25 | namespace __internal { | |
| 26 | ||
| 27 | //------------------------------------------------------------------------ | |
| 28 | // transform_exclusive_scan | |
| 29 | // | |
| 30 | // walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...) | |
| 31 | //------------------------------------------------------------------------ | |
| 32 | ||
| 33 | // Exclusive form | |
| 34 | template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation> | |
| 35 | std::pair<_OutputIterator, _Tp> __brick_transform_scan( | |
| 36 | _ForwardIterator __first, | |
| 37 | _ForwardIterator __last, | |
| 38 | _OutputIterator __result, | |
| 39 | _UnaryOperation __unary_op, | |
| 40 | _Tp __init, | |
| 41 | _BinaryOperation __binary_op, | |
| 42 | /*Inclusive*/ std::false_type, | |
| 43 | /*is_vector=*/std::false_type) noexcept { | |
| 44 | for (; __first != __last; ++__first, ++__result) { | |
| 45 | *__result = __init; | |
| 46 | __init = __binary_op(__init, __unary_op(*__first)); | |
| 47 | } | |
| 48 | return std::make_pair(__result, __init); | |
| 49 | } | |
| 50 | ||
| 51 | // Inclusive form | |
| 52 | template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation> | |
| 53 | std::pair<_OutputIterator, _Tp> __brick_transform_scan( | |
| 54 | _RandomAccessIterator __first, | |
| 55 | _RandomAccessIterator __last, | |
| 56 | _OutputIterator __result, | |
| 57 | _UnaryOperation __unary_op, | |
| 58 | _Tp __init, | |
| 59 | _BinaryOperation __binary_op, | |
| 60 | /*Inclusive*/ std::true_type, | |
| 61 | /*is_vector=*/std::false_type) noexcept { | |
| 62 | for (; __first != __last; ++__first, ++__result) { | |
| 63 | __init = __binary_op(__init, __unary_op(*__first)); | |
| 64 | *__result = __init; | |
| 65 | } | |
| 66 | return std::make_pair(__result, __init); | |
| 67 | } | |
| 68 | ||
| 69 | // type is arithmetic and binary operation is a user defined operation. | |
| 70 | template <typename _Tp, typename _BinaryOperation> | |
| 71 | using is_arithmetic_udop = | |
| 72 | std::integral_constant<bool, | |
| 73 | std::is_arithmetic<_Tp>::value && !std::is_same<_BinaryOperation, std::plus<_Tp>>::value>; | |
| 74 | ||
| 75 | // [restriction] - T shall be DefaultConstructible. | |
| 76 | // [violation] - default ctor of T shall set the identity value for binary_op. | |
| 77 | template <class _RandomAccessIterator, | |
| 78 | class _OutputIterator, | |
| 79 | class _UnaryOperation, | |
| 80 | class _Tp, | |
| 81 | class _BinaryOperation, | |
| 82 | class _Inclusive> | |
| 83 | typename std::enable_if<!is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 84 | __brick_transform_scan( | |
| 85 | _RandomAccessIterator __first, | |
| 86 | _RandomAccessIterator __last, | |
| 87 | _OutputIterator __result, | |
| 88 | _UnaryOperation __unary_op, | |
| 89 | _Tp __init, | |
| 90 | _BinaryOperation __binary_op, | |
| 91 | _Inclusive, | |
| 92 | /*is_vector=*/std::true_type) noexcept { | |
| 93 | #if defined(_PSTL_UDS_PRESENT) | |
| 94 | return __unseq_backend::__simd_scan( | |
| 95 | __first, __last - __first, __result, __unary_op, __init, __binary_op, _Inclusive()); | |
| 96 | #else | |
| 97 | // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive() | |
| 98 | // value | |
| 99 | return __internal::__brick_transform_scan( | |
| 100 | __first, | |
| 101 | __last, | |
| 102 | __result, | |
| 103 | __unary_op, | |
| 104 | __init, | |
| 105 | __binary_op, | |
| 106 | _Inclusive(), | |
| 107 | /*is_vector=*/std::false_type()); | |
| 108 | #endif | |
| 109 | } | |
| 110 | ||
| 111 | template <class _RandomAccessIterator, | |
| 112 | class _OutputIterator, | |
| 113 | class _UnaryOperation, | |
| 114 | class _Tp, | |
| 115 | class _BinaryOperation, | |
| 116 | class _Inclusive> | |
| 117 | typename std::enable_if<is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 118 | __brick_transform_scan( | |
| 119 | _RandomAccessIterator __first, | |
| 120 | _RandomAccessIterator __last, | |
| 121 | _OutputIterator __result, | |
| 122 | _UnaryOperation __unary_op, | |
| 123 | _Tp __init, | |
| 124 | _BinaryOperation __binary_op, | |
| 125 | _Inclusive, | |
| 126 | /*is_vector=*/std::true_type) noexcept { | |
| 127 | return __internal::__brick_transform_scan( | |
| 128 | __first, | |
| 129 | __last, | |
| 130 | __result, | |
| 131 | __unary_op, | |
| 132 | __init, | |
| 133 | __binary_op, | |
| 134 | _Inclusive(), | |
| 135 | /*is_vector=*/std::false_type()); | |
| 136 | } | |
| 137 | ||
| 138 | template <class _Tag, | |
| 139 | class _ExecutionPolicy, | |
| 140 | class _ForwardIterator, | |
| 141 | class _OutputIterator, | |
| 142 | class _UnaryOperation, | |
| 143 | class _Tp, | |
| 144 | class _BinaryOperation, | |
| 145 | class _Inclusive> | |
| 146 | _OutputIterator __pattern_transform_scan( | |
| 147 | _Tag, | |
| 148 | _ExecutionPolicy&&, | |
| 149 | _ForwardIterator __first, | |
| 150 | _ForwardIterator __last, | |
| 151 | _OutputIterator __result, | |
| 152 | _UnaryOperation __unary_op, | |
| 153 | _Tp __init, | |
| 154 | _BinaryOperation __binary_op, | |
| 155 | _Inclusive) noexcept { | |
| 156 | return __internal::__brick_transform_scan( | |
| 157 | __first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), typename _Tag::__is_vector{}) | |
| 158 | .first; | |
| 159 | } | |
| 160 | ||
| 161 | template <class _IsVector, | |
| 162 | class _ExecutionPolicy, | |
| 163 | class _RandomAccessIterator, | |
| 164 | class _OutputIterator, | |
| 165 | class _UnaryOperation, | |
| 166 | class _Tp, | |
| 167 | class _BinaryOperation, | |
| 168 | class _Inclusive> | |
| 169 | typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan( | |
| 170 | __parallel_tag<_IsVector> __tag, | |
| 171 | _ExecutionPolicy&& __exec, | |
| 172 | _RandomAccessIterator __first, | |
| 173 | _RandomAccessIterator __last, | |
| 174 | _OutputIterator __result, | |
| 175 | _UnaryOperation __unary_op, | |
| 176 | _Tp __init, | |
| 177 | _BinaryOperation __binary_op, | |
| 178 | _Inclusive) { | |
| 179 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 180 | ||
| 181 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; | |
| 182 | ||
| 183 | return __internal::__except_handler([&]() { | |
| 184 | __par_backend::__parallel_transform_scan( | |
| 185 | __backend_tag{}, | |
| 186 | std::forward<_ExecutionPolicy>(__exec), | |
| 187 | __last - __first, | |
| 188 | [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, | |
| 189 | __init, | |
| 190 | __binary_op, | |
| 191 | [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) { | |
| 192 | // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a | |
| 193 | // commutative operation for the guarantee of correct scan. | |
| 194 | return __internal::__brick_transform_reduce( | |
| 195 | __first + __i, | |
| 196 | __first + __j, | |
| 197 | __init, | |
| 198 | __binary_op, | |
| 199 | __unary_op, | |
| 200 | /*__is_vector*/ std::false_type()); | |
| 201 | }, | |
| 202 | [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) { | |
| 203 | return __internal::__brick_transform_scan( | |
| 204 | __first + __i, | |
| 205 | __first + __j, | |
| 206 | __result + __i, | |
| 207 | __unary_op, | |
| 208 | __init, | |
| 209 | __binary_op, | |
| 210 | _Inclusive(), | |
| 211 | _IsVector{}) | |
| 212 | .second; | |
| 213 | }); | |
| 214 | return __result + (__last - __first); | |
| 215 | }); | |
| 216 | } | |
| 217 | ||
| 218 | template <class _IsVector, | |
| 219 | class _ExecutionPolicy, | |
| 220 | class _RandomAccessIterator, | |
| 221 | class _OutputIterator, | |
| 222 | class _UnaryOperation, | |
| 223 | class _Tp, | |
| 224 | class _BinaryOperation, | |
| 225 | class _Inclusive> | |
| 226 | typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type __pattern_transform_scan( | |
| 227 | __parallel_tag<_IsVector> __tag, | |
| 228 | _ExecutionPolicy&& __exec, | |
| 229 | _RandomAccessIterator __first, | |
| 230 | _RandomAccessIterator __last, | |
| 231 | _OutputIterator __result, | |
| 232 | _UnaryOperation __unary_op, | |
| 233 | _Tp __init, | |
| 234 | _BinaryOperation __binary_op, | |
| 235 | _Inclusive) { | |
| 236 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 237 | ||
| 238 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; | |
| 239 | _DifferenceType __n = __last - __first; | |
| 240 | ||
| 241 | if (__n <= 0) { | |
| 242 | return __result; | |
| 243 | } | |
| 244 | return __internal::__except_handler([&]() { | |
| 245 | __par_backend::__parallel_strict_scan( | |
| 246 | __backend_tag{}, | |
| 247 | std::forward<_ExecutionPolicy>(__exec), | |
| 248 | __n, | |
| 249 | __init, | |
| 250 | [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) { | |
| 251 | return __internal::__brick_transform_scan( | |
| 252 | __first + __i, | |
| 253 | __first + (__i + __len), | |
| 254 | __result + __i, | |
| 255 | __unary_op, | |
| 256 | _Tp{}, | |
| 257 | __binary_op, | |
| 258 | _Inclusive(), | |
| 259 | _IsVector{}) | |
| 260 | .second; | |
| 261 | }, | |
| 262 | __binary_op, | |
| 263 | [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) { | |
| 264 | return *(std::transform(__result + __i, | |
| 265 | __result + __i + __len, | |
| 266 | __result + __i, | |
| 267 | [&__initial, &__binary_op](const _Tp& __x) { | |
| 268 | return __binary_op(__initial, __x); | |
| 269 | }) - | |
| 270 | 1); | |
| 271 | }, | |
| 272 | [](_Tp) {}); | |
| 273 | return __result + (__last - __first); | |
| 274 | }); | |
| 275 | } | |
| 276 | ||
| 277 | //------------------------------------------------------------------------ | |
| 278 | // adjacent_difference | |
| 279 | //------------------------------------------------------------------------ | |
| 280 | ||
| 281 | template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation> | |
| 282 | _OutputIterator __brick_adjacent_difference( | |
| 283 | _ForwardIterator __first, | |
| 284 | _ForwardIterator __last, | |
| 285 | _OutputIterator __d_first, | |
| 286 | _BinaryOperation __op, | |
| 287 | /*is_vector*/ std::false_type) noexcept { | |
| 288 | return std::adjacent_difference(__first, __last, __d_first, __op); | |
| 289 | } | |
| 290 | ||
| 291 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class BinaryOperation> | |
| 292 | _RandomAccessIterator2 __brick_adjacent_difference( | |
| 293 | _RandomAccessIterator1 __first, | |
| 294 | _RandomAccessIterator1 __last, | |
| 295 | _RandomAccessIterator2 __d_first, | |
| 296 | BinaryOperation __op, | |
| 297 | /*is_vector=*/std::true_type) noexcept { | |
| 298 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "Range cannot be empty"); | |
| 299 | ||
| 300 | typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; | |
| 301 | typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; | |
| 302 | ||
| 303 | auto __n = __last - __first; | |
| 304 | *__d_first = *__first; | |
| 305 | return __unseq_backend::__simd_walk_3( | |
| 306 | __first + 1, | |
| 307 | __n - 1, | |
| 308 | __first, | |
| 309 | __d_first + 1, | |
| 310 | [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); }); | |
| 311 | } | |
| 312 | ||
| 313 | template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation> | |
| 314 | _OutputIterator __pattern_adjacent_difference( | |
| 315 | _Tag, | |
| 316 | _ExecutionPolicy&&, | |
| 317 | _ForwardIterator __first, | |
| 318 | _ForwardIterator __last, | |
| 319 | _OutputIterator __d_first, | |
| 320 | _BinaryOperation __op) noexcept { | |
| 321 | return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{}); | |
| 322 | } | |
| 323 | ||
| 324 | template <class _IsVector, | |
| 325 | class _ExecutionPolicy, | |
| 326 | class _RandomAccessIterator1, | |
| 327 | class _RandomAccessIterator2, | |
| 328 | class _BinaryOperation> | |
| 329 | _RandomAccessIterator2 __pattern_adjacent_difference( | |
| 330 | __parallel_tag<_IsVector> __tag, | |
| 331 | _ExecutionPolicy&& __exec, | |
| 332 | _RandomAccessIterator1 __first, | |
| 333 | _RandomAccessIterator1 __last, | |
| 334 | _RandomAccessIterator2 __d_first, | |
| 335 | _BinaryOperation __op) { | |
| 336 | _LIBCPP_ASSERT_UNCATEGORIZED(__first != __last, "range cannot be empty"); | |
| 337 | typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; | |
| 338 | typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; | |
| 339 | ||
| 340 | using __backend_tag = typename decltype(__tag)::__backend_tag; | |
| 341 | ||
| 342 | *__d_first = *__first; | |
| 343 | __par_backend::__parallel_for( | |
| 344 | __backend_tag{}, | |
| 345 | std::forward<_ExecutionPolicy>(__exec), | |
| 346 | __first, | |
| 347 | __last - 1, | |
| 348 | [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { | |
| 349 | _RandomAccessIterator2 __d_b = __d_first + (__b - __first); | |
| 350 | __internal::__brick_walk3( | |
| 351 | __b, | |
| 352 | __e, | |
| 353 | __b + 1, | |
| 354 | __d_b + 1, | |
| 355 | [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); }, | |
| 356 | _IsVector{}); | |
| 357 | }); | |
| 358 | return __d_first + (__last - __first); | |
| 359 | } | |
| 360 | ||
| 361 | } // namespace __internal | |
| 362 | } // namespace __pstl | |
| 363 | ||
| 364 | #endif /* _PSTL_NUMERIC_IMPL_H */ |
lib/libcxx/include/__pstl/internal/omp/parallel_for.h created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_FOR_H | |
| 13 | ||
| 14 | #include <cstddef> | |
| 15 | ||
| 16 | #include "util.h" | |
| 17 | ||
| 18 | namespace __pstl | |
| 19 | { | |
| 20 | namespace __omp_backend | |
| 21 | { | |
| 22 | ||
| 23 | template <class _Index, class _Fp> | |
| 24 | void | |
| 25 | __parallel_for_body(_Index __first, _Index __last, _Fp __f) | |
| 26 | { | |
| 27 | // initial partition of the iteration space into chunks | |
| 28 | auto __policy = __omp_backend::__chunk_partitioner(__first, __last); | |
| 29 | ||
| 30 | // To avoid over-subscription we use taskloop for the nested parallelism | |
| 31 | _PSTL_PRAGMA(omp taskloop untied mergeable) | |
| 32 | for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk) | |
| 33 | { | |
| 34 | __pstl::__omp_backend::__process_chunk(__policy, __first, __chunk, __f); | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | //------------------------------------------------------------------------ | |
| 39 | // Notation: | |
| 40 | // Evaluation of brick f[i,j) for each subrange [i,j) of [first, last) | |
| 41 | //------------------------------------------------------------------------ | |
| 42 | ||
| 43 | template <class _ExecutionPolicy, class _Index, class _Fp> | |
| 44 | void | |
| 45 | __parallel_for(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) | |
| 46 | { | |
| 47 | if (omp_in_parallel()) | |
| 48 | { | |
| 49 | // we don't create a nested parallel region in an existing parallel | |
| 50 | // region: just create tasks | |
| 51 | __pstl::__omp_backend::__parallel_for_body(__first, __last, __f); | |
| 52 | } | |
| 53 | else | |
| 54 | { | |
| 55 | // in any case (nested or non-nested) one parallel region is created and | |
| 56 | // only one thread creates a set of tasks | |
| 57 | _PSTL_PRAGMA(omp parallel) | |
| 58 | _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_body(__first, __last, __f); } | |
| 59 | } | |
| 60 | } | |
| 61 | ||
| 62 | } // namespace __omp_backend | |
| 63 | } // namespace __pstl | |
| 64 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_H |
lib/libcxx/include/__pstl/internal/omp/parallel_for_each.h created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <class _ForwardIterator, class _Fp> | |
| 22 | void | |
| 23 | __parallel_for_each_body(_ForwardIterator __first, _ForwardIterator __last, _Fp __f) | |
| 24 | { | |
| 25 | using DifferenceType = typename std::iterator_traits<_ForwardIterator>::difference_type; | |
| 26 | // TODO: Think of an approach to remove the std::distance call | |
| 27 | auto __size = std::distance(__first, __last); | |
| 28 | ||
| 29 | _PSTL_PRAGMA(omp taskloop untied mergeable) | |
| 30 | for (DifferenceType __index = 0; __index < __size; ++__index) | |
| 31 | { | |
| 32 | // TODO: Think of an approach to remove the increment here each time. | |
| 33 | auto __iter = std::next(__first, __index); | |
| 34 | __f(*__iter); | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | template <class _ExecutionPolicy, class _ForwardIterator, class _Fp> | |
| 39 | void | |
| 40 | __parallel_for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Fp __f) | |
| 41 | { | |
| 42 | if (omp_in_parallel()) | |
| 43 | { | |
| 44 | // we don't create a nested parallel region in an existing parallel | |
| 45 | // region: just create tasks | |
| 46 | __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f); | |
| 47 | } | |
| 48 | else | |
| 49 | { | |
| 50 | // in any case (nested or non-nested) one parallel region is created and | |
| 51 | // only one thread creates a set of tasks | |
| 52 | _PSTL_PRAGMA(omp parallel) | |
| 53 | _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_each_body(__first, __last, __f); } | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | } // namespace __omp_backend | |
| 58 | } // namespace __pstl | |
| 59 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_EACH_H |
lib/libcxx/include/__pstl/internal/omp/parallel_invoke.h created+50| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <typename _F1, typename _F2> | |
| 22 | void | |
| 23 | __parallel_invoke_body(_F1&& __f1, _F2&& __f2) | |
| 24 | { | |
| 25 | _PSTL_PRAGMA(omp taskgroup) | |
| 26 | { | |
| 27 | _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F1>(__f1)(); } | |
| 28 | _PSTL_PRAGMA(omp task untied mergeable) { std::forward<_F2>(__f2)(); } | |
| 29 | } | |
| 30 | } | |
| 31 | ||
| 32 | template <class _ExecutionPolicy, typename _F1, typename _F2> | |
| 33 | void | |
| 34 | __parallel_invoke(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) | |
| 35 | { | |
| 36 | if (omp_in_parallel()) | |
| 37 | { | |
| 38 | __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); | |
| 39 | } | |
| 40 | else | |
| 41 | { | |
| 42 | _PSTL_PRAGMA(omp parallel) | |
| 43 | _PSTL_PRAGMA(omp single nowait) | |
| 44 | __pstl::__omp_backend::__parallel_invoke_body(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | } // namespace __omp_backend | |
| 49 | } // namespace __pstl | |
| 50 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_INVOKE_H |
lib/libcxx/include/__pstl/internal/omp/parallel_merge.h created+98| ... | ... | @@ -0,0 +1,98 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3, | |
| 22 | typename _Compare, typename _LeafMerge> | |
| 23 | void | |
| 24 | __parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessIterator1 __xs, | |
| 25 | _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, | |
| 26 | _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge) | |
| 27 | { | |
| 28 | ||
| 29 | if (__size_x + __size_y <= __omp_backend::__default_chunk_size) | |
| 30 | { | |
| 31 | __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp); | |
| 32 | return; | |
| 33 | } | |
| 34 | ||
| 35 | _RandomAccessIterator1 __xm; | |
| 36 | _RandomAccessIterator2 __ym; | |
| 37 | ||
| 38 | if (__size_x < __size_y) | |
| 39 | { | |
| 40 | __ym = __ys + (__size_y / 2); | |
| 41 | __xm = std::upper_bound(__xs, __xe, *__ym, __comp); | |
| 42 | } | |
| 43 | else | |
| 44 | { | |
| 45 | __xm = __xs + (__size_x / 2); | |
| 46 | __ym = std::lower_bound(__ys, __ye, *__xm, __comp); | |
| 47 | } | |
| 48 | ||
| 49 | auto __zm = __zs + (__xm - __xs) + (__ym - __ys); | |
| 50 | ||
| 51 | _PSTL_PRAGMA(omp task untied mergeable default(none) | |
| 52 | firstprivate(__xs, __xm, __ys, __ym, __zs, __comp, __leaf_merge)) | |
| 53 | __pstl::__omp_backend::__parallel_merge_body(__xm - __xs, __ym - __ys, __xs, __xm, __ys, __ym, __zs, __comp, | |
| 54 | __leaf_merge); | |
| 55 | ||
| 56 | _PSTL_PRAGMA(omp task untied mergeable default(none) | |
| 57 | firstprivate(__xm, __xe, __ym, __ye, __zm, __comp, __leaf_merge)) | |
| 58 | __pstl::__omp_backend::__parallel_merge_body(__xe - __xm, __ye - __ym, __xm, __xe, __ym, __ye, __zm, __comp, | |
| 59 | __leaf_merge); | |
| 60 | ||
| 61 | _PSTL_PRAGMA(omp taskwait) | |
| 62 | } | |
| 63 | ||
| 64 | template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2, | |
| 65 | typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge> | |
| 66 | void | |
| 67 | __parallel_merge(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs, | |
| 68 | _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, | |
| 69 | _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge) | |
| 70 | ||
| 71 | { | |
| 72 | std::size_t __size_x = __xe - __xs; | |
| 73 | std::size_t __size_y = __ye - __ys; | |
| 74 | ||
| 75 | /* | |
| 76 | * Run the merge in parallel by chunking it up. Use the smaller range (if any) as the iteration range, and the | |
| 77 | * larger range as the search range. | |
| 78 | */ | |
| 79 | ||
| 80 | if (omp_in_parallel()) | |
| 81 | { | |
| 82 | __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp, | |
| 83 | __leaf_merge); | |
| 84 | } | |
| 85 | else | |
| 86 | { | |
| 87 | _PSTL_PRAGMA(omp parallel) | |
| 88 | { | |
| 89 | _PSTL_PRAGMA(omp single nowait) | |
| 90 | __pstl::__omp_backend::__parallel_merge_body(__size_x, __size_y, __xs, __xe, __ys, __ye, __zs, __comp, | |
| 91 | __leaf_merge); | |
| 92 | } | |
| 93 | } | |
| 94 | } | |
| 95 | ||
| 96 | } // namespace __omp_backend | |
| 97 | } // namespace __pstl | |
| 98 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_MERGE_H |
lib/libcxx/include/__pstl/internal/omp/parallel_reduce.h created+73| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction> | |
| 22 | _Value | |
| 23 | __parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity, | |
| 24 | _RealBody __real_body, _Reduction __reduce) | |
| 25 | { | |
| 26 | if (__should_run_serial(__first, __last)) | |
| 27 | { | |
| 28 | return __real_body(__first, __last, __identity); | |
| 29 | } | |
| 30 | ||
| 31 | auto __middle = __first + ((__last - __first) / 2); | |
| 32 | _Value __v1(__identity), __v2(__identity); | |
| 33 | __parallel_invoke_body( | |
| 34 | [&]() { __v1 = __parallel_reduce_body(__first, __middle, __identity, __real_body, __reduce); }, | |
| 35 | [&]() { __v2 = __parallel_reduce_body(__middle, __last, __identity, __real_body, __reduce); }); | |
| 36 | ||
| 37 | return __reduce(__v1, __v2); | |
| 38 | } | |
| 39 | ||
| 40 | //------------------------------------------------------------------------ | |
| 41 | // Notation: | |
| 42 | // r(i,j,init) returns reduction of init with reduction over [i,j) | |
| 43 | // c(x,y) combines values x and y that were the result of r | |
| 44 | //------------------------------------------------------------------------ | |
| 45 | ||
| 46 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction> | |
| 47 | _Value | |
| 48 | __parallel_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first, | |
| 49 | _RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction) | |
| 50 | { | |
| 51 | // We don't create a nested parallel region in an existing parallel region: | |
| 52 | // just create tasks. | |
| 53 | if (omp_in_parallel()) | |
| 54 | { | |
| 55 | return __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction); | |
| 56 | } | |
| 57 | ||
| 58 | // In any case (nested or non-nested) one parallel region is created and only | |
| 59 | // one thread creates a set of tasks. | |
| 60 | _Value __res = __identity; | |
| 61 | ||
| 62 | _PSTL_PRAGMA(omp parallel) | |
| 63 | _PSTL_PRAGMA(omp single nowait) | |
| 64 | { | |
| 65 | __res = __pstl::__omp_backend::__parallel_reduce_body(__first, __last, __identity, __real_body, __reduction); | |
| 66 | } | |
| 67 | ||
| 68 | return __res; | |
| 69 | } | |
| 70 | ||
| 71 | } // namespace __omp_backend | |
| 72 | } // namespace __pstl | |
| 73 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_REDUCE_H |
lib/libcxx/include/__pstl/internal/omp/parallel_scan.h created+136| ... | ... | @@ -0,0 +1,136 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H | |
| 13 | ||
| 14 | #include "parallel_invoke.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <typename _Index> | |
| 22 | _Index | |
| 23 | __split(_Index __m) | |
| 24 | { | |
| 25 | _Index __k = 1; | |
| 26 | while (2 * __k < __m) | |
| 27 | __k *= 2; | |
| 28 | return __k; | |
| 29 | } | |
| 30 | ||
| 31 | template <typename _Index, typename _Tp, typename _Rp, typename _Cp> | |
| 32 | void | |
| 33 | __upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine) | |
| 34 | { | |
| 35 | if (__m == 1) | |
| 36 | __r[0] = __reduce(__i * __tilesize, __lastsize); | |
| 37 | else | |
| 38 | { | |
| 39 | _Index __k = __split(__m); | |
| 40 | __omp_backend::__parallel_invoke_body( | |
| 41 | [=] { __omp_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); }, | |
| 42 | [=] { | |
| 43 | __omp_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine); | |
| 44 | }); | |
| 45 | if (__m == 2 * __k) | |
| 46 | __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | template <typename _Index, typename _Tp, typename _Cp, typename _Sp> | |
| 51 | void | |
| 52 | __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine, | |
| 53 | _Sp __scan) | |
| 54 | { | |
| 55 | if (__m == 1) | |
| 56 | __scan(__i * __tilesize, __lastsize, __initial); | |
| 57 | else | |
| 58 | { | |
| 59 | const _Index __k = __split(__m); | |
| 60 | __omp_backend::__parallel_invoke_body( | |
| 61 | [=] { __omp_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); }, | |
| 62 | // Assumes that __combine never throws. | |
| 63 | // TODO: Consider adding a requirement for user functors to be constant. | |
| 64 | [=, &__combine] | |
| 65 | { | |
| 66 | __omp_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, | |
| 67 | __combine(__initial, __r[__k - 1]), __combine, __scan); | |
| 68 | }); | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | template <typename _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, | |
| 73 | typename _Ap> | |
| 74 | void | |
| 75 | __parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) | |
| 76 | { | |
| 77 | _Index __p = omp_get_num_threads(); | |
| 78 | const _Index __slack = 4; | |
| 79 | _Index __tilesize = (__n - 1) / (__slack * __p) + 1; | |
| 80 | _Index __m = (__n - 1) / __tilesize; | |
| 81 | __buffer<_Tp> __buf(__m + 1); | |
| 82 | _Tp* __r = __buf.get(); | |
| 83 | ||
| 84 | __omp_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, __combine); | |
| 85 | ||
| 86 | std::size_t __k = __m + 1; | |
| 87 | _Tp __t = __r[__k - 1]; | |
| 88 | while ((__k &= __k - 1)) | |
| 89 | { | |
| 90 | __t = __combine(__r[__k - 1], __t); | |
| 91 | } | |
| 92 | ||
| 93 | __apex(__combine(__initial, __t)); | |
| 94 | __omp_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial, | |
| 95 | __combine, __scan); | |
| 96 | } | |
| 97 | ||
| 98 | template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> | |
| 99 | void | |
| 100 | __parallel_strict_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial, | |
| 101 | _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) | |
| 102 | { | |
| 103 | if (__n <= __default_chunk_size) | |
| 104 | { | |
| 105 | _Tp __sum = __initial; | |
| 106 | if (__n) | |
| 107 | { | |
| 108 | __sum = __combine(__sum, __reduce(_Index(0), __n)); | |
| 109 | } | |
| 110 | __apex(__sum); | |
| 111 | if (__n) | |
| 112 | { | |
| 113 | __scan(_Index(0), __n, __initial); | |
| 114 | } | |
| 115 | return; | |
| 116 | } | |
| 117 | ||
| 118 | if (omp_in_parallel()) | |
| 119 | { | |
| 120 | __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine, | |
| 121 | __scan, __apex); | |
| 122 | } | |
| 123 | else | |
| 124 | { | |
| 125 | _PSTL_PRAGMA(omp parallel) | |
| 126 | _PSTL_PRAGMA(omp single nowait) | |
| 127 | { | |
| 128 | __pstl::__omp_backend::__parallel_strict_scan_body<_ExecutionPolicy>(__n, __initial, __reduce, __combine, | |
| 129 | __scan, __apex); | |
| 130 | } | |
| 131 | } | |
| 132 | } | |
| 133 | ||
| 134 | } // namespace __omp_backend | |
| 135 | } // namespace __pstl | |
| 136 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_SCAN_H |
lib/libcxx/include/__pstl/internal/omp/parallel_stable_partial_sort.h created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort> | |
| 22 | void | |
| 23 | __parallel_stable_partial_sort(__pstl::__internal::__openmp_backend_tag, _RandomAccessIterator __xs, | |
| 24 | _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, | |
| 25 | std::size_t /* __nsort */) | |
| 26 | { | |
| 27 | // TODO: "Parallel partial sort needs to be implemented."); | |
| 28 | __leaf_sort(__xs, __xe, __comp); | |
| 29 | } | |
| 30 | ||
| 31 | } // namespace __omp_backend | |
| 32 | } // namespace __pstl | |
| 33 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_PARTIAL_SORT_H |
lib/libcxx/include/__pstl/internal/omp/parallel_stable_sort.h created+160| ... | ... | @@ -0,0 +1,160 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | #include "parallel_merge.h" | |
| 16 | ||
| 17 | namespace __pstl | |
| 18 | { | |
| 19 | namespace __omp_backend | |
| 20 | { | |
| 21 | ||
| 22 | namespace __sort_details | |
| 23 | { | |
| 24 | struct __move_value | |
| 25 | { | |
| 26 | template <typename _Iterator, typename _OutputIterator> | |
| 27 | void | |
| 28 | operator()(_Iterator __x, _OutputIterator __z) const | |
| 29 | { | |
| 30 | *__z = std::move(*__x); | |
| 31 | } | |
| 32 | }; | |
| 33 | ||
| 34 | template <typename _RandomAccessIterator, typename _OutputIterator> | |
| 35 | _OutputIterator | |
| 36 | __parallel_move_range(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first) | |
| 37 | { | |
| 38 | std::size_t __size = __last1 - __first1; | |
| 39 | ||
| 40 | // Perform serial moving of small chunks | |
| 41 | ||
| 42 | if (__size <= __default_chunk_size) | |
| 43 | { | |
| 44 | return std::move(__first1, __last1, __d_first); | |
| 45 | } | |
| 46 | ||
| 47 | // Perform parallel moving of larger chunks | |
| 48 | auto __policy = __pstl::__omp_backend::__chunk_partitioner(__first1, __last1); | |
| 49 | ||
| 50 | _PSTL_PRAGMA(omp taskloop) | |
| 51 | for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk) | |
| 52 | { | |
| 53 | __pstl::__omp_backend::__process_chunk(__policy, __first1, __chunk, | |
| 54 | [&](auto __chunk_first, auto __chunk_last) | |
| 55 | { | |
| 56 | auto __chunk_offset = __chunk_first - __first1; | |
| 57 | auto __output_it = __d_first + __chunk_offset; | |
| 58 | std::move(__chunk_first, __chunk_last, __output_it); | |
| 59 | }); | |
| 60 | } | |
| 61 | ||
| 62 | return __d_first + __size; | |
| 63 | } | |
| 64 | ||
| 65 | struct __move_range | |
| 66 | { | |
| 67 | template <typename _RandomAccessIterator, typename _OutputIterator> | |
| 68 | _OutputIterator | |
| 69 | operator()(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _OutputIterator __d_first) const | |
| 70 | { | |
| 71 | return __pstl::__omp_backend::__sort_details::__parallel_move_range(__first1, __last1, __d_first); | |
| 72 | } | |
| 73 | }; | |
| 74 | } // namespace __sort_details | |
| 75 | ||
| 76 | template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort> | |
| 77 | void | |
| 78 | __parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, | |
| 79 | _LeafSort __leaf_sort) | |
| 80 | { | |
| 81 | using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type; | |
| 82 | using _VecType = typename std::vector<_ValueType>; | |
| 83 | using _OutputIterator = typename _VecType::iterator; | |
| 84 | using _MoveValue = typename __omp_backend::__sort_details::__move_value; | |
| 85 | using _MoveRange = __omp_backend::__sort_details::__move_range; | |
| 86 | ||
| 87 | if (__should_run_serial(__xs, __xe)) | |
| 88 | { | |
| 89 | __leaf_sort(__xs, __xe, __comp); | |
| 90 | } | |
| 91 | else | |
| 92 | { | |
| 93 | std::size_t __size = __xe - __xs; | |
| 94 | auto __mid = __xs + (__size / 2); | |
| 95 | __pstl::__omp_backend::__parallel_invoke_body( | |
| 96 | [&]() { __parallel_stable_sort_body(__xs, __mid, __comp, __leaf_sort); }, | |
| 97 | [&]() { __parallel_stable_sort_body(__mid, __xe, __comp, __leaf_sort); }); | |
| 98 | ||
| 99 | // Perform a parallel merge of the sorted ranges into __output_data. | |
| 100 | _VecType __output_data(__size); | |
| 101 | _MoveValue __move_value; | |
| 102 | _MoveRange __move_range; | |
| 103 | __utils::__serial_move_merge __merge(__size); | |
| 104 | __pstl::__omp_backend::__parallel_merge_body( | |
| 105 | __mid - __xs, __xe - __mid, __xs, __mid, __mid, __xe, __output_data.begin(), __comp, | |
| 106 | [&__merge, &__move_value, &__move_range](_RandomAccessIterator __as, _RandomAccessIterator __ae, | |
| 107 | _RandomAccessIterator __bs, _RandomAccessIterator __be, | |
| 108 | _OutputIterator __cs, _Compare __comp) | |
| 109 | { __merge(__as, __ae, __bs, __be, __cs, __comp, __move_value, __move_value, __move_range, __move_range); }); | |
| 110 | ||
| 111 | // Move the values from __output_data back in the original source range. | |
| 112 | __pstl::__omp_backend::__sort_details::__parallel_move_range(__output_data.begin(), __output_data.end(), __xs); | |
| 113 | } | |
| 114 | } | |
| 115 | ||
| 116 | template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> | |
| 117 | void | |
| 118 | __parallel_stable_sort(__pstl::__internal::__openmp_backend_tag __tag, _ExecutionPolicy&& /*__exec*/, | |
| 119 | _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, | |
| 120 | std::size_t __nsort = 0) | |
| 121 | { | |
| 122 | auto __count = static_cast<std::size_t>(__xe - __xs); | |
| 123 | if (__count <= __default_chunk_size || __nsort < __count) | |
| 124 | { | |
| 125 | __leaf_sort(__xs, __xe, __comp); | |
| 126 | return; | |
| 127 | } | |
| 128 | ||
| 129 | // TODO: the partial sort implementation should | |
| 130 | // be shared with the other backends. | |
| 131 | ||
| 132 | if (omp_in_parallel()) | |
| 133 | { | |
| 134 | if (__count <= __nsort) | |
| 135 | { | |
| 136 | __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort); | |
| 137 | } | |
| 138 | else | |
| 139 | { | |
| 140 | __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort); | |
| 141 | } | |
| 142 | } | |
| 143 | else | |
| 144 | { | |
| 145 | _PSTL_PRAGMA(omp parallel) | |
| 146 | _PSTL_PRAGMA(omp single nowait) | |
| 147 | if (__count <= __nsort) | |
| 148 | { | |
| 149 | __pstl::__omp_backend::__parallel_stable_sort_body(__xs, __xe, __comp, __leaf_sort); | |
| 150 | } | |
| 151 | else | |
| 152 | { | |
| 153 | __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort); | |
| 154 | } | |
| 155 | } | |
| 156 | } | |
| 157 | ||
| 158 | } // namespace __omp_backend | |
| 159 | } // namespace __pstl | |
| 160 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_STABLE_SORT_H |
lib/libcxx/include/__pstl/internal/omp/parallel_transform_reduce.h created+113| ... | ... | @@ -0,0 +1,113 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | //------------------------------------------------------------------------ | |
| 22 | // parallel_transform_reduce | |
| 23 | // | |
| 24 | // Notation: | |
| 25 | // r(i,j,init) returns reduction of init with reduction over [i,j) | |
| 26 | // u(i) returns f(i,i+1,identity) for a hypothetical left identity element | |
| 27 | // of r c(x,y) combines values x and y that were the result of r or u | |
| 28 | //------------------------------------------------------------------------ | |
| 29 | ||
| 30 | template <class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner, class _Reduction> | |
| 31 | auto | |
| 32 | __transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, | |
| 33 | _Combiner __combiner, _Reduction __reduction) | |
| 34 | { | |
| 35 | const std::size_t __num_threads = omp_get_num_threads(); | |
| 36 | const std::size_t __size = __last - __first; | |
| 37 | ||
| 38 | // Initial partition of the iteration space into chunks. If the range is too small, | |
| 39 | // this will result in a nonsense policy, so we check on the size as well below. | |
| 40 | auto __policy = __omp_backend::__chunk_partitioner(__first + __num_threads, __last); | |
| 41 | ||
| 42 | if (__size <= __num_threads || __policy.__n_chunks < 2) | |
| 43 | { | |
| 44 | return __reduction(__first, __last, __init); | |
| 45 | } | |
| 46 | ||
| 47 | // Here, we cannot use OpenMP UDR because we must store the init value in | |
| 48 | // the combiner and it will be used several times. Although there should be | |
| 49 | // the only one; we manually generate the identity elements for each thread. | |
| 50 | std::vector<_Value> __accums; | |
| 51 | __accums.reserve(__num_threads); | |
| 52 | ||
| 53 | // initialize accumulators for all threads | |
| 54 | for (std::size_t __i = 0; __i < __num_threads; ++__i) | |
| 55 | { | |
| 56 | __accums.emplace_back(__unary_op(__first + __i)); | |
| 57 | } | |
| 58 | ||
| 59 | // main loop | |
| 60 | _PSTL_PRAGMA(omp taskloop shared(__accums)) | |
| 61 | for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk) | |
| 62 | { | |
| 63 | __pstl::__omp_backend::__process_chunk(__policy, __first + __num_threads, __chunk, | |
| 64 | [&](auto __chunk_first, auto __chunk_last) | |
| 65 | { | |
| 66 | auto __thread_num = omp_get_thread_num(); | |
| 67 | __accums[__thread_num] = | |
| 68 | __reduction(__chunk_first, __chunk_last, __accums[__thread_num]); | |
| 69 | }); | |
| 70 | } | |
| 71 | ||
| 72 | // combine by accumulators | |
| 73 | for (std::size_t __i = 0; __i < __num_threads; ++__i) | |
| 74 | { | |
| 75 | __init = __combiner(__init, __accums[__i]); | |
| 76 | } | |
| 77 | ||
| 78 | return __init; | |
| 79 | } | |
| 80 | ||
| 81 | template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner, | |
| 82 | class _Reduction> | |
| 83 | _Value | |
| 84 | __parallel_transform_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first, | |
| 85 | _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, _Combiner __combiner, | |
| 86 | _Reduction __reduction) | |
| 87 | { | |
| 88 | _Value __result = __init; | |
| 89 | if (omp_in_parallel()) | |
| 90 | { | |
| 91 | // We don't create a nested parallel region in an existing parallel | |
| 92 | // region: just create tasks | |
| 93 | __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner, | |
| 94 | __reduction); | |
| 95 | } | |
| 96 | else | |
| 97 | { | |
| 98 | // Create a parallel region, and a single thread will create tasks | |
| 99 | // for the region. | |
| 100 | _PSTL_PRAGMA(omp parallel) | |
| 101 | _PSTL_PRAGMA(omp single nowait) | |
| 102 | { | |
| 103 | __result = __pstl::__omp_backend::__transform_reduce_body(__first, __last, __unary_op, __init, __combiner, | |
| 104 | __reduction); | |
| 105 | } | |
| 106 | } | |
| 107 | ||
| 108 | return __result; | |
| 109 | } | |
| 110 | ||
| 111 | } // namespace __omp_backend | |
| 112 | } // namespace __pstl | |
| 113 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_REDUCE_H |
lib/libcxx/include/__pstl/internal/omp/parallel_transform_scan.h created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H | |
| 12 | #define _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | ||
| 16 | namespace __pstl | |
| 17 | { | |
| 18 | namespace __omp_backend | |
| 19 | { | |
| 20 | ||
| 21 | template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp> | |
| 22 | _Tp | |
| 23 | __parallel_transform_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */, | |
| 24 | _Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan) | |
| 25 | { | |
| 26 | // TODO: parallelize this function. | |
| 27 | return __scan(_Index(0), __n, __init); | |
| 28 | } | |
| 29 | ||
| 30 | } // namespace __omp_backend | |
| 31 | } // namespace __pstl | |
| 32 | #endif // _PSTL_INTERNAL_OMP_PARALLEL_TRANSFORM_SCAN_H |
lib/libcxx/include/__pstl/internal/omp/util.h created+171| ... | ... | @@ -0,0 +1,171 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_INTERNAL_OMP_UTIL_H | |
| 12 | #define _PSTL_INTERNAL_OMP_UTIL_H | |
| 13 | ||
| 14 | #include <algorithm> | |
| 15 | #include <atomic> | |
| 16 | #include <iterator> | |
| 17 | #include <cstddef> | |
| 18 | #include <cstdio> | |
| 19 | #include <memory> | |
| 20 | #include <vector> | |
| 21 | #include <omp.h> | |
| 22 | ||
| 23 | #include "../parallel_backend_utils.h" | |
| 24 | #include "../unseq_backend_simd.h" | |
| 25 | #include "../utils.h" | |
| 26 | ||
| 27 | // Portability "#pragma" definition | |
| 28 | #ifdef _MSC_VER | |
| 29 | # define _PSTL_PRAGMA(x) __pragma(x) | |
| 30 | #else | |
| 31 | # define _PSTL_PRAGMA(x) _Pragma(# x) | |
| 32 | #endif | |
| 33 | ||
| 34 | namespace __pstl | |
| 35 | { | |
| 36 | namespace __omp_backend | |
| 37 | { | |
| 38 | ||
| 39 | //------------------------------------------------------------------------ | |
| 40 | // use to cancel execution | |
| 41 | //------------------------------------------------------------------------ | |
| 42 | inline void | |
| 43 | __cancel_execution() | |
| 44 | { | |
| 45 | // TODO: Figure out how to make cancelation work. | |
| 46 | } | |
| 47 | ||
| 48 | //------------------------------------------------------------------------ | |
| 49 | // raw buffer | |
| 50 | //------------------------------------------------------------------------ | |
| 51 | ||
| 52 | template <typename _Tp> | |
| 53 | class __buffer | |
| 54 | { | |
| 55 | std::allocator<_Tp> __allocator_; | |
| 56 | _Tp* __ptr_; | |
| 57 | const std::size_t __buf_size_; | |
| 58 | __buffer(const __buffer&) = delete; | |
| 59 | void | |
| 60 | operator=(const __buffer&) = delete; | |
| 61 | ||
| 62 | public: | |
| 63 | __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {} | |
| 64 | ||
| 65 | operator bool() const { return __ptr_ != nullptr; } | |
| 66 | ||
| 67 | _Tp* | |
| 68 | get() const | |
| 69 | { | |
| 70 | return __ptr_; | |
| 71 | } | |
| 72 | ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); } | |
| 73 | }; | |
| 74 | ||
| 75 | // Preliminary size of each chunk: requires further discussion | |
| 76 | inline constexpr std::size_t __default_chunk_size = 2048; | |
| 77 | ||
| 78 | // Convenience function to determine when we should run serial. | |
| 79 | template <typename _Iterator, std::enable_if_t<!std::is_integral<_Iterator>::value, bool> = true> | |
| 80 | constexpr auto | |
| 81 | __should_run_serial(_Iterator __first, _Iterator __last) -> bool | |
| 82 | { | |
| 83 | using _difference_type = typename std::iterator_traits<_Iterator>::difference_type; | |
| 84 | auto __size = std::distance(__first, __last); | |
| 85 | return __size <= static_cast<_difference_type>(__default_chunk_size); | |
| 86 | } | |
| 87 | ||
| 88 | template <typename _Index, std::enable_if_t<std::is_integral<_Index>::value, bool> = true> | |
| 89 | constexpr auto | |
| 90 | __should_run_serial(_Index __first, _Index __last) -> bool | |
| 91 | { | |
| 92 | using _difference_type = _Index; | |
| 93 | auto __size = __last - __first; | |
| 94 | return __size <= static_cast<_difference_type>(__default_chunk_size); | |
| 95 | } | |
| 96 | ||
| 97 | struct __chunk_metrics | |
| 98 | { | |
| 99 | std::size_t __n_chunks; | |
| 100 | std::size_t __chunk_size; | |
| 101 | std::size_t __first_chunk_size; | |
| 102 | }; | |
| 103 | ||
| 104 | // The iteration space partitioner according to __requested_chunk_size | |
| 105 | template <class _RandomAccessIterator, class _Size = std::size_t> | |
| 106 | auto | |
| 107 | __chunk_partitioner(_RandomAccessIterator __first, _RandomAccessIterator __last, | |
| 108 | _Size __requested_chunk_size = __default_chunk_size) -> __chunk_metrics | |
| 109 | { | |
| 110 | /* | |
| 111 | * This algorithm improves distribution of elements in chunks by avoiding | |
| 112 | * small tail chunks. The leftover elements that do not fit neatly into | |
| 113 | * the chunk size are redistributed to early chunks. This improves | |
| 114 | * utilization of the processor's prefetch and reduces the number of | |
| 115 | * tasks needed by 1. | |
| 116 | */ | |
| 117 | ||
| 118 | const _Size __n = __last - __first; | |
| 119 | _Size __n_chunks = 0; | |
| 120 | _Size __chunk_size = 0; | |
| 121 | _Size __first_chunk_size = 0; | |
| 122 | if (__n < __requested_chunk_size) | |
| 123 | { | |
| 124 | __chunk_size = __n; | |
| 125 | __first_chunk_size = __n; | |
| 126 | __n_chunks = 1; | |
| 127 | return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size}; | |
| 128 | } | |
| 129 | ||
| 130 | __n_chunks = (__n / __requested_chunk_size) + 1; | |
| 131 | __chunk_size = __n / __n_chunks; | |
| 132 | __first_chunk_size = __chunk_size; | |
| 133 | const _Size __n_leftover_items = __n - (__n_chunks * __chunk_size); | |
| 134 | ||
| 135 | if (__n_leftover_items == __chunk_size) | |
| 136 | { | |
| 137 | __n_chunks += 1; | |
| 138 | return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size}; | |
| 139 | } | |
| 140 | else if (__n_leftover_items == 0) | |
| 141 | { | |
| 142 | __first_chunk_size = __chunk_size; | |
| 143 | return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size}; | |
| 144 | } | |
| 145 | ||
| 146 | const _Size __n_extra_items_per_chunk = __n_leftover_items / __n_chunks; | |
| 147 | const _Size __n_final_leftover_items = __n_leftover_items - (__n_extra_items_per_chunk * __n_chunks); | |
| 148 | ||
| 149 | __chunk_size += __n_extra_items_per_chunk; | |
| 150 | __first_chunk_size = __chunk_size + __n_final_leftover_items; | |
| 151 | ||
| 152 | return __chunk_metrics{__n_chunks, __chunk_size, __first_chunk_size}; | |
| 153 | } | |
| 154 | ||
| 155 | template <typename _Iterator, typename _Index, typename _Func> | |
| 156 | void | |
| 157 | __process_chunk(const __chunk_metrics& __metrics, _Iterator __base, _Index __chunk_index, _Func __f) | |
| 158 | { | |
| 159 | auto __this_chunk_size = __chunk_index == 0 ? __metrics.__first_chunk_size : __metrics.__chunk_size; | |
| 160 | auto __index = __chunk_index == 0 ? 0 | |
| 161 | : (__chunk_index * __metrics.__chunk_size) + | |
| 162 | (__metrics.__first_chunk_size - __metrics.__chunk_size); | |
| 163 | auto __first = __base + __index; | |
| 164 | auto __last = __first + __this_chunk_size; | |
| 165 | __f(__first, __last); | |
| 166 | } | |
| 167 | ||
| 168 | } // namespace __omp_backend | |
| 169 | } // namespace __pstl | |
| 170 | ||
| 171 | #endif // _PSTL_INTERNAL_OMP_UTIL_H |
lib/libcxx/include/__pstl/internal/parallel_backend.h created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_PARALLEL_BACKEND_H | |
| 11 | #define _PSTL_PARALLEL_BACKEND_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | ||
| 15 | #if defined(_PSTL_PAR_BACKEND_SERIAL) | |
| 16 | # include "parallel_backend_serial.h" | |
| 17 | # if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 18 | namespace __pstl | |
| 19 | { | |
| 20 | namespace __par_backend = __serial_backend; | |
| 21 | } // namespace __pstl | |
| 22 | # endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 23 | #elif defined(_PSTL_PAR_BACKEND_TBB) | |
| 24 | # include "parallel_backend_tbb.h" | |
| 25 | namespace __pstl | |
| 26 | { | |
| 27 | namespace __par_backend = __tbb_backend; | |
| 28 | } | |
| 29 | #elif defined(_PSTL_PAR_BACKEND_OPENMP) | |
| 30 | # include "parallel_backend_omp.h" | |
| 31 | namespace __pstl | |
| 32 | { | |
| 33 | namespace __par_backend = __omp_backend; | |
| 34 | } | |
| 35 | #else | |
| 36 | # error "No backend set" | |
| 37 | #endif | |
| 38 | ||
| 39 | #endif /* _PSTL_PARALLEL_BACKEND_H */ |
lib/libcxx/include/__pstl/internal/parallel_backend_omp.h created+58| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | // -*- C++ -*- | |
| 2 | // -*-===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 5 | // | |
| 6 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 7 | // See https://llvm.org/LICENSE.txt for license information. | |
| 8 | // | |
| 9 | //===----------------------------------------------------------------------===// | |
| 10 | ||
| 11 | #ifndef _PSTL_PARALLEL_BACKEND_OMP_H | |
| 12 | #define _PSTL_PARALLEL_BACKEND_OMP_H | |
| 13 | ||
| 14 | //------------------------------------------------------------------------ | |
| 15 | // parallel_invoke | |
| 16 | //------------------------------------------------------------------------ | |
| 17 | ||
| 18 | #include "./omp/parallel_invoke.h" | |
| 19 | ||
| 20 | //------------------------------------------------------------------------ | |
| 21 | // parallel_for | |
| 22 | //------------------------------------------------------------------------ | |
| 23 | ||
| 24 | #include "./omp/parallel_for.h" | |
| 25 | ||
| 26 | //------------------------------------------------------------------------ | |
| 27 | // parallel_for_each | |
| 28 | //------------------------------------------------------------------------ | |
| 29 | ||
| 30 | #include "./omp/parallel_for_each.h" | |
| 31 | ||
| 32 | //------------------------------------------------------------------------ | |
| 33 | // parallel_reduce | |
| 34 | //------------------------------------------------------------------------ | |
| 35 | ||
| 36 | #include "./omp/parallel_reduce.h" | |
| 37 | #include "./omp/parallel_transform_reduce.h" | |
| 38 | ||
| 39 | //------------------------------------------------------------------------ | |
| 40 | // parallel_scan | |
| 41 | //------------------------------------------------------------------------ | |
| 42 | ||
| 43 | #include "./omp/parallel_scan.h" | |
| 44 | #include "./omp/parallel_transform_scan.h" | |
| 45 | ||
| 46 | //------------------------------------------------------------------------ | |
| 47 | // parallel_stable_sort | |
| 48 | //------------------------------------------------------------------------ | |
| 49 | ||
| 50 | #include "./omp/parallel_stable_partial_sort.h" | |
| 51 | #include "./omp/parallel_stable_sort.h" | |
| 52 | ||
| 53 | //------------------------------------------------------------------------ | |
| 54 | // parallel_merge | |
| 55 | //------------------------------------------------------------------------ | |
| 56 | #include "./omp/parallel_merge.h" | |
| 57 | ||
| 58 | #endif //_PSTL_PARALLEL_BACKEND_OMP_H |
lib/libcxx/include/__pstl/internal/parallel_backend_serial.h created+106| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_PARALLEL_BACKEND_SERIAL_H | |
| 11 | #define _PSTL_PARALLEL_BACKEND_SERIAL_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__memory/allocator.h> | |
| 15 | #include <__pstl/internal/execution_impl.h> | |
| 16 | #include <__utility/forward.h> | |
| 17 | #include <cstddef> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 20 | ||
| 21 | namespace __pstl | |
| 22 | { | |
| 23 | namespace __serial_backend | |
| 24 | { | |
| 25 | ||
| 26 | template <typename _Tp> | |
| 27 | class __buffer | |
| 28 | { | |
| 29 | std::allocator<_Tp> __allocator_; | |
| 30 | _Tp* __ptr_; | |
| 31 | const std::size_t __buf_size_; | |
| 32 | __buffer(const __buffer&) = delete; | |
| 33 | void | |
| 34 | operator=(const __buffer&) = delete; | |
| 35 | ||
| 36 | public: | |
| 37 | _LIBCPP_HIDE_FROM_ABI | |
| 38 | __buffer(std::size_t __n) : __allocator_(), __ptr_(__allocator_.allocate(__n)), __buf_size_(__n) {} | |
| 39 | ||
| 40 | _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ptr_ != nullptr; } | |
| 41 | _LIBCPP_HIDE_FROM_ABI _Tp* | |
| 42 | get() const | |
| 43 | { | |
| 44 | return __ptr_; | |
| 45 | } | |
| 46 | _LIBCPP_HIDE_FROM_ABI ~__buffer() { __allocator_.deallocate(__ptr_, __buf_size_); } | |
| 47 | }; | |
| 48 | ||
| 49 | template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction> | |
| 50 | _LIBCPP_HIDE_FROM_ABI _Value | |
| 51 | __parallel_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, | |
| 52 | const _Value& __identity, const _RealBody& __real_body, const _Reduction&) | |
| 53 | { | |
| 54 | if (__first == __last) | |
| 55 | { | |
| 56 | return __identity; | |
| 57 | } | |
| 58 | else | |
| 59 | { | |
| 60 | return __real_body(__first, __last, __identity); | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> | |
| 65 | _LIBCPP_HIDE_FROM_ABI void | |
| 66 | __parallel_strict_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial, | |
| 67 | _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) | |
| 68 | { | |
| 69 | _Tp __sum = __initial; | |
| 70 | if (__n) | |
| 71 | __sum = __combine(__sum, __reduce(_Index(0), __n)); | |
| 72 | __apex(__sum); | |
| 73 | if (__n) | |
| 74 | __scan(_Index(0), __n, __initial); | |
| 75 | } | |
| 76 | ||
| 77 | template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan> | |
| 78 | _LIBCPP_HIDE_FROM_ABI _Tp | |
| 79 | __parallel_transform_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp, | |
| 80 | _Tp __init, _BinaryOp, _Reduce, _Scan __scan) | |
| 81 | { | |
| 82 | return __scan(_Index(0), __n, __init); | |
| 83 | } | |
| 84 | ||
| 85 | template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> | |
| 86 | _LIBCPP_HIDE_FROM_ABI void | |
| 87 | __parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first, | |
| 88 | _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0) | |
| 89 | { | |
| 90 | __leaf_sort(__first, __last, __comp); | |
| 91 | } | |
| 92 | ||
| 93 | template <class _ExecutionPolicy, typename _F1, typename _F2> | |
| 94 | _LIBCPP_HIDE_FROM_ABI void | |
| 95 | __parallel_invoke(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) | |
| 96 | { | |
| 97 | std::forward<_F1>(__f1)(); | |
| 98 | std::forward<_F2>(__f2)(); | |
| 99 | } | |
| 100 | ||
| 101 | } // namespace __serial_backend | |
| 102 | } // namespace __pstl | |
| 103 | ||
| 104 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 105 | ||
| 106 | #endif /* _PSTL_PARALLEL_BACKEND_SERIAL_H */ |
lib/libcxx/include/__pstl/internal/parallel_backend_tbb.h created+1295| ... | ... | @@ -0,0 +1,1295 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_PARALLEL_BACKEND_TBB_H | |
| 11 | #define _PSTL_PARALLEL_BACKEND_TBB_H | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <algorithm> | |
| 16 | #include <type_traits> | |
| 17 | ||
| 18 | #include "parallel_backend_utils.h" | |
| 19 | ||
| 20 | // Bring in minimal required subset of Intel TBB | |
| 21 | #include <tbb/blocked_range.h> | |
| 22 | #include <tbb/parallel_for.h> | |
| 23 | #include <tbb/parallel_reduce.h> | |
| 24 | #include <tbb/parallel_scan.h> | |
| 25 | #include <tbb/parallel_invoke.h> | |
| 26 | #include <tbb/task_arena.h> | |
| 27 | #include <tbb/tbb_allocator.h> | |
| 28 | #include <tbb/task.h> | |
| 29 | ||
| 30 | #if TBB_INTERFACE_VERSION < 10000 | |
| 31 | # error Intel(R) Threading Building Blocks 2018 is required; older versions are not supported. | |
| 32 | #endif | |
| 33 | ||
| 34 | namespace __pstl | |
| 35 | { | |
| 36 | namespace __tbb_backend | |
| 37 | { | |
| 38 | ||
| 39 | //! Raw memory buffer with automatic freeing and no exceptions. | |
| 40 | /** Some of our algorithms need to start with raw memory buffer, | |
| 41 | not an initialize array, because initialization/destruction | |
| 42 | would make the span be at least O(N). */ | |
| 43 | // tbb::allocator can improve performance in some cases. | |
| 44 | template <typename _Tp> | |
| 45 | class __buffer | |
| 46 | { | |
| 47 | tbb::tbb_allocator<_Tp> _M_allocator; | |
| 48 | _Tp* _M_ptr; | |
| 49 | const std::size_t _M_buf_size; | |
| 50 | __buffer(const __buffer&) = delete; | |
| 51 | void | |
| 52 | operator=(const __buffer&) = delete; | |
| 53 | ||
| 54 | public: | |
| 55 | //! Try to obtain buffer of given size to store objects of _Tp type | |
| 56 | __buffer(std::size_t n) : _M_allocator(), _M_ptr(_M_allocator.allocate(n)), _M_buf_size(n) {} | |
| 57 | //! True if buffer was successfully obtained, zero otherwise. | |
| 58 | operator bool() const { return _M_ptr != NULL; } | |
| 59 | //! Return pointer to buffer, or NULL if buffer could not be obtained. | |
| 60 | _Tp* | |
| 61 | get() const | |
| 62 | { | |
| 63 | return _M_ptr; | |
| 64 | } | |
| 65 | //! Destroy buffer | |
| 66 | ~__buffer() { _M_allocator.deallocate(_M_ptr, _M_buf_size); } | |
| 67 | }; | |
| 68 | ||
| 69 | // Wrapper for tbb::task | |
| 70 | inline void | |
| 71 | __cancel_execution() | |
| 72 | { | |
| 73 | #if TBB_INTERFACE_VERSION <= 12000 | |
| 74 | tbb::task::self().group()->cancel_group_execution(); | |
| 75 | #else | |
| 76 | tbb::task::current_context()->cancel_group_execution(); | |
| 77 | #endif | |
| 78 | } | |
| 79 | ||
| 80 | //------------------------------------------------------------------------ | |
| 81 | // parallel_for | |
| 82 | //------------------------------------------------------------------------ | |
| 83 | ||
| 84 | template <class _Index, class _RealBody> | |
| 85 | class __parallel_for_body | |
| 86 | { | |
| 87 | public: | |
| 88 | __parallel_for_body(const _RealBody& __body) : _M_body(__body) {} | |
| 89 | __parallel_for_body(const __parallel_for_body& __body) : _M_body(__body._M_body) {} | |
| 90 | void | |
| 91 | operator()(const tbb::blocked_range<_Index>& __range) const | |
| 92 | { | |
| 93 | _M_body(__range.begin(), __range.end()); | |
| 94 | } | |
| 95 | ||
| 96 | private: | |
| 97 | _RealBody _M_body; | |
| 98 | }; | |
| 99 | ||
| 100 | //! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last) | |
| 101 | // wrapper over tbb::parallel_for | |
| 102 | template <class _ExecutionPolicy, class _Index, class _Fp> | |
| 103 | void | |
| 104 | __parallel_for(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) | |
| 105 | { | |
| 106 | tbb::this_task_arena::isolate([=]() { | |
| 107 | tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f)); | |
| 108 | }); | |
| 109 | } | |
| 110 | ||
| 111 | //! Evaluation of brick f[i,j) for each subrange [i,j) of [first,last) | |
| 112 | // wrapper over tbb::parallel_reduce | |
| 113 | template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction> | |
| 114 | _Value | |
| 115 | __parallel_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, | |
| 116 | const _Value& __identity, const _RealBody& __real_body, const _Reduction& __reduction) | |
| 117 | { | |
| 118 | return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value { | |
| 119 | return tbb::parallel_reduce( | |
| 120 | tbb::blocked_range<_Index>(__first, __last), __identity, | |
| 121 | [__real_body](const tbb::blocked_range<_Index>& __r, const _Value& __value) -> _Value { | |
| 122 | return __real_body(__r.begin(), __r.end(), __value); | |
| 123 | }, | |
| 124 | __reduction); | |
| 125 | }); | |
| 126 | } | |
| 127 | ||
| 128 | //------------------------------------------------------------------------ | |
| 129 | // parallel_transform_reduce | |
| 130 | // | |
| 131 | // Notation: | |
| 132 | // r(i,j,init) returns reduction of init with reduction over [i,j) | |
| 133 | // u(i) returns f(i,i+1,identity) for a hypothetical left identity element of r | |
| 134 | // c(x,y) combines values x and y that were the result of r or u | |
| 135 | //------------------------------------------------------------------------ | |
| 136 | ||
| 137 | template <class _Index, class _Up, class _Tp, class _Cp, class _Rp> | |
| 138 | struct __par_trans_red_body | |
| 139 | { | |
| 140 | alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true | |
| 141 | _Rp _M_brick_reduce; // Most likely to have non-empty layout | |
| 142 | _Up _M_u; | |
| 143 | _Cp _M_combine; | |
| 144 | bool _M_has_sum; // Put last to minimize size of class | |
| 145 | _Tp& | |
| 146 | sum() | |
| 147 | { | |
| 148 | __TBB_ASSERT(_M_has_sum, "sum expected"); | |
| 149 | return *(_Tp*)_M_sum_storage; | |
| 150 | } | |
| 151 | __par_trans_red_body(_Up __u, _Tp __init, _Cp __c, _Rp __r) | |
| 152 | : _M_brick_reduce(__r), _M_u(__u), _M_combine(__c), _M_has_sum(true) | |
| 153 | { | |
| 154 | new (_M_sum_storage) _Tp(__init); | |
| 155 | } | |
| 156 | ||
| 157 | __par_trans_red_body(__par_trans_red_body& __left, tbb::split) | |
| 158 | : _M_brick_reduce(__left._M_brick_reduce), _M_u(__left._M_u), _M_combine(__left._M_combine), _M_has_sum(false) | |
| 159 | { | |
| 160 | } | |
| 161 | ||
| 162 | ~__par_trans_red_body() | |
| 163 | { | |
| 164 | // 17.6.5.12 tells us to not worry about catching exceptions from destructors. | |
| 165 | if (_M_has_sum) | |
| 166 | sum().~_Tp(); | |
| 167 | } | |
| 168 | ||
| 169 | void | |
| 170 | join(__par_trans_red_body& __rhs) | |
| 171 | { | |
| 172 | sum() = _M_combine(sum(), __rhs.sum()); | |
| 173 | } | |
| 174 | ||
| 175 | void | |
| 176 | operator()(const tbb::blocked_range<_Index>& __range) | |
| 177 | { | |
| 178 | _Index __i = __range.begin(); | |
| 179 | _Index __j = __range.end(); | |
| 180 | if (!_M_has_sum) | |
| 181 | { | |
| 182 | __TBB_ASSERT(__range.size() > 1, "there should be at least 2 elements"); | |
| 183 | new (&_M_sum_storage) | |
| 184 | _Tp(_M_combine(_M_u(__i), _M_u(__i + 1))); // The condition i+1 < j is provided by the grain size of 3 | |
| 185 | _M_has_sum = true; | |
| 186 | std::advance(__i, 2); | |
| 187 | if (__i == __j) | |
| 188 | return; | |
| 189 | } | |
| 190 | sum() = _M_brick_reduce(__i, __j, sum()); | |
| 191 | } | |
| 192 | }; | |
| 193 | ||
| 194 | template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp> | |
| 195 | _Tp | |
| 196 | __parallel_transform_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, | |
| 197 | _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce) | |
| 198 | { | |
| 199 | __tbb_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce); | |
| 200 | // The grain size of 3 is used in order to provide mininum 2 elements for each body | |
| 201 | tbb::this_task_arena::isolate( | |
| 202 | [__first, __last, &__body]() { tbb::parallel_reduce(tbb::blocked_range<_Index>(__first, __last, 3), __body); }); | |
| 203 | return __body.sum(); | |
| 204 | } | |
| 205 | ||
| 206 | //------------------------------------------------------------------------ | |
| 207 | // parallel_scan | |
| 208 | //------------------------------------------------------------------------ | |
| 209 | ||
| 210 | template <class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp> | |
| 211 | class __trans_scan_body | |
| 212 | { | |
| 213 | alignas(_Tp) char _M_sum_storage[sizeof(_Tp)]; // Holds generalized non-commutative sum when has_sum==true | |
| 214 | _Rp _M_brick_reduce; // Most likely to have non-empty layout | |
| 215 | _Up _M_u; | |
| 216 | _Cp _M_combine; | |
| 217 | _Sp _M_scan; | |
| 218 | bool _M_has_sum; // Put last to minimize size of class | |
| 219 | public: | |
| 220 | __trans_scan_body(_Up __u, _Tp __init, _Cp __combine, _Rp __reduce, _Sp __scan) | |
| 221 | : _M_brick_reduce(__reduce), _M_u(__u), _M_combine(__combine), _M_scan(__scan), _M_has_sum(true) | |
| 222 | { | |
| 223 | new (_M_sum_storage) _Tp(__init); | |
| 224 | } | |
| 225 | ||
| 226 | __trans_scan_body(__trans_scan_body& __b, tbb::split) | |
| 227 | : _M_brick_reduce(__b._M_brick_reduce), _M_u(__b._M_u), _M_combine(__b._M_combine), _M_scan(__b._M_scan), | |
| 228 | _M_has_sum(false) | |
| 229 | { | |
| 230 | } | |
| 231 | ||
| 232 | ~__trans_scan_body() | |
| 233 | { | |
| 234 | // 17.6.5.12 tells us to not worry about catching exceptions from destructors. | |
| 235 | if (_M_has_sum) | |
| 236 | sum().~_Tp(); | |
| 237 | } | |
| 238 | ||
| 239 | _Tp& | |
| 240 | sum() const | |
| 241 | { | |
| 242 | __TBB_ASSERT(_M_has_sum, "sum expected"); | |
| 243 | return *const_cast<_Tp*>(reinterpret_cast<_Tp const*>(_M_sum_storage)); | |
| 244 | } | |
| 245 | ||
| 246 | void | |
| 247 | operator()(const tbb::blocked_range<_Index>& __range, tbb::pre_scan_tag) | |
| 248 | { | |
| 249 | _Index __i = __range.begin(); | |
| 250 | _Index __j = __range.end(); | |
| 251 | if (!_M_has_sum) | |
| 252 | { | |
| 253 | new (&_M_sum_storage) _Tp(_M_u(__i)); | |
| 254 | _M_has_sum = true; | |
| 255 | ++__i; | |
| 256 | if (__i == __j) | |
| 257 | return; | |
| 258 | } | |
| 259 | sum() = _M_brick_reduce(__i, __j, sum()); | |
| 260 | } | |
| 261 | ||
| 262 | void | |
| 263 | operator()(const tbb::blocked_range<_Index>& __range, tbb::final_scan_tag) | |
| 264 | { | |
| 265 | sum() = _M_scan(__range.begin(), __range.end(), sum()); | |
| 266 | } | |
| 267 | ||
| 268 | void | |
| 269 | reverse_join(__trans_scan_body& __a) | |
| 270 | { | |
| 271 | if (_M_has_sum) | |
| 272 | { | |
| 273 | sum() = _M_combine(__a.sum(), sum()); | |
| 274 | } | |
| 275 | else | |
| 276 | { | |
| 277 | new (&_M_sum_storage) _Tp(__a.sum()); | |
| 278 | _M_has_sum = true; | |
| 279 | } | |
| 280 | } | |
| 281 | ||
| 282 | void | |
| 283 | assign(__trans_scan_body& __b) | |
| 284 | { | |
| 285 | sum() = __b.sum(); | |
| 286 | } | |
| 287 | }; | |
| 288 | ||
| 289 | template <typename _Index> | |
| 290 | _Index | |
| 291 | __split(_Index __m) | |
| 292 | { | |
| 293 | _Index __k = 1; | |
| 294 | while (2 * __k < __m) | |
| 295 | __k *= 2; | |
| 296 | return __k; | |
| 297 | } | |
| 298 | ||
| 299 | //------------------------------------------------------------------------ | |
| 300 | // __parallel_strict_scan | |
| 301 | //------------------------------------------------------------------------ | |
| 302 | ||
| 303 | template <typename _Index, typename _Tp, typename _Rp, typename _Cp> | |
| 304 | void | |
| 305 | __upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Rp __reduce, _Cp __combine) | |
| 306 | { | |
| 307 | if (__m == 1) | |
| 308 | __r[0] = __reduce(__i * __tilesize, __lastsize); | |
| 309 | else | |
| 310 | { | |
| 311 | _Index __k = __split(__m); | |
| 312 | tbb::parallel_invoke( | |
| 313 | [=] { __tbb_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); }, | |
| 314 | [=] { | |
| 315 | __tbb_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine); | |
| 316 | }); | |
| 317 | if (__m == 2 * __k) | |
| 318 | __r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]); | |
| 319 | } | |
| 320 | } | |
| 321 | ||
| 322 | template <typename _Index, typename _Tp, typename _Cp, typename _Sp> | |
| 323 | void | |
| 324 | __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize, _Tp __initial, _Cp __combine, | |
| 325 | _Sp __scan) | |
| 326 | { | |
| 327 | if (__m == 1) | |
| 328 | __scan(__i * __tilesize, __lastsize, __initial); | |
| 329 | else | |
| 330 | { | |
| 331 | const _Index __k = __split(__m); | |
| 332 | tbb::parallel_invoke( | |
| 333 | [=] { __tbb_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); }, | |
| 334 | // Assumes that __combine never throws. | |
| 335 | //TODO: Consider adding a requirement for user functors to be constant. | |
| 336 | [=, &__combine] { | |
| 337 | __tbb_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, | |
| 338 | __combine(__initial, __r[__k - 1]), __combine, __scan); | |
| 339 | }); | |
| 340 | } | |
| 341 | } | |
| 342 | ||
| 343 | // Adapted from Intel(R) Cilk(TM) version from cilkpub. | |
| 344 | // Let i:len denote a counted interval of length n starting at i. s denotes a generalized-sum value. | |
| 345 | // Expected actions of the functors are: | |
| 346 | // reduce(i,len) -> s -- return reduction value of i:len. | |
| 347 | // combine(s1,s2) -> s -- return merged sum | |
| 348 | // apex(s) -- do any processing necessary between reduce and scan. | |
| 349 | // scan(i,len,initial) -- perform scan over i:len starting with initial. | |
| 350 | // The initial range 0:n is partitioned into consecutive subranges. | |
| 351 | // reduce and scan are each called exactly once per subrange. | |
| 352 | // Thus callers can rely upon side effects in reduce. | |
| 353 | // combine must not throw an exception. | |
| 354 | // apex is called exactly once, after all calls to reduce and before all calls to scan. | |
| 355 | // For example, it's useful for allocating a __buffer used by scan but whose size is the sum of all reduction values. | |
| 356 | // T must have a trivial constructor and destructor. | |
| 357 | template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> | |
| 358 | void | |
| 359 | __parallel_strict_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial, | |
| 360 | _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex) | |
| 361 | { | |
| 362 | tbb::this_task_arena::isolate([=, &__combine]() { | |
| 363 | if (__n > 1) | |
| 364 | { | |
| 365 | _Index __p = tbb::this_task_arena::max_concurrency(); | |
| 366 | const _Index __slack = 4; | |
| 367 | _Index __tilesize = (__n - 1) / (__slack * __p) + 1; | |
| 368 | _Index __m = (__n - 1) / __tilesize; | |
| 369 | __buffer<_Tp> __buf(__m + 1); | |
| 370 | _Tp* __r = __buf.get(); | |
| 371 | __tbb_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, | |
| 372 | __combine); | |
| 373 | ||
| 374 | // When __apex is a no-op and __combine has no side effects, a good optimizer | |
| 375 | // should be able to eliminate all code between here and __apex. | |
| 376 | // Alternatively, provide a default value for __apex that can be | |
| 377 | // recognized by metaprogramming that conditionlly executes the following. | |
| 378 | size_t __k = __m + 1; | |
| 379 | _Tp __t = __r[__k - 1]; | |
| 380 | while ((__k &= __k - 1)) | |
| 381 | __t = __combine(__r[__k - 1], __t); | |
| 382 | __apex(__combine(__initial, __t)); | |
| 383 | __tbb_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial, | |
| 384 | __combine, __scan); | |
| 385 | return; | |
| 386 | } | |
| 387 | // Fewer than 2 elements in sequence, or out of memory. Handle has single block. | |
| 388 | _Tp __sum = __initial; | |
| 389 | if (__n) | |
| 390 | __sum = __combine(__sum, __reduce(_Index(0), __n)); | |
| 391 | __apex(__sum); | |
| 392 | if (__n) | |
| 393 | __scan(_Index(0), __n, __initial); | |
| 394 | }); | |
| 395 | } | |
| 396 | ||
| 397 | template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp> | |
| 398 | _Tp | |
| 399 | __parallel_transform_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init, | |
| 400 | _Cp __combine, _Rp __brick_reduce, _Sp __scan) | |
| 401 | { | |
| 402 | __trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan); | |
| 403 | auto __range = tbb::blocked_range<_Index>(0, __n); | |
| 404 | tbb::this_task_arena::isolate([__range, &__body]() { tbb::parallel_scan(__range, __body); }); | |
| 405 | return __body.sum(); | |
| 406 | } | |
| 407 | ||
| 408 | //------------------------------------------------------------------------ | |
| 409 | // parallel_stable_sort | |
| 410 | //------------------------------------------------------------------------ | |
| 411 | ||
| 412 | //------------------------------------------------------------------------ | |
| 413 | // stable_sort utilities | |
| 414 | // | |
| 415 | // These are used by parallel implementations but do not depend on them. | |
| 416 | //------------------------------------------------------------------------ | |
| 417 | #define _PSTL_MERGE_CUT_OFF 2000 | |
| 418 | ||
| 419 | template <typename _Func> | |
| 420 | class __func_task; | |
| 421 | template <typename _Func> | |
| 422 | class __root_task; | |
| 423 | ||
| 424 | #if TBB_INTERFACE_VERSION <= 12000 | |
| 425 | class __task : public tbb::task | |
| 426 | { | |
| 427 | public: | |
| 428 | template <typename _Fn> | |
| 429 | __task* | |
| 430 | make_continuation(_Fn&& __f) | |
| 431 | { | |
| 432 | return new (allocate_continuation()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f)); | |
| 433 | } | |
| 434 | ||
| 435 | template <typename _Fn> | |
| 436 | __task* | |
| 437 | make_child_of(__task* parent, _Fn&& __f) | |
| 438 | { | |
| 439 | return new (parent->allocate_child()) __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f)); | |
| 440 | } | |
| 441 | ||
| 442 | template <typename _Fn> | |
| 443 | __task* | |
| 444 | make_additional_child_of(tbb::task* parent, _Fn&& __f) | |
| 445 | { | |
| 446 | return new (tbb::task::allocate_additional_child_of(*parent)) | |
| 447 | __func_task<typename std::decay<_Fn>::type>(std::forward<_Fn>(__f)); | |
| 448 | } | |
| 449 | ||
| 450 | inline void | |
| 451 | recycle_as_continuation() | |
| 452 | { | |
| 453 | tbb::task::recycle_as_continuation(); | |
| 454 | } | |
| 455 | ||
| 456 | inline void | |
| 457 | recycle_as_child_of(__task* parent) | |
| 458 | { | |
| 459 | tbb::task::recycle_as_child_of(*parent); | |
| 460 | } | |
| 461 | ||
| 462 | inline void | |
| 463 | spawn(__task* __t) | |
| 464 | { | |
| 465 | tbb::task::spawn(*__t); | |
| 466 | } | |
| 467 | ||
| 468 | template <typename _Fn> | |
| 469 | static inline void | |
| 470 | spawn_root_and_wait(__root_task<_Fn>& __root) | |
| 471 | { | |
| 472 | tbb::task::spawn_root_and_wait(*__root._M_task); | |
| 473 | } | |
| 474 | }; | |
| 475 | ||
| 476 | template <typename _Func> | |
| 477 | class __func_task : public __task | |
| 478 | { | |
| 479 | _Func _M_func; | |
| 480 | ||
| 481 | tbb::task* | |
| 482 | execute() | |
| 483 | { | |
| 484 | return _M_func(this); | |
| 485 | }; | |
| 486 | ||
| 487 | public: | |
| 488 | template <typename _Fn> | |
| 489 | __func_task(_Fn&& __f) : _M_func{std::forward<_Fn>(__f)} | |
| 490 | { | |
| 491 | } | |
| 492 | ||
| 493 | _Func& | |
| 494 | body() | |
| 495 | { | |
| 496 | return _M_func; | |
| 497 | } | |
| 498 | }; | |
| 499 | ||
| 500 | template <typename _Func> | |
| 501 | class __root_task | |
| 502 | { | |
| 503 | tbb::task* _M_task; | |
| 504 | ||
| 505 | public: | |
| 506 | template <typename... Args> | |
| 507 | __root_task(Args&&... args) | |
| 508 | : _M_task{new (tbb::task::allocate_root()) __func_task<_Func>{_Func(std::forward<Args>(args)...)}} | |
| 509 | { | |
| 510 | } | |
| 511 | ||
| 512 | friend class __task; | |
| 513 | friend class __func_task<_Func>; | |
| 514 | }; | |
| 515 | ||
| 516 | #else // TBB_INTERFACE_VERSION <= 12000 | |
| 517 | class __task : public tbb::detail::d1::task | |
| 518 | { | |
| 519 | protected: | |
| 520 | tbb::detail::d1::small_object_allocator _M_allocator{}; | |
| 521 | tbb::detail::d1::execution_data* _M_execute_data{}; | |
| 522 | __task* _M_parent{}; | |
| 523 | std::atomic<int> _M_refcount{}; | |
| 524 | bool _M_recycle{}; | |
| 525 | ||
| 526 | template <typename _Fn> | |
| 527 | __task* | |
| 528 | allocate_func_task(_Fn&& __f) | |
| 529 | { | |
| 530 | _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, ""); | |
| 531 | tbb::detail::d1::small_object_allocator __alloc{}; | |
| 532 | auto __t = | |
| 533 | __alloc.new_object<__func_task<typename std::decay<_Fn>::type>>(*_M_execute_data, std::forward<_Fn>(__f)); | |
| 534 | __t->_M_allocator = __alloc; | |
| 535 | return __t; | |
| 536 | } | |
| 537 | ||
| 538 | public: | |
| 539 | __task* | |
| 540 | parent() | |
| 541 | { | |
| 542 | return _M_parent; | |
| 543 | } | |
| 544 | ||
| 545 | void | |
| 546 | set_ref_count(int __n) | |
| 547 | { | |
| 548 | _M_refcount.store(__n, std::memory_order_release); | |
| 549 | } | |
| 550 | ||
| 551 | template <typename _Fn> | |
| 552 | __task* | |
| 553 | make_continuation(_Fn&& __f) | |
| 554 | { | |
| 555 | auto __t = allocate_func_task(std::forward<_Fn&&>(__f)); | |
| 556 | __t->_M_parent = _M_parent; | |
| 557 | _M_parent = nullptr; | |
| 558 | return __t; | |
| 559 | } | |
| 560 | ||
| 561 | template <typename _Fn> | |
| 562 | __task* | |
| 563 | make_child_of(__task* __parent, _Fn&& __f) | |
| 564 | { | |
| 565 | auto __t = allocate_func_task(std::forward<_Fn&&>(__f)); | |
| 566 | __t->_M_parent = __parent; | |
| 567 | return __t; | |
| 568 | } | |
| 569 | ||
| 570 | template <typename _Fn> | |
| 571 | __task* | |
| 572 | make_additional_child_of(__task* __parent, _Fn&& __f) | |
| 573 | { | |
| 574 | auto __t = make_child_of(__parent, std::forward<_Fn>(__f)); | |
| 575 | _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, ""); | |
| 576 | ++__parent->_M_refcount; | |
| 577 | return __t; | |
| 578 | } | |
| 579 | ||
| 580 | inline void | |
| 581 | recycle_as_continuation() | |
| 582 | { | |
| 583 | _M_recycle = true; | |
| 584 | } | |
| 585 | ||
| 586 | inline void | |
| 587 | recycle_as_child_of(__task* parent) | |
| 588 | { | |
| 589 | _M_recycle = true; | |
| 590 | _M_parent = parent; | |
| 591 | } | |
| 592 | ||
| 593 | inline void | |
| 594 | spawn(__task* __t) | |
| 595 | { | |
| 596 | _LIBCPP_ASSERT_UNCATEGORIZED(_M_execute_data != nullptr, ""); | |
| 597 | tbb::detail::d1::spawn(*__t, *_M_execute_data->context); | |
| 598 | } | |
| 599 | ||
| 600 | template <typename _Fn> | |
| 601 | static inline void | |
| 602 | spawn_root_and_wait(__root_task<_Fn>& __root) | |
| 603 | { | |
| 604 | tbb::detail::d1::execute_and_wait(*__root._M_func_task, __root._M_context, __root._M_wait_object, | |
| 605 | __root._M_context); | |
| 606 | } | |
| 607 | ||
| 608 | template <typename _Func> | |
| 609 | friend class __func_task; | |
| 610 | }; | |
| 611 | ||
| 612 | template <typename _Func> | |
| 613 | class __func_task : public __task | |
| 614 | { | |
| 615 | _Func _M_func; | |
| 616 | ||
| 617 | __task* | |
| 618 | execute(tbb::detail::d1::execution_data& __ed) override | |
| 619 | { | |
| 620 | _M_execute_data = &__ed; | |
| 621 | _M_recycle = false; | |
| 622 | __task* __next = _M_func(this); | |
| 623 | return finalize(__next); | |
| 624 | }; | |
| 625 | ||
| 626 | __task* | |
| 627 | cancel(tbb::detail::d1::execution_data& __ed) override | |
| 628 | { | |
| 629 | return finalize(nullptr); | |
| 630 | } | |
| 631 | ||
| 632 | __task* | |
| 633 | finalize(__task* __next) | |
| 634 | { | |
| 635 | bool __recycle = _M_recycle; | |
| 636 | _M_recycle = false; | |
| 637 | ||
| 638 | if (__recycle) | |
| 639 | { | |
| 640 | return __next; | |
| 641 | } | |
| 642 | ||
| 643 | auto __parent = _M_parent; | |
| 644 | auto __alloc = _M_allocator; | |
| 645 | auto __ed = _M_execute_data; | |
| 646 | ||
| 647 | this->~__func_task(); | |
| 648 | ||
| 649 | _LIBCPP_ASSERT_UNCATEGORIZED(__parent != nullptr, ""); | |
| 650 | _LIBCPP_ASSERT_UNCATEGORIZED(__parent->_M_refcount.load(std::memory_order_relaxed) > 0, ""); | |
| 651 | if (--__parent->_M_refcount == 0) | |
| 652 | { | |
| 653 | _LIBCPP_ASSERT_UNCATEGORIZED(__next == nullptr, ""); | |
| 654 | __alloc.deallocate(this, *__ed); | |
| 655 | return __parent; | |
| 656 | } | |
| 657 | ||
| 658 | return __next; | |
| 659 | } | |
| 660 | ||
| 661 | friend class __root_task<_Func>; | |
| 662 | ||
| 663 | public: | |
| 664 | template <typename _Fn> | |
| 665 | __func_task(_Fn&& __f) : _M_func(std::forward<_Fn>(__f)) | |
| 666 | { | |
| 667 | } | |
| 668 | ||
| 669 | _Func& | |
| 670 | body() | |
| 671 | { | |
| 672 | return _M_func; | |
| 673 | } | |
| 674 | }; | |
| 675 | ||
| 676 | template <typename _Func> | |
| 677 | class __root_task : public __task | |
| 678 | { | |
| 679 | __task* | |
| 680 | execute(tbb::detail::d1::execution_data& __ed) override | |
| 681 | { | |
| 682 | _M_wait_object.release(); | |
| 683 | return nullptr; | |
| 684 | }; | |
| 685 | ||
| 686 | __task* | |
| 687 | cancel(tbb::detail::d1::execution_data& __ed) override | |
| 688 | { | |
| 689 | _M_wait_object.release(); | |
| 690 | return nullptr; | |
| 691 | } | |
| 692 | ||
| 693 | __func_task<_Func>* _M_func_task{}; | |
| 694 | tbb::detail::d1::wait_context _M_wait_object{0}; | |
| 695 | tbb::task_group_context _M_context{}; | |
| 696 | ||
| 697 | public: | |
| 698 | template <typename... Args> | |
| 699 | __root_task(Args&&... args) : _M_wait_object{1} | |
| 700 | { | |
| 701 | tbb::detail::d1::small_object_allocator __alloc{}; | |
| 702 | _M_func_task = __alloc.new_object<__func_task<_Func>>(_Func(std::forward<Args>(args)...)); | |
| 703 | _M_func_task->_M_allocator = __alloc; | |
| 704 | _M_func_task->_M_parent = this; | |
| 705 | _M_refcount.store(1, std::memory_order_relaxed); | |
| 706 | } | |
| 707 | ||
| 708 | friend class __task; | |
| 709 | }; | |
| 710 | #endif // TBB_INTERFACE_VERSION <= 12000 | |
| 711 | ||
| 712 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _Cleanup, | |
| 713 | typename _LeafMerge> | |
| 714 | class __merge_func | |
| 715 | { | |
| 716 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; | |
| 717 | typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; | |
| 718 | typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType; | |
| 719 | typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _ValueType; | |
| 720 | ||
| 721 | _RandomAccessIterator1 _M_x_beg; | |
| 722 | _RandomAccessIterator2 _M_z_beg; | |
| 723 | ||
| 724 | _SizeType _M_xs, _M_xe; | |
| 725 | _SizeType _M_ys, _M_ye; | |
| 726 | _SizeType _M_zs; | |
| 727 | _Compare _M_comp; | |
| 728 | _LeafMerge _M_leaf_merge; | |
| 729 | _SizeType _M_nsort; //number of elements to be sorted for partial_sort alforithm | |
| 730 | ||
| 731 | static const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF; | |
| 732 | ||
| 733 | bool _root; //means a task is merging root task | |
| 734 | bool _x_orig; //"true" means X(or left ) subrange is in the original container; false - in the buffer | |
| 735 | bool _y_orig; //"true" means Y(or right) subrange is in the original container; false - in the buffer | |
| 736 | bool _split; //"true" means a merge task is a split task for parallel merging, the execution logic differs | |
| 737 | ||
| 738 | bool | |
| 739 | is_partial() const | |
| 740 | { | |
| 741 | return _M_nsort > 0; | |
| 742 | } | |
| 743 | ||
| 744 | struct __move_value | |
| 745 | { | |
| 746 | template <typename Iterator1, typename Iterator2> | |
| 747 | void | |
| 748 | operator()(Iterator1 __x, Iterator2 __z) | |
| 749 | { | |
| 750 | *__z = std::move(*__x); | |
| 751 | } | |
| 752 | }; | |
| 753 | ||
| 754 | struct __move_value_construct | |
| 755 | { | |
| 756 | template <typename Iterator1, typename Iterator2> | |
| 757 | void | |
| 758 | operator()(Iterator1 __x, Iterator2 __z) | |
| 759 | { | |
| 760 | ::new (std::addressof(*__z)) _ValueType(std::move(*__x)); | |
| 761 | } | |
| 762 | }; | |
| 763 | ||
| 764 | struct __move_range | |
| 765 | { | |
| 766 | template <typename Iterator1, typename Iterator2> | |
| 767 | Iterator2 | |
| 768 | operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2) | |
| 769 | { | |
| 770 | if (__last1 - __first1 < __merge_cut_off) | |
| 771 | return std::move(__first1, __last1, __first2); | |
| 772 | ||
| 773 | auto __n = __last1 - __first1; | |
| 774 | tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off), | |
| 775 | [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) { | |
| 776 | std::move(__first1 + __range.begin(), __first1 + __range.end(), | |
| 777 | __first2 + __range.begin()); | |
| 778 | }); | |
| 779 | return __first2 + __n; | |
| 780 | } | |
| 781 | }; | |
| 782 | ||
| 783 | struct __move_range_construct | |
| 784 | { | |
| 785 | template <typename Iterator1, typename Iterator2> | |
| 786 | Iterator2 | |
| 787 | operator()(Iterator1 __first1, Iterator1 __last1, Iterator2 __first2) | |
| 788 | { | |
| 789 | if (__last1 - __first1 < __merge_cut_off) | |
| 790 | { | |
| 791 | for (; __first1 != __last1; ++__first1, ++__first2) | |
| 792 | __move_value_construct()(__first1, __first2); | |
| 793 | return __first2; | |
| 794 | } | |
| 795 | ||
| 796 | auto __n = __last1 - __first1; | |
| 797 | tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off), | |
| 798 | [__first1, __first2](const tbb::blocked_range<_SizeType>& __range) { | |
| 799 | for (auto i = __range.begin(); i != __range.end(); ++i) | |
| 800 | __move_value_construct()(__first1 + i, __first2 + i); | |
| 801 | }); | |
| 802 | return __first2 + __n; | |
| 803 | } | |
| 804 | }; | |
| 805 | ||
| 806 | struct __cleanup_range | |
| 807 | { | |
| 808 | template <typename Iterator> | |
| 809 | void | |
| 810 | operator()(Iterator __first, Iterator __last) | |
| 811 | { | |
| 812 | if (__last - __first < __merge_cut_off) | |
| 813 | _Cleanup()(__first, __last); | |
| 814 | else | |
| 815 | { | |
| 816 | auto __n = __last - __first; | |
| 817 | tbb::parallel_for(tbb::blocked_range<_SizeType>(0, __n, __merge_cut_off), | |
| 818 | [__first](const tbb::blocked_range<_SizeType>& __range) { | |
| 819 | _Cleanup()(__first + __range.begin(), __first + __range.end()); | |
| 820 | }); | |
| 821 | } | |
| 822 | } | |
| 823 | }; | |
| 824 | ||
| 825 | public: | |
| 826 | __merge_func(_SizeType __xs, _SizeType __xe, _SizeType __ys, _SizeType __ye, _SizeType __zs, _Compare __comp, | |
| 827 | _Cleanup, _LeafMerge __leaf_merge, _SizeType __nsort, _RandomAccessIterator1 __x_beg, | |
| 828 | _RandomAccessIterator2 __z_beg, bool __x_orig, bool __y_orig, bool __root) | |
| 829 | : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_x_beg(__x_beg), _M_z_beg(__z_beg), | |
| 830 | _M_comp(__comp), _M_leaf_merge(__leaf_merge), _M_nsort(__nsort), _root(__root), | |
| 831 | _x_orig(__x_orig), _y_orig(__y_orig), _split(false) | |
| 832 | { | |
| 833 | } | |
| 834 | ||
| 835 | bool | |
| 836 | is_left(_SizeType __idx) const | |
| 837 | { | |
| 838 | return _M_xs == __idx; | |
| 839 | } | |
| 840 | ||
| 841 | template <typename IndexType> | |
| 842 | void | |
| 843 | set_odd(IndexType __idx, bool __on_off) | |
| 844 | { | |
| 845 | if (is_left(__idx)) | |
| 846 | _x_orig = __on_off; | |
| 847 | else | |
| 848 | _y_orig = __on_off; | |
| 849 | } | |
| 850 | ||
| 851 | __task* | |
| 852 | operator()(__task* __self); | |
| 853 | ||
| 854 | private: | |
| 855 | __merge_func* | |
| 856 | parent_merge(__task* __self) const | |
| 857 | { | |
| 858 | return _root ? nullptr : &static_cast<__func_task<__merge_func>*>(__self->parent())->body(); | |
| 859 | } | |
| 860 | bool | |
| 861 | x_less_y() | |
| 862 | { | |
| 863 | const auto __nx = (_M_xe - _M_xs); | |
| 864 | const auto __ny = (_M_ye - _M_ys); | |
| 865 | _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, ""); | |
| 866 | ||
| 867 | _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); | |
| 868 | _LIBCPP_ASSERT_UNCATEGORIZED(!is_partial(), ""); | |
| 869 | ||
| 870 | if (_x_orig) | |
| 871 | { | |
| 872 | _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_comp), ""); | |
| 873 | _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_comp), ""); | |
| 874 | return !_M_comp(*(_M_x_beg + _M_ys), *(_M_x_beg + _M_xe - 1)); | |
| 875 | } | |
| 876 | ||
| 877 | _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), ""); | |
| 878 | _LIBCPP_ASSERT_UNCATEGORIZED(std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), ""); | |
| 879 | return !_M_comp(*(_M_z_beg + _M_zs + __nx), *(_M_z_beg + _M_zs + __nx - 1)); | |
| 880 | } | |
| 881 | void | |
| 882 | move_x_range() | |
| 883 | { | |
| 884 | const auto __nx = (_M_xe - _M_xs); | |
| 885 | const auto __ny = (_M_ye - _M_ys); | |
| 886 | _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0 && __ny > 0, ""); | |
| 887 | ||
| 888 | if (_x_orig) | |
| 889 | __move_range_construct()(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_z_beg + _M_zs); | |
| 890 | else | |
| 891 | { | |
| 892 | __move_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx, _M_x_beg + _M_xs); | |
| 893 | __cleanup_range()(_M_z_beg + _M_zs, _M_z_beg + _M_zs + __nx); | |
| 894 | } | |
| 895 | ||
| 896 | _x_orig = !_x_orig; | |
| 897 | } | |
| 898 | void | |
| 899 | move_y_range() | |
| 900 | { | |
| 901 | const auto __nx = (_M_xe - _M_xs); | |
| 902 | const auto __ny = (_M_ye - _M_ys); | |
| 903 | ||
| 904 | if (_y_orig) | |
| 905 | __move_range_construct()(_M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs + __nx); | |
| 906 | else | |
| 907 | { | |
| 908 | __move_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny, _M_x_beg + _M_ys); | |
| 909 | __cleanup_range()(_M_z_beg + _M_zs + __nx, _M_z_beg + _M_zs + __nx + __ny); | |
| 910 | } | |
| 911 | ||
| 912 | _y_orig = !_y_orig; | |
| 913 | } | |
| 914 | __task* | |
| 915 | merge_ranges(__task* __self) | |
| 916 | { | |
| 917 | _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); // two merged subrange must be lie into the same buffer | |
| 918 | ||
| 919 | const auto __nx = (_M_xe - _M_xs); | |
| 920 | const auto __ny = (_M_ye - _M_ys); | |
| 921 | const auto __n = __nx + __ny; | |
| 922 | ||
| 923 | // need to merge {x} and {y} | |
| 924 | if (__n > __merge_cut_off) | |
| 925 | return split_merging(__self); | |
| 926 | ||
| 927 | //merge to buffer | |
| 928 | if (_x_orig) | |
| 929 | { | |
| 930 | _M_leaf_merge(_M_x_beg + _M_xs, _M_x_beg + _M_xe, _M_x_beg + _M_ys, _M_x_beg + _M_ye, _M_z_beg + _M_zs, | |
| 931 | _M_comp, __move_value_construct(), __move_value_construct(), __move_range_construct(), | |
| 932 | __move_range_construct()); | |
| 933 | _LIBCPP_ASSERT_UNCATEGORIZED(parent_merge(__self), ""); //not root merging task | |
| 934 | } | |
| 935 | //merge to "origin" | |
| 936 | else | |
| 937 | { | |
| 938 | _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); | |
| 939 | ||
| 940 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 941 | is_partial() || std::is_sorted(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_comp), ""); | |
| 942 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 943 | is_partial() || std::is_sorted(_M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_comp), ""); | |
| 944 | ||
| 945 | const auto __nx = (_M_xe - _M_xs); | |
| 946 | const auto __ny = (_M_ye - _M_ys); | |
| 947 | ||
| 948 | _M_leaf_merge(_M_z_beg + _M_xs, _M_z_beg + _M_xe, _M_z_beg + _M_ys, _M_z_beg + _M_ye, _M_x_beg + _M_zs, | |
| 949 | _M_comp, __move_value(), __move_value(), __move_range(), __move_range()); | |
| 950 | ||
| 951 | __cleanup_range()(_M_z_beg + _M_xs, _M_z_beg + _M_xe); | |
| 952 | __cleanup_range()(_M_z_beg + _M_ys, _M_z_beg + _M_ye); | |
| 953 | } | |
| 954 | return nullptr; | |
| 955 | } | |
| 956 | ||
| 957 | __task* | |
| 958 | process_ranges(__task* __self) | |
| 959 | { | |
| 960 | _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); | |
| 961 | _LIBCPP_ASSERT_UNCATEGORIZED(!_split, ""); | |
| 962 | ||
| 963 | auto p = parent_merge(__self); | |
| 964 | ||
| 965 | if (!p) | |
| 966 | { //root merging task | |
| 967 | ||
| 968 | //optimization, just for sort algorithm, //{x} <= {y} | |
| 969 | if (!is_partial() && x_less_y()) //we have a solution | |
| 970 | { | |
| 971 | if (!_x_orig) | |
| 972 | { //we have to move the solution to the origin | |
| 973 | move_x_range(); //parallel moving | |
| 974 | move_y_range(); //parallel moving | |
| 975 | } | |
| 976 | return nullptr; | |
| 977 | } | |
| 978 | //else: if we have data in the origin, | |
| 979 | //we have to move data to the buffer for final merging into the origin. | |
| 980 | if (_x_orig) | |
| 981 | { | |
| 982 | move_x_range(); //parallel moving | |
| 983 | move_y_range(); //parallel moving | |
| 984 | } | |
| 985 | // need to merge {x} and {y}. | |
| 986 | return merge_ranges(__self); | |
| 987 | } | |
| 988 | //else: not root merging task (parent_merge() == NULL) | |
| 989 | //optimization, just for sort algorithm, //{x} <= {y} | |
| 990 | if (!is_partial() && x_less_y()) | |
| 991 | { | |
| 992 | const auto id_range = _M_zs; | |
| 993 | p->set_odd(id_range, _x_orig); | |
| 994 | return nullptr; | |
| 995 | } | |
| 996 | //else: we have to revert "_x(y)_orig" flag of the parent merging task | |
| 997 | const auto id_range = _M_zs; | |
| 998 | p->set_odd(id_range, !_x_orig); | |
| 999 | ||
| 1000 | return merge_ranges(__self); | |
| 1001 | } | |
| 1002 | ||
| 1003 | //splitting as merge task into 2 of the same level | |
| 1004 | __task* | |
| 1005 | split_merging(__task* __self) | |
| 1006 | { | |
| 1007 | _LIBCPP_ASSERT_UNCATEGORIZED(_x_orig == _y_orig, ""); | |
| 1008 | const auto __nx = (_M_xe - _M_xs); | |
| 1009 | const auto __ny = (_M_ye - _M_ys); | |
| 1010 | ||
| 1011 | _SizeType __xm{}; | |
| 1012 | _SizeType __ym{}; | |
| 1013 | if (__nx < __ny) | |
| 1014 | { | |
| 1015 | __ym = _M_ys + __ny / 2; | |
| 1016 | ||
| 1017 | if (_x_orig) | |
| 1018 | __xm = std::upper_bound(_M_x_beg + _M_xs, _M_x_beg + _M_xe, *(_M_x_beg + __ym), _M_comp) - _M_x_beg; | |
| 1019 | else | |
| 1020 | __xm = std::upper_bound(_M_z_beg + _M_xs, _M_z_beg + _M_xe, *(_M_z_beg + __ym), _M_comp) - _M_z_beg; | |
| 1021 | } | |
| 1022 | else | |
| 1023 | { | |
| 1024 | __xm = _M_xs + __nx / 2; | |
| 1025 | ||
| 1026 | if (_y_orig) | |
| 1027 | __ym = std::lower_bound(_M_x_beg + _M_ys, _M_x_beg + _M_ye, *(_M_x_beg + __xm), _M_comp) - _M_x_beg; | |
| 1028 | else | |
| 1029 | __ym = std::lower_bound(_M_z_beg + _M_ys, _M_z_beg + _M_ye, *(_M_z_beg + __xm), _M_comp) - _M_z_beg; | |
| 1030 | } | |
| 1031 | ||
| 1032 | auto __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys)); | |
| 1033 | __merge_func __right_func(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _Cleanup(), _M_leaf_merge, _M_nsort, | |
| 1034 | _M_x_beg, _M_z_beg, _x_orig, _y_orig, _root); | |
| 1035 | __right_func._split = true; | |
| 1036 | auto __merge_task = __self->make_additional_child_of(__self->parent(), std::move(__right_func)); | |
| 1037 | __self->spawn(__merge_task); | |
| 1038 | __self->recycle_as_continuation(); | |
| 1039 | ||
| 1040 | _M_xe = __xm; | |
| 1041 | _M_ye = __ym; | |
| 1042 | _split = true; | |
| 1043 | ||
| 1044 | return __self; | |
| 1045 | } | |
| 1046 | }; | |
| 1047 | ||
| 1048 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename __M_Compare, typename _Cleanup, | |
| 1049 | typename _LeafMerge> | |
| 1050 | __task* | |
| 1051 | __merge_func<_RandomAccessIterator1, _RandomAccessIterator2, __M_Compare, _Cleanup, _LeafMerge>:: | |
| 1052 | operator()(__task* __self) | |
| 1053 | { | |
| 1054 | //a. split merge task into 2 of the same level; the special logic, | |
| 1055 | //without processing(process_ranges) adjacent sub-ranges x and y | |
| 1056 | if (_split) | |
| 1057 | return merge_ranges(__self); | |
| 1058 | ||
| 1059 | //b. General merging of adjacent sub-ranges x and y (with optimization in case of {x} <= {y} ) | |
| 1060 | ||
| 1061 | //1. x and y are in the even buffer | |
| 1062 | //2. x and y are in the odd buffer | |
| 1063 | if (_x_orig == _y_orig) | |
| 1064 | return process_ranges(__self); | |
| 1065 | ||
| 1066 | //3. x is in even buffer, y is in the odd buffer | |
| 1067 | //4. x is in odd buffer, y is in the even buffer | |
| 1068 | if (!parent_merge(__self)) | |
| 1069 | { //root merge task | |
| 1070 | if (_x_orig) | |
| 1071 | move_x_range(); | |
| 1072 | else | |
| 1073 | move_y_range(); | |
| 1074 | } | |
| 1075 | else | |
| 1076 | { | |
| 1077 | const _SizeType __nx = (_M_xe - _M_xs); | |
| 1078 | const _SizeType __ny = (_M_ye - _M_ys); | |
| 1079 | _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, ""); | |
| 1080 | _LIBCPP_ASSERT_UNCATEGORIZED(__nx > 0, ""); | |
| 1081 | ||
| 1082 | if (__nx < __ny) | |
| 1083 | move_x_range(); | |
| 1084 | else | |
| 1085 | move_y_range(); | |
| 1086 | } | |
| 1087 | ||
| 1088 | return process_ranges(__self); | |
| 1089 | } | |
| 1090 | ||
| 1091 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort> | |
| 1092 | class __stable_sort_func | |
| 1093 | { | |
| 1094 | public: | |
| 1095 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; | |
| 1096 | typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; | |
| 1097 | typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType; | |
| 1098 | ||
| 1099 | private: | |
| 1100 | _RandomAccessIterator1 _M_xs, _M_xe, _M_x_beg; | |
| 1101 | _RandomAccessIterator2 _M_zs, _M_z_beg; | |
| 1102 | _Compare _M_comp; | |
| 1103 | _LeafSort _M_leaf_sort; | |
| 1104 | bool _M_root; | |
| 1105 | _SizeType _M_nsort; //zero or number of elements to be sorted for partial_sort alforithm | |
| 1106 | ||
| 1107 | public: | |
| 1108 | __stable_sort_func(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __zs, | |
| 1109 | bool __root, _Compare __comp, _LeafSort __leaf_sort, _SizeType __nsort, | |
| 1110 | _RandomAccessIterator1 __x_beg, _RandomAccessIterator2 __z_beg) | |
| 1111 | : _M_xs(__xs), _M_xe(__xe), _M_x_beg(__x_beg), _M_zs(__zs), _M_z_beg(__z_beg), _M_comp(__comp), | |
| 1112 | _M_leaf_sort(__leaf_sort), _M_root(__root), _M_nsort(__nsort) | |
| 1113 | { | |
| 1114 | } | |
| 1115 | ||
| 1116 | __task* | |
| 1117 | operator()(__task* __self); | |
| 1118 | }; | |
| 1119 | ||
| 1120 | #define _PSTL_STABLE_SORT_CUT_OFF 500 | |
| 1121 | ||
| 1122 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _Compare, typename _LeafSort> | |
| 1123 | __task* | |
| 1124 | __stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _LeafSort>::operator()(__task* __self) | |
| 1125 | { | |
| 1126 | typedef __merge_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, __utils::__serial_destroy, | |
| 1127 | __utils::__serial_move_merge> | |
| 1128 | _MergeTaskType; | |
| 1129 | ||
| 1130 | const _SizeType __n = _M_xe - _M_xs; | |
| 1131 | const _SizeType __nmerge = _M_nsort > 0 ? _M_nsort : __n; | |
| 1132 | const _SizeType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF; | |
| 1133 | if (__n <= __sort_cut_off) | |
| 1134 | { | |
| 1135 | _M_leaf_sort(_M_xs, _M_xe, _M_comp); | |
| 1136 | _LIBCPP_ASSERT_UNCATEGORIZED(!_M_root, ""); | |
| 1137 | return nullptr; | |
| 1138 | } | |
| 1139 | ||
| 1140 | const _RandomAccessIterator1 __xm = _M_xs + __n / 2; | |
| 1141 | const _RandomAccessIterator2 __zm = _M_zs + (__xm - _M_xs); | |
| 1142 | const _RandomAccessIterator2 __ze = _M_zs + __n; | |
| 1143 | _MergeTaskType __m(_MergeTaskType(_M_xs - _M_x_beg, __xm - _M_x_beg, __xm - _M_x_beg, _M_xe - _M_x_beg, | |
| 1144 | _M_zs - _M_z_beg, _M_comp, __utils::__serial_destroy(), | |
| 1145 | __utils::__serial_move_merge(__nmerge), _M_nsort, _M_x_beg, _M_z_beg, | |
| 1146 | /*x_orig*/ true, /*y_orig*/ true, /*root*/ _M_root)); | |
| 1147 | auto __parent = __self->make_continuation(std::move(__m)); | |
| 1148 | __parent->set_ref_count(2); | |
| 1149 | auto __right = __self->make_child_of( | |
| 1150 | __parent, __stable_sort_func(__xm, _M_xe, __zm, false, _M_comp, _M_leaf_sort, _M_nsort, _M_x_beg, _M_z_beg)); | |
| 1151 | __self->spawn(__right); | |
| 1152 | __self->recycle_as_child_of(__parent); | |
| 1153 | _M_root = false; | |
| 1154 | _M_xe = __xm; | |
| 1155 | ||
| 1156 | return __self; | |
| 1157 | } | |
| 1158 | ||
| 1159 | template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> | |
| 1160 | void | |
| 1161 | __parallel_stable_sort(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __xs, | |
| 1162 | _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0) | |
| 1163 | { | |
| 1164 | tbb::this_task_arena::isolate([=, &__nsort]() { | |
| 1165 | //sorting based on task tree and parallel merge | |
| 1166 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType; | |
| 1167 | typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; | |
| 1168 | const _DifferenceType __n = __xe - __xs; | |
| 1169 | if (__nsort == __n) | |
| 1170 | __nsort = 0; // 'partial_sort' becames 'sort' | |
| 1171 | ||
| 1172 | const _DifferenceType __sort_cut_off = _PSTL_STABLE_SORT_CUT_OFF; | |
| 1173 | if (__n > __sort_cut_off) | |
| 1174 | { | |
| 1175 | __buffer<_ValueType> __buf(__n); | |
| 1176 | __root_task<__stable_sort_func<_RandomAccessIterator, _ValueType*, _Compare, _LeafSort>> __root{ | |
| 1177 | __xs, __xe, __buf.get(), true, __comp, __leaf_sort, __nsort, __xs, __buf.get()}; | |
| 1178 | __task::spawn_root_and_wait(__root); | |
| 1179 | return; | |
| 1180 | } | |
| 1181 | //serial sort | |
| 1182 | __leaf_sort(__xs, __xe, __comp); | |
| 1183 | }); | |
| 1184 | } | |
| 1185 | ||
| 1186 | //------------------------------------------------------------------------ | |
| 1187 | // parallel_merge | |
| 1188 | //------------------------------------------------------------------------ | |
| 1189 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3, | |
| 1190 | typename _Compare, typename _LeafMerge> | |
| 1191 | class __merge_func_static | |
| 1192 | { | |
| 1193 | _RandomAccessIterator1 _M_xs, _M_xe; | |
| 1194 | _RandomAccessIterator2 _M_ys, _M_ye; | |
| 1195 | _RandomAccessIterator3 _M_zs; | |
| 1196 | _Compare _M_comp; | |
| 1197 | _LeafMerge _M_leaf_merge; | |
| 1198 | ||
| 1199 | public: | |
| 1200 | __merge_func_static(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, | |
| 1201 | _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, | |
| 1202 | _LeafMerge __leaf_merge) | |
| 1203 | : _M_xs(__xs), _M_xe(__xe), _M_ys(__ys), _M_ye(__ye), _M_zs(__zs), _M_comp(__comp), _M_leaf_merge(__leaf_merge) | |
| 1204 | { | |
| 1205 | } | |
| 1206 | ||
| 1207 | __task* | |
| 1208 | operator()(__task* __self); | |
| 1209 | }; | |
| 1210 | ||
| 1211 | //TODO: consider usage of parallel_for with a custom blocked_range | |
| 1212 | template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3, | |
| 1213 | typename __M_Compare, typename _LeafMerge> | |
| 1214 | __task* | |
| 1215 | __merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, __M_Compare, _LeafMerge>:: | |
| 1216 | operator()(__task* __self) | |
| 1217 | { | |
| 1218 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; | |
| 1219 | typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; | |
| 1220 | typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType; | |
| 1221 | const _SizeType __n = (_M_xe - _M_xs) + (_M_ye - _M_ys); | |
| 1222 | const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF; | |
| 1223 | if (__n <= __merge_cut_off) | |
| 1224 | { | |
| 1225 | _M_leaf_merge(_M_xs, _M_xe, _M_ys, _M_ye, _M_zs, _M_comp); | |
| 1226 | return nullptr; | |
| 1227 | } | |
| 1228 | ||
| 1229 | _RandomAccessIterator1 __xm; | |
| 1230 | _RandomAccessIterator2 __ym; | |
| 1231 | if (_M_xe - _M_xs < _M_ye - _M_ys) | |
| 1232 | { | |
| 1233 | __ym = _M_ys + (_M_ye - _M_ys) / 2; | |
| 1234 | __xm = std::upper_bound(_M_xs, _M_xe, *__ym, _M_comp); | |
| 1235 | } | |
| 1236 | else | |
| 1237 | { | |
| 1238 | __xm = _M_xs + (_M_xe - _M_xs) / 2; | |
| 1239 | __ym = std::lower_bound(_M_ys, _M_ye, *__xm, _M_comp); | |
| 1240 | } | |
| 1241 | const _RandomAccessIterator3 __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys)); | |
| 1242 | auto __right = __self->make_additional_child_of( | |
| 1243 | __self->parent(), __merge_func_static(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _M_leaf_merge)); | |
| 1244 | __self->spawn(__right); | |
| 1245 | __self->recycle_as_continuation(); | |
| 1246 | _M_xe = __xm; | |
| 1247 | _M_ye = __ym; | |
| 1248 | ||
| 1249 | return __self; | |
| 1250 | } | |
| 1251 | ||
| 1252 | template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2, | |
| 1253 | typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge> | |
| 1254 | void | |
| 1255 | __parallel_merge(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs, | |
| 1256 | _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, | |
| 1257 | _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge) | |
| 1258 | { | |
| 1259 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; | |
| 1260 | typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; | |
| 1261 | typedef typename std::common_type<_DifferenceType1, _DifferenceType2>::type _SizeType; | |
| 1262 | const _SizeType __n = (__xe - __xs) + (__ye - __ys); | |
| 1263 | const _SizeType __merge_cut_off = _PSTL_MERGE_CUT_OFF; | |
| 1264 | if (__n <= __merge_cut_off) | |
| 1265 | { | |
| 1266 | // Fall back on serial merge | |
| 1267 | __leaf_merge(__xs, __xe, __ys, __ye, __zs, __comp); | |
| 1268 | } | |
| 1269 | else | |
| 1270 | { | |
| 1271 | tbb::this_task_arena::isolate([=]() { | |
| 1272 | typedef __merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, | |
| 1273 | _Compare, _LeafMerge> | |
| 1274 | _TaskType; | |
| 1275 | __root_task<_TaskType> __root{__xs, __xe, __ys, __ye, __zs, __comp, __leaf_merge}; | |
| 1276 | __task::spawn_root_and_wait(__root); | |
| 1277 | }); | |
| 1278 | } | |
| 1279 | } | |
| 1280 | ||
| 1281 | //------------------------------------------------------------------------ | |
| 1282 | // parallel_invoke | |
| 1283 | //------------------------------------------------------------------------ | |
| 1284 | template <class _ExecutionPolicy, typename _F1, typename _F2> | |
| 1285 | void | |
| 1286 | __parallel_invoke(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) | |
| 1287 | { | |
| 1288 | //TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future | |
| 1289 | tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); }); | |
| 1290 | } | |
| 1291 | ||
| 1292 | } // namespace __tbb_backend | |
| 1293 | } // namespace __pstl | |
| 1294 | ||
| 1295 | #endif /* _PSTL_PARALLEL_BACKEND_TBB_H */ |
lib/libcxx/include/__pstl/internal/parallel_backend_utils.h created+260| ... | ... | @@ -0,0 +1,260 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_PARALLEL_BACKEND_UTILS_H | |
| 11 | #define _PSTL_PARALLEL_BACKEND_UTILS_H | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__memory/addressof.h> | |
| 17 | ||
| 18 | #include "utils.h" | |
| 19 | ||
| 20 | namespace __pstl | |
| 21 | { | |
| 22 | ||
| 23 | namespace __utils | |
| 24 | { | |
| 25 | ||
| 26 | //! Destroy sequence [xs,xe) | |
| 27 | struct __serial_destroy | |
| 28 | { | |
| 29 | template <typename _RandomAccessIterator> | |
| 30 | void | |
| 31 | operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze) | |
| 32 | { | |
| 33 | typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType; | |
| 34 | while (__zs != __ze) | |
| 35 | { | |
| 36 | --__ze; | |
| 37 | (*__ze).~_ValueType(); | |
| 38 | } | |
| 39 | } | |
| 40 | }; | |
| 41 | ||
| 42 | //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move | |
| 43 | struct __serial_move_merge | |
| 44 | { | |
| 45 | const std::size_t _M_nmerge; | |
| 46 | ||
| 47 | explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {} | |
| 48 | template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare, | |
| 49 | class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY> | |
| 50 | void | |
| 51 | operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, | |
| 52 | _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x, | |
| 53 | _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y) | |
| 54 | { | |
| 55 | constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value; | |
| 56 | constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value; | |
| 57 | ||
| 58 | auto __n = _M_nmerge; | |
| 59 | _LIBCPP_ASSERT_UNCATEGORIZED(__n > 0, ""); | |
| 60 | ||
| 61 | auto __nx = __xe - __xs; | |
| 62 | //auto __ny = __ye - __ys; | |
| 63 | _RandomAccessIterator3 __zs_beg = __zs; | |
| 64 | ||
| 65 | if (__xs != __xe) | |
| 66 | { | |
| 67 | if (__ys != __ye) | |
| 68 | { | |
| 69 | for (;;) | |
| 70 | { | |
| 71 | if (__comp(*__ys, *__xs)) | |
| 72 | { | |
| 73 | const auto __i = __zs - __zs_beg; | |
| 74 | if (__i < __nx) | |
| 75 | __move_value_x(__ys, __zs); | |
| 76 | else | |
| 77 | __move_value_y(__ys, __zs); | |
| 78 | ++__zs, --__n; | |
| 79 | if (++__ys == __ye) | |
| 80 | { | |
| 81 | break; | |
| 82 | } | |
| 83 | else if (__n == 0) | |
| 84 | { | |
| 85 | const auto __j = __zs - __zs_beg; | |
| 86 | if (__same_move_seq || __j < __nx) | |
| 87 | __zs = __move_sequence_x(__ys, __ye, __zs); | |
| 88 | else | |
| 89 | __zs = __move_sequence_y(__ys, __ye, __zs); | |
| 90 | break; | |
| 91 | } | |
| 92 | } | |
| 93 | else | |
| 94 | { | |
| 95 | const auto __i = __zs - __zs_beg; | |
| 96 | if (__same_move_val || __i < __nx) | |
| 97 | __move_value_x(__xs, __zs); | |
| 98 | else | |
| 99 | __move_value_y(__xs, __zs); | |
| 100 | ++__zs, --__n; | |
| 101 | if (++__xs == __xe) | |
| 102 | { | |
| 103 | const auto __j = __zs - __zs_beg; | |
| 104 | if (__same_move_seq || __j < __nx) | |
| 105 | __move_sequence_x(__ys, __ye, __zs); | |
| 106 | else | |
| 107 | __move_sequence_y(__ys, __ye, __zs); | |
| 108 | return; | |
| 109 | } | |
| 110 | else if (__n == 0) | |
| 111 | { | |
| 112 | const auto __j = __zs - __zs_beg; | |
| 113 | if (__same_move_seq || __j < __nx) | |
| 114 | { | |
| 115 | __zs = __move_sequence_x(__xs, __xe, __zs); | |
| 116 | __move_sequence_x(__ys, __ye, __zs); | |
| 117 | } | |
| 118 | else | |
| 119 | { | |
| 120 | __zs = __move_sequence_y(__xs, __xe, __zs); | |
| 121 | __move_sequence_y(__ys, __ye, __zs); | |
| 122 | } | |
| 123 | return; | |
| 124 | } | |
| 125 | } | |
| 126 | } | |
| 127 | } | |
| 128 | __ys = __xs; | |
| 129 | __ye = __xe; | |
| 130 | } | |
| 131 | const auto __i = __zs - __zs_beg; | |
| 132 | if (__same_move_seq || __i < __nx) | |
| 133 | __move_sequence_x(__ys, __ye, __zs); | |
| 134 | else | |
| 135 | __move_sequence_y(__ys, __ye, __zs); | |
| 136 | } | |
| 137 | }; | |
| 138 | ||
| 139 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare, | |
| 140 | typename _CopyConstructRange> | |
| 141 | _OutputIterator | |
| 142 | __set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, | |
| 143 | _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, | |
| 144 | _CopyConstructRange __cc_range) | |
| 145 | { | |
| 146 | using _Tp = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 147 | ||
| 148 | for (; __first1 != __last1; ++__result) | |
| 149 | { | |
| 150 | if (__first2 == __last2) | |
| 151 | return __cc_range(__first1, __last1, __result); | |
| 152 | if (__comp(*__first2, *__first1)) | |
| 153 | { | |
| 154 | ::new (std::addressof(*__result)) _Tp(*__first2); | |
| 155 | ++__first2; | |
| 156 | } | |
| 157 | else | |
| 158 | { | |
| 159 | ::new (std::addressof(*__result)) _Tp(*__first1); | |
| 160 | if (!__comp(*__first1, *__first2)) | |
| 161 | ++__first2; | |
| 162 | ++__first1; | |
| 163 | } | |
| 164 | } | |
| 165 | return __cc_range(__first2, __last2, __result); | |
| 166 | } | |
| 167 | ||
| 168 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare> | |
| 169 | _OutputIterator | |
| 170 | __set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, | |
| 171 | _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp) | |
| 172 | { | |
| 173 | using _Tp = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 174 | ||
| 175 | for (; __first1 != __last1 && __first2 != __last2;) | |
| 176 | { | |
| 177 | if (__comp(*__first1, *__first2)) | |
| 178 | ++__first1; | |
| 179 | else | |
| 180 | { | |
| 181 | if (!__comp(*__first2, *__first1)) | |
| 182 | { | |
| 183 | ::new (std::addressof(*__result)) _Tp(*__first1); | |
| 184 | ++__result; | |
| 185 | ++__first1; | |
| 186 | } | |
| 187 | ++__first2; | |
| 188 | } | |
| 189 | } | |
| 190 | return __result; | |
| 191 | } | |
| 192 | ||
| 193 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare, | |
| 194 | typename _CopyConstructRange> | |
| 195 | _OutputIterator | |
| 196 | __set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, | |
| 197 | _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, | |
| 198 | _CopyConstructRange __cc_range) | |
| 199 | { | |
| 200 | using _Tp = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 201 | ||
| 202 | for (; __first1 != __last1;) | |
| 203 | { | |
| 204 | if (__first2 == __last2) | |
| 205 | return __cc_range(__first1, __last1, __result); | |
| 206 | ||
| 207 | if (__comp(*__first1, *__first2)) | |
| 208 | { | |
| 209 | ::new (std::addressof(*__result)) _Tp(*__first1); | |
| 210 | ++__result; | |
| 211 | ++__first1; | |
| 212 | } | |
| 213 | else | |
| 214 | { | |
| 215 | if (!__comp(*__first2, *__first1)) | |
| 216 | ++__first1; | |
| 217 | ++__first2; | |
| 218 | } | |
| 219 | } | |
| 220 | return __result; | |
| 221 | } | |
| 222 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare, | |
| 223 | typename _CopyConstructRange> | |
| 224 | _OutputIterator | |
| 225 | __set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, | |
| 226 | _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, | |
| 227 | _CopyConstructRange __cc_range) | |
| 228 | { | |
| 229 | using _Tp = typename std::iterator_traits<_OutputIterator>::value_type; | |
| 230 | ||
| 231 | for (; __first1 != __last1;) | |
| 232 | { | |
| 233 | if (__first2 == __last2) | |
| 234 | return __cc_range(__first1, __last1, __result); | |
| 235 | ||
| 236 | if (__comp(*__first1, *__first2)) | |
| 237 | { | |
| 238 | ::new (std::addressof(*__result)) _Tp(*__first1); | |
| 239 | ++__result; | |
| 240 | ++__first1; | |
| 241 | } | |
| 242 | else | |
| 243 | { | |
| 244 | if (__comp(*__first2, *__first1)) | |
| 245 | { | |
| 246 | ::new (std::addressof(*__result)) _Tp(*__first2); | |
| 247 | ++__result; | |
| 248 | } | |
| 249 | else | |
| 250 | ++__first1; | |
| 251 | ++__first2; | |
| 252 | } | |
| 253 | } | |
| 254 | return __cc_range(__first2, __last2, __result); | |
| 255 | } | |
| 256 | ||
| 257 | } // namespace __utils | |
| 258 | } // namespace __pstl | |
| 259 | ||
| 260 | #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */ |
lib/libcxx/include/__pstl/internal/unseq_backend_simd.h created+697| ... | ... | @@ -0,0 +1,697 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_UNSEQ_BACKEND_SIMD_H | |
| 11 | #define _PSTL_UNSEQ_BACKEND_SIMD_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__functional/operations.h> | |
| 15 | #include <__iterator/iterator_traits.h> | |
| 16 | #include <__type_traits/is_arithmetic.h> | |
| 17 | #include <__type_traits/is_same.h> | |
| 18 | #include <__utility/move.h> | |
| 19 | #include <__utility/pair.h> | |
| 20 | #include <cstddef> | |
| 21 | #include <cstdint> | |
| 22 | ||
| 23 | #include <__pstl/internal/utils.h> | |
| 24 | ||
| 25 | // This header defines the minimum set of vector routines required | |
| 26 | // to support parallel STL. | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 29 | ||
| 30 | namespace __pstl | |
| 31 | { | |
| 32 | namespace __unseq_backend | |
| 33 | { | |
| 34 | ||
| 35 | // Expect vector width up to 64 (or 512 bit) | |
| 36 | const std::size_t __lane_size = 64; | |
| 37 | ||
| 38 | template <class _Iterator, class _DifferenceType, class _Function> | |
| 39 | _LIBCPP_HIDE_FROM_ABI _Iterator | |
| 40 | __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept | |
| 41 | { | |
| 42 | _PSTL_PRAGMA_SIMD | |
| 43 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 44 | __f(__first[__i]); | |
| 45 | ||
| 46 | return __first + __n; | |
| 47 | } | |
| 48 | ||
| 49 | template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Function> | |
| 50 | _LIBCPP_HIDE_FROM_ABI _Iterator2 | |
| 51 | __simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept | |
| 52 | { | |
| 53 | _PSTL_PRAGMA_SIMD | |
| 54 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 55 | __f(__first1[__i], __first2[__i]); | |
| 56 | return __first2 + __n; | |
| 57 | } | |
| 58 | ||
| 59 | template <class _Iterator1, class _DifferenceType, class _Iterator2, class _Iterator3, class _Function> | |
| 60 | _LIBCPP_HIDE_FROM_ABI _Iterator3 | |
| 61 | __simd_walk_3(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, | |
| 62 | _Function __f) noexcept | |
| 63 | { | |
| 64 | _PSTL_PRAGMA_SIMD | |
| 65 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 66 | __f(__first1[__i], __first2[__i], __first3[__i]); | |
| 67 | return __first3 + __n; | |
| 68 | } | |
| 69 | ||
| 70 | // TODO: check whether __simd_first() can be used here | |
| 71 | template <class _Index, class _DifferenceType, class _Pred> | |
| 72 | _LIBCPP_HIDE_FROM_ABI bool | |
| 73 | __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept | |
| 74 | { | |
| 75 | _DifferenceType __block_size = 4 < __n ? 4 : __n; | |
| 76 | const _Index __last = __first + __n; | |
| 77 | while (__last != __first) | |
| 78 | { | |
| 79 | int32_t __flag = 1; | |
| 80 | _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag) | |
| 81 | for (_DifferenceType __i = 0; __i < __block_size; ++__i) | |
| 82 | if (__pred(*(__first + __i))) | |
| 83 | __flag = 0; | |
| 84 | if (!__flag) | |
| 85 | return true; | |
| 86 | ||
| 87 | __first += __block_size; | |
| 88 | if (__last - __first >= __block_size << 1) | |
| 89 | { | |
| 90 | // Double the block _Size. Any unnecessary iterations can be amortized against work done so far. | |
| 91 | __block_size <<= 1; | |
| 92 | } | |
| 93 | else | |
| 94 | { | |
| 95 | __block_size = __last - __first; | |
| 96 | } | |
| 97 | } | |
| 98 | return false; | |
| 99 | } | |
| 100 | ||
| 101 | template <class _Index1, class _DifferenceType, class _Index2, class _Pred> | |
| 102 | _LIBCPP_HIDE_FROM_ABI std::pair<_Index1, _Index2> | |
| 103 | __simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pred) noexcept | |
| 104 | { | |
| 105 | const _Index1 __last1 = __first1 + __n; | |
| 106 | const _Index2 __last2 = __first2 + __n; | |
| 107 | // Experiments show good block sizes like this | |
| 108 | const _DifferenceType __block_size = 8; | |
| 109 | alignas(__lane_size) _DifferenceType __lane[__block_size] = {0}; | |
| 110 | while (__last1 - __first1 >= __block_size) | |
| 111 | { | |
| 112 | _DifferenceType __found = 0; | |
| 113 | _DifferenceType __i; | |
| 114 | _PSTL_PRAGMA_SIMD_REDUCTION(| | |
| 115 | : __found) for (__i = 0; __i < __block_size; ++__i) | |
| 116 | { | |
| 117 | const _DifferenceType __t = __pred(__first1[__i], __first2[__i]); | |
| 118 | __lane[__i] = __t; | |
| 119 | __found |= __t; | |
| 120 | } | |
| 121 | if (__found) | |
| 122 | { | |
| 123 | _DifferenceType __i2; | |
| 124 | // This will vectorize | |
| 125 | for (__i2 = 0; __i2 < __block_size; ++__i2) | |
| 126 | { | |
| 127 | if (__lane[__i2]) | |
| 128 | break; | |
| 129 | } | |
| 130 | return std::make_pair(__first1 + __i2, __first2 + __i2); | |
| 131 | } | |
| 132 | __first1 += __block_size; | |
| 133 | __first2 += __block_size; | |
| 134 | } | |
| 135 | ||
| 136 | //Keep remainder scalar | |
| 137 | for (; __last1 != __first1; ++__first1, ++__first2) | |
| 138 | if (__pred(*(__first1), *(__first2))) | |
| 139 | return std::make_pair(__first1, __first2); | |
| 140 | ||
| 141 | return std::make_pair(__last1, __last2); | |
| 142 | } | |
| 143 | ||
| 144 | template <class _Index, class _DifferenceType, class _Pred> | |
| 145 | _LIBCPP_HIDE_FROM_ABI _DifferenceType | |
| 146 | __simd_count(_Index __index, _DifferenceType __n, _Pred __pred) noexcept | |
| 147 | { | |
| 148 | _DifferenceType __count = 0; | |
| 149 | _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count) | |
| 150 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 151 | if (__pred(*(__index + __i))) | |
| 152 | ++__count; | |
| 153 | ||
| 154 | return __count; | |
| 155 | } | |
| 156 | ||
| 157 | template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _BinaryPredicate> | |
| 158 | _LIBCPP_HIDE_FROM_ABI _OutputIterator | |
| 159 | __simd_unique_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, | |
| 160 | _BinaryPredicate __pred) noexcept | |
| 161 | { | |
| 162 | if (__n == 0) | |
| 163 | return __result; | |
| 164 | ||
| 165 | _DifferenceType __cnt = 1; | |
| 166 | __result[0] = __first[0]; | |
| 167 | ||
| 168 | _PSTL_PRAGMA_SIMD | |
| 169 | for (_DifferenceType __i = 1; __i < __n; ++__i) | |
| 170 | { | |
| 171 | if (!__pred(__first[__i], __first[__i - 1])) | |
| 172 | { | |
| 173 | __result[__cnt] = __first[__i]; | |
| 174 | ++__cnt; | |
| 175 | } | |
| 176 | } | |
| 177 | return __result + __cnt; | |
| 178 | } | |
| 179 | ||
| 180 | template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner> | |
| 181 | _LIBCPP_HIDE_FROM_ABI _OutputIterator | |
| 182 | __simd_assign(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _Assigner __assigner) noexcept | |
| 183 | { | |
| 184 | _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED | |
| 185 | _PSTL_PRAGMA_SIMD | |
| 186 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 187 | __assigner(__first + __i, __result + __i); | |
| 188 | return __result + __n; | |
| 189 | } | |
| 190 | ||
| 191 | template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _UnaryPredicate> | |
| 192 | _LIBCPP_HIDE_FROM_ABI _OutputIterator | |
| 193 | __simd_copy_if(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, _UnaryPredicate __pred) noexcept | |
| 194 | { | |
| 195 | _DifferenceType __cnt = 0; | |
| 196 | ||
| 197 | _PSTL_PRAGMA_SIMD | |
| 198 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 199 | { | |
| 200 | if (__pred(__first[__i])) | |
| 201 | { | |
| 202 | __result[__cnt] = __first[__i]; | |
| 203 | ++__cnt; | |
| 204 | } | |
| 205 | } | |
| 206 | return __result + __cnt; | |
| 207 | } | |
| 208 | ||
| 209 | template <class _InputIterator, class _DifferenceType, class _BinaryPredicate> | |
| 210 | _LIBCPP_HIDE_FROM_ABI _DifferenceType | |
| 211 | __simd_calc_mask_2(_InputIterator __first, _DifferenceType __n, bool* __mask, _BinaryPredicate __pred) noexcept | |
| 212 | { | |
| 213 | _DifferenceType __count = 0; | |
| 214 | ||
| 215 | _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count) | |
| 216 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 217 | { | |
| 218 | __mask[__i] = !__pred(__first[__i], __first[__i - 1]); | |
| 219 | __count += __mask[__i]; | |
| 220 | } | |
| 221 | return __count; | |
| 222 | } | |
| 223 | ||
| 224 | template <class _InputIterator, class _DifferenceType, class _UnaryPredicate> | |
| 225 | _LIBCPP_HIDE_FROM_ABI _DifferenceType | |
| 226 | __simd_calc_mask_1(_InputIterator __first, _DifferenceType __n, bool* __mask, _UnaryPredicate __pred) noexcept | |
| 227 | { | |
| 228 | _DifferenceType __count = 0; | |
| 229 | ||
| 230 | _PSTL_PRAGMA_SIMD_REDUCTION(+ : __count) | |
| 231 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 232 | { | |
| 233 | __mask[__i] = __pred(__first[__i]); | |
| 234 | __count += __mask[__i]; | |
| 235 | } | |
| 236 | return __count; | |
| 237 | } | |
| 238 | ||
| 239 | template <class _InputIterator, class _DifferenceType, class _OutputIterator, class _Assigner> | |
| 240 | _LIBCPP_HIDE_FROM_ABI void | |
| 241 | __simd_copy_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator __result, bool* __mask, | |
| 242 | _Assigner __assigner) noexcept | |
| 243 | { | |
| 244 | _DifferenceType __cnt = 0; | |
| 245 | _PSTL_PRAGMA_SIMD | |
| 246 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 247 | { | |
| 248 | if (__mask[__i]) | |
| 249 | { | |
| 250 | { | |
| 251 | __assigner(__first + __i, __result + __cnt); | |
| 252 | ++__cnt; | |
| 253 | } | |
| 254 | } | |
| 255 | } | |
| 256 | } | |
| 257 | ||
| 258 | template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2> | |
| 259 | _LIBCPP_HIDE_FROM_ABI void | |
| 260 | __simd_partition_by_mask(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true, | |
| 261 | _OutputIterator2 __out_false, bool* __mask) noexcept | |
| 262 | { | |
| 263 | _DifferenceType __cnt_true = 0, __cnt_false = 0; | |
| 264 | _PSTL_PRAGMA_SIMD | |
| 265 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 266 | { | |
| 267 | if (__mask[__i]) | |
| 268 | { | |
| 269 | __out_true[__cnt_true] = __first[__i]; | |
| 270 | ++__cnt_true; | |
| 271 | } | |
| 272 | else | |
| 273 | { | |
| 274 | __out_false[__cnt_false] = __first[__i]; | |
| 275 | ++__cnt_false; | |
| 276 | } | |
| 277 | } | |
| 278 | } | |
| 279 | ||
| 280 | template <class _Index, class _DifferenceType, class _Generator> | |
| 281 | _LIBCPP_HIDE_FROM_ABI _Index | |
| 282 | __simd_generate_n(_Index __first, _DifferenceType __size, _Generator __g) noexcept | |
| 283 | { | |
| 284 | _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED | |
| 285 | _PSTL_PRAGMA_SIMD | |
| 286 | for (_DifferenceType __i = 0; __i < __size; ++__i) | |
| 287 | __first[__i] = __g(); | |
| 288 | return __first + __size; | |
| 289 | } | |
| 290 | ||
| 291 | template <class _Index, class _BinaryPredicate> | |
| 292 | _LIBCPP_HIDE_FROM_ABI _Index | |
| 293 | __simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, bool __or_semantic) noexcept | |
| 294 | { | |
| 295 | if (__last - __first < 2) | |
| 296 | return __last; | |
| 297 | ||
| 298 | typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType; | |
| 299 | _DifferenceType __i = 0; | |
| 300 | ||
| 301 | // Experiments show good block sizes like this | |
| 302 | //TODO: to consider tuning block_size for various data types | |
| 303 | const _DifferenceType __block_size = 8; | |
| 304 | alignas(__lane_size) _DifferenceType __lane[__block_size] = {0}; | |
| 305 | while (__last - __first >= __block_size) | |
| 306 | { | |
| 307 | _DifferenceType __found = 0; | |
| 308 | _PSTL_PRAGMA_SIMD_REDUCTION(| | |
| 309 | : __found) for (__i = 0; __i < __block_size - 1; ++__i) | |
| 310 | { | |
| 311 | //TODO: to improve SIMD vectorization | |
| 312 | const _DifferenceType __t = __pred(*(__first + __i), *(__first + __i + 1)); | |
| 313 | __lane[__i] = __t; | |
| 314 | __found |= __t; | |
| 315 | } | |
| 316 | ||
| 317 | //Process a pair of elements on a boundary of a data block | |
| 318 | if (__first + __block_size < __last && __pred(*(__first + __i), *(__first + __i + 1))) | |
| 319 | __lane[__i] = __found = 1; | |
| 320 | ||
| 321 | if (__found) | |
| 322 | { | |
| 323 | if (__or_semantic) | |
| 324 | return __first; | |
| 325 | ||
| 326 | // This will vectorize | |
| 327 | for (__i = 0; __i < __block_size; ++__i) | |
| 328 | if (__lane[__i]) | |
| 329 | break; | |
| 330 | return __first + __i; //As far as found is true a __result (__lane[__i] is true) is guaranteed | |
| 331 | } | |
| 332 | __first += __block_size; | |
| 333 | } | |
| 334 | //Process the rest elements | |
| 335 | for (; __last - __first > 1; ++__first) | |
| 336 | if (__pred(*__first, *(__first + 1))) | |
| 337 | return __first; | |
| 338 | ||
| 339 | return __last; | |
| 340 | } | |
| 341 | ||
| 342 | // It was created to reduce the code inside std::enable_if | |
| 343 | template <typename _Tp, typename _BinaryOperation> | |
| 344 | using is_arithmetic_plus = std::integral_constant<bool, std::is_arithmetic<_Tp>::value && | |
| 345 | std::is_same<_BinaryOperation, std::plus<_Tp>>::value>; | |
| 346 | ||
| 347 | // Exclusive scan for "+" and arithmetic types | |
| 348 | template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp, | |
| 349 | class _BinaryOperation> | |
| 350 | _LIBCPP_HIDE_FROM_ABI | |
| 351 | typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 352 | __simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, | |
| 353 | _BinaryOperation, /*Inclusive*/ std::false_type) | |
| 354 | { | |
| 355 | _PSTL_PRAGMA_SIMD_SCAN(+ : __init) | |
| 356 | for (_Size __i = 0; __i < __n; ++__i) | |
| 357 | { | |
| 358 | __result[__i] = __init; | |
| 359 | _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__init) | |
| 360 | __init += __unary_op(__first[__i]); | |
| 361 | } | |
| 362 | return std::make_pair(__result + __n, __init); | |
| 363 | } | |
| 364 | ||
| 365 | // As soon as we cannot call __binary_op in "combiner" we create a wrapper over _Tp to encapsulate __binary_op | |
| 366 | template <typename _Tp, typename _BinaryOp> | |
| 367 | struct _Combiner | |
| 368 | { | |
| 369 | _Tp __value_; | |
| 370 | _BinaryOp* __bin_op_; // Here is a pointer to function because of default ctor | |
| 371 | ||
| 372 | _LIBCPP_HIDE_FROM_ABI _Combiner() : __value_{}, __bin_op_(nullptr) {} | |
| 373 | _LIBCPP_HIDE_FROM_ABI | |
| 374 | _Combiner(const _Tp& __value, const _BinaryOp* __bin_op) | |
| 375 | : __value_(__value), __bin_op_(const_cast<_BinaryOp*>(__bin_op)) {} | |
| 376 | _LIBCPP_HIDE_FROM_ABI _Combiner(const _Combiner& __obj) : __value_{}, __bin_op_(__obj.__bin_op) {} | |
| 377 | ||
| 378 | _LIBCPP_HIDE_FROM_ABI void | |
| 379 | operator()(const _Combiner& __obj) | |
| 380 | { | |
| 381 | __value_ = (*__bin_op_)(__value_, __obj.__value_); | |
| 382 | } | |
| 383 | }; | |
| 384 | ||
| 385 | // Exclusive scan for other binary operations and types | |
| 386 | template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp, | |
| 387 | class _BinaryOperation> | |
| 388 | _LIBCPP_HIDE_FROM_ABI | |
| 389 | typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 390 | __simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, | |
| 391 | _BinaryOperation __binary_op, /*Inclusive*/ std::false_type) | |
| 392 | { | |
| 393 | typedef _Combiner<_Tp, _BinaryOperation> _CombinerType; | |
| 394 | _CombinerType __combined_init{__init, &__binary_op}; | |
| 395 | ||
| 396 | _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType) | |
| 397 | _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init) | |
| 398 | for (_Size __i = 0; __i < __n; ++__i) | |
| 399 | { | |
| 400 | __result[__i] = __combined_init.__value_; | |
| 401 | _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(__combined_init) | |
| 402 | __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i])); | |
| 403 | } | |
| 404 | return std::make_pair(__result + __n, __combined_init.__value_); | |
| 405 | } | |
| 406 | ||
| 407 | // Inclusive scan for "+" and arithmetic types | |
| 408 | template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp, | |
| 409 | class _BinaryOperation> | |
| 410 | _LIBCPP_HIDE_FROM_ABI | |
| 411 | typename std::enable_if<is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 412 | __simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, | |
| 413 | _BinaryOperation, /*Inclusive*/ std::true_type) | |
| 414 | { | |
| 415 | _PSTL_PRAGMA_SIMD_SCAN(+ : __init) | |
| 416 | for (_Size __i = 0; __i < __n; ++__i) | |
| 417 | { | |
| 418 | __init += __unary_op(__first[__i]); | |
| 419 | _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__init) | |
| 420 | __result[__i] = __init; | |
| 421 | } | |
| 422 | return std::make_pair(__result + __n, __init); | |
| 423 | } | |
| 424 | ||
| 425 | // Inclusive scan for other binary operations and types | |
| 426 | template <class _InputIterator, class _Size, class _OutputIterator, class _UnaryOperation, class _Tp, | |
| 427 | class _BinaryOperation> | |
| 428 | _LIBCPP_HIDE_FROM_ABI | |
| 429 | typename std::enable_if<!is_arithmetic_plus<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type | |
| 430 | __simd_scan(_InputIterator __first, _Size __n, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, | |
| 431 | _BinaryOperation __binary_op, std::true_type) | |
| 432 | { | |
| 433 | typedef _Combiner<_Tp, _BinaryOperation> _CombinerType; | |
| 434 | _CombinerType __combined_init{__init, &__binary_op}; | |
| 435 | ||
| 436 | _PSTL_PRAGMA_DECLARE_REDUCTION(__bin_op, _CombinerType) | |
| 437 | _PSTL_PRAGMA_SIMD_SCAN(__bin_op : __combined_init) | |
| 438 | for (_Size __i = 0; __i < __n; ++__i) | |
| 439 | { | |
| 440 | __combined_init.__value_ = __binary_op(__combined_init.__value_, __unary_op(__first[__i])); | |
| 441 | _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(__combined_init) | |
| 442 | __result[__i] = __combined_init.__value_; | |
| 443 | } | |
| 444 | return std::make_pair(__result + __n, __combined_init.__value_); | |
| 445 | } | |
| 446 | ||
| 447 | // [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible. | |
| 448 | // complexity [violation] - We will have at most (__n-1 + number_of_lanes) comparisons instead of at most __n-1. | |
| 449 | template <typename _ForwardIterator, typename _Size, typename _Compare> | |
| 450 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 451 | __simd_min_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept | |
| 452 | { | |
| 453 | if (__n == 0) | |
| 454 | { | |
| 455 | return __first; | |
| 456 | } | |
| 457 | ||
| 458 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 459 | struct _ComplexType | |
| 460 | { | |
| 461 | _ValueType __min_val_; | |
| 462 | _Size __min_ind_; | |
| 463 | _Compare* __min_comp_; | |
| 464 | ||
| 465 | _LIBCPP_HIDE_FROM_ABI _ComplexType() : __min_val_{}, __min_ind_{}, __min_comp_(nullptr) {} | |
| 466 | _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ValueType& __val, const _Compare* __comp) | |
| 467 | : __min_val_(__val), __min_ind_(0), __min_comp_(const_cast<_Compare*>(__comp)) | |
| 468 | { | |
| 469 | } | |
| 470 | _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj) | |
| 471 | : __min_val_(__obj.__min_val_), __min_ind_(__obj.__min_ind_), __min_comp_(__obj.__min_comp_) | |
| 472 | { | |
| 473 | } | |
| 474 | ||
| 475 | _PSTL_PRAGMA_DECLARE_SIMD | |
| 476 | _LIBCPP_HIDE_FROM_ABI void | |
| 477 | operator()(const _ComplexType& __obj) | |
| 478 | { | |
| 479 | if (!(*__min_comp_)(__min_val_, __obj.__min_val_) && | |
| 480 | ((*__min_comp_)(__obj.__min_val_, __min_val_) || __obj.__min_ind_ - __min_ind_ < 0)) | |
| 481 | { | |
| 482 | __min_val_ = __obj.__min_val_; | |
| 483 | __min_ind_ = __obj.__min_ind_; | |
| 484 | } | |
| 485 | } | |
| 486 | }; | |
| 487 | ||
| 488 | _ComplexType __init{*__first, &__comp}; | |
| 489 | ||
| 490 | _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType) | |
| 491 | ||
| 492 | _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init) | |
| 493 | for (_Size __i = 1; __i < __n; ++__i) | |
| 494 | { | |
| 495 | const _ValueType __min_val = __init.__min_val_; | |
| 496 | const _ValueType __current = __first[__i]; | |
| 497 | if (__comp(__current, __min_val)) | |
| 498 | { | |
| 499 | __init.__min_val_ = __current; | |
| 500 | __init.__min_ind_ = __i; | |
| 501 | } | |
| 502 | } | |
| 503 | return __first + __init.__min_ind_; | |
| 504 | } | |
| 505 | ||
| 506 | // [restriction] - std::iterator_traits<_ForwardIterator>::value_type should be DefaultConstructible. | |
| 507 | // complexity [violation] - We will have at most (2*(__n-1) + 4*number_of_lanes) comparisons instead of at most [1.5*(__n-1)]. | |
| 508 | template <typename _ForwardIterator, typename _Size, typename _Compare> | |
| 509 | _LIBCPP_HIDE_FROM_ABI std::pair<_ForwardIterator, _ForwardIterator> | |
| 510 | __simd_minmax_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcept | |
| 511 | { | |
| 512 | if (__n == 0) | |
| 513 | { | |
| 514 | return std::make_pair(__first, __first); | |
| 515 | } | |
| 516 | typedef typename std::iterator_traits<_ForwardIterator>::value_type _ValueType; | |
| 517 | ||
| 518 | struct _ComplexType | |
| 519 | { | |
| 520 | _ValueType __min_val_; | |
| 521 | _ValueType __max_val_; | |
| 522 | _Size __min_ind_; | |
| 523 | _Size __max_ind_; | |
| 524 | _Compare* __minmax_comp; | |
| 525 | ||
| 526 | _LIBCPP_HIDE_FROM_ABI _ComplexType() | |
| 527 | : __min_val_{}, __max_val_{}, __min_ind_{}, __max_ind_{}, __minmax_comp(nullptr) {} | |
| 528 | _LIBCPP_HIDE_FROM_ABI _ComplexType( | |
| 529 | const _ValueType& __min_val, const _ValueType& __max_val, const _Compare* __comp) | |
| 530 | : __min_val_(__min_val), __max_val_(__max_val), __min_ind_(0), __max_ind_(0), | |
| 531 | __minmax_comp(const_cast<_Compare*>(__comp)) | |
| 532 | { | |
| 533 | } | |
| 534 | _LIBCPP_HIDE_FROM_ABI _ComplexType(const _ComplexType& __obj) | |
| 535 | : __min_val_(__obj.__min_val_), __max_val_(__obj.__max_val_), __min_ind_(__obj.__min_ind_), | |
| 536 | __max_ind_(__obj.__max_ind_), __minmax_comp(__obj.__minmax_comp) | |
| 537 | { | |
| 538 | } | |
| 539 | ||
| 540 | _LIBCPP_HIDE_FROM_ABI void | |
| 541 | operator()(const _ComplexType& __obj) | |
| 542 | { | |
| 543 | // min | |
| 544 | if ((*__minmax_comp)(__obj.__min_val_, __min_val_)) | |
| 545 | { | |
| 546 | __min_val_ = __obj.__min_val_; | |
| 547 | __min_ind_ = __obj.__min_ind_; | |
| 548 | } | |
| 549 | else if (!(*__minmax_comp)(__min_val_, __obj.__min_val_)) | |
| 550 | { | |
| 551 | __min_val_ = __obj.__min_val_; | |
| 552 | __min_ind_ = (__min_ind_ - __obj.__min_ind_ < 0) ? __min_ind_ : __obj.__min_ind_; | |
| 553 | } | |
| 554 | ||
| 555 | // max | |
| 556 | if ((*__minmax_comp)(__max_val_, __obj.__max_val_)) | |
| 557 | { | |
| 558 | __max_val_ = __obj.__max_val_; | |
| 559 | __max_ind_ = __obj.__max_ind_; | |
| 560 | } | |
| 561 | else if (!(*__minmax_comp)(__obj.__max_val_, __max_val_)) | |
| 562 | { | |
| 563 | __max_val_ = __obj.__max_val_; | |
| 564 | __max_ind_ = (__max_ind_ - __obj.__max_ind_ < 0) ? __obj.__max_ind_ : __max_ind_; | |
| 565 | } | |
| 566 | } | |
| 567 | }; | |
| 568 | ||
| 569 | _ComplexType __init{*__first, *__first, &__comp}; | |
| 570 | ||
| 571 | _PSTL_PRAGMA_DECLARE_REDUCTION(__min_func, _ComplexType); | |
| 572 | ||
| 573 | _PSTL_PRAGMA_SIMD_REDUCTION(__min_func : __init) | |
| 574 | for (_Size __i = 1; __i < __n; ++__i) | |
| 575 | { | |
| 576 | auto __min_val = __init.__min_val_; | |
| 577 | auto __max_val = __init.__max_val_; | |
| 578 | auto __current = __first + __i; | |
| 579 | if (__comp(*__current, __min_val)) | |
| 580 | { | |
| 581 | __init.__min_val_ = *__current; | |
| 582 | __init.__min_ind_ = __i; | |
| 583 | } | |
| 584 | else if (!__comp(*__current, __max_val)) | |
| 585 | { | |
| 586 | __init.__max_val_ = *__current; | |
| 587 | __init.__max_ind_ = __i; | |
| 588 | } | |
| 589 | } | |
| 590 | return std::make_pair(__first + __init.__min_ind_, __first + __init.__max_ind_); | |
| 591 | } | |
| 592 | ||
| 593 | template <class _InputIterator, class _DifferenceType, class _OutputIterator1, class _OutputIterator2, | |
| 594 | class _UnaryPredicate> | |
| 595 | _LIBCPP_HIDE_FROM_ABI std::pair<_OutputIterator1, _OutputIterator2> | |
| 596 | __simd_partition_copy(_InputIterator __first, _DifferenceType __n, _OutputIterator1 __out_true, | |
| 597 | _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept | |
| 598 | { | |
| 599 | _DifferenceType __cnt_true = 0, __cnt_false = 0; | |
| 600 | ||
| 601 | _PSTL_PRAGMA_SIMD | |
| 602 | for (_DifferenceType __i = 0; __i < __n; ++__i) | |
| 603 | { | |
| 604 | if (__pred(__first[__i])) | |
| 605 | { | |
| 606 | __out_true[__cnt_true] = __first[__i]; | |
| 607 | ++__cnt_true; | |
| 608 | } | |
| 609 | else | |
| 610 | { | |
| 611 | __out_false[__cnt_false] = __first[__i]; | |
| 612 | ++__cnt_false; | |
| 613 | } | |
| 614 | } | |
| 615 | return std::make_pair(__out_true + __cnt_true, __out_false + __cnt_false); | |
| 616 | } | |
| 617 | ||
| 618 | template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> | |
| 619 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator1 | |
| 620 | __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, | |
| 621 | _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept | |
| 622 | { | |
| 623 | typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferencType; | |
| 624 | ||
| 625 | const _DifferencType __n1 = __last - __first; | |
| 626 | const _DifferencType __n2 = __s_last - __s_first; | |
| 627 | if (__n1 == 0 || __n2 == 0) | |
| 628 | { | |
| 629 | return __last; // according to the standard | |
| 630 | } | |
| 631 | ||
| 632 | // Common case | |
| 633 | // If first sequence larger than second then we'll run simd_first with parameters of first sequence. | |
| 634 | // Otherwise, vice versa. | |
| 635 | if (__n1 < __n2) | |
| 636 | { | |
| 637 | for (; __first != __last; ++__first) | |
| 638 | { | |
| 639 | if (__unseq_backend::__simd_or( | |
| 640 | __s_first, __n2, | |
| 641 | __internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred))) | |
| 642 | { | |
| 643 | return __first; | |
| 644 | } | |
| 645 | } | |
| 646 | } | |
| 647 | else | |
| 648 | { | |
| 649 | for (; __s_first != __s_last; ++__s_first) | |
| 650 | { | |
| 651 | const auto __result = __unseq_backend::__simd_first( | |
| 652 | __first, _DifferencType(0), __n1, [__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) { | |
| 653 | return __pred(__it[__i], *__s_first); | |
| 654 | }); | |
| 655 | if (__result != __last) | |
| 656 | { | |
| 657 | return __result; | |
| 658 | } | |
| 659 | } | |
| 660 | } | |
| 661 | return __last; | |
| 662 | } | |
| 663 | ||
| 664 | template <class _RandomAccessIterator, class _DifferenceType, class _UnaryPredicate> | |
| 665 | _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator | |
| 666 | __simd_remove_if(_RandomAccessIterator __first, _DifferenceType __n, _UnaryPredicate __pred) noexcept | |
| 667 | { | |
| 668 | // find first element we need to remove | |
| 669 | auto __current = __unseq_backend::__simd_first( | |
| 670 | __first, _DifferenceType(0), __n, | |
| 671 | [&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); }); | |
| 672 | __n -= __current - __first; | |
| 673 | ||
| 674 | // if we have in sequence only one element that pred(__current[1]) != false we can exit the function | |
| 675 | if (__n < 2) | |
| 676 | { | |
| 677 | return __current; | |
| 678 | } | |
| 679 | ||
| 680 | _DifferenceType __cnt = 0; | |
| 681 | _PSTL_PRAGMA_SIMD | |
| 682 | for (_DifferenceType __i = 1; __i < __n; ++__i) | |
| 683 | { | |
| 684 | if (!__pred(__current[__i])) | |
| 685 | { | |
| 686 | __current[__cnt] = std::move(__current[__i]); | |
| 687 | ++__cnt; | |
| 688 | } | |
| 689 | } | |
| 690 | return __current + __cnt; | |
| 691 | } | |
| 692 | } // namespace __unseq_backend | |
| 693 | } // namespace __pstl | |
| 694 | ||
| 695 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 696 | ||
| 697 | #endif /* _PSTL_UNSEQ_BACKEND_SIMD_H */ |
lib/libcxx/include/__pstl/internal/utils.h created+144| ... | ... | @@ -0,0 +1,144 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _PSTL_UTILS_H | |
| 11 | #define _PSTL_UTILS_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__exception/terminate.h> | |
| 15 | #include <__utility/forward.h> | |
| 16 | #include <new> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 19 | ||
| 20 | namespace __pstl { | |
| 21 | namespace __internal { | |
| 22 | ||
| 23 | template <typename _Fp> | |
| 24 | _LIBCPP_HIDE_FROM_ABI auto __except_handler(_Fp __f) -> decltype(__f()) { | |
| 25 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 26 | try { | |
| 27 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 28 | return __f(); | |
| 29 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 30 | } catch (const std::bad_alloc&) { | |
| 31 | throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions] | |
| 32 | } catch (...) { | |
| 33 | std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions] | |
| 34 | } | |
| 35 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 36 | } | |
| 37 | ||
| 38 | template <typename _Fp> | |
| 39 | _LIBCPP_HIDE_FROM_ABI void __invoke_if(std::true_type, _Fp __f) { | |
| 40 | __f(); | |
| 41 | } | |
| 42 | ||
| 43 | template <typename _Fp> | |
| 44 | _LIBCPP_HIDE_FROM_ABI void __invoke_if(std::false_type, _Fp) {} | |
| 45 | ||
| 46 | template <typename _Fp> | |
| 47 | _LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::false_type, _Fp __f) { | |
| 48 | __f(); | |
| 49 | } | |
| 50 | ||
| 51 | template <typename _Fp> | |
| 52 | _LIBCPP_HIDE_FROM_ABI void __invoke_if_not(std::true_type, _Fp) {} | |
| 53 | ||
| 54 | template <typename _F1, typename _F2> | |
| 55 | _LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1()) { | |
| 56 | return __f1(); | |
| 57 | } | |
| 58 | ||
| 59 | template <typename _F1, typename _F2> | |
| 60 | _LIBCPP_HIDE_FROM_ABI auto __invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2()) { | |
| 61 | return __f2(); | |
| 62 | } | |
| 63 | ||
| 64 | //! Unary operator that returns reference to its argument. | |
| 65 | struct __no_op { | |
| 66 | template <typename _Tp> | |
| 67 | _LIBCPP_HIDE_FROM_ABI _Tp&& operator()(_Tp&& __a) const { | |
| 68 | return std::forward<_Tp>(__a); | |
| 69 | } | |
| 70 | }; | |
| 71 | ||
| 72 | template <typename _Pred> | |
| 73 | class __reorder_pred { | |
| 74 | _Pred __pred_; | |
| 75 | ||
| 76 | public: | |
| 77 | _LIBCPP_HIDE_FROM_ABI explicit __reorder_pred(_Pred __pred) : __pred_(__pred) {} | |
| 78 | ||
| 79 | template <typename _FTp, typename _STp> | |
| 80 | _LIBCPP_HIDE_FROM_ABI bool operator()(_FTp&& __a, _STp&& __b) { | |
| 81 | return __pred_(std::forward<_STp>(__b), std::forward<_FTp>(__a)); | |
| 82 | } | |
| 83 | }; | |
| 84 | ||
| 85 | //! Like a polymorphic lambda for pred(...,value) | |
| 86 | template <typename _Tp, typename _Predicate> | |
| 87 | class __equal_value_by_pred { | |
| 88 | const _Tp& __value_; | |
| 89 | _Predicate __pred_; | |
| 90 | ||
| 91 | public: | |
| 92 | _LIBCPP_HIDE_FROM_ABI __equal_value_by_pred(const _Tp& __value, _Predicate __pred) | |
| 93 | : __value_(__value), __pred_(__pred) {} | |
| 94 | ||
| 95 | template <typename _Arg> | |
| 96 | _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) { | |
| 97 | return __pred_(std::forward<_Arg>(__arg), __value_); | |
| 98 | } | |
| 99 | }; | |
| 100 | ||
| 101 | //! Like a polymorphic lambda for ==value | |
| 102 | template <typename _Tp> | |
| 103 | class __equal_value { | |
| 104 | const _Tp& __value_; | |
| 105 | ||
| 106 | public: | |
| 107 | _LIBCPP_HIDE_FROM_ABI explicit __equal_value(const _Tp& __value) : __value_(__value) {} | |
| 108 | ||
| 109 | template <typename _Arg> | |
| 110 | _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const { | |
| 111 | return std::forward<_Arg>(__arg) == __value_; | |
| 112 | } | |
| 113 | }; | |
| 114 | ||
| 115 | //! Logical negation of ==value | |
| 116 | template <typename _Tp> | |
| 117 | class __not_equal_value { | |
| 118 | const _Tp& __value_; | |
| 119 | ||
| 120 | public: | |
| 121 | _LIBCPP_HIDE_FROM_ABI explicit __not_equal_value(const _Tp& __value) : __value_(__value) {} | |
| 122 | ||
| 123 | template <typename _Arg> | |
| 124 | _LIBCPP_HIDE_FROM_ABI bool operator()(_Arg&& __arg) const { | |
| 125 | return !(std::forward<_Arg>(__arg) == __value_); | |
| 126 | } | |
| 127 | }; | |
| 128 | ||
| 129 | template <typename _ForwardIterator, typename _Compare> | |
| 130 | _LIBCPP_HIDE_FROM_ABI _ForwardIterator | |
| 131 | __cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp) { | |
| 132 | if (__a < __b) { // we should return closer iterator | |
| 133 | return __comp(*__b, *__a) ? __b : __a; | |
| 134 | } else { | |
| 135 | return __comp(*__a, *__b) ? __a : __b; | |
| 136 | } | |
| 137 | } | |
| 138 | ||
| 139 | } // namespace __internal | |
| 140 | } // namespace __pstl | |
| 141 | ||
| 142 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 143 | ||
| 144 | #endif /* _PSTL_UTILS_H */ |
lib/libcxx/include/__pstl_algorithm created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef __PSTL_ALGORITHM | |
| 11 | #define __PSTL_ALGORITHM | |
| 12 | ||
| 13 | #include <pstl/internal/glue_algorithm_impl.h> | |
| 14 | ||
| 15 | #endif /* __PSTL_ALGORITHM */ |
lib/libcxx/include/__pstl_memory created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef __PSTL_MEMORY | |
| 11 | #define __PSTL_MEMORY | |
| 12 | ||
| 13 | #include <pstl/internal/glue_memory_impl.h> | |
| 14 | ||
| 15 | #endif /* __PSTL_MEMORY */ |
lib/libcxx/include/__pstl_numeric created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef __PSTL_NUMERIC | |
| 11 | #define __PSTL_NUMERIC | |
| 12 | ||
| 13 | #include <pstl/internal/glue_numeric_impl.h> | |
| 14 | ||
| 15 | #endif /* __PSTL_NUMERIC */ |
lib/libcxx/include/__random/binomial_distribution.h+3-2| ... | ... | @@ -42,7 +42,7 @@ public: |
| 42 | 42 | public: |
| 43 | 43 | typedef binomial_distribution distribution_type; |
| 44 | 44 | |
| 45 | explicit param_type(result_type __t = 1, double __p = 0.5); | |
| 45 | _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __t = 1, double __p = 0.5); | |
| 46 | 46 | |
| 47 | 47 | _LIBCPP_INLINE_VISIBILITY |
| 48 | 48 | result_type t() const {return __t_;} |
| ... | ... | @@ -85,7 +85,8 @@ public: |
| 85 | 85 | _LIBCPP_INLINE_VISIBILITY |
| 86 | 86 | result_type operator()(_URNG& __g) |
| 87 | 87 | {return (*this)(__g, __p_);} |
| 88 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 88 | template<class _URNG> | |
| 89 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 89 | 90 | |
| 90 | 91 | // property functions |
| 91 | 92 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/clamp_to_integral.h+2-3| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <cmath> |
| 14 | 14 | #include <limits> |
| 15 | #include <type_traits> | |
| 16 | 15 | |
| 17 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 18 | 17 | # pragma GCC system_header |
| ... | ... | @@ -44,8 +43,8 @@ template <class _IntT, class _RealT> |
| 44 | 43 | _LIBCPP_INLINE_VISIBILITY |
| 45 | 44 | _IntT __clamp_to_integral(_RealT __r) _NOEXCEPT { |
| 46 | 45 | using _Lim = numeric_limits<_IntT>; |
| 47 | const _IntT _MaxVal = __max_representable_int_for_float<_IntT, _RealT>(); | |
| 48 | if (__r >= ::nextafter(static_cast<_RealT>(_MaxVal), INFINITY)) { | |
| 46 | const _IntT __max_val = __max_representable_int_for_float<_IntT, _RealT>(); | |
| 47 | if (__r >= ::nextafter(static_cast<_RealT>(__max_val), INFINITY)) { | |
| 49 | 48 | return _Lim::max(); |
| 50 | 49 | } else if (__r <= _Lim::lowest()) { |
| 51 | 50 | return _Lim::min(); |
lib/libcxx/include/__random/discard_block_engine.h+4-2| ... | ... | @@ -11,10 +11,12 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__random/is_seed_sequence.h> |
| 14 | #include <__type_traits/enable_if.h> | |
| 15 | #include <__type_traits/is_convertible.h> | |
| 14 | 16 | #include <__utility/move.h> |
| 17 | #include <cstddef> | |
| 15 | 18 | #include <iosfwd> |
| 16 | 19 | #include <limits> |
| 17 | #include <type_traits> | |
| 18 | 20 | |
| 19 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 22 | # pragma GCC system_header |
| ... | ... | @@ -90,7 +92,7 @@ public: |
| 90 | 92 | seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;} |
| 91 | 93 | |
| 92 | 94 | // generating functions |
| 93 | result_type operator()(); | |
| 95 | _LIBCPP_HIDE_FROM_ABI result_type operator()(); | |
| 94 | 96 | _LIBCPP_INLINE_VISIBILITY |
| 95 | 97 | void discard(unsigned long long __z) {for (; __z; --__z) operator()();} |
| 96 | 98 |
lib/libcxx/include/__random/discrete_distribution.h+5-4| ... | ... | @@ -53,10 +53,10 @@ public: |
| 53 | 53 | : __p_(__wl.begin(), __wl.end()) {__init();} |
| 54 | 54 | #endif // _LIBCPP_CXX03_LANG |
| 55 | 55 | template<class _UnaryOperation> |
| 56 | param_type(size_t __nw, double __xmin, double __xmax, | |
| 56 | _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, double __xmin, double __xmax, | |
| 57 | 57 | _UnaryOperation __fw); |
| 58 | 58 | |
| 59 | vector<double> probabilities() const; | |
| 59 | _LIBCPP_HIDE_FROM_ABI vector<double> probabilities() const; | |
| 60 | 60 | |
| 61 | 61 | friend _LIBCPP_INLINE_VISIBILITY |
| 62 | 62 | bool operator==(const param_type& __x, const param_type& __y) |
| ... | ... | @@ -66,7 +66,7 @@ public: |
| 66 | 66 | {return !(__x == __y);} |
| 67 | 67 | |
| 68 | 68 | private: |
| 69 | void __init(); | |
| 69 | _LIBCPP_HIDE_FROM_ABI void __init(); | |
| 70 | 70 | |
| 71 | 71 | friend class discrete_distribution; |
| 72 | 72 | |
| ... | ... | @@ -115,7 +115,8 @@ public: |
| 115 | 115 | _LIBCPP_INLINE_VISIBILITY |
| 116 | 116 | result_type operator()(_URNG& __g) |
| 117 | 117 | {return (*this)(__g, __p_);} |
| 118 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 118 | template<class _URNG> | |
| 119 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 119 | 120 | |
| 120 | 121 | // property functions |
| 121 | 122 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/exponential_distribution.h+2-1| ... | ... | @@ -79,7 +79,8 @@ public: |
| 79 | 79 | _LIBCPP_INLINE_VISIBILITY |
| 80 | 80 | result_type operator()(_URNG& __g) |
| 81 | 81 | {return (*this)(__g, __p_);} |
| 82 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 82 | template<class _URNG> | |
| 83 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 83 | 84 | |
| 84 | 85 | // property functions |
| 85 | 86 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/extreme_value_distribution.h+2-1| ... | ... | @@ -84,7 +84,8 @@ public: |
| 84 | 84 | _LIBCPP_INLINE_VISIBILITY |
| 85 | 85 | result_type operator()(_URNG& __g) |
| 86 | 86 | {return (*this)(__g, __p_);} |
| 87 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 87 | template<class _URNG> | |
| 88 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 88 | 89 | |
| 89 | 90 | // property functions |
| 90 | 91 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/fisher_f_distribution.h+2-1| ... | ... | @@ -82,7 +82,8 @@ public: |
| 82 | 82 | _LIBCPP_INLINE_VISIBILITY |
| 83 | 83 | result_type operator()(_URNG& __g) |
| 84 | 84 | {return (*this)(__g, __p_);} |
| 85 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 85 | template<class _URNG> | |
| 86 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 86 | 87 | |
| 87 | 88 | // property functions |
| 88 | 89 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/gamma_distribution.h+2-1| ... | ... | @@ -85,7 +85,8 @@ public: |
| 85 | 85 | _LIBCPP_INLINE_VISIBILITY |
| 86 | 86 | result_type operator()(_URNG& __g) |
| 87 | 87 | {return (*this)(__g, __p_);} |
| 88 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 88 | template<class _URNG> | |
| 89 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 89 | 90 | |
| 90 | 91 | // property functions |
| 91 | 92 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/generate_canonical.h+11-11| ... | ... | @@ -30,20 +30,20 @@ template<class _RealType, size_t __bits, class _URNG> |
| 30 | 30 | _LIBCPP_HIDE_FROM_ABI _RealType |
| 31 | 31 | generate_canonical(_URNG& __g) |
| 32 | 32 | { |
| 33 | const size_t _Dt = numeric_limits<_RealType>::digits; | |
| 34 | const size_t __b = _Dt < __bits ? _Dt : __bits; | |
| 33 | const size_t __dt = numeric_limits<_RealType>::digits; | |
| 34 | const size_t __b = __dt < __bits ? __dt : __bits; | |
| 35 | 35 | #ifdef _LIBCPP_CXX03_LANG |
| 36 | const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value; | |
| 36 | const size_t __log_r = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value; | |
| 37 | 37 | #else |
| 38 | const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value; | |
| 38 | const size_t __log_r = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value; | |
| 39 | 39 | #endif |
| 40 | const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0); | |
| 41 | const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); | |
| 42 | _RealType __base = _Rp; | |
| 43 | _RealType _Sp = __g() - _URNG::min(); | |
| 44 | for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) | |
| 45 | _Sp += (__g() - _URNG::min()) * __base; | |
| 46 | return _Sp / __base; | |
| 40 | const size_t __k = __b / __log_r + (__b % __log_r != 0) + (__b == 0); | |
| 41 | const _RealType __rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1); | |
| 42 | _RealType __base = __rp; | |
| 43 | _RealType __sp = __g() - _URNG::min(); | |
| 44 | for (size_t __i = 1; __i < __k; ++__i, __base *= __rp) | |
| 45 | __sp += (__g() - _URNG::min()) * __base; | |
| 46 | return __sp / __base; | |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__random/independent_bits_engine.h+9-6| ... | ... | @@ -12,10 +12,13 @@ |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__random/is_seed_sequence.h> |
| 14 | 14 | #include <__random/log2.h> |
| 15 | #include <__type_traits/conditional.h> | |
| 16 | #include <__type_traits/enable_if.h> | |
| 17 | #include <__type_traits/is_convertible.h> | |
| 15 | 18 | #include <__utility/move.h> |
| 19 | #include <cstddef> | |
| 16 | 20 | #include <iosfwd> |
| 17 | 21 | #include <limits> |
| 18 | #include <type_traits> | |
| 19 | 22 | |
| 20 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 24 | # pragma GCC system_header |
| ... | ... | @@ -161,7 +164,7 @@ public: |
| 161 | 164 | private: |
| 162 | 165 | _LIBCPP_INLINE_VISIBILITY |
| 163 | 166 | result_type __eval(false_type); |
| 164 | result_type __eval(true_type); | |
| 167 | _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type); | |
| 165 | 168 | |
| 166 | 169 | template <size_t __count> |
| 167 | 170 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -196,7 +199,7 @@ template<class _Engine, size_t __w, class _UIntType> |
| 196 | 199 | _UIntType |
| 197 | 200 | independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type) |
| 198 | 201 | { |
| 199 | result_type _Sp = 0; | |
| 202 | result_type __sp = 0; | |
| 200 | 203 | for (size_t __k = 0; __k < __n0; ++__k) |
| 201 | 204 | { |
| 202 | 205 | _Engine_result_type __u; |
| ... | ... | @@ -204,7 +207,7 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type) |
| 204 | 207 | { |
| 205 | 208 | __u = __e_() - _Engine::min(); |
| 206 | 209 | } while (__u >= __y0); |
| 207 | _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0)); | |
| 210 | __sp = static_cast<result_type>(__lshift<__w0>(__sp) + (__u & __mask0)); | |
| 208 | 211 | } |
| 209 | 212 | for (size_t __k = __n0; __k < __n; ++__k) |
| 210 | 213 | { |
| ... | ... | @@ -213,9 +216,9 @@ independent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type) |
| 213 | 216 | { |
| 214 | 217 | __u = __e_() - _Engine::min(); |
| 215 | 218 | } while (__u >= __y1); |
| 216 | _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1)); | |
| 219 | __sp = static_cast<result_type>(__lshift<__w0+1>(__sp) + (__u & __mask1)); | |
| 217 | 220 | } |
| 218 | return _Sp; | |
| 221 | return __sp; | |
| 219 | 222 | } |
| 220 | 223 | |
| 221 | 224 | template<class _Eng, size_t _Wp, class _UInt> |
lib/libcxx/include/__random/is_seed_sequence.h+3-1| ... | ... | @@ -10,7 +10,9 @@ |
| 10 | 10 | #define _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <type_traits> | |
| 13 | #include <__type_traits/is_convertible.h> | |
| 14 | #include <__type_traits/is_same.h> | |
| 15 | #include <__type_traits/remove_cv.h> | |
| 14 | 16 | |
| 15 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 16 | 18 | # pragma GCC system_header |
lib/libcxx/include/__random/is_valid.h+5-1| ... | ... | @@ -10,8 +10,12 @@ |
| 10 | 10 | #define _LIBCPP___RANDOM_IS_VALID_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <__type_traits/enable_if.h> | |
| 14 | #include <__type_traits/integral_constant.h> | |
| 15 | #include <__type_traits/is_same.h> | |
| 16 | #include <__type_traits/is_unsigned.h> | |
| 17 | #include <__utility/declval.h> | |
| 13 | 18 | #include <cstdint> |
| 14 | #include <type_traits> | |
| 15 | 19 | |
| 16 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 21 | # pragma GCC system_header |
lib/libcxx/include/__random/linear_congruential_engine.h+5-3| ... | ... | @@ -11,9 +11,11 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__random/is_seed_sequence.h> |
| 14 | #include <__type_traits/enable_if.h> | |
| 15 | #include <__type_traits/integral_constant.h> | |
| 16 | #include <__type_traits/is_unsigned.h> | |
| 14 | 17 | #include <cstdint> |
| 15 | 18 | #include <iosfwd> |
| 16 | #include <type_traits> | |
| 17 | 19 | |
| 18 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 21 | # pragma GCC system_header |
| ... | ... | @@ -294,9 +296,9 @@ private: |
| 294 | 296 | void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;} |
| 295 | 297 | |
| 296 | 298 | template<class _Sseq> |
| 297 | void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 299 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 298 | 300 | template<class _Sseq> |
| 299 | void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 301 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 300 | 302 | |
| 301 | 303 | template <class _CharT, class _Traits, |
| 302 | 304 | class _Up, _Up _Ap, _Up _Cp, _Up _Np> |
lib/libcxx/include/__random/log2.h+1-1| ... | ... | @@ -10,8 +10,8 @@ |
| 10 | 10 | #define _LIBCPP___RANDOM_LOG2_H |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | #include <__type_traits/conditional.h> | |
| 13 | 14 | #include <cstddef> |
| 14 | #include <type_traits> | |
| 15 | 15 | |
| 16 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 17 | 17 | # pragma GCC system_header |
lib/libcxx/include/__random/lognormal_distribution.h-138| ... | ... | @@ -24,142 +24,6 @@ _LIBCPP_PUSH_MACROS |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #ifdef _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION | |
| 28 | ||
| 29 | template<class _RealType = double> | |
| 30 | class _LIBCPP_TEMPLATE_VIS lognormal_distribution | |
| 31 | { | |
| 32 | public: | |
| 33 | // types | |
| 34 | typedef _RealType result_type; | |
| 35 | ||
| 36 | class _LIBCPP_TEMPLATE_VIS param_type | |
| 37 | { | |
| 38 | normal_distribution<result_type> __nd_; | |
| 39 | public: | |
| 40 | typedef lognormal_distribution distribution_type; | |
| 41 | ||
| 42 | _LIBCPP_INLINE_VISIBILITY | |
| 43 | explicit param_type(result_type __m = 0, result_type __s = 1) | |
| 44 | : __nd_(__m, __s) {} | |
| 45 | ||
| 46 | _LIBCPP_INLINE_VISIBILITY | |
| 47 | result_type m() const {return __nd_.mean();} | |
| 48 | _LIBCPP_INLINE_VISIBILITY | |
| 49 | result_type s() const {return __nd_.stddev();} | |
| 50 | ||
| 51 | friend _LIBCPP_INLINE_VISIBILITY | |
| 52 | bool operator==(const param_type& __x, const param_type& __y) | |
| 53 | {return __x.__nd_ == __y.__nd_;} | |
| 54 | friend _LIBCPP_INLINE_VISIBILITY | |
| 55 | bool operator!=(const param_type& __x, const param_type& __y) | |
| 56 | {return !(__x == __y);} | |
| 57 | friend class lognormal_distribution; | |
| 58 | ||
| 59 | template <class _CharT, class _Traits, class _RT> | |
| 60 | friend | |
| 61 | basic_ostream<_CharT, _Traits>& | |
| 62 | operator<<(basic_ostream<_CharT, _Traits>& __os, | |
| 63 | const lognormal_distribution<_RT>& __x); | |
| 64 | ||
| 65 | template <class _CharT, class _Traits, class _RT> | |
| 66 | friend | |
| 67 | basic_istream<_CharT, _Traits>& | |
| 68 | operator>>(basic_istream<_CharT, _Traits>& __is, | |
| 69 | lognormal_distribution<_RT>& __x); | |
| 70 | }; | |
| 71 | ||
| 72 | private: | |
| 73 | param_type __p_; | |
| 74 | ||
| 75 | public: | |
| 76 | // constructor and reset functions | |
| 77 | #ifndef _LIBCPP_CXX03_LANG | |
| 78 | _LIBCPP_INLINE_VISIBILITY | |
| 79 | lognormal_distribution() : lognormal_distribution(0) {} | |
| 80 | _LIBCPP_INLINE_VISIBILITY | |
| 81 | explicit lognormal_distribution(result_type __m, result_type __s = 1) | |
| 82 | : __p_(param_type(__m, __s)) {} | |
| 83 | #else | |
| 84 | _LIBCPP_INLINE_VISIBILITY | |
| 85 | explicit lognormal_distribution(result_type __m = 0, | |
| 86 | result_type __s = 1) | |
| 87 | : __p_(param_type(__m, __s)) {} | |
| 88 | #endif | |
| 89 | _LIBCPP_INLINE_VISIBILITY | |
| 90 | explicit lognormal_distribution(const param_type& __p) | |
| 91 | : __p_(__p) {} | |
| 92 | _LIBCPP_INLINE_VISIBILITY | |
| 93 | void reset() {__p_.__nd_.reset();} | |
| 94 | ||
| 95 | // generating functions | |
| 96 | template<class _URNG> | |
| 97 | _LIBCPP_INLINE_VISIBILITY | |
| 98 | result_type operator()(_URNG& __g) | |
| 99 | {return (*this)(__g, __p_);} | |
| 100 | template<class _URNG> | |
| 101 | _LIBCPP_INLINE_VISIBILITY | |
| 102 | result_type operator()(_URNG& __g, const param_type& __p) | |
| 103 | {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));} | |
| 104 | ||
| 105 | // property functions | |
| 106 | _LIBCPP_INLINE_VISIBILITY | |
| 107 | result_type m() const {return __p_.m();} | |
| 108 | _LIBCPP_INLINE_VISIBILITY | |
| 109 | result_type s() const {return __p_.s();} | |
| 110 | ||
| 111 | _LIBCPP_INLINE_VISIBILITY | |
| 112 | param_type param() const {return __p_;} | |
| 113 | _LIBCPP_INLINE_VISIBILITY | |
| 114 | void param(const param_type& __p) {__p_ = __p;} | |
| 115 | ||
| 116 | _LIBCPP_INLINE_VISIBILITY | |
| 117 | result_type min() const {return 0;} | |
| 118 | _LIBCPP_INLINE_VISIBILITY | |
| 119 | result_type max() const {return numeric_limits<result_type>::infinity();} | |
| 120 | ||
| 121 | friend _LIBCPP_INLINE_VISIBILITY | |
| 122 | bool operator==(const lognormal_distribution& __x, | |
| 123 | const lognormal_distribution& __y) | |
| 124 | {return __x.__p_ == __y.__p_;} | |
| 125 | friend _LIBCPP_INLINE_VISIBILITY | |
| 126 | bool operator!=(const lognormal_distribution& __x, | |
| 127 | const lognormal_distribution& __y) | |
| 128 | {return !(__x == __y);} | |
| 129 | ||
| 130 | template <class _CharT, class _Traits, class _RT> | |
| 131 | friend | |
| 132 | basic_ostream<_CharT, _Traits>& | |
| 133 | operator<<(basic_ostream<_CharT, _Traits>& __os, | |
| 134 | const lognormal_distribution<_RT>& __x); | |
| 135 | ||
| 136 | template <class _CharT, class _Traits, class _RT> | |
| 137 | friend | |
| 138 | basic_istream<_CharT, _Traits>& | |
| 139 | operator>>(basic_istream<_CharT, _Traits>& __is, | |
| 140 | lognormal_distribution<_RT>& __x); | |
| 141 | }; | |
| 142 | ||
| 143 | template <class _CharT, class _Traits, class _RT> | |
| 144 | inline _LIBCPP_INLINE_VISIBILITY | |
| 145 | basic_ostream<_CharT, _Traits>& | |
| 146 | operator<<(basic_ostream<_CharT, _Traits>& __os, | |
| 147 | const lognormal_distribution<_RT>& __x) | |
| 148 | { | |
| 149 | return __os << __x.__p_.__nd_; | |
| 150 | } | |
| 151 | ||
| 152 | template <class _CharT, class _Traits, class _RT> | |
| 153 | inline _LIBCPP_INLINE_VISIBILITY | |
| 154 | basic_istream<_CharT, _Traits>& | |
| 155 | operator>>(basic_istream<_CharT, _Traits>& __is, | |
| 156 | lognormal_distribution<_RT>& __x) | |
| 157 | { | |
| 158 | return __is >> __x.__p_.__nd_; | |
| 159 | } | |
| 160 | ||
| 161 | #else // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION | |
| 162 | ||
| 163 | 27 | template<class _RealType = double> |
| 164 | 28 | class _LIBCPP_TEMPLATE_VIS lognormal_distribution |
| 165 | 29 | { |
| ... | ... | @@ -290,8 +154,6 @@ operator>>(basic_istream<_CharT, _Traits>& __is, |
| 290 | 154 | return __is >> __x.__nd_; |
| 291 | 155 | } |
| 292 | 156 | |
| 293 | #endif // _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION | |
| 294 | ||
| 295 | 157 | _LIBCPP_END_NAMESPACE_STD |
| 296 | 158 | |
| 297 | 159 | _LIBCPP_POP_MACROS |
lib/libcxx/include/__random/mersenne_twister_engine.h+6-7| ... | ... | @@ -17,7 +17,6 @@ |
| 17 | 17 | #include <cstdint> |
| 18 | 18 | #include <iosfwd> |
| 19 | 19 | #include <limits> |
| 20 | #include <type_traits> | |
| 21 | 20 | |
| 22 | 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 23 | 22 | # pragma GCC system_header |
| ... | ... | @@ -141,7 +140,7 @@ public: |
| 141 | 140 | explicit mersenne_twister_engine(_Sseq& __q, |
| 142 | 141 | typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0) |
| 143 | 142 | {seed(__q);} |
| 144 | void seed(result_type __sd = default_seed); | |
| 143 | _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd = default_seed); | |
| 145 | 144 | template<class _Sseq> |
| 146 | 145 | _LIBCPP_INLINE_VISIBILITY |
| 147 | 146 | typename enable_if |
| ... | ... | @@ -153,7 +152,7 @@ public: |
| 153 | 152 | {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());} |
| 154 | 153 | |
| 155 | 154 | // generating functions |
| 156 | result_type operator()(); | |
| 155 | _LIBCPP_HIDE_FROM_ABI result_type operator()(); | |
| 157 | 156 | _LIBCPP_INLINE_VISIBILITY |
| 158 | 157 | void discard(unsigned long long __z) {for (; __z; --__z) operator()();} |
| 159 | 158 | |
| ... | ... | @@ -199,9 +198,9 @@ public: |
| 199 | 198 | private: |
| 200 | 199 | |
| 201 | 200 | template<class _Sseq> |
| 202 | void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 201 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 203 | 202 | template<class _Sseq> |
| 204 | void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 203 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 205 | 204 | |
| 206 | 205 | template <size_t __count> |
| 207 | 206 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -403,9 +402,9 @@ mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, |
| 403 | 402 | const size_t __j = (__i_ + 1) % __n; |
| 404 | 403 | const result_type __mask = __r == _Dt ? result_type(~0) : |
| 405 | 404 | (result_type(1) << __r) - result_type(1); |
| 406 | const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); | |
| 405 | const result_type __yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask); | |
| 407 | 406 | const size_t __k = (__i_ + __m) % __n; |
| 408 | __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1)); | |
| 407 | __x_[__i_] = __x_[__k] ^ __rshift<1>(__yp) ^ (__a * (__yp & 1)); | |
| 409 | 408 | result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d); |
| 410 | 409 | __i_ = __j; |
| 411 | 410 | __z ^= __lshift<__s>(__z) & __b; |
lib/libcxx/include/__random/negative_binomial_distribution.h+5-3| ... | ... | @@ -85,7 +85,8 @@ public: |
| 85 | 85 | _LIBCPP_INLINE_VISIBILITY |
| 86 | 86 | result_type operator()(_URNG& __g) |
| 87 | 87 | {return (*this)(__g, __p_);} |
| 88 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 88 | template<class _URNG> | |
| 89 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 89 | 90 | |
| 90 | 91 | // property functions |
| 91 | 92 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -135,8 +136,9 @@ negative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_ |
| 135 | 136 | else |
| 136 | 137 | ++__f; |
| 137 | 138 | } |
| 138 | _LIBCPP_ASSERT(__f >= 0, "std::negative_binomial_distribution should never produce negative values. " | |
| 139 | "This is almost certainly a signed integer overflow issue on __f."); | |
| 139 | _LIBCPP_ASSERT_UNCATEGORIZED(__f >= 0, | |
| 140 | "std::negative_binomial_distribution should never produce negative values. " | |
| 141 | "This is almost certainly a signed integer overflow issue on __f."); | |
| 140 | 142 | return __f; |
| 141 | 143 | } |
| 142 | 144 | return poisson_distribution<result_type>(gamma_distribution<double> |
lib/libcxx/include/__random/normal_distribution.h+18-17| ... | ... | @@ -86,7 +86,8 @@ public: |
| 86 | 86 | _LIBCPP_INLINE_VISIBILITY |
| 87 | 87 | result_type operator()(_URNG& __g) |
| 88 | 88 | {return (*this)(__g, __p_);} |
| 89 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 89 | template<class _URNG> | |
| 90 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 90 | 91 | |
| 91 | 92 | // property functions |
| 92 | 93 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -133,30 +134,30 @@ _RealType |
| 133 | 134 | normal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p) |
| 134 | 135 | { |
| 135 | 136 | static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); |
| 136 | result_type _Up; | |
| 137 | result_type __up; | |
| 137 | 138 | if (__v_hot_) |
| 138 | 139 | { |
| 139 | 140 | __v_hot_ = false; |
| 140 | _Up = __v_; | |
| 141 | __up = __v_; | |
| 141 | 142 | } |
| 142 | 143 | else |
| 143 | 144 | { |
| 144 | uniform_real_distribution<result_type> _Uni(-1, 1); | |
| 145 | uniform_real_distribution<result_type> __uni(-1, 1); | |
| 145 | 146 | result_type __u; |
| 146 | 147 | result_type __v; |
| 147 | 148 | result_type __s; |
| 148 | 149 | do |
| 149 | 150 | { |
| 150 | __u = _Uni(__g); | |
| 151 | __v = _Uni(__g); | |
| 151 | __u = __uni(__g); | |
| 152 | __v = __uni(__g); | |
| 152 | 153 | __s = __u * __u + __v * __v; |
| 153 | 154 | } while (__s > 1 || __s == 0); |
| 154 | result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s); | |
| 155 | __v_ = __v * _Fp; | |
| 155 | result_type __fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s); | |
| 156 | __v_ = __v * __fp; | |
| 156 | 157 | __v_hot_ = true; |
| 157 | _Up = __u * _Fp; | |
| 158 | __up = __u * __fp; | |
| 158 | 159 | } |
| 159 | return _Up * __p.stddev() + __p.mean(); | |
| 160 | return __up * __p.stddev() + __p.mean(); | |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | 163 | template <class _CharT, class _Traits, class _RT> |
| ... | ... | @@ -189,16 +190,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is, |
| 189 | 190 | __is.flags(_Istream::dec | _Istream::skipws); |
| 190 | 191 | result_type __mean; |
| 191 | 192 | result_type __stddev; |
| 192 | result_type _Vp = 0; | |
| 193 | bool _V_hot = false; | |
| 194 | __is >> __mean >> __stddev >> _V_hot; | |
| 195 | if (_V_hot) | |
| 196 | __is >> _Vp; | |
| 193 | result_type __vp = 0; | |
| 194 | bool __v_hot = false; | |
| 195 | __is >> __mean >> __stddev >> __v_hot; | |
| 196 | if (__v_hot) | |
| 197 | __is >> __vp; | |
| 197 | 198 | if (!__is.fail()) |
| 198 | 199 | { |
| 199 | 200 | __x.param(param_type(__mean, __stddev)); |
| 200 | __x.__v_hot_ = _V_hot; | |
| 201 | __x.__v_ = _Vp; | |
| 201 | __x.__v_hot_ = __v_hot; | |
| 202 | __x.__v_ = __vp; | |
| 202 | 203 | } |
| 203 | 204 | return __is; |
| 204 | 205 | } |
lib/libcxx/include/__random/piecewise_constant_distribution.h+9-8| ... | ... | @@ -41,19 +41,19 @@ public: |
| 41 | 41 | public: |
| 42 | 42 | typedef piecewise_constant_distribution distribution_type; |
| 43 | 43 | |
| 44 | param_type(); | |
| 44 | _LIBCPP_HIDE_FROM_ABI param_type(); | |
| 45 | 45 | template<class _InputIteratorB, class _InputIteratorW> |
| 46 | param_type(_InputIteratorB __f_b, _InputIteratorB __l_b, | |
| 46 | _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b, | |
| 47 | 47 | _InputIteratorW __f_w); |
| 48 | 48 | #ifndef _LIBCPP_CXX03_LANG |
| 49 | 49 | template<class _UnaryOperation> |
| 50 | param_type(initializer_list<result_type> __bl, _UnaryOperation __fw); | |
| 50 | _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw); | |
| 51 | 51 | #endif // _LIBCPP_CXX03_LANG |
| 52 | 52 | template<class _UnaryOperation> |
| 53 | param_type(size_t __nw, result_type __xmin, result_type __xmax, | |
| 53 | _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax, | |
| 54 | 54 | _UnaryOperation __fw); |
| 55 | param_type(param_type const&) = default; | |
| 56 | param_type & operator=(const param_type& __rhs); | |
| 55 | _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default; | |
| 56 | _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs); | |
| 57 | 57 | |
| 58 | 58 | _LIBCPP_INLINE_VISIBILITY |
| 59 | 59 | vector<result_type> intervals() const {return __b_;} |
| ... | ... | @@ -68,7 +68,7 @@ public: |
| 68 | 68 | {return !(__x == __y);} |
| 69 | 69 | |
| 70 | 70 | private: |
| 71 | void __init(); | |
| 71 | _LIBCPP_HIDE_FROM_ABI void __init(); | |
| 72 | 72 | |
| 73 | 73 | friend class piecewise_constant_distribution; |
| 74 | 74 | |
| ... | ... | @@ -125,7 +125,8 @@ public: |
| 125 | 125 | _LIBCPP_INLINE_VISIBILITY |
| 126 | 126 | result_type operator()(_URNG& __g) |
| 127 | 127 | {return (*this)(__g, __p_);} |
| 128 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 128 | template<class _URNG> | |
| 129 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 129 | 130 | |
| 130 | 131 | // property functions |
| 131 | 132 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/piecewise_linear_distribution.h+13-12| ... | ... | @@ -41,19 +41,19 @@ public: |
| 41 | 41 | public: |
| 42 | 42 | typedef piecewise_linear_distribution distribution_type; |
| 43 | 43 | |
| 44 | param_type(); | |
| 44 | _LIBCPP_HIDE_FROM_ABI param_type(); | |
| 45 | 45 | template<class _InputIteratorB, class _InputIteratorW> |
| 46 | param_type(_InputIteratorB __f_b, _InputIteratorB __l_b, | |
| 46 | _LIBCPP_HIDE_FROM_ABI param_type(_InputIteratorB __f_b, _InputIteratorB __l_b, | |
| 47 | 47 | _InputIteratorW __f_w); |
| 48 | 48 | #ifndef _LIBCPP_CXX03_LANG |
| 49 | 49 | template<class _UnaryOperation> |
| 50 | param_type(initializer_list<result_type> __bl, _UnaryOperation __fw); | |
| 50 | _LIBCPP_HIDE_FROM_ABI param_type(initializer_list<result_type> __bl, _UnaryOperation __fw); | |
| 51 | 51 | #endif // _LIBCPP_CXX03_LANG |
| 52 | 52 | template<class _UnaryOperation> |
| 53 | param_type(size_t __nw, result_type __xmin, result_type __xmax, | |
| 53 | _LIBCPP_HIDE_FROM_ABI param_type(size_t __nw, result_type __xmin, result_type __xmax, | |
| 54 | 54 | _UnaryOperation __fw); |
| 55 | param_type(param_type const&) = default; | |
| 56 | param_type & operator=(const param_type& __rhs); | |
| 55 | _LIBCPP_HIDE_FROM_ABI param_type(param_type const&) = default; | |
| 56 | _LIBCPP_HIDE_FROM_ABI param_type & operator=(const param_type& __rhs); | |
| 57 | 57 | |
| 58 | 58 | _LIBCPP_INLINE_VISIBILITY |
| 59 | 59 | vector<result_type> intervals() const {return __b_;} |
| ... | ... | @@ -68,7 +68,7 @@ public: |
| 68 | 68 | {return !(__x == __y);} |
| 69 | 69 | |
| 70 | 70 | private: |
| 71 | void __init(); | |
| 71 | _LIBCPP_HIDE_FROM_ABI void __init(); | |
| 72 | 72 | |
| 73 | 73 | friend class piecewise_linear_distribution; |
| 74 | 74 | |
| ... | ... | @@ -125,7 +125,8 @@ public: |
| 125 | 125 | _LIBCPP_INLINE_VISIBILITY |
| 126 | 126 | result_type operator()(_URNG& __g) |
| 127 | 127 | {return (*this)(__g, __p_);} |
| 128 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 128 | template<class _URNG> | |
| 129 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 129 | 130 | |
| 130 | 131 | // property functions |
| 131 | 132 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -188,23 +189,23 @@ void |
| 188 | 189 | piecewise_linear_distribution<_RealType>::param_type::__init() |
| 189 | 190 | { |
| 190 | 191 | __areas_.assign(__densities_.size() - 1, result_type()); |
| 191 | result_type _Sp = 0; | |
| 192 | result_type __sp = 0; | |
| 192 | 193 | for (size_t __i = 0; __i < __areas_.size(); ++__i) |
| 193 | 194 | { |
| 194 | 195 | __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) * |
| 195 | 196 | (__b_[__i+1] - __b_[__i]) * .5; |
| 196 | _Sp += __areas_[__i]; | |
| 197 | __sp += __areas_[__i]; | |
| 197 | 198 | } |
| 198 | 199 | for (size_t __i = __areas_.size(); __i > 1;) |
| 199 | 200 | { |
| 200 | 201 | --__i; |
| 201 | __areas_[__i] = __areas_[__i-1] / _Sp; | |
| 202 | __areas_[__i] = __areas_[__i-1] / __sp; | |
| 202 | 203 | } |
| 203 | 204 | __areas_[0] = 0; |
| 204 | 205 | for (size_t __i = 1; __i < __areas_.size(); ++__i) |
| 205 | 206 | __areas_[__i] += __areas_[__i-1]; |
| 206 | 207 | for (size_t __i = 0; __i < __densities_.size(); ++__i) |
| 207 | __densities_[__i] /= _Sp; | |
| 208 | __densities_[__i] /= __sp; | |
| 208 | 209 | } |
| 209 | 210 | |
| 210 | 211 | template<class _RealType> |
lib/libcxx/include/__random/poisson_distribution.h+9-8| ... | ... | @@ -52,7 +52,7 @@ public: |
| 52 | 52 | public: |
| 53 | 53 | typedef poisson_distribution distribution_type; |
| 54 | 54 | |
| 55 | explicit param_type(double __mean = 1.0); | |
| 55 | _LIBCPP_HIDE_FROM_ABI explicit param_type(double __mean = 1.0); | |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_INLINE_VISIBILITY |
| 58 | 58 | double mean() const {return __mean_;} |
| ... | ... | @@ -93,7 +93,8 @@ public: |
| 93 | 93 | _LIBCPP_INLINE_VISIBILITY |
| 94 | 94 | result_type operator()(_URNG& __g) |
| 95 | 95 | {return (*this)(__g, __p_);} |
| 96 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 96 | template<class _URNG> | |
| 97 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 97 | 98 | |
| 98 | 99 | // property functions |
| 99 | 100 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -144,12 +145,12 @@ poisson_distribution<_IntType>::param_type::param_type(double __mean) |
| 144 | 145 | __d_ = 6 * __mean_ * __mean_; |
| 145 | 146 | __l_ = _VSTD::trunc(__mean_ - 1.1484); |
| 146 | 147 | __omega_ = .3989423 / __s_; |
| 147 | double __b1_ = .4166667E-1 / __mean_; | |
| 148 | double __b2_ = .3 * __b1_ * __b1_; | |
| 149 | __c3_ = .1428571 * __b1_ * __b2_; | |
| 150 | __c2_ = __b2_ - 15. * __c3_; | |
| 151 | __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_; | |
| 152 | __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_; | |
| 148 | double __b1 = .4166667E-1 / __mean_; | |
| 149 | double __b2 = .3 * __b1 * __b1; | |
| 150 | __c3_ = .1428571 * __b1 * __b2; | |
| 151 | __c2_ = __b2 - 15. * __c3_; | |
| 152 | __c1_ = __b1 - 6. * __b2 + 45. * __c3_; | |
| 153 | __c0_ = 1. - __b1 + 3. * __b2 - 15. * __c3_; | |
| 153 | 154 | __c_ = .1069 / __mean_; |
| 154 | 155 | } |
| 155 | 156 | } |
lib/libcxx/include/__random/random_device.h+2-2| ... | ... | @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | 24 | #if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE) |
| 25 | 25 | |
| 26 | class _LIBCPP_TYPE_VIS random_device | |
| 26 | class _LIBCPP_EXPORTED_FROM_ABI random_device | |
| 27 | 27 | { |
| 28 | 28 | #ifdef _LIBCPP_USING_DEV_RANDOM |
| 29 | 29 | int __f_; |
| ... | ... | @@ -58,7 +58,7 @@ public: |
| 58 | 58 | |
| 59 | 59 | // constructors |
| 60 | 60 | #ifndef _LIBCPP_CXX03_LANG |
| 61 | random_device() : random_device("/dev/urandom") {} | |
| 61 | _LIBCPP_HIDE_FROM_ABI random_device() : random_device("/dev/urandom") {} | |
| 62 | 62 | explicit random_device(const string& __token); |
| 63 | 63 | #else |
| 64 | 64 | explicit random_device(const string& __token = "/dev/urandom"); |
lib/libcxx/include/__random/seed_seq.h+4-2| ... | ... | @@ -13,6 +13,8 @@ |
| 13 | 13 | #include <__algorithm/fill.h> |
| 14 | 14 | #include <__algorithm/max.h> |
| 15 | 15 | #include <__config> |
| 16 | #include <__iterator/iterator_traits.h> | |
| 17 | #include <cstdint> | |
| 16 | 18 | #include <initializer_list> |
| 17 | 19 | #include <vector> |
| 18 | 20 | |
| ... | ... | @@ -52,7 +54,7 @@ public: |
| 52 | 54 | |
| 53 | 55 | // generating functions |
| 54 | 56 | template<class _RandomAccessIterator> |
| 55 | void generate(_RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 57 | _LIBCPP_HIDE_FROM_ABI void generate(_RandomAccessIterator __first, _RandomAccessIterator __last); | |
| 56 | 58 | |
| 57 | 59 | // property functions |
| 58 | 60 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -70,7 +72,7 @@ public: |
| 70 | 72 | |
| 71 | 73 | private: |
| 72 | 74 | template<class _InputIterator> |
| 73 | void __init(_InputIterator __first, _InputIterator __last); | |
| 75 | _LIBCPP_HIDE_FROM_ABI void __init(_InputIterator __first, _InputIterator __last); | |
| 74 | 76 | |
| 75 | 77 | vector<result_type> __v_; |
| 76 | 78 | }; |
lib/libcxx/include/__random/shuffle_order_engine.h+10-7| ... | ... | @@ -12,10 +12,13 @@ |
| 12 | 12 | #include <__algorithm/equal.h> |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__random/is_seed_sequence.h> |
| 15 | #include <__type_traits/enable_if.h> | |
| 16 | #include <__type_traits/integral_constant.h> | |
| 17 | #include <__type_traits/is_convertible.h> | |
| 15 | 18 | #include <__utility/move.h> |
| 19 | #include <cstddef> | |
| 16 | 20 | #include <cstdint> |
| 17 | 21 | #include <iosfwd> |
| 18 | #include <type_traits> | |
| 19 | 22 | |
| 20 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 21 | 24 | # pragma GCC system_header |
| ... | ... | @@ -201,10 +204,10 @@ private: |
| 201 | 204 | _LIBCPP_INLINE_VISIBILITY |
| 202 | 205 | result_type __evalf() |
| 203 | 206 | { |
| 204 | const double _Fp = __d == 0 ? | |
| 207 | const double __fp = __d == 0 ? | |
| 205 | 208 | __n / (2. * 0x8000000000000000ull) : |
| 206 | 209 | __n / (double)__d; |
| 207 | const size_t __j = static_cast<size_t>(_Fp * (__y_ - _Min)); | |
| 210 | const size_t __j = static_cast<size_t>(__fp * (__y_ - _Min)); | |
| 208 | 211 | __y_ = __v_[__j]; |
| 209 | 212 | __v_[__j] = __e_(); |
| 210 | 213 | return __y_; |
| ... | ... | @@ -262,16 +265,16 @@ operator>>(basic_istream<_CharT, _Traits>& __is, |
| 262 | 265 | typedef basic_istream<_CharT, _Traits> _Istream; |
| 263 | 266 | __is.flags(_Istream::dec | _Istream::skipws); |
| 264 | 267 | _Eng __e; |
| 265 | result_type _Vp[_Kp+1]; | |
| 268 | result_type __vp[_Kp+1]; | |
| 266 | 269 | __is >> __e; |
| 267 | 270 | for (size_t __i = 0; __i < _Kp+1; ++__i) |
| 268 | __is >> _Vp[__i]; | |
| 271 | __is >> __vp[__i]; | |
| 269 | 272 | if (!__is.fail()) |
| 270 | 273 | { |
| 271 | 274 | __x.__e_ = __e; |
| 272 | 275 | for (size_t __i = 0; __i < _Kp; ++__i) |
| 273 | __x.__v_[__i] = _Vp[__i]; | |
| 274 | __x.__y_ = _Vp[_Kp]; | |
| 276 | __x.__v_[__i] = __vp[__i]; | |
| 277 | __x.__y_ = __vp[_Kp]; | |
| 275 | 278 | } |
| 276 | 279 | return __is; |
| 277 | 280 | } |
lib/libcxx/include/__random/student_t_distribution.h+2-1| ... | ... | @@ -81,7 +81,8 @@ public: |
| 81 | 81 | _LIBCPP_INLINE_VISIBILITY |
| 82 | 82 | result_type operator()(_URNG& __g) |
| 83 | 83 | {return (*this)(__g, __p_);} |
| 84 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 84 | template<class _URNG> | |
| 85 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 85 | 86 | |
| 86 | 87 | // property functions |
| 87 | 88 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__random/subtract_with_carry_engine.h+5-6| ... | ... | @@ -18,7 +18,6 @@ |
| 18 | 18 | #include <cstdint> |
| 19 | 19 | #include <iosfwd> |
| 20 | 20 | #include <limits> |
| 21 | #include <type_traits> | |
| 22 | 21 | |
| 23 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 23 | # pragma GCC system_header |
| ... | ... | @@ -121,7 +120,7 @@ public: |
| 121 | 120 | {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());} |
| 122 | 121 | |
| 123 | 122 | // generating functions |
| 124 | result_type operator()(); | |
| 123 | _LIBCPP_HIDE_FROM_ABI result_type operator()(); | |
| 125 | 124 | _LIBCPP_INLINE_VISIBILITY |
| 126 | 125 | void discard(unsigned long long __z) {for (; __z; --__z) operator()();} |
| 127 | 126 | |
| ... | ... | @@ -155,12 +154,12 @@ public: |
| 155 | 154 | |
| 156 | 155 | private: |
| 157 | 156 | |
| 158 | void seed(result_type __sd, integral_constant<unsigned, 1>); | |
| 159 | void seed(result_type __sd, integral_constant<unsigned, 2>); | |
| 157 | _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 1>); | |
| 158 | _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd, integral_constant<unsigned, 2>); | |
| 160 | 159 | template<class _Sseq> |
| 161 | void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 160 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 1>); | |
| 162 | 161 | template<class _Sseq> |
| 163 | void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 162 | _LIBCPP_HIDE_FROM_ABI void __seed(_Sseq& __q, integral_constant<unsigned, 2>); | |
| 164 | 163 | }; |
| 165 | 164 | |
| 166 | 165 | template<class _UIntType, size_t __w, size_t __s, size_t __r> |
lib/libcxx/include/__random/uniform_int_distribution.h+43-40| ... | ... | @@ -9,15 +9,16 @@ |
| 9 | 9 | #ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H |
| 10 | 10 | #define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H |
| 11 | 11 | |
| 12 | #include <__bit/countl.h> | |
| 12 | 13 | #include <__config> |
| 13 | 14 | #include <__random/is_valid.h> |
| 14 | 15 | #include <__random/log2.h> |
| 15 | #include <bit> | |
| 16 | #include <__type_traits/conditional.h> | |
| 17 | #include <__type_traits/make_unsigned.h> | |
| 16 | 18 | #include <cstddef> |
| 17 | 19 | #include <cstdint> |
| 18 | 20 | #include <iosfwd> |
| 19 | 21 | #include <limits> |
| 20 | #include <type_traits> | |
| 21 | 22 | |
| 22 | 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 23 | 24 | # pragma GCC system_header |
| ... | ... | @@ -63,14 +64,14 @@ private: |
| 63 | 64 | |
| 64 | 65 | public: |
| 65 | 66 | // constructors and seeding functions |
| 66 | __independent_bits_engine(_Engine& __e, size_t __w); | |
| 67 | _LIBCPP_HIDE_FROM_ABI __independent_bits_engine(_Engine& __e, size_t __w); | |
| 67 | 68 | |
| 68 | 69 | // generating functions |
| 69 | result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());} | |
| 70 | _LIBCPP_HIDE_FROM_ABI result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());} | |
| 70 | 71 | |
| 71 | 72 | private: |
| 72 | result_type __eval(false_type); | |
| 73 | result_type __eval(true_type); | |
| 73 | _LIBCPP_HIDE_FROM_ABI result_type __eval(false_type); | |
| 74 | _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type); | |
| 74 | 75 | }; |
| 75 | 76 | |
| 76 | 77 | template<class _Engine, class _UIntType> |
| ... | ... | @@ -120,8 +121,8 @@ template<class _Engine, class _UIntType> |
| 120 | 121 | _UIntType |
| 121 | 122 | __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) |
| 122 | 123 | { |
| 123 | const size_t _WRt = numeric_limits<result_type>::digits; | |
| 124 | result_type _Sp = 0; | |
| 124 | const size_t __w_rt = numeric_limits<result_type>::digits; | |
| 125 | result_type __sp = 0; | |
| 125 | 126 | for (size_t __k = 0; __k < __n0_; ++__k) |
| 126 | 127 | { |
| 127 | 128 | _Engine_result_type __u; |
| ... | ... | @@ -129,11 +130,11 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) |
| 129 | 130 | { |
| 130 | 131 | __u = __e_() - _Engine::min(); |
| 131 | 132 | } while (__u >= __y0_); |
| 132 | if (__w0_ < _WRt) | |
| 133 | _Sp <<= __w0_; | |
| 133 | if (__w0_ < __w_rt) | |
| 134 | __sp <<= __w0_; | |
| 134 | 135 | else |
| 135 | _Sp = 0; | |
| 136 | _Sp += __u & __mask0_; | |
| 136 | __sp = 0; | |
| 137 | __sp += __u & __mask0_; | |
| 137 | 138 | } |
| 138 | 139 | for (size_t __k = __n0_; __k < __n_; ++__k) |
| 139 | 140 | { |
| ... | ... | @@ -142,13 +143,13 @@ __independent_bits_engine<_Engine, _UIntType>::__eval(true_type) |
| 142 | 143 | { |
| 143 | 144 | __u = __e_() - _Engine::min(); |
| 144 | 145 | } while (__u >= __y1_); |
| 145 | if (__w0_ < _WRt - 1) | |
| 146 | _Sp <<= __w0_ + 1; | |
| 146 | if (__w0_ < __w_rt - 1) | |
| 147 | __sp <<= __w0_ + 1; | |
| 147 | 148 | else |
| 148 | _Sp = 0; | |
| 149 | _Sp += __u & __mask1_; | |
| 149 | __sp = 0; | |
| 150 | __sp += __u & __mask1_; | |
| 150 | 151 | } |
| 151 | return _Sp; | |
| 152 | return __sp; | |
| 152 | 153 | } |
| 153 | 154 | |
| 154 | 155 | template<class _IntType = int> |
| ... | ... | @@ -166,12 +167,12 @@ public: |
| 166 | 167 | public: |
| 167 | 168 | typedef uniform_int_distribution distribution_type; |
| 168 | 169 | |
| 169 | explicit param_type(result_type __a = 0, | |
| 170 | _LIBCPP_HIDE_FROM_ABI explicit param_type(result_type __a = 0, | |
| 170 | 171 | result_type __b = numeric_limits<result_type>::max()) |
| 171 | 172 | : __a_(__a), __b_(__b) {} |
| 172 | 173 | |
| 173 | result_type a() const {return __a_;} | |
| 174 | result_type b() const {return __b_;} | |
| 174 | _LIBCPP_HIDE_FROM_ABI result_type a() const {return __a_;} | |
| 175 | _LIBCPP_HIDE_FROM_ABI result_type b() const {return __b_;} | |
| 175 | 176 | |
| 176 | 177 | _LIBCPP_HIDE_FROM_ABI |
| 177 | 178 | friend bool operator==(const param_type& __x, const param_type& __y) |
| ... | ... | @@ -187,8 +188,8 @@ private: |
| 187 | 188 | public: |
| 188 | 189 | // constructors and reset functions |
| 189 | 190 | #ifndef _LIBCPP_CXX03_LANG |
| 190 | uniform_int_distribution() : uniform_int_distribution(0) {} | |
| 191 | explicit uniform_int_distribution( | |
| 191 | _LIBCPP_HIDE_FROM_ABI uniform_int_distribution() : uniform_int_distribution(0) {} | |
| 192 | _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution( | |
| 192 | 193 | result_type __a, result_type __b = numeric_limits<result_type>::max()) |
| 193 | 194 | : __p_(param_type(__a, __b)) {} |
| 194 | 195 | #else |
| ... | ... | @@ -197,23 +198,25 @@ public: |
| 197 | 198 | result_type __b = numeric_limits<result_type>::max()) |
| 198 | 199 | : __p_(param_type(__a, __b)) {} |
| 199 | 200 | #endif |
| 200 | explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} | |
| 201 | void reset() {} | |
| 201 | _LIBCPP_HIDE_FROM_ABI explicit uniform_int_distribution(const param_type& __p) : __p_(__p) {} | |
| 202 | _LIBCPP_HIDE_FROM_ABI void reset() {} | |
| 202 | 203 | |
| 203 | 204 | // generating functions |
| 204 | template<class _URNG> result_type operator()(_URNG& __g) | |
| 205 | template<class _URNG> | |
| 206 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g) | |
| 205 | 207 | {return (*this)(__g, __p_);} |
| 206 | template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p); | |
| 208 | template<class _URNG> | |
| 209 | _LIBCPP_HIDE_FROM_ABI result_type operator()(_URNG& __g, const param_type& __p); | |
| 207 | 210 | |
| 208 | 211 | // property functions |
| 209 | result_type a() const {return __p_.a();} | |
| 210 | result_type b() const {return __p_.b();} | |
| 212 | _LIBCPP_HIDE_FROM_ABI result_type a() const {return __p_.a();} | |
| 213 | _LIBCPP_HIDE_FROM_ABI result_type b() const {return __p_.b();} | |
| 211 | 214 | |
| 212 | param_type param() const {return __p_;} | |
| 213 | void param(const param_type& __p) {__p_ = __p;} | |
| 215 | _LIBCPP_HIDE_FROM_ABI param_type param() const {return __p_;} | |
| 216 | _LIBCPP_HIDE_FROM_ABI void param(const param_type& __p) {__p_ = __p;} | |
| 214 | 217 | |
| 215 | result_type min() const {return a();} | |
| 216 | result_type max() const {return b();} | |
| 218 | _LIBCPP_HIDE_FROM_ABI result_type min() const {return a();} | |
| 219 | _LIBCPP_HIDE_FROM_ABI result_type max() const {return b();} | |
| 217 | 220 | |
| 218 | 221 | _LIBCPP_HIDE_FROM_ABI |
| 219 | 222 | friend bool operator==(const uniform_int_distribution& __x, |
| ... | ... | @@ -234,22 +237,22 @@ _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK |
| 234 | 237 | static_assert(__libcpp_random_is_valid_urng<_URNG>::value, ""); |
| 235 | 238 | typedef __conditional_t<sizeof(result_type) <= sizeof(uint32_t), uint32_t, __make_unsigned_t<result_type> > |
| 236 | 239 | _UIntType; |
| 237 | const _UIntType _Rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); | |
| 238 | if (_Rp == 1) | |
| 240 | const _UIntType __rp = _UIntType(__p.b()) - _UIntType(__p.a()) + _UIntType(1); | |
| 241 | if (__rp == 1) | |
| 239 | 242 | return __p.a(); |
| 240 | const size_t _Dt = numeric_limits<_UIntType>::digits; | |
| 243 | const size_t __dt = numeric_limits<_UIntType>::digits; | |
| 241 | 244 | typedef __independent_bits_engine<_URNG, _UIntType> _Eng; |
| 242 | if (_Rp == 0) | |
| 243 | return static_cast<result_type>(_Eng(__g, _Dt)()); | |
| 244 | size_t __w = _Dt - std::__countl_zero(_Rp) - 1; | |
| 245 | if ((_Rp & (numeric_limits<_UIntType>::max() >> (_Dt - __w))) != 0) | |
| 245 | if (__rp == 0) | |
| 246 | return static_cast<result_type>(_Eng(__g, __dt)()); | |
| 247 | size_t __w = __dt - std::__countl_zero(__rp) - 1; | |
| 248 | if ((__rp & (numeric_limits<_UIntType>::max() >> (__dt - __w))) != 0) | |
| 246 | 249 | ++__w; |
| 247 | 250 | _Eng __e(__g, __w); |
| 248 | 251 | _UIntType __u; |
| 249 | 252 | do |
| 250 | 253 | { |
| 251 | 254 | __u = __e(); |
| 252 | } while (__u >= _Rp); | |
| 255 | } while (__u >= __rp); | |
| 253 | 256 | return static_cast<result_type>(__u + __p.a()); |
| 254 | 257 | } |
| 255 | 258 |
lib/libcxx/include/__random/uniform_random_bit_generator.h+4-3| ... | ... | @@ -13,7 +13,8 @@ |
| 13 | 13 | #include <__concepts/invocable.h> |
| 14 | 14 | #include <__concepts/same_as.h> |
| 15 | 15 | #include <__config> |
| 16 | #include <type_traits> | |
| 16 | #include <__functional/invoke.h> | |
| 17 | #include <__type_traits/integral_constant.h> | |
| 17 | 18 | |
| 18 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 20 | # pragma GCC system_header |
| ... | ... | @@ -24,7 +25,7 @@ _LIBCPP_PUSH_MACROS |
| 24 | 25 | |
| 25 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 27 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 29 | |
| 29 | 30 | // [rand.req.urng] |
| 30 | 31 | template<class _Gen> |
| ... | ... | @@ -36,7 +37,7 @@ concept uniform_random_bit_generator = |
| 36 | 37 | requires bool_constant<(_Gen::min() < _Gen::max())>::value; |
| 37 | 38 | }; |
| 38 | 39 | |
| 39 | #endif // _LIBCPP_STD_VER > 17 | |
| 40 | #endif // _LIBCPP_STD_VER >= 20 | |
| 40 | 41 | |
| 41 | 42 | _LIBCPP_END_NAMESPACE_STD |
| 42 | 43 |
lib/libcxx/include/__random/uniform_real_distribution.h+1-2| ... | ... | @@ -14,7 +14,6 @@ |
| 14 | 14 | #include <__random/is_valid.h> |
| 15 | 15 | #include <iosfwd> |
| 16 | 16 | #include <limits> |
| 17 | #include <type_traits> | |
| 18 | 17 | |
| 19 | 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 19 | # pragma GCC system_header |
| ... | ... | @@ -65,7 +64,7 @@ public: |
| 65 | 64 | #ifndef _LIBCPP_CXX03_LANG |
| 66 | 65 | _LIBCPP_INLINE_VISIBILITY |
| 67 | 66 | uniform_real_distribution() : uniform_real_distribution(0) {} |
| 68 | explicit uniform_real_distribution(result_type __a, result_type __b = 1) | |
| 67 | _LIBCPP_HIDE_FROM_ABI explicit uniform_real_distribution(result_type __a, result_type __b = 1) | |
| 69 | 68 | : __p_(param_type(__a, __b)) {} |
| 70 | 69 | #else |
| 71 | 70 | _LIBCPP_INLINE_VISIBILITY |
lib/libcxx/include/__ranges/access.h+2-2| ... | ... | @@ -29,7 +29,7 @@ |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 31 | |
| 32 | #if _LIBCPP_STD_VER > 17 | |
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | 33 | |
| 34 | 34 | namespace ranges { |
| 35 | 35 | template <class _Tp> |
| ... | ... | @@ -223,7 +223,7 @@ inline namespace __cpo { |
| 223 | 223 | } // namespace __cpo |
| 224 | 224 | } // namespace ranges |
| 225 | 225 | |
| 226 | #endif // _LIBCPP_STD_VER > 17 | |
| 226 | #endif // _LIBCPP_STD_VER >= 20 | |
| 227 | 227 | |
| 228 | 228 | _LIBCPP_END_NAMESPACE_STD |
| 229 | 229 |
lib/libcxx/include/__ranges/all.h+5-3| ... | ... | @@ -11,6 +11,8 @@ |
| 11 | 11 | #define _LIBCPP___RANGES_ALL_H |
| 12 | 12 | |
| 13 | 13 | #include <__config> |
| 14 | #include <__functional/compose.h> // TODO(modules): Those should not be required | |
| 15 | #include <__functional/perfect_forward.h> // | |
| 14 | 16 | #include <__iterator/concepts.h> |
| 15 | 17 | #include <__iterator/iterator_traits.h> |
| 16 | 18 | #include <__ranges/access.h> |
| ... | ... | @@ -18,10 +20,10 @@ |
| 18 | 20 | #include <__ranges/owning_view.h> |
| 19 | 21 | #include <__ranges/range_adaptor.h> |
| 20 | 22 | #include <__ranges/ref_view.h> |
| 23 | #include <__type_traits/decay.h> | |
| 21 | 24 | #include <__utility/auto_cast.h> |
| 22 | 25 | #include <__utility/declval.h> |
| 23 | 26 | #include <__utility/forward.h> |
| 24 | #include <type_traits> | |
| 25 | 27 | |
| 26 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 29 | # pragma GCC system_header |
| ... | ... | @@ -29,7 +31,7 @@ |
| 29 | 31 | |
| 30 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 33 | |
| 32 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | 35 | |
| 34 | 36 | namespace ranges::views { |
| 35 | 37 | |
| ... | ... | @@ -77,7 +79,7 @@ using all_t = decltype(views::all(std::declval<_Range>())); |
| 77 | 79 | |
| 78 | 80 | } // namespace ranges::views |
| 79 | 81 | |
| 80 | #endif // _LIBCPP_STD_VER > 17 | |
| 82 | #endif // _LIBCPP_STD_VER >= 20 | |
| 81 | 83 | |
| 82 | 84 | _LIBCPP_END_NAMESPACE_STD |
| 83 | 85 |
lib/libcxx/include/__ranges/as_rvalue_view.h+6-1| ... | ... | @@ -28,6 +28,9 @@ |
| 28 | 28 | # pragma GCC system_header |
| 29 | 29 | #endif |
| 30 | 30 | |
| 31 | _LIBCPP_PUSH_MACROS | |
| 32 | #include <__undef_macros> | |
| 33 | ||
| 31 | 34 | #if _LIBCPP_STD_VER >= 23 |
| 32 | 35 | |
| 33 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| ... | ... | @@ -125,7 +128,7 @@ struct __fn : __range_adaptor_closure<__fn> { |
| 125 | 128 | } // namespace __as_rvalue |
| 126 | 129 | |
| 127 | 130 | inline namespace __cpo { |
| 128 | constexpr auto as_rvalue = __as_rvalue::__fn{}; | |
| 131 | inline constexpr auto as_rvalue = __as_rvalue::__fn{}; | |
| 129 | 132 | } // namespace __cpo |
| 130 | 133 | } // namespace views |
| 131 | 134 | } // namespace ranges |
| ... | ... | @@ -134,4 +137,6 @@ _LIBCPP_END_NAMESPACE_STD |
| 134 | 137 | |
| 135 | 138 | #endif // _LIBCPP_STD_VER >= 23 |
| 136 | 139 | |
| 140 | _LIBCPP_POP_MACROS | |
| 141 | ||
| 137 | 142 | #endif // _LIBCPP___RANGES_AS_RVALUE_H |
lib/libcxx/include/__ranges/common_view.h+7-3| ... | ... | @@ -24,15 +24,17 @@ |
| 24 | 24 | #include <__ranges/view_interface.h> |
| 25 | 25 | #include <__utility/forward.h> |
| 26 | 26 | #include <__utility/move.h> |
| 27 | #include <type_traits> | |
| 28 | 27 | |
| 29 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 30 | 29 | # pragma GCC system_header |
| 31 | 30 | #endif |
| 32 | 31 | |
| 32 | _LIBCPP_PUSH_MACROS | |
| 33 | #include <__undef_macros> | |
| 34 | ||
| 33 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 34 | 36 | |
| 35 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 36 | 38 | |
| 37 | 39 | namespace ranges { |
| 38 | 40 | |
| ... | ... | @@ -130,8 +132,10 @@ inline namespace __cpo { |
| 130 | 132 | } // namespace views |
| 131 | 133 | } // namespace ranges |
| 132 | 134 | |
| 133 | #endif // _LIBCPP_STD_VER > 17 | |
| 135 | #endif // _LIBCPP_STD_VER >= 20 | |
| 134 | 136 | |
| 135 | 137 | _LIBCPP_END_NAMESPACE_STD |
| 136 | 138 | |
| 139 | _LIBCPP_POP_MACROS | |
| 140 | ||
| 137 | 141 | #endif // _LIBCPP___RANGES_COMMON_VIEW_H |
lib/libcxx/include/__ranges/concepts.h+5-2| ... | ... | @@ -37,7 +37,7 @@ |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 39 | 39 | |
| 40 | #if _LIBCPP_STD_VER > 17 | |
| 40 | #if _LIBCPP_STD_VER >= 20 | |
| 41 | 41 | |
| 42 | 42 | namespace ranges { |
| 43 | 43 | |
| ... | ... | @@ -73,6 +73,9 @@ namespace ranges { |
| 73 | 73 | template <range _Rp> |
| 74 | 74 | using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>; |
| 75 | 75 | |
| 76 | template <range _Rp> | |
| 77 | using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>; | |
| 78 | ||
| 76 | 79 | // [range.sized] |
| 77 | 80 | template <class _Tp> |
| 78 | 81 | concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; |
| ... | ... | @@ -140,7 +143,7 @@ namespace ranges { |
| 140 | 143 | |
| 141 | 144 | } // namespace ranges |
| 142 | 145 | |
| 143 | #endif // _LIBCPP_STD_VER > 17 | |
| 146 | #endif // _LIBCPP_STD_VER >= 20 | |
| 144 | 147 | |
| 145 | 148 | _LIBCPP_END_NAMESPACE_STD |
| 146 | 149 |
lib/libcxx/include/__ranges/container_compatible_range.h created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H | |
| 11 | #define _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H | |
| 12 | ||
| 13 | #include <__concepts/convertible_to.h> | |
| 14 | #include <__config> | |
| 15 | #include <__ranges/concepts.h> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | #if _LIBCPP_STD_VER >= 23 | |
| 24 | ||
| 25 | template <class _Range, class _Tp> | |
| 26 | concept _ContainerCompatibleRange = | |
| 27 | ranges::input_range<_Range> && convertible_to<ranges::range_reference_t<_Range>, _Tp>; | |
| 28 | ||
| 29 | #endif // _LIBCPP_STD_VER >= 23 | |
| 30 | ||
| 31 | _LIBCPP_END_NAMESPACE_STD | |
| 32 | ||
| 33 | #endif // _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H |
lib/libcxx/include/__ranges/copyable_box.h deleted-180| ... | ... | @@ -1,180 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_COPYABLE_BOX_H | |
| 11 | #define _LIBCPP___RANGES_COPYABLE_BOX_H | |
| 12 | ||
| 13 | #include <__concepts/constructible.h> | |
| 14 | #include <__concepts/copyable.h> | |
| 15 | #include <__concepts/movable.h> | |
| 16 | #include <__config> | |
| 17 | #include <__memory/addressof.h> | |
| 18 | #include <__memory/construct_at.h> | |
| 19 | #include <__utility/move.h> | |
| 20 | #include <optional> | |
| 21 | #include <type_traits> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 30 | ||
| 31 | // __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into | |
| 32 | // a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state | |
| 33 | // and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary | |
| 34 | // to handle the case where the copy construction fails after destroying the object. | |
| 35 | // | |
| 36 | // In some cases, we can completely avoid the use of an empty state; we provide a specialization of | |
| 37 | // __copyable_box that does this, see below for the details. | |
| 38 | ||
| 39 | template<class _Tp> | |
| 40 | concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>; | |
| 41 | ||
| 42 | namespace ranges { | |
| 43 | // Primary template - uses std::optional and introduces an empty state in case assignment fails. | |
| 44 | template<__copy_constructible_object _Tp> | |
| 45 | class __copyable_box { | |
| 46 | _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_; | |
| 47 | ||
| 48 | public: | |
| 49 | template<class ..._Args> | |
| 50 | requires is_constructible_v<_Tp, _Args...> | |
| 51 | _LIBCPP_HIDE_FROM_ABI | |
| 52 | constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) | |
| 53 | noexcept(is_nothrow_constructible_v<_Tp, _Args...>) | |
| 54 | : __val_(in_place, std::forward<_Args>(__args)...) | |
| 55 | { } | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI | |
| 58 | constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) | |
| 59 | requires default_initializable<_Tp> | |
| 60 | : __val_(in_place) | |
| 61 | { } | |
| 62 | ||
| 63 | _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; | |
| 64 | _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; | |
| 65 | ||
| 66 | _LIBCPP_HIDE_FROM_ABI | |
| 67 | constexpr __copyable_box& operator=(__copyable_box const& __other) | |
| 68 | noexcept(is_nothrow_copy_constructible_v<_Tp>) | |
| 69 | { | |
| 70 | if (this != std::addressof(__other)) { | |
| 71 | if (__other.__has_value()) __val_.emplace(*__other); | |
| 72 | else __val_.reset(); | |
| 73 | } | |
| 74 | return *this; | |
| 75 | } | |
| 76 | ||
| 77 | _LIBCPP_HIDE_FROM_ABI | |
| 78 | __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; | |
| 79 | ||
| 80 | _LIBCPP_HIDE_FROM_ABI | |
| 81 | constexpr __copyable_box& operator=(__copyable_box&& __other) | |
| 82 | noexcept(is_nothrow_move_constructible_v<_Tp>) | |
| 83 | { | |
| 84 | if (this != std::addressof(__other)) { | |
| 85 | if (__other.__has_value()) __val_.emplace(std::move(*__other)); | |
| 86 | else __val_.reset(); | |
| 87 | } | |
| 88 | return *this; | |
| 89 | } | |
| 90 | ||
| 91 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; } | |
| 92 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; } | |
| 93 | ||
| 94 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return __val_.operator->(); } | |
| 95 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); } | |
| 96 | ||
| 97 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); } | |
| 98 | }; | |
| 99 | ||
| 100 | // This partial specialization implements an optimization for when we know we don't need to store | |
| 101 | // an empty state to represent failure to perform an assignment. For copy-assignment, this happens: | |
| 102 | // | |
| 103 | // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator | |
| 104 | // directly and avoid using std::optional. | |
| 105 | // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as | |
| 106 | // destroy-and-then-construct and we know it will never fail, so we don't need an empty state. | |
| 107 | // | |
| 108 | // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and | |
| 109 | // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled | |
| 110 | // whenever we can apply any of these optimizations for both the copy assignment and the move assignment | |
| 111 | // operator. | |
| 112 | template<class _Tp> | |
| 113 | concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>; | |
| 114 | ||
| 115 | template<class _Tp> | |
| 116 | concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>; | |
| 117 | ||
| 118 | template<__copy_constructible_object _Tp> | |
| 119 | requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp> | |
| 120 | class __copyable_box<_Tp> { | |
| 121 | _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; | |
| 122 | ||
| 123 | public: | |
| 124 | template<class ..._Args> | |
| 125 | requires is_constructible_v<_Tp, _Args...> | |
| 126 | _LIBCPP_HIDE_FROM_ABI | |
| 127 | constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) | |
| 128 | noexcept(is_nothrow_constructible_v<_Tp, _Args...>) | |
| 129 | : __val_(std::forward<_Args>(__args)...) | |
| 130 | { } | |
| 131 | ||
| 132 | _LIBCPP_HIDE_FROM_ABI | |
| 133 | constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) | |
| 134 | requires default_initializable<_Tp> | |
| 135 | : __val_() | |
| 136 | { } | |
| 137 | ||
| 138 | _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; | |
| 139 | _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; | |
| 140 | ||
| 141 | // Implementation of assignment operators in case we perform optimization (1) | |
| 142 | _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default; | |
| 143 | _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; | |
| 144 | ||
| 145 | // Implementation of assignment operators in case we perform optimization (2) | |
| 146 | _LIBCPP_HIDE_FROM_ABI | |
| 147 | constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept { | |
| 148 | static_assert(is_nothrow_copy_constructible_v<_Tp>); | |
| 149 | if (this != std::addressof(__other)) { | |
| 150 | std::destroy_at(std::addressof(__val_)); | |
| 151 | std::construct_at(std::addressof(__val_), __other.__val_); | |
| 152 | } | |
| 153 | return *this; | |
| 154 | } | |
| 155 | ||
| 156 | _LIBCPP_HIDE_FROM_ABI | |
| 157 | constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept { | |
| 158 | static_assert(is_nothrow_move_constructible_v<_Tp>); | |
| 159 | if (this != std::addressof(__other)) { | |
| 160 | std::destroy_at(std::addressof(__val_)); | |
| 161 | std::construct_at(std::addressof(__val_), std::move(__other.__val_)); | |
| 162 | } | |
| 163 | return *this; | |
| 164 | } | |
| 165 | ||
| 166 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; } | |
| 167 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; } | |
| 168 | ||
| 169 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp *operator->() const noexcept { return std::addressof(__val_); } | |
| 170 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); } | |
| 171 | ||
| 172 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; } | |
| 173 | }; | |
| 174 | } // namespace ranges | |
| 175 | ||
| 176 | #endif // _LIBCPP_STD_VER > 17 | |
| 177 | ||
| 178 | _LIBCPP_END_NAMESPACE_STD | |
| 179 | ||
| 180 | #endif // _LIBCPP___RANGES_COPYABLE_BOX_H |
lib/libcxx/include/__ranges/counted.h+4-3| ... | ... | @@ -19,10 +19,11 @@ |
| 19 | 19 | #include <__iterator/iterator_traits.h> |
| 20 | 20 | #include <__memory/pointer_traits.h> |
| 21 | 21 | #include <__ranges/subrange.h> |
| 22 | #include <__type_traits/decay.h> | |
| 22 | 23 | #include <__utility/forward.h> |
| 23 | 24 | #include <__utility/move.h> |
| 25 | #include <cstddef> | |
| 24 | 26 | #include <span> |
| 25 | #include <type_traits> | |
| 26 | 27 | |
| 27 | 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 28 | 29 | # pragma GCC system_header |
| ... | ... | @@ -30,7 +31,7 @@ |
| 30 | 31 | |
| 31 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 33 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 35 | |
| 35 | 36 | namespace ranges::views { |
| 36 | 37 | |
| ... | ... | @@ -75,7 +76,7 @@ inline namespace __cpo { |
| 75 | 76 | |
| 76 | 77 | } // namespace ranges::views |
| 77 | 78 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 79 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 80 | |
| 80 | 81 | _LIBCPP_END_NAMESPACE_STD |
| 81 | 82 |
lib/libcxx/include/__ranges/dangling.h+2-2| ... | ... | @@ -21,7 +21,7 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 24 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 25 | |
| 26 | 26 | namespace ranges { |
| 27 | 27 | struct dangling { |
| ... | ... | @@ -35,7 +35,7 @@ using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>; |
| 35 | 35 | // borrowed_subrange_t defined in <__ranges/subrange.h> |
| 36 | 36 | } // namespace ranges |
| 37 | 37 | |
| 38 | #endif // _LIBCPP_STD_VER > 17 | |
| 38 | #endif // _LIBCPP_STD_VER >= 20 | |
| 39 | 39 | |
| 40 | 40 | _LIBCPP_END_NAMESPACE_STD |
| 41 | 41 |
lib/libcxx/include/__ranges/data.h+2-2| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | // [range.prim.data] |
| 36 | 36 | |
| ... | ... | @@ -105,7 +105,7 @@ inline namespace __cpo { |
| 105 | 105 | } // namespace __cpo |
| 106 | 106 | } // namespace ranges |
| 107 | 107 | |
| 108 | #endif // _LIBCPP_STD_VER > 17 | |
| 108 | #endif // _LIBCPP_STD_VER >= 20 | |
| 109 | 109 | |
| 110 | 110 | _LIBCPP_END_NAMESPACE_STD |
| 111 | 111 |
lib/libcxx/include/__ranges/drop_view.h+45-10| ... | ... | @@ -30,13 +30,19 @@ |
| 30 | 30 | #include <__ranges/iota_view.h> |
| 31 | 31 | #include <__ranges/non_propagating_cache.h> |
| 32 | 32 | #include <__ranges/range_adaptor.h> |
| 33 | #include <__ranges/repeat_view.h> | |
| 33 | 34 | #include <__ranges/size.h> |
| 34 | 35 | #include <__ranges/subrange.h> |
| 35 | 36 | #include <__ranges/view_interface.h> |
| 37 | #include <__type_traits/conditional.h> | |
| 38 | #include <__type_traits/decay.h> | |
| 39 | #include <__type_traits/is_nothrow_constructible.h> | |
| 40 | #include <__type_traits/make_unsigned.h> | |
| 41 | #include <__type_traits/remove_cvref.h> | |
| 36 | 42 | #include <__utility/auto_cast.h> |
| 37 | 43 | #include <__utility/forward.h> |
| 38 | 44 | #include <__utility/move.h> |
| 39 | #include <type_traits> | |
| 45 | #include <cstddef> | |
| 40 | 46 | |
| 41 | 47 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 42 | 48 | # pragma GCC system_header |
| ... | ... | @@ -47,7 +53,7 @@ _LIBCPP_PUSH_MACROS |
| 47 | 53 | |
| 48 | 54 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 49 | 55 | |
| 50 | #if _LIBCPP_STD_VER > 17 | |
| 56 | #if _LIBCPP_STD_VER >= 20 | |
| 51 | 57 | |
| 52 | 58 | namespace ranges { |
| 53 | 59 | template<view _View> |
| ... | ... | @@ -66,14 +72,14 @@ namespace ranges { |
| 66 | 72 | _View __base_ = _View(); |
| 67 | 73 | |
| 68 | 74 | public: |
| 69 | drop_view() requires default_initializable<_View> = default; | |
| 75 | _LIBCPP_HIDE_FROM_ABI drop_view() requires default_initializable<_View> = default; | |
| 70 | 76 | |
| 71 | 77 | _LIBCPP_HIDE_FROM_ABI |
| 72 | constexpr drop_view(_View __base, range_difference_t<_View> __count) | |
| 78 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_view(_View __base, range_difference_t<_View> __count) | |
| 73 | 79 | : __count_(__count) |
| 74 | 80 | , __base_(std::move(__base)) |
| 75 | 81 | { |
| 76 | _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero."); | |
| 82 | _LIBCPP_ASSERT_UNCATEGORIZED(__count_ >= 0, "count must be greater than or equal to zero."); | |
| 77 | 83 | } |
| 78 | 84 | |
| 79 | 85 | _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; } |
| ... | ... | @@ -255,13 +261,39 @@ struct __fn { |
| 255 | 261 | { |
| 256 | 262 | // Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the |
| 257 | 263 | // expression used in the `noexcept` clause and the return statement). |
| 258 | auto dist = ranges::distance(__rng); | |
| 259 | auto clamped = std::min<_Dist>(dist, std::forward<_Np>(__n)); | |
| 264 | auto __dist = ranges::distance(__rng); | |
| 265 | auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n)); | |
| 260 | 266 | return _RawRange( |
| 261 | ranges::begin(__rng) + clamped, | |
| 267 | ranges::begin(__rng) + __clamped, | |
| 262 | 268 | ranges::end(__rng), |
| 263 | std::__to_unsigned_like(dist - clamped) | |
| 269 | std::__to_unsigned_like(__dist - __clamped) | |
| 264 | 270 | );} |
| 271 | // clang-format off | |
| 272 | #if _LIBCPP_STD_VER >= 23 | |
| 273 | // [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case. | |
| 274 | template <class _Range, | |
| 275 | convertible_to<range_difference_t<_Range>> _Np, | |
| 276 | class _RawRange = remove_cvref_t<_Range>, | |
| 277 | class _Dist = range_difference_t<_Range>> | |
| 278 | requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) | |
| 279 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const | |
| 280 | noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) | |
| 281 | -> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) | |
| 282 | { return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } | |
| 283 | ||
| 284 | // [range.drop.overview]: the `repeat_view` "otherwise" case. | |
| 285 | template <class _Range, | |
| 286 | convertible_to<range_difference_t<_Range>> _Np, | |
| 287 | class _RawRange = remove_cvref_t<_Range>, | |
| 288 | class _Dist = range_difference_t<_Range>> | |
| 289 | requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) | |
| 290 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI | |
| 291 | constexpr auto operator()(_Range&& __range, _Np&&) const | |
| 292 | noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))) | |
| 293 | -> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) | |
| 294 | { return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); } | |
| 295 | #endif | |
| 296 | // clang-format on | |
| 265 | 297 | |
| 266 | 298 | // [range.drop.overview]: the "otherwise" case. |
| 267 | 299 | template <class _Range, convertible_to<range_difference_t<_Range>> _Np, |
| ... | ... | @@ -269,6 +301,9 @@ struct __fn { |
| 269 | 301 | // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other |
| 270 | 302 | // overloads. |
| 271 | 303 | requires (!(__is_empty_view<_RawRange> || |
| 304 | #if _LIBCPP_STD_VER >= 23 | |
| 305 | __is_repeat_specialization<_RawRange> || | |
| 306 | #endif | |
| 272 | 307 | (__is_subrange_specialization_with_store_size<_RawRange> && |
| 273 | 308 | sized_range<_RawRange> && |
| 274 | 309 | random_access_range<_RawRange>) || |
| ... | ... | @@ -299,7 +334,7 @@ inline namespace __cpo { |
| 299 | 334 | |
| 300 | 335 | } // namespace ranges |
| 301 | 336 | |
| 302 | #endif // _LIBCPP_STD_VER > 17 | |
| 337 | #endif // _LIBCPP_STD_VER >= 20 | |
| 303 | 338 | |
| 304 | 339 | _LIBCPP_END_NAMESPACE_STD |
| 305 | 340 |
lib/libcxx/include/__ranges/drop_while_view.h+7-6| ... | ... | @@ -20,8 +20,8 @@ |
| 20 | 20 | #include <__ranges/access.h> |
| 21 | 21 | #include <__ranges/all.h> |
| 22 | 22 | #include <__ranges/concepts.h> |
| 23 | #include <__ranges/copyable_box.h> | |
| 24 | 23 | #include <__ranges/enable_borrowed_range.h> |
| 24 | #include <__ranges/movable_box.h> | |
| 25 | 25 | #include <__ranges/non_propagating_cache.h> |
| 26 | 26 | #include <__ranges/range_adaptor.h> |
| 27 | 27 | #include <__ranges/view_interface.h> |
| ... | ... | @@ -51,7 +51,7 @@ public: |
| 51 | 51 | requires default_initializable<_View> && default_initializable<_Pred> |
| 52 | 52 | = default; |
| 53 | 53 | |
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr drop_while_view(_View __base, _Pred __pred) | |
| 54 | _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_while_view(_View __base, _Pred __pred) | |
| 55 | 55 | : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {} |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& |
| ... | ... | @@ -65,9 +65,10 @@ public: |
| 65 | 65 | _LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; } |
| 66 | 66 | |
| 67 | 67 | _LIBCPP_HIDE_FROM_ABI constexpr auto begin() { |
| 68 | _LIBCPP_ASSERT(__pred_.__has_value(), | |
| 69 | "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous " | |
| 70 | "assignment to this drop_while_view fail?"); | |
| 68 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 69 | __pred_.__has_value(), | |
| 70 | "drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous " | |
| 71 | "assignment to this drop_while_view fail?"); | |
| 71 | 72 | if constexpr (_UseCache) { |
| 72 | 73 | if (!__cached_begin_.__has_value()) { |
| 73 | 74 | __cached_begin_.__emplace(ranges::find_if_not(__base_, std::cref(*__pred_))); |
| ... | ... | @@ -82,7 +83,7 @@ public: |
| 82 | 83 | |
| 83 | 84 | private: |
| 84 | 85 | _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); |
| 85 | _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; | |
| 86 | _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; | |
| 86 | 87 | |
| 87 | 88 | static constexpr bool _UseCache = forward_range<_View>; |
| 88 | 89 | using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; |
lib/libcxx/include/__ranges/elements_view.h+7-7| ... | ... | @@ -26,9 +26,9 @@ |
| 26 | 26 | #include <__ranges/range_adaptor.h> |
| 27 | 27 | #include <__ranges/size.h> |
| 28 | 28 | #include <__ranges/view_interface.h> |
| 29 | #include <__tuple_dir/tuple_element.h> | |
| 30 | #include <__tuple_dir/tuple_like.h> | |
| 31 | #include <__tuple_dir/tuple_size.h> | |
| 29 | #include <__tuple/tuple_element.h> | |
| 30 | #include <__tuple/tuple_like.h> | |
| 31 | #include <__tuple/tuple_size.h> | |
| 32 | 32 | #include <__type_traits/is_reference.h> |
| 33 | 33 | #include <__type_traits/maybe_const.h> |
| 34 | 34 | #include <__type_traits/remove_cv.h> |
| ... | ... | @@ -224,9 +224,9 @@ public: |
| 224 | 224 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) |
| 225 | 225 | requires forward_range<_Base> |
| 226 | 226 | { |
| 227 | auto temp = *this; | |
| 227 | auto __temp = *this; | |
| 228 | 228 | ++__current_; |
| 229 | return temp; | |
| 229 | return __temp; | |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() |
| ... | ... | @@ -239,9 +239,9 @@ public: |
| 239 | 239 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) |
| 240 | 240 | requires bidirectional_range<_Base> |
| 241 | 241 | { |
| 242 | auto temp = *this; | |
| 242 | auto __temp = *this; | |
| 243 | 243 | --__current_; |
| 244 | return temp; | |
| 244 | return __temp; | |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | 247 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) |
lib/libcxx/include/__ranges/empty.h+2-2| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | // [range.prim.empty] |
| 28 | 28 | |
| ... | ... | @@ -75,7 +75,7 @@ inline namespace __cpo { |
| 75 | 75 | } // namespace __cpo |
| 76 | 76 | } // namespace ranges |
| 77 | 77 | |
| 78 | #endif // _LIBCPP_STD_VER > 17 | |
| 78 | #endif // _LIBCPP_STD_VER >= 20 | |
| 79 | 79 | |
| 80 | 80 | _LIBCPP_END_NAMESPACE_STD |
| 81 | 81 |
lib/libcxx/include/__ranges/empty_view.h+4-3| ... | ... | @@ -13,7 +13,8 @@ |
| 13 | 13 | #include <__config> |
| 14 | 14 | #include <__ranges/enable_borrowed_range.h> |
| 15 | 15 | #include <__ranges/view_interface.h> |
| 16 | #include <type_traits> | |
| 16 | #include <__type_traits/is_object.h> | |
| 17 | #include <cstddef> | |
| 17 | 18 | |
| 18 | 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 20 | # pragma GCC system_header |
| ... | ... | @@ -21,7 +22,7 @@ |
| 21 | 22 | |
| 22 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 24 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 26 | |
| 26 | 27 | namespace ranges { |
| 27 | 28 | template<class _Tp> |
| ... | ... | @@ -46,7 +47,7 @@ namespace ranges { |
| 46 | 47 | } // namespace views |
| 47 | 48 | } // namespace ranges |
| 48 | 49 | |
| 49 | #endif // _LIBCPP_STD_VER > 17 | |
| 50 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | 51 | |
| 51 | 52 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 53 |
lib/libcxx/include/__ranges/enable_borrowed_range.h+2-2| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 25 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 26 | |
| 27 | 27 | namespace ranges { |
| 28 | 28 | |
| ... | ... | @@ -33,7 +33,7 @@ inline constexpr bool enable_borrowed_range = false; |
| 33 | 33 | |
| 34 | 34 | } // namespace ranges |
| 35 | 35 | |
| 36 | #endif // _LIBCPP_STD_VER > 17 | |
| 36 | #endif // _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_END_NAMESPACE_STD |
| 39 | 39 |
lib/libcxx/include/__ranges/enable_view.h+2-2| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | |
| 28 | 28 | namespace ranges { |
| 29 | 29 | |
| ... | ... | @@ -43,7 +43,7 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> || |
| 43 | 43 | |
| 44 | 44 | } // namespace ranges |
| 45 | 45 | |
| 46 | #endif // _LIBCPP_STD_VER > 17 | |
| 46 | #endif // _LIBCPP_STD_VER >= 20 | |
| 47 | 47 | |
| 48 | 48 | _LIBCPP_END_NAMESPACE_STD |
| 49 | 49 |
lib/libcxx/include/__ranges/filter_view.h+16-13| ... | ... | @@ -11,12 +11,12 @@ |
| 11 | 11 | #define _LIBCPP___RANGES_FILTER_VIEW_H |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/ranges_find_if.h> |
| 14 | #include <__assert> | |
| 14 | 15 | #include <__concepts/constructible.h> |
| 15 | 16 | #include <__concepts/copyable.h> |
| 16 | 17 | #include <__concepts/derived_from.h> |
| 17 | 18 | #include <__concepts/equality_comparable.h> |
| 18 | 19 | #include <__config> |
| 19 | #include <__debug> | |
| 20 | 20 | #include <__functional/bind_back.h> |
| 21 | 21 | #include <__functional/invoke.h> |
| 22 | 22 | #include <__functional/reference_wrapper.h> |
| ... | ... | @@ -28,14 +28,17 @@ |
| 28 | 28 | #include <__ranges/access.h> |
| 29 | 29 | #include <__ranges/all.h> |
| 30 | 30 | #include <__ranges/concepts.h> |
| 31 | #include <__ranges/copyable_box.h> | |
| 31 | #include <__ranges/movable_box.h> | |
| 32 | 32 | #include <__ranges/non_propagating_cache.h> |
| 33 | 33 | #include <__ranges/range_adaptor.h> |
| 34 | 34 | #include <__ranges/view_interface.h> |
| 35 | #include <__type_traits/conditional.h> | |
| 36 | #include <__type_traits/decay.h> | |
| 37 | #include <__type_traits/is_nothrow_constructible.h> | |
| 38 | #include <__type_traits/is_object.h> | |
| 35 | 39 | #include <__utility/forward.h> |
| 36 | 40 | #include <__utility/in_place.h> |
| 37 | 41 | #include <__utility/move.h> |
| 38 | #include <type_traits> | |
| 39 | 42 | |
| 40 | 43 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 41 | 44 | # pragma GCC system_header |
| ... | ... | @@ -43,14 +46,14 @@ |
| 43 | 46 | |
| 44 | 47 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 45 | 48 | |
| 46 | #if _LIBCPP_STD_VER > 17 | |
| 49 | #if _LIBCPP_STD_VER >= 20 | |
| 47 | 50 | |
| 48 | 51 | namespace ranges { |
| 49 | 52 | template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> |
| 50 | 53 | requires view<_View> && is_object_v<_Pred> |
| 51 | 54 | class filter_view : public view_interface<filter_view<_View, _Pred>> { |
| 52 | 55 | _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); |
| 53 | _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; | |
| 56 | _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; | |
| 54 | 57 | |
| 55 | 58 | // We cache the result of begin() to allow providing an amortized O(1) begin() whenever |
| 56 | 59 | // the underlying range is at least a forward_range. |
| ... | ... | @@ -65,10 +68,8 @@ namespace ranges { |
| 65 | 68 | _LIBCPP_HIDE_FROM_ABI |
| 66 | 69 | filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default; |
| 67 | 70 | |
| 68 | _LIBCPP_HIDE_FROM_ABI | |
| 69 | constexpr filter_view(_View __base, _Pred __pred) | |
| 70 | : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) | |
| 71 | { } | |
| 71 | _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 filter_view(_View __base, _Pred __pred) | |
| 72 | : __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {} | |
| 72 | 73 | |
| 73 | 74 | template<class _Vp = _View> |
| 74 | 75 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -81,7 +82,9 @@ namespace ranges { |
| 81 | 82 | |
| 82 | 83 | _LIBCPP_HIDE_FROM_ABI |
| 83 | 84 | constexpr __iterator begin() { |
| 84 | _LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate."); | |
| 85 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 86 | __pred_.__has_value(), | |
| 87 | "Trying to call begin() on a filter_view that does not have a valid predicate."); | |
| 85 | 88 | if constexpr (_UseCache) { |
| 86 | 89 | if (!__cached_begin_.__has_value()) { |
| 87 | 90 | __cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_))); |
| ... | ... | @@ -180,9 +183,9 @@ namespace ranges { |
| 180 | 183 | } |
| 181 | 184 | _LIBCPP_HIDE_FROM_ABI |
| 182 | 185 | constexpr __iterator operator--(int) requires bidirectional_range<_View> { |
| 183 | auto tmp = *this; | |
| 186 | auto __tmp = *this; | |
| 184 | 187 | --*this; |
| 185 | return tmp; | |
| 188 | return __tmp; | |
| 186 | 189 | } |
| 187 | 190 | |
| 188 | 191 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -257,7 +260,7 @@ inline namespace __cpo { |
| 257 | 260 | |
| 258 | 261 | } // namespace ranges |
| 259 | 262 | |
| 260 | #endif // _LIBCPP_STD_VER > 17 | |
| 263 | #endif // _LIBCPP_STD_VER >= 20 | |
| 261 | 264 | |
| 262 | 265 | _LIBCPP_END_NAMESPACE_STD |
| 263 | 266 |
lib/libcxx/include/__ranges/from_range.h created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_FROM_RANGE_H | |
| 11 | #define _LIBCPP___RANGES_FROM_RANGE_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | #if _LIBCPP_STD_VER >= 23 | |
| 22 | ||
| 23 | struct from_range_t { | |
| 24 | explicit from_range_t() = default; | |
| 25 | }; | |
| 26 | ||
| 27 | inline constexpr from_range_t from_range{}; | |
| 28 | ||
| 29 | #endif // _LIBCPP_STD_VER >= 23 | |
| 30 | ||
| 31 | _LIBCPP_END_NAMESPACE_STD | |
| 32 | ||
| 33 | #endif // _LIBCPP___RANGES_FROM_RANGE_H |
lib/libcxx/include/__ranges/iota_view.h+17-13| ... | ... | @@ -27,12 +27,15 @@ |
| 27 | 27 | #include <__iterator/incrementable_traits.h> |
| 28 | 28 | #include <__iterator/iterator_traits.h> |
| 29 | 29 | #include <__iterator/unreachable_sentinel.h> |
| 30 | #include <__ranges/copyable_box.h> | |
| 31 | 30 | #include <__ranges/enable_borrowed_range.h> |
| 31 | #include <__ranges/movable_box.h> | |
| 32 | 32 | #include <__ranges/view_interface.h> |
| 33 | #include <__type_traits/conditional.h> | |
| 34 | #include <__type_traits/is_nothrow_copy_constructible.h> | |
| 35 | #include <__type_traits/make_unsigned.h> | |
| 36 | #include <__type_traits/type_identity.h> | |
| 33 | 37 | #include <__utility/forward.h> |
| 34 | 38 | #include <__utility/move.h> |
| 35 | #include <type_traits> | |
| 36 | 39 | |
| 37 | 40 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 38 | 41 | # pragma GCC system_header |
| ... | ... | @@ -40,12 +43,12 @@ |
| 40 | 43 | |
| 41 | 44 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 42 | 45 | |
| 43 | #if _LIBCPP_STD_VER > 17 | |
| 46 | #if _LIBCPP_STD_VER >= 20 | |
| 44 | 47 | |
| 45 | 48 | namespace ranges { |
| 46 | 49 | template<class _Int> |
| 47 | 50 | struct __get_wider_signed { |
| 48 | static auto __call() { | |
| 51 | consteval static auto __call() { | |
| 49 | 52 | if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{}; |
| 50 | 53 | else if constexpr (sizeof(_Int) < sizeof(int)) return type_identity<int>{}; |
| 51 | 54 | else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{}; |
| ... | ... | @@ -278,7 +281,8 @@ namespace ranges { |
| 278 | 281 | public: |
| 279 | 282 | _LIBCPP_HIDE_FROM_ABI |
| 280 | 283 | __sentinel() = default; |
| 281 | constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) : __bound_sentinel_(std::move(__bound_sentinel)) {} | |
| 284 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel) | |
| 285 | : __bound_sentinel_(std::move(__bound_sentinel)) {} | |
| 282 | 286 | |
| 283 | 287 | _LIBCPP_HIDE_FROM_ABI |
| 284 | 288 | friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) { |
| ... | ... | @@ -311,28 +315,28 @@ namespace ranges { |
| 311 | 315 | constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { } |
| 312 | 316 | |
| 313 | 317 | _LIBCPP_HIDE_FROM_ABI |
| 314 | constexpr iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel) | |
| 318 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel) | |
| 315 | 319 | : __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) { |
| 316 | 320 | // Validate the precondition if possible. |
| 317 | 321 | if constexpr (totally_ordered_with<_Start, _BoundSentinel>) { |
| 318 | _LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_sentinel_), | |
| 319 | "Precondition violated: value is greater than bound."); | |
| 322 | _LIBCPP_ASSERT_UNCATEGORIZED(ranges::less_equal()(__value_, __bound_sentinel_), | |
| 323 | "Precondition violated: value is greater than bound."); | |
| 320 | 324 | } |
| 321 | 325 | } |
| 322 | 326 | |
| 323 | 327 | _LIBCPP_HIDE_FROM_ABI |
| 324 | constexpr iota_view(__iterator __first, __iterator __last) | |
| 328 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last) | |
| 325 | 329 | requires same_as<_Start, _BoundSentinel> |
| 326 | 330 | : iota_view(std::move(__first.__value_), std::move(__last.__value_)) {} |
| 327 | 331 | |
| 328 | 332 | _LIBCPP_HIDE_FROM_ABI |
| 329 | constexpr iota_view(__iterator __first, _BoundSentinel __last) | |
| 333 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last) | |
| 330 | 334 | requires same_as<_BoundSentinel, unreachable_sentinel_t> |
| 331 | 335 | : iota_view(std::move(__first.__value_), std::move(__last)) {} |
| 332 | 336 | |
| 333 | 337 | _LIBCPP_HIDE_FROM_ABI |
| 334 | constexpr iota_view(__iterator __first, __sentinel __last) | |
| 335 | requires(!same_as<_Start, _BoundSentinel> && !same_as<_Start, unreachable_sentinel_t>) | |
| 338 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last) | |
| 339 | requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>) | |
| 336 | 340 | : iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {} |
| 337 | 341 | |
| 338 | 342 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -403,7 +407,7 @@ inline namespace __cpo { |
| 403 | 407 | } // namespace views |
| 404 | 408 | } // namespace ranges |
| 405 | 409 | |
| 406 | #endif // _LIBCPP_STD_VER > 17 | |
| 410 | #endif // _LIBCPP_STD_VER >= 20 | |
| 407 | 411 | |
| 408 | 412 | _LIBCPP_END_NAMESPACE_STD |
| 409 | 413 |
lib/libcxx/include/__ranges/join_view.h+6-5| ... | ... | @@ -22,6 +22,7 @@ |
| 22 | 22 | #include <__iterator/iterator_traits.h> |
| 23 | 23 | #include <__iterator/iterator_with_data.h> |
| 24 | 24 | #include <__iterator/segmented_iterator.h> |
| 25 | #include <__memory/addressof.h> | |
| 25 | 26 | #include <__ranges/access.h> |
| 26 | 27 | #include <__ranges/all.h> |
| 27 | 28 | #include <__ranges/concepts.h> |
| ... | ... | @@ -29,10 +30,10 @@ |
| 29 | 30 | #include <__ranges/non_propagating_cache.h> |
| 30 | 31 | #include <__ranges/range_adaptor.h> |
| 31 | 32 | #include <__ranges/view_interface.h> |
| 33 | #include <__type_traits/common_type.h> | |
| 32 | 34 | #include <__type_traits/maybe_const.h> |
| 33 | 35 | #include <__utility/forward.h> |
| 34 | 36 | #include <optional> |
| 35 | #include <type_traits> | |
| 36 | 37 | |
| 37 | 38 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 38 | 39 | # pragma GCC system_header |
| ... | ... | @@ -43,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 43 | 44 | // Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in |
| 44 | 45 | // the pipeline (https://isocpp.org/files/papers/D2770R0.html). |
| 45 | 46 | // TODO: make `join_view` non-experimental once D2770 is implemented. |
| 46 | #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) | |
| 47 | #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) | |
| 47 | 48 | |
| 48 | 49 | namespace ranges { |
| 49 | 50 | template<class> |
| ... | ... | @@ -394,8 +395,8 @@ inline namespace __cpo { |
| 394 | 395 | template <class _JoinViewIterator> |
| 395 | 396 | requires(_JoinViewIterator::__is_join_view_iterator && |
| 396 | 397 | ranges::common_range<typename _JoinViewIterator::_Parent> && |
| 397 | __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Outer>::value && | |
| 398 | __is_cpp17_random_access_iterator<typename _JoinViewIterator::_Inner>::value) | |
| 398 | __has_random_access_iterator_category<typename _JoinViewIterator::_Outer>::value && | |
| 399 | __has_random_access_iterator_category<typename _JoinViewIterator::_Inner>::value) | |
| 399 | 400 | struct __segmented_iterator_traits<_JoinViewIterator> { |
| 400 | 401 | |
| 401 | 402 | using __segment_iterator = |
| ... | ... | @@ -435,7 +436,7 @@ struct __segmented_iterator_traits<_JoinViewIterator> { |
| 435 | 436 | } |
| 436 | 437 | }; |
| 437 | 438 | |
| 438 | #endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) | |
| 439 | #endif // #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) | |
| 439 | 440 | |
| 440 | 441 | _LIBCPP_END_NAMESPACE_STD |
| 441 | 442 |
lib/libcxx/include/__ranges/lazy_split_view.h+11-7| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__algorithm/ranges_find.h> |
| 14 | 14 | #include <__algorithm/ranges_mismatch.h> |
| 15 | #include <__assert> | |
| 15 | 16 | #include <__concepts/constructible.h> |
| 16 | 17 | #include <__concepts/convertible_to.h> |
| 17 | 18 | #include <__concepts/derived_from.h> |
| ... | ... | @@ -34,10 +35,13 @@ |
| 34 | 35 | #include <__ranges/single_view.h> |
| 35 | 36 | #include <__ranges/subrange.h> |
| 36 | 37 | #include <__ranges/view_interface.h> |
| 38 | #include <__type_traits/conditional.h> | |
| 39 | #include <__type_traits/decay.h> | |
| 40 | #include <__type_traits/is_nothrow_constructible.h> | |
| 37 | 41 | #include <__type_traits/maybe_const.h> |
| 42 | #include <__type_traits/remove_reference.h> | |
| 38 | 43 | #include <__utility/forward.h> |
| 39 | 44 | #include <__utility/move.h> |
| 40 | #include <type_traits> | |
| 41 | 45 | |
| 42 | 46 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 43 | 47 | # pragma GCC system_header |
| ... | ... | @@ -45,7 +49,7 @@ |
| 45 | 49 | |
| 46 | 50 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 47 | 51 | |
| 48 | #if _LIBCPP_STD_VER > 17 | |
| 52 | #if _LIBCPP_STD_VER >= 20 | |
| 49 | 53 | |
| 50 | 54 | namespace ranges { |
| 51 | 55 | |
| ... | ... | @@ -78,14 +82,14 @@ public: |
| 78 | 82 | requires default_initializable<_View> && default_initializable<_Pattern> = default; |
| 79 | 83 | |
| 80 | 84 | _LIBCPP_HIDE_FROM_ABI |
| 81 | constexpr lazy_split_view(_View __base, _Pattern __pattern) | |
| 85 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_View __base, _Pattern __pattern) | |
| 82 | 86 | : __base_(std::move(__base)), __pattern_(std::move(__pattern)) {} |
| 83 | 87 | |
| 84 | 88 | template <input_range _Range> |
| 85 | 89 | requires constructible_from<_View, views::all_t<_Range>> && |
| 86 | 90 | constructible_from<_Pattern, single_view<range_value_t<_Range>>> |
| 87 | 91 | _LIBCPP_HIDE_FROM_ABI |
| 88 | constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e) | |
| 92 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_Range&& __r, range_value_t<_Range> __e) | |
| 89 | 93 | : __base_(views::all(std::forward<_Range>(__r))) |
| 90 | 94 | , __pattern_(views::single(std::move(__e))) {} |
| 91 | 95 | |
| ... | ... | @@ -276,7 +280,7 @@ private: |
| 276 | 280 | |
| 277 | 281 | _LIBCPP_HIDE_FROM_ABI |
| 278 | 282 | friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) { |
| 279 | _LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator."); | |
| 283 | _LIBCPP_ASSERT_UNCATEGORIZED(__x.__parent_, "Cannot call comparison on a default-constructed iterator."); | |
| 280 | 284 | return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_; |
| 281 | 285 | } |
| 282 | 286 | }; |
| ... | ... | @@ -307,7 +311,7 @@ private: |
| 307 | 311 | |
| 308 | 312 | _LIBCPP_HIDE_FROM_ABI |
| 309 | 313 | constexpr bool __is_done() const { |
| 310 | _LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator."); | |
| 314 | _LIBCPP_ASSERT_UNCATEGORIZED(__i_.__parent_, "Cannot call comparison on a default-constructed iterator."); | |
| 311 | 315 | |
| 312 | 316 | auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_}; |
| 313 | 317 | auto __end = ranges::end(__i_.__parent_->__base_); |
| ... | ... | @@ -458,7 +462,7 @@ inline namespace __cpo { |
| 458 | 462 | |
| 459 | 463 | } // namespace ranges |
| 460 | 464 | |
| 461 | #endif // _LIBCPP_STD_VER > 17 | |
| 465 | #endif // _LIBCPP_STD_VER >= 20 | |
| 462 | 466 | |
| 463 | 467 | _LIBCPP_END_NAMESPACE_STD |
| 464 | 468 |
lib/libcxx/include/__ranges/movable_box.h created+206| ... | ... | @@ -0,0 +1,206 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_MOVABLE_BOX_H | |
| 11 | #define _LIBCPP___RANGES_MOVABLE_BOX_H | |
| 12 | ||
| 13 | #include <__concepts/constructible.h> | |
| 14 | #include <__concepts/copyable.h> | |
| 15 | #include <__concepts/movable.h> | |
| 16 | #include <__config> | |
| 17 | #include <__memory/addressof.h> | |
| 18 | #include <__memory/construct_at.h> | |
| 19 | #include <__type_traits/is_nothrow_constructible.h> | |
| 20 | #include <__type_traits/is_nothrow_copy_constructible.h> | |
| 21 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 22 | #include <__utility/move.h> | |
| 23 | #include <optional> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | ||
| 33 | // __movable_box allows turning a type that is move-constructible (but maybe not move-assignable) into | |
| 34 | // a type that is both move-constructible and move-assignable. It does that by introducing an empty state | |
| 35 | // and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary | |
| 36 | // to handle the case where the copy construction fails after destroying the object. | |
| 37 | // | |
| 38 | // In some cases, we can completely avoid the use of an empty state; we provide a specialization of | |
| 39 | // __movable_box that does this, see below for the details. | |
| 40 | ||
| 41 | // until C++23, `__movable_box` was named `__copyable_box` and required the stored type to be copy-constructible, not | |
| 42 | // just move-constructible; we preserve the old behavior in pre-C++23 modes. | |
| 43 | template <class _Tp> | |
| 44 | concept __movable_box_object = | |
| 45 | # if _LIBCPP_STD_VER >= 23 | |
| 46 | move_constructible<_Tp> | |
| 47 | # else | |
| 48 | copy_constructible<_Tp> | |
| 49 | # endif | |
| 50 | && is_object_v<_Tp>; | |
| 51 | ||
| 52 | namespace ranges { | |
| 53 | // Primary template - uses std::optional and introduces an empty state in case assignment fails. | |
| 54 | template <__movable_box_object _Tp> | |
| 55 | class __movable_box { | |
| 56 | _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_; | |
| 57 | ||
| 58 | public: | |
| 59 | template <class... _Args> | |
| 60 | requires is_constructible_v<_Tp, _Args...> | |
| 61 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept( | |
| 62 | is_nothrow_constructible_v<_Tp, _Args...>) | |
| 63 | : __val_(in_place, std::forward<_Args>(__args)...) {} | |
| 64 | ||
| 65 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) | |
| 66 | requires default_initializable<_Tp> | |
| 67 | : __val_(in_place) {} | |
| 68 | ||
| 69 | _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default; | |
| 70 | _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default; | |
| 71 | ||
| 72 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& | |
| 73 | operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>) | |
| 74 | # if _LIBCPP_STD_VER >= 23 | |
| 75 | requires copy_constructible<_Tp> | |
| 76 | # endif | |
| 77 | { | |
| 78 | if (this != std::addressof(__other)) { | |
| 79 | if (__other.__has_value()) | |
| 80 | __val_.emplace(*__other); | |
| 81 | else | |
| 82 | __val_.reset(); | |
| 83 | } | |
| 84 | return *this; | |
| 85 | } | |
| 86 | ||
| 87 | _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&) | |
| 88 | requires movable<_Tp> | |
| 89 | = default; | |
| 90 | ||
| 91 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& | |
| 92 | operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) { | |
| 93 | if (this != std::addressof(__other)) { | |
| 94 | if (__other.__has_value()) | |
| 95 | __val_.emplace(std::move(*__other)); | |
| 96 | else | |
| 97 | __val_.reset(); | |
| 98 | } | |
| 99 | return *this; | |
| 100 | } | |
| 101 | ||
| 102 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; } | |
| 103 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; } | |
| 104 | ||
| 105 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return __val_.operator->(); } | |
| 106 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); } | |
| 107 | ||
| 108 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); } | |
| 109 | }; | |
| 110 | ||
| 111 | // This partial specialization implements an optimization for when we know we don't need to store | |
| 112 | // an empty state to represent failure to perform an assignment. For copy-assignment, this happens: | |
| 113 | // | |
| 114 | // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator | |
| 115 | // directly and avoid using std::optional. | |
| 116 | // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as | |
| 117 | // destroy-and-then-construct and we know it will never fail, so we don't need an empty state. | |
| 118 | // | |
| 119 | // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and | |
| 120 | // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled | |
| 121 | // whenever we can apply any of these optimizations for both the copy assignment and the move assignment | |
| 122 | // operator. | |
| 123 | ||
| 124 | # if _LIBCPP_STD_VER >= 23 | |
| 125 | template <class _Tp> | |
| 126 | concept __doesnt_need_empty_state = | |
| 127 | (copy_constructible<_Tp> | |
| 128 | // 1. If copy_constructible<T> is true, movable-box<T> should store only a T if either T models | |
| 129 | // copyable, or is_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true. | |
| 130 | ? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>) | |
| 131 | // 2. Otherwise, movable-box<T> should store only a T if either T models movable or | |
| 132 | // is_nothrow_move_constructible_v<T> is true. | |
| 133 | : movable<_Tp> || is_nothrow_move_constructible_v<_Tp>); | |
| 134 | # else | |
| 135 | ||
| 136 | template <class _Tp> | |
| 137 | concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>; | |
| 138 | ||
| 139 | template <class _Tp> | |
| 140 | concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>; | |
| 141 | ||
| 142 | template <class _Tp> | |
| 143 | concept __doesnt_need_empty_state = __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>; | |
| 144 | # endif | |
| 145 | ||
| 146 | template <__movable_box_object _Tp> | |
| 147 | requires __doesnt_need_empty_state<_Tp> | |
| 148 | class __movable_box<_Tp> { | |
| 149 | _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; | |
| 150 | ||
| 151 | public: | |
| 152 | template <class... _Args> | |
| 153 | requires is_constructible_v<_Tp, _Args...> | |
| 154 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept( | |
| 155 | is_nothrow_constructible_v<_Tp, _Args...>) | |
| 156 | : __val_(std::forward<_Args>(__args)...) {} | |
| 157 | ||
| 158 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) | |
| 159 | requires default_initializable<_Tp> | |
| 160 | : __val_() {} | |
| 161 | ||
| 162 | _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default; | |
| 163 | _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default; | |
| 164 | ||
| 165 | // Implementation of assignment operators in case we perform optimization (1) | |
| 166 | _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&) | |
| 167 | requires copyable<_Tp> | |
| 168 | = default; | |
| 169 | _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&) | |
| 170 | requires movable<_Tp> | |
| 171 | = default; | |
| 172 | ||
| 173 | // Implementation of assignment operators in case we perform optimization (2) | |
| 174 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept { | |
| 175 | static_assert(is_nothrow_copy_constructible_v<_Tp>); | |
| 176 | if (this != std::addressof(__other)) { | |
| 177 | std::destroy_at(std::addressof(__val_)); | |
| 178 | std::construct_at(std::addressof(__val_), __other.__val_); | |
| 179 | } | |
| 180 | return *this; | |
| 181 | } | |
| 182 | ||
| 183 | _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept { | |
| 184 | static_assert(is_nothrow_move_constructible_v<_Tp>); | |
| 185 | if (this != std::addressof(__other)) { | |
| 186 | std::destroy_at(std::addressof(__val_)); | |
| 187 | std::construct_at(std::addressof(__val_), std::move(__other.__val_)); | |
| 188 | } | |
| 189 | return *this; | |
| 190 | } | |
| 191 | ||
| 192 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; } | |
| 193 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; } | |
| 194 | ||
| 195 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__val_); } | |
| 196 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__val_); } | |
| 197 | ||
| 198 | _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; } | |
| 199 | }; | |
| 200 | } // namespace ranges | |
| 201 | ||
| 202 | #endif // _LIBCPP_STD_VER >= 20 | |
| 203 | ||
| 204 | _LIBCPP_END_NAMESPACE_STD | |
| 205 | ||
| 206 | #endif // _LIBCPP___RANGES_MOVABLE_BOX_H |
lib/libcxx/include/__ranges/non_propagating_cache.h+7-7| ... | ... | @@ -16,7 +16,6 @@ |
| 16 | 16 | #include <__memory/addressof.h> |
| 17 | 17 | #include <__utility/forward.h> |
| 18 | 18 | #include <optional> |
| 19 | #include <type_traits> | |
| 20 | 19 | |
| 21 | 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 21 | # pragma GCC system_header |
| ... | ... | @@ -24,7 +23,7 @@ |
| 24 | 23 | |
| 25 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 25 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 27 | |
| 29 | 28 | namespace ranges { |
| 30 | 29 | // __non_propagating_cache is a helper type that allows storing an optional value in it, |
| ... | ... | @@ -44,10 +43,11 @@ namespace ranges { |
| 44 | 43 | // This helper class is needed to perform copy and move elision when |
| 45 | 44 | // constructing the contained type from an iterator. |
| 46 | 45 | struct __wrapper { |
| 47 | template<class ..._Args> | |
| 48 | constexpr explicit __wrapper(__forward_tag, _Args&& ...__args) : __t_(std::forward<_Args>(__args)...) { } | |
| 49 | template<class _Fn> | |
| 50 | constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) { } | |
| 46 | template <class... _Args> | |
| 47 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__forward_tag, _Args&&... __args) | |
| 48 | : __t_(std::forward<_Args>(__args)...) {} | |
| 49 | template <class _Fn> | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) {} | |
| 51 | 51 | _Tp __t_; |
| 52 | 52 | }; |
| 53 | 53 | |
| ... | ... | @@ -107,7 +107,7 @@ namespace ranges { |
| 107 | 107 | struct __empty_cache { }; |
| 108 | 108 | } // namespace ranges |
| 109 | 109 | |
| 110 | #endif // _LIBCPP_STD_VER > 17 | |
| 110 | #endif // _LIBCPP_STD_VER >= 20 | |
| 111 | 111 | |
| 112 | 112 | _LIBCPP_END_NAMESPACE_STD |
| 113 | 113 |
lib/libcxx/include/__ranges/owning_view.h+11-6| ... | ... | @@ -20,16 +20,19 @@ |
| 20 | 20 | #include <__ranges/enable_borrowed_range.h> |
| 21 | 21 | #include <__ranges/size.h> |
| 22 | 22 | #include <__ranges/view_interface.h> |
| 23 | #include <__type_traits/remove_cvref.h> | |
| 23 | 24 | #include <__utility/move.h> |
| 24 | #include <type_traits> | |
| 25 | 25 | |
| 26 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 27 | 27 | # pragma GCC system_header |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | _LIBCPP_PUSH_MACROS | |
| 31 | #include <__undef_macros> | |
| 32 | ||
| 30 | 33 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 31 | 34 | |
| 32 | #if _LIBCPP_STD_VER > 17 | |
| 35 | #if _LIBCPP_STD_VER >= 20 | |
| 33 | 36 | |
| 34 | 37 | namespace ranges { |
| 35 | 38 | template<range _Rp> |
| ... | ... | @@ -38,11 +41,11 @@ namespace ranges { |
| 38 | 41 | _Rp __r_ = _Rp(); |
| 39 | 42 | |
| 40 | 43 | public: |
| 41 | owning_view() requires default_initializable<_Rp> = default; | |
| 44 | _LIBCPP_HIDE_FROM_ABI owning_view() requires default_initializable<_Rp> = default; | |
| 42 | 45 | _LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {} |
| 43 | 46 | |
| 44 | owning_view(owning_view&&) = default; | |
| 45 | owning_view& operator=(owning_view&&) = default; | |
| 47 | _LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default; | |
| 48 | _LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default; | |
| 46 | 49 | |
| 47 | 50 | _LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; } |
| 48 | 51 | _LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; } |
| ... | ... | @@ -76,8 +79,10 @@ public: |
| 76 | 79 | |
| 77 | 80 | } // namespace ranges |
| 78 | 81 | |
| 79 | #endif // _LIBCPP_STD_VER > 17 | |
| 82 | #endif // _LIBCPP_STD_VER >= 20 | |
| 80 | 83 | |
| 81 | 84 | _LIBCPP_END_NAMESPACE_STD |
| 82 | 85 | |
| 86 | _LIBCPP_POP_MACROS | |
| 87 | ||
| 83 | 88 | #endif // _LIBCPP___RANGES_OWNING_VIEW_H |
lib/libcxx/include/__ranges/range_adaptor.h+11-4| ... | ... | @@ -18,17 +18,22 @@ |
| 18 | 18 | #include <__functional/compose.h> |
| 19 | 19 | #include <__functional/invoke.h> |
| 20 | 20 | #include <__ranges/concepts.h> |
| 21 | #include <__type_traits/decay.h> | |
| 22 | #include <__type_traits/is_nothrow_constructible.h> | |
| 23 | #include <__type_traits/remove_cvref.h> | |
| 21 | 24 | #include <__utility/forward.h> |
| 22 | 25 | #include <__utility/move.h> |
| 23 | #include <type_traits> | |
| 24 | 26 | |
| 25 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 26 | 28 | # pragma GCC system_header |
| 27 | 29 | #endif |
| 28 | 30 | |
| 31 | _LIBCPP_PUSH_MACROS | |
| 32 | #include <__undef_macros> | |
| 33 | ||
| 29 | 34 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 35 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 36 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 37 | |
| 33 | 38 | // CRTP base that one can derive from in order to be considered a range adaptor closure |
| 34 | 39 | // by the library. When deriving from this class, a pipe operator will be provided to |
| ... | ... | @@ -42,7 +47,7 @@ struct __range_adaptor_closure; |
| 42 | 47 | // i.e. something that can be called via the `x | f` notation. |
| 43 | 48 | template <class _Fn> |
| 44 | 49 | struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> { |
| 45 | constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { } | |
| 50 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { } | |
| 46 | 51 | }; |
| 47 | 52 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t); |
| 48 | 53 | |
| ... | ... | @@ -70,8 +75,10 @@ struct __range_adaptor_closure { |
| 70 | 75 | { return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); } |
| 71 | 76 | }; |
| 72 | 77 | |
| 73 | #endif // _LIBCPP_STD_VER > 17 | |
| 78 | #endif // _LIBCPP_STD_VER >= 20 | |
| 74 | 79 | |
| 75 | 80 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 81 | |
| 82 | _LIBCPP_POP_MACROS | |
| 83 | ||
| 77 | 84 | #endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H |
lib/libcxx/include/__ranges/rbegin.h+6-3| ... | ... | @@ -17,8 +17,11 @@ |
| 17 | 17 | #include <__iterator/readable_traits.h> |
| 18 | 18 | #include <__iterator/reverse_iterator.h> |
| 19 | 19 | #include <__ranges/access.h> |
| 20 | #include <__type_traits/decay.h> | |
| 21 | #include <__type_traits/is_reference.h> | |
| 22 | #include <__type_traits/remove_cvref.h> | |
| 23 | #include <__type_traits/remove_reference.h> | |
| 20 | 24 | #include <__utility/auto_cast.h> |
| 21 | #include <type_traits> | |
| 22 | 25 | |
| 23 | 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 27 | # pragma GCC system_header |
| ... | ... | @@ -26,7 +29,7 @@ |
| 26 | 29 | |
| 27 | 30 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 31 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 32 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 33 | |
| 31 | 34 | // [ranges.access.rbegin] |
| 32 | 35 | |
| ... | ... | @@ -124,7 +127,7 @@ inline namespace __cpo { |
| 124 | 127 | } // namespace __cpo |
| 125 | 128 | } // namespace ranges |
| 126 | 129 | |
| 127 | #endif // _LIBCPP_STD_VER > 17 | |
| 130 | #endif // _LIBCPP_STD_VER >= 20 | |
| 128 | 131 | |
| 129 | 132 | _LIBCPP_END_NAMESPACE_STD |
| 130 | 133 |
lib/libcxx/include/__ranges/ref_view.h+4-3| ... | ... | @@ -24,8 +24,9 @@ |
| 24 | 24 | #include <__ranges/enable_borrowed_range.h> |
| 25 | 25 | #include <__ranges/size.h> |
| 26 | 26 | #include <__ranges/view_interface.h> |
| 27 | #include <__type_traits/is_object.h> | |
| 28 | #include <__utility/declval.h> | |
| 27 | 29 | #include <__utility/forward.h> |
| 28 | #include <type_traits> | |
| 29 | 30 | |
| 30 | 31 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 31 | 32 | # pragma GCC system_header |
| ... | ... | @@ -33,7 +34,7 @@ |
| 33 | 34 | |
| 34 | 35 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 35 | 36 | |
| 36 | #if _LIBCPP_STD_VER > 17 | |
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 37 | 38 | |
| 38 | 39 | namespace ranges { |
| 39 | 40 | template<range _Range> |
| ... | ... | @@ -81,7 +82,7 @@ public: |
| 81 | 82 | inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; |
| 82 | 83 | } // namespace ranges |
| 83 | 84 | |
| 84 | #endif // _LIBCPP_STD_VER > 17 | |
| 85 | #endif // _LIBCPP_STD_VER >= 20 | |
| 85 | 86 | |
| 86 | 87 | _LIBCPP_END_NAMESPACE_STD |
| 87 | 88 |
lib/libcxx/include/__ranges/rend.h+6-3| ... | ... | @@ -18,8 +18,11 @@ |
| 18 | 18 | #include <__iterator/reverse_iterator.h> |
| 19 | 19 | #include <__ranges/access.h> |
| 20 | 20 | #include <__ranges/rbegin.h> |
| 21 | #include <__type_traits/decay.h> | |
| 22 | #include <__type_traits/is_reference.h> | |
| 23 | #include <__type_traits/remove_cvref.h> | |
| 24 | #include <__type_traits/remove_reference.h> | |
| 21 | 25 | #include <__utility/auto_cast.h> |
| 22 | #include <type_traits> | |
| 23 | 26 | |
| 24 | 27 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 25 | 28 | # pragma GCC system_header |
| ... | ... | @@ -27,7 +30,7 @@ |
| 27 | 30 | |
| 28 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 32 | |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 34 | |
| 32 | 35 | // [range.access.rend] |
| 33 | 36 | |
| ... | ... | @@ -128,7 +131,7 @@ inline namespace __cpo { |
| 128 | 131 | } // namespace __cpo |
| 129 | 132 | } // namespace ranges |
| 130 | 133 | |
| 131 | #endif // _LIBCPP_STD_VER > 17 | |
| 134 | #endif // _LIBCPP_STD_VER >= 20 | |
| 132 | 135 | |
| 133 | 136 | _LIBCPP_END_NAMESPACE_STD |
| 134 | 137 |
lib/libcxx/include/__ranges/repeat_view.h created+260| ... | ... | @@ -0,0 +1,260 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_REPEAT_VIEW_H | |
| 11 | #define _LIBCPP___RANGES_REPEAT_VIEW_H | |
| 12 | ||
| 13 | #include <__concepts/constructible.h> | |
| 14 | #include <__concepts/same_as.h> | |
| 15 | #include <__concepts/semiregular.h> | |
| 16 | #include <__config> | |
| 17 | #include <__iterator/concepts.h> | |
| 18 | #include <__iterator/iterator_traits.h> | |
| 19 | #include <__iterator/unreachable_sentinel.h> | |
| 20 | #include <__memory/addressof.h> | |
| 21 | #include <__ranges/iota_view.h> | |
| 22 | #include <__ranges/movable_box.h> | |
| 23 | #include <__ranges/view_interface.h> | |
| 24 | #include <__type_traits/is_object.h> | |
| 25 | #include <__type_traits/make_unsigned.h> | |
| 26 | #include <__type_traits/remove_cv.h> | |
| 27 | #include <__utility/forward.h> | |
| 28 | #include <__utility/in_place.h> | |
| 29 | #include <__utility/move.h> | |
| 30 | #include <__utility/piecewise_construct.h> | |
| 31 | #include <tuple> | |
| 32 | ||
| 33 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 34 | # pragma GCC system_header | |
| 35 | #endif | |
| 36 | ||
| 37 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 38 | ||
| 39 | #if _LIBCPP_STD_VER >= 23 | |
| 40 | ||
| 41 | namespace ranges { | |
| 42 | ||
| 43 | template <class _Tp> | |
| 44 | concept __integer_like_with_usable_difference_type = | |
| 45 | __signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>); | |
| 46 | ||
| 47 | template <class _Tp> | |
| 48 | struct __repeat_view_iterator_difference { | |
| 49 | using type = _IotaDiffT<_Tp>; | |
| 50 | }; | |
| 51 | ||
| 52 | template <__signed_integer_like _Tp> | |
| 53 | struct __repeat_view_iterator_difference<_Tp> { | |
| 54 | using type = _Tp; | |
| 55 | }; | |
| 56 | ||
| 57 | template <class _Tp> | |
| 58 | using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type; | |
| 59 | ||
| 60 | namespace views::__drop { | |
| 61 | struct __fn; | |
| 62 | } // namespace views::__drop | |
| 63 | ||
| 64 | namespace views::__take { | |
| 65 | struct __fn; | |
| 66 | } // namespace views::__take | |
| 67 | ||
| 68 | template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t> | |
| 69 | requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> && | |
| 70 | (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>)) | |
| 71 | class repeat_view : public view_interface<repeat_view<_Tp, _Bound>> { | |
| 72 | friend struct views::__take::__fn; | |
| 73 | friend struct views::__drop::__fn; | |
| 74 | class __iterator; | |
| 75 | ||
| 76 | public: | |
| 77 | _LIBCPP_HIDE_FROM_ABI repeat_view() | |
| 78 | requires default_initializable<_Tp> | |
| 79 | = default; | |
| 80 | ||
| 81 | _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound()) | |
| 82 | requires copy_constructible<_Tp> | |
| 83 | : __value_(in_place, __value), __bound_(__bound_sentinel) { | |
| 84 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 85 | _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0"); | |
| 86 | } | |
| 87 | ||
| 88 | _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound()) | |
| 89 | : __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) { | |
| 90 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 91 | _LIBCPP_ASSERT(__bound_ >= 0, "The value of bound must be greater than or equal to 0"); | |
| 92 | } | |
| 93 | ||
| 94 | template <class... _TpArgs, class... _BoundArgs> | |
| 95 | requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>) | |
| 96 | _LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view( | |
| 97 | piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{}) | |
| 98 | : __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))), | |
| 99 | __bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) { | |
| 100 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 101 | _LIBCPP_ASSERT( | |
| 102 | __bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative"); | |
| 103 | } | |
| 104 | ||
| 105 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); } | |
| 106 | ||
| 107 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const | |
| 108 | requires(!same_as<_Bound, unreachable_sentinel_t>) | |
| 109 | { | |
| 110 | return __iterator(std::addressof(*__value_), __bound_); | |
| 111 | } | |
| 112 | ||
| 113 | _LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; } | |
| 114 | ||
| 115 | _LIBCPP_HIDE_FROM_ABI constexpr auto size() const | |
| 116 | requires(!same_as<_Bound, unreachable_sentinel_t>) | |
| 117 | { | |
| 118 | return std::__to_unsigned_like(__bound_); | |
| 119 | } | |
| 120 | ||
| 121 | private: | |
| 122 | __movable_box<_Tp> __value_; | |
| 123 | _LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound(); | |
| 124 | }; | |
| 125 | ||
| 126 | template <class _Tp, class _Bound> | |
| 127 | repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>; | |
| 128 | ||
| 129 | // [range.repeat.iterator] | |
| 130 | template <move_constructible _Tp, semiregular _Bound> | |
| 131 | requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> && | |
| 132 | (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>)) | |
| 133 | class repeat_view<_Tp, _Bound>::__iterator { | |
| 134 | friend class repeat_view; | |
| 135 | ||
| 136 | using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>; | |
| 137 | ||
| 138 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT()) | |
| 139 | : __value_(__value), __current_(__bound_sentinel) {} | |
| 140 | ||
| 141 | public: | |
| 142 | using iterator_concept = random_access_iterator_tag; | |
| 143 | using iterator_category = random_access_iterator_tag; | |
| 144 | using value_type = _Tp; | |
| 145 | using difference_type = __repeat_view_iterator_difference_t<_IndexT>; | |
| 146 | ||
| 147 | _LIBCPP_HIDE_FROM_ABI __iterator() = default; | |
| 148 | ||
| 149 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; } | |
| 150 | ||
| 151 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { | |
| 152 | ++__current_; | |
| 153 | return *this; | |
| 154 | } | |
| 155 | ||
| 156 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) { | |
| 157 | auto __tmp = *this; | |
| 158 | ++*this; | |
| 159 | return __tmp; | |
| 160 | } | |
| 161 | ||
| 162 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() { | |
| 163 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 164 | _LIBCPP_ASSERT(__current_ > 0, "The value of bound must be greater than or equal to 0"); | |
| 165 | --__current_; | |
| 166 | return *this; | |
| 167 | } | |
| 168 | ||
| 169 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) { | |
| 170 | auto __tmp = *this; | |
| 171 | --*this; | |
| 172 | return __tmp; | |
| 173 | } | |
| 174 | ||
| 175 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) { | |
| 176 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 177 | _LIBCPP_ASSERT(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0"); | |
| 178 | __current_ += __n; | |
| 179 | return *this; | |
| 180 | } | |
| 181 | ||
| 182 | _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) { | |
| 183 | if constexpr (!same_as<_Bound, unreachable_sentinel_t>) | |
| 184 | _LIBCPP_ASSERT(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0"); | |
| 185 | __current_ -= __n; | |
| 186 | return *this; | |
| 187 | } | |
| 188 | ||
| 189 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); } | |
| 190 | ||
| 191 | _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) { | |
| 192 | return __x.__current_ == __y.__current_; | |
| 193 | } | |
| 194 | ||
| 195 | _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) { | |
| 196 | return __x.__current_ <=> __y.__current_; | |
| 197 | } | |
| 198 | ||
| 199 | _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) { | |
| 200 | __i += __n; | |
| 201 | return __i; | |
| 202 | } | |
| 203 | ||
| 204 | _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) { | |
| 205 | __i += __n; | |
| 206 | return __i; | |
| 207 | } | |
| 208 | ||
| 209 | _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) { | |
| 210 | __i -= __n; | |
| 211 | return __i; | |
| 212 | } | |
| 213 | ||
| 214 | _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) { | |
| 215 | return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_); | |
| 216 | } | |
| 217 | ||
| 218 | private: | |
| 219 | const _Tp* __value_ = nullptr; | |
| 220 | _IndexT __current_ = _IndexT(); | |
| 221 | }; | |
| 222 | ||
| 223 | // clang-format off | |
| 224 | namespace views { | |
| 225 | namespace __repeat { | |
| 226 | struct __fn { | |
| 227 | template <class _Tp> | |
| 228 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value) const | |
| 229 | noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value)))) | |
| 230 | -> decltype( ranges::repeat_view(std::forward<_Tp>(__value))) | |
| 231 | { return ranges::repeat_view(std::forward<_Tp>(__value)); } | |
| 232 | ||
| 233 | ||
| 234 | template <class _Tp, class _Bound> | |
| 235 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) const | |
| 236 | noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))) | |
| 237 | -> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))) | |
| 238 | { return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); } | |
| 239 | }; | |
| 240 | } // namespace __repeat | |
| 241 | // clang-format on | |
| 242 | ||
| 243 | inline namespace __cpo { | |
| 244 | inline constexpr auto repeat = __repeat::__fn{}; | |
| 245 | } // namespace __cpo | |
| 246 | } // namespace views | |
| 247 | ||
| 248 | template <class _Tp> | |
| 249 | inline constexpr bool __is_repeat_specialization = false; | |
| 250 | ||
| 251 | template <class _Tp, class _Bound> | |
| 252 | inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true; | |
| 253 | ||
| 254 | } // namespace ranges | |
| 255 | ||
| 256 | #endif // _LIBCPP_STD_VER >= 23 | |
| 257 | ||
| 258 | _LIBCPP_END_NAMESPACE_STD | |
| 259 | ||
| 260 | #endif // _LIBCPP___RANGES_REPEAT_VIEW_H |
lib/libcxx/include/__ranges/reverse_view.h+4-3| ... | ... | @@ -24,9 +24,10 @@ |
| 24 | 24 | #include <__ranges/size.h> |
| 25 | 25 | #include <__ranges/subrange.h> |
| 26 | 26 | #include <__ranges/view_interface.h> |
| 27 | #include <__type_traits/conditional.h> | |
| 28 | #include <__type_traits/remove_cvref.h> | |
| 27 | 29 | #include <__utility/forward.h> |
| 28 | 30 | #include <__utility/move.h> |
| 29 | #include <type_traits> | |
| 30 | 31 | |
| 31 | 32 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 32 | 33 | # pragma GCC system_header |
| ... | ... | @@ -34,7 +35,7 @@ |
| 34 | 35 | |
| 35 | 36 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 36 | 37 | |
| 37 | #if _LIBCPP_STD_VER > 17 | |
| 38 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | 39 | |
| 39 | 40 | namespace ranges { |
| 40 | 41 | template<view _View> |
| ... | ... | @@ -184,7 +185,7 @@ namespace ranges { |
| 184 | 185 | } // namespace views |
| 185 | 186 | } // namespace ranges |
| 186 | 187 | |
| 187 | #endif // _LIBCPP_STD_VER > 17 | |
| 188 | #endif // _LIBCPP_STD_VER >= 20 | |
| 188 | 189 | |
| 189 | 190 | _LIBCPP_END_NAMESPACE_STD |
| 190 | 191 |
lib/libcxx/include/__ranges/single_view.h+40-38| ... | ... | @@ -12,13 +12,15 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__concepts/constructible.h> |
| 14 | 14 | #include <__config> |
| 15 | #include <__ranges/copyable_box.h> | |
| 15 | #include <__ranges/movable_box.h> | |
| 16 | 16 | #include <__ranges/range_adaptor.h> |
| 17 | 17 | #include <__ranges/view_interface.h> |
| 18 | #include <__type_traits/decay.h> | |
| 19 | #include <__type_traits/is_object.h> | |
| 18 | 20 | #include <__utility/forward.h> |
| 19 | 21 | #include <__utility/in_place.h> |
| 20 | 22 | #include <__utility/move.h> |
| 21 | #include <type_traits> | |
| 23 | #include <cstddef> | |
| 22 | 24 | |
| 23 | 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 24 | 26 | # pragma GCC system_header |
| ... | ... | @@ -26,51 +28,51 @@ |
| 26 | 28 | |
| 27 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 30 | |
| 29 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 30 | 32 | |
| 31 | 33 | namespace ranges { |
| 32 | template<copy_constructible _Tp> | |
| 33 | requires is_object_v<_Tp> | |
| 34 | class single_view : public view_interface<single_view<_Tp>> { | |
| 35 | __copyable_box<_Tp> __value_; | |
| 36 | ||
| 37 | public: | |
| 38 | _LIBCPP_HIDE_FROM_ABI | |
| 39 | single_view() requires default_initializable<_Tp> = default; | |
| 40 | ||
| 41 | _LIBCPP_HIDE_FROM_ABI | |
| 42 | constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {} | |
| 43 | ||
| 44 | _LIBCPP_HIDE_FROM_ABI | |
| 45 | constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {} | |
| 46 | ||
| 47 | template<class... _Args> | |
| 48 | requires constructible_from<_Tp, _Args...> | |
| 49 | _LIBCPP_HIDE_FROM_ABI | |
| 50 | constexpr explicit single_view(in_place_t, _Args&&... __args) | |
| 34 | # if _LIBCPP_STD_VER >= 23 | |
| 35 | template <move_constructible _Tp> | |
| 36 | # else | |
| 37 | template <copy_constructible _Tp> | |
| 38 | # endif | |
| 39 | requires is_object_v<_Tp> | |
| 40 | class single_view : public view_interface<single_view<_Tp>> { | |
| 41 | __movable_box<_Tp> __value_; | |
| 42 | ||
| 43 | public: | |
| 44 | _LIBCPP_HIDE_FROM_ABI single_view() | |
| 45 | requires default_initializable<_Tp> | |
| 46 | = default; | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t) | |
| 49 | # if _LIBCPP_STD_VER >= 23 | |
| 50 | requires copy_constructible<_Tp> | |
| 51 | # endif | |
| 52 | : __value_(in_place, __t) { | |
| 53 | } | |
| 54 | ||
| 55 | _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {} | |
| 56 | ||
| 57 | template <class... _Args> | |
| 58 | requires constructible_from<_Tp, _Args...> | |
| 59 | _LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args) | |
| 51 | 60 | : __value_{in_place, std::forward<_Args>(__args)...} {} |
| 52 | 61 | |
| 53 | _LIBCPP_HIDE_FROM_ABI | |
| 54 | constexpr _Tp* begin() noexcept { return data(); } | |
| 62 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); } | |
| 55 | 63 | |
| 56 | _LIBCPP_HIDE_FROM_ABI | |
| 57 | constexpr const _Tp* begin() const noexcept { return data(); } | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); } | |
| 58 | 65 | |
| 59 | _LIBCPP_HIDE_FROM_ABI | |
| 60 | constexpr _Tp* end() noexcept { return data() + 1; } | |
| 66 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; } | |
| 61 | 67 | |
| 62 | _LIBCPP_HIDE_FROM_ABI | |
| 63 | constexpr const _Tp* end() const noexcept { return data() + 1; } | |
| 68 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; } | |
| 64 | 69 | |
| 65 | _LIBCPP_HIDE_FROM_ABI | |
| 66 | static constexpr size_t size() noexcept { return 1; } | |
| 70 | _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; } | |
| 67 | 71 | |
| 68 | _LIBCPP_HIDE_FROM_ABI | |
| 69 | constexpr _Tp* data() noexcept { return __value_.operator->(); } | |
| 72 | _LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); } | |
| 70 | 73 | |
| 71 | _LIBCPP_HIDE_FROM_ABI | |
| 72 | constexpr const _Tp* data() const noexcept { return __value_.operator->(); } | |
| 73 | }; | |
| 74 | _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); } | |
| 75 | }; | |
| 74 | 76 | |
| 75 | 77 | template<class _Tp> |
| 76 | 78 | single_view(_Tp) -> single_view<_Tp>; |
| ... | ... | @@ -95,7 +97,7 @@ inline namespace __cpo { |
| 95 | 97 | } // namespace views |
| 96 | 98 | } // namespace ranges |
| 97 | 99 | |
| 98 | #endif // _LIBCPP_STD_VER > 17 | |
| 100 | #endif // _LIBCPP_STD_VER >= 20 | |
| 99 | 101 | |
| 100 | 102 | _LIBCPP_END_NAMESPACE_STD |
| 101 | 103 |
lib/libcxx/include/__ranges/size.h+2-2| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 17 | |
| 33 | #if _LIBCPP_STD_VER >= 20 | |
| 34 | 34 | |
| 35 | 35 | namespace ranges { |
| 36 | 36 | template<class> |
| ... | ... | @@ -141,7 +141,7 @@ inline namespace __cpo { |
| 141 | 141 | } // namespace __cpo |
| 142 | 142 | } // namespace ranges |
| 143 | 143 | |
| 144 | #endif // _LIBCPP_STD_VER > 17 | |
| 144 | #endif // _LIBCPP_STD_VER >= 20 | |
| 145 | 145 | |
| 146 | 146 | _LIBCPP_END_NAMESPACE_STD |
| 147 | 147 |
lib/libcxx/include/__ranges/split_view.h+3-2| ... | ... | @@ -75,13 +75,14 @@ public: |
| 75 | 75 | requires default_initializable<_View> && default_initializable<_Pattern> |
| 76 | 76 | = default; |
| 77 | 77 | |
| 78 | _LIBCPP_HIDE_FROM_ABI constexpr split_view(_View __base, _Pattern __pattern) | |
| 78 | _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 split_view(_View __base, _Pattern __pattern) | |
| 79 | 79 | : __base_(std::move(__base)), __pattern_(std::move((__pattern))) {} |
| 80 | 80 | |
| 81 | 81 | template <forward_range _Range> |
| 82 | 82 | requires constructible_from<_View, views::all_t<_Range>> && |
| 83 | 83 | constructible_from<_Pattern, single_view<range_value_t<_Range>>> |
| 84 | _LIBCPP_HIDE_FROM_ABI constexpr split_view(_Range&& __range, range_value_t<_Range> __elem) | |
| 84 | _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 | |
| 85 | split_view(_Range&& __range, range_value_t<_Range> __elem) | |
| 85 | 86 | : __base_(views::all(std::forward<_Range>(__range))), __pattern_(views::single(std::move(__elem))) {} |
| 86 | 87 | |
| 87 | 88 | _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& |
lib/libcxx/include/__ranges/subrange.h+12-7| ... | ... | @@ -29,9 +29,9 @@ |
| 29 | 29 | #include <__ranges/enable_borrowed_range.h> |
| 30 | 30 | #include <__ranges/size.h> |
| 31 | 31 | #include <__ranges/view_interface.h> |
| 32 | #include <__tuple_dir/pair_like.h> | |
| 33 | #include <__tuple_dir/tuple_element.h> | |
| 34 | #include <__tuple_dir/tuple_size.h> | |
| 32 | #include <__tuple/pair_like.h> | |
| 33 | #include <__tuple/tuple_element.h> | |
| 34 | #include <__tuple/tuple_size.h> | |
| 35 | 35 | #include <__type_traits/conditional.h> |
| 36 | 36 | #include <__type_traits/decay.h> |
| 37 | 37 | #include <__type_traits/is_pointer.h> |
| ... | ... | @@ -46,9 +46,12 @@ |
| 46 | 46 | # pragma GCC system_header |
| 47 | 47 | #endif |
| 48 | 48 | |
| 49 | _LIBCPP_PUSH_MACROS | |
| 50 | #include <__undef_macros> | |
| 51 | ||
| 49 | 52 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 50 | 53 | |
| 51 | #if _LIBCPP_STD_VER > 17 | |
| 54 | #if _LIBCPP_STD_VER >= 20 | |
| 52 | 55 | |
| 53 | 56 | namespace ranges { |
| 54 | 57 | template<class _From, class _To> |
| ... | ... | @@ -82,7 +85,7 @@ namespace ranges { |
| 82 | 85 | |
| 83 | 86 | private: |
| 84 | 87 | static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics |
| 85 | struct _Empty { constexpr _Empty(auto) noexcept { } }; | |
| 88 | struct _Empty { _LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept { } }; | |
| 86 | 89 | using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>; |
| 87 | 90 | _LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter(); |
| 88 | 91 | _LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent(); |
| ... | ... | @@ -105,7 +108,7 @@ namespace ranges { |
| 105 | 108 | : __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n) |
| 106 | 109 | { |
| 107 | 110 | if constexpr (sized_sentinel_for<_Sent, _Iter>) |
| 108 | _LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n), | |
| 111 | _LIBCPP_ASSERT_UNCATEGORIZED((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n), | |
| 109 | 112 | "std::ranges::subrange was passed an invalid size hint"); |
| 110 | 113 | } |
| 111 | 114 | |
| ... | ... | @@ -284,8 +287,10 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> { |
| 284 | 287 | using type = _Sp; |
| 285 | 288 | }; |
| 286 | 289 | |
| 287 | #endif // _LIBCPP_STD_VER > 17 | |
| 290 | #endif // _LIBCPP_STD_VER >= 20 | |
| 288 | 291 | |
| 289 | 292 | _LIBCPP_END_NAMESPACE_STD |
| 290 | 293 | |
| 294 | _LIBCPP_POP_MACROS | |
| 295 | ||
| 291 | 296 | #endif // _LIBCPP___RANGES_SUBRANGE_H |
lib/libcxx/include/__ranges/take_view.h+38-5| ... | ... | @@ -31,14 +31,18 @@ |
| 31 | 31 | #include <__ranges/enable_borrowed_range.h> |
| 32 | 32 | #include <__ranges/iota_view.h> |
| 33 | 33 | #include <__ranges/range_adaptor.h> |
| 34 | #include <__ranges/repeat_view.h> | |
| 34 | 35 | #include <__ranges/size.h> |
| 35 | 36 | #include <__ranges/subrange.h> |
| 36 | 37 | #include <__ranges/view_interface.h> |
| 38 | #include <__type_traits/decay.h> | |
| 39 | #include <__type_traits/is_nothrow_constructible.h> | |
| 37 | 40 | #include <__type_traits/maybe_const.h> |
| 41 | #include <__type_traits/remove_cvref.h> | |
| 38 | 42 | #include <__utility/auto_cast.h> |
| 39 | 43 | #include <__utility/forward.h> |
| 40 | 44 | #include <__utility/move.h> |
| 41 | #include <type_traits> | |
| 45 | #include <cstddef> | |
| 42 | 46 | |
| 43 | 47 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 44 | 48 | # pragma GCC system_header |
| ... | ... | @@ -49,7 +53,7 @@ _LIBCPP_PUSH_MACROS |
| 49 | 53 | |
| 50 | 54 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 51 | 55 | |
| 52 | #if _LIBCPP_STD_VER > 17 | |
| 56 | #if _LIBCPP_STD_VER >= 20 | |
| 53 | 57 | |
| 54 | 58 | namespace ranges { |
| 55 | 59 | |
| ... | ... | @@ -64,9 +68,10 @@ public: |
| 64 | 68 | _LIBCPP_HIDE_FROM_ABI |
| 65 | 69 | take_view() requires default_initializable<_View> = default; |
| 66 | 70 | |
| 67 | _LIBCPP_HIDE_FROM_ABI constexpr take_view(_View __base, range_difference_t<_View> __count) | |
| 71 | _LIBCPP_HIDE_FROM_ABI | |
| 72 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_view(_View __base, range_difference_t<_View> __count) | |
| 68 | 73 | : __base_(std::move(__base)), __count_(__count) { |
| 69 | _LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero"); | |
| 74 | _LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to be greater than or equal to zero"); | |
| 70 | 75 | } |
| 71 | 76 | |
| 72 | 77 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -297,6 +302,31 @@ struct __fn { |
| 297 | 302 | *ranges::begin(__rng), |
| 298 | 303 | *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)) |
| 299 | 304 | ); } |
| 305 | // clang-format off | |
| 306 | #if _LIBCPP_STD_VER >= 23 | |
| 307 | // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case. | |
| 308 | template <class _Range, | |
| 309 | convertible_to<range_difference_t<_Range>> _Np, | |
| 310 | class _RawRange = remove_cvref_t<_Range>, | |
| 311 | class _Dist = range_difference_t<_Range>> | |
| 312 | requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>) | |
| 313 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const | |
| 314 | noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))) | |
| 315 | -> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))) | |
| 316 | { return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); } | |
| 317 | ||
| 318 | // [range.take.overview]: the `repeat_view` "otherwise" case. | |
| 319 | template <class _Range, | |
| 320 | convertible_to<range_difference_t<_Range>> _Np, | |
| 321 | class _RawRange = remove_cvref_t<_Range>, | |
| 322 | class _Dist = range_difference_t<_Range>> | |
| 323 | requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>) | |
| 324 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const | |
| 325 | noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n)))) | |
| 326 | -> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n))) | |
| 327 | { return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); } | |
| 328 | #endif | |
| 329 | // clang-format on | |
| 300 | 330 | |
| 301 | 331 | // [range.take.overview]: the "otherwise" case. |
| 302 | 332 | template <class _Range, convertible_to<range_difference_t<_Range>> _Np, |
| ... | ... | @@ -304,6 +334,9 @@ struct __fn { |
| 304 | 334 | // Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other |
| 305 | 335 | // overloads. |
| 306 | 336 | requires (!(__is_empty_view<_RawRange> || |
| 337 | #if _LIBCPP_STD_VER >= 23 | |
| 338 | __is_repeat_specialization<_RawRange> || | |
| 339 | #endif | |
| 307 | 340 | (__is_iota_specialization<_RawRange> && |
| 308 | 341 | sized_range<_RawRange> && |
| 309 | 342 | random_access_range<_RawRange>) || |
| ... | ... | @@ -334,7 +367,7 @@ inline namespace __cpo { |
| 334 | 367 | |
| 335 | 368 | } // namespace ranges |
| 336 | 369 | |
| 337 | #endif // _LIBCPP_STD_VER > 17 | |
| 370 | #endif // _LIBCPP_STD_VER >= 20 | |
| 338 | 371 | |
| 339 | 372 | _LIBCPP_END_NAMESPACE_STD |
| 340 | 373 |
lib/libcxx/include/__ranges/take_while_view.h+3-3| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | #include <__ranges/access.h> |
| 21 | 21 | #include <__ranges/all.h> |
| 22 | 22 | #include <__ranges/concepts.h> |
| 23 | #include <__ranges/copyable_box.h> | |
| 23 | #include <__ranges/movable_box.h> | |
| 24 | 24 | #include <__ranges/range_adaptor.h> |
| 25 | 25 | #include <__ranges/view_interface.h> |
| 26 | 26 | #include <__type_traits/decay.h> |
| ... | ... | @@ -60,14 +60,14 @@ class take_while_view : public view_interface<take_while_view<_View, _Pred>> { |
| 60 | 60 | class __sentinel; |
| 61 | 61 | |
| 62 | 62 | _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); |
| 63 | _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_; | |
| 63 | _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; | |
| 64 | 64 | |
| 65 | 65 | public: |
| 66 | 66 | _LIBCPP_HIDE_FROM_ABI take_while_view() |
| 67 | 67 | requires default_initializable<_View> && default_initializable<_Pred> |
| 68 | 68 | = default; |
| 69 | 69 | |
| 70 | _LIBCPP_HIDE_FROM_ABI constexpr take_while_view(_View __base, _Pred __pred) | |
| 70 | _LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_while_view(_View __base, _Pred __pred) | |
| 71 | 71 | : __base_(std::move(__base)), __pred_(std::in_place, std::move(__pred)) {} |
| 72 | 72 | |
| 73 | 73 | _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& |
lib/libcxx/include/__ranges/to.h created+247| ... | ... | @@ -0,0 +1,247 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___RANGES_TO_H | |
| 11 | #define _LIBCPP___RANGES_TO_H | |
| 12 | ||
| 13 | #include <__algorithm/ranges_copy.h> | |
| 14 | #include <__concepts/constructible.h> | |
| 15 | #include <__concepts/convertible_to.h> | |
| 16 | #include <__concepts/derived_from.h> | |
| 17 | #include <__concepts/same_as.h> | |
| 18 | #include <__config> | |
| 19 | #include <__functional/bind_back.h> | |
| 20 | #include <__iterator/back_insert_iterator.h> | |
| 21 | #include <__iterator/insert_iterator.h> | |
| 22 | #include <__iterator/iterator_traits.h> | |
| 23 | #include <__ranges/access.h> | |
| 24 | #include <__ranges/concepts.h> | |
| 25 | #include <__ranges/from_range.h> | |
| 26 | #include <__ranges/range_adaptor.h> | |
| 27 | #include <__ranges/size.h> | |
| 28 | #include <__ranges/transform_view.h> | |
| 29 | #include <__type_traits/add_pointer.h> | |
| 30 | #include <__type_traits/is_const.h> | |
| 31 | #include <__type_traits/is_volatile.h> | |
| 32 | #include <__type_traits/type_identity.h> | |
| 33 | #include <__utility/declval.h> | |
| 34 | #include <__utility/forward.h> | |
| 35 | #include <cstddef> | |
| 36 | ||
| 37 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 38 | # pragma GCC system_header | |
| 39 | #endif | |
| 40 | ||
| 41 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 42 | ||
| 43 | #if _LIBCPP_STD_VER >= 23 | |
| 44 | ||
| 45 | namespace ranges { | |
| 46 | ||
| 47 | // TODO(clang-15): in the Standard, it's a `constexpr bool` variable, not a concept, but constexpr variables don't | |
| 48 | // short-circuit properly on Clang 15 (fixed in later versions), so use a concept as a workaround. | |
| 49 | template <class _Container> | |
| 50 | concept __reservable_container = sized_range<_Container> && requires(_Container& __c, range_size_t<_Container> __n) { | |
| 51 | __c.reserve(__n); | |
| 52 | { __c.capacity() } -> same_as<decltype(__n)>; | |
| 53 | { __c.max_size() } -> same_as<decltype(__n)>; | |
| 54 | }; | |
| 55 | ||
| 56 | template <class _Container, class _Ref> | |
| 57 | constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) { | |
| 58 | requires( | |
| 59 | requires { __c.push_back(std::forward<_Ref>(__ref)); } || | |
| 60 | requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); }); | |
| 61 | }; | |
| 62 | ||
| 63 | template <class _Ref, class _Container> | |
| 64 | _LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) { | |
| 65 | if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) { | |
| 66 | return std::back_inserter(__c); | |
| 67 | } else { | |
| 68 | return std::inserter(__c, __c.end()); | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | // Note: making this a concept allows short-circuiting the second condition. | |
| 73 | template <class _Container, class _Range> | |
| 74 | concept __try_non_recursive_conversion = | |
| 75 | !input_range<_Container> || convertible_to<range_reference_t<_Range>, range_value_t<_Container>>; | |
| 76 | ||
| 77 | template <class _Container, class _Range, class... _Args> | |
| 78 | concept __constructible_from_iter_pair = | |
| 79 | common_range<_Range> && requires { typename iterator_traits<iterator_t<_Range>>::iterator_category; } && | |
| 80 | derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> && | |
| 81 | constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>; | |
| 82 | ||
| 83 | template <class> | |
| 84 | concept __always_false = false; | |
| 85 | ||
| 86 | // `ranges::to` base template -- the `_Container` type is a simple type template parameter. | |
| 87 | template <class _Container, input_range _Range, class... _Args> | |
| 88 | requires(!view<_Container>) | |
| 89 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) { | |
| 90 | // Mandates: C is a cv-unqualified class type. | |
| 91 | static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const"); | |
| 92 | static_assert( | |
| 93 | !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile"); | |
| 94 | ||
| 95 | // First see if the non-recursive case applies -- the conversion target is either: | |
| 96 | // - a range with a convertible value type; | |
| 97 | // - a non-range type which might support being created from the input argument(s) (e.g. an `optional`). | |
| 98 | if constexpr (__try_non_recursive_conversion<_Container, _Range>) { | |
| 99 | // Case 1 -- construct directly from the given range. | |
| 100 | if constexpr (constructible_from<_Container, _Range, _Args...>) { | |
| 101 | return _Container(std::forward<_Range>(__range), std::forward<_Args>(__args)...); | |
| 102 | } | |
| 103 | ||
| 104 | // Case 2 -- construct using the `from_range_t` tagged constructor. | |
| 105 | else if constexpr (constructible_from<_Container, from_range_t, _Range, _Args...>) { | |
| 106 | return _Container(from_range, std::forward<_Range>(__range), std::forward<_Args>(__args)...); | |
| 107 | } | |
| 108 | ||
| 109 | // Case 3 -- construct from a begin-end iterator pair. | |
| 110 | else if constexpr (__constructible_from_iter_pair<_Container, _Range, _Args...>) { | |
| 111 | return _Container(ranges::begin(__range), ranges::end(__range), std::forward<_Args>(__args)...); | |
| 112 | } | |
| 113 | ||
| 114 | // Case 4 -- default-construct (or construct from the extra arguments) and insert, reserving the size if possible. | |
| 115 | else if constexpr (constructible_from<_Container, _Args...> && | |
| 116 | __container_insertable<_Container, range_reference_t<_Range>>) { | |
| 117 | _Container __result(std::forward<_Args>(__args)...); | |
| 118 | if constexpr (sized_range<_Range> && __reservable_container<_Container>) { | |
| 119 | __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range))); | |
| 120 | } | |
| 121 | ||
| 122 | ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result)); | |
| 123 | ||
| 124 | return __result; | |
| 125 | ||
| 126 | } else { | |
| 127 | static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type."); | |
| 128 | } | |
| 129 | ||
| 130 | // Try the recursive case. | |
| 131 | } else if constexpr (input_range<range_reference_t<_Range>>) { | |
| 132 | return ranges::to<_Container>( | |
| 133 | __range | views::transform([](auto&& __elem) { | |
| 134 | return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem)); | |
| 135 | }), | |
| 136 | std::forward<_Args>(__args)...); | |
| 137 | ||
| 138 | } else { | |
| 139 | static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type."); | |
| 140 | } | |
| 141 | } | |
| 142 | ||
| 143 | template <class _Range> | |
| 144 | struct __minimal_input_iterator { | |
| 145 | using iterator_category = input_iterator_tag; | |
| 146 | using value_type = range_value_t<_Range>; | |
| 147 | using difference_type = ptrdiff_t; | |
| 148 | using pointer = add_pointer_t<range_reference_t<_Range>>; | |
| 149 | using reference = range_reference_t<_Range>; | |
| 150 | ||
| 151 | reference operator*() const; | |
| 152 | pointer operator->() const; | |
| 153 | __minimal_input_iterator& operator++(); | |
| 154 | __minimal_input_iterator operator++(int); | |
| 155 | bool operator==(const __minimal_input_iterator&) const; | |
| 156 | }; | |
| 157 | ||
| 158 | // Deduces the full type of the container from the given template template parameter. | |
| 159 | template <template <class...> class _Container, input_range _Range, class... _Args> | |
| 160 | struct _Deducer { | |
| 161 | _LIBCPP_HIDE_FROM_ABI static constexpr auto __deduce_func() { | |
| 162 | using _InputIter = __minimal_input_iterator<_Range>; | |
| 163 | ||
| 164 | // Case 1 -- can construct directly from the given range. | |
| 165 | if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) { | |
| 166 | using _Result = decltype( // | |
| 167 | _Container(std::declval<_Range>(), std::declval<_Args>()...)); | |
| 168 | return type_identity<_Result>{}; | |
| 169 | ||
| 170 | // Case 2 -- can construct from the given range using the `from_range_t` tagged constructor. | |
| 171 | } else if constexpr ( // | |
| 172 | requires { _Container(from_range, std::declval<_Range>(), std::declval<_Args>()...); }) { | |
| 173 | using _Result = // | |
| 174 | decltype(_Container(from_range, std::declval<_Range>(), std::declval<_Args>()...)); | |
| 175 | return type_identity<_Result>{}; | |
| 176 | ||
| 177 | // Case 3 -- can construct from a begin-end iterator pair. | |
| 178 | } else if constexpr ( // | |
| 179 | requires { _Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...); }) { | |
| 180 | using _Result = | |
| 181 | decltype(_Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...)); | |
| 182 | return type_identity<_Result>{}; | |
| 183 | ||
| 184 | } else { | |
| 185 | static_assert(__always_false<_Range>, | |
| 186 | "ranges::to: unable to deduce the container type from the template template argument."); | |
| 187 | } | |
| 188 | } | |
| 189 | ||
| 190 | using type = typename decltype(__deduce_func())::type; | |
| 191 | }; | |
| 192 | ||
| 193 | // `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the | |
| 194 | // container element type. | |
| 195 | template <template <class...> class _Container, input_range _Range, class... _Args> | |
| 196 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Range&& __range, _Args&&... __args) { | |
| 197 | using _DeduceExpr = typename _Deducer<_Container, _Range, _Args...>::type; | |
| 198 | return ranges::to<_DeduceExpr>(std::forward<_Range>(__range), std::forward<_Args>(__args)...); | |
| 199 | } | |
| 200 | ||
| 201 | // Range adaptor closure object 1 -- wrapping the `ranges::to` version where `_Container` is a simple type template | |
| 202 | // parameter. | |
| 203 | template <class _Container, class... _Args> | |
| 204 | requires(!view<_Container>) | |
| 205 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) { | |
| 206 | // Mandates: C is a cv-unqualified class type. | |
| 207 | static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const"); | |
| 208 | static_assert( | |
| 209 | !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile"); | |
| 210 | ||
| 211 | auto __to_func = []<input_range _Range, class... _Tail>(_Range && __range, _Tail && ... __tail) | |
| 212 | requires requires { // | |
| 213 | /**/ ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); | |
| 214 | } | |
| 215 | { | |
| 216 | return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); | |
| 217 | }; | |
| 218 | ||
| 219 | return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...)); | |
| 220 | } | |
| 221 | ||
| 222 | // Range adaptor closure object 2 -- wrapping the `ranges::to` version where `_Container` is a template template | |
| 223 | // parameter. | |
| 224 | template <template <class...> class _Container, class... _Args> | |
| 225 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) { | |
| 226 | // clang-format off | |
| 227 | auto __to_func = []<input_range _Range, class... _Tail, | |
| 228 | class _DeducedExpr = typename _Deducer<_Container, _Range, _Tail...>::type> | |
| 229 | (_Range&& __range, _Tail&& ... __tail) | |
| 230 | requires requires { // | |
| 231 | /**/ ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); | |
| 232 | } | |
| 233 | { | |
| 234 | return ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); | |
| 235 | }; | |
| 236 | // clang-format on | |
| 237 | ||
| 238 | return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...)); | |
| 239 | } | |
| 240 | ||
| 241 | } // namespace ranges | |
| 242 | ||
| 243 | #endif // _LIBCPP_STD_VER >= 23 | |
| 244 | ||
| 245 | _LIBCPP_END_NAMESPACE_STD | |
| 246 | ||
| 247 | #endif // _LIBCPP___RANGES_TO_H |
lib/libcxx/include/__ranges/transform_view.h+31-14| ... | ... | @@ -20,22 +20,28 @@ |
| 20 | 20 | #include <__config> |
| 21 | 21 | #include <__functional/bind_back.h> |
| 22 | 22 | #include <__functional/invoke.h> |
| 23 | #include <__functional/perfect_forward.h> | |
| 23 | 24 | #include <__iterator/concepts.h> |
| 24 | 25 | #include <__iterator/iterator_traits.h> |
| 25 | 26 | #include <__memory/addressof.h> |
| 26 | 27 | #include <__ranges/access.h> |
| 27 | 28 | #include <__ranges/all.h> |
| 28 | 29 | #include <__ranges/concepts.h> |
| 29 | #include <__ranges/copyable_box.h> | |
| 30 | 30 | #include <__ranges/empty.h> |
| 31 | #include <__ranges/movable_box.h> | |
| 31 | 32 | #include <__ranges/range_adaptor.h> |
| 32 | 33 | #include <__ranges/size.h> |
| 33 | 34 | #include <__ranges/view_interface.h> |
| 35 | #include <__type_traits/conditional.h> | |
| 36 | #include <__type_traits/decay.h> | |
| 37 | #include <__type_traits/is_nothrow_constructible.h> | |
| 38 | #include <__type_traits/is_object.h> | |
| 39 | #include <__type_traits/is_reference.h> | |
| 34 | 40 | #include <__type_traits/maybe_const.h> |
| 41 | #include <__type_traits/remove_cvref.h> | |
| 35 | 42 | #include <__utility/forward.h> |
| 36 | 43 | #include <__utility/in_place.h> |
| 37 | 44 | #include <__utility/move.h> |
| 38 | #include <type_traits> | |
| 39 | 45 | |
| 40 | 46 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 41 | 47 | # pragma GCC system_header |
| ... | ... | @@ -43,7 +49,7 @@ |
| 43 | 49 | |
| 44 | 50 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 45 | 51 | |
| 46 | #if _LIBCPP_STD_VER > 17 | |
| 52 | #if _LIBCPP_STD_VER >= 20 | |
| 47 | 53 | |
| 48 | 54 | namespace ranges { |
| 49 | 55 | |
| ... | ... | @@ -57,13 +63,17 @@ concept __transform_view_constraints = |
| 57 | 63 | regular_invocable<_Fn&, range_reference_t<_View>> && |
| 58 | 64 | __can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>; |
| 59 | 65 | |
| 60 | template<input_range _View, copy_constructible _Fn> | |
| 66 | # if _LIBCPP_STD_VER >= 23 | |
| 67 | template <input_range _View, move_constructible _Fn> | |
| 68 | # else | |
| 69 | template <input_range _View, copy_constructible _Fn> | |
| 70 | # endif | |
| 61 | 71 | requires __transform_view_constraints<_View, _Fn> |
| 62 | 72 | class transform_view : public view_interface<transform_view<_View, _Fn>> { |
| 63 | 73 | template<bool> class __iterator; |
| 64 | 74 | template<bool> class __sentinel; |
| 65 | 75 | |
| 66 | _LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_; | |
| 76 | _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __func_; | |
| 67 | 77 | _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); |
| 68 | 78 | |
| 69 | 79 | public: |
| ... | ... | @@ -72,7 +82,7 @@ public: |
| 72 | 82 | requires default_initializable<_View> && default_initializable<_Fn> = default; |
| 73 | 83 | |
| 74 | 84 | _LIBCPP_HIDE_FROM_ABI |
| 75 | constexpr transform_view(_View __base, _Fn __func) | |
| 85 | constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func) | |
| 76 | 86 | : __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {} |
| 77 | 87 | |
| 78 | 88 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -146,7 +156,7 @@ struct __transform_view_iterator_category_base<_View, _Fn> { |
| 146 | 156 | using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; |
| 147 | 157 | |
| 148 | 158 | using iterator_category = conditional_t< |
| 149 | is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>, | |
| 159 | is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>, | |
| 150 | 160 | conditional_t< |
| 151 | 161 | derived_from<_Cat, contiguous_iterator_tag>, |
| 152 | 162 | random_access_iterator_tag, |
| ... | ... | @@ -156,11 +166,14 @@ struct __transform_view_iterator_category_base<_View, _Fn> { |
| 156 | 166 | >; |
| 157 | 167 | }; |
| 158 | 168 | |
| 159 | template<input_range _View, copy_constructible _Fn> | |
| 169 | # if _LIBCPP_STD_VER >= 23 | |
| 170 | template <input_range _View, move_constructible _Fn> | |
| 171 | # else | |
| 172 | template <input_range _View, copy_constructible _Fn> | |
| 173 | # endif | |
| 160 | 174 | requires __transform_view_constraints<_View, _Fn> |
| 161 | template<bool _Const> | |
| 162 | class transform_view<_View, _Fn>::__iterator | |
| 163 | : public __transform_view_iterator_category_base<_View, _Fn> { | |
| 175 | template <bool _Const> | |
| 176 | class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn> { | |
| 164 | 177 | |
| 165 | 178 | using _Parent = __maybe_const<_Const, transform_view>; |
| 166 | 179 | using _Base = __maybe_const<_Const, _View>; |
| ... | ... | @@ -352,9 +365,13 @@ public: |
| 352 | 365 | } |
| 353 | 366 | }; |
| 354 | 367 | |
| 355 | template<input_range _View, copy_constructible _Fn> | |
| 368 | # if _LIBCPP_STD_VER >= 23 | |
| 369 | template <input_range _View, move_constructible _Fn> | |
| 370 | # else | |
| 371 | template <input_range _View, copy_constructible _Fn> | |
| 372 | # endif | |
| 356 | 373 | requires __transform_view_constraints<_View, _Fn> |
| 357 | template<bool _Const> | |
| 374 | template <bool _Const> | |
| 358 | 375 | class transform_view<_View, _Fn>::__sentinel { |
| 359 | 376 | using _Parent = __maybe_const<_Const, transform_view>; |
| 360 | 377 | using _Base = __maybe_const<_Const, _View>; |
| ... | ... | @@ -435,7 +452,7 @@ inline namespace __cpo { |
| 435 | 452 | |
| 436 | 453 | } // namespace ranges |
| 437 | 454 | |
| 438 | #endif // _LIBCPP_STD_VER > 17 | |
| 455 | #endif // _LIBCPP_STD_VER >= 20 | |
| 439 | 456 | |
| 440 | 457 | _LIBCPP_END_NAMESPACE_STD |
| 441 | 458 |
lib/libcxx/include/__ranges/view_interface.h+6-6| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | |
| 36 | 36 | namespace ranges { |
| 37 | 37 | |
| ... | ... | @@ -118,7 +118,7 @@ public: |
| 118 | 118 | constexpr decltype(auto) front() |
| 119 | 119 | requires forward_range<_D2> |
| 120 | 120 | { |
| 121 | _LIBCPP_ASSERT(!empty(), | |
| 121 | _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), | |
| 122 | 122 | "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); |
| 123 | 123 | return *ranges::begin(__derived()); |
| 124 | 124 | } |
| ... | ... | @@ -128,7 +128,7 @@ public: |
| 128 | 128 | constexpr decltype(auto) front() const |
| 129 | 129 | requires forward_range<const _D2> |
| 130 | 130 | { |
| 131 | _LIBCPP_ASSERT(!empty(), | |
| 131 | _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), | |
| 132 | 132 | "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); |
| 133 | 133 | return *ranges::begin(__derived()); |
| 134 | 134 | } |
| ... | ... | @@ -138,7 +138,7 @@ public: |
| 138 | 138 | constexpr decltype(auto) back() |
| 139 | 139 | requires bidirectional_range<_D2> && common_range<_D2> |
| 140 | 140 | { |
| 141 | _LIBCPP_ASSERT(!empty(), | |
| 141 | _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), | |
| 142 | 142 | "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); |
| 143 | 143 | return *ranges::prev(ranges::end(__derived())); |
| 144 | 144 | } |
| ... | ... | @@ -148,7 +148,7 @@ public: |
| 148 | 148 | constexpr decltype(auto) back() const |
| 149 | 149 | requires bidirectional_range<const _D2> && common_range<const _D2> |
| 150 | 150 | { |
| 151 | _LIBCPP_ASSERT(!empty(), | |
| 151 | _LIBCPP_ASSERT_UNCATEGORIZED(!empty(), | |
| 152 | 152 | "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); |
| 153 | 153 | return *ranges::prev(ranges::end(__derived())); |
| 154 | 154 | } |
| ... | ... | @@ -170,7 +170,7 @@ public: |
| 170 | 170 | |
| 171 | 171 | } // namespace ranges |
| 172 | 172 | |
| 173 | #endif // _LIBCPP_STD_VER > 17 | |
| 173 | #endif // _LIBCPP_STD_VER >= 20 | |
| 174 | 174 | |
| 175 | 175 | _LIBCPP_END_NAMESPACE_STD |
| 176 | 176 |
lib/libcxx/include/__ranges/views.h+2-2| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 17 | |
| 21 | #if _LIBCPP_STD_VER >= 20 | |
| 22 | 22 | |
| 23 | 23 | namespace ranges { |
| 24 | 24 | |
| ... | ... | @@ -28,7 +28,7 @@ namespace views { } |
| 28 | 28 | |
| 29 | 29 | namespace views = ranges::views; |
| 30 | 30 | |
| 31 | #endif // _LIBCPP_STD_VER > 17 | |
| 31 | #endif // _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | |
| 33 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 34 |
lib/libcxx/include/__ranges/zip_view.h+8-4| ... | ... | @@ -30,11 +30,13 @@ |
| 30 | 30 | #include <__ranges/enable_borrowed_range.h> |
| 31 | 31 | #include <__ranges/size.h> |
| 32 | 32 | #include <__ranges/view_interface.h> |
| 33 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 34 | #include <__type_traits/make_unsigned.h> | |
| 35 | #include <__utility/declval.h> | |
| 33 | 36 | #include <__utility/forward.h> |
| 34 | 37 | #include <__utility/integer_sequence.h> |
| 35 | 38 | #include <__utility/move.h> |
| 36 | 39 | #include <tuple> |
| 37 | #include <type_traits> | |
| 38 | 40 | |
| 39 | 41 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 40 | 42 | # pragma GCC system_header |
| ... | ... | @@ -45,7 +47,7 @@ _LIBCPP_PUSH_MACROS |
| 45 | 47 | |
| 46 | 48 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 47 | 49 | |
| 48 | #if _LIBCPP_STD_VER > 20 | |
| 50 | #if _LIBCPP_STD_VER >= 23 | |
| 49 | 51 | |
| 50 | 52 | namespace ranges { |
| 51 | 53 | |
| ... | ... | @@ -77,7 +79,9 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tu |
| 77 | 79 | template <class _Fun, class _Tuple> |
| 78 | 80 | _LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tuple) { |
| 79 | 81 | std::apply( |
| 80 | [&]<class... _Types>(_Types&&... __elements) { (std::invoke(__f, std::forward<_Types>(__elements)), ...); }, | |
| 82 | [&]<class... _Types>(_Types&&... __elements) { | |
| 83 | (static_cast<void>(std::invoke(__f, std::forward<_Types>(__elements))), ...); | |
| 84 | }, | |
| 81 | 85 | std::forward<_Tuple>(__tuple)); |
| 82 | 86 | } |
| 83 | 87 | |
| ... | ... | @@ -503,7 +507,7 @@ inline namespace __cpo { |
| 503 | 507 | } // namespace views |
| 504 | 508 | } // namespace ranges |
| 505 | 509 | |
| 506 | #endif // _LIBCPP_STD_VER > 20 | |
| 510 | #endif // _LIBCPP_STD_VER >= 23 | |
| 507 | 511 | |
| 508 | 512 | _LIBCPP_END_NAMESPACE_STD |
| 509 | 513 |
lib/libcxx/include/__split_buffer+193-162| ... | ... | @@ -23,9 +23,18 @@ |
| 23 | 23 | #include <__memory/compressed_pair.h> |
| 24 | 24 | #include <__memory/pointer_traits.h> |
| 25 | 25 | #include <__memory/swap_allocator.h> |
| 26 | #include <__type_traits/add_lvalue_reference.h> | |
| 27 | #include <__type_traits/enable_if.h> | |
| 28 | #include <__type_traits/integral_constant.h> | |
| 29 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 30 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 31 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 32 | #include <__type_traits/is_swappable.h> | |
| 33 | #include <__type_traits/is_trivially_destructible.h> | |
| 34 | #include <__type_traits/remove_reference.h> | |
| 26 | 35 | #include <__utility/forward.h> |
| 27 | 36 | #include <__utility/move.h> |
| 28 | #include <type_traits> | |
| 37 | #include <cstddef> | |
| 29 | 38 | |
| 30 | 39 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 31 | 40 | # pragma GCC system_header |
| ... | ... | @@ -44,139 +53,173 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 44 | 53 | template <class _Tp, class _Allocator = allocator<_Tp> > |
| 45 | 54 | struct __split_buffer |
| 46 | 55 | { |
| 47 | private: | |
| 48 | __split_buffer(const __split_buffer&); | |
| 49 | __split_buffer& operator=(const __split_buffer&); | |
| 50 | 56 | public: |
| 51 | typedef _Tp value_type; | |
| 52 | typedef _Allocator allocator_type; | |
| 53 | typedef __libcpp_remove_reference_t<allocator_type> __alloc_rr; | |
| 54 | typedef allocator_traits<__alloc_rr> __alloc_traits; | |
| 55 | typedef value_type& reference; | |
| 56 | typedef const value_type& const_reference; | |
| 57 | typedef typename __alloc_traits::size_type size_type; | |
| 58 | typedef typename __alloc_traits::difference_type difference_type; | |
| 59 | typedef typename __alloc_traits::pointer pointer; | |
| 60 | typedef typename __alloc_traits::const_pointer const_pointer; | |
| 61 | typedef pointer iterator; | |
| 62 | typedef const_pointer const_iterator; | |
| 63 | ||
| 64 | pointer __first_; | |
| 65 | pointer __begin_; | |
| 66 | pointer __end_; | |
| 67 | __compressed_pair<pointer, allocator_type> __end_cap_; | |
| 68 | ||
| 69 | typedef __add_lvalue_reference_t<allocator_type> __alloc_ref; | |
| 70 | typedef __add_lvalue_reference_t<allocator_type> __alloc_const_ref; | |
| 71 | ||
| 72 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();} | |
| 73 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();} | |
| 74 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();} | |
| 75 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();} | |
| 76 | ||
| 77 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 78 | __split_buffer() | |
| 79 | _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); | |
| 80 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 81 | explicit __split_buffer(__alloc_rr& __a); | |
| 82 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 83 | explicit __split_buffer(const __alloc_rr& __a); | |
| 84 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); | |
| 85 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer(); | |
| 86 | ||
| 87 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c) | |
| 88 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); | |
| 89 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); | |
| 90 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c) | |
| 91 | _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && | |
| 92 | is_nothrow_move_assignable<allocator_type>::value) || | |
| 93 | !__alloc_traits::propagate_on_container_move_assignment::value); | |
| 94 | ||
| 95 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT {return __begin_;} | |
| 96 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT {return __begin_;} | |
| 97 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT {return __end_;} | |
| 98 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT {return __end_;} | |
| 99 | ||
| 100 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 101 | void clear() _NOEXCEPT | |
| 102 | {__destruct_at_end(__begin_);} | |
| 103 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {return static_cast<size_type>(__end_ - __begin_);} | |
| 104 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const {return __end_ == __begin_;} | |
| 105 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);} | |
| 106 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);} | |
| 107 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);} | |
| 108 | ||
| 109 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() {return *__begin_;} | |
| 110 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const {return *__begin_;} | |
| 111 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() {return *(__end_ - 1);} | |
| 112 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const {return *(__end_ - 1);} | |
| 113 | ||
| 114 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n); | |
| 115 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; | |
| 116 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x); | |
| 117 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x); | |
| 118 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x); | |
| 119 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); | |
| 120 | template <class... _Args> | |
| 121 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); | |
| 122 | ||
| 123 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() {__destruct_at_begin(__begin_+1);} | |
| 124 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() {__destruct_at_end(__end_-1);} | |
| 125 | ||
| 126 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n); | |
| 127 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x); | |
| 128 | template <class _InputIter> | |
| 129 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value> | |
| 130 | __construct_at_end(_InputIter __first, _InputIter __last); | |
| 131 | template <class _ForwardIterator> | |
| 132 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value> | |
| 133 | __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); | |
| 134 | ||
| 135 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) | |
| 136 | {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());} | |
| 137 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 138 | void __destruct_at_begin(pointer __new_begin, false_type); | |
| 139 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 140 | void __destruct_at_begin(pointer __new_begin, true_type); | |
| 141 | ||
| 142 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 143 | void __destruct_at_end(pointer __new_last) _NOEXCEPT | |
| 144 | {__destruct_at_end(__new_last, false_type());} | |
| 145 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 146 | void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; | |
| 147 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 148 | void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; | |
| 149 | ||
| 150 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x) | |
| 151 | _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| | |
| 152 | __is_nothrow_swappable<__alloc_rr>::value); | |
| 57 | using value_type = _Tp; | |
| 58 | using allocator_type = _Allocator; | |
| 59 | using __alloc_rr = __libcpp_remove_reference_t<allocator_type>; | |
| 60 | using __alloc_traits = allocator_traits<__alloc_rr>; | |
| 61 | using reference = value_type&; | |
| 62 | using const_reference = const value_type&; | |
| 63 | using size_type = typename __alloc_traits::size_type; | |
| 64 | using difference_type = typename __alloc_traits::difference_type; | |
| 65 | using pointer = typename __alloc_traits::pointer; | |
| 66 | using const_pointer = typename __alloc_traits::const_pointer; | |
| 67 | using iterator = pointer; | |
| 68 | using const_iterator = const_pointer; | |
| 69 | ||
| 70 | pointer __first_; | |
| 71 | pointer __begin_; | |
| 72 | pointer __end_; | |
| 73 | __compressed_pair<pointer, allocator_type> __end_cap_; | |
| 74 | ||
| 75 | using __alloc_ref = __add_lvalue_reference_t<allocator_type>; | |
| 76 | using __alloc_const_ref = __add_lvalue_reference_t<allocator_type>; | |
| 77 | ||
| 78 | __split_buffer(const __split_buffer&) = delete; | |
| 79 | __split_buffer& operator=(const __split_buffer&) = delete; | |
| 80 | ||
| 81 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer() | |
| 82 | _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) | |
| 83 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) {} | |
| 84 | ||
| 85 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a) | |
| 86 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {} | |
| 87 | ||
| 88 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a) | |
| 89 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {} | |
| 90 | ||
| 91 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 92 | __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); | |
| 93 | ||
| 94 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c) | |
| 95 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); | |
| 96 | ||
| 97 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); | |
| 98 | ||
| 99 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c) | |
| 100 | _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && | |
| 101 | is_nothrow_move_assignable<allocator_type>::value) || | |
| 102 | !__alloc_traits::propagate_on_container_move_assignment::value); | |
| 103 | ||
| 104 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer(); | |
| 105 | ||
| 106 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __end_cap_.second(); } | |
| 107 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT { | |
| 108 | return __end_cap_.second(); | |
| 109 | } | |
| 110 | ||
| 111 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_.first(); } | |
| 112 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT { | |
| 113 | return __end_cap_.first(); | |
| 114 | } | |
| 115 | ||
| 116 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; } | |
| 117 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; } | |
| 118 | ||
| 119 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; } | |
| 120 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; } | |
| 121 | ||
| 122 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); } | |
| 123 | ||
| 124 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const { | |
| 125 | return static_cast<size_type>(__end_ - __begin_); | |
| 126 | } | |
| 127 | ||
| 128 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; } | |
| 129 | ||
| 130 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const { | |
| 131 | return static_cast<size_type>(__end_cap() - __first_); | |
| 132 | } | |
| 133 | ||
| 134 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const { | |
| 135 | return static_cast<size_type>(__begin_ - __first_); | |
| 136 | } | |
| 137 | ||
| 138 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const { | |
| 139 | return static_cast<size_type>(__end_cap() - __end_); | |
| 140 | } | |
| 141 | ||
| 142 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; } | |
| 143 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; } | |
| 144 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); } | |
| 145 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); } | |
| 146 | ||
| 147 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n); | |
| 148 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT; | |
| 149 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x); | |
| 150 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x); | |
| 151 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x); | |
| 152 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); | |
| 153 | ||
| 154 | template <class... _Args> | |
| 155 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); | |
| 156 | ||
| 157 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); } | |
| 158 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); } | |
| 159 | ||
| 160 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n); | |
| 161 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x); | |
| 162 | ||
| 163 | template <class _InputIter> | |
| 164 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 165 | __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value> | |
| 166 | __construct_at_end(_InputIter __first, _InputIter __last); | |
| 167 | ||
| 168 | template <class _ForwardIterator> | |
| 169 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 170 | __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value> | |
| 171 | __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); | |
| 172 | ||
| 173 | template <class _Iterator, class _Sentinel> | |
| 174 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 175 | void __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last); | |
| 176 | ||
| 177 | template <class _Iterator> | |
| 178 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 179 | void __construct_at_end_with_size(_Iterator __first, size_type __n); | |
| 180 | ||
| 181 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) { | |
| 182 | __destruct_at_begin(__new_begin, is_trivially_destructible<value_type>()); | |
| 183 | } | |
| 184 | ||
| 185 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, false_type); | |
| 186 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, true_type); | |
| 187 | ||
| 188 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT { | |
| 189 | __destruct_at_end(__new_last, false_type()); | |
| 190 | } | |
| 191 | ||
| 192 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; | |
| 193 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; | |
| 153 | 194 | |
| 154 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; | |
| 195 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x) | |
| 196 | _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__alloc_rr>::value); | |
| 197 | ||
| 198 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; | |
| 155 | 199 | |
| 156 | 200 | private: |
| 157 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 158 | void __move_assign_alloc(__split_buffer& __c, true_type) | |
| 159 | _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) | |
| 160 | { | |
| 161 | __alloc() = _VSTD::move(__c.__alloc()); | |
| 162 | } | |
| 201 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type) | |
| 202 | _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) { | |
| 203 | __alloc() = _VSTD::move(__c.__alloc()); | |
| 204 | } | |
| 205 | ||
| 206 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {} | |
| 207 | ||
| 208 | struct _ConstructTransaction { | |
| 209 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction( | |
| 210 | pointer* __p, size_type __n) _NOEXCEPT | |
| 211 | : __pos_(*__p), | |
| 212 | __end_(*__p + __n), | |
| 213 | __dest_(__p) {} | |
| 163 | 214 | |
| 164 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 165 | void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT | |
| 166 | {} | |
| 167 | ||
| 168 | struct _ConstructTransaction { | |
| 169 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT | |
| 170 | : __pos_(*__p), __end_(*__p + __n), __dest_(__p) { | |
| 171 | } | |
| 172 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { | |
| 173 | *__dest_ = __pos_; | |
| 174 | } | |
| 175 | pointer __pos_; | |
| 176 | const pointer __end_; | |
| 177 | private: | |
| 178 | pointer *__dest_; | |
| 179 | }; | |
| 215 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; } | |
| 216 | ||
| 217 | pointer __pos_; | |
| 218 | const pointer __end_; | |
| 219 | ||
| 220 | private: | |
| 221 | pointer* __dest_; | |
| 222 | }; | |
| 180 | 223 | }; |
| 181 | 224 | |
| 182 | 225 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -241,9 +284,16 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_referen |
| 241 | 284 | |
| 242 | 285 | template <class _Tp, class _Allocator> |
| 243 | 286 | template <class _InputIter> |
| 244 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIter>::value> | |
| 287 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value> | |
| 245 | 288 | __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) |
| 246 | 289 | { |
| 290 | __construct_at_end_with_sentinel(__first, __last); | |
| 291 | } | |
| 292 | ||
| 293 | template <class _Tp, class _Allocator> | |
| 294 | template <class _Iterator, class _Sentinel> | |
| 295 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 296 | void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) { | |
| 247 | 297 | __alloc_rr& __a = this->__alloc(); |
| 248 | 298 | for (; __first != __last; ++__first) |
| 249 | 299 | { |
| ... | ... | @@ -261,13 +311,19 @@ __split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIt |
| 261 | 311 | ++this->__end_; |
| 262 | 312 | } |
| 263 | 313 | } |
| 264 | ||
| 265 | 314 | template <class _Tp, class _Allocator> |
| 266 | 315 | template <class _ForwardIterator> |
| 267 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value> | |
| 316 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value> | |
| 268 | 317 | __split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) |
| 269 | 318 | { |
| 270 | _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last)); | |
| 319 | __construct_at_end_with_size(__first, std::distance(__first, __last)); | |
| 320 | } | |
| 321 | ||
| 322 | template <class _Tp, class _Allocator> | |
| 323 | template <class _ForwardIterator> | |
| 324 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 325 | void __split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) { | |
| 326 | _ConstructTransaction __tx(&this->__end_, __n); | |
| 271 | 327 | for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void) ++__first) { |
| 272 | 328 | __alloc_traits::construct(this->__alloc(), |
| 273 | 329 | _VSTD::__to_address(__tx.__pos_), *__first); |
| ... | ... | @@ -328,31 +384,6 @@ __split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __sta |
| 328 | 384 | __end_cap() = __first_ + __cap; |
| 329 | 385 | } |
| 330 | 386 | |
| 331 | template <class _Tp, class _Allocator> | |
| 332 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 333 | inline | |
| 334 | __split_buffer<_Tp, _Allocator>::__split_buffer() | |
| 335 | _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) | |
| 336 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) | |
| 337 | { | |
| 338 | } | |
| 339 | ||
| 340 | template <class _Tp, class _Allocator> | |
| 341 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 342 | inline | |
| 343 | __split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) | |
| 344 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) | |
| 345 | { | |
| 346 | } | |
| 347 | ||
| 348 | template <class _Tp, class _Allocator> | |
| 349 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 350 | inline | |
| 351 | __split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) | |
| 352 | : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) | |
| 353 | { | |
| 354 | } | |
| 355 | ||
| 356 | 387 | template <class _Tp, class _Allocator> |
| 357 | 388 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 358 | 389 | __split_buffer<_Tp, _Allocator>::~__split_buffer() |
| ... | ... | @@ -463,10 +494,10 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT |
| 463 | 494 | { |
| 464 | 495 | if (capacity() > size()) |
| 465 | 496 | { |
| 466 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 497 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 467 | 498 | try |
| 468 | 499 | { |
| 469 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 500 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 470 | 501 | __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc()); |
| 471 | 502 | __t.__construct_at_end(move_iterator<pointer>(__begin_), |
| 472 | 503 | move_iterator<pointer>(__end_)); |
| ... | ... | @@ -475,12 +506,12 @@ __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT |
| 475 | 506 | _VSTD::swap(__begin_, __t.__begin_); |
| 476 | 507 | _VSTD::swap(__end_, __t.__end_); |
| 477 | 508 | _VSTD::swap(__end_cap(), __t.__end_cap()); |
| 478 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 509 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 479 | 510 | } |
| 480 | 511 | catch (...) |
| 481 | 512 | { |
| 482 | 513 | } |
| 483 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 514 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 484 | 515 | } |
| 485 | 516 | } |
| 486 | 517 |
lib/libcxx/include/__std_mbstate_t.h created+29| ... | ... | @@ -0,0 +1,29 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STD_MBSTATE_T_H | |
| 11 | #define _LIBCPP___STD_MBSTATE_T_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__mbstate_t.h> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | // The goal of this header is to provide std::mbstate_t without requiring all | |
| 21 | // of <cuchar> or <cwchar>. | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | using ::mbstate_t _LIBCPP_USING_IF_EXISTS; | |
| 26 | ||
| 27 | _LIBCPP_END_NAMESPACE_STD | |
| 28 | ||
| 29 | #endif // _LIBCPP___STD_MBSTATE_T_H |
lib/libcxx/include/__std_stream deleted-361| ... | ... | @@ -1,361 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STD_STREAM | |
| 11 | #define _LIBCPP___STD_STREAM | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__locale> | |
| 15 | #include <cstdio> | |
| 16 | #include <istream> | |
| 17 | #include <ostream> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_PUSH_MACROS | |
| 24 | #include <__undef_macros> | |
| 25 | ||
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | static const int __limit = 8; | |
| 30 | ||
| 31 | // __stdinbuf | |
| 32 | ||
| 33 | template <class _CharT> | |
| 34 | class _LIBCPP_HIDDEN __stdinbuf | |
| 35 | : public basic_streambuf<_CharT, char_traits<_CharT> > | |
| 36 | { | |
| 37 | public: | |
| 38 | typedef _CharT char_type; | |
| 39 | typedef char_traits<char_type> traits_type; | |
| 40 | typedef typename traits_type::int_type int_type; | |
| 41 | typedef typename traits_type::pos_type pos_type; | |
| 42 | typedef typename traits_type::off_type off_type; | |
| 43 | typedef typename traits_type::state_type state_type; | |
| 44 | ||
| 45 | __stdinbuf(FILE* __fp, state_type* __st); | |
| 46 | ||
| 47 | protected: | |
| 48 | virtual int_type underflow(); | |
| 49 | virtual int_type uflow(); | |
| 50 | virtual int_type pbackfail(int_type __c = traits_type::eof()); | |
| 51 | virtual void imbue(const locale& __loc); | |
| 52 | ||
| 53 | private: | |
| 54 | ||
| 55 | FILE* __file_; | |
| 56 | const codecvt<char_type, char, state_type>* __cv_; | |
| 57 | state_type* __st_; | |
| 58 | int __encoding_; | |
| 59 | int_type __last_consumed_; | |
| 60 | bool __last_consumed_is_next_; | |
| 61 | bool __always_noconv_; | |
| 62 | ||
| 63 | __stdinbuf(const __stdinbuf&); | |
| 64 | __stdinbuf& operator=(const __stdinbuf&); | |
| 65 | ||
| 66 | int_type __getchar(bool __consume); | |
| 67 | }; | |
| 68 | ||
| 69 | template <class _CharT> | |
| 70 | __stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st) | |
| 71 | : __file_(__fp), | |
| 72 | __st_(__st), | |
| 73 | __last_consumed_(traits_type::eof()), | |
| 74 | __last_consumed_is_next_(false) | |
| 75 | { | |
| 76 | imbue(this->getloc()); | |
| 77 | } | |
| 78 | ||
| 79 | template <class _CharT> | |
| 80 | void | |
| 81 | __stdinbuf<_CharT>::imbue(const locale& __loc) | |
| 82 | { | |
| 83 | __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc); | |
| 84 | __encoding_ = __cv_->encoding(); | |
| 85 | __always_noconv_ = __cv_->always_noconv(); | |
| 86 | if (__encoding_ > __limit) | |
| 87 | __throw_runtime_error("unsupported locale for standard input"); | |
| 88 | } | |
| 89 | ||
| 90 | template <class _CharT> | |
| 91 | typename __stdinbuf<_CharT>::int_type | |
| 92 | __stdinbuf<_CharT>::underflow() | |
| 93 | { | |
| 94 | return __getchar(false); | |
| 95 | } | |
| 96 | ||
| 97 | template <class _CharT> | |
| 98 | typename __stdinbuf<_CharT>::int_type | |
| 99 | __stdinbuf<_CharT>::uflow() | |
| 100 | { | |
| 101 | return __getchar(true); | |
| 102 | } | |
| 103 | ||
| 104 | template <class _CharT> | |
| 105 | typename __stdinbuf<_CharT>::int_type | |
| 106 | __stdinbuf<_CharT>::__getchar(bool __consume) | |
| 107 | { | |
| 108 | if (__last_consumed_is_next_) | |
| 109 | { | |
| 110 | int_type __result = __last_consumed_; | |
| 111 | if (__consume) | |
| 112 | { | |
| 113 | __last_consumed_ = traits_type::eof(); | |
| 114 | __last_consumed_is_next_ = false; | |
| 115 | } | |
| 116 | return __result; | |
| 117 | } | |
| 118 | char __extbuf[__limit]; | |
| 119 | int __nread = _VSTD::max(1, __encoding_); | |
| 120 | for (int __i = 0; __i < __nread; ++__i) | |
| 121 | { | |
| 122 | int __c = getc(__file_); | |
| 123 | if (__c == EOF) | |
| 124 | return traits_type::eof(); | |
| 125 | __extbuf[__i] = static_cast<char>(__c); | |
| 126 | } | |
| 127 | char_type __1buf; | |
| 128 | if (__always_noconv_) | |
| 129 | __1buf = static_cast<char_type>(__extbuf[0]); | |
| 130 | else | |
| 131 | { | |
| 132 | const char* __enxt; | |
| 133 | char_type* __inxt; | |
| 134 | codecvt_base::result __r; | |
| 135 | do | |
| 136 | { | |
| 137 | state_type __sv_st = *__st_; | |
| 138 | __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt, | |
| 139 | &__1buf, &__1buf + 1, __inxt); | |
| 140 | switch (__r) | |
| 141 | { | |
| 142 | case _VSTD::codecvt_base::ok: | |
| 143 | break; | |
| 144 | case codecvt_base::partial: | |
| 145 | *__st_ = __sv_st; | |
| 146 | if (__nread == sizeof(__extbuf)) | |
| 147 | return traits_type::eof(); | |
| 148 | { | |
| 149 | int __c = getc(__file_); | |
| 150 | if (__c == EOF) | |
| 151 | return traits_type::eof(); | |
| 152 | __extbuf[__nread] = static_cast<char>(__c); | |
| 153 | } | |
| 154 | ++__nread; | |
| 155 | break; | |
| 156 | case codecvt_base::error: | |
| 157 | return traits_type::eof(); | |
| 158 | case _VSTD::codecvt_base::noconv: | |
| 159 | __1buf = static_cast<char_type>(__extbuf[0]); | |
| 160 | break; | |
| 161 | } | |
| 162 | } while (__r == _VSTD::codecvt_base::partial); | |
| 163 | } | |
| 164 | if (!__consume) | |
| 165 | { | |
| 166 | for (int __i = __nread; __i > 0;) | |
| 167 | { | |
| 168 | if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF) | |
| 169 | return traits_type::eof(); | |
| 170 | } | |
| 171 | } | |
| 172 | else | |
| 173 | __last_consumed_ = traits_type::to_int_type(__1buf); | |
| 174 | return traits_type::to_int_type(__1buf); | |
| 175 | } | |
| 176 | ||
| 177 | template <class _CharT> | |
| 178 | typename __stdinbuf<_CharT>::int_type | |
| 179 | __stdinbuf<_CharT>::pbackfail(int_type __c) | |
| 180 | { | |
| 181 | if (traits_type::eq_int_type(__c, traits_type::eof())) | |
| 182 | { | |
| 183 | if (!__last_consumed_is_next_) | |
| 184 | { | |
| 185 | __c = __last_consumed_; | |
| 186 | __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_, | |
| 187 | traits_type::eof()); | |
| 188 | } | |
| 189 | return __c; | |
| 190 | } | |
| 191 | if (__last_consumed_is_next_) | |
| 192 | { | |
| 193 | char __extbuf[__limit]; | |
| 194 | char* __enxt; | |
| 195 | const char_type __ci = traits_type::to_char_type(__last_consumed_); | |
| 196 | const char_type* __inxt; | |
| 197 | switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt, | |
| 198 | __extbuf, __extbuf + sizeof(__extbuf), __enxt)) | |
| 199 | { | |
| 200 | case _VSTD::codecvt_base::ok: | |
| 201 | break; | |
| 202 | case _VSTD::codecvt_base::noconv: | |
| 203 | __extbuf[0] = static_cast<char>(__last_consumed_); | |
| 204 | __enxt = __extbuf + 1; | |
| 205 | break; | |
| 206 | case codecvt_base::partial: | |
| 207 | case codecvt_base::error: | |
| 208 | return traits_type::eof(); | |
| 209 | } | |
| 210 | while (__enxt > __extbuf) | |
| 211 | if (ungetc(*--__enxt, __file_) == EOF) | |
| 212 | return traits_type::eof(); | |
| 213 | } | |
| 214 | __last_consumed_ = __c; | |
| 215 | __last_consumed_is_next_ = true; | |
| 216 | return __c; | |
| 217 | } | |
| 218 | ||
| 219 | // __stdoutbuf | |
| 220 | ||
| 221 | template <class _CharT> | |
| 222 | class _LIBCPP_HIDDEN __stdoutbuf | |
| 223 | : public basic_streambuf<_CharT, char_traits<_CharT> > | |
| 224 | { | |
| 225 | public: | |
| 226 | typedef _CharT char_type; | |
| 227 | typedef char_traits<char_type> traits_type; | |
| 228 | typedef typename traits_type::int_type int_type; | |
| 229 | typedef typename traits_type::pos_type pos_type; | |
| 230 | typedef typename traits_type::off_type off_type; | |
| 231 | typedef typename traits_type::state_type state_type; | |
| 232 | ||
| 233 | __stdoutbuf(FILE* __fp, state_type* __st); | |
| 234 | ||
| 235 | protected: | |
| 236 | virtual int_type overflow (int_type __c = traits_type::eof()); | |
| 237 | virtual streamsize xsputn(const char_type* __s, streamsize __n); | |
| 238 | virtual int sync(); | |
| 239 | virtual void imbue(const locale& __loc); | |
| 240 | ||
| 241 | private: | |
| 242 | FILE* __file_; | |
| 243 | const codecvt<char_type, char, state_type>* __cv_; | |
| 244 | state_type* __st_; | |
| 245 | bool __always_noconv_; | |
| 246 | ||
| 247 | __stdoutbuf(const __stdoutbuf&); | |
| 248 | __stdoutbuf& operator=(const __stdoutbuf&); | |
| 249 | }; | |
| 250 | ||
| 251 | template <class _CharT> | |
| 252 | __stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st) | |
| 253 | : __file_(__fp), | |
| 254 | __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())), | |
| 255 | __st_(__st), | |
| 256 | __always_noconv_(__cv_->always_noconv()) | |
| 257 | { | |
| 258 | } | |
| 259 | ||
| 260 | template <class _CharT> | |
| 261 | typename __stdoutbuf<_CharT>::int_type | |
| 262 | __stdoutbuf<_CharT>::overflow(int_type __c) | |
| 263 | { | |
| 264 | char __extbuf[__limit]; | |
| 265 | char_type __1buf; | |
| 266 | if (!traits_type::eq_int_type(__c, traits_type::eof())) | |
| 267 | { | |
| 268 | __1buf = traits_type::to_char_type(__c); | |
| 269 | if (__always_noconv_) | |
| 270 | { | |
| 271 | if (fwrite(&__1buf, sizeof(char_type), 1, __file_) != 1) | |
| 272 | return traits_type::eof(); | |
| 273 | } | |
| 274 | else | |
| 275 | { | |
| 276 | char* __extbe = __extbuf; | |
| 277 | codecvt_base::result __r; | |
| 278 | char_type* pbase = &__1buf; | |
| 279 | char_type* pptr = pbase + 1; | |
| 280 | do | |
| 281 | { | |
| 282 | const char_type* __e; | |
| 283 | __r = __cv_->out(*__st_, pbase, pptr, __e, | |
| 284 | __extbuf, | |
| 285 | __extbuf + sizeof(__extbuf), | |
| 286 | __extbe); | |
| 287 | if (__e == pbase) | |
| 288 | return traits_type::eof(); | |
| 289 | if (__r == codecvt_base::noconv) | |
| 290 | { | |
| 291 | if (fwrite(pbase, 1, 1, __file_) != 1) | |
| 292 | return traits_type::eof(); | |
| 293 | } | |
| 294 | else if (__r == codecvt_base::ok || __r == codecvt_base::partial) | |
| 295 | { | |
| 296 | size_t __nmemb = static_cast<size_t>(__extbe - __extbuf); | |
| 297 | if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) | |
| 298 | return traits_type::eof(); | |
| 299 | if (__r == codecvt_base::partial) | |
| 300 | { | |
| 301 | pbase = const_cast<char_type*>(__e); | |
| 302 | } | |
| 303 | } | |
| 304 | else | |
| 305 | return traits_type::eof(); | |
| 306 | } while (__r == codecvt_base::partial); | |
| 307 | } | |
| 308 | } | |
| 309 | return traits_type::not_eof(__c); | |
| 310 | } | |
| 311 | ||
| 312 | template <class _CharT> | |
| 313 | streamsize | |
| 314 | __stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n) | |
| 315 | { | |
| 316 | if (__always_noconv_) | |
| 317 | return fwrite(__s, sizeof(char_type), __n, __file_); | |
| 318 | streamsize __i = 0; | |
| 319 | for (; __i < __n; ++__i, ++__s) | |
| 320 | if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof()) | |
| 321 | break; | |
| 322 | return __i; | |
| 323 | } | |
| 324 | ||
| 325 | template <class _CharT> | |
| 326 | int | |
| 327 | __stdoutbuf<_CharT>::sync() | |
| 328 | { | |
| 329 | char __extbuf[__limit]; | |
| 330 | codecvt_base::result __r; | |
| 331 | do | |
| 332 | { | |
| 333 | char* __extbe; | |
| 334 | __r = __cv_->unshift(*__st_, __extbuf, | |
| 335 | __extbuf + sizeof(__extbuf), | |
| 336 | __extbe); | |
| 337 | size_t __nmemb = static_cast<size_t>(__extbe - __extbuf); | |
| 338 | if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) | |
| 339 | return -1; | |
| 340 | } while (__r == codecvt_base::partial); | |
| 341 | if (__r == codecvt_base::error) | |
| 342 | return -1; | |
| 343 | if (fflush(__file_)) | |
| 344 | return -1; | |
| 345 | return 0; | |
| 346 | } | |
| 347 | ||
| 348 | template <class _CharT> | |
| 349 | void | |
| 350 | __stdoutbuf<_CharT>::imbue(const locale& __loc) | |
| 351 | { | |
| 352 | sync(); | |
| 353 | __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc); | |
| 354 | __always_noconv_ = __cv_->always_noconv(); | |
| 355 | } | |
| 356 | ||
| 357 | _LIBCPP_END_NAMESPACE_STD | |
| 358 | ||
| 359 | _LIBCPP_POP_MACROS | |
| 360 | ||
| 361 | #endif // _LIBCPP___STD_STREAM |
lib/libcxx/include/__stop_token/atomic_unique_lock.h created+139| ... | ... | @@ -0,0 +1,139 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H | |
| 12 | ||
| 13 | #include <__bit/popcount.h> | |
| 14 | #include <__config> | |
| 15 | #include <atomic> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | ||
| 25 | // This class implements an RAII unique_lock without a mutex. | |
| 26 | // It uses std::atomic<State>, | |
| 27 | // where State contains a lock bit and might contain other data, | |
| 28 | // and LockedBit is the value of State when the lock bit is set, e.g 1 << 2 | |
| 29 | template <class _State, _State _LockedBit> | |
| 30 | class _LIBCPP_AVAILABILITY_SYNC __atomic_unique_lock { | |
| 31 | static_assert(std::popcount(_LockedBit) == 1, "LockedBit must be an integer where only one bit is set"); | |
| 32 | ||
| 33 | std::atomic<_State>& __state_; | |
| 34 | bool __is_locked_; | |
| 35 | ||
| 36 | public: | |
| 37 | _LIBCPP_HIDE_FROM_ABI explicit __atomic_unique_lock(std::atomic<_State>& __state) noexcept | |
| 38 | : __state_(__state), __is_locked_(true) { | |
| 39 | __lock(); | |
| 40 | } | |
| 41 | ||
| 42 | template <class _Pred> | |
| 43 | _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock(std::atomic<_State>& __state, _Pred&& __give_up_locking) noexcept | |
| 44 | : __state_(__state), __is_locked_(false) { | |
| 45 | __is_locked_ = __lock_impl(__give_up_locking, __set_locked_bit, std::memory_order_acquire); | |
| 46 | } | |
| 47 | ||
| 48 | template <class _Pred, class _UnaryFunction> | |
| 49 | _LIBCPP_HIDE_FROM_ABI __atomic_unique_lock( | |
| 50 | std::atomic<_State>& __state, | |
| 51 | _Pred&& __give_up_locking, | |
| 52 | _UnaryFunction&& __state_after_lock, | |
| 53 | std::memory_order __locked_ordering) noexcept | |
| 54 | : __state_(__state), __is_locked_(false) { | |
| 55 | __is_locked_ = __lock_impl(__give_up_locking, __state_after_lock, __locked_ordering); | |
| 56 | } | |
| 57 | ||
| 58 | __atomic_unique_lock(const __atomic_unique_lock&) = delete; | |
| 59 | __atomic_unique_lock(__atomic_unique_lock&&) = delete; | |
| 60 | __atomic_unique_lock& operator=(const __atomic_unique_lock&) = delete; | |
| 61 | __atomic_unique_lock& operator=(__atomic_unique_lock&&) = delete; | |
| 62 | ||
| 63 | _LIBCPP_HIDE_FROM_ABI ~__atomic_unique_lock() { | |
| 64 | if (__is_locked_) { | |
| 65 | __unlock(); | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 69 | _LIBCPP_HIDE_FROM_ABI bool __owns_lock() const noexcept { return __is_locked_; } | |
| 70 | ||
| 71 | _LIBCPP_HIDE_FROM_ABI void __lock() noexcept { | |
| 72 | const auto __never_give_up_locking = [](_State) { return false; }; | |
| 73 | // std::memory_order_acquire because we'd like to make sure that all the read operations after the lock can read the | |
| 74 | // up-to-date values. | |
| 75 | __lock_impl(__never_give_up_locking, __set_locked_bit, std::memory_order_acquire); | |
| 76 | __is_locked_ = true; | |
| 77 | } | |
| 78 | ||
| 79 | _LIBCPP_HIDE_FROM_ABI void __unlock() noexcept { | |
| 80 | // unset the _LockedBit. `memory_order_release` because we need to make sure all the write operations before calling | |
| 81 | // `__unlock` will be made visible to other threads | |
| 82 | __state_.fetch_and(static_cast<_State>(~_LockedBit), std::memory_order_release); | |
| 83 | __state_.notify_all(); | |
| 84 | __is_locked_ = false; | |
| 85 | } | |
| 86 | ||
| 87 | private: | |
| 88 | template <class _Pred, class _UnaryFunction> | |
| 89 | _LIBCPP_HIDE_FROM_ABI bool | |
| 90 | __lock_impl(_Pred&& __give_up_locking, // while trying to lock the state, if the predicate returns true, give up | |
| 91 | // locking and return | |
| 92 | _UnaryFunction&& __state_after_lock, | |
| 93 | std::memory_order __locked_ordering) noexcept { | |
| 94 | // At this stage, until we exit the inner while loop, other than the atomic state, we are not reading any order | |
| 95 | // dependent values that is written on other threads, or writing anything that needs to be seen on other threads. | |
| 96 | // Therefore `memory_order_relaxed` is enough. | |
| 97 | _State __current_state = __state_.load(std::memory_order_relaxed); | |
| 98 | do { | |
| 99 | while (true) { | |
| 100 | if (__give_up_locking(__current_state)) { | |
| 101 | // user provided early return condition. fail to lock | |
| 102 | return false; | |
| 103 | } else if ((__current_state & _LockedBit) != 0) { | |
| 104 | // another thread has locked the state, we need to wait | |
| 105 | __state_.wait(__current_state, std::memory_order_relaxed); | |
| 106 | // when it is woken up by notifyAll or spuriously, the __state_ | |
| 107 | // might have changed. reload the state | |
| 108 | // Note that the new state's _LockedBit may or may not equal to 0 | |
| 109 | __current_state = __state_.load(std::memory_order_relaxed); | |
| 110 | } else { | |
| 111 | // at least for now, it is not locked. we can try `compare_exchange_weak` to lock it. | |
| 112 | // Note that the variable `__current_state`'s lock bit has to be 0 at this point. | |
| 113 | break; | |
| 114 | } | |
| 115 | } | |
| 116 | } while (!__state_.compare_exchange_weak( | |
| 117 | __current_state, // if __state_ has the same value of __current_state, lock bit must be zero before exchange and | |
| 118 | // we are good to lock/exchange and return. If _state has a different value, because other | |
| 119 | // threads locked it between the `break` statement above and this statement, exchange will fail | |
| 120 | // and go back to the inner while loop above. | |
| 121 | __state_after_lock(__current_state), // state after lock. Usually it should be __current_state | _LockedBit. | |
| 122 | // Some use cases need to set other bits at the same time as an atomic | |
| 123 | // operation therefore we accept a function | |
| 124 | __locked_ordering, // sucessful exchange order. Usually it should be std::memory_order_acquire. | |
| 125 | // Some use cases need more strict ordering therefore we accept it as a parameter | |
| 126 | std::memory_order_relaxed // fail to exchange order. We don't need any ordering as we are going back to the | |
| 127 | // inner while loop | |
| 128 | )); | |
| 129 | return true; | |
| 130 | } | |
| 131 | ||
| 132 | _LIBCPP_HIDE_FROM_ABI static constexpr auto __set_locked_bit = [](_State __state) { return __state | _LockedBit; }; | |
| 133 | }; | |
| 134 | ||
| 135 | #endif // _LIBCPP_STD_VER >= 20 | |
| 136 | ||
| 137 | _LIBCPP_END_NAMESPACE_STD | |
| 138 | ||
| 139 | #endif // _LIBCPP___STOP_TOKEN_ATOMIC_UNIQUE_GUARD_H |
lib/libcxx/include/__stop_token/intrusive_list_view.h created+85| ... | ... | @@ -0,0 +1,85 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H | |
| 12 | ||
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 21 | ||
| 22 | #if _LIBCPP_STD_VER >= 20 | |
| 23 | ||
| 24 | template <class _Derived> | |
| 25 | struct __intrusive_node_base { | |
| 26 | _Derived* __next_ = nullptr; | |
| 27 | _Derived* __prev_ = nullptr; | |
| 28 | }; | |
| 29 | ||
| 30 | // This class is a view of underlying double-linked list. | |
| 31 | // It does not own the nodes. It provides user-friendly | |
| 32 | // operations on the linked list. | |
| 33 | template <class _Node> | |
| 34 | struct __intrusive_list_view { | |
| 35 | _LIBCPP_HIDE_FROM_ABI __intrusive_list_view() = default; | |
| 36 | _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view const&) = default; | |
| 37 | _LIBCPP_HIDE_FROM_ABI __intrusive_list_view(__intrusive_list_view&&) = default; | |
| 38 | _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view const&) = default; | |
| 39 | _LIBCPP_HIDE_FROM_ABI __intrusive_list_view& operator=(__intrusive_list_view&&) = default; | |
| 40 | _LIBCPP_HIDE_FROM_ABI ~__intrusive_list_view() = default; | |
| 41 | ||
| 42 | _LIBCPP_HIDE_FROM_ABI bool __empty() const noexcept { return __head_ == nullptr; } | |
| 43 | ||
| 44 | _LIBCPP_HIDE_FROM_ABI void __push_front(_Node* __node) noexcept { | |
| 45 | __node->__next_ = __head_; | |
| 46 | if (__head_) { | |
| 47 | __head_->__prev_ = __node; | |
| 48 | } | |
| 49 | __head_ = __node; | |
| 50 | } | |
| 51 | ||
| 52 | _LIBCPP_HIDE_FROM_ABI _Node* __pop_front() noexcept { | |
| 53 | _Node* __front = __head_; | |
| 54 | __head_ = __head_->__next_; | |
| 55 | if (__head_) { | |
| 56 | __head_->__prev_ = nullptr; | |
| 57 | } | |
| 58 | // OK not to set __front->__next_ = nullptr as __front is not part of the list anymore | |
| 59 | return __front; | |
| 60 | } | |
| 61 | ||
| 62 | _LIBCPP_HIDE_FROM_ABI void __remove(_Node* __node) noexcept { | |
| 63 | if (__node->__prev_) { | |
| 64 | // prev exists, set its next to our next to skip __node | |
| 65 | __node->__prev_->__next_ = __node->__next_; | |
| 66 | if (__node->__next_) { | |
| 67 | __node->__next_->__prev_ = __node->__prev_; | |
| 68 | } | |
| 69 | } else { | |
| 70 | _LIBCPP_ASSERT_INTERNAL(__node == __head_, "Node to be removed has no prev node, so it has to be the head"); | |
| 71 | __pop_front(); | |
| 72 | } | |
| 73 | } | |
| 74 | ||
| 75 | _LIBCPP_HIDE_FROM_ABI bool __is_head(_Node* __node) noexcept { return __node == __head_; } | |
| 76 | ||
| 77 | private: | |
| 78 | _Node* __head_ = nullptr; | |
| 79 | }; | |
| 80 | ||
| 81 | #endif // _LIBCPP_STD_VER >= 20 | |
| 82 | ||
| 83 | _LIBCPP_END_NAMESPACE_STD | |
| 84 | ||
| 85 | #endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_LIST_VIEW_H |
lib/libcxx/include/__stop_token/intrusive_shared_ptr.h created+134| ... | ... | @@ -0,0 +1,134 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H | |
| 12 | ||
| 13 | #include <__atomic/atomic.h> | |
| 14 | #include <__atomic/memory_order.h> | |
| 15 | #include <__config> | |
| 16 | #include <__type_traits/is_reference.h> | |
| 17 | #include <__utility/move.h> | |
| 18 | #include <__utility/swap.h> | |
| 19 | #include <cstddef> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_PUSH_MACROS | |
| 26 | #include <__undef_macros> | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | ||
| 32 | // For intrusive_shared_ptr to work with a type T, specialize __intrusive_shared_ptr_traits<T> and implement | |
| 33 | // the following function: | |
| 34 | // | |
| 35 | // static std::atomic<U>& __get_atomic_ref_count(T&); | |
| 36 | // | |
| 37 | // where U must be an integral type representing the number of references to the object. | |
| 38 | template <class _Tp> | |
| 39 | struct __intrusive_shared_ptr_traits; | |
| 40 | ||
| 41 | // A reference counting shared_ptr for types whose reference counter | |
| 42 | // is stored inside the class _Tp itself. | |
| 43 | // When the reference count goes to zero, the destructor of _Tp will be called | |
| 44 | template <class _Tp> | |
| 45 | struct __intrusive_shared_ptr { | |
| 46 | _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr() = default; | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI explicit __intrusive_shared_ptr(_Tp* __raw_ptr) : __raw_ptr_(__raw_ptr) { | |
| 49 | if (__raw_ptr_) | |
| 50 | __increment_ref_count(*__raw_ptr_); | |
| 51 | } | |
| 52 | ||
| 53 | _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(const __intrusive_shared_ptr& __other) noexcept | |
| 54 | : __raw_ptr_(__other.__raw_ptr_) { | |
| 55 | if (__raw_ptr_) | |
| 56 | __increment_ref_count(*__raw_ptr_); | |
| 57 | } | |
| 58 | ||
| 59 | _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr(__intrusive_shared_ptr&& __other) noexcept | |
| 60 | : __raw_ptr_(__other.__raw_ptr_) { | |
| 61 | __other.__raw_ptr_ = nullptr; | |
| 62 | } | |
| 63 | ||
| 64 | _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(const __intrusive_shared_ptr& __other) noexcept { | |
| 65 | if (__other.__raw_ptr_ != __raw_ptr_) { | |
| 66 | if (__other.__raw_ptr_) { | |
| 67 | __increment_ref_count(*__other.__raw_ptr_); | |
| 68 | } | |
| 69 | if (__raw_ptr_) { | |
| 70 | __decrement_ref_count(*__raw_ptr_); | |
| 71 | } | |
| 72 | __raw_ptr_ = __other.__raw_ptr_; | |
| 73 | } | |
| 74 | return *this; | |
| 75 | } | |
| 76 | ||
| 77 | _LIBCPP_HIDE_FROM_ABI __intrusive_shared_ptr& operator=(__intrusive_shared_ptr&& __other) noexcept { | |
| 78 | __intrusive_shared_ptr(std::move(__other)).swap(*this); | |
| 79 | return *this; | |
| 80 | } | |
| 81 | ||
| 82 | _LIBCPP_HIDE_FROM_ABI ~__intrusive_shared_ptr() { | |
| 83 | if (__raw_ptr_) { | |
| 84 | __decrement_ref_count(*__raw_ptr_); | |
| 85 | } | |
| 86 | } | |
| 87 | ||
| 88 | _LIBCPP_HIDE_FROM_ABI _Tp* operator->() const noexcept { return __raw_ptr_; } | |
| 89 | _LIBCPP_HIDE_FROM_ABI _Tp& operator*() const noexcept { return *__raw_ptr_; } | |
| 90 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __raw_ptr_ != nullptr; } | |
| 91 | ||
| 92 | _LIBCPP_HIDE_FROM_ABI void swap(__intrusive_shared_ptr& __other) { std::swap(__raw_ptr_, __other.__raw_ptr_); } | |
| 93 | ||
| 94 | _LIBCPP_HIDE_FROM_ABI friend void swap(__intrusive_shared_ptr& __lhs, __intrusive_shared_ptr& __rhs) { | |
| 95 | __lhs.swap(__rhs); | |
| 96 | } | |
| 97 | ||
| 98 | _LIBCPP_HIDE_FROM_ABI friend bool constexpr | |
| 99 | operator==(const __intrusive_shared_ptr&, const __intrusive_shared_ptr&) = default; | |
| 100 | ||
| 101 | _LIBCPP_HIDE_FROM_ABI friend bool constexpr operator==(const __intrusive_shared_ptr& __ptr, std::nullptr_t) { | |
| 102 | return __ptr.__raw_ptr_ == nullptr; | |
| 103 | } | |
| 104 | ||
| 105 | private: | |
| 106 | _Tp* __raw_ptr_ = nullptr; | |
| 107 | ||
| 108 | // the memory order for increment/decrement the counter is the same for shared_ptr | |
| 109 | // increment is relaxed and decrement is acq_rel | |
| 110 | _LIBCPP_HIDE_FROM_ABI static void __increment_ref_count(_Tp& __obj) { | |
| 111 | __get_atomic_ref_count(__obj).fetch_add(1, std::memory_order_relaxed); | |
| 112 | } | |
| 113 | ||
| 114 | _LIBCPP_HIDE_FROM_ABI static void __decrement_ref_count(_Tp& __obj) { | |
| 115 | if (__get_atomic_ref_count(__obj).fetch_sub(1, std::memory_order_acq_rel) == 1) { | |
| 116 | delete &__obj; | |
| 117 | } | |
| 118 | } | |
| 119 | ||
| 120 | _LIBCPP_HIDE_FROM_ABI static decltype(auto) __get_atomic_ref_count(_Tp& __obj) { | |
| 121 | using __ret_type = decltype(__intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj)); | |
| 122 | static_assert( | |
| 123 | std::is_reference_v<__ret_type>, "__get_atomic_ref_count should return a reference to the atomic counter"); | |
| 124 | return __intrusive_shared_ptr_traits<_Tp>::__get_atomic_ref_count(__obj); | |
| 125 | } | |
| 126 | }; | |
| 127 | ||
| 128 | #endif // _LIBCPP_STD_VER >= 20 | |
| 129 | ||
| 130 | _LIBCPP_END_NAMESPACE_STD | |
| 131 | ||
| 132 | _LIBCPP_POP_MACROS | |
| 133 | ||
| 134 | #endif // _LIBCPP___STOP_TOKEN_INTRUSIVE_SHARED_PTR_H |
lib/libcxx/include/__stop_token/stop_callback.h created+99| ... | ... | @@ -0,0 +1,99 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_STOP_CALLBACK_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_STOP_CALLBACK_H | |
| 12 | ||
| 13 | #include <__availability> | |
| 14 | #include <__concepts/constructible.h> | |
| 15 | #include <__concepts/destructible.h> | |
| 16 | #include <__concepts/invocable.h> | |
| 17 | #include <__config> | |
| 18 | #include <__stop_token/intrusive_shared_ptr.h> | |
| 19 | #include <__stop_token/stop_state.h> | |
| 20 | #include <__stop_token/stop_token.h> | |
| 21 | #include <__type_traits/is_nothrow_constructible.h> | |
| 22 | #include <__utility/forward.h> | |
| 23 | #include <__utility/move.h> | |
| 24 | ||
| 25 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 26 | # pragma GCC system_header | |
| 27 | #endif | |
| 28 | ||
| 29 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 30 | ||
| 31 | #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) | |
| 32 | ||
| 33 | template <class _Callback> | |
| 34 | class _LIBCPP_AVAILABILITY_SYNC stop_callback : private __stop_callback_base { | |
| 35 | static_assert(invocable<_Callback>, | |
| 36 | "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that " | |
| 37 | "satisfies invocable."); | |
| 38 | static_assert(destructible<_Callback>, | |
| 39 | "Mandates: stop_callback is instantiated with an argument for the template parameter Callback that " | |
| 40 | "satisfies destructible."); | |
| 41 | ||
| 42 | public: | |
| 43 | using callback_type = _Callback; | |
| 44 | ||
| 45 | template <class _Cb> | |
| 46 | requires constructible_from<_Callback, _Cb> | |
| 47 | _LIBCPP_HIDE_FROM_ABI explicit stop_callback(const stop_token& __st, | |
| 48 | _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>) | |
| 49 | : stop_callback(__private_tag{}, __st.__state_, std::forward<_Cb>(__cb)) {} | |
| 50 | ||
| 51 | template <class _Cb> | |
| 52 | requires constructible_from<_Callback, _Cb> | |
| 53 | _LIBCPP_HIDE_FROM_ABI explicit stop_callback(stop_token&& __st, | |
| 54 | _Cb&& __cb) noexcept(is_nothrow_constructible_v<_Callback, _Cb>) | |
| 55 | : stop_callback(__private_tag{}, std::move(__st.__state_), std::forward<_Cb>(__cb)) {} | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI ~stop_callback() { | |
| 58 | if (__state_) { | |
| 59 | __state_->__remove_callback(this); | |
| 60 | } | |
| 61 | } | |
| 62 | ||
| 63 | stop_callback(const stop_callback&) = delete; | |
| 64 | stop_callback(stop_callback&&) = delete; | |
| 65 | stop_callback& operator=(const stop_callback&) = delete; | |
| 66 | stop_callback& operator=(stop_callback&&) = delete; | |
| 67 | ||
| 68 | private: | |
| 69 | _LIBCPP_NO_UNIQUE_ADDRESS _Callback __callback_; | |
| 70 | __intrusive_shared_ptr<__stop_state> __state_; | |
| 71 | ||
| 72 | friend __stop_callback_base; | |
| 73 | ||
| 74 | struct __private_tag {}; | |
| 75 | ||
| 76 | template <class _StatePtr, class _Cb> | |
| 77 | _LIBCPP_HIDE_FROM_ABI explicit stop_callback(__private_tag, _StatePtr&& __state, _Cb&& __cb) noexcept( | |
| 78 | is_nothrow_constructible_v<_Callback, _Cb>) | |
| 79 | : __stop_callback_base([](__stop_callback_base* __cb_base) noexcept { | |
| 80 | // stop callback is supposed to only be called once | |
| 81 | std::forward<_Callback>(static_cast<stop_callback*>(__cb_base)->__callback_)(); | |
| 82 | }), | |
| 83 | __callback_(std::forward<_Cb>(__cb)), | |
| 84 | __state_() { | |
| 85 | if (__state && __state->__add_callback(this)) { | |
| 86 | // st.stop_requested() was false and this is successfully added to the linked list | |
| 87 | __state_ = std::forward<_StatePtr>(__state); | |
| 88 | } | |
| 89 | } | |
| 90 | }; | |
| 91 | ||
| 92 | template <class _Callback> | |
| 93 | _LIBCPP_AVAILABILITY_SYNC stop_callback(stop_token, _Callback) -> stop_callback<_Callback>; | |
| 94 | ||
| 95 | #endif // _LIBCPP_STD_VER >= 20 | |
| 96 | ||
| 97 | _LIBCPP_END_NAMESPACE_STD | |
| 98 | ||
| 99 | #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) |
lib/libcxx/include/__stop_token/stop_source.h created+92| ... | ... | @@ -0,0 +1,92 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_STOP_SOURCE_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_STOP_SOURCE_H | |
| 12 | ||
| 13 | #include <__availability> | |
| 14 | #include <__config> | |
| 15 | #include <__stop_token/intrusive_shared_ptr.h> | |
| 16 | #include <__stop_token/stop_state.h> | |
| 17 | #include <__stop_token/stop_token.h> | |
| 18 | #include <__utility/move.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) | |
| 27 | ||
| 28 | struct nostopstate_t { | |
| 29 | explicit nostopstate_t() = default; | |
| 30 | }; | |
| 31 | ||
| 32 | inline constexpr nostopstate_t nostopstate{}; | |
| 33 | ||
| 34 | class _LIBCPP_AVAILABILITY_SYNC stop_source { | |
| 35 | public: | |
| 36 | _LIBCPP_HIDE_FROM_ABI stop_source() : __state_(new __stop_state()) { __state_->__increment_stop_source_counter(); } | |
| 37 | ||
| 38 | _LIBCPP_HIDE_FROM_ABI explicit stop_source(nostopstate_t) noexcept : __state_(nullptr) {} | |
| 39 | ||
| 40 | _LIBCPP_HIDE_FROM_ABI stop_source(const stop_source& __other) noexcept : __state_(__other.__state_) { | |
| 41 | if (__state_) { | |
| 42 | __state_->__increment_stop_source_counter(); | |
| 43 | } | |
| 44 | } | |
| 45 | ||
| 46 | _LIBCPP_HIDE_FROM_ABI stop_source(stop_source&& __other) noexcept = default; | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI stop_source& operator=(const stop_source& __other) noexcept { | |
| 49 | // increment `__other` first so that we don't hit 0 in case of self-assignment | |
| 50 | if (__other.__state_) { | |
| 51 | __other.__state_->__increment_stop_source_counter(); | |
| 52 | } | |
| 53 | if (__state_) { | |
| 54 | __state_->__decrement_stop_source_counter(); | |
| 55 | } | |
| 56 | __state_ = __other.__state_; | |
| 57 | return *this; | |
| 58 | } | |
| 59 | ||
| 60 | _LIBCPP_HIDE_FROM_ABI stop_source& operator=(stop_source&&) noexcept = default; | |
| 61 | ||
| 62 | _LIBCPP_HIDE_FROM_ABI ~stop_source() { | |
| 63 | if (__state_) { | |
| 64 | __state_->__decrement_stop_source_counter(); | |
| 65 | } | |
| 66 | } | |
| 67 | ||
| 68 | _LIBCPP_HIDE_FROM_ABI void swap(stop_source& __other) noexcept { __state_.swap(__other.__state_); } | |
| 69 | ||
| 70 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_token get_token() const noexcept { return stop_token(__state_); } | |
| 71 | ||
| 72 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept { return __state_ != nullptr; } | |
| 73 | ||
| 74 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept { | |
| 75 | return __state_ != nullptr && __state_->__stop_requested(); | |
| 76 | } | |
| 77 | ||
| 78 | _LIBCPP_HIDE_FROM_ABI bool request_stop() noexcept { return __state_ && __state_->__request_stop(); } | |
| 79 | ||
| 80 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_source&, const stop_source&) noexcept = default; | |
| 81 | ||
| 82 | _LIBCPP_HIDE_FROM_ABI friend void swap(stop_source& __lhs, stop_source& __rhs) noexcept { __lhs.swap(__rhs); } | |
| 83 | ||
| 84 | private: | |
| 85 | __intrusive_shared_ptr<__stop_state> __state_; | |
| 86 | }; | |
| 87 | ||
| 88 | #endif // _LIBCPP_STD_VER >= 20 | |
| 89 | ||
| 90 | _LIBCPP_END_NAMESPACE_STD | |
| 91 | ||
| 92 | #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) |
lib/libcxx/include/__stop_token/stop_state.h created+236| ... | ... | @@ -0,0 +1,236 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_STOP_STATE_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_STOP_STATE_H | |
| 12 | ||
| 13 | #include <__availability> | |
| 14 | #include <__config> | |
| 15 | #include <__stop_token/atomic_unique_lock.h> | |
| 16 | #include <__stop_token/intrusive_list_view.h> | |
| 17 | #include <atomic> | |
| 18 | #include <cstdint> | |
| 19 | #include <thread> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | ||
| 29 | struct __stop_callback_base : __intrusive_node_base<__stop_callback_base> { | |
| 30 | using __callback_fn_t = void(__stop_callback_base*) noexcept; | |
| 31 | _LIBCPP_HIDE_FROM_ABI explicit __stop_callback_base(__callback_fn_t* __callback_fn) : __callback_fn_(__callback_fn) {} | |
| 32 | ||
| 33 | _LIBCPP_HIDE_FROM_ABI void __invoke() noexcept { __callback_fn_(this); } | |
| 34 | ||
| 35 | __callback_fn_t* __callback_fn_; | |
| 36 | atomic<bool> __completed_ = false; | |
| 37 | bool* __destroyed_ = nullptr; | |
| 38 | }; | |
| 39 | ||
| 40 | class __stop_state { | |
| 41 | static constexpr uint32_t __stop_requested_bit = 1; | |
| 42 | static constexpr uint32_t __callback_list_locked_bit = 1 << 1; | |
| 43 | static constexpr uint32_t __stop_source_counter_shift = 2; | |
| 44 | ||
| 45 | // The "stop_source counter" is not used for lifetime reference counting. | |
| 46 | // When the number of stop_source reaches 0, the remaining stop_tokens's | |
| 47 | // stop_possible will return false. We need this counter to track this. | |
| 48 | // | |
| 49 | // The "callback list locked" bit implements the atomic_unique_lock to | |
| 50 | // guard the operations on the callback list | |
| 51 | // | |
| 52 | // 31 - 2 | 1 | 0 | | |
| 53 | // stop_source counter | callback list locked | stop_requested | | |
| 54 | atomic<uint32_t> __state_ = 0; | |
| 55 | ||
| 56 | // Reference count for stop_token + stop_callback + stop_source | |
| 57 | // When the counter reaches zero, the state is destroyed | |
| 58 | // It is used by __intrusive_shared_ptr, but it is stored here for better layout | |
| 59 | atomic<uint32_t> __ref_count_ = 0; | |
| 60 | ||
| 61 | using __state_t = uint32_t; | |
| 62 | using __callback_list_lock = __atomic_unique_lock<__state_t, __callback_list_locked_bit>; | |
| 63 | using __callback_list = __intrusive_list_view<__stop_callback_base>; | |
| 64 | ||
| 65 | __callback_list __callback_list_; | |
| 66 | thread::id __requesting_thread_; | |
| 67 | ||
| 68 | public: | |
| 69 | _LIBCPP_HIDE_FROM_ABI __stop_state() noexcept = default; | |
| 70 | ||
| 71 | _LIBCPP_HIDE_FROM_ABI void __increment_stop_source_counter() noexcept { | |
| 72 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 73 | __state_.load(std::memory_order_relaxed) <= static_cast<__state_t>(~(1 << __stop_source_counter_shift)), | |
| 74 | "stop_source's counter reaches the maximum. Incrementing the counter will overflow"); | |
| 75 | __state_.fetch_add(1 << __stop_source_counter_shift, std::memory_order_relaxed); | |
| 76 | } | |
| 77 | ||
| 78 | // We are not destroying the object after counter decrements to zero, nor do we have | |
| 79 | // operations depend on the ordering of decrementing the counter. relaxed is enough. | |
| 80 | _LIBCPP_HIDE_FROM_ABI void __decrement_stop_source_counter() noexcept { | |
| 81 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 82 | __state_.load(std::memory_order_relaxed) >= static_cast<__state_t>(1 << __stop_source_counter_shift), | |
| 83 | "stop_source's counter is 0. Decrementing the counter will underflow"); | |
| 84 | __state_.fetch_sub(1 << __stop_source_counter_shift, std::memory_order_relaxed); | |
| 85 | } | |
| 86 | ||
| 87 | _LIBCPP_HIDE_FROM_ABI bool __stop_requested() const noexcept { | |
| 88 | // acquire because [thread.stoptoken.intro] A call to request_stop that returns true | |
| 89 | // synchronizes with a call to stop_requested on an associated stop_token or stop_source | |
| 90 | // object that returns true. | |
| 91 | // request_stop's compare_exchange_weak has release which syncs with this acquire | |
| 92 | return (__state_.load(std::memory_order_acquire) & __stop_requested_bit) != 0; | |
| 93 | } | |
| 94 | ||
| 95 | _LIBCPP_HIDE_FROM_ABI bool __stop_possible_for_stop_token() const noexcept { | |
| 96 | // [stoptoken.mem] false if "a stop request was not made and there are no associated stop_source objects" | |
| 97 | // Todo: Can this be std::memory_order_relaxed as the standard does not say anything except not to introduce data | |
| 98 | // race? | |
| 99 | __state_t __curent_state = __state_.load(std::memory_order_acquire); | |
| 100 | return ((__curent_state & __stop_requested_bit) != 0) || ((__curent_state >> __stop_source_counter_shift) != 0); | |
| 101 | } | |
| 102 | ||
| 103 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __request_stop() noexcept { | |
| 104 | auto __cb_list_lock = __try_lock_for_request_stop(); | |
| 105 | if (!__cb_list_lock.__owns_lock()) { | |
| 106 | return false; | |
| 107 | } | |
| 108 | __requesting_thread_ = this_thread::get_id(); | |
| 109 | ||
| 110 | while (!__callback_list_.__empty()) { | |
| 111 | auto __cb = __callback_list_.__pop_front(); | |
| 112 | ||
| 113 | // allow other callbacks to be removed while invoking the current callback | |
| 114 | __cb_list_lock.__unlock(); | |
| 115 | ||
| 116 | bool __destroyed = false; | |
| 117 | __cb->__destroyed_ = &__destroyed; | |
| 118 | ||
| 119 | __cb->__invoke(); | |
| 120 | ||
| 121 | // __cb's invoke function could potentially delete itself. We need to check before accessing __cb's member | |
| 122 | if (!__destroyed) { | |
| 123 | // needs to set __destroyed_ pointer to nullptr, otherwise it points to a local variable | |
| 124 | // which is to be destroyed at the end of the loop | |
| 125 | __cb->__destroyed_ = nullptr; | |
| 126 | ||
| 127 | // [stopcallback.cons] If callback is concurrently executing on another thread, then the return | |
| 128 | // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed. | |
| 129 | // this release syncs with the acquire in the remove_callback | |
| 130 | __cb->__completed_.store(true, std::memory_order_release); | |
| 131 | __cb->__completed_.notify_all(); | |
| 132 | } | |
| 133 | ||
| 134 | __cb_list_lock.__lock(); | |
| 135 | } | |
| 136 | ||
| 137 | return true; | |
| 138 | } | |
| 139 | ||
| 140 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI bool __add_callback(__stop_callback_base* __cb) noexcept { | |
| 141 | // If it is already stop_requested. Do not try to request it again. | |
| 142 | const auto __give_up_trying_to_lock_condition = [__cb](__state_t __state) { | |
| 143 | if ((__state & __stop_requested_bit) != 0) { | |
| 144 | // already stop requested, synchronously run the callback and no need to lock the list again | |
| 145 | __cb->__invoke(); | |
| 146 | return true; | |
| 147 | } | |
| 148 | // no stop source. no need to lock the list to add the callback as it can never be invoked | |
| 149 | return (__state >> __stop_source_counter_shift) == 0; | |
| 150 | }; | |
| 151 | ||
| 152 | __callback_list_lock __cb_list_lock(__state_, __give_up_trying_to_lock_condition); | |
| 153 | ||
| 154 | if (!__cb_list_lock.__owns_lock()) { | |
| 155 | return false; | |
| 156 | } | |
| 157 | ||
| 158 | __callback_list_.__push_front(__cb); | |
| 159 | ||
| 160 | return true; | |
| 161 | // unlock here: [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of | |
| 162 | // that callback. | |
| 163 | // Note: this release sync with the acquire in the request_stop' __try_lock_for_request_stop | |
| 164 | } | |
| 165 | ||
| 166 | // called by the destructor of stop_callback | |
| 167 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __remove_callback(__stop_callback_base* __cb) noexcept { | |
| 168 | __callback_list_lock __cb_list_lock(__state_); | |
| 169 | ||
| 170 | // under below condition, the request_stop call just popped __cb from the list and could execute it now | |
| 171 | bool __potentially_executing_now = __cb->__prev_ == nullptr && !__callback_list_.__is_head(__cb); | |
| 172 | ||
| 173 | if (__potentially_executing_now) { | |
| 174 | auto __requested_thread = __requesting_thread_; | |
| 175 | __cb_list_lock.__unlock(); | |
| 176 | ||
| 177 | if (std::this_thread::get_id() != __requested_thread) { | |
| 178 | // [stopcallback.cons] If callback is concurrently executing on another thread, then the return | |
| 179 | // from the invocation of callback strongly happens before ([intro.races]) callback is destroyed. | |
| 180 | __cb->__completed_.wait(false, std::memory_order_acquire); | |
| 181 | } else { | |
| 182 | // The destructor of stop_callback runs on the same thread of the thread that invokes the callback. | |
| 183 | // The callback is potentially invoking its own destuctor. Set the flag to avoid accessing destroyed | |
| 184 | // members on the invoking side | |
| 185 | if (__cb->__destroyed_) { | |
| 186 | *__cb->__destroyed_ = true; | |
| 187 | } | |
| 188 | } | |
| 189 | } else { | |
| 190 | __callback_list_.__remove(__cb); | |
| 191 | } | |
| 192 | } | |
| 193 | ||
| 194 | private: | |
| 195 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI __callback_list_lock __try_lock_for_request_stop() noexcept { | |
| 196 | // If it is already stop_requested, do not try to request stop or lock the list again. | |
| 197 | const auto __lock_fail_condition = [](__state_t __state) { return (__state & __stop_requested_bit) != 0; }; | |
| 198 | ||
| 199 | // set locked and requested bit at the same time | |
| 200 | const auto __after_lock_state = [](__state_t __state) { | |
| 201 | return __state | __callback_list_locked_bit | __stop_requested_bit; | |
| 202 | }; | |
| 203 | ||
| 204 | // acq because [thread.stoptoken.intro] Registration of a callback synchronizes with the invocation of that | |
| 205 | // callback. We are going to invoke the callback after getting the lock, acquire so that we can see the | |
| 206 | // registration of a callback (and other writes that happens-before the add_callback) | |
| 207 | // Note: the rel (unlock) in the add_callback syncs with this acq | |
| 208 | // rel because [thread.stoptoken.intro] A call to request_stop that returns true synchronizes with a call | |
| 209 | // to stop_requested on an associated stop_token or stop_source object that returns true. | |
| 210 | // We need to make sure that all writes (including user code) before request_stop will be made visible | |
| 211 | // to the threads that waiting for `stop_requested == true` | |
| 212 | // Note: this rel syncs with the acq in `stop_requested` | |
| 213 | const auto __locked_ordering = std::memory_order_acq_rel; | |
| 214 | ||
| 215 | return __callback_list_lock(__state_, __lock_fail_condition, __after_lock_state, __locked_ordering); | |
| 216 | } | |
| 217 | ||
| 218 | template <class _Tp> | |
| 219 | friend struct __intrusive_shared_ptr_traits; | |
| 220 | }; | |
| 221 | ||
| 222 | template <class _Tp> | |
| 223 | struct __intrusive_shared_ptr_traits; | |
| 224 | ||
| 225 | template <> | |
| 226 | struct __intrusive_shared_ptr_traits<__stop_state> { | |
| 227 | _LIBCPP_HIDE_FROM_ABI static atomic<uint32_t>& __get_atomic_ref_count(__stop_state& __state) { | |
| 228 | return __state.__ref_count_; | |
| 229 | } | |
| 230 | }; | |
| 231 | ||
| 232 | #endif // _LIBCPP_STD_VER >= 20 | |
| 233 | ||
| 234 | _LIBCPP_END_NAMESPACE_STD | |
| 235 | ||
| 236 | #endif // _LIBCPP___STOP_TOKEN_STOP_STATE_H |
lib/libcxx/include/__stop_token/stop_token.h created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___STOP_TOKEN_STOP_TOKEN_H | |
| 11 | #define _LIBCPP___STOP_TOKEN_STOP_TOKEN_H | |
| 12 | ||
| 13 | #include <__availability> | |
| 14 | #include <__config> | |
| 15 | #include <__stop_token/intrusive_shared_ptr.h> | |
| 16 | #include <__stop_token/stop_state.h> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) | |
| 25 | ||
| 26 | class _LIBCPP_AVAILABILITY_SYNC stop_token { | |
| 27 | public: | |
| 28 | _LIBCPP_HIDE_FROM_ABI stop_token() noexcept = default; | |
| 29 | ||
| 30 | _LIBCPP_HIDE_FROM_ABI stop_token(const stop_token&) noexcept = default; | |
| 31 | _LIBCPP_HIDE_FROM_ABI stop_token(stop_token&&) noexcept = default; | |
| 32 | _LIBCPP_HIDE_FROM_ABI stop_token& operator=(const stop_token&) noexcept = default; | |
| 33 | _LIBCPP_HIDE_FROM_ABI stop_token& operator=(stop_token&&) noexcept = default; | |
| 34 | _LIBCPP_HIDE_FROM_ABI ~stop_token() = default; | |
| 35 | ||
| 36 | _LIBCPP_HIDE_FROM_ABI void swap(stop_token& __other) noexcept { __state_.swap(__other.__state_); } | |
| 37 | ||
| 38 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept { | |
| 39 | return __state_ != nullptr && __state_->__stop_requested(); | |
| 40 | } | |
| 41 | ||
| 42 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept { | |
| 43 | return __state_ != nullptr && __state_->__stop_possible_for_stop_token(); | |
| 44 | } | |
| 45 | ||
| 46 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_token&, const stop_token&) noexcept = default; | |
| 47 | ||
| 48 | _LIBCPP_HIDE_FROM_ABI friend void swap(stop_token& __lhs, stop_token& __rhs) noexcept { __lhs.swap(__rhs); } | |
| 49 | ||
| 50 | private: | |
| 51 | __intrusive_shared_ptr<__stop_state> __state_; | |
| 52 | ||
| 53 | friend class stop_source; | |
| 54 | template <class _Tp> | |
| 55 | friend class stop_callback; | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI explicit stop_token(const __intrusive_shared_ptr<__stop_state>& __state) : __state_(__state) {} | |
| 58 | }; | |
| 59 | ||
| 60 | #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) | |
| 61 | ||
| 62 | _LIBCPP_END_NAMESPACE_STD | |
| 63 | ||
| 64 | #endif // _LIBCPP___STOP_TOKEN_STOP_TOKEN_H |
lib/libcxx/include/__string/char_traits.h+122-115| ... | ... | @@ -18,11 +18,11 @@ |
| 18 | 18 | #include <__config> |
| 19 | 19 | #include <__functional/hash.h> |
| 20 | 20 | #include <__iterator/iterator_traits.h> |
| 21 | #include <__string/constexpr_c_functions.h> | |
| 21 | 22 | #include <__type_traits/is_constant_evaluated.h> |
| 22 | 23 | #include <cstddef> |
| 23 | 24 | #include <cstdint> |
| 24 | 25 | #include <cstdio> |
| 25 | #include <cstring> | |
| 26 | 26 | #include <iosfwd> |
| 27 | 27 | |
| 28 | 28 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -73,7 +73,7 @@ exposition-only to document what members a char_traits specialization should pro |
| 73 | 73 | |
| 74 | 74 | // |
| 75 | 75 | // Temporary extension to provide a base template for std::char_traits. |
| 76 | // TODO: Remove in LLVM 18. | |
| 76 | // TODO(LLVM-18): Remove this class. | |
| 77 | 77 | // |
| 78 | 78 | template <class _CharT> |
| 79 | 79 | struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 18, so please migrate off of it.") |
| ... | ... | @@ -85,14 +85,14 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha |
| 85 | 85 | using pos_type = streampos; |
| 86 | 86 | using state_type = mbstate_t; |
| 87 | 87 | |
| 88 | static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 88 | static inline void _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_HIDE_FROM_ABI | |
| 89 | 89 | assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} |
| 90 | static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 90 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 91 | 91 | {return __c1 == __c2;} |
| 92 | static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 92 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 93 | 93 | {return __c1 < __c2;} |
| 94 | 94 | |
| 95 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 95 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 96 | 96 | int compare(const char_type* __s1, const char_type* __s2, size_t __n) { |
| 97 | 97 | for (; __n; --__n, ++__s1, ++__s2) |
| 98 | 98 | { |
| ... | ... | @@ -120,7 +120,7 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha |
| 120 | 120 | } |
| 121 | 121 | return nullptr; |
| 122 | 122 | } |
| 123 | static _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 123 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 124 | 124 | char_type* move(char_type* __s1, const char_type* __s2, size_t __n) { |
| 125 | 125 | if (__n == 0) return __s1; |
| 126 | 126 | char_type* __r = __s1; |
| ... | ... | @@ -142,7 +142,8 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha |
| 142 | 142 | static _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 143 | 143 | char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) { |
| 144 | 144 | if (!__libcpp_is_constant_evaluated()) { |
| 145 | _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 145 | _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| 146 | __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range"); | |
| 146 | 147 | } |
| 147 | 148 | char_type* __r = __s1; |
| 148 | 149 | for (; __n; --__n, ++__s1, ++__s2) |
| ... | ... | @@ -158,37 +159,18 @@ struct _LIBCPP_DEPRECATED_("char_traits<T> for T not equal to char, wchar_t, cha |
| 158 | 159 | return __r; |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 162 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 162 | 163 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 163 | static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 164 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 164 | 165 | {return char_type(__c);} |
| 165 | static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 166 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 166 | 167 | {return int_type(__c);} |
| 167 | static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 168 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 168 | 169 | {return __c1 == __c2;} |
| 169 | static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 170 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 170 | 171 | {return int_type(EOF);} |
| 171 | 172 | }; |
| 172 | 173 | |
| 173 | template <class _CharT> | |
| 174 | _LIBCPP_HIDE_FROM_ABI static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 175 | _CharT* __char_traits_move(_CharT* __dest, const _CharT* __source, size_t __n) _NOEXCEPT | |
| 176 | { | |
| 177 | #ifdef _LIBCPP_COMPILER_GCC | |
| 178 | if (__libcpp_is_constant_evaluated()) { | |
| 179 | if (__n == 0) | |
| 180 | return __dest; | |
| 181 | _CharT* __allocation = new _CharT[__n]; | |
| 182 | std::copy_n(__source, __n, __allocation); | |
| 183 | std::copy_n(static_cast<const _CharT*>(__allocation), __n, __dest); | |
| 184 | delete[] __allocation; | |
| 185 | return __dest; | |
| 186 | } | |
| 187 | #endif | |
| 188 | ::__builtin_memmove(__dest, __source, __n * sizeof(_CharT)); | |
| 189 | return __dest; | |
| 190 | } | |
| 191 | ||
| 192 | 174 | // char_traits<char> |
| 193 | 175 | |
| 194 | 176 | template <> |
| ... | ... | @@ -199,62 +181,83 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char> |
| 199 | 181 | using off_type = streamoff; |
| 200 | 182 | using pos_type = streampos; |
| 201 | 183 | using state_type = mbstate_t; |
| 202 | #if _LIBCPP_STD_VER > 17 | |
| 184 | #if _LIBCPP_STD_VER >= 20 | |
| 203 | 185 | using comparison_category = strong_ordering; |
| 204 | 186 | #endif |
| 205 | 187 | |
| 206 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 188 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 207 | 189 | void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} |
| 208 | static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 190 | ||
| 191 | // TODO: Make this _LIBCPP_HIDE_FROM_ABI | |
| 192 | static inline _LIBCPP_HIDDEN _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 209 | 193 | {return __c1 == __c2;} |
| 210 | static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 194 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 211 | 195 | {return (unsigned char)__c1 < (unsigned char)__c2;} |
| 212 | 196 | |
| 213 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { | |
| 214 | if (__n == 0) | |
| 215 | return 0; | |
| 216 | return std::__constexpr_memcmp(__s1, __s2, __n); | |
| 217 | } | |
| 197 | // __constexpr_memcmp requires a trivially lexicographically comparable type, but char is not when char is a signed type | |
| 198 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int | |
| 199 | compare(const char_type* __lhs, const char_type* __rhs, size_t __count) _NOEXCEPT { | |
| 200 | if (__libcpp_is_constant_evaluated()) { | |
| 201 | #ifdef _LIBCPP_COMPILER_CLANG_BASED | |
| 202 | return __builtin_memcmp(__lhs, __rhs, __count); | |
| 203 | #else | |
| 204 | while (__count != 0) { | |
| 205 | if (lt(*__lhs, *__rhs)) | |
| 206 | return -1; | |
| 207 | if (lt(*__rhs, *__lhs)) | |
| 208 | return 1; | |
| 218 | 209 | |
| 219 | static inline size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT { | |
| 220 | return std::__constexpr_strlen(__s); | |
| 221 | } | |
| 210 | __count -= sizeof(char_type); | |
| 211 | ++__lhs; | |
| 212 | ++__rhs; | |
| 213 | } | |
| 214 | return 0; | |
| 215 | #endif // _LIBCPP_COMPILER_CLANG_BASED | |
| 216 | } else { | |
| 217 | return __builtin_memcmp(__lhs, __rhs, __count); | |
| 218 | } | |
| 219 | } | |
| 222 | 220 | |
| 223 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 224 | const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { | |
| 225 | if (__n == 0) | |
| 226 | return nullptr; | |
| 227 | return std::__constexpr_char_memchr(__s, static_cast<int>(__a), __n); | |
| 228 | } | |
| 221 | static inline _LIBCPP_HIDE_FROM_ABI size_t _LIBCPP_CONSTEXPR_SINCE_CXX17 length(const char_type* __s) _NOEXCEPT { | |
| 222 | return std::__constexpr_strlen(__s); | |
| 223 | } | |
| 229 | 224 | |
| 230 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 225 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 226 | const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { | |
| 227 | if (__n == 0) | |
| 228 | return nullptr; | |
| 229 | return std::__constexpr_memchr(__s, __a, __n); | |
| 230 | } | |
| 231 | ||
| 232 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 231 | 233 | char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 232 | return std::__char_traits_move(__s1, __s2, __n); | |
| 234 | return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); | |
| 233 | 235 | } |
| 234 | 236 | |
| 235 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 237 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 236 | 238 | char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 237 | 239 | if (!__libcpp_is_constant_evaluated()) |
| 238 | _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 240 | _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| 241 | __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range"); | |
| 239 | 242 | std::copy_n(__s2, __n, __s1); |
| 240 | 243 | return __s1; |
| 241 | 244 | } |
| 242 | 245 | |
| 243 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 246 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 244 | 247 | char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { |
| 245 | 248 | std::fill_n(__s, __n, __a); |
| 246 | 249 | return __s; |
| 247 | 250 | } |
| 248 | 251 | |
| 249 | static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 252 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 250 | 253 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 251 | static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 254 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 252 | 255 | {return char_type(__c);} |
| 253 | static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 256 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 254 | 257 | {return int_type((unsigned char)__c);} |
| 255 | static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 258 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 256 | 259 | {return __c1 == __c2;} |
| 257 | static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 260 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 258 | 261 | {return int_type(EOF);} |
| 259 | 262 | }; |
| 260 | 263 | |
| ... | ... | @@ -269,62 +272,64 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<wchar_t> |
| 269 | 272 | using off_type = streamoff; |
| 270 | 273 | using pos_type = streampos; |
| 271 | 274 | using state_type = mbstate_t; |
| 272 | #if _LIBCPP_STD_VER > 17 | |
| 275 | #if _LIBCPP_STD_VER >= 20 | |
| 273 | 276 | using comparison_category = strong_ordering; |
| 274 | 277 | #endif |
| 275 | 278 | |
| 276 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 279 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 277 | 280 | void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} |
| 278 | static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 281 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 279 | 282 | {return __c1 == __c2;} |
| 280 | static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 283 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 281 | 284 | {return __c1 < __c2;} |
| 282 | 285 | |
| 283 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 int compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { | |
| 286 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 int | |
| 287 | compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { | |
| 284 | 288 | if (__n == 0) |
| 285 | return 0; | |
| 289 | return 0; | |
| 286 | 290 | return std::__constexpr_wmemcmp(__s1, __s2, __n); |
| 287 | 291 | } |
| 288 | 292 | |
| 289 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT { | |
| 293 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 size_t length(const char_type* __s) _NOEXCEPT { | |
| 290 | 294 | return std::__constexpr_wcslen(__s); |
| 291 | 295 | } |
| 292 | 296 | |
| 293 | static _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 297 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 294 | 298 | const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT { |
| 295 | 299 | if (__n == 0) |
| 296 | 300 | return nullptr; |
| 297 | 301 | return std::__constexpr_wmemchr(__s, __a, __n); |
| 298 | 302 | } |
| 299 | 303 | |
| 300 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 304 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 301 | 305 | char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 302 | return std::__char_traits_move(__s1, __s2, __n); | |
| 306 | return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); | |
| 303 | 307 | } |
| 304 | 308 | |
| 305 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 309 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 306 | 310 | char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 307 | 311 | if (!__libcpp_is_constant_evaluated()) |
| 308 | _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 312 | _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| 313 | __s2 < __s1 || __s2 >= __s1 + __n, "char_traits::copy overlapped range"); | |
| 309 | 314 | std::copy_n(__s2, __n, __s1); |
| 310 | 315 | return __s1; |
| 311 | 316 | } |
| 312 | 317 | |
| 313 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 318 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 314 | 319 | char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { |
| 315 | 320 | std::fill_n(__s, __n, __a); |
| 316 | 321 | return __s; |
| 317 | 322 | } |
| 318 | 323 | |
| 319 | static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 324 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 320 | 325 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 321 | static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 326 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 322 | 327 | {return char_type(__c);} |
| 323 | static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 328 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 324 | 329 | {return int_type(__c);} |
| 325 | static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 330 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 326 | 331 | {return __c1 == __c2;} |
| 327 | static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 332 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 328 | 333 | {return int_type(WEOF);} |
| 329 | 334 | }; |
| 330 | 335 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -339,56 +344,57 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char8_t> |
| 339 | 344 | using off_type = streamoff; |
| 340 | 345 | using pos_type = u8streampos; |
| 341 | 346 | using state_type = mbstate_t; |
| 342 | #if _LIBCPP_STD_VER > 17 | |
| 347 | #if _LIBCPP_STD_VER >= 20 | |
| 343 | 348 | using comparison_category = strong_ordering; |
| 344 | 349 | #endif |
| 345 | 350 | |
| 346 | static inline constexpr void assign(char_type& __c1, const char_type& __c2) noexcept | |
| 351 | static inline _LIBCPP_HIDE_FROM_ABI constexpr void assign(char_type& __c1, const char_type& __c2) noexcept | |
| 347 | 352 | {__c1 = __c2;} |
| 348 | static inline constexpr bool eq(char_type __c1, char_type __c2) noexcept | |
| 353 | static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq(char_type __c1, char_type __c2) noexcept | |
| 349 | 354 | {return __c1 == __c2;} |
| 350 | static inline constexpr bool lt(char_type __c1, char_type __c2) noexcept | |
| 355 | static inline _LIBCPP_HIDE_FROM_ABI constexpr bool lt(char_type __c1, char_type __c2) noexcept | |
| 351 | 356 | {return __c1 < __c2;} |
| 352 | 357 | |
| 353 | 358 | static _LIBCPP_HIDE_FROM_ABI constexpr int |
| 354 | 359 | compare(const char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 355 | return std::__constexpr_memcmp(__s1, __s2, __n); | |
| 360 | return std::__constexpr_memcmp(__s1, __s2, __element_count(__n)); | |
| 356 | 361 | } |
| 357 | 362 | |
| 358 | static constexpr | |
| 363 | static _LIBCPP_HIDE_FROM_ABI constexpr | |
| 359 | 364 | size_t length(const char_type* __s) _NOEXCEPT; |
| 360 | 365 | |
| 361 | 366 | _LIBCPP_INLINE_VISIBILITY static constexpr |
| 362 | 367 | const char_type* find(const char_type* __s, size_t __n, const char_type& __a) _NOEXCEPT; |
| 363 | 368 | |
| 364 | static _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 369 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 365 | 370 | char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 366 | return std::__char_traits_move(__s1, __s2, __n); | |
| 371 | return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); | |
| 367 | 372 | } |
| 368 | 373 | |
| 369 | static _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 374 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 370 | 375 | char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 371 | 376 | if (!__libcpp_is_constant_evaluated()) |
| 372 | _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 377 | _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| 378 | __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 373 | 379 | std::copy_n(__s2, __n, __s1); |
| 374 | 380 | return __s1; |
| 375 | 381 | } |
| 376 | 382 | |
| 377 | static _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 383 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 378 | 384 | char_type* assign(char_type* __s, size_t __n, char_type __a) _NOEXCEPT { |
| 379 | 385 | std::fill_n(__s, __n, __a); |
| 380 | 386 | return __s; |
| 381 | 387 | } |
| 382 | 388 | |
| 383 | static inline constexpr int_type not_eof(int_type __c) noexcept | |
| 389 | static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type not_eof(int_type __c) noexcept | |
| 384 | 390 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 385 | static inline constexpr char_type to_char_type(int_type __c) noexcept | |
| 391 | static inline _LIBCPP_HIDE_FROM_ABI constexpr char_type to_char_type(int_type __c) noexcept | |
| 386 | 392 | {return char_type(__c);} |
| 387 | static inline constexpr int_type to_int_type(char_type __c) noexcept | |
| 393 | static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type to_int_type(char_type __c) noexcept | |
| 388 | 394 | {return int_type(__c);} |
| 389 | static inline constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept | |
| 395 | static inline _LIBCPP_HIDE_FROM_ABI constexpr bool eq_int_type(int_type __c1, int_type __c2) noexcept | |
| 390 | 396 | {return __c1 == __c2;} |
| 391 | static inline constexpr int_type eof() noexcept | |
| 397 | static inline _LIBCPP_HIDE_FROM_ABI constexpr int_type eof() noexcept | |
| 392 | 398 | {return int_type(EOF);} |
| 393 | 399 | }; |
| 394 | 400 | |
| ... | ... | @@ -427,15 +433,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> |
| 427 | 433 | using off_type = streamoff; |
| 428 | 434 | using pos_type = u16streampos; |
| 429 | 435 | using state_type = mbstate_t; |
| 430 | #if _LIBCPP_STD_VER > 17 | |
| 436 | #if _LIBCPP_STD_VER >= 20 | |
| 431 | 437 | using comparison_category = strong_ordering; |
| 432 | 438 | #endif |
| 433 | 439 | |
| 434 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 440 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 435 | 441 | void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} |
| 436 | static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 442 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 437 | 443 | {return __c1 == __c2;} |
| 438 | static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 444 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 439 | 445 | {return __c1 < __c2;} |
| 440 | 446 | |
| 441 | 447 | _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| ... | ... | @@ -447,13 +453,14 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> |
| 447 | 453 | |
| 448 | 454 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 449 | 455 | static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 450 | return std::__char_traits_move(__s1, __s2, __n); | |
| 456 | return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); | |
| 451 | 457 | } |
| 452 | 458 | |
| 453 | 459 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 454 | 460 | static char_type* copy(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 455 | 461 | if (!__libcpp_is_constant_evaluated()) |
| 456 | _LIBCPP_ASSERT(__s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 462 | _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES( | |
| 463 | __s2 < __s1 || __s2 >= __s1+__n, "char_traits::copy overlapped range"); | |
| 457 | 464 | std::copy_n(__s2, __n, __s1); |
| 458 | 465 | return __s1; |
| 459 | 466 | } |
| ... | ... | @@ -464,15 +471,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char16_t> |
| 464 | 471 | return __s; |
| 465 | 472 | } |
| 466 | 473 | |
| 467 | static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 474 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 468 | 475 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 469 | static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 476 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 470 | 477 | {return char_type(__c);} |
| 471 | static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 478 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 472 | 479 | {return int_type(__c);} |
| 473 | static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 480 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 474 | 481 | {return __c1 == __c2;} |
| 475 | static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 482 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 476 | 483 | {return int_type(0xFFFF);} |
| 477 | 484 | }; |
| 478 | 485 | |
| ... | ... | @@ -521,15 +528,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> |
| 521 | 528 | using off_type = streamoff; |
| 522 | 529 | using pos_type = u32streampos; |
| 523 | 530 | using state_type = mbstate_t; |
| 524 | #if _LIBCPP_STD_VER > 17 | |
| 531 | #if _LIBCPP_STD_VER >= 20 | |
| 525 | 532 | using comparison_category = strong_ordering; |
| 526 | 533 | #endif |
| 527 | 534 | |
| 528 | static inline _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 535 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 | |
| 529 | 536 | void assign(char_type& __c1, const char_type& __c2) _NOEXCEPT {__c1 = __c2;} |
| 530 | static inline _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 537 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq(char_type __c1, char_type __c2) _NOEXCEPT | |
| 531 | 538 | {return __c1 == __c2;} |
| 532 | static inline _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 539 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool lt(char_type __c1, char_type __c2) _NOEXCEPT | |
| 533 | 540 | {return __c1 < __c2;} |
| 534 | 541 | |
| 535 | 542 | _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| ... | ... | @@ -541,7 +548,7 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> |
| 541 | 548 | |
| 542 | 549 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 543 | 550 | static char_type* move(char_type* __s1, const char_type* __s2, size_t __n) _NOEXCEPT { |
| 544 | return std::__char_traits_move(__s1, __s2, __n); | |
| 551 | return std::__constexpr_memmove(__s1, __s2, __element_count(__n)); | |
| 545 | 552 | } |
| 546 | 553 | |
| 547 | 554 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -556,15 +563,15 @@ struct _LIBCPP_TEMPLATE_VIS char_traits<char32_t> |
| 556 | 563 | return __s; |
| 557 | 564 | } |
| 558 | 565 | |
| 559 | static inline _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 566 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type not_eof(int_type __c) _NOEXCEPT | |
| 560 | 567 | {return eq_int_type(__c, eof()) ? ~eof() : __c;} |
| 561 | static inline _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 568 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR char_type to_char_type(int_type __c) _NOEXCEPT | |
| 562 | 569 | {return char_type(__c);} |
| 563 | static inline _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 570 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type to_int_type(char_type __c) _NOEXCEPT | |
| 564 | 571 | {return int_type(__c);} |
| 565 | static inline _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 572 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool eq_int_type(int_type __c1, int_type __c2) _NOEXCEPT | |
| 566 | 573 | {return __c1 == __c2;} |
| 567 | static inline _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 574 | static inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int_type eof() _NOEXCEPT | |
| 568 | 575 | {return int_type(0xFFFFFFFF);} |
| 569 | 576 | }; |
| 570 | 577 |
lib/libcxx/include/__string/constexpr_c_functions.h created+219| ... | ... | @@ -0,0 +1,219 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H | |
| 10 | #define _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__memory/addressof.h> | |
| 14 | #include <__memory/construct_at.h> | |
| 15 | #include <__type_traits/datasizeof.h> | |
| 16 | #include <__type_traits/is_always_bitcastable.h> | |
| 17 | #include <__type_traits/is_assignable.h> | |
| 18 | #include <__type_traits/is_constant_evaluated.h> | |
| 19 | #include <__type_traits/is_constructible.h> | |
| 20 | #include <__type_traits/is_equality_comparable.h> | |
| 21 | #include <__type_traits/is_same.h> | |
| 22 | #include <__type_traits/is_trivially_copyable.h> | |
| 23 | #include <__type_traits/is_trivially_lexicographically_comparable.h> | |
| 24 | #include <__type_traits/remove_cv.h> | |
| 25 | #include <__utility/is_pointer_in_range.h> | |
| 26 | #include <cstddef> | |
| 27 | ||
| 28 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 29 | # pragma GCC system_header | |
| 30 | #endif | |
| 31 | ||
| 32 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 33 | ||
| 34 | // Type used to encode that a function takes an integer that represents a number | |
| 35 | // of elements as opposed to a number of bytes. | |
| 36 | enum class __element_count : size_t {}; | |
| 37 | ||
| 38 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) { | |
| 39 | // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation. | |
| 40 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816 | |
| 41 | #ifdef _LIBCPP_COMPILER_GCC | |
| 42 | if (__libcpp_is_constant_evaluated()) { | |
| 43 | size_t __i = 0; | |
| 44 | for (; __str[__i] != '\0'; ++__i) | |
| 45 | ; | |
| 46 | return __i; | |
| 47 | } | |
| 48 | #endif | |
| 49 | return __builtin_strlen(__str); | |
| 50 | } | |
| 51 | ||
| 52 | // Because of __libcpp_is_trivially_lexicographically_comparable we know that comparing the object representations is | |
| 53 | // equivalent to a std::memcmp. Since we have multiple objects contiguously in memory, we can call memcmp once instead | |
| 54 | // of invoking it on every object individually. | |
| 55 | template <class _Tp, class _Up> | |
| 56 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int | |
| 57 | __constexpr_memcmp(const _Tp* __lhs, const _Up* __rhs, __element_count __n) { | |
| 58 | static_assert(__libcpp_is_trivially_lexicographically_comparable<_Tp, _Up>::value, | |
| 59 | "_Tp and _Up have to be trivially lexicographically comparable"); | |
| 60 | ||
| 61 | auto __count = static_cast<size_t>(__n); | |
| 62 | ||
| 63 | if (__libcpp_is_constant_evaluated()) { | |
| 64 | #ifdef _LIBCPP_COMPILER_CLANG_BASED | |
| 65 | if (sizeof(_Tp) == 1 && !is_same<_Tp, bool>::value) | |
| 66 | return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)); | |
| 67 | #endif | |
| 68 | ||
| 69 | while (__count != 0) { | |
| 70 | if (*__lhs < *__rhs) | |
| 71 | return -1; | |
| 72 | if (*__rhs < *__lhs) | |
| 73 | return 1; | |
| 74 | ||
| 75 | --__count; | |
| 76 | ++__lhs; | |
| 77 | ++__rhs; | |
| 78 | } | |
| 79 | return 0; | |
| 80 | } else { | |
| 81 | return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)); | |
| 82 | } | |
| 83 | } | |
| 84 | ||
| 85 | // Because of __libcpp_is_trivially_equality_comparable we know that comparing the object representations is equivalent | |
| 86 | // to a std::memcmp(...) == 0. Since we have multiple objects contiguously in memory, we can call memcmp once instead | |
| 87 | // of invoking it on every object individually. | |
| 88 | template <class _Tp, class _Up> | |
| 89 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool | |
| 90 | __constexpr_memcmp_equal(const _Tp* __lhs, const _Up* __rhs, __element_count __n) { | |
| 91 | static_assert(__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, | |
| 92 | "_Tp and _Up have to be trivially equality comparable"); | |
| 93 | ||
| 94 | auto __count = static_cast<size_t>(__n); | |
| 95 | ||
| 96 | if (__libcpp_is_constant_evaluated()) { | |
| 97 | #ifdef _LIBCPP_COMPILER_CLANG_BASED | |
| 98 | if (sizeof(_Tp) == 1 && is_integral<_Tp>::value && !is_same<_Tp, bool>::value) | |
| 99 | return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0; | |
| 100 | #endif | |
| 101 | while (__count != 0) { | |
| 102 | if (*__lhs != *__rhs) | |
| 103 | return false; | |
| 104 | ||
| 105 | --__count; | |
| 106 | ++__lhs; | |
| 107 | ++__rhs; | |
| 108 | } | |
| 109 | return true; | |
| 110 | } else { | |
| 111 | return __builtin_memcmp(__lhs, __rhs, __count * sizeof(_Tp)) == 0; | |
| 112 | } | |
| 113 | } | |
| 114 | ||
| 115 | template <class _Tp, class _Up> | |
| 116 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_memchr(_Tp* __str, _Up __value, size_t __count) { | |
| 117 | static_assert(sizeof(_Tp) == 1 && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, | |
| 118 | "Calling memchr on non-trivially equality comparable types is unsafe."); | |
| 119 | ||
| 120 | if (__libcpp_is_constant_evaluated()) { | |
| 121 | // use __builtin_char_memchr to optimize constexpr evaluation if we can | |
| 122 | #if _LIBCPP_STD_VER >= 17 && __has_builtin(__builtin_char_memchr) | |
| 123 | if constexpr (is_same_v<remove_cv_t<_Tp>, char> && is_same_v<remove_cv_t<_Up>, char>) | |
| 124 | return __builtin_char_memchr(__str, __value, __count); | |
| 125 | #endif | |
| 126 | ||
| 127 | for (; __count; --__count) { | |
| 128 | if (*__str == __value) | |
| 129 | return __str; | |
| 130 | ++__str; | |
| 131 | } | |
| 132 | return nullptr; | |
| 133 | } else { | |
| 134 | char __value_buffer = 0; | |
| 135 | __builtin_memcpy(&__value_buffer, &__value, sizeof(char)); | |
| 136 | return static_cast<_Tp*>(__builtin_memchr(__str, __value_buffer, __count)); | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 | // This function performs an assignment to an existing, already alive TriviallyCopyable object | |
| 141 | // from another TriviallyCopyable object. | |
| 142 | // | |
| 143 | // It basically works around the fact that TriviallyCopyable objects are not required to be | |
| 144 | // syntactically copy/move constructible or copy/move assignable. Technically, only one of the | |
| 145 | // four operations is required to be syntactically valid -- but at least one definitely has to | |
| 146 | // be valid. | |
| 147 | // | |
| 148 | // This is necessary in order to implement __constexpr_memmove below in a way that mirrors as | |
| 149 | // closely as possible what the compiler's __builtin_memmove is able to do. | |
| 150 | template <class _Tp, class _Up, __enable_if_t<is_assignable<_Tp&, _Up const&>::value, int> = 0> | |
| 151 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) { | |
| 152 | __dest = __src; | |
| 153 | return __dest; | |
| 154 | } | |
| 155 | ||
| 156 | // clang-format off | |
| 157 | template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value && | |
| 158 | is_assignable<_Tp&, _Up&&>::value, int> = 0> | |
| 159 | // clang-format on | |
| 160 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) { | |
| 161 | __dest = | |
| 162 | static_cast<_Up&&>(__src); // this is safe, we're not actually moving anything since the assignment is trivial | |
| 163 | return __dest; | |
| 164 | } | |
| 165 | ||
| 166 | // clang-format off | |
| 167 | template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value && | |
| 168 | !is_assignable<_Tp&, _Up&&>::value && | |
| 169 | is_constructible<_Tp, _Up const&>::value, int> = 0> | |
| 170 | // clang-format on | |
| 171 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up const& __src) { | |
| 172 | // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object | |
| 173 | // that was there previously | |
| 174 | std::__construct_at(std::addressof(__dest), __src); | |
| 175 | return __dest; | |
| 176 | } | |
| 177 | ||
| 178 | // clang-format off | |
| 179 | template <class _Tp, class _Up, __enable_if_t<!is_assignable<_Tp&, _Up const&>::value && | |
| 180 | !is_assignable<_Tp&, _Up&&>::value && | |
| 181 | !is_constructible<_Tp, _Up const&>::value && | |
| 182 | is_constructible<_Tp, _Up&&>::value, int> = 0> | |
| 183 | // clang-format on | |
| 184 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __assign_trivially_copyable(_Tp& __dest, _Up& __src) { | |
| 185 | // _Tp is trivially destructible, so we don't need to call its destructor to end the lifetime of the object | |
| 186 | // that was there previously | |
| 187 | std::__construct_at( | |
| 188 | std::addressof(__dest), | |
| 189 | static_cast<_Up&&>(__src)); // this is safe, we're not actually moving anything since the constructor is trivial | |
| 190 | return __dest; | |
| 191 | } | |
| 192 | ||
| 193 | template <class _Tp, class _Up, __enable_if_t<__is_always_bitcastable<_Up, _Tp>::value, int> = 0> | |
| 194 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* | |
| 195 | __constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n) { | |
| 196 | size_t __count = static_cast<size_t>(__n); | |
| 197 | if (__libcpp_is_constant_evaluated()) { | |
| 198 | #ifdef _LIBCPP_COMPILER_CLANG_BASED | |
| 199 | if (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value) { | |
| 200 | ::__builtin_memmove(__dest, __src, __count * sizeof(_Tp)); | |
| 201 | return __dest; | |
| 202 | } | |
| 203 | #endif | |
| 204 | if (std::__is_pointer_in_range(__src, __src + __count, __dest)) { | |
| 205 | for (; __count > 0; --__count) | |
| 206 | std::__assign_trivially_copyable(__dest[__count - 1], __src[__count - 1]); | |
| 207 | } else { | |
| 208 | for (size_t __i = 0; __i != __count; ++__i) | |
| 209 | std::__assign_trivially_copyable(__dest[__i], __src[__i]); | |
| 210 | } | |
| 211 | } else if (__count > 0) { | |
| 212 | ::__builtin_memmove(__dest, __src, (__count - 1) * sizeof(_Tp) + __libcpp_datasizeof<_Tp>::value); | |
| 213 | } | |
| 214 | return __dest; | |
| 215 | } | |
| 216 | ||
| 217 | _LIBCPP_END_NAMESPACE_STD | |
| 218 | ||
| 219 | #endif // _LIBCPP___STRING_CONSTEXPR_C_FUNCTIONS_H |
lib/libcxx/include/__string/extern_template_lists.h+95-96| ... | ... | @@ -28,104 +28,103 @@ |
| 28 | 28 | // functions supporting new c++ version / API changes. Typically entries |
| 29 | 29 | // must never be removed from the stable list. |
| 30 | 30 | #define _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_Func, _CharType) \ |
| 31 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ | |
| 32 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ | |
| 33 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ | |
| 34 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&)) \ | |
| 35 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ | |
| 36 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \ | |
| 37 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ | |
| 38 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \ | |
| 39 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ | |
| 40 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ | |
| 41 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ | |
| 42 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \ | |
| 43 | _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \ | |
| 44 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ | |
| 45 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ | |
| 46 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ | |
| 47 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \ | |
| 48 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \ | |
| 49 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ | |
| 50 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ | |
| 51 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ | |
| 52 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \ | |
| 53 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ | |
| 54 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \ | |
| 55 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ | |
| 56 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ | |
| 57 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ | |
| 58 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ | |
| 59 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \ | |
| 60 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ | |
| 61 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ | |
| 62 | _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ | |
| 63 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ | |
| 64 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \ | |
| 65 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ | |
| 66 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \ | |
| 67 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ | |
| 68 | _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \ | |
| 69 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \ | |
| 70 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ | |
| 71 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ | |
| 72 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ | |
| 73 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \ | |
| 74 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ | |
| 75 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ | |
| 76 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ | |
| 77 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \ | |
| 78 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) | |
| 31 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ | |
| 32 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ | |
| 33 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ | |
| 34 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&)) \ | |
| 35 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ | |
| 36 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, allocator<_CharType> const&)) \ | |
| 37 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ | |
| 38 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \ | |
| 39 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ | |
| 40 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ | |
| 41 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ | |
| 42 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \ | |
| 43 | _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \ | |
| 44 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ | |
| 45 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ | |
| 46 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ | |
| 47 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*, size_type)) \ | |
| 48 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \ | |
| 49 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ | |
| 50 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ | |
| 51 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ | |
| 52 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \ | |
| 53 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ | |
| 54 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \ | |
| 55 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ | |
| 56 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ | |
| 57 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ | |
| 58 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ | |
| 59 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \ | |
| 60 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ | |
| 61 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ | |
| 62 | _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ | |
| 63 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ | |
| 64 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::erase(size_type, size_type)) \ | |
| 65 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ | |
| 66 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \ | |
| 67 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ | |
| 68 | _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \ | |
| 69 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(value_type const*)) \ | |
| 70 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ | |
| 71 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ | |
| 72 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ | |
| 73 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(basic_string const&)) \ | |
| 74 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ | |
| 75 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ | |
| 76 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ | |
| 77 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \ | |
| 78 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) | |
| 79 | 79 | |
| 80 | 80 | #define _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_Func, _CharType) \ |
| 81 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ | |
| 82 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ | |
| 83 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ | |
| 84 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ | |
| 85 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ | |
| 86 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::~basic_string()) \ | |
| 87 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ | |
| 88 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ | |
| 89 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ | |
| 90 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(value_type const*, size_type)) \ | |
| 91 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \ | |
| 92 | _Func(_LIBCPP_FUNC_VIS const _CharType& basic_string<_CharType>::at(size_type) const) \ | |
| 93 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ | |
| 94 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ | |
| 95 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ | |
| 96 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \ | |
| 97 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \ | |
| 98 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::reserve(size_type)) \ | |
| 99 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ | |
| 100 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ | |
| 101 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ | |
| 102 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \ | |
| 103 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ | |
| 104 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__init(size_type, value_type)) \ | |
| 105 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ | |
| 106 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ | |
| 107 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by(size_type, size_type, size_type, size_type, size_type, size_type)) \ | |
| 108 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ | |
| 109 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \ | |
| 110 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \ | |
| 111 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::push_back(value_type)) \ | |
| 112 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ | |
| 113 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ | |
| 114 | _Func(_LIBCPP_FUNC_VIS const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ | |
| 115 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ | |
| 116 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \ | |
| 117 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ | |
| 118 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(value_type const*) const) \ | |
| 119 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ | |
| 120 | _Func(_LIBCPP_FUNC_VIS _CharType& basic_string<_CharType>::at(size_type)) \ | |
| 121 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ | |
| 122 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ | |
| 123 | _Func(_LIBCPP_FUNC_VIS int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ | |
| 124 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ | |
| 125 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ | |
| 126 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ | |
| 127 | _Func(_LIBCPP_FUNC_VIS void basic_string<_CharType>::resize(size_type, value_type)) \ | |
| 128 | _Func(_LIBCPP_FUNC_VIS basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) | |
| 81 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*, size_type)) \ | |
| 82 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type const*, size_type, size_type) const) \ | |
| 83 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type, size_type)) \ | |
| 84 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, value_type const*)) \ | |
| 85 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_not_of(value_type const*, size_type, size_type) const) \ | |
| 86 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::~basic_string()) \ | |
| 87 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_not_of(value_type const*, size_type, size_type) const) \ | |
| 88 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, size_type, value_type)) \ | |
| 89 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::operator=(value_type)) \ | |
| 90 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(value_type const*, size_type)) \ | |
| 91 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init_copy_ctor_external(value_type const*, size_type)) \ | |
| 92 | _Func(_LIBCPP_EXPORTED_FROM_ABI const _CharType& basic_string<_CharType>::at(size_type) const) \ | |
| 93 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*, size_type)) \ | |
| 94 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_first_of(value_type const*, size_type, size_type) const) \ | |
| 95 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, size_type, value_type)) \ | |
| 96 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*, size_type)) \ | |
| 97 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_external(value_type const*)) \ | |
| 98 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::reserve(size_type)) \ | |
| 99 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*, size_type)) \ | |
| 100 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(basic_string const&, size_type, size_type)) \ | |
| 101 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::copy(value_type*, size_type, size_type) const) \ | |
| 102 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::basic_string(basic_string const&, size_type, size_type, allocator<_CharType> const&)) \ | |
| 103 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type, size_type) const) \ | |
| 104 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__init(size_type, value_type)) \ | |
| 105 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, value_type const*)) \ | |
| 106 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find_last_of(value_type const*, size_type, size_type) const) \ | |
| 107 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__grow_by_and_replace(size_type, size_type, size_type, size_type, size_type, size_type, value_type const*)) \ | |
| 108 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<false>(value_type const*, size_type)) \ | |
| 109 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::__assign_no_alias<true>(value_type const*, size_type)) \ | |
| 110 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::push_back(value_type)) \ | |
| 111 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(size_type, value_type)) \ | |
| 112 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::rfind(value_type, size_type) const) \ | |
| 113 | _Func(_LIBCPP_EXPORTED_FROM_ABI const basic_string<_CharType>::size_type basic_string<_CharType>::npos) \ | |
| 114 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::assign(size_type, value_type)) \ | |
| 115 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::__erase_external_with_move(size_type, size_type)) \ | |
| 116 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(basic_string const&, size_type, size_type)) \ | |
| 117 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(value_type const*) const) \ | |
| 118 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*) const) \ | |
| 119 | _Func(_LIBCPP_EXPORTED_FROM_ABI _CharType& basic_string<_CharType>::at(size_type)) \ | |
| 120 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::size_type basic_string<_CharType>::find(value_type const*, size_type, size_type) const) \ | |
| 121 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, basic_string const&, size_type, size_type) const) \ | |
| 122 | _Func(_LIBCPP_EXPORTED_FROM_ABI int basic_string<_CharType>::compare(size_type, size_type, value_type const*, size_type) const) \ | |
| 123 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::append(value_type const*)) \ | |
| 124 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::replace(size_type, size_type, basic_string const&, size_type, size_type)) \ | |
| 125 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>::iterator basic_string<_CharType>::insert(basic_string::const_iterator, value_type)) \ | |
| 126 | _Func(_LIBCPP_EXPORTED_FROM_ABI void basic_string<_CharType>::resize(size_type, value_type)) \ | |
| 127 | _Func(_LIBCPP_EXPORTED_FROM_ABI basic_string<_CharType>& basic_string<_CharType>::insert(size_type, basic_string const&, size_type, size_type)) | |
| 129 | 128 | |
| 130 | 129 | |
| 131 | 130 | #endif // _LIBCPP___STRING_EXTERN_TEMPLATE_LISTS_H |
lib/libcxx/include/__support/musl/xlocale.h+2-1| ... | ... | @@ -37,7 +37,8 @@ inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoll_l(const wchar_t* __nptr, wchar_ |
| 37 | 37 | return ::wcstoll(__nptr, __endptr, __base); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | inline _LIBCPP_HIDE_FROM_ABI_C long long wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { | |
| 40 | inline _LIBCPP_HIDE_FROM_ABI_C unsigned long long | |
| 41 | wcstoull_l(const wchar_t* __nptr, wchar_t** __endptr, int __base, locale_t) { | |
| 41 | 42 | return ::wcstoull(__nptr, __endptr, __base); |
| 42 | 43 | } |
| 43 | 44 |
lib/libcxx/include/__support/solaris/floatingpoint.h deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #define atof sun_atof | |
| 10 | #define strtod sun_strtod | |
| 11 | #include_next "floatingpoint.h" | |
| 12 | #undef atof | |
| 13 | #undef strtod |
lib/libcxx/include/__support/solaris/wchar.h deleted-46| ... | ... | @@ -1,46 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #define iswalpha sun_iswalpha | |
| 10 | #define iswupper sun_iswupper | |
| 11 | #define iswlower sun_iswlower | |
| 12 | #define iswdigit sun_iswdigit | |
| 13 | #define iswxdigit sun_iswxdigit | |
| 14 | #define iswalnum sun_iswalnum | |
| 15 | #define iswspace sun_iswspace | |
| 16 | #define iswpunct sun_iswpunct | |
| 17 | #define iswprint sun_iswprint | |
| 18 | #define iswgraph sun_iswgraph | |
| 19 | #define iswcntrl sun_iswcntrl | |
| 20 | #define iswctype sun_iswctype | |
| 21 | #define towlower sun_towlower | |
| 22 | #define towupper sun_towupper | |
| 23 | #define wcswcs sun_wcswcs | |
| 24 | #define wcswidth sun_wcswidth | |
| 25 | #define wcwidth sun_wcwidth | |
| 26 | #define wctype sun_wctype | |
| 27 | #define _WCHAR_T 1 | |
| 28 | #include_next "wchar.h" | |
| 29 | #undef iswalpha | |
| 30 | #undef iswupper | |
| 31 | #undef iswlower | |
| 32 | #undef iswdigit | |
| 33 | #undef iswxdigit | |
| 34 | #undef iswalnum | |
| 35 | #undef iswspace | |
| 36 | #undef iswpunct | |
| 37 | #undef iswprint | |
| 38 | #undef iswgraph | |
| 39 | #undef iswcntrl | |
| 40 | #undef iswctype | |
| 41 | #undef towlower | |
| 42 | #undef towupper | |
| 43 | #undef wcswcs | |
| 44 | #undef wcswidth | |
| 45 | #undef wcwidth | |
| 46 | #undef wctype |
lib/libcxx/include/__support/solaris/xlocale.h deleted-75| ... | ... | @@ -1,75 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | //////////////////////////////////////////////////////////////////////////////// | |
| 10 | // Minimal xlocale implementation for Solaris. This implements the subset of | |
| 11 | // the xlocale APIs that libc++ depends on. | |
| 12 | //////////////////////////////////////////////////////////////////////////////// | |
| 13 | #ifndef __XLOCALE_H_INCLUDED | |
| 14 | #define __XLOCALE_H_INCLUDED | |
| 15 | ||
| 16 | #include <stdlib.h> | |
| 17 | ||
| 18 | #ifdef __cplusplus | |
| 19 | extern "C" { | |
| 20 | #endif | |
| 21 | ||
| 22 | ||
| 23 | int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...); | |
| 24 | int asprintf_l(char **__s, locale_t __l, const char *__format, ...); | |
| 25 | ||
| 26 | int sscanf_l(const char *__s, locale_t __l, const char *__format, ...); | |
| 27 | ||
| 28 | int toupper_l(int __c, locale_t __l); | |
| 29 | int tolower_l(int __c, locale_t __l); | |
| 30 | ||
| 31 | struct lconv *localeconv(void); | |
| 32 | struct lconv *localeconv_l(locale_t __l); | |
| 33 | ||
| 34 | // FIXME: These are quick-and-dirty hacks to make things pretend to work | |
| 35 | inline _LIBCPP_HIDE_FROM_ABI long long | |
| 36 | strtoll_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) { | |
| 37 | return ::strtoll(__nptr, __endptr, __base); | |
| 38 | } | |
| 39 | ||
| 40 | inline _LIBCPP_HIDE_FROM_ABI long | |
| 41 | strtol_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) { | |
| 42 | return ::strtol(__nptr, __endptr, __base); | |
| 43 | } | |
| 44 | ||
| 45 | inline _LIBCPP_HIDE_FROM_ABI unsigned long long | |
| 46 | strtoull_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) | |
| 47 | return ::strtoull(__nptr, __endptr, __base); | |
| 48 | } | |
| 49 | ||
| 50 | inline _LIBCPP_HIDE_FROM_ABI unsigned long | |
| 51 | strtoul_l(const char *__nptr, char **__endptr, int __base, locale_t __loc) { | |
| 52 | return ::strtoul(__nptr, __endptr, __base); | |
| 53 | } | |
| 54 | ||
| 55 | inline _LIBCPP_HIDE_FROM_ABI float | |
| 56 | strtof_l(const char *__nptr, char **__endptr, locale_t __loc) { | |
| 57 | return ::strtof(__nptr, __endptr); | |
| 58 | } | |
| 59 | ||
| 60 | inline _LIBCPP_HIDE_FROM_ABI double | |
| 61 | strtod_l(const char *__nptr, char **__endptr, locale_t __loc) { | |
| 62 | return ::strtod(__nptr, __endptr); | |
| 63 | } | |
| 64 | ||
| 65 | inline _LIBCPP_HIDE_FROM_ABI long double | |
| 66 | strtold_l(const char *__nptr, char **__endptr, locale_t __loc) { | |
| 67 | return ::strtold(__nptr, __endptr); | |
| 68 | } | |
| 69 | ||
| 70 | ||
| 71 | #ifdef __cplusplus | |
| 72 | } | |
| 73 | #endif | |
| 74 | ||
| 75 | #endif |
lib/libcxx/include/__support/win32/locale_win32.h+6-6| ... | ... | @@ -221,8 +221,8 @@ decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ); |
| 221 | 221 | #define strtof_l _strtof_l |
| 222 | 222 | #define strtold_l _strtold_l |
| 223 | 223 | #else |
| 224 | _LIBCPP_FUNC_VIS float strtof_l(const char*, char**, locale_t); | |
| 225 | _LIBCPP_FUNC_VIS long double strtold_l(const char*, char**, locale_t); | |
| 224 | _LIBCPP_EXPORTED_FROM_ABI float strtof_l(const char*, char**, locale_t); | |
| 225 | _LIBCPP_EXPORTED_FROM_ABI long double strtold_l(const char*, char**, locale_t); | |
| 226 | 226 | #endif |
| 227 | 227 | inline _LIBCPP_HIDE_FROM_ABI int |
| 228 | 228 | islower_l(int __c, _locale_t __loc) |
| ... | ... | @@ -256,7 +256,7 @@ isupper_l(int __c, _locale_t __loc) |
| 256 | 256 | #define towupper_l _towupper_l |
| 257 | 257 | #define towlower_l _towlower_l |
| 258 | 258 | #if defined(__MINGW32__) && __MSVCRT_VERSION__ < 0x0800 |
| 259 | _LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format, | |
| 259 | _LIBCPP_EXPORTED_FROM_ABI size_t strftime_l(char *ret, size_t n, const char *format, | |
| 260 | 260 | const struct tm *tm, locale_t loc); |
| 261 | 261 | #else |
| 262 | 262 | #define strftime_l _strftime_l |
| ... | ... | @@ -265,9 +265,9 @@ _LIBCPP_FUNC_VIS size_t strftime_l(char *ret, size_t n, const char *format, |
| 265 | 265 | #define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ ) |
| 266 | 266 | #define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ ) |
| 267 | 267 | #define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ ) |
| 268 | _LIBCPP_FUNC_VIS int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...); | |
| 269 | _LIBCPP_FUNC_VIS int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... ); | |
| 270 | _LIBCPP_FUNC_VIS int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap ); | |
| 268 | _LIBCPP_EXPORTED_FROM_ABI int snprintf_l(char *__ret, size_t __n, locale_t __loc, const char *__format, ...); | |
| 269 | _LIBCPP_EXPORTED_FROM_ABI int asprintf_l( char **__ret, locale_t __loc, const char *__format, ... ); | |
| 270 | _LIBCPP_EXPORTED_FROM_ABI int vasprintf_l( char **__ret, locale_t __loc, const char *__format, va_list __ap ); | |
| 271 | 271 | |
| 272 | 272 | // not-so-pressing FIXME: use locale to determine blank characters |
| 273 | 273 | inline int isblank_l( int __c, locale_t /*loc*/ ) |
lib/libcxx/include/__system_error/errc.h created+217| ... | ... | @@ -0,0 +1,217 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___ERRC | |
| 11 | #define _LIBCPP___ERRC | |
| 12 | ||
| 13 | /* | |
| 14 | system_error synopsis | |
| 15 | ||
| 16 | namespace std | |
| 17 | { | |
| 18 | ||
| 19 | enum class errc | |
| 20 | { | |
| 21 | address_family_not_supported, // EAFNOSUPPORT | |
| 22 | address_in_use, // EADDRINUSE | |
| 23 | address_not_available, // EADDRNOTAVAIL | |
| 24 | already_connected, // EISCONN | |
| 25 | argument_list_too_long, // E2BIG | |
| 26 | argument_out_of_domain, // EDOM | |
| 27 | bad_address, // EFAULT | |
| 28 | bad_file_descriptor, // EBADF | |
| 29 | bad_message, // EBADMSG | |
| 30 | broken_pipe, // EPIPE | |
| 31 | connection_aborted, // ECONNABORTED | |
| 32 | connection_already_in_progress, // EALREADY | |
| 33 | connection_refused, // ECONNREFUSED | |
| 34 | connection_reset, // ECONNRESET | |
| 35 | cross_device_link, // EXDEV | |
| 36 | destination_address_required, // EDESTADDRREQ | |
| 37 | device_or_resource_busy, // EBUSY | |
| 38 | directory_not_empty, // ENOTEMPTY | |
| 39 | executable_format_error, // ENOEXEC | |
| 40 | file_exists, // EEXIST | |
| 41 | file_too_large, // EFBIG | |
| 42 | filename_too_long, // ENAMETOOLONG | |
| 43 | function_not_supported, // ENOSYS | |
| 44 | host_unreachable, // EHOSTUNREACH | |
| 45 | identifier_removed, // EIDRM | |
| 46 | illegal_byte_sequence, // EILSEQ | |
| 47 | inappropriate_io_control_operation, // ENOTTY | |
| 48 | interrupted, // EINTR | |
| 49 | invalid_argument, // EINVAL | |
| 50 | invalid_seek, // ESPIPE | |
| 51 | io_error, // EIO | |
| 52 | is_a_directory, // EISDIR | |
| 53 | message_size, // EMSGSIZE | |
| 54 | network_down, // ENETDOWN | |
| 55 | network_reset, // ENETRESET | |
| 56 | network_unreachable, // ENETUNREACH | |
| 57 | no_buffer_space, // ENOBUFS | |
| 58 | no_child_process, // ECHILD | |
| 59 | no_link, // ENOLINK | |
| 60 | no_lock_available, // ENOLCK | |
| 61 | no_message_available, // ENODATA | |
| 62 | no_message, // ENOMSG | |
| 63 | no_protocol_option, // ENOPROTOOPT | |
| 64 | no_space_on_device, // ENOSPC | |
| 65 | no_stream_resources, // ENOSR | |
| 66 | no_such_device_or_address, // ENXIO | |
| 67 | no_such_device, // ENODEV | |
| 68 | no_such_file_or_directory, // ENOENT | |
| 69 | no_such_process, // ESRCH | |
| 70 | not_a_directory, // ENOTDIR | |
| 71 | not_a_socket, // ENOTSOCK | |
| 72 | not_a_stream, // ENOSTR | |
| 73 | not_connected, // ENOTCONN | |
| 74 | not_enough_memory, // ENOMEM | |
| 75 | not_supported, // ENOTSUP | |
| 76 | operation_canceled, // ECANCELED | |
| 77 | operation_in_progress, // EINPROGRESS | |
| 78 | operation_not_permitted, // EPERM | |
| 79 | operation_not_supported, // EOPNOTSUPP | |
| 80 | operation_would_block, // EWOULDBLOCK | |
| 81 | owner_dead, // EOWNERDEAD | |
| 82 | permission_denied, // EACCES | |
| 83 | protocol_error, // EPROTO | |
| 84 | protocol_not_supported, // EPROTONOSUPPORT | |
| 85 | read_only_file_system, // EROFS | |
| 86 | resource_deadlock_would_occur, // EDEADLK | |
| 87 | resource_unavailable_try_again, // EAGAIN | |
| 88 | result_out_of_range, // ERANGE | |
| 89 | state_not_recoverable, // ENOTRECOVERABLE | |
| 90 | stream_timeout, // ETIME | |
| 91 | text_file_busy, // ETXTBSY | |
| 92 | timed_out, // ETIMEDOUT | |
| 93 | too_many_files_open_in_system, // ENFILE | |
| 94 | too_many_files_open, // EMFILE | |
| 95 | too_many_links, // EMLINK | |
| 96 | too_many_symbolic_link_levels, // ELOOP | |
| 97 | value_too_large, // EOVERFLOW | |
| 98 | wrong_protocol_type // EPROTOTYPE | |
| 99 | }; | |
| 100 | ||
| 101 | */ | |
| 102 | ||
| 103 | #include <__config> | |
| 104 | #include <cerrno> | |
| 105 | ||
| 106 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 107 | # pragma GCC system_header | |
| 108 | #endif | |
| 109 | ||
| 110 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 111 | ||
| 112 | // Some error codes are not present on all platforms, so we provide equivalents | |
| 113 | // for them: | |
| 114 | ||
| 115 | //enum class errc | |
| 116 | _LIBCPP_DECLARE_STRONG_ENUM(errc) | |
| 117 | { | |
| 118 | address_family_not_supported = EAFNOSUPPORT, | |
| 119 | address_in_use = EADDRINUSE, | |
| 120 | address_not_available = EADDRNOTAVAIL, | |
| 121 | already_connected = EISCONN, | |
| 122 | argument_list_too_long = E2BIG, | |
| 123 | argument_out_of_domain = EDOM, | |
| 124 | bad_address = EFAULT, | |
| 125 | bad_file_descriptor = EBADF, | |
| 126 | bad_message = EBADMSG, | |
| 127 | broken_pipe = EPIPE, | |
| 128 | connection_aborted = ECONNABORTED, | |
| 129 | connection_already_in_progress = EALREADY, | |
| 130 | connection_refused = ECONNREFUSED, | |
| 131 | connection_reset = ECONNRESET, | |
| 132 | cross_device_link = EXDEV, | |
| 133 | destination_address_required = EDESTADDRREQ, | |
| 134 | device_or_resource_busy = EBUSY, | |
| 135 | directory_not_empty = ENOTEMPTY, | |
| 136 | executable_format_error = ENOEXEC, | |
| 137 | file_exists = EEXIST, | |
| 138 | file_too_large = EFBIG, | |
| 139 | filename_too_long = ENAMETOOLONG, | |
| 140 | function_not_supported = ENOSYS, | |
| 141 | host_unreachable = EHOSTUNREACH, | |
| 142 | identifier_removed = EIDRM, | |
| 143 | illegal_byte_sequence = EILSEQ, | |
| 144 | inappropriate_io_control_operation = ENOTTY, | |
| 145 | interrupted = EINTR, | |
| 146 | invalid_argument = EINVAL, | |
| 147 | invalid_seek = ESPIPE, | |
| 148 | io_error = EIO, | |
| 149 | is_a_directory = EISDIR, | |
| 150 | message_size = EMSGSIZE, | |
| 151 | network_down = ENETDOWN, | |
| 152 | network_reset = ENETRESET, | |
| 153 | network_unreachable = ENETUNREACH, | |
| 154 | no_buffer_space = ENOBUFS, | |
| 155 | no_child_process = ECHILD, | |
| 156 | no_link = ENOLINK, | |
| 157 | no_lock_available = ENOLCK, | |
| 158 | #ifdef ENODATA | |
| 159 | no_message_available = ENODATA, | |
| 160 | #else | |
| 161 | no_message_available = ENOMSG, | |
| 162 | #endif | |
| 163 | no_message = ENOMSG, | |
| 164 | no_protocol_option = ENOPROTOOPT, | |
| 165 | no_space_on_device = ENOSPC, | |
| 166 | #ifdef ENOSR | |
| 167 | no_stream_resources = ENOSR, | |
| 168 | #else | |
| 169 | no_stream_resources = ENOMEM, | |
| 170 | #endif | |
| 171 | no_such_device_or_address = ENXIO, | |
| 172 | no_such_device = ENODEV, | |
| 173 | no_such_file_or_directory = ENOENT, | |
| 174 | no_such_process = ESRCH, | |
| 175 | not_a_directory = ENOTDIR, | |
| 176 | not_a_socket = ENOTSOCK, | |
| 177 | #ifdef ENOSTR | |
| 178 | not_a_stream = ENOSTR, | |
| 179 | #else | |
| 180 | not_a_stream = EINVAL, | |
| 181 | #endif | |
| 182 | not_connected = ENOTCONN, | |
| 183 | not_enough_memory = ENOMEM, | |
| 184 | not_supported = ENOTSUP, | |
| 185 | operation_canceled = ECANCELED, | |
| 186 | operation_in_progress = EINPROGRESS, | |
| 187 | operation_not_permitted = EPERM, | |
| 188 | operation_not_supported = EOPNOTSUPP, | |
| 189 | operation_would_block = EWOULDBLOCK, | |
| 190 | owner_dead = EOWNERDEAD, | |
| 191 | permission_denied = EACCES, | |
| 192 | protocol_error = EPROTO, | |
| 193 | protocol_not_supported = EPROTONOSUPPORT, | |
| 194 | read_only_file_system = EROFS, | |
| 195 | resource_deadlock_would_occur = EDEADLK, | |
| 196 | resource_unavailable_try_again = EAGAIN, | |
| 197 | result_out_of_range = ERANGE, | |
| 198 | state_not_recoverable = ENOTRECOVERABLE, | |
| 199 | #ifdef ETIME | |
| 200 | stream_timeout = ETIME, | |
| 201 | #else | |
| 202 | stream_timeout = ETIMEDOUT, | |
| 203 | #endif | |
| 204 | text_file_busy = ETXTBSY, | |
| 205 | timed_out = ETIMEDOUT, | |
| 206 | too_many_files_open_in_system = ENFILE, | |
| 207 | too_many_files_open = EMFILE, | |
| 208 | too_many_links = EMLINK, | |
| 209 | too_many_symbolic_link_levels = ELOOP, | |
| 210 | value_too_large = EOVERFLOW, | |
| 211 | wrong_protocol_type = EPROTOTYPE | |
| 212 | }; | |
| 213 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(errc) | |
| 214 | ||
| 215 | _LIBCPP_END_NAMESPACE_STD | |
| 216 | ||
| 217 | #endif // _LIBCPP___ERRC |
lib/libcxx/include/__system_error/error_category.h created+75| ... | ... | @@ -0,0 +1,75 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H | |
| 11 | #define _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H | |
| 12 | ||
| 13 | #include <__compare/ordering.h> | |
| 14 | #include <__config> | |
| 15 | #include <string> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | class _LIBCPP_EXPORTED_FROM_ABI error_condition; | |
| 24 | class _LIBCPP_EXPORTED_FROM_ABI error_code; | |
| 25 | ||
| 26 | class _LIBCPP_HIDDEN __do_message; | |
| 27 | ||
| 28 | class _LIBCPP_EXPORTED_FROM_ABI error_category { | |
| 29 | public: | |
| 30 | virtual ~error_category() _NOEXCEPT; | |
| 31 | ||
| 32 | #if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS) | |
| 33 | error_category() noexcept; | |
| 34 | #else | |
| 35 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default; | |
| 36 | #endif | |
| 37 | error_category(const error_category&) = delete; | |
| 38 | error_category& operator=(const error_category&) = delete; | |
| 39 | ||
| 40 | virtual const char* name() const _NOEXCEPT = 0; | |
| 41 | virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; | |
| 42 | virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; | |
| 43 | virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; | |
| 44 | virtual string message(int __ev) const = 0; | |
| 45 | ||
| 46 | _LIBCPP_HIDE_FROM_ABI bool operator==(const error_category& __rhs) const _NOEXCEPT { return this == &__rhs; } | |
| 47 | ||
| 48 | #if _LIBCPP_STD_VER >= 20 | |
| 49 | ||
| 50 | _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_category& __rhs) const noexcept { | |
| 51 | return compare_three_way()(this, std::addressof(__rhs)); | |
| 52 | } | |
| 53 | ||
| 54 | #else // _LIBCPP_STD_VER >= 20 | |
| 55 | ||
| 56 | _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_category& __rhs) const _NOEXCEPT { return !(*this == __rhs); } | |
| 57 | ||
| 58 | _LIBCPP_HIDE_FROM_ABI bool operator<(const error_category& __rhs) const _NOEXCEPT { return this < &__rhs; } | |
| 59 | ||
| 60 | #endif // _LIBCPP_STD_VER >= 20 | |
| 61 | ||
| 62 | friend class _LIBCPP_HIDDEN __do_message; | |
| 63 | }; | |
| 64 | ||
| 65 | class _LIBCPP_HIDDEN __do_message : public error_category { | |
| 66 | public: | |
| 67 | string message(int __ev) const override; | |
| 68 | }; | |
| 69 | ||
| 70 | _LIBCPP_EXPORTED_FROM_ABI const error_category& generic_category() _NOEXCEPT; | |
| 71 | _LIBCPP_EXPORTED_FROM_ABI const error_category& system_category() _NOEXCEPT; | |
| 72 | ||
| 73 | _LIBCPP_END_NAMESPACE_STD | |
| 74 | ||
| 75 | #endif // _LIBCPP___SYSTEM_ERROR_ERROR_CATEGORY_H |
lib/libcxx/include/__system_error/error_code.h created+145| ... | ... | @@ -0,0 +1,145 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H | |
| 11 | #define _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H | |
| 12 | ||
| 13 | #include <__compare/ordering.h> | |
| 14 | #include <__config> | |
| 15 | #include <__functional/hash.h> | |
| 16 | #include <__functional/unary_function.h> | |
| 17 | #include <__system_error/errc.h> | |
| 18 | #include <__system_error/error_category.h> | |
| 19 | #include <__system_error/error_condition.h> | |
| 20 | #include <cstddef> | |
| 21 | #include <string> | |
| 22 | ||
| 23 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 24 | # pragma GCC system_header | |
| 25 | #endif | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS is_error_code_enum : public false_type {}; | |
| 31 | ||
| 32 | #if _LIBCPP_STD_VER >= 17 | |
| 33 | template <class _Tp> | |
| 34 | inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; | |
| 35 | #endif | |
| 36 | ||
| 37 | namespace __adl_only { | |
| 38 | // Those cause ADL to trigger but they are not viable candidates, | |
| 39 | // so they are never actually selected. | |
| 40 | void make_error_code() = delete; | |
| 41 | } // namespace __adl_only | |
| 42 | ||
| 43 | class _LIBCPP_EXPORTED_FROM_ABI error_code { | |
| 44 | int __val_; | |
| 45 | const error_category* __cat_; | |
| 46 | ||
| 47 | public: | |
| 48 | _LIBCPP_HIDE_FROM_ABI error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} | |
| 49 | ||
| 50 | _LIBCPP_HIDE_FROM_ABI error_code(int __val, const error_category& __cat) _NOEXCEPT : __val_(__val), __cat_(&__cat) {} | |
| 51 | ||
| 52 | template <class _Ep> | |
| 53 | _LIBCPP_HIDE_FROM_ABI | |
| 54 | error_code(_Ep __e, typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT { | |
| 55 | using __adl_only::make_error_code; | |
| 56 | *this = make_error_code(__e); | |
| 57 | } | |
| 58 | ||
| 59 | _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT { | |
| 60 | __val_ = __val; | |
| 61 | __cat_ = &__cat; | |
| 62 | } | |
| 63 | ||
| 64 | template <class _Ep> | |
| 65 | _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_code_enum<_Ep>::value, error_code& >::type | |
| 66 | operator=(_Ep __e) _NOEXCEPT { | |
| 67 | using __adl_only::make_error_code; | |
| 68 | *this = make_error_code(__e); | |
| 69 | return *this; | |
| 70 | } | |
| 71 | ||
| 72 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { | |
| 73 | __val_ = 0; | |
| 74 | __cat_ = &system_category(); | |
| 75 | } | |
| 76 | ||
| 77 | _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } | |
| 78 | ||
| 79 | _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } | |
| 80 | ||
| 81 | _LIBCPP_HIDE_FROM_ABI error_condition default_error_condition() const _NOEXCEPT { | |
| 82 | return __cat_->default_error_condition(__val_); | |
| 83 | } | |
| 84 | ||
| 85 | string message() const; | |
| 86 | ||
| 87 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } | |
| 88 | }; | |
| 89 | ||
| 90 | inline _LIBCPP_HIDE_FROM_ABI error_code make_error_code(errc __e) _NOEXCEPT { | |
| 91 | return error_code(static_cast<int>(__e), generic_category()); | |
| 92 | } | |
| 93 | ||
| 94 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_code& __y) _NOEXCEPT { | |
| 95 | return __x.category() == __y.category() && __x.value() == __y.value(); | |
| 96 | } | |
| 97 | ||
| 98 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT { | |
| 99 | return __x.category().equivalent(__x.value(), __y) || __y.category().equivalent(__x, __y.value()); | |
| 100 | } | |
| 101 | ||
| 102 | #if _LIBCPP_STD_VER <= 17 | |
| 103 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT { | |
| 104 | return __y == __x; | |
| 105 | } | |
| 106 | #endif | |
| 107 | ||
| 108 | #if _LIBCPP_STD_VER <= 17 | |
| 109 | ||
| 110 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT { | |
| 111 | return !(__x == __y); | |
| 112 | } | |
| 113 | ||
| 114 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT { | |
| 115 | return !(__x == __y); | |
| 116 | } | |
| 117 | ||
| 118 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT { | |
| 119 | return !(__x == __y); | |
| 120 | } | |
| 121 | ||
| 122 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_code& __x, const error_code& __y) _NOEXCEPT { | |
| 123 | return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value()); | |
| 124 | } | |
| 125 | ||
| 126 | #else // _LIBCPP_STD_VER <= 17 | |
| 127 | ||
| 128 | inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const error_code& __x, const error_code& __y) noexcept { | |
| 129 | if (auto __c = __x.category() <=> __y.category(); __c != 0) | |
| 130 | return __c; | |
| 131 | return __x.value() <=> __y.value(); | |
| 132 | } | |
| 133 | ||
| 134 | #endif // _LIBCPP_STD_VER <= 17 | |
| 135 | ||
| 136 | template <> | |
| 137 | struct _LIBCPP_TEMPLATE_VIS hash<error_code> : public __unary_function<error_code, size_t> { | |
| 138 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_code& __ec) const _NOEXCEPT { | |
| 139 | return static_cast<size_t>(__ec.value()); | |
| 140 | } | |
| 141 | }; | |
| 142 | ||
| 143 | _LIBCPP_END_NAMESPACE_STD | |
| 144 | ||
| 145 | #endif // _LIBCPP___SYSTEM_ERROR_ERROR_CODE_H |
lib/libcxx/include/__system_error/error_condition.h created+132| ... | ... | @@ -0,0 +1,132 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H | |
| 11 | #define _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H | |
| 12 | ||
| 13 | #include <__compare/ordering.h> | |
| 14 | #include <__config> | |
| 15 | #include <__functional/hash.h> | |
| 16 | #include <__functional/unary_function.h> | |
| 17 | #include <__system_error/errc.h> | |
| 18 | #include <__system_error/error_category.h> | |
| 19 | #include <cstddef> | |
| 20 | #include <string> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | template <class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum : public false_type {}; | |
| 30 | ||
| 31 | #if _LIBCPP_STD_VER >= 17 | |
| 32 | template <class _Tp> | |
| 33 | inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; | |
| 34 | #endif | |
| 35 | ||
| 36 | template <> | |
| 37 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> : true_type {}; | |
| 38 | ||
| 39 | #ifdef _LIBCPP_CXX03_LANG | |
| 40 | template <> | |
| 41 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> : true_type {}; | |
| 42 | #endif | |
| 43 | ||
| 44 | namespace __adl_only { | |
| 45 | // Those cause ADL to trigger but they are not viable candidates, | |
| 46 | // so they are never actually selected. | |
| 47 | void make_error_condition() = delete; | |
| 48 | } // namespace __adl_only | |
| 49 | ||
| 50 | class _LIBCPP_EXPORTED_FROM_ABI error_condition { | |
| 51 | int __val_; | |
| 52 | const error_category* __cat_; | |
| 53 | ||
| 54 | public: | |
| 55 | _LIBCPP_HIDE_FROM_ABI error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} | |
| 56 | ||
| 57 | _LIBCPP_HIDE_FROM_ABI error_condition(int __val, const error_category& __cat) _NOEXCEPT | |
| 58 | : __val_(__val), | |
| 59 | __cat_(&__cat) {} | |
| 60 | ||
| 61 | template <class _Ep> | |
| 62 | _LIBCPP_HIDE_FROM_ABI | |
| 63 | error_condition(_Ep __e, typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr) _NOEXCEPT { | |
| 64 | using __adl_only::make_error_condition; | |
| 65 | *this = make_error_condition(__e); | |
| 66 | } | |
| 67 | ||
| 68 | _LIBCPP_HIDE_FROM_ABI void assign(int __val, const error_category& __cat) _NOEXCEPT { | |
| 69 | __val_ = __val; | |
| 70 | __cat_ = &__cat; | |
| 71 | } | |
| 72 | ||
| 73 | template <class _Ep> | |
| 74 | _LIBCPP_HIDE_FROM_ABI typename enable_if< is_error_condition_enum<_Ep>::value, error_condition& >::type | |
| 75 | operator=(_Ep __e) _NOEXCEPT { | |
| 76 | using __adl_only::make_error_condition; | |
| 77 | *this = make_error_condition(__e); | |
| 78 | return *this; | |
| 79 | } | |
| 80 | ||
| 81 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { | |
| 82 | __val_ = 0; | |
| 83 | __cat_ = &generic_category(); | |
| 84 | } | |
| 85 | ||
| 86 | _LIBCPP_HIDE_FROM_ABI int value() const _NOEXCEPT { return __val_; } | |
| 87 | ||
| 88 | _LIBCPP_HIDE_FROM_ABI const error_category& category() const _NOEXCEPT { return *__cat_; } | |
| 89 | string message() const; | |
| 90 | ||
| 91 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __val_ != 0; } | |
| 92 | }; | |
| 93 | ||
| 94 | inline _LIBCPP_HIDE_FROM_ABI error_condition make_error_condition(errc __e) _NOEXCEPT { | |
| 95 | return error_condition(static_cast<int>(__e), generic_category()); | |
| 96 | } | |
| 97 | ||
| 98 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT { | |
| 99 | return __x.category() == __y.category() && __x.value() == __y.value(); | |
| 100 | } | |
| 101 | ||
| 102 | #if _LIBCPP_STD_VER <= 17 | |
| 103 | ||
| 104 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT { | |
| 105 | return !(__x == __y); | |
| 106 | } | |
| 107 | ||
| 108 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT { | |
| 109 | return __x.category() < __y.category() || (__x.category() == __y.category() && __x.value() < __y.value()); | |
| 110 | } | |
| 111 | ||
| 112 | #else // _LIBCPP_STD_VER <= 17 | |
| 113 | ||
| 114 | inline _LIBCPP_HIDE_FROM_ABI strong_ordering | |
| 115 | operator<=>(const error_condition& __x, const error_condition& __y) noexcept { | |
| 116 | if (auto __c = __x.category() <=> __y.category(); __c != 0) | |
| 117 | return __c; | |
| 118 | return __x.value() <=> __y.value(); | |
| 119 | } | |
| 120 | ||
| 121 | #endif // _LIBCPP_STD_VER <= 17 | |
| 122 | ||
| 123 | template <> | |
| 124 | struct _LIBCPP_TEMPLATE_VIS hash<error_condition> : public __unary_function<error_condition, size_t> { | |
| 125 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const error_condition& __ec) const _NOEXCEPT { | |
| 126 | return static_cast<size_t>(__ec.value()); | |
| 127 | } | |
| 128 | }; | |
| 129 | ||
| 130 | _LIBCPP_END_NAMESPACE_STD | |
| 131 | ||
| 132 | #endif // _LIBCPP___SYSTEM_ERROR_ERROR_CONDITION_H |
lib/libcxx/include/__system_error/system_error.h created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H | |
| 11 | #define _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__system_error/error_category.h> | |
| 15 | #include <__system_error/error_code.h> | |
| 16 | #include <stdexcept> | |
| 17 | #include <string> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | class _LIBCPP_EXPORTED_FROM_ABI system_error : public runtime_error { | |
| 26 | error_code __ec_; | |
| 27 | ||
| 28 | public: | |
| 29 | system_error(error_code __ec, const string& __what_arg); | |
| 30 | system_error(error_code __ec, const char* __what_arg); | |
| 31 | system_error(error_code __ec); | |
| 32 | system_error(int __ev, const error_category& __ecat, const string& __what_arg); | |
| 33 | system_error(int __ev, const error_category& __ecat, const char* __what_arg); | |
| 34 | system_error(int __ev, const error_category& __ecat); | |
| 35 | _LIBCPP_HIDE_FROM_ABI system_error(const system_error&) _NOEXCEPT = default; | |
| 36 | ~system_error() _NOEXCEPT override; | |
| 37 | ||
| 38 | _LIBCPP_HIDE_FROM_ABI const error_code& code() const _NOEXCEPT { return __ec_; } | |
| 39 | ||
| 40 | private: | |
| 41 | static string __init(const error_code&, string); | |
| 42 | }; | |
| 43 | ||
| 44 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_system_error(int __ev, const char* __what_arg); | |
| 45 | ||
| 46 | _LIBCPP_END_NAMESPACE_STD | |
| 47 | ||
| 48 | #endif // _LIBCPP___SYSTEM_ERROR_SYSTEM_ERROR_H |
lib/libcxx/include/__thread/formatter.h created+80| ... | ... | @@ -0,0 +1,80 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___THREAD_FORMATTER_H | |
| 11 | #define _LIBCPP___THREAD_FORMATTER_H | |
| 12 | ||
| 13 | #include <__concepts/arithmetic.h> | |
| 14 | #include <__config> | |
| 15 | #include <__format/concepts.h> | |
| 16 | #include <__format/format_parse_context.h> | |
| 17 | #include <__format/formatter.h> | |
| 18 | #include <__format/formatter_integral.h> | |
| 19 | #include <__format/parser_std_format_spec.h> | |
| 20 | #include <__thread/id.h> | |
| 21 | #include <__type_traits/conditional.h> | |
| 22 | #include <__type_traits/is_pointer.h> | |
| 23 | #include <__type_traits/is_same.h> | |
| 24 | #include <cstdint> | |
| 25 | ||
| 26 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 27 | # pragma GCC system_header | |
| 28 | #endif | |
| 29 | ||
| 30 | #if _LIBCPP_STD_VER >= 23 | |
| 31 | ||
| 32 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 33 | ||
| 34 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 35 | ||
| 36 | template <__fmt_char_type _CharT> | |
| 37 | struct _LIBCPP_TEMPLATE_VIS formatter<__thread_id, _CharT> { | |
| 38 | public: | |
| 39 | template <class _ParseContext> | |
| 40 | _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { | |
| 41 | return __parser_.__parse(__ctx, __format_spec::__fields_fill_align_width); | |
| 42 | } | |
| 43 | ||
| 44 | template <class _FormatContext> | |
| 45 | _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(__thread_id __id, _FormatContext& __ctx) const { | |
| 46 | // In __threading_support __libcpp_thread_id is either a | |
| 47 | // unsigned long long or a pthread_t. | |
| 48 | // | |
| 49 | // The type of pthread_t is left unspecified in POSIX so it can be any | |
| 50 | // type. The most logical types are an integral or pointer. | |
| 51 | // On Linux systems pthread_t is an unsigned long long. | |
| 52 | // On Apple systems pthread_t is a pointer type. | |
| 53 | // | |
| 54 | // Note the output should match what the stream operator does. Since | |
| 55 | // the ostream operator has been shipped years before this formatter | |
| 56 | // was added to the Standard, this formatter does what the stream | |
| 57 | // operator does. This may require platform specific changes. | |
| 58 | ||
| 59 | using _Tp = decltype(__get_underlying_id(__id)); | |
| 60 | using _Cp = conditional_t<integral<_Tp>, _Tp, conditional_t<is_pointer_v<_Tp>, uintptr_t, void>>; | |
| 61 | static_assert(!is_same_v<_Cp, void>, "unsupported thread::id type, please file a bug report"); | |
| 62 | ||
| 63 | __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); | |
| 64 | if constexpr (is_pointer_v<_Tp>) { | |
| 65 | __specs.__std_.__alternate_form_ = true; | |
| 66 | __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; | |
| 67 | } | |
| 68 | return __formatter::__format_integer(reinterpret_cast<_Cp>(__get_underlying_id(__id)), __ctx, __specs); | |
| 69 | } | |
| 70 | ||
| 71 | __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right}; | |
| 72 | }; | |
| 73 | ||
| 74 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 75 | ||
| 76 | _LIBCPP_END_NAMESPACE_STD | |
| 77 | ||
| 78 | #endif // _LIBCPP_STD_VER >= 23 | |
| 79 | ||
| 80 | #endif // _LIBCPP___THREAD_FORMATTER_H |
lib/libcxx/include/__thread/id.h created+121| ... | ... | @@ -0,0 +1,121 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___THREAD_ID_H | |
| 11 | #define _LIBCPP___THREAD_ID_H | |
| 12 | ||
| 13 | #include <__compare/ordering.h> | |
| 14 | #include <__config> | |
| 15 | #include <__fwd/hash.h> | |
| 16 | #include <__threading_support> | |
| 17 | #include <iosfwd> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 26 | class _LIBCPP_EXPORTED_FROM_ABI __thread_id; | |
| 27 | ||
| 28 | namespace this_thread { | |
| 29 | ||
| 30 | _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT; | |
| 31 | ||
| 32 | } // namespace this_thread | |
| 33 | ||
| 34 | template <> | |
| 35 | struct hash<__thread_id>; | |
| 36 | ||
| 37 | class _LIBCPP_TEMPLATE_VIS __thread_id { | |
| 38 | // FIXME: pthread_t is a pointer on Darwin but a long on Linux. | |
| 39 | // NULL is the no-thread value on Darwin. Someone needs to check | |
| 40 | // on other platforms. We assume 0 works everywhere for now. | |
| 41 | __libcpp_thread_id __id_; | |
| 42 | ||
| 43 | static _LIBCPP_HIDE_FROM_ABI bool | |
| 44 | __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id | |
| 45 | if (__x.__id_ == 0) | |
| 46 | return __y.__id_ != 0; | |
| 47 | if (__y.__id_ == 0) | |
| 48 | return false; | |
| 49 | return __libcpp_thread_id_less(__x.__id_, __y.__id_); | |
| 50 | } | |
| 51 | ||
| 52 | public: | |
| 53 | _LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {} | |
| 54 | ||
| 55 | _LIBCPP_HIDE_FROM_ABI void __reset() { __id_ = 0; } | |
| 56 | ||
| 57 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT; | |
| 58 | # if _LIBCPP_STD_VER <= 17 | |
| 59 | friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT; | |
| 60 | # else // _LIBCPP_STD_VER <= 17 | |
| 61 | friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept; | |
| 62 | # endif // _LIBCPP_STD_VER <= 17 | |
| 63 | ||
| 64 | template <class _CharT, class _Traits> | |
| 65 | friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& | |
| 66 | operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); | |
| 67 | ||
| 68 | private: | |
| 69 | _LIBCPP_HIDE_FROM_ABI __thread_id(__libcpp_thread_id __id) : __id_(__id) {} | |
| 70 | ||
| 71 | _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; } | |
| 72 | ||
| 73 | friend __thread_id this_thread::get_id() _NOEXCEPT; | |
| 74 | friend class _LIBCPP_EXPORTED_FROM_ABI thread; | |
| 75 | friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; | |
| 76 | }; | |
| 77 | ||
| 78 | inline _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT { | |
| 79 | // Don't pass id==0 to underlying routines | |
| 80 | if (__x.__id_ == 0) | |
| 81 | return __y.__id_ == 0; | |
| 82 | if (__y.__id_ == 0) | |
| 83 | return false; | |
| 84 | return __libcpp_thread_id_equal(__x.__id_, __y.__id_); | |
| 85 | } | |
| 86 | ||
| 87 | # if _LIBCPP_STD_VER <= 17 | |
| 88 | ||
| 89 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); } | |
| 90 | ||
| 91 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT { | |
| 92 | return __thread_id::__lt_impl(__x.__id_, __y.__id_); | |
| 93 | } | |
| 94 | ||
| 95 | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); } | |
| 96 | inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; } | |
| 97 | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); } | |
| 98 | ||
| 99 | # else // _LIBCPP_STD_VER <= 17 | |
| 100 | ||
| 101 | inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept { | |
| 102 | if (__x == __y) | |
| 103 | return strong_ordering::equal; | |
| 104 | if (__thread_id::__lt_impl(__x, __y)) | |
| 105 | return strong_ordering::less; | |
| 106 | return strong_ordering::greater; | |
| 107 | } | |
| 108 | ||
| 109 | # endif // _LIBCPP_STD_VER <= 17 | |
| 110 | ||
| 111 | namespace this_thread { | |
| 112 | ||
| 113 | inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); } | |
| 114 | ||
| 115 | } // namespace this_thread | |
| 116 | ||
| 117 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 118 | ||
| 119 | _LIBCPP_END_NAMESPACE_STD | |
| 120 | ||
| 121 | #endif // _LIBCPP___THREAD_ID_H |
lib/libcxx/include/__thread/this_thread.h created+87| ... | ... | @@ -0,0 +1,87 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___THREAD_THIS_THREAD_H | |
| 11 | #define _LIBCPP___THREAD_THIS_THREAD_H | |
| 12 | ||
| 13 | #include <__chrono/steady_clock.h> | |
| 14 | #include <__chrono/time_point.h> | |
| 15 | #include <__condition_variable/condition_variable.h> | |
| 16 | #include <__config> | |
| 17 | #include <__mutex/mutex.h> | |
| 18 | #include <__mutex/unique_lock.h> | |
| 19 | #include <__threading_support> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_PUSH_MACROS | |
| 26 | #include <__undef_macros> | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 29 | ||
| 30 | namespace this_thread | |
| 31 | { | |
| 32 | ||
| 33 | _LIBCPP_EXPORTED_FROM_ABI void sleep_for(const chrono::nanoseconds& __ns); | |
| 34 | ||
| 35 | template <class _Rep, class _Period> | |
| 36 | _LIBCPP_HIDE_FROM_ABI void | |
| 37 | sleep_for(const chrono::duration<_Rep, _Period>& __d) | |
| 38 | { | |
| 39 | if (__d > chrono::duration<_Rep, _Period>::zero()) | |
| 40 | { | |
| 41 | // The standard guarantees a 64bit signed integer resolution for nanoseconds, | |
| 42 | // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> | |
| 43 | // and issues with long double folding on PowerPC with GCC. | |
| 44 | _LIBCPP_CONSTEXPR chrono::duration<long double> __max = | |
| 45 | chrono::duration<long double>(9223372036.0L); | |
| 46 | chrono::nanoseconds __ns; | |
| 47 | if (__d < __max) | |
| 48 | { | |
| 49 | __ns = chrono::duration_cast<chrono::nanoseconds>(__d); | |
| 50 | if (__ns < __d) | |
| 51 | ++__ns; | |
| 52 | } | |
| 53 | else | |
| 54 | __ns = chrono::nanoseconds::max(); | |
| 55 | this_thread::sleep_for(__ns); | |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | template <class _Clock, class _Duration> | |
| 60 | _LIBCPP_HIDE_FROM_ABI void | |
| 61 | sleep_until(const chrono::time_point<_Clock, _Duration>& __t) | |
| 62 | { | |
| 63 | mutex __mut; | |
| 64 | condition_variable __cv; | |
| 65 | unique_lock<mutex> __lk(__mut); | |
| 66 | while (_Clock::now() < __t) | |
| 67 | __cv.wait_until(__lk, __t); | |
| 68 | } | |
| 69 | ||
| 70 | template <class _Duration> | |
| 71 | inline _LIBCPP_INLINE_VISIBILITY | |
| 72 | void | |
| 73 | sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) | |
| 74 | { | |
| 75 | this_thread::sleep_for(__t - chrono::steady_clock::now()); | |
| 76 | } | |
| 77 | ||
| 78 | inline _LIBCPP_INLINE_VISIBILITY | |
| 79 | void yield() _NOEXCEPT {__libcpp_thread_yield();} | |
| 80 | ||
| 81 | } // namespace this_thread | |
| 82 | ||
| 83 | _LIBCPP_END_NAMESPACE_STD | |
| 84 | ||
| 85 | _LIBCPP_POP_MACROS | |
| 86 | ||
| 87 | #endif // _LIBCPP___THREAD_THIS_THREAD_H |
lib/libcxx/include/__thread/thread.h created+297| ... | ... | @@ -0,0 +1,297 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___THREAD_THREAD_H | |
| 11 | #define _LIBCPP___THREAD_THREAD_H | |
| 12 | ||
| 13 | #include <__condition_variable/condition_variable.h> | |
| 14 | #include <__config> | |
| 15 | #include <__exception/terminate.h> | |
| 16 | #include <__functional/hash.h> | |
| 17 | #include <__functional/unary_function.h> | |
| 18 | #include <__memory/unique_ptr.h> | |
| 19 | #include <__mutex/mutex.h> | |
| 20 | #include <__system_error/system_error.h> | |
| 21 | #include <__thread/id.h> | |
| 22 | #include <__threading_support> | |
| 23 | #include <__utility/forward.h> | |
| 24 | #include <iosfwd> | |
| 25 | #include <tuple> | |
| 26 | ||
| 27 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION | |
| 28 | # include <locale> | |
| 29 | # include <sstream> | |
| 30 | #endif | |
| 31 | ||
| 32 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 33 | # pragma GCC system_header | |
| 34 | #endif | |
| 35 | ||
| 36 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 37 | ||
| 38 | template <class _Tp> class __thread_specific_ptr; | |
| 39 | class _LIBCPP_EXPORTED_FROM_ABI __thread_struct; | |
| 40 | class _LIBCPP_HIDDEN __thread_struct_imp; | |
| 41 | class __assoc_sub_state; | |
| 42 | ||
| 43 | _LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data(); | |
| 44 | ||
| 45 | class _LIBCPP_EXPORTED_FROM_ABI __thread_struct | |
| 46 | { | |
| 47 | __thread_struct_imp* __p_; | |
| 48 | ||
| 49 | __thread_struct(const __thread_struct&); | |
| 50 | __thread_struct& operator=(const __thread_struct&); | |
| 51 | public: | |
| 52 | __thread_struct(); | |
| 53 | ~__thread_struct(); | |
| 54 | ||
| 55 | void notify_all_at_thread_exit(condition_variable*, mutex*); | |
| 56 | void __make_ready_at_thread_exit(__assoc_sub_state*); | |
| 57 | }; | |
| 58 | ||
| 59 | template <class _Tp> | |
| 60 | class __thread_specific_ptr | |
| 61 | { | |
| 62 | __libcpp_tls_key __key_; | |
| 63 | ||
| 64 | // Only __thread_local_data() may construct a __thread_specific_ptr | |
| 65 | // and only with _Tp == __thread_struct. | |
| 66 | static_assert((is_same<_Tp, __thread_struct>::value), ""); | |
| 67 | __thread_specific_ptr(); | |
| 68 | friend _LIBCPP_EXPORTED_FROM_ABI __thread_specific_ptr<__thread_struct>& __thread_local_data(); | |
| 69 | ||
| 70 | __thread_specific_ptr(const __thread_specific_ptr&); | |
| 71 | __thread_specific_ptr& operator=(const __thread_specific_ptr&); | |
| 72 | ||
| 73 | _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); | |
| 74 | ||
| 75 | public: | |
| 76 | typedef _Tp* pointer; | |
| 77 | ||
| 78 | ~__thread_specific_ptr(); | |
| 79 | ||
| 80 | _LIBCPP_INLINE_VISIBILITY | |
| 81 | pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));} | |
| 82 | _LIBCPP_INLINE_VISIBILITY | |
| 83 | pointer operator*() const {return *get();} | |
| 84 | _LIBCPP_INLINE_VISIBILITY | |
| 85 | pointer operator->() const {return get();} | |
| 86 | void set_pointer(pointer __p); | |
| 87 | }; | |
| 88 | ||
| 89 | template <class _Tp> | |
| 90 | void _LIBCPP_TLS_DESTRUCTOR_CC | |
| 91 | __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) | |
| 92 | { | |
| 93 | delete static_cast<pointer>(__p); | |
| 94 | } | |
| 95 | ||
| 96 | template <class _Tp> | |
| 97 | __thread_specific_ptr<_Tp>::__thread_specific_ptr() | |
| 98 | { | |
| 99 | int __ec = | |
| 100 | __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit); | |
| 101 | if (__ec) | |
| 102 | __throw_system_error(__ec, "__thread_specific_ptr construction failed"); | |
| 103 | } | |
| 104 | ||
| 105 | template <class _Tp> | |
| 106 | __thread_specific_ptr<_Tp>::~__thread_specific_ptr() | |
| 107 | { | |
| 108 | // __thread_specific_ptr is only created with a static storage duration | |
| 109 | // so this destructor is only invoked during program termination. Invoking | |
| 110 | // pthread_key_delete(__key_) may prevent other threads from deleting their | |
| 111 | // thread local data. For this reason we leak the key. | |
| 112 | } | |
| 113 | ||
| 114 | template <class _Tp> | |
| 115 | void | |
| 116 | __thread_specific_ptr<_Tp>::set_pointer(pointer __p) | |
| 117 | { | |
| 118 | _LIBCPP_ASSERT_UNCATEGORIZED(get() == nullptr, | |
| 119 | "Attempting to overwrite thread local data"); | |
| 120 | std::__libcpp_tls_set(__key_, __p); | |
| 121 | } | |
| 122 | ||
| 123 | template<> | |
| 124 | struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> | |
| 125 | : public __unary_function<__thread_id, size_t> | |
| 126 | { | |
| 127 | _LIBCPP_INLINE_VISIBILITY | |
| 128 | size_t operator()(__thread_id __v) const _NOEXCEPT | |
| 129 | { | |
| 130 | return hash<__libcpp_thread_id>()(__v.__id_); | |
| 131 | } | |
| 132 | }; | |
| 133 | ||
| 134 | #ifndef _LIBCPP_HAS_NO_LOCALIZATION | |
| 135 | template <class _CharT, class _Traits> | |
| 136 | _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& | |
| 137 | operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) { | |
| 138 | // [thread.thread.id]/9 | |
| 139 | // Effects: Inserts the text representation for charT of id into out. | |
| 140 | // | |
| 141 | // [thread.thread.id]/2 | |
| 142 | // The text representation for the character type charT of an | |
| 143 | // object of type thread::id is an unspecified sequence of charT | |
| 144 | // such that, for two objects of type thread::id x and y, if | |
| 145 | // x == y is true, the thread::id objects have the same text | |
| 146 | // representation, and if x != y is true, the thread::id objects | |
| 147 | // have distinct text representations. | |
| 148 | // | |
| 149 | // Since various flags in the output stream can affect how the | |
| 150 | // thread id is represented (e.g. numpunct or showbase), we | |
| 151 | // use a temporary stream instead and just output the thread | |
| 152 | // id representation as a string. | |
| 153 | ||
| 154 | basic_ostringstream<_CharT, _Traits> __sstr; | |
| 155 | __sstr.imbue(locale::classic()); | |
| 156 | __sstr << __id.__id_; | |
| 157 | return __os << __sstr.str(); | |
| 158 | } | |
| 159 | #endif // _LIBCPP_HAS_NO_LOCALIZATION | |
| 160 | ||
| 161 | class _LIBCPP_EXPORTED_FROM_ABI thread | |
| 162 | { | |
| 163 | __libcpp_thread_t __t_; | |
| 164 | ||
| 165 | thread(const thread&); | |
| 166 | thread& operator=(const thread&); | |
| 167 | public: | |
| 168 | typedef __thread_id id; | |
| 169 | typedef __libcpp_thread_t native_handle_type; | |
| 170 | ||
| 171 | _LIBCPP_INLINE_VISIBILITY | |
| 172 | thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} | |
| 173 | #ifndef _LIBCPP_CXX03_LANG | |
| 174 | template <class _Fp, class ..._Args, | |
| 175 | class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> > | |
| 176 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 177 | explicit thread(_Fp&& __f, _Args&&... __args); | |
| 178 | #else // _LIBCPP_CXX03_LANG | |
| 179 | template <class _Fp> | |
| 180 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 181 | explicit thread(_Fp __f); | |
| 182 | #endif | |
| 183 | ~thread(); | |
| 184 | ||
| 185 | _LIBCPP_INLINE_VISIBILITY | |
| 186 | thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { | |
| 187 | __t.__t_ = _LIBCPP_NULL_THREAD; | |
| 188 | } | |
| 189 | ||
| 190 | _LIBCPP_INLINE_VISIBILITY | |
| 191 | thread& operator=(thread&& __t) _NOEXCEPT { | |
| 192 | if (!__libcpp_thread_isnull(&__t_)) | |
| 193 | terminate(); | |
| 194 | __t_ = __t.__t_; | |
| 195 | __t.__t_ = _LIBCPP_NULL_THREAD; | |
| 196 | return *this; | |
| 197 | } | |
| 198 | ||
| 199 | _LIBCPP_INLINE_VISIBILITY | |
| 200 | void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} | |
| 201 | ||
| 202 | _LIBCPP_INLINE_VISIBILITY | |
| 203 | bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);} | |
| 204 | void join(); | |
| 205 | void detach(); | |
| 206 | _LIBCPP_INLINE_VISIBILITY | |
| 207 | id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} | |
| 208 | _LIBCPP_INLINE_VISIBILITY | |
| 209 | native_handle_type native_handle() _NOEXCEPT {return __t_;} | |
| 210 | ||
| 211 | static unsigned hardware_concurrency() _NOEXCEPT; | |
| 212 | }; | |
| 213 | ||
| 214 | #ifndef _LIBCPP_CXX03_LANG | |
| 215 | ||
| 216 | template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> | |
| 217 | inline _LIBCPP_INLINE_VISIBILITY | |
| 218 | void | |
| 219 | __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) | |
| 220 | { | |
| 221 | _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); | |
| 222 | } | |
| 223 | ||
| 224 | template <class _Fp> | |
| 225 | _LIBCPP_INLINE_VISIBILITY | |
| 226 | void* __thread_proxy(void* __vp) | |
| 227 | { | |
| 228 | // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...> | |
| 229 | unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
| 230 | __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release()); | |
| 231 | typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; | |
| 232 | _VSTD::__thread_execute(*__p.get(), _Index()); | |
| 233 | return nullptr; | |
| 234 | } | |
| 235 | ||
| 236 | template <class _Fp, class ..._Args, | |
| 237 | class | |
| 238 | > | |
| 239 | thread::thread(_Fp&& __f, _Args&&... __args) | |
| 240 | { | |
| 241 | typedef unique_ptr<__thread_struct> _TSPtr; | |
| 242 | _TSPtr __tsp(new __thread_struct); | |
| 243 | typedef tuple<_TSPtr, __decay_t<_Fp>, __decay_t<_Args>...> _Gp; | |
| 244 | unique_ptr<_Gp> __p( | |
| 245 | new _Gp(_VSTD::move(__tsp), | |
| 246 | _VSTD::forward<_Fp>(__f), | |
| 247 | _VSTD::forward<_Args>(__args)...)); | |
| 248 | int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
| 249 | if (__ec == 0) | |
| 250 | __p.release(); | |
| 251 | else | |
| 252 | __throw_system_error(__ec, "thread constructor failed"); | |
| 253 | } | |
| 254 | ||
| 255 | #else // _LIBCPP_CXX03_LANG | |
| 256 | ||
| 257 | template <class _Fp> | |
| 258 | struct __thread_invoke_pair { | |
| 259 | // This type is used to pass memory for thread local storage and a functor | |
| 260 | // to a newly created thread because std::pair doesn't work with | |
| 261 | // std::unique_ptr in C++03. | |
| 262 | _LIBCPP_HIDE_FROM_ABI __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} | |
| 263 | unique_ptr<__thread_struct> __tsp_; | |
| 264 | _Fp __fn_; | |
| 265 | }; | |
| 266 | ||
| 267 | template <class _Fp> | |
| 268 | _LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) | |
| 269 | { | |
| 270 | unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
| 271 | __thread_local_data().set_pointer(__p->__tsp_.release()); | |
| 272 | (__p->__fn_)(); | |
| 273 | return nullptr; | |
| 274 | } | |
| 275 | ||
| 276 | template <class _Fp> | |
| 277 | thread::thread(_Fp __f) | |
| 278 | { | |
| 279 | ||
| 280 | typedef __thread_invoke_pair<_Fp> _InvokePair; | |
| 281 | typedef unique_ptr<_InvokePair> _PairPtr; | |
| 282 | _PairPtr __pp(new _InvokePair(__f)); | |
| 283 | int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); | |
| 284 | if (__ec == 0) | |
| 285 | __pp.release(); | |
| 286 | else | |
| 287 | __throw_system_error(__ec, "thread constructor failed"); | |
| 288 | } | |
| 289 | ||
| 290 | #endif // _LIBCPP_CXX03_LANG | |
| 291 | ||
| 292 | inline _LIBCPP_INLINE_VISIBILITY | |
| 293 | void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} | |
| 294 | ||
| 295 | _LIBCPP_END_NAMESPACE_STD | |
| 296 | ||
| 297 | #endif // _LIBCPP___THREAD_THREAD_H |
lib/libcxx/include/__threading_support+19-136| ... | ... | @@ -13,13 +13,9 @@ |
| 13 | 13 | #include <__availability> |
| 14 | 14 | #include <__chrono/convert_to_timespec.h> |
| 15 | 15 | #include <__chrono/duration.h> |
| 16 | #include <__compare/ordering.h> | |
| 17 | 16 | #include <__config> |
| 18 | #include <__fwd/hash.h> | |
| 19 | 17 | #include <__thread/poll_with_backoff.h> |
| 20 | 18 | #include <errno.h> |
| 21 | #include <iosfwd> | |
| 22 | #include <limits> | |
| 23 | 19 | |
| 24 | 20 | #ifdef __MVS__ |
| 25 | 21 | # include <__support/ibm/nanosleep.h> |
| ... | ... | @@ -34,26 +30,26 @@ |
| 34 | 30 | #elif !defined(_LIBCPP_HAS_NO_THREADS) |
| 35 | 31 | |
| 36 | 32 | #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) |
| 33 | // Some platforms require <bits/atomic_wide_counter.h> in order for | |
| 34 | // PTHREAD_COND_INITIALIZER to be expanded. Normally that would come | |
| 35 | // in via <pthread.h>, but it's a non-modular header on those platforms, | |
| 36 | // so libc++'s <math.h> usually absorbs atomic_wide_counter.h into the | |
| 37 | // module with <math.h> and makes atomic_wide_counter.h invisible. | |
| 38 | // Include <math.h> here to work around that. | |
| 39 | # include <math.h> | |
| 40 | ||
| 37 | 41 | # include <pthread.h> |
| 38 | 42 | # include <sched.h> |
| 39 | 43 | #elif defined(_LIBCPP_HAS_THREAD_API_C11) |
| 40 | 44 | # include <threads.h> |
| 41 | 45 | #endif |
| 42 | 46 | |
| 43 | #if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ | |
| 44 | defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \ | |
| 45 | defined(_LIBCPP_HAS_THREAD_API_WIN32) | |
| 46 | #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS | |
| 47 | #if defined(_LIBCPP_HAS_THREAD_API_WIN32) | |
| 48 | #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_EXPORTED_FROM_ABI | |
| 47 | 49 | #else |
| 48 | 50 | #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY |
| 49 | 51 | #endif |
| 50 | 52 | |
| 51 | #if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(no_thread_safety_analysis) | |
| 52 | #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) | |
| 53 | #else | |
| 54 | #define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS | |
| 55 | #endif | |
| 56 | ||
| 57 | 53 | typedef ::timespec __libcpp_timespec_t; |
| 58 | 54 | #endif // !defined(_LIBCPP_HAS_NO_THREADS) |
| 59 | 55 | |
| ... | ... | @@ -252,28 +248,25 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p); |
| 252 | 248 | |
| 253 | 249 | #endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) |
| 254 | 250 | |
| 255 | #if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \ | |
| 256 | defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) | |
| 257 | ||
| 258 | 251 | #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) |
| 259 | 252 | |
| 260 | 253 | int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m) |
| 261 | 254 | { |
| 262 | pthread_mutexattr_t attr; | |
| 263 | int __ec = pthread_mutexattr_init(&attr); | |
| 255 | pthread_mutexattr_t __attr; | |
| 256 | int __ec = pthread_mutexattr_init(&__attr); | |
| 264 | 257 | if (__ec) |
| 265 | 258 | return __ec; |
| 266 | __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
| 259 | __ec = pthread_mutexattr_settype(&__attr, PTHREAD_MUTEX_RECURSIVE); | |
| 267 | 260 | if (__ec) { |
| 268 | pthread_mutexattr_destroy(&attr); | |
| 261 | pthread_mutexattr_destroy(&__attr); | |
| 269 | 262 | return __ec; |
| 270 | 263 | } |
| 271 | __ec = pthread_mutex_init(__m, &attr); | |
| 264 | __ec = pthread_mutex_init(__m, &__attr); | |
| 272 | 265 | if (__ec) { |
| 273 | pthread_mutexattr_destroy(&attr); | |
| 266 | pthread_mutexattr_destroy(&__attr); | |
| 274 | 267 | return __ec; |
| 275 | 268 | } |
| 276 | __ec = pthread_mutexattr_destroy(&attr); | |
| 269 | __ec = pthread_mutexattr_destroy(&__attr); | |
| 277 | 270 | if (__ec) { |
| 278 | 271 | pthread_mutex_destroy(__m); |
| 279 | 272 | return __ec; |
| ... | ... | @@ -380,8 +373,8 @@ int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), |
| 380 | 373 | |
| 381 | 374 | __libcpp_thread_id __libcpp_thread_get_current_id() |
| 382 | 375 | { |
| 383 | const __libcpp_thread_t thread = pthread_self(); | |
| 384 | return __libcpp_thread_get_id(&thread); | |
| 376 | const __libcpp_thread_t __current_thread = pthread_self(); | |
| 377 | return __libcpp_thread_get_id(&__current_thread); | |
| 385 | 378 | } |
| 386 | 379 | |
| 387 | 380 | __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) |
| ... | ... | @@ -589,116 +582,6 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p) |
| 589 | 582 | |
| 590 | 583 | #endif |
| 591 | 584 | |
| 592 | ||
| 593 | #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL | |
| 594 | ||
| 595 | class _LIBCPP_TYPE_VIS thread; | |
| 596 | class _LIBCPP_TYPE_VIS __thread_id; | |
| 597 | ||
| 598 | namespace this_thread | |
| 599 | { | |
| 600 | ||
| 601 | _LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; | |
| 602 | ||
| 603 | } // namespace this_thread | |
| 604 | ||
| 605 | template<> struct hash<__thread_id>; | |
| 606 | ||
| 607 | class _LIBCPP_TEMPLATE_VIS __thread_id | |
| 608 | { | |
| 609 | // FIXME: pthread_t is a pointer on Darwin but a long on Linux. | |
| 610 | // NULL is the no-thread value on Darwin. Someone needs to check | |
| 611 | // on other platforms. We assume 0 works everywhere for now. | |
| 612 | __libcpp_thread_id __id_; | |
| 613 | ||
| 614 | static _LIBCPP_HIDE_FROM_ABI | |
| 615 | bool __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT | |
| 616 | { // id==0 is always less than any other thread_id | |
| 617 | if (__x.__id_ == 0) return __y.__id_ != 0; | |
| 618 | if (__y.__id_ == 0) return false; | |
| 619 | return __libcpp_thread_id_less(__x.__id_, __y.__id_); | |
| 620 | } | |
| 621 | ||
| 622 | public: | |
| 623 | _LIBCPP_INLINE_VISIBILITY | |
| 624 | __thread_id() _NOEXCEPT : __id_(0) {} | |
| 625 | ||
| 626 | _LIBCPP_INLINE_VISIBILITY | |
| 627 | void __reset() { __id_ = 0; } | |
| 628 | ||
| 629 | friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT; | |
| 630 | #if _LIBCPP_STD_VER <= 17 | |
| 631 | friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT; | |
| 632 | #else // _LIBCPP_STD_VER <= 17 | |
| 633 | friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept; | |
| 634 | #endif // _LIBCPP_STD_VER <= 17 | |
| 635 | ||
| 636 | template<class _CharT, class _Traits> | |
| 637 | friend | |
| 638 | _LIBCPP_INLINE_VISIBILITY | |
| 639 | basic_ostream<_CharT, _Traits>& | |
| 640 | operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); | |
| 641 | ||
| 642 | private: | |
| 643 | _LIBCPP_INLINE_VISIBILITY | |
| 644 | __thread_id(__libcpp_thread_id __id) : __id_(__id) {} | |
| 645 | ||
| 646 | friend __thread_id this_thread::get_id() _NOEXCEPT; | |
| 647 | friend class _LIBCPP_TYPE_VIS thread; | |
| 648 | friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; | |
| 649 | }; | |
| 650 | ||
| 651 | inline _LIBCPP_HIDE_FROM_ABI | |
| 652 | bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT { | |
| 653 | // Don't pass id==0 to underlying routines | |
| 654 | if (__x.__id_ == 0) | |
| 655 | return __y.__id_ == 0; | |
| 656 | if (__y.__id_ == 0) | |
| 657 | return false; | |
| 658 | return __libcpp_thread_id_equal(__x.__id_, __y.__id_); | |
| 659 | } | |
| 660 | ||
| 661 | #if _LIBCPP_STD_VER <= 17 | |
| 662 | ||
| 663 | inline _LIBCPP_HIDE_FROM_ABI | |
| 664 | bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { | |
| 665 | return !(__x == __y); | |
| 666 | } | |
| 667 | ||
| 668 | inline _LIBCPP_HIDE_FROM_ABI | |
| 669 | bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT { | |
| 670 | return __thread_id::__lt_impl(__x.__id_, __y.__id_); | |
| 671 | } | |
| 672 | ||
| 673 | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); } | |
| 674 | inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; } | |
| 675 | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); } | |
| 676 | ||
| 677 | #else // _LIBCPP_STD_VER <= 17 | |
| 678 | ||
| 679 | inline _LIBCPP_HIDE_FROM_ABI | |
| 680 | strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept { | |
| 681 | if (__x == __y) | |
| 682 | return strong_ordering::equal; | |
| 683 | if (__thread_id::__lt_impl(__x, __y)) | |
| 684 | return strong_ordering::less; | |
| 685 | return strong_ordering::greater; | |
| 686 | } | |
| 687 | ||
| 688 | #endif // _LIBCPP_STD_VER <= 17 | |
| 689 | ||
| 690 | namespace this_thread | |
| 691 | { | |
| 692 | ||
| 693 | inline _LIBCPP_INLINE_VISIBILITY | |
| 694 | __thread_id | |
| 695 | get_id() _NOEXCEPT | |
| 696 | { | |
| 697 | return __libcpp_thread_get_current_id(); | |
| 698 | } | |
| 699 | ||
| 700 | } // namespace this_thread | |
| 701 | ||
| 702 | 585 | #endif // !_LIBCPP_HAS_NO_THREADS |
| 703 | 586 | |
| 704 | 587 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__tree+74-76| ... | ... | @@ -13,11 +13,11 @@ |
| 13 | 13 | #include <__algorithm/min.h> |
| 14 | 14 | #include <__assert> |
| 15 | 15 | #include <__config> |
| 16 | #include <__debug> | |
| 17 | 16 | #include <__functional/invoke.h> |
| 18 | 17 | #include <__iterator/distance.h> |
| 19 | 18 | #include <__iterator/iterator_traits.h> |
| 20 | 19 | #include <__iterator/next.h> |
| 20 | #include <__memory/addressof.h> | |
| 21 | 21 | #include <__memory/allocator_traits.h> |
| 22 | 22 | #include <__memory/compressed_pair.h> |
| 23 | 23 | #include <__memory/pointer_traits.h> |
| ... | ... | @@ -26,6 +26,7 @@ |
| 26 | 26 | #include <__type_traits/can_extract_key.h> |
| 27 | 27 | #include <__type_traits/conditional.h> |
| 28 | 28 | #include <__type_traits/is_const.h> |
| 29 | #include <__type_traits/is_copy_constructible.h> | |
| 29 | 30 | #include <__type_traits/is_nothrow_copy_constructible.h> |
| 30 | 31 | #include <__type_traits/is_nothrow_default_constructible.h> |
| 31 | 32 | #include <__type_traits/is_nothrow_move_assignable.h> |
| ... | ... | @@ -167,7 +168,7 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 167 | 168 | _NodePtr |
| 168 | 169 | __tree_min(_NodePtr __x) _NOEXCEPT |
| 169 | 170 | { |
| 170 | _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null"); | |
| 171 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null"); | |
| 171 | 172 | while (__x->__left_ != nullptr) |
| 172 | 173 | __x = __x->__left_; |
| 173 | 174 | return __x; |
| ... | ... | @@ -179,7 +180,7 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 179 | 180 | _NodePtr |
| 180 | 181 | __tree_max(_NodePtr __x) _NOEXCEPT |
| 181 | 182 | { |
| 182 | _LIBCPP_ASSERT(__x != nullptr, "Root node shouldn't be null"); | |
| 183 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Root node shouldn't be null"); | |
| 183 | 184 | while (__x->__right_ != nullptr) |
| 184 | 185 | __x = __x->__right_; |
| 185 | 186 | return __x; |
| ... | ... | @@ -190,7 +191,7 @@ template <class _NodePtr> |
| 190 | 191 | _LIBCPP_HIDE_FROM_ABI _NodePtr |
| 191 | 192 | __tree_next(_NodePtr __x) _NOEXCEPT |
| 192 | 193 | { |
| 193 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 194 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 194 | 195 | if (__x->__right_ != nullptr) |
| 195 | 196 | return _VSTD::__tree_min(__x->__right_); |
| 196 | 197 | while (!_VSTD::__tree_is_left_child(__x)) |
| ... | ... | @@ -203,7 +204,7 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 203 | 204 | _EndNodePtr |
| 204 | 205 | __tree_next_iter(_NodePtr __x) _NOEXCEPT |
| 205 | 206 | { |
| 206 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 207 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 207 | 208 | if (__x->__right_ != nullptr) |
| 208 | 209 | return static_cast<_EndNodePtr>(_VSTD::__tree_min(__x->__right_)); |
| 209 | 210 | while (!_VSTD::__tree_is_left_child(__x)) |
| ... | ... | @@ -218,7 +219,7 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 218 | 219 | _NodePtr |
| 219 | 220 | __tree_prev_iter(_EndNodePtr __x) _NOEXCEPT |
| 220 | 221 | { |
| 221 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 222 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 222 | 223 | if (__x->__left_ != nullptr) |
| 223 | 224 | return _VSTD::__tree_max(__x->__left_); |
| 224 | 225 | _NodePtr __xx = static_cast<_NodePtr>(__x); |
| ... | ... | @@ -232,7 +233,7 @@ template <class _NodePtr> |
| 232 | 233 | _LIBCPP_HIDE_FROM_ABI _NodePtr |
| 233 | 234 | __tree_leaf(_NodePtr __x) _NOEXCEPT |
| 234 | 235 | { |
| 235 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 236 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 236 | 237 | while (true) |
| 237 | 238 | { |
| 238 | 239 | if (__x->__left_ != nullptr) |
| ... | ... | @@ -256,8 +257,8 @@ template <class _NodePtr> |
| 256 | 257 | _LIBCPP_HIDE_FROM_ABI void |
| 257 | 258 | __tree_left_rotate(_NodePtr __x) _NOEXCEPT |
| 258 | 259 | { |
| 259 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 260 | _LIBCPP_ASSERT(__x->__right_ != nullptr, "node should have a right child"); | |
| 260 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 261 | _LIBCPP_ASSERT_INTERNAL(__x->__right_ != nullptr, "node should have a right child"); | |
| 261 | 262 | _NodePtr __y = __x->__right_; |
| 262 | 263 | __x->__right_ = __y->__left_; |
| 263 | 264 | if (__x->__right_ != nullptr) |
| ... | ... | @@ -277,8 +278,8 @@ template <class _NodePtr> |
| 277 | 278 | _LIBCPP_HIDE_FROM_ABI void |
| 278 | 279 | __tree_right_rotate(_NodePtr __x) _NOEXCEPT |
| 279 | 280 | { |
| 280 | _LIBCPP_ASSERT(__x != nullptr, "node shouldn't be null"); | |
| 281 | _LIBCPP_ASSERT(__x->__left_ != nullptr, "node should have a left child"); | |
| 281 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null"); | |
| 282 | _LIBCPP_ASSERT_INTERNAL(__x->__left_ != nullptr, "node should have a left child"); | |
| 282 | 283 | _NodePtr __y = __x->__left_; |
| 283 | 284 | __x->__left_ = __y->__right_; |
| 284 | 285 | if (__x->__left_ != nullptr) |
| ... | ... | @@ -303,8 +304,8 @@ template <class _NodePtr> |
| 303 | 304 | _LIBCPP_HIDE_FROM_ABI void |
| 304 | 305 | __tree_balance_after_insert(_NodePtr __root, _NodePtr __x) _NOEXCEPT |
| 305 | 306 | { |
| 306 | _LIBCPP_ASSERT(__root != nullptr, "Root of the tree shouldn't be null"); | |
| 307 | _LIBCPP_ASSERT(__x != nullptr, "Can't attach null node to a leaf"); | |
| 307 | _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root of the tree shouldn't be null"); | |
| 308 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "Can't attach null node to a leaf"); | |
| 308 | 309 | __x->__is_black_ = __x == __root; |
| 309 | 310 | while (__x != __root && !__x->__parent_unsafe()->__is_black_) |
| 310 | 311 | { |
| ... | ... | @@ -373,9 +374,9 @@ template <class _NodePtr> |
| 373 | 374 | _LIBCPP_HIDE_FROM_ABI void |
| 374 | 375 | __tree_remove(_NodePtr __root, _NodePtr __z) _NOEXCEPT |
| 375 | 376 | { |
| 376 | _LIBCPP_ASSERT(__root != nullptr, "Root node should not be null"); | |
| 377 | _LIBCPP_ASSERT(__z != nullptr, "The node to remove should not be null"); | |
| 378 | _LIBCPP_DEBUG_ASSERT(__tree_invariant(__root), "The tree invariants should hold"); | |
| 377 | _LIBCPP_ASSERT_INTERNAL(__root != nullptr, "Root node should not be null"); | |
| 378 | _LIBCPP_ASSERT_INTERNAL(__z != nullptr, "The node to remove should not be null"); | |
| 379 | _LIBCPP_ASSERT_INTERNAL(std::__tree_invariant(__root), "The tree invariants should hold"); | |
| 379 | 380 | // __z will be removed from the tree. Client still needs to destruct/deallocate it |
| 380 | 381 | // __y is either __z, or if __z has two children, __tree_next(__z). |
| 381 | 382 | // __y will have at most one child. |
| ... | ... | @@ -797,7 +798,7 @@ public: |
| 797 | 798 | bool __value_constructed; |
| 798 | 799 | |
| 799 | 800 | |
| 800 | __tree_node_destructor(const __tree_node_destructor &) = default; | |
| 801 | _LIBCPP_HIDE_FROM_ABI __tree_node_destructor(const __tree_node_destructor &) = default; | |
| 801 | 802 | __tree_node_destructor& operator=(const __tree_node_destructor&) = delete; |
| 802 | 803 | |
| 803 | 804 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -818,7 +819,7 @@ public: |
| 818 | 819 | template <class> friend class __map_node_destructor; |
| 819 | 820 | }; |
| 820 | 821 | |
| 821 | #if _LIBCPP_STD_VER > 14 | |
| 822 | #if _LIBCPP_STD_VER >= 17 | |
| 822 | 823 | template <class _NodeType, class _Alloc> |
| 823 | 824 | struct __generic_container_node_destructor; |
| 824 | 825 | template <class _Tp, class _VoidPtr, class _Alloc> |
| ... | ... | @@ -849,7 +850,7 @@ public: |
| 849 | 850 | typedef typename _NodeTypes::__node_value_type_pointer pointer; |
| 850 | 851 | |
| 851 | 852 | _LIBCPP_INLINE_VISIBILITY __tree_iterator() _NOEXCEPT |
| 852 | #if _LIBCPP_STD_VER > 11 | |
| 853 | #if _LIBCPP_STD_VER >= 14 | |
| 853 | 854 | : __ptr_(nullptr) |
| 854 | 855 | #endif |
| 855 | 856 | {} |
| ... | ... | @@ -922,7 +923,7 @@ public: |
| 922 | 923 | typedef typename _NodeTypes::__const_node_value_type_pointer pointer; |
| 923 | 924 | |
| 924 | 925 | _LIBCPP_INLINE_VISIBILITY __tree_const_iterator() _NOEXCEPT |
| 925 | #if _LIBCPP_STD_VER > 11 | |
| 926 | #if _LIBCPP_STD_VER >= 14 | |
| 926 | 927 | : __ptr_(nullptr) |
| 927 | 928 | #endif |
| 928 | 929 | {} |
| ... | ... | @@ -1100,36 +1101,36 @@ public: |
| 1100 | 1101 | __node_pointer __root() const _NOEXCEPT |
| 1101 | 1102 | {return static_cast<__node_pointer>(__end_node()->__left_);} |
| 1102 | 1103 | |
| 1103 | __node_base_pointer* __root_ptr() const _NOEXCEPT { | |
| 1104 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer* __root_ptr() const _NOEXCEPT { | |
| 1104 | 1105 | return _VSTD::addressof(__end_node()->__left_); |
| 1105 | 1106 | } |
| 1106 | 1107 | |
| 1107 | 1108 | typedef __tree_iterator<value_type, __node_pointer, difference_type> iterator; |
| 1108 | 1109 | typedef __tree_const_iterator<value_type, __node_pointer, difference_type> const_iterator; |
| 1109 | 1110 | |
| 1110 | explicit __tree(const value_compare& __comp) | |
| 1111 | _LIBCPP_HIDE_FROM_ABI explicit __tree(const value_compare& __comp) | |
| 1111 | 1112 | _NOEXCEPT_( |
| 1112 | 1113 | is_nothrow_default_constructible<__node_allocator>::value && |
| 1113 | 1114 | is_nothrow_copy_constructible<value_compare>::value); |
| 1114 | explicit __tree(const allocator_type& __a); | |
| 1115 | __tree(const value_compare& __comp, const allocator_type& __a); | |
| 1116 | __tree(const __tree& __t); | |
| 1117 | __tree& operator=(const __tree& __t); | |
| 1115 | _LIBCPP_HIDE_FROM_ABI explicit __tree(const allocator_type& __a); | |
| 1116 | _LIBCPP_HIDE_FROM_ABI __tree(const value_compare& __comp, const allocator_type& __a); | |
| 1117 | _LIBCPP_HIDE_FROM_ABI __tree(const __tree& __t); | |
| 1118 | _LIBCPP_HIDE_FROM_ABI __tree& operator=(const __tree& __t); | |
| 1118 | 1119 | template <class _ForwardIterator> |
| 1119 | void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); | |
| 1120 | _LIBCPP_HIDE_FROM_ABI void __assign_unique(_ForwardIterator __first, _ForwardIterator __last); | |
| 1120 | 1121 | template <class _InputIterator> |
| 1121 | void __assign_multi(_InputIterator __first, _InputIterator __last); | |
| 1122 | __tree(__tree&& __t) | |
| 1122 | _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); | |
| 1123 | _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t) | |
| 1123 | 1124 | _NOEXCEPT_( |
| 1124 | 1125 | is_nothrow_move_constructible<__node_allocator>::value && |
| 1125 | 1126 | is_nothrow_move_constructible<value_compare>::value); |
| 1126 | __tree(__tree&& __t, const allocator_type& __a); | |
| 1127 | __tree& operator=(__tree&& __t) | |
| 1127 | _LIBCPP_HIDE_FROM_ABI __tree(__tree&& __t, const allocator_type& __a); | |
| 1128 | _LIBCPP_HIDE_FROM_ABI __tree& operator=(__tree&& __t) | |
| 1128 | 1129 | _NOEXCEPT_( |
| 1129 | 1130 | __node_traits::propagate_on_container_move_assignment::value && |
| 1130 | 1131 | is_nothrow_move_assignable<value_compare>::value && |
| 1131 | 1132 | is_nothrow_move_assignable<__node_allocator>::value); |
| 1132 | ~__tree(); | |
| 1133 | _LIBCPP_HIDE_FROM_ABI ~__tree(); | |
| 1133 | 1134 | |
| 1134 | 1135 | _LIBCPP_INLINE_VISIBILITY |
| 1135 | 1136 | iterator begin() _NOEXCEPT {return iterator(__begin_node());} |
| ... | ... | @@ -1146,9 +1147,9 @@ public: |
| 1146 | 1147 | __node_traits::max_size(__node_alloc()), |
| 1147 | 1148 | numeric_limits<difference_type >::max());} |
| 1148 | 1149 | |
| 1149 | void clear() _NOEXCEPT; | |
| 1150 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; | |
| 1150 | 1151 | |
| 1151 | void swap(__tree& __t) | |
| 1152 | _LIBCPP_HIDE_FROM_ABI void swap(__tree& __t) | |
| 1152 | 1153 | #if _LIBCPP_STD_VER <= 11 |
| 1153 | 1154 | _NOEXCEPT_( |
| 1154 | 1155 | __is_nothrow_swappable<value_compare>::value |
| ... | ... | @@ -1160,23 +1161,23 @@ public: |
| 1160 | 1161 | #endif |
| 1161 | 1162 | |
| 1162 | 1163 | template <class _Key, class ..._Args> |
| 1163 | pair<iterator, bool> | |
| 1164 | _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> | |
| 1164 | 1165 | __emplace_unique_key_args(_Key const&, _Args&&... __args); |
| 1165 | 1166 | template <class _Key, class ..._Args> |
| 1166 | pair<iterator, bool> | |
| 1167 | _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> | |
| 1167 | 1168 | __emplace_hint_unique_key_args(const_iterator, _Key const&, _Args&&...); |
| 1168 | 1169 | |
| 1169 | 1170 | template <class... _Args> |
| 1170 | pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); | |
| 1171 | _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __emplace_unique_impl(_Args&&... __args); | |
| 1171 | 1172 | |
| 1172 | 1173 | template <class... _Args> |
| 1173 | iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); | |
| 1174 | _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_unique_impl(const_iterator __p, _Args&&... __args); | |
| 1174 | 1175 | |
| 1175 | 1176 | template <class... _Args> |
| 1176 | iterator __emplace_multi(_Args&&... __args); | |
| 1177 | _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args); | |
| 1177 | 1178 | |
| 1178 | 1179 | template <class... _Args> |
| 1179 | iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); | |
| 1180 | _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); | |
| 1180 | 1181 | |
| 1181 | 1182 | template <class _Pp> |
| 1182 | 1183 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1331,7 +1332,7 @@ public: |
| 1331 | 1332 | _LIBCPP_INLINE_VISIBILITY iterator |
| 1332 | 1333 | __remove_node_pointer(__node_pointer) _NOEXCEPT; |
| 1333 | 1334 | |
| 1334 | #if _LIBCPP_STD_VER > 14 | |
| 1335 | #if _LIBCPP_STD_VER >= 17 | |
| 1335 | 1336 | template <class _NodeHandle, class _InsertReturnType> |
| 1336 | 1337 | _LIBCPP_INLINE_VISIBILITY |
| 1337 | 1338 | _InsertReturnType __node_handle_insert_unique(_NodeHandle&&); |
| ... | ... | @@ -1361,33 +1362,33 @@ public: |
| 1361 | 1362 | _NodeHandle __node_handle_extract(const_iterator); |
| 1362 | 1363 | #endif |
| 1363 | 1364 | |
| 1364 | iterator erase(const_iterator __p); | |
| 1365 | iterator erase(const_iterator __f, const_iterator __l); | |
| 1365 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); | |
| 1366 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); | |
| 1366 | 1367 | template <class _Key> |
| 1367 | size_type __erase_unique(const _Key& __k); | |
| 1368 | _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); | |
| 1368 | 1369 | template <class _Key> |
| 1369 | size_type __erase_multi(const _Key& __k); | |
| 1370 | _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); | |
| 1370 | 1371 | |
| 1371 | void __insert_node_at(__parent_pointer __parent, | |
| 1372 | _LIBCPP_HIDE_FROM_ABI void __insert_node_at(__parent_pointer __parent, | |
| 1372 | 1373 | __node_base_pointer& __child, |
| 1373 | 1374 | __node_base_pointer __new_node) _NOEXCEPT; |
| 1374 | 1375 | |
| 1375 | 1376 | template <class _Key> |
| 1376 | iterator find(const _Key& __v); | |
| 1377 | _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __v); | |
| 1377 | 1378 | template <class _Key> |
| 1378 | const_iterator find(const _Key& __v) const; | |
| 1379 | _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __v) const; | |
| 1379 | 1380 | |
| 1380 | 1381 | template <class _Key> |
| 1381 | size_type __count_unique(const _Key& __k) const; | |
| 1382 | _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const; | |
| 1382 | 1383 | template <class _Key> |
| 1383 | size_type __count_multi(const _Key& __k) const; | |
| 1384 | _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; | |
| 1384 | 1385 | |
| 1385 | 1386 | template <class _Key> |
| 1386 | 1387 | _LIBCPP_INLINE_VISIBILITY |
| 1387 | 1388 | iterator lower_bound(const _Key& __v) |
| 1388 | 1389 | {return __lower_bound(__v, __root(), __end_node());} |
| 1389 | 1390 | template <class _Key> |
| 1390 | iterator __lower_bound(const _Key& __v, | |
| 1391 | _LIBCPP_HIDE_FROM_ABI iterator __lower_bound(const _Key& __v, | |
| 1391 | 1392 | __node_pointer __root, |
| 1392 | 1393 | __iter_pointer __result); |
| 1393 | 1394 | template <class _Key> |
| ... | ... | @@ -1395,7 +1396,7 @@ public: |
| 1395 | 1396 | const_iterator lower_bound(const _Key& __v) const |
| 1396 | 1397 | {return __lower_bound(__v, __root(), __end_node());} |
| 1397 | 1398 | template <class _Key> |
| 1398 | const_iterator __lower_bound(const _Key& __v, | |
| 1399 | _LIBCPP_HIDE_FROM_ABI const_iterator __lower_bound(const _Key& __v, | |
| 1399 | 1400 | __node_pointer __root, |
| 1400 | 1401 | __iter_pointer __result) const; |
| 1401 | 1402 | template <class _Key> |
| ... | ... | @@ -1403,7 +1404,7 @@ public: |
| 1403 | 1404 | iterator upper_bound(const _Key& __v) |
| 1404 | 1405 | {return __upper_bound(__v, __root(), __end_node());} |
| 1405 | 1406 | template <class _Key> |
| 1406 | iterator __upper_bound(const _Key& __v, | |
| 1407 | _LIBCPP_HIDE_FROM_ABI iterator __upper_bound(const _Key& __v, | |
| 1407 | 1408 | __node_pointer __root, |
| 1408 | 1409 | __iter_pointer __result); |
| 1409 | 1410 | template <class _Key> |
| ... | ... | @@ -1411,55 +1412,52 @@ public: |
| 1411 | 1412 | const_iterator upper_bound(const _Key& __v) const |
| 1412 | 1413 | {return __upper_bound(__v, __root(), __end_node());} |
| 1413 | 1414 | template <class _Key> |
| 1414 | const_iterator __upper_bound(const _Key& __v, | |
| 1415 | _LIBCPP_HIDE_FROM_ABI const_iterator __upper_bound(const _Key& __v, | |
| 1415 | 1416 | __node_pointer __root, |
| 1416 | 1417 | __iter_pointer __result) const; |
| 1417 | 1418 | template <class _Key> |
| 1418 | pair<iterator, iterator> | |
| 1419 | _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> | |
| 1419 | 1420 | __equal_range_unique(const _Key& __k); |
| 1420 | 1421 | template <class _Key> |
| 1421 | pair<const_iterator, const_iterator> | |
| 1422 | _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> | |
| 1422 | 1423 | __equal_range_unique(const _Key& __k) const; |
| 1423 | 1424 | |
| 1424 | 1425 | template <class _Key> |
| 1425 | pair<iterator, iterator> | |
| 1426 | _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> | |
| 1426 | 1427 | __equal_range_multi(const _Key& __k); |
| 1427 | 1428 | template <class _Key> |
| 1428 | pair<const_iterator, const_iterator> | |
| 1429 | _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> | |
| 1429 | 1430 | __equal_range_multi(const _Key& __k) const; |
| 1430 | 1431 | |
| 1431 | 1432 | typedef __tree_node_destructor<__node_allocator> _Dp; |
| 1432 | 1433 | typedef unique_ptr<__node, _Dp> __node_holder; |
| 1433 | 1434 | |
| 1434 | __node_holder remove(const_iterator __p) _NOEXCEPT; | |
| 1435 | _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; | |
| 1435 | 1436 | private: |
| 1436 | __node_base_pointer& | |
| 1437 | __find_leaf_low(__parent_pointer& __parent, const key_type& __v); | |
| 1438 | __node_base_pointer& | |
| 1439 | __find_leaf_high(__parent_pointer& __parent, const key_type& __v); | |
| 1440 | __node_base_pointer& | |
| 1441 | __find_leaf(const_iterator __hint, | |
| 1442 | __parent_pointer& __parent, const key_type& __v); | |
| 1437 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_low(__parent_pointer& __parent, const key_type& __v); | |
| 1438 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_leaf_high(__parent_pointer& __parent, const key_type& __v); | |
| 1439 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer& | |
| 1440 | __find_leaf(const_iterator __hint, __parent_pointer& __parent, const key_type& __v); | |
| 1443 | 1441 | // FIXME: Make this function const qualified. Unfortunately doing so |
| 1444 | 1442 | // breaks existing code which uses non-const callable comparators. |
| 1445 | 1443 | template <class _Key> |
| 1446 | __node_base_pointer& | |
| 1447 | __find_equal(__parent_pointer& __parent, const _Key& __v); | |
| 1444 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal(__parent_pointer& __parent, const _Key& __v); | |
| 1448 | 1445 | template <class _Key> |
| 1449 | 1446 | _LIBCPP_INLINE_VISIBILITY __node_base_pointer& |
| 1450 | 1447 | __find_equal(__parent_pointer& __parent, const _Key& __v) const { |
| 1451 | 1448 | return const_cast<__tree*>(this)->__find_equal(__parent, __v); |
| 1452 | 1449 | } |
| 1453 | 1450 | template <class _Key> |
| 1454 | __node_base_pointer& | |
| 1451 | _LIBCPP_HIDE_FROM_ABI __node_base_pointer& | |
| 1455 | 1452 | __find_equal(const_iterator __hint, __parent_pointer& __parent, |
| 1456 | 1453 | __node_base_pointer& __dummy, |
| 1457 | 1454 | const _Key& __v); |
| 1458 | 1455 | |
| 1459 | 1456 | template <class ..._Args> |
| 1460 | __node_holder __construct_node(_Args&& ...__args); | |
| 1457 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args); | |
| 1461 | 1458 | |
| 1462 | void destroy(__node_pointer __nd) _NOEXCEPT; | |
| 1459 | // TODO: Make this _LIBCPP_HIDE_FROM_ABI | |
| 1460 | _LIBCPP_HIDDEN void destroy(__node_pointer __nd) _NOEXCEPT; | |
| 1463 | 1461 | |
| 1464 | 1462 | _LIBCPP_INLINE_VISIBILITY |
| 1465 | 1463 | void __copy_assign_alloc(const __tree& __t) |
| ... | ... | @@ -1476,8 +1474,8 @@ private: |
| 1476 | 1474 | _LIBCPP_INLINE_VISIBILITY |
| 1477 | 1475 | void __copy_assign_alloc(const __tree&, false_type) {} |
| 1478 | 1476 | |
| 1479 | void __move_assign(__tree& __t, false_type); | |
| 1480 | void __move_assign(__tree& __t, true_type) | |
| 1477 | _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, false_type); | |
| 1478 | _LIBCPP_HIDE_FROM_ABI void __move_assign(__tree& __t, true_type) | |
| 1481 | 1479 | _NOEXCEPT_(is_nothrow_move_assignable<value_compare>::value && |
| 1482 | 1480 | is_nothrow_move_assignable<__node_allocator>::value); |
| 1483 | 1481 | |
| ... | ... | @@ -1640,7 +1638,7 @@ __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first, _Fo |
| 1640 | 1638 | typedef typename _ITraits::value_type _ItValueType; |
| 1641 | 1639 | static_assert((is_same<_ItValueType, __container_value_type>::value), |
| 1642 | 1640 | "__assign_unique may only be called with the containers value type"); |
| 1643 | static_assert(__is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 1641 | static_assert(__has_forward_iterator_category<_ForwardIterator>::value, | |
| 1644 | 1642 | "__assign_unique requires a forward iterator"); |
| 1645 | 1643 | if (size() != 0) |
| 1646 | 1644 | { |
| ... | ... | @@ -2265,7 +2263,7 @@ __tree<_Tp, _Compare, _Allocator>::__remove_node_pointer(__node_pointer __ptr) _ |
| 2265 | 2263 | return __r; |
| 2266 | 2264 | } |
| 2267 | 2265 | |
| 2268 | #if _LIBCPP_STD_VER > 14 | |
| 2266 | #if _LIBCPP_STD_VER >= 17 | |
| 2269 | 2267 | template <class _Tp, class _Compare, class _Allocator> |
| 2270 | 2268 | template <class _NodeHandle, class _InsertReturnType> |
| 2271 | 2269 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -2422,7 +2420,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_merge_multi(_Tree& __source) |
| 2422 | 2420 | } |
| 2423 | 2421 | } |
| 2424 | 2422 | |
| 2425 | #endif // _LIBCPP_STD_VER > 14 | |
| 2423 | #endif // _LIBCPP_STD_VER >= 17 | |
| 2426 | 2424 | |
| 2427 | 2425 | template <class _Tp, class _Compare, class _Allocator> |
| 2428 | 2426 | typename __tree<_Tp, _Compare, _Allocator>::iterator |
lib/libcxx/include/__tuple/make_tuple_types.h created+80| ... | ... | @@ -0,0 +1,80 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H | |
| 10 | #define _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/tuple.h> | |
| 15 | #include <__tuple/tuple_element.h> | |
| 16 | #include <__tuple/tuple_indices.h> | |
| 17 | #include <__tuple/tuple_size.h> | |
| 18 | #include <__tuple/tuple_types.h> | |
| 19 | #include <__type_traits/apply_cv.h> | |
| 20 | #include <__type_traits/remove_cv.h> | |
| 21 | #include <__type_traits/remove_reference.h> | |
| 22 | #include <cstddef> | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 25 | # pragma GCC system_header | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef _LIBCPP_CXX03_LANG | |
| 29 | ||
| 30 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 31 | ||
| 32 | // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a | |
| 33 | // __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). | |
| 34 | // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a | |
| 35 | // lvalue_reference type, then __tuple_types<_Types&...> is the result. | |
| 36 | ||
| 37 | template <class _TupleTypes, class _TupleIndices> | |
| 38 | struct __make_tuple_types_flat; | |
| 39 | ||
| 40 | template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> | |
| 41 | struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { | |
| 42 | // Specialization for pair, tuple, and __tuple_types | |
| 43 | template <class _Tp> | |
| 44 | using __apply_quals _LIBCPP_NODEBUG = __tuple_types<__apply_cv_t<_Tp, __type_pack_element<_Idx, _Types...>>...>; | |
| 45 | }; | |
| 46 | ||
| 47 | template <class _Vt, size_t _Np, size_t ..._Idx> | |
| 48 | struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { | |
| 49 | template <size_t> | |
| 50 | using __value_type = _Vt; | |
| 51 | template <class _Tp> | |
| 52 | using __apply_quals = __tuple_types<__apply_cv_t<_Tp, __value_type<_Idx>>...>; | |
| 53 | }; | |
| 54 | ||
| 55 | template <class _Tp, size_t _Ep = tuple_size<__libcpp_remove_reference_t<_Tp> >::value, | |
| 56 | size_t _Sp = 0, | |
| 57 | bool _SameSize = (_Ep == tuple_size<__libcpp_remove_reference_t<_Tp> >::value)> | |
| 58 | struct __make_tuple_types | |
| 59 | { | |
| 60 | static_assert(_Sp <= _Ep, "__make_tuple_types input error"); | |
| 61 | using _RawTp = __remove_cv_t<__libcpp_remove_reference_t<_Tp> >; | |
| 62 | using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; | |
| 63 | using type = typename _Maker::template __apply_quals<_Tp>; | |
| 64 | }; | |
| 65 | ||
| 66 | template <class ..._Types, size_t _Ep> | |
| 67 | struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { | |
| 68 | typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type; | |
| 69 | }; | |
| 70 | ||
| 71 | template <class ..._Types, size_t _Ep> | |
| 72 | struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { | |
| 73 | typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type; | |
| 74 | }; | |
| 75 | ||
| 76 | _LIBCPP_END_NAMESPACE_STD | |
| 77 | ||
| 78 | #endif // _LIBCPP_CXX03_LANG | |
| 79 | ||
| 80 | #endif // _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H |
lib/libcxx/include/__tuple/pair_like.h created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_PAIR_LIKE_H | |
| 10 | #define _LIBCPP___TUPLE_PAIR_LIKE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__tuple/tuple_like.h> | |
| 14 | #include <__tuple/tuple_size.h> | |
| 15 | #include <__type_traits/remove_cvref.h> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | ||
| 25 | template <class _Tp> | |
| 26 | concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2; | |
| 27 | ||
| 28 | #endif // _LIBCPP_STD_VER >= 20 | |
| 29 | ||
| 30 | _LIBCPP_END_NAMESPACE_STD | |
| 31 | ||
| 32 | #endif // _LIBCPP___TUPLE_PAIR_LIKE_H |
lib/libcxx/include/__tuple/sfinae_helpers.h created+183| ... | ... | @@ -0,0 +1,183 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H | |
| 10 | #define _LIBCPP___TUPLE_SFINAE_HELPERS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/tuple.h> | |
| 14 | #include <__tuple/make_tuple_types.h> | |
| 15 | #include <__tuple/tuple_element.h> | |
| 16 | #include <__tuple/tuple_like_ext.h> | |
| 17 | #include <__tuple/tuple_size.h> | |
| 18 | #include <__tuple/tuple_types.h> | |
| 19 | #include <__type_traits/enable_if.h> | |
| 20 | #include <__type_traits/integral_constant.h> | |
| 21 | #include <__type_traits/is_assignable.h> | |
| 22 | #include <__type_traits/is_constructible.h> | |
| 23 | #include <__type_traits/is_convertible.h> | |
| 24 | #include <__type_traits/is_same.h> | |
| 25 | #include <__type_traits/remove_cvref.h> | |
| 26 | #include <__type_traits/remove_reference.h> | |
| 27 | #include <cstddef> | |
| 28 | ||
| 29 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 30 | # pragma GCC system_header | |
| 31 | #endif | |
| 32 | ||
| 33 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 34 | ||
| 35 | #ifndef _LIBCPP_CXX03_LANG | |
| 36 | ||
| 37 | template <bool ..._Preds> | |
| 38 | struct __all_dummy; | |
| 39 | ||
| 40 | template <bool ..._Pred> | |
| 41 | struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {}; | |
| 42 | ||
| 43 | struct __tuple_sfinae_base { | |
| 44 | template <template <class, class...> class _Trait, | |
| 45 | class ..._LArgs, class ..._RArgs> | |
| 46 | static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) | |
| 47 | -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>; | |
| 48 | template <template <class...> class> | |
| 49 | static auto __do_test(...) -> false_type; | |
| 50 | ||
| 51 | template <class _FromArgs, class _ToArgs> | |
| 52 | using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); | |
| 53 | template <class _FromArgs, class _ToArgs> | |
| 54 | using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); | |
| 55 | template <class _FromArgs, class _ToArgs> | |
| 56 | using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); | |
| 57 | }; | |
| 58 | ||
| 59 | // __tuple_convertible | |
| 60 | ||
| 61 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 62 | bool = __tuple_like_ext<_Up>::value> | |
| 63 | struct __tuple_convertible | |
| 64 | : public false_type {}; | |
| 65 | ||
| 66 | template <class _Tp, class _Up> | |
| 67 | struct __tuple_convertible<_Tp, _Up, true, true> | |
| 68 | : public __tuple_sfinae_base::__convertible< | |
| 69 | typename __make_tuple_types<_Tp>::type | |
| 70 | , typename __make_tuple_types<_Up>::type | |
| 71 | > | |
| 72 | {}; | |
| 73 | ||
| 74 | // __tuple_constructible | |
| 75 | ||
| 76 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 77 | bool = __tuple_like_ext<_Up>::value> | |
| 78 | struct __tuple_constructible | |
| 79 | : public false_type {}; | |
| 80 | ||
| 81 | template <class _Tp, class _Up> | |
| 82 | struct __tuple_constructible<_Tp, _Up, true, true> | |
| 83 | : public __tuple_sfinae_base::__constructible< | |
| 84 | typename __make_tuple_types<_Tp>::type | |
| 85 | , typename __make_tuple_types<_Up>::type | |
| 86 | > | |
| 87 | {}; | |
| 88 | ||
| 89 | // __tuple_assignable | |
| 90 | ||
| 91 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 92 | bool = __tuple_like_ext<_Up>::value> | |
| 93 | struct __tuple_assignable | |
| 94 | : public false_type {}; | |
| 95 | ||
| 96 | template <class _Tp, class _Up> | |
| 97 | struct __tuple_assignable<_Tp, _Up, true, true> | |
| 98 | : public __tuple_sfinae_base::__assignable< | |
| 99 | typename __make_tuple_types<_Tp>::type | |
| 100 | , typename __make_tuple_types<_Up&>::type | |
| 101 | > | |
| 102 | {}; | |
| 103 | ||
| 104 | ||
| 105 | template <size_t _Ip, class ..._Tp> | |
| 106 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > | |
| 107 | { | |
| 108 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; | |
| 109 | }; | |
| 110 | ||
| 111 | struct _LIBCPP_EXPORTED_FROM_ABI __check_tuple_constructor_fail { | |
| 112 | ||
| 113 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { return false; } | |
| 114 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { return false; } | |
| 115 | template <class ...> | |
| 116 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { return false; } | |
| 117 | template <class ...> | |
| 118 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { return false; } | |
| 119 | template <class ...> | |
| 120 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_assign() { return false; } | |
| 121 | }; | |
| 122 | #endif // !defined(_LIBCPP_CXX03_LANG) | |
| 123 | ||
| 124 | #if _LIBCPP_STD_VER >= 17 | |
| 125 | ||
| 126 | template <bool _CanCopy, bool _CanMove> | |
| 127 | struct __sfinae_ctor_base {}; | |
| 128 | template <> | |
| 129 | struct __sfinae_ctor_base<false, false> { | |
| 130 | __sfinae_ctor_base() = default; | |
| 131 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; | |
| 132 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; | |
| 133 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 134 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 135 | }; | |
| 136 | template <> | |
| 137 | struct __sfinae_ctor_base<true, false> { | |
| 138 | __sfinae_ctor_base() = default; | |
| 139 | __sfinae_ctor_base(__sfinae_ctor_base const&) = default; | |
| 140 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; | |
| 141 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 142 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 143 | }; | |
| 144 | template <> | |
| 145 | struct __sfinae_ctor_base<false, true> { | |
| 146 | __sfinae_ctor_base() = default; | |
| 147 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; | |
| 148 | __sfinae_ctor_base(__sfinae_ctor_base &&) = default; | |
| 149 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 150 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 151 | }; | |
| 152 | ||
| 153 | template <bool _CanCopy, bool _CanMove> | |
| 154 | struct __sfinae_assign_base {}; | |
| 155 | template <> | |
| 156 | struct __sfinae_assign_base<false, false> { | |
| 157 | __sfinae_assign_base() = default; | |
| 158 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 159 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 160 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; | |
| 161 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; | |
| 162 | }; | |
| 163 | template <> | |
| 164 | struct __sfinae_assign_base<true, false> { | |
| 165 | __sfinae_assign_base() = default; | |
| 166 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 167 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 168 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default; | |
| 169 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; | |
| 170 | }; | |
| 171 | template <> | |
| 172 | struct __sfinae_assign_base<false, true> { | |
| 173 | __sfinae_assign_base() = default; | |
| 174 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 175 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 176 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; | |
| 177 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default; | |
| 178 | }; | |
| 179 | #endif // _LIBCPP_STD_VER >= 17 | |
| 180 | ||
| 181 | _LIBCPP_END_NAMESPACE_STD | |
| 182 | ||
| 183 | #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H |
lib/libcxx/include/__tuple/tuple_element.h created+93| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_ELEMENT_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_ELEMENT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__tuple/tuple_indices.h> | |
| 14 | #include <__tuple/tuple_types.h> | |
| 15 | #include <__type_traits/add_const.h> | |
| 16 | #include <__type_traits/add_cv.h> | |
| 17 | #include <__type_traits/add_volatile.h> | |
| 18 | #include <cstddef> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element; | |
| 27 | ||
| 28 | template <size_t _Ip, class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> | |
| 30 | { | |
| 31 | typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 32 | }; | |
| 33 | ||
| 34 | template <size_t _Ip, class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> | |
| 36 | { | |
| 37 | typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 38 | }; | |
| 39 | ||
| 40 | template <size_t _Ip, class _Tp> | |
| 41 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> | |
| 42 | { | |
| 43 | typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 44 | }; | |
| 45 | ||
| 46 | #ifndef _LIBCPP_CXX03_LANG | |
| 47 | ||
| 48 | #if !__has_builtin(__type_pack_element) | |
| 49 | ||
| 50 | namespace __indexer_detail { | |
| 51 | ||
| 52 | template <size_t _Idx, class _Tp> | |
| 53 | struct __indexed { using type _LIBCPP_NODEBUG = _Tp; }; | |
| 54 | ||
| 55 | template <class _Types, class _Indexes> struct __indexer; | |
| 56 | ||
| 57 | template <class ..._Types, size_t ..._Idx> | |
| 58 | struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> | |
| 59 | : __indexed<_Idx, _Types>... | |
| 60 | {}; | |
| 61 | ||
| 62 | template <size_t _Idx, class _Tp> | |
| 63 | __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); | |
| 64 | ||
| 65 | } // namespace __indexer_detail | |
| 66 | ||
| 67 | template <size_t _Idx, class ..._Types> | |
| 68 | using __type_pack_element _LIBCPP_NODEBUG = typename decltype( | |
| 69 | __indexer_detail::__at_index<_Idx>( | |
| 70 | __indexer_detail::__indexer< | |
| 71 | __tuple_types<_Types...>, | |
| 72 | typename __make_tuple_indices<sizeof...(_Types)>::type | |
| 73 | >{}) | |
| 74 | )::type; | |
| 75 | #endif | |
| 76 | ||
| 77 | template <size_t _Ip, class ..._Types> | |
| 78 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> > | |
| 79 | { | |
| 80 | static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); | |
| 81 | typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type; | |
| 82 | }; | |
| 83 | ||
| 84 | #if _LIBCPP_STD_VER >= 14 | |
| 85 | template <size_t _Ip, class ..._Tp> | |
| 86 | using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type; | |
| 87 | #endif | |
| 88 | ||
| 89 | #endif // _LIBCPP_CXX03_LANG | |
| 90 | ||
| 91 | _LIBCPP_END_NAMESPACE_STD | |
| 92 | ||
| 93 | #endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H |
lib/libcxx/include/__tuple/tuple_indices.h created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H | |
| 10 | #define _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__utility/integer_sequence.h> | |
| 14 | #include <cstddef> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #ifndef _LIBCPP_CXX03_LANG | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | template <size_t...> struct __tuple_indices {}; | |
| 25 | ||
| 26 | template <size_t _Ep, size_t _Sp = 0> | |
| 27 | struct __make_tuple_indices | |
| 28 | { | |
| 29 | static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); | |
| 30 | typedef __make_indices_imp<_Ep, _Sp> type; | |
| 31 | }; | |
| 32 | ||
| 33 | _LIBCPP_END_NAMESPACE_STD | |
| 34 | ||
| 35 | #endif // _LIBCPP_CXX03_LANG | |
| 36 | ||
| 37 | #endif // _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H |
lib/libcxx/include/__tuple/tuple_like.h created+51| ... | ... | @@ -0,0 +1,51 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_LIKE_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_LIKE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/pair.h> | |
| 15 | #include <__fwd/subrange.h> | |
| 16 | #include <__fwd/tuple.h> | |
| 17 | #include <__type_traits/integral_constant.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <cstddef> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct __tuple_like_impl : false_type {}; | |
| 31 | ||
| 32 | template <class... _Tp> | |
| 33 | struct __tuple_like_impl<tuple<_Tp...> > : true_type {}; | |
| 34 | ||
| 35 | template <class _T1, class _T2> | |
| 36 | struct __tuple_like_impl<pair<_T1, _T2> > : true_type {}; | |
| 37 | ||
| 38 | template <class _Tp, size_t _Size> | |
| 39 | struct __tuple_like_impl<array<_Tp, _Size> > : true_type {}; | |
| 40 | ||
| 41 | template <class _Ip, class _Sp, ranges::subrange_kind _Kp> | |
| 42 | struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {}; | |
| 43 | ||
| 44 | template <class _Tp> | |
| 45 | concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value; | |
| 46 | ||
| 47 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | ||
| 49 | _LIBCPP_END_NAMESPACE_STD | |
| 50 | ||
| 51 | #endif // _LIBCPP___TUPLE_TUPLE_LIKE_H |
lib/libcxx/include/__tuple/tuple_like_ext.h created+44| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/pair.h> | |
| 15 | #include <__fwd/tuple.h> | |
| 16 | #include <__tuple/tuple_types.h> | |
| 17 | #include <__type_traits/integral_constant.h> | |
| 18 | #include <cstddef> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <class _Tp> struct __tuple_like_ext : false_type {}; | |
| 27 | ||
| 28 | template <class _Tp> struct __tuple_like_ext<const _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 29 | template <class _Tp> struct __tuple_like_ext<volatile _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 30 | template <class _Tp> struct __tuple_like_ext<const volatile _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 31 | ||
| 32 | #ifndef _LIBCPP_CXX03_LANG | |
| 33 | template <class... _Tp> struct __tuple_like_ext<tuple<_Tp...> > : true_type {}; | |
| 34 | #endif | |
| 35 | ||
| 36 | template <class _T1, class _T2> struct __tuple_like_ext<pair<_T1, _T2> > : true_type {}; | |
| 37 | ||
| 38 | template <class _Tp, size_t _Size> struct __tuple_like_ext<array<_Tp, _Size> > : true_type {}; | |
| 39 | ||
| 40 | template <class... _Tp> struct __tuple_like_ext<__tuple_types<_Tp...> > : true_type {}; | |
| 41 | ||
| 42 | _LIBCPP_END_NAMESPACE_STD | |
| 43 | ||
| 44 | #endif // _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H |
lib/libcxx/include/__tuple/tuple_size.h created+75| ... | ... | @@ -0,0 +1,75 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_SIZE_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_SIZE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/tuple.h> | |
| 14 | #include <__tuple/tuple_types.h> | |
| 15 | #include <__type_traits/is_const.h> | |
| 16 | #include <__type_traits/is_volatile.h> | |
| 17 | #include <cstddef> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_CXX03_LANG) | |
| 28 | template <class _Tp, class...> | |
| 29 | using __enable_if_tuple_size_imp = _Tp; | |
| 30 | ||
| 31 | template <class _Tp> | |
| 32 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 33 | const _Tp, | |
| 34 | __enable_if_t<!is_volatile<_Tp>::value>, | |
| 35 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 36 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 37 | ||
| 38 | template <class _Tp> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 40 | volatile _Tp, | |
| 41 | __enable_if_t<!is_const<_Tp>::value>, | |
| 42 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 43 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 44 | ||
| 45 | template <class _Tp> | |
| 46 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 47 | const volatile _Tp, | |
| 48 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 49 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 50 | ||
| 51 | #else | |
| 52 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; | |
| 53 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; | |
| 54 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; | |
| 55 | #endif | |
| 56 | ||
| 57 | #ifndef _LIBCPP_CXX03_LANG | |
| 58 | ||
| 59 | template <class ..._Tp> | |
| 60 | struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > | |
| 61 | : public integral_constant<size_t, sizeof...(_Tp)> | |
| 62 | { | |
| 63 | }; | |
| 64 | ||
| 65 | template <class ..._Tp> | |
| 66 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > | |
| 67 | : public integral_constant<size_t, sizeof...(_Tp)> | |
| 68 | { | |
| 69 | }; | |
| 70 | ||
| 71 | #endif // _LIBCPP_CXX03_LANG | |
| 72 | ||
| 73 | _LIBCPP_END_NAMESPACE_STD | |
| 74 | ||
| 75 | #endif // _LIBCPP___TUPLE_TUPLE_SIZE_H |
lib/libcxx/include/__tuple/tuple_types.h created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_TYPES_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_TYPES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 19 | ||
| 20 | template <class ..._Tp> struct __tuple_types {}; | |
| 21 | ||
| 22 | _LIBCPP_END_NAMESPACE_STD | |
| 23 | ||
| 24 | #endif // _LIBCPP___TUPLE_TUPLE_TYPES_H |
lib/libcxx/include/__tuple_dir/apply_cv.h deleted-70| ... | ... | @@ -1,70 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_APPLY_CV_H | |
| 10 | #define _LIBCPP___TUPLE_APPLY_CV_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/is_const.h> | |
| 14 | #include <__type_traits/is_reference.h> | |
| 15 | #include <__type_traits/is_volatile.h> | |
| 16 | #include <__type_traits/remove_reference.h> | |
| 17 | ||
| 18 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 19 | # pragma GCC system_header | |
| 20 | #endif | |
| 21 | ||
| 22 | #ifndef _LIBCPP_CXX03_LANG | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <bool _ApplyLV, bool _ApplyConst, bool _ApplyVolatile> | |
| 27 | struct __apply_cv_mf; | |
| 28 | template <> | |
| 29 | struct __apply_cv_mf<false, false, false> { | |
| 30 | template <class _Tp> using __apply = _Tp; | |
| 31 | }; | |
| 32 | template <> | |
| 33 | struct __apply_cv_mf<false, true, false> { | |
| 34 | template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp; | |
| 35 | }; | |
| 36 | template <> | |
| 37 | struct __apply_cv_mf<false, false, true> { | |
| 38 | template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp; | |
| 39 | }; | |
| 40 | template <> | |
| 41 | struct __apply_cv_mf<false, true, true> { | |
| 42 | template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp; | |
| 43 | }; | |
| 44 | template <> | |
| 45 | struct __apply_cv_mf<true, false, false> { | |
| 46 | template <class _Tp> using __apply _LIBCPP_NODEBUG = _Tp&; | |
| 47 | }; | |
| 48 | template <> | |
| 49 | struct __apply_cv_mf<true, true, false> { | |
| 50 | template <class _Tp> using __apply _LIBCPP_NODEBUG = const _Tp&; | |
| 51 | }; | |
| 52 | template <> | |
| 53 | struct __apply_cv_mf<true, false, true> { | |
| 54 | template <class _Tp> using __apply _LIBCPP_NODEBUG = volatile _Tp&; | |
| 55 | }; | |
| 56 | template <> | |
| 57 | struct __apply_cv_mf<true, true, true> { | |
| 58 | template <class _Tp> using __apply _LIBCPP_NODEBUG = const volatile _Tp&; | |
| 59 | }; | |
| 60 | template <class _Tp, class _RawTp = __libcpp_remove_reference_t<_Tp> > | |
| 61 | using __apply_cv_t _LIBCPP_NODEBUG = __apply_cv_mf< | |
| 62 | is_lvalue_reference<_Tp>::value, | |
| 63 | is_const<_RawTp>::value, | |
| 64 | is_volatile<_RawTp>::value>; | |
| 65 | ||
| 66 | _LIBCPP_END_NAMESPACE_STD | |
| 67 | ||
| 68 | #endif // _LIBCPP_CXX03_LANG | |
| 69 | ||
| 70 | #endif // _LIBCPP___TUPLE_APPLY_CV_H |
lib/libcxx/include/__tuple_dir/make_tuple_types.h deleted-84| ... | ... | @@ -1,84 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H | |
| 10 | #define _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/tuple.h> | |
| 15 | #include <__tuple_dir/apply_cv.h> | |
| 16 | #include <__tuple_dir/tuple_element.h> | |
| 17 | #include <__tuple_dir/tuple_indices.h> | |
| 18 | #include <__tuple_dir/tuple_size.h> | |
| 19 | #include <__tuple_dir/tuple_types.h> | |
| 20 | #include <__type_traits/remove_cv.h> | |
| 21 | #include <__type_traits/remove_reference.h> | |
| 22 | #include <cstddef> | |
| 23 | ||
| 24 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 25 | # pragma GCC system_header | |
| 26 | #endif | |
| 27 | ||
| 28 | #ifndef _LIBCPP_CXX03_LANG | |
| 29 | ||
| 30 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 31 | ||
| 32 | // __make_tuple_types<_Tuple<_Types...>, _Ep, _Sp>::type is a | |
| 33 | // __tuple_types<_Types...> using only those _Types in the range [_Sp, _Ep). | |
| 34 | // _Sp defaults to 0 and _Ep defaults to tuple_size<_Tuple>. If _Tuple is a | |
| 35 | // lvalue_reference type, then __tuple_types<_Types&...> is the result. | |
| 36 | ||
| 37 | template <class _TupleTypes, class _TupleIndices> | |
| 38 | struct __make_tuple_types_flat; | |
| 39 | ||
| 40 | template <template <class...> class _Tuple, class ..._Types, size_t ..._Idx> | |
| 41 | struct __make_tuple_types_flat<_Tuple<_Types...>, __tuple_indices<_Idx...>> { | |
| 42 | // Specialization for pair, tuple, and __tuple_types | |
| 43 | template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> | |
| 44 | using __apply_quals _LIBCPP_NODEBUG = __tuple_types< | |
| 45 | typename _ApplyFn::template __apply<__type_pack_element<_Idx, _Types...>>... | |
| 46 | >; | |
| 47 | }; | |
| 48 | ||
| 49 | template <class _Vt, size_t _Np, size_t ..._Idx> | |
| 50 | struct __make_tuple_types_flat<array<_Vt, _Np>, __tuple_indices<_Idx...>> { | |
| 51 | template <size_t> | |
| 52 | using __value_type = _Vt; | |
| 53 | template <class _Tp, class _ApplyFn = __apply_cv_t<_Tp>> | |
| 54 | using __apply_quals = __tuple_types< | |
| 55 | typename _ApplyFn::template __apply<__value_type<_Idx>>... | |
| 56 | >; | |
| 57 | }; | |
| 58 | ||
| 59 | template <class _Tp, size_t _Ep = tuple_size<__libcpp_remove_reference_t<_Tp> >::value, | |
| 60 | size_t _Sp = 0, | |
| 61 | bool _SameSize = (_Ep == tuple_size<__libcpp_remove_reference_t<_Tp> >::value)> | |
| 62 | struct __make_tuple_types | |
| 63 | { | |
| 64 | static_assert(_Sp <= _Ep, "__make_tuple_types input error"); | |
| 65 | using _RawTp = __remove_cv_t<__libcpp_remove_reference_t<_Tp> >; | |
| 66 | using _Maker = __make_tuple_types_flat<_RawTp, typename __make_tuple_indices<_Ep, _Sp>::type>; | |
| 67 | using type = typename _Maker::template __apply_quals<_Tp>; | |
| 68 | }; | |
| 69 | ||
| 70 | template <class ..._Types, size_t _Ep> | |
| 71 | struct __make_tuple_types<tuple<_Types...>, _Ep, 0, true> { | |
| 72 | typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type; | |
| 73 | }; | |
| 74 | ||
| 75 | template <class ..._Types, size_t _Ep> | |
| 76 | struct __make_tuple_types<__tuple_types<_Types...>, _Ep, 0, true> { | |
| 77 | typedef _LIBCPP_NODEBUG __tuple_types<_Types...> type; | |
| 78 | }; | |
| 79 | ||
| 80 | _LIBCPP_END_NAMESPACE_STD | |
| 81 | ||
| 82 | #endif // _LIBCPP_CXX03_LANG | |
| 83 | ||
| 84 | #endif // _LIBCPP___TUPLE_MAKE_TUPLE_TYPES_H |
lib/libcxx/include/__tuple_dir/pair_like.h deleted-32| ... | ... | @@ -1,32 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_PAIR_LIKE_H | |
| 10 | #define _LIBCPP___TUPLE_PAIR_LIKE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__tuple_dir/tuple_like.h> | |
| 14 | #include <__tuple_dir/tuple_size.h> | |
| 15 | #include <__type_traits/remove_cvref.h> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | #if _LIBCPP_STD_VER >= 20 | |
| 24 | ||
| 25 | template <class _Tp> | |
| 26 | concept __pair_like = __tuple_like<_Tp> && tuple_size<remove_cvref_t<_Tp>>::value == 2; | |
| 27 | ||
| 28 | #endif // _LIBCPP_STD_VER >= 20 | |
| 29 | ||
| 30 | _LIBCPP_END_NAMESPACE_STD | |
| 31 | ||
| 32 | #endif // _LIBCPP___TUPLE_PAIR_LIKE_H |
lib/libcxx/include/__tuple_dir/sfinae_helpers.h deleted-196| ... | ... | @@ -1,196 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_SFINAE_HELPERS_H | |
| 10 | #define _LIBCPP___TUPLE_SFINAE_HELPERS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/tuple.h> | |
| 14 | #include <__tuple_dir/make_tuple_types.h> | |
| 15 | #include <__tuple_dir/tuple_element.h> | |
| 16 | #include <__tuple_dir/tuple_like_ext.h> | |
| 17 | #include <__tuple_dir/tuple_size.h> | |
| 18 | #include <__tuple_dir/tuple_types.h> | |
| 19 | #include <__type_traits/enable_if.h> | |
| 20 | #include <__type_traits/integral_constant.h> | |
| 21 | #include <__type_traits/is_assignable.h> | |
| 22 | #include <__type_traits/is_constructible.h> | |
| 23 | #include <__type_traits/is_convertible.h> | |
| 24 | #include <__type_traits/is_same.h> | |
| 25 | #include <__type_traits/remove_cvref.h> | |
| 26 | #include <__type_traits/remove_reference.h> | |
| 27 | #include <cstddef> | |
| 28 | ||
| 29 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 30 | # pragma GCC system_header | |
| 31 | #endif | |
| 32 | ||
| 33 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 34 | ||
| 35 | #ifndef _LIBCPP_CXX03_LANG | |
| 36 | ||
| 37 | template <bool ..._Preds> | |
| 38 | struct __all_dummy; | |
| 39 | ||
| 40 | template <bool ..._Pred> | |
| 41 | struct __all : _IsSame<__all_dummy<_Pred...>, __all_dummy<((void)_Pred, true)...>> {}; | |
| 42 | ||
| 43 | struct __tuple_sfinae_base { | |
| 44 | template <template <class, class...> class _Trait, | |
| 45 | class ..._LArgs, class ..._RArgs> | |
| 46 | static auto __do_test(__tuple_types<_LArgs...>, __tuple_types<_RArgs...>) | |
| 47 | -> __all<__enable_if_t<_Trait<_LArgs, _RArgs>::value, bool>{true}...>; | |
| 48 | template <template <class...> class> | |
| 49 | static auto __do_test(...) -> false_type; | |
| 50 | ||
| 51 | template <class _FromArgs, class _ToArgs> | |
| 52 | using __constructible = decltype(__do_test<is_constructible>(_ToArgs{}, _FromArgs{})); | |
| 53 | template <class _FromArgs, class _ToArgs> | |
| 54 | using __convertible = decltype(__do_test<is_convertible>(_FromArgs{}, _ToArgs{})); | |
| 55 | template <class _FromArgs, class _ToArgs> | |
| 56 | using __assignable = decltype(__do_test<is_assignable>(_ToArgs{}, _FromArgs{})); | |
| 57 | }; | |
| 58 | ||
| 59 | // __tuple_convertible | |
| 60 | ||
| 61 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 62 | bool = __tuple_like_ext<_Up>::value> | |
| 63 | struct __tuple_convertible | |
| 64 | : public false_type {}; | |
| 65 | ||
| 66 | template <class _Tp, class _Up> | |
| 67 | struct __tuple_convertible<_Tp, _Up, true, true> | |
| 68 | : public __tuple_sfinae_base::__convertible< | |
| 69 | typename __make_tuple_types<_Tp>::type | |
| 70 | , typename __make_tuple_types<_Up>::type | |
| 71 | > | |
| 72 | {}; | |
| 73 | ||
| 74 | // __tuple_constructible | |
| 75 | ||
| 76 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 77 | bool = __tuple_like_ext<_Up>::value> | |
| 78 | struct __tuple_constructible | |
| 79 | : public false_type {}; | |
| 80 | ||
| 81 | template <class _Tp, class _Up> | |
| 82 | struct __tuple_constructible<_Tp, _Up, true, true> | |
| 83 | : public __tuple_sfinae_base::__constructible< | |
| 84 | typename __make_tuple_types<_Tp>::type | |
| 85 | , typename __make_tuple_types<_Up>::type | |
| 86 | > | |
| 87 | {}; | |
| 88 | ||
| 89 | // __tuple_assignable | |
| 90 | ||
| 91 | template <class _Tp, class _Up, bool = __tuple_like_ext<__libcpp_remove_reference_t<_Tp> >::value, | |
| 92 | bool = __tuple_like_ext<_Up>::value> | |
| 93 | struct __tuple_assignable | |
| 94 | : public false_type {}; | |
| 95 | ||
| 96 | template <class _Tp, class _Up> | |
| 97 | struct __tuple_assignable<_Tp, _Up, true, true> | |
| 98 | : public __tuple_sfinae_base::__assignable< | |
| 99 | typename __make_tuple_types<_Tp>::type | |
| 100 | , typename __make_tuple_types<_Up&>::type | |
| 101 | > | |
| 102 | {}; | |
| 103 | ||
| 104 | ||
| 105 | template <size_t _Ip, class ..._Tp> | |
| 106 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, tuple<_Tp...> > | |
| 107 | { | |
| 108 | typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; | |
| 109 | }; | |
| 110 | ||
| 111 | template <bool _IsTuple, class _SizeTrait, size_t _Expected> | |
| 112 | struct __tuple_like_with_size_imp : false_type {}; | |
| 113 | ||
| 114 | template <class _SizeTrait, size_t _Expected> | |
| 115 | struct __tuple_like_with_size_imp<true, _SizeTrait, _Expected> | |
| 116 | : integral_constant<bool, _SizeTrait::value == _Expected> {}; | |
| 117 | ||
| 118 | template <class _Tuple, size_t _ExpectedSize, class _RawTuple = __libcpp_remove_reference_t<_Tuple> > | |
| 119 | using __tuple_like_with_size _LIBCPP_NODEBUG = __tuple_like_with_size_imp< | |
| 120 | __tuple_like_ext<_RawTuple>::value, | |
| 121 | tuple_size<_RawTuple>, _ExpectedSize | |
| 122 | >; | |
| 123 | ||
| 124 | struct _LIBCPP_TYPE_VIS __check_tuple_constructor_fail { | |
| 125 | ||
| 126 | static constexpr bool __enable_explicit_default() { return false; } | |
| 127 | static constexpr bool __enable_implicit_default() { return false; } | |
| 128 | template <class ...> | |
| 129 | static constexpr bool __enable_explicit() { return false; } | |
| 130 | template <class ...> | |
| 131 | static constexpr bool __enable_implicit() { return false; } | |
| 132 | template <class ...> | |
| 133 | static constexpr bool __enable_assign() { return false; } | |
| 134 | }; | |
| 135 | #endif // !defined(_LIBCPP_CXX03_LANG) | |
| 136 | ||
| 137 | #if _LIBCPP_STD_VER > 14 | |
| 138 | ||
| 139 | template <bool _CanCopy, bool _CanMove> | |
| 140 | struct __sfinae_ctor_base {}; | |
| 141 | template <> | |
| 142 | struct __sfinae_ctor_base<false, false> { | |
| 143 | __sfinae_ctor_base() = default; | |
| 144 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; | |
| 145 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; | |
| 146 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 147 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 148 | }; | |
| 149 | template <> | |
| 150 | struct __sfinae_ctor_base<true, false> { | |
| 151 | __sfinae_ctor_base() = default; | |
| 152 | __sfinae_ctor_base(__sfinae_ctor_base const&) = default; | |
| 153 | __sfinae_ctor_base(__sfinae_ctor_base &&) = delete; | |
| 154 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 155 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 156 | }; | |
| 157 | template <> | |
| 158 | struct __sfinae_ctor_base<false, true> { | |
| 159 | __sfinae_ctor_base() = default; | |
| 160 | __sfinae_ctor_base(__sfinae_ctor_base const&) = delete; | |
| 161 | __sfinae_ctor_base(__sfinae_ctor_base &&) = default; | |
| 162 | __sfinae_ctor_base& operator=(__sfinae_ctor_base const&) = default; | |
| 163 | __sfinae_ctor_base& operator=(__sfinae_ctor_base&&) = default; | |
| 164 | }; | |
| 165 | ||
| 166 | template <bool _CanCopy, bool _CanMove> | |
| 167 | struct __sfinae_assign_base {}; | |
| 168 | template <> | |
| 169 | struct __sfinae_assign_base<false, false> { | |
| 170 | __sfinae_assign_base() = default; | |
| 171 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 172 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 173 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; | |
| 174 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; | |
| 175 | }; | |
| 176 | template <> | |
| 177 | struct __sfinae_assign_base<true, false> { | |
| 178 | __sfinae_assign_base() = default; | |
| 179 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 180 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 181 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = default; | |
| 182 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = delete; | |
| 183 | }; | |
| 184 | template <> | |
| 185 | struct __sfinae_assign_base<false, true> { | |
| 186 | __sfinae_assign_base() = default; | |
| 187 | __sfinae_assign_base(__sfinae_assign_base const&) = default; | |
| 188 | __sfinae_assign_base(__sfinae_assign_base &&) = default; | |
| 189 | __sfinae_assign_base& operator=(__sfinae_assign_base const&) = delete; | |
| 190 | __sfinae_assign_base& operator=(__sfinae_assign_base&&) = default; | |
| 191 | }; | |
| 192 | #endif // _LIBCPP_STD_VER > 14 | |
| 193 | ||
| 194 | _LIBCPP_END_NAMESPACE_STD | |
| 195 | ||
| 196 | #endif // _LIBCPP___TUPLE_SFINAE_HELPERS_H |
lib/libcxx/include/__tuple_dir/tuple_element.h deleted-93| ... | ... | @@ -1,93 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_ELEMENT_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_ELEMENT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__tuple_dir/tuple_indices.h> | |
| 14 | #include <__tuple_dir/tuple_types.h> | |
| 15 | #include <__type_traits/add_const.h> | |
| 16 | #include <__type_traits/add_cv.h> | |
| 17 | #include <__type_traits/add_volatile.h> | |
| 18 | #include <cstddef> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <size_t _Ip, class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_element; | |
| 27 | ||
| 28 | template <size_t _Ip, class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const _Tp> | |
| 30 | { | |
| 31 | typedef _LIBCPP_NODEBUG typename add_const<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 32 | }; | |
| 33 | ||
| 34 | template <size_t _Ip, class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, volatile _Tp> | |
| 36 | { | |
| 37 | typedef _LIBCPP_NODEBUG typename add_volatile<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 38 | }; | |
| 39 | ||
| 40 | template <size_t _Ip, class _Tp> | |
| 41 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, const volatile _Tp> | |
| 42 | { | |
| 43 | typedef _LIBCPP_NODEBUG typename add_cv<typename tuple_element<_Ip, _Tp>::type>::type type; | |
| 44 | }; | |
| 45 | ||
| 46 | #ifndef _LIBCPP_CXX03_LANG | |
| 47 | ||
| 48 | #if !__has_builtin(__type_pack_element) | |
| 49 | ||
| 50 | namespace __indexer_detail { | |
| 51 | ||
| 52 | template <size_t _Idx, class _Tp> | |
| 53 | struct __indexed { using type _LIBCPP_NODEBUG = _Tp; }; | |
| 54 | ||
| 55 | template <class _Types, class _Indexes> struct __indexer; | |
| 56 | ||
| 57 | template <class ..._Types, size_t ..._Idx> | |
| 58 | struct __indexer<__tuple_types<_Types...>, __tuple_indices<_Idx...>> | |
| 59 | : __indexed<_Idx, _Types>... | |
| 60 | {}; | |
| 61 | ||
| 62 | template <size_t _Idx, class _Tp> | |
| 63 | __indexed<_Idx, _Tp> __at_index(__indexed<_Idx, _Tp> const&); | |
| 64 | ||
| 65 | } // namespace __indexer_detail | |
| 66 | ||
| 67 | template <size_t _Idx, class ..._Types> | |
| 68 | using __type_pack_element _LIBCPP_NODEBUG = typename decltype( | |
| 69 | __indexer_detail::__at_index<_Idx>( | |
| 70 | __indexer_detail::__indexer< | |
| 71 | __tuple_types<_Types...>, | |
| 72 | typename __make_tuple_indices<sizeof...(_Types)>::type | |
| 73 | >{}) | |
| 74 | )::type; | |
| 75 | #endif | |
| 76 | ||
| 77 | template <size_t _Ip, class ..._Types> | |
| 78 | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, __tuple_types<_Types...> > | |
| 79 | { | |
| 80 | static_assert(_Ip < sizeof...(_Types), "tuple_element index out of range"); | |
| 81 | typedef _LIBCPP_NODEBUG __type_pack_element<_Ip, _Types...> type; | |
| 82 | }; | |
| 83 | ||
| 84 | #if _LIBCPP_STD_VER > 11 | |
| 85 | template <size_t _Ip, class ..._Tp> | |
| 86 | using tuple_element_t _LIBCPP_NODEBUG = typename tuple_element <_Ip, _Tp...>::type; | |
| 87 | #endif | |
| 88 | ||
| 89 | #endif // _LIBCPP_CXX03_LANG | |
| 90 | ||
| 91 | _LIBCPP_END_NAMESPACE_STD | |
| 92 | ||
| 93 | #endif // _LIBCPP___TUPLE_TUPLE_ELEMENT_H |
lib/libcxx/include/__tuple_dir/tuple_indices.h deleted-37| ... | ... | @@ -1,37 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H | |
| 10 | #define _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__utility/integer_sequence.h> | |
| 14 | #include <cstddef> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #ifndef _LIBCPP_CXX03_LANG | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | template <size_t...> struct __tuple_indices {}; | |
| 25 | ||
| 26 | template <size_t _Ep, size_t _Sp = 0> | |
| 27 | struct __make_tuple_indices | |
| 28 | { | |
| 29 | static_assert(_Sp <= _Ep, "__make_tuple_indices input error"); | |
| 30 | typedef __make_indices_imp<_Ep, _Sp> type; | |
| 31 | }; | |
| 32 | ||
| 33 | _LIBCPP_END_NAMESPACE_STD | |
| 34 | ||
| 35 | #endif // _LIBCPP_CXX03_LANG | |
| 36 | ||
| 37 | #endif // _LIBCPP___TUPLE_MAKE_TUPLE_INDICES_H |
lib/libcxx/include/__tuple_dir/tuple_like.h deleted-51| ... | ... | @@ -1,51 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_LIKE_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_LIKE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/pair.h> | |
| 15 | #include <__fwd/subrange.h> | |
| 16 | #include <__fwd/tuple.h> | |
| 17 | #include <__type_traits/integral_constant.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <cstddef> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct __tuple_like_impl : false_type {}; | |
| 31 | ||
| 32 | template <class... _Tp> | |
| 33 | struct __tuple_like_impl<tuple<_Tp...> > : true_type {}; | |
| 34 | ||
| 35 | template <class _T1, class _T2> | |
| 36 | struct __tuple_like_impl<pair<_T1, _T2> > : true_type {}; | |
| 37 | ||
| 38 | template <class _Tp, size_t _Size> | |
| 39 | struct __tuple_like_impl<array<_Tp, _Size> > : true_type {}; | |
| 40 | ||
| 41 | template <class _Ip, class _Sp, ranges::subrange_kind _Kp> | |
| 42 | struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {}; | |
| 43 | ||
| 44 | template <class _Tp> | |
| 45 | concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value; | |
| 46 | ||
| 47 | #endif // _LIBCPP_STD_VER >= 20 | |
| 48 | ||
| 49 | _LIBCPP_END_NAMESPACE_STD | |
| 50 | ||
| 51 | #endif // _LIBCPP___TUPLE_TUPLE_LIKE_H |
lib/libcxx/include/__tuple_dir/tuple_like_ext.h deleted-44| ... | ... | @@ -1,44 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/array.h> | |
| 14 | #include <__fwd/pair.h> | |
| 15 | #include <__fwd/tuple.h> | |
| 16 | #include <__tuple_dir/tuple_types.h> | |
| 17 | #include <__type_traits/integral_constant.h> | |
| 18 | #include <cstddef> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | template <class _Tp> struct __tuple_like_ext : false_type {}; | |
| 27 | ||
| 28 | template <class _Tp> struct __tuple_like_ext<const _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 29 | template <class _Tp> struct __tuple_like_ext<volatile _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 30 | template <class _Tp> struct __tuple_like_ext<const volatile _Tp> : public __tuple_like_ext<_Tp> {}; | |
| 31 | ||
| 32 | #ifndef _LIBCPP_CXX03_LANG | |
| 33 | template <class... _Tp> struct __tuple_like_ext<tuple<_Tp...> > : true_type {}; | |
| 34 | #endif | |
| 35 | ||
| 36 | template <class _T1, class _T2> struct __tuple_like_ext<pair<_T1, _T2> > : true_type {}; | |
| 37 | ||
| 38 | template <class _Tp, size_t _Size> struct __tuple_like_ext<array<_Tp, _Size> > : true_type {}; | |
| 39 | ||
| 40 | template <class... _Tp> struct __tuple_like_ext<__tuple_types<_Tp...> > : true_type {}; | |
| 41 | ||
| 42 | _LIBCPP_END_NAMESPACE_STD | |
| 43 | ||
| 44 | #endif // _LIBCPP___TUPLE_TUPLE_LIKE_EXT_H |
lib/libcxx/include/__tuple_dir/tuple_size.h deleted-75| ... | ... | @@ -1,75 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_SIZE_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_SIZE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__fwd/tuple.h> | |
| 14 | #include <__tuple_dir/tuple_types.h> | |
| 15 | #include <__type_traits/is_const.h> | |
| 16 | #include <__type_traits/is_volatile.h> | |
| 17 | #include <cstddef> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 24 | ||
| 25 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size; | |
| 26 | ||
| 27 | #if !defined(_LIBCPP_CXX03_LANG) | |
| 28 | template <class _Tp, class...> | |
| 29 | using __enable_if_tuple_size_imp = _Tp; | |
| 30 | ||
| 31 | template <class _Tp> | |
| 32 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 33 | const _Tp, | |
| 34 | __enable_if_t<!is_volatile<_Tp>::value>, | |
| 35 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 36 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 37 | ||
| 38 | template <class _Tp> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 40 | volatile _Tp, | |
| 41 | __enable_if_t<!is_const<_Tp>::value>, | |
| 42 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 43 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 44 | ||
| 45 | template <class _Tp> | |
| 46 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__enable_if_tuple_size_imp< | |
| 47 | const volatile _Tp, | |
| 48 | integral_constant<size_t, sizeof(tuple_size<_Tp>)>>> | |
| 49 | : public integral_constant<size_t, tuple_size<_Tp>::value> {}; | |
| 50 | ||
| 51 | #else | |
| 52 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const _Tp> : public tuple_size<_Tp> {}; | |
| 53 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<volatile _Tp> : public tuple_size<_Tp> {}; | |
| 54 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS tuple_size<const volatile _Tp> : public tuple_size<_Tp> {}; | |
| 55 | #endif | |
| 56 | ||
| 57 | #ifndef _LIBCPP_CXX03_LANG | |
| 58 | ||
| 59 | template <class ..._Tp> | |
| 60 | struct _LIBCPP_TEMPLATE_VIS tuple_size<tuple<_Tp...> > | |
| 61 | : public integral_constant<size_t, sizeof...(_Tp)> | |
| 62 | { | |
| 63 | }; | |
| 64 | ||
| 65 | template <class ..._Tp> | |
| 66 | struct _LIBCPP_TEMPLATE_VIS tuple_size<__tuple_types<_Tp...> > | |
| 67 | : public integral_constant<size_t, sizeof...(_Tp)> | |
| 68 | { | |
| 69 | }; | |
| 70 | ||
| 71 | #endif // _LIBCPP_CXX03_LANG | |
| 72 | ||
| 73 | _LIBCPP_END_NAMESPACE_STD | |
| 74 | ||
| 75 | #endif // _LIBCPP___TUPLE_TUPLE_SIZE_H |
lib/libcxx/include/__tuple_dir/tuple_types.h deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TUPLE_TUPLE_TYPES_H | |
| 10 | #define _LIBCPP___TUPLE_TUPLE_TYPES_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | ||
| 14 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 15 | # pragma GCC system_header | |
| 16 | #endif | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 19 | ||
| 20 | template <class ..._Tp> struct __tuple_types {}; | |
| 21 | ||
| 22 | _LIBCPP_END_NAMESPACE_STD | |
| 23 | ||
| 24 | #endif // _LIBCPP___TUPLE_TUPLE_TYPES_H |
lib/libcxx/include/__type_traits/add_const.h+5-3| ... | ... | @@ -17,12 +17,14 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_const { | |
| 20 | template <class _Tp> | |
| 21 | struct _LIBCPP_TEMPLATE_VIS add_const { | |
| 21 | 22 | typedef _LIBCPP_NODEBUG const _Tp type; |
| 22 | 23 | }; |
| 23 | 24 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 25 | template <class _Tp> using add_const_t = typename add_const<_Tp>::type; | |
| 25 | #if _LIBCPP_STD_VER >= 14 | |
| 26 | template <class _Tp> | |
| 27 | using add_const_t = typename add_const<_Tp>::type; | |
| 26 | 28 | #endif |
| 27 | 29 | |
| 28 | 30 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/add_cv.h+5-3| ... | ... | @@ -17,12 +17,14 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_cv { | |
| 20 | template <class _Tp> | |
| 21 | struct _LIBCPP_TEMPLATE_VIS add_cv { | |
| 21 | 22 | typedef _LIBCPP_NODEBUG const volatile _Tp type; |
| 22 | 23 | }; |
| 23 | 24 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 25 | template <class _Tp> using add_cv_t = typename add_cv<_Tp>::type; | |
| 25 | #if _LIBCPP_STD_VER >= 14 | |
| 26 | template <class _Tp> | |
| 27 | using add_cv_t = typename add_cv<_Tp>::type; | |
| 26 | 28 | #endif |
| 27 | 29 | |
| 28 | 30 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/add_lvalue_reference.h+3-2| ... | ... | @@ -44,8 +44,9 @@ struct add_lvalue_reference { |
| 44 | 44 | using type _LIBCPP_NODEBUG = __add_lvalue_reference_t<_Tp>; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | #if _LIBCPP_STD_VER > 11 | |
| 48 | template <class _Tp> using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>; | |
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | template <class _Tp> | |
| 49 | using add_lvalue_reference_t = __add_lvalue_reference_t<_Tp>; | |
| 49 | 50 | #endif |
| 50 | 51 | |
| 51 | 52 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/add_pointer.h+8-6| ... | ... | @@ -28,13 +28,14 @@ template <class _Tp> |
| 28 | 28 | using __add_pointer_t = __add_pointer(_Tp); |
| 29 | 29 | |
| 30 | 30 | #else |
| 31 | template <class _Tp, | |
| 32 | bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value> | |
| 31 | template <class _Tp, bool = __libcpp_is_referenceable<_Tp>::value || is_void<_Tp>::value> | |
| 33 | 32 | struct __add_pointer_impl { |
| 34 | 33 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp>* type; |
| 35 | 34 | }; |
| 36 | template <class _Tp> struct __add_pointer_impl<_Tp, false> | |
| 37 | {typedef _LIBCPP_NODEBUG _Tp type;}; | |
| 35 | template <class _Tp> | |
| 36 | struct __add_pointer_impl<_Tp, false> { | |
| 37 | typedef _LIBCPP_NODEBUG _Tp type; | |
| 38 | }; | |
| 38 | 39 | |
| 39 | 40 | template <class _Tp> |
| 40 | 41 | using __add_pointer_t = typename __add_pointer_impl<_Tp>::type; |
| ... | ... | @@ -46,8 +47,9 @@ struct add_pointer { |
| 46 | 47 | using type _LIBCPP_NODEBUG = __add_pointer_t<_Tp>; |
| 47 | 48 | }; |
| 48 | 49 | |
| 49 | #if _LIBCPP_STD_VER > 11 | |
| 50 | template <class _Tp> using add_pointer_t = __add_pointer_t<_Tp>; | |
| 50 | #if _LIBCPP_STD_VER >= 14 | |
| 51 | template <class _Tp> | |
| 52 | using add_pointer_t = __add_pointer_t<_Tp>; | |
| 51 | 53 | #endif |
| 52 | 54 | |
| 53 | 55 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/add_rvalue_reference.h+1-1| ... | ... | @@ -44,7 +44,7 @@ struct add_rvalue_reference { |
| 44 | 44 | using type = __add_rvalue_reference_t<_Tp>; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | #if _LIBCPP_STD_VER > 11 | |
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | 48 | template <class _Tp> |
| 49 | 49 | using add_rvalue_reference_t = __add_rvalue_reference_t<_Tp>; |
| 50 | 50 | #endif |
lib/libcxx/include/__type_traits/add_volatile.h+5-3| ... | ... | @@ -17,12 +17,14 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS add_volatile { | |
| 20 | template <class _Tp> | |
| 21 | struct _LIBCPP_TEMPLATE_VIS add_volatile { | |
| 21 | 22 | typedef _LIBCPP_NODEBUG volatile _Tp type; |
| 22 | 23 | }; |
| 23 | 24 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 25 | template <class _Tp> using add_volatile_t = typename add_volatile<_Tp>::type; | |
| 25 | #if _LIBCPP_STD_VER >= 14 | |
| 26 | template <class _Tp> | |
| 27 | using add_volatile_t = typename add_volatile<_Tp>::type; | |
| 26 | 28 | #endif |
| 27 | 29 | |
| 28 | 30 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/aligned_storage.h+54-54| ... | ... | @@ -23,59 +23,63 @@ |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | 25 | template <class _Tp> |
| 26 | struct __align_type | |
| 27 | { | |
| 28 | static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); | |
| 29 | typedef _Tp type; | |
| 26 | struct __align_type { | |
| 27 | static const size_t value = _LIBCPP_PREFERRED_ALIGNOF(_Tp); | |
| 28 | typedef _Tp type; | |
| 30 | 29 | }; |
| 31 | 30 | |
| 32 | struct __struct_double {long double __lx;}; | |
| 33 | struct __struct_double4 {double __lx[4];}; | |
| 34 | ||
| 35 | typedef | |
| 36 | __type_list<__align_type<unsigned char>, | |
| 37 | __type_list<__align_type<unsigned short>, | |
| 38 | __type_list<__align_type<unsigned int>, | |
| 39 | __type_list<__align_type<unsigned long>, | |
| 40 | __type_list<__align_type<unsigned long long>, | |
| 41 | __type_list<__align_type<double>, | |
| 42 | __type_list<__align_type<long double>, | |
| 43 | __type_list<__align_type<__struct_double>, | |
| 44 | __type_list<__align_type<__struct_double4>, | |
| 45 | __type_list<__align_type<int*>, | |
| 46 | __nat | |
| 47 | > > > > > > > > > > __all_types; | |
| 31 | struct __struct_double { | |
| 32 | long double __lx; | |
| 33 | }; | |
| 34 | struct __struct_double4 { | |
| 35 | double __lx[4]; | |
| 36 | }; | |
| 37 | ||
| 38 | // clang-format off | |
| 39 | typedef __type_list<__align_type<unsigned char>, | |
| 40 | __type_list<__align_type<unsigned short>, | |
| 41 | __type_list<__align_type<unsigned int>, | |
| 42 | __type_list<__align_type<unsigned long>, | |
| 43 | __type_list<__align_type<unsigned long long>, | |
| 44 | __type_list<__align_type<double>, | |
| 45 | __type_list<__align_type<long double>, | |
| 46 | __type_list<__align_type<__struct_double>, | |
| 47 | __type_list<__align_type<__struct_double4>, | |
| 48 | __type_list<__align_type<int*>, | |
| 49 | __nat | |
| 50 | > > > > > > > > > > __all_types; | |
| 51 | // clang-format on | |
| 48 | 52 | |
| 49 | 53 | template <size_t _Align> |
| 50 | 54 | struct _ALIGNAS(_Align) __fallback_overaligned {}; |
| 51 | 55 | |
| 52 | template <class _TL, size_t _Align> struct __find_pod; | |
| 56 | template <class _TL, size_t _Align> | |
| 57 | struct __find_pod; | |
| 53 | 58 | |
| 54 | 59 | template <class _Hp, size_t _Align> |
| 55 | struct __find_pod<__type_list<_Hp, __nat>, _Align> | |
| 56 | { | |
| 57 | typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type; | |
| 60 | struct __find_pod<__type_list<_Hp, __nat>, _Align> { | |
| 61 | typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, __fallback_overaligned<_Align> > type; | |
| 58 | 62 | }; |
| 59 | 63 | |
| 60 | 64 | template <class _Hp, class _Tp, size_t _Align> |
| 61 | struct __find_pod<__type_list<_Hp, _Tp>, _Align> | |
| 62 | { | |
| 63 | typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type; | |
| 65 | struct __find_pod<__type_list<_Hp, _Tp>, _Align> { | |
| 66 | typedef __conditional_t<_Align == _Hp::value, typename _Hp::type, typename __find_pod<_Tp, _Align>::type> type; | |
| 64 | 67 | }; |
| 65 | 68 | |
| 66 | template <class _TL, size_t _Len> struct __find_max_align; | |
| 69 | template <class _TL, size_t _Len> | |
| 70 | struct __find_max_align; | |
| 67 | 71 | |
| 68 | 72 | template <class _Hp, size_t _Len> |
| 69 | 73 | struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant<size_t, _Hp::value> {}; |
| 70 | 74 | |
| 71 | 75 | template <size_t _Len, size_t _A1, size_t _A2> |
| 72 | struct __select_align | |
| 73 | { | |
| 76 | struct __select_align { | |
| 74 | 77 | private: |
| 75 | static const size_t __min = _A2 < _A1 ? _A2 : _A1; | |
| 76 | static const size_t __max = _A1 < _A2 ? _A2 : _A1; | |
| 78 | static const size_t __min = _A2 < _A1 ? _A2 : _A1; | |
| 79 | static const size_t __max = _A1 < _A2 ? _A2 : _A1; | |
| 80 | ||
| 77 | 81 | public: |
| 78 | static const size_t value = _Len < __max ? __min : __max; | |
| 82 | static const size_t value = _Len < __max ? __min : __max; | |
| 79 | 83 | }; |
| 80 | 84 | |
| 81 | 85 | template <class _Hp, class _Tp, size_t _Len> |
| ... | ... | @@ -83,34 +87,30 @@ struct __find_max_align<__type_list<_Hp, _Tp>, _Len> |
| 83 | 87 | : public integral_constant<size_t, __select_align<_Len, _Hp::value, __find_max_align<_Tp, _Len>::value>::value> {}; |
| 84 | 88 | |
| 85 | 89 | template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> |
| 86 | struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage | |
| 87 | { | |
| 88 | typedef typename __find_pod<__all_types, _Align>::type _Aligner; | |
| 89 | union type | |
| 90 | { | |
| 91 | _Aligner __align; | |
| 92 | unsigned char __data[(_Len + _Align - 1)/_Align * _Align]; | |
| 93 | }; | |
| 90 | struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage { | |
| 91 | typedef typename __find_pod<__all_types, _Align>::type _Aligner; | |
| 92 | union type { | |
| 93 | _Aligner __align; | |
| 94 | unsigned char __data[(_Len + _Align - 1) / _Align * _Align]; | |
| 95 | }; | |
| 94 | 96 | }; |
| 95 | 97 | |
| 96 | #if _LIBCPP_STD_VER > 11 | |
| 98 | #if _LIBCPP_STD_VER >= 14 | |
| 97 | 99 | |
| 98 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH | |
| 100 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH | |
| 99 | 101 | template <size_t _Len, size_t _Align = __find_max_align<__all_types, _Len>::value> |
| 100 | using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type; | |
| 101 | _LIBCPP_SUPPRESS_DEPRECATED_POP | |
| 102 | using aligned_storage_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_storage<_Len, _Align>::type; | |
| 103 | _LIBCPP_SUPPRESS_DEPRECATED_POP | |
| 102 | 104 | |
| 103 | 105 | #endif |
| 104 | 106 | |
| 105 | #define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ | |
| 106 | template <size_t _Len>\ | |
| 107 | struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n>\ | |
| 108 | {\ | |
| 109 | struct _ALIGNAS(n) type\ | |
| 110 | {\ | |
| 111 | unsigned char __lx[(_Len + n - 1)/n * n];\ | |
| 112 | };\ | |
| 113 | } | |
| 107 | #define _CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ | |
| 108 | template <size_t _Len> \ | |
| 109 | struct _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_TEMPLATE_VIS aligned_storage<_Len, n> { \ | |
| 110 | struct _ALIGNAS(n) type { \ | |
| 111 | unsigned char __lx[(_Len + n - 1) / n * n]; \ | |
| 112 | }; \ | |
| 113 | } | |
| 114 | 114 | |
| 115 | 115 | _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1); |
| 116 | 116 | _CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2); |
lib/libcxx/include/__type_traits/aligned_union.h+13-18| ... | ... | @@ -20,33 +20,28 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | template <size_t _I0, size_t ..._In> | |
| 23 | template <size_t _I0, size_t... _In> | |
| 24 | 24 | struct __static_max; |
| 25 | 25 | |
| 26 | 26 | template <size_t _I0> |
| 27 | struct __static_max<_I0> | |
| 28 | { | |
| 29 | static const size_t value = _I0; | |
| 27 | struct __static_max<_I0> { | |
| 28 | static const size_t value = _I0; | |
| 30 | 29 | }; |
| 31 | 30 | |
| 32 | template <size_t _I0, size_t _I1, size_t ..._In> | |
| 33 | struct __static_max<_I0, _I1, _In...> | |
| 34 | { | |
| 35 | static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : | |
| 36 | __static_max<_I1, _In...>::value; | |
| 31 | template <size_t _I0, size_t _I1, size_t... _In> | |
| 32 | struct __static_max<_I0, _I1, _In...> { | |
| 33 | static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : __static_max<_I1, _In...>::value; | |
| 37 | 34 | }; |
| 38 | 35 | |
| 39 | template <size_t _Len, class _Type0, class ..._Types> | |
| 40 | struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union | |
| 41 | { | |
| 42 | static const size_t alignment_value = __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), | |
| 43 | _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value; | |
| 44 | static const size_t __len = __static_max<_Len, sizeof(_Type0), | |
| 45 | sizeof(_Types)...>::value; | |
| 46 | typedef typename aligned_storage<__len, alignment_value>::type type; | |
| 36 | template <size_t _Len, class _Type0, class... _Types> | |
| 37 | struct _LIBCPP_DEPRECATED_IN_CXX23 aligned_union { | |
| 38 | static const size_t alignment_value = | |
| 39 | __static_max<_LIBCPP_PREFERRED_ALIGNOF(_Type0), _LIBCPP_PREFERRED_ALIGNOF(_Types)...>::value; | |
| 40 | static const size_t __len = __static_max<_Len, sizeof(_Type0), sizeof(_Types)...>::value; | |
| 41 | typedef typename aligned_storage<__len, alignment_value>::type type; | |
| 47 | 42 | }; |
| 48 | 43 | |
| 49 | #if _LIBCPP_STD_VER > 11 | |
| 44 | #if _LIBCPP_STD_VER >= 14 | |
| 50 | 45 | template <size_t _Len, class... _Types> |
| 51 | 46 | using aligned_union_t _LIBCPP_DEPRECATED_IN_CXX23 = typename aligned_union<_Len, _Types...>::type; |
| 52 | 47 | #endif |
lib/libcxx/include/__type_traits/alignment_of.h+3-3| ... | ... | @@ -19,10 +19,10 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS alignment_of | |
| 23 | : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {}; | |
| 22 | template <class _Tp> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS alignment_of : public integral_constant<size_t, _LIBCPP_ALIGNOF(_Tp)> {}; | |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | inline constexpr size_t alignment_of_v = _LIBCPP_ALIGNOF(_Tp); |
| 28 | 28 | #endif |
lib/libcxx/include/__type_traits/apply_cv.h+37-34| ... | ... | @@ -13,7 +13,6 @@ |
| 13 | 13 | #include <__type_traits/is_const.h> |
| 14 | 14 | #include <__type_traits/is_volatile.h> |
| 15 | 15 | #include <__type_traits/remove_reference.h> |
| 16 | #include <cstddef> | |
| 17 | 16 | |
| 18 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 18 | # pragma GCC system_header |
| ... | ... | @@ -21,55 +20,59 @@ |
| 21 | 20 | |
| 22 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 22 | |
| 24 | template <class _Tp, class _Up, bool = is_const<__libcpp_remove_reference_t<_Tp> >::value, | |
| 25 | bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value> | |
| 26 | struct __apply_cv | |
| 27 | { | |
| 28 | typedef _LIBCPP_NODEBUG _Up type; | |
| 23 | template <class _Tp, | |
| 24 | bool = is_const<__libcpp_remove_reference_t<_Tp> >::value, | |
| 25 | bool = is_volatile<__libcpp_remove_reference_t<_Tp> >::value> | |
| 26 | struct __apply_cv_impl { | |
| 27 | template <class _Up> | |
| 28 | using __apply _LIBCPP_NODEBUG = _Up; | |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | template <class _Tp, class _Up> | |
| 32 | struct __apply_cv<_Tp, _Up, true, false> | |
| 33 | { | |
| 34 | typedef _LIBCPP_NODEBUG const _Up type; | |
| 31 | template <class _Tp> | |
| 32 | struct __apply_cv_impl<_Tp, true, false> { | |
| 33 | template <class _Up> | |
| 34 | using __apply _LIBCPP_NODEBUG = const _Up; | |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | template <class _Tp, class _Up> | |
| 38 | struct __apply_cv<_Tp, _Up, false, true> | |
| 39 | { | |
| 40 | typedef volatile _Up type; | |
| 37 | template <class _Tp> | |
| 38 | struct __apply_cv_impl<_Tp, false, true> { | |
| 39 | template <class _Up> | |
| 40 | using __apply _LIBCPP_NODEBUG = volatile _Up; | |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | template <class _Tp, class _Up> | |
| 44 | struct __apply_cv<_Tp, _Up, true, true> | |
| 45 | { | |
| 46 | typedef const volatile _Up type; | |
| 43 | template <class _Tp> | |
| 44 | struct __apply_cv_impl<_Tp, true, true> { | |
| 45 | template <class _Up> | |
| 46 | using __apply _LIBCPP_NODEBUG = const volatile _Up; | |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | template <class _Tp, class _Up> | |
| 50 | struct __apply_cv<_Tp&, _Up, false, false> | |
| 51 | { | |
| 52 | typedef _Up& type; | |
| 49 | template <class _Tp> | |
| 50 | struct __apply_cv_impl<_Tp&, false, false> { | |
| 51 | template <class _Up> | |
| 52 | using __apply _LIBCPP_NODEBUG = _Up&; | |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | template <class _Tp, class _Up> | |
| 56 | struct __apply_cv<_Tp&, _Up, true, false> | |
| 57 | { | |
| 58 | typedef const _Up& type; | |
| 55 | template <class _Tp> | |
| 56 | struct __apply_cv_impl<_Tp&, true, false> { | |
| 57 | template <class _Up> | |
| 58 | using __apply _LIBCPP_NODEBUG = const _Up&; | |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | template <class _Tp, class _Up> | |
| 62 | struct __apply_cv<_Tp&, _Up, false, true> | |
| 63 | { | |
| 64 | typedef volatile _Up& type; | |
| 61 | template <class _Tp> | |
| 62 | struct __apply_cv_impl<_Tp&, false, true> { | |
| 63 | template <class _Up> | |
| 64 | using __apply _LIBCPP_NODEBUG = volatile _Up&; | |
| 65 | 65 | }; |
| 66 | 66 | |
| 67 | template <class _Tp, class _Up> | |
| 68 | struct __apply_cv<_Tp&, _Up, true, true> | |
| 69 | { | |
| 70 | typedef const volatile _Up& type; | |
| 67 | template <class _Tp> | |
| 68 | struct __apply_cv_impl<_Tp&, true, true> { | |
| 69 | template <class _Up> | |
| 70 | using __apply _LIBCPP_NODEBUG = const volatile _Up&; | |
| 71 | 71 | }; |
| 72 | 72 | |
| 73 | template <class _Tp, class _Up> | |
| 74 | using __apply_cv_t _LIBCPP_NODEBUG = typename __apply_cv_impl<_Tp>::template __apply<_Up>; | |
| 75 | ||
| 73 | 76 | _LIBCPP_END_NAMESPACE_STD |
| 74 | 77 | |
| 75 | 78 | #endif // _LIBCPP___TYPE_TRAITS_APPLY_CV_H |
lib/libcxx/include/__type_traits/can_extract_key.h+3-6| ... | ... | @@ -40,16 +40,13 @@ struct __can_extract_key<_Pair, _Key, pair<_First, _Second> > |
| 40 | 40 | // __can_extract_map_key uses true_type/false_type instead of the tags. |
| 41 | 41 | // It returns true if _Key != _ContainerValueTy (the container is a map not a set) |
| 42 | 42 | // and _ValTy == _Key. |
| 43 | template <class _ValTy, class _Key, class _ContainerValueTy, | |
| 44 | class _RawValTy = __remove_const_ref_t<_ValTy> > | |
| 45 | struct __can_extract_map_key | |
| 46 | : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {}; | |
| 43 | template <class _ValTy, class _Key, class _ContainerValueTy, class _RawValTy = __remove_const_ref_t<_ValTy> > | |
| 44 | struct __can_extract_map_key : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {}; | |
| 47 | 45 | |
| 48 | 46 | // This specialization returns __extract_key_fail_tag for non-map containers |
| 49 | 47 | // because _Key == _ContainerValueTy |
| 50 | 48 | template <class _ValTy, class _Key, class _RawValTy> |
| 51 | struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> | |
| 52 | : false_type {}; | |
| 49 | struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> : false_type {}; | |
| 53 | 50 | |
| 54 | 51 | _LIBCPP_END_NAMESPACE_STD |
| 55 | 52 |
lib/libcxx/include/__type_traits/common_reference.h+67-62| ... | ... | @@ -27,11 +27,10 @@ |
| 27 | 27 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 28 | 28 | |
| 29 | 29 | // common_reference |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | // Let COND_RES(X, Y) be: |
| 32 | 32 | template <class _Xp, class _Yp> |
| 33 | using __cond_res = | |
| 34 | decltype(false ? std::declval<_Xp(&)()>()() : std::declval<_Yp(&)()>()()); | |
| 33 | using __cond_res = decltype(false ? std::declval<_Xp (&)()>()() : std::declval<_Yp (&)()>()()); | |
| 35 | 34 | |
| 36 | 35 | // Let `XREF(A)` denote a unary alias template `T` such that `T<U>` denotes the same type as `U` |
| 37 | 36 | // with the addition of `A`'s cv and reference qualifiers, for a non-reference cv-unqualified type |
| ... | ... | @@ -39,47 +38,49 @@ using __cond_res = |
| 39 | 38 | // [Note: `XREF(A)` is `__xref<A>::template __apply`] |
| 40 | 39 | template <class _Tp> |
| 41 | 40 | struct __xref { |
| 42 | template<class _Up> | |
| 41 | template <class _Up> | |
| 43 | 42 | using __apply = __copy_cvref_t<_Tp, _Up>; |
| 44 | 43 | }; |
| 45 | 44 | |
| 46 | 45 | // Given types A and B, let X be remove_reference_t<A>, let Y be remove_reference_t<B>, |
| 47 | 46 | // and let COMMON-REF(A, B) be: |
| 48 | template<class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>> | |
| 47 | template <class _Ap, class _Bp, class _Xp = remove_reference_t<_Ap>, class _Yp = remove_reference_t<_Bp>> | |
| 49 | 48 | struct __common_ref; |
| 50 | 49 | |
| 51 | template<class _Xp, class _Yp> | |
| 50 | template <class _Xp, class _Yp> | |
| 52 | 51 | using __common_ref_t = typename __common_ref<_Xp, _Yp>::__type; |
| 53 | 52 | |
| 54 | template<class _Xp, class _Yp> | |
| 53 | template <class _Xp, class _Yp> | |
| 55 | 54 | using __cv_cond_res = __cond_res<__copy_cv_t<_Xp, _Yp>&, __copy_cv_t<_Yp, _Xp>&>; |
| 56 | 55 | |
| 57 | ||
| 58 | 56 | // If A and B are both lvalue reference types, COMMON-REF(A, B) is |
| 59 | 57 | // COND-RES(COPYCV(X, Y)&, COPYCV(Y, X)&) if that type exists and is a reference type. |
| 60 | template<class _Ap, class _Bp, class _Xp, class _Yp> | |
| 61 | requires requires { typename __cv_cond_res<_Xp, _Yp>; } && is_reference_v<__cv_cond_res<_Xp, _Yp>> | |
| 62 | struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> | |
| 63 | { | |
| 64 | using __type = __cv_cond_res<_Xp, _Yp>; | |
| 58 | // clang-format off | |
| 59 | template <class _Ap, class _Bp, class _Xp, class _Yp> | |
| 60 | requires | |
| 61 | requires { typename __cv_cond_res<_Xp, _Yp>; } && | |
| 62 | is_reference_v<__cv_cond_res<_Xp, _Yp>> | |
| 63 | struct __common_ref<_Ap&, _Bp&, _Xp, _Yp> { | |
| 64 | using __type = __cv_cond_res<_Xp, _Yp>; | |
| 65 | 65 | }; |
| 66 | // clang-format on | |
| 66 | 67 | |
| 67 | 68 | // Otherwise, let C be remove_reference_t<COMMON-REF(X&, Y&)>&&. ... |
| 68 | 69 | template <class _Xp, class _Yp> |
| 69 | 70 | using __common_ref_C = remove_reference_t<__common_ref_t<_Xp&, _Yp&>>&&; |
| 70 | 71 | |
| 71 | ||
| 72 | 72 | // .... If A and B are both rvalue reference types, C is well-formed, and |
| 73 | 73 | // is_convertible_v<A, C> && is_convertible_v<B, C> is true, then COMMON-REF(A, B) is C. |
| 74 | template<class _Ap, class _Bp, class _Xp, class _Yp> | |
| 75 | requires | |
| 76 | requires { typename __common_ref_C<_Xp, _Yp>; } && | |
| 77 | is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> && | |
| 78 | is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>> | |
| 79 | struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> | |
| 80 | { | |
| 81 | using __type = __common_ref_C<_Xp, _Yp>; | |
| 74 | // clang-format off | |
| 75 | template <class _Ap, class _Bp, class _Xp, class _Yp> | |
| 76 | requires | |
| 77 | requires { typename __common_ref_C<_Xp, _Yp>; } && | |
| 78 | is_convertible_v<_Ap&&, __common_ref_C<_Xp, _Yp>> && | |
| 79 | is_convertible_v<_Bp&&, __common_ref_C<_Xp, _Yp>> | |
| 80 | struct __common_ref<_Ap&&, _Bp&&, _Xp, _Yp> { | |
| 81 | using __type = __common_ref_C<_Xp, _Yp>; | |
| 82 | 82 | }; |
| 83 | // clang-format on | |
| 83 | 84 | |
| 84 | 85 | // Otherwise, let D be COMMON-REF(const X&, Y&). ... |
| 85 | 86 | template <class _Tp, class _Up> |
| ... | ... | @@ -87,21 +88,23 @@ using __common_ref_D = __common_ref_t<const _Tp&, _Up&>; |
| 87 | 88 | |
| 88 | 89 | // ... If A is an rvalue reference and B is an lvalue reference and D is well-formed and |
| 89 | 90 | // is_convertible_v<A, D> is true, then COMMON-REF(A, B) is D. |
| 90 | template<class _Ap, class _Bp, class _Xp, class _Yp> | |
| 91 | requires requires { typename __common_ref_D<_Xp, _Yp>; } && | |
| 92 | is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>> | |
| 93 | struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> | |
| 94 | { | |
| 95 | using __type = __common_ref_D<_Xp, _Yp>; | |
| 91 | // clang-format off | |
| 92 | template <class _Ap, class _Bp, class _Xp, class _Yp> | |
| 93 | requires | |
| 94 | requires { typename __common_ref_D<_Xp, _Yp>; } && | |
| 95 | is_convertible_v<_Ap&&, __common_ref_D<_Xp, _Yp>> | |
| 96 | struct __common_ref<_Ap&&, _Bp&, _Xp, _Yp> { | |
| 97 | using __type = __common_ref_D<_Xp, _Yp>; | |
| 96 | 98 | }; |
| 99 | // clang-format on | |
| 97 | 100 | |
| 98 | 101 | // Otherwise, if A is an lvalue reference and B is an rvalue reference, then |
| 99 | 102 | // COMMON-REF(A, B) is COMMON-REF(B, A). |
| 100 | template<class _Ap, class _Bp, class _Xp, class _Yp> | |
| 103 | template <class _Ap, class _Bp, class _Xp, class _Yp> | |
| 101 | 104 | struct __common_ref<_Ap&, _Bp&&, _Xp, _Yp> : __common_ref<_Bp&&, _Ap&> {}; |
| 102 | 105 | |
| 103 | 106 | // Otherwise, COMMON-REF(A, B) is ill-formed. |
| 104 | template<class _Ap, class _Bp, class _Xp, class _Yp> | |
| 107 | template <class _Ap, class _Bp, class _Xp, class _Yp> | |
| 105 | 108 | struct __common_ref {}; |
| 106 | 109 | |
| 107 | 110 | // Note C: For the common_reference trait applied to a parameter pack [...] |
| ... | ... | @@ -113,75 +116,77 @@ template <class... _Types> |
| 113 | 116 | using common_reference_t = typename common_reference<_Types...>::type; |
| 114 | 117 | |
| 115 | 118 | // bullet 1 - sizeof...(T) == 0 |
| 116 | template<> | |
| 119 | template <> | |
| 117 | 120 | struct common_reference<> {}; |
| 118 | 121 | |
| 119 | 122 | // bullet 2 - sizeof...(T) == 1 |
| 120 | 123 | template <class _Tp> |
| 121 | struct common_reference<_Tp> | |
| 122 | { | |
| 123 | using type = _Tp; | |
| 124 | struct common_reference<_Tp> { | |
| 125 | using type = _Tp; | |
| 124 | 126 | }; |
| 125 | 127 | |
| 126 | 128 | // bullet 3 - sizeof...(T) == 2 |
| 127 | template <class _Tp, class _Up> struct __common_reference_sub_bullet3; | |
| 128 | template <class _Tp, class _Up> struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {}; | |
| 129 | template <class _Tp, class _Up> struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {}; | |
| 129 | template <class _Tp, class _Up> | |
| 130 | struct __common_reference_sub_bullet3; | |
| 131 | template <class _Tp, class _Up> | |
| 132 | struct __common_reference_sub_bullet2 : __common_reference_sub_bullet3<_Tp, _Up> {}; | |
| 133 | template <class _Tp, class _Up> | |
| 134 | struct __common_reference_sub_bullet1 : __common_reference_sub_bullet2<_Tp, _Up> {}; | |
| 130 | 135 | |
| 131 | 136 | // sub-bullet 1 - If T1 and T2 are reference types and COMMON-REF(T1, T2) is well-formed, then |
| 132 | 137 | // the member typedef `type` denotes that type. |
| 133 | template <class _Tp, class _Up> struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {}; | |
| 138 | template <class _Tp, class _Up> | |
| 139 | struct common_reference<_Tp, _Up> : __common_reference_sub_bullet1<_Tp, _Up> {}; | |
| 134 | 140 | |
| 135 | 141 | template <class _Tp, class _Up> |
| 136 | requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; } | |
| 137 | struct __common_reference_sub_bullet1<_Tp, _Up> | |
| 138 | { | |
| 139 | using type = __common_ref_t<_Tp, _Up>; | |
| 142 | requires is_reference_v<_Tp> && is_reference_v<_Up> && requires { typename __common_ref_t<_Tp, _Up>; } | |
| 143 | struct __common_reference_sub_bullet1<_Tp, _Up> { | |
| 144 | using type = __common_ref_t<_Tp, _Up>; | |
| 140 | 145 | }; |
| 141 | 146 | |
| 142 | 147 | // sub-bullet 2 - Otherwise, if basic_common_reference<remove_cvref_t<T1>, remove_cvref_t<T2>, XREF(T1), XREF(T2)>::type |
| 143 | 148 | // is well-formed, then the member typedef `type` denotes that type. |
| 144 | template <class, class, template <class> class, template <class> class> struct basic_common_reference {}; | |
| 149 | template <class, class, template <class> class, template <class> class> | |
| 150 | struct basic_common_reference {}; | |
| 145 | 151 | |
| 146 | 152 | template <class _Tp, class _Up> |
| 147 | using __basic_common_reference_t = typename basic_common_reference< | |
| 148 | remove_cvref_t<_Tp>, remove_cvref_t<_Up>, | |
| 149 | __xref<_Tp>::template __apply, __xref<_Up>::template __apply>::type; | |
| 153 | using __basic_common_reference_t = | |
| 154 | typename basic_common_reference<remove_cvref_t<_Tp>, | |
| 155 | remove_cvref_t<_Up>, | |
| 156 | __xref<_Tp>::template __apply, | |
| 157 | __xref<_Up>::template __apply>::type; | |
| 150 | 158 | |
| 151 | 159 | template <class _Tp, class _Up> |
| 152 | requires requires { typename __basic_common_reference_t<_Tp, _Up>; } | |
| 153 | struct __common_reference_sub_bullet2<_Tp, _Up> | |
| 154 | { | |
| 155 | using type = __basic_common_reference_t<_Tp, _Up>; | |
| 160 | requires requires { typename __basic_common_reference_t<_Tp, _Up>; } | |
| 161 | struct __common_reference_sub_bullet2<_Tp, _Up> { | |
| 162 | using type = __basic_common_reference_t<_Tp, _Up>; | |
| 156 | 163 | }; |
| 157 | 164 | |
| 158 | 165 | // sub-bullet 3 - Otherwise, if COND-RES(T1, T2) is well-formed, |
| 159 | 166 | // then the member typedef `type` denotes that type. |
| 160 | 167 | template <class _Tp, class _Up> |
| 161 | requires requires { typename __cond_res<_Tp, _Up>; } | |
| 162 | struct __common_reference_sub_bullet3<_Tp, _Up> | |
| 163 | { | |
| 164 | using type = __cond_res<_Tp, _Up>; | |
| 168 | requires requires { typename __cond_res<_Tp, _Up>; } | |
| 169 | struct __common_reference_sub_bullet3<_Tp, _Up> { | |
| 170 | using type = __cond_res<_Tp, _Up>; | |
| 165 | 171 | }; |
| 166 | 172 | |
| 167 | ||
| 168 | 173 | // sub-bullet 4 & 5 - Otherwise, if common_type_t<T1, T2> is well-formed, |
| 169 | 174 | // then the member typedef `type` denotes that type. |
| 170 | 175 | // - Otherwise, there shall be no member `type`. |
| 171 | template <class _Tp, class _Up> struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {}; | |
| 176 | template <class _Tp, class _Up> | |
| 177 | struct __common_reference_sub_bullet3 : common_type<_Tp, _Up> {}; | |
| 172 | 178 | |
| 173 | 179 | // bullet 4 - If there is such a type `C`, the member typedef type shall denote the same type, if |
| 174 | 180 | // any, as `common_reference_t<C, Rest...>`. |
| 175 | 181 | template <class _Tp, class _Up, class _Vp, class... _Rest> |
| 176 | requires requires { typename common_reference_t<_Tp, _Up>; } | |
| 177 | struct common_reference<_Tp, _Up, _Vp, _Rest...> | |
| 178 | : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...> | |
| 179 | {}; | |
| 182 | requires requires { typename common_reference_t<_Tp, _Up>; } | |
| 183 | struct common_reference<_Tp, _Up, _Vp, _Rest...> : common_reference<common_reference_t<_Tp, _Up>, _Vp, _Rest...> {}; | |
| 180 | 184 | |
| 181 | 185 | // bullet 5 - Otherwise, there shall be no member `type`. |
| 182 | template <class...> struct common_reference {}; | |
| 186 | template <class...> | |
| 187 | struct common_reference {}; | |
| 183 | 188 | |
| 184 | #endif // _LIBCPP_STD_VER > 17 | |
| 189 | #endif // _LIBCPP_STD_VER >= 20 | |
| 185 | 190 | |
| 186 | 191 | _LIBCPP_END_NAMESPACE_STD |
| 187 | 192 |
lib/libcxx/include/__type_traits/common_type.h+19-51| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 27 | 27 | // Let COND_RES(X, Y) be: |
| 28 | 28 | template <class _Tp, class _Up> |
| 29 | 29 | using __cond_type = decltype(false ? std::declval<_Tp>() : std::declval<_Up>()); |
| ... | ... | @@ -33,9 +33,8 @@ struct __common_type3 {}; |
| 33 | 33 | |
| 34 | 34 | // sub-bullet 4 - "if COND_RES(CREF(D1), CREF(D2)) denotes a type..." |
| 35 | 35 | template <class _Tp, class _Up> |
| 36 | struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> | |
| 37 | { | |
| 38 | using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>; | |
| 36 | struct __common_type3<_Tp, _Up, void_t<__cond_type<const _Tp&, const _Up&>>> { | |
| 37 | using type = remove_cvref_t<__cond_type<const _Tp&, const _Up&>>; | |
| 39 | 38 | }; |
| 40 | 39 | |
| 41 | 40 | template <class _Tp, class _Up, class = void> |
| ... | ... | @@ -47,50 +46,26 @@ struct __common_type2_imp {}; |
| 47 | 46 | |
| 48 | 47 | // sub-bullet 3 - "if decay_t<decltype(false ? declval<D1>() : declval<D2>())> ..." |
| 49 | 48 | template <class _Tp, class _Up> |
| 50 | struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> > | |
| 51 | { | |
| 52 | typedef _LIBCPP_NODEBUG typename decay<decltype( | |
| 53 | true ? std::declval<_Tp>() : std::declval<_Up>() | |
| 54 | )>::type type; | |
| 49 | struct __common_type2_imp<_Tp, _Up, __void_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> > { | |
| 50 | typedef _LIBCPP_NODEBUG __decay_t<decltype(true ? std::declval<_Tp>() : std::declval<_Up>())> type; | |
| 55 | 51 | }; |
| 56 | 52 | |
| 57 | 53 | template <class, class = void> |
| 58 | 54 | struct __common_type_impl {}; |
| 59 | 55 | |
| 60 | // Clang provides variadic templates in C++03 as an extension. | |
| 61 | #if !defined(_LIBCPP_CXX03_LANG) || defined(__clang__) | |
| 62 | # define _LIBCPP_OPTIONAL_PACK(...) , __VA_ARGS__ | |
| 63 | 56 | template <class... _Tp> |
| 64 | 57 | struct __common_types; |
| 65 | 58 | template <class... _Tp> |
| 66 | 59 | struct _LIBCPP_TEMPLATE_VIS common_type; |
| 67 | #else | |
| 68 | # define _LIBCPP_OPTIONAL_PACK(...) | |
| 69 | struct __no_arg; | |
| 70 | template <class _Tp, class _Up, class = __no_arg> | |
| 71 | struct __common_types; | |
| 72 | template <class _Tp = __no_arg, class _Up = __no_arg, class _Vp = __no_arg, | |
| 73 | class _Unused = __no_arg> | |
| 74 | struct common_type { | |
| 75 | static_assert(sizeof(_Unused) == 0, | |
| 76 | "common_type accepts at most 3 arguments in C++03"); | |
| 77 | }; | |
| 78 | #endif // _LIBCPP_CXX03_LANG | |
| 79 | 60 | |
| 80 | 61 | template <class _Tp, class _Up> |
| 81 | struct __common_type_impl< | |
| 82 | __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> > | |
| 83 | { | |
| 62 | struct __common_type_impl< __common_types<_Tp, _Up>, __void_t<typename common_type<_Tp, _Up>::type> > { | |
| 84 | 63 | typedef typename common_type<_Tp, _Up>::type type; |
| 85 | 64 | }; |
| 86 | 65 | |
| 87 | template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)> | |
| 88 | struct __common_type_impl< | |
| 89 | __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)>, | |
| 90 | __void_t<typename common_type<_Tp, _Up>::type> > | |
| 91 | : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type, | |
| 92 | _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > { | |
| 93 | }; | |
| 66 | template <class _Tp, class _Up, class _Vp, class... _Rest> | |
| 67 | struct __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...>, __void_t<typename common_type<_Tp, _Up>::type> > | |
| 68 | : __common_type_impl<__common_types<typename common_type<_Tp, _Up>::type, _Vp, _Rest...> > {}; | |
| 94 | 69 | |
| 95 | 70 | // bullet 1 - sizeof...(Tp) == 0 |
| 96 | 71 | |
| ... | ... | @@ -100,33 +75,26 @@ struct _LIBCPP_TEMPLATE_VIS common_type<> {}; |
| 100 | 75 | // bullet 2 - sizeof...(Tp) == 1 |
| 101 | 76 | |
| 102 | 77 | template <class _Tp> |
| 103 | struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> | |
| 104 | : public common_type<_Tp, _Tp> {}; | |
| 78 | struct _LIBCPP_TEMPLATE_VIS common_type<_Tp> : public common_type<_Tp, _Tp> {}; | |
| 105 | 79 | |
| 106 | 80 | // bullet 3 - sizeof...(Tp) == 2 |
| 107 | 81 | |
| 108 | 82 | // sub-bullet 1 - "If is_same_v<T1, D1> is false or ..." |
| 109 | 83 | template <class _Tp, class _Up> |
| 110 | 84 | struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up> |
| 111 | : conditional< | |
| 112 | _IsSame<_Tp, typename decay<_Tp>::type>::value && _IsSame<_Up, typename decay<_Up>::type>::value, | |
| 113 | __common_type2_imp<_Tp, _Up>, | |
| 114 | common_type<typename decay<_Tp>::type, typename decay<_Up>::type> | |
| 115 | >::type | |
| 116 | {}; | |
| 85 | : conditional<_IsSame<_Tp, __decay_t<_Tp> >::value && _IsSame<_Up, __decay_t<_Up> >::value, | |
| 86 | __common_type2_imp<_Tp, _Up>, | |
| 87 | common_type<__decay_t<_Tp>, __decay_t<_Up> > >::type {}; | |
| 117 | 88 | |
| 118 | 89 | // bullet 4 - sizeof...(Tp) > 2 |
| 119 | 90 | |
| 120 | template <class _Tp, class _Up, class _Vp _LIBCPP_OPTIONAL_PACK(class... _Rest)> | |
| 121 | struct _LIBCPP_TEMPLATE_VIS | |
| 122 | common_type<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> | |
| 123 | : __common_type_impl< | |
| 124 | __common_types<_Tp, _Up, _Vp _LIBCPP_OPTIONAL_PACK(_Rest...)> > {}; | |
| 125 | ||
| 126 | #undef _LIBCPP_OPTIONAL_PACK | |
| 91 | template <class _Tp, class _Up, class _Vp, class... _Rest> | |
| 92 | struct _LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up, _Vp, _Rest...> | |
| 93 | : __common_type_impl<__common_types<_Tp, _Up, _Vp, _Rest...> > {}; | |
| 127 | 94 | |
| 128 | #if _LIBCPP_STD_VER > 11 | |
| 129 | template <class ..._Tp> using common_type_t = typename common_type<_Tp...>::type; | |
| 95 | #if _LIBCPP_STD_VER >= 14 | |
| 96 | template <class... _Tp> | |
| 97 | using common_type_t = typename common_type<_Tp...>::type; | |
| 130 | 98 | #endif |
| 131 | 99 | |
| 132 | 100 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/conditional.h+1-1| ... | ... | @@ -44,7 +44,7 @@ struct _LIBCPP_TEMPLATE_VIS conditional<false, _If, _Then> { |
| 44 | 44 | using type _LIBCPP_NODEBUG = _Then; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | #if _LIBCPP_STD_VER > 11 | |
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | 48 | template <bool _Bp, class _IfRes, class _ElseRes> |
| 49 | 49 | using conditional_t _LIBCPP_NODEBUG = typename conditional<_Bp, _IfRes, _ElseRes>::type; |
| 50 | 50 | #endif |
lib/libcxx/include/__type_traits/conjunction.h+2-2| ... | ... | @@ -37,7 +37,7 @@ false_type __and_helper(...); |
| 37 | 37 | template <class... _Pred> |
| 38 | 38 | using _And _LIBCPP_NODEBUG = decltype(std::__and_helper<_Pred...>(0)); |
| 39 | 39 | |
| 40 | #if _LIBCPP_STD_VER > 14 | |
| 40 | #if _LIBCPP_STD_VER >= 17 | |
| 41 | 41 | |
| 42 | 42 | template <class...> |
| 43 | 43 | struct conjunction : true_type {}; |
| ... | ... | @@ -51,7 +51,7 @@ struct conjunction<_Arg, _Args...> : conditional_t<!bool(_Arg::value), _Arg, con |
| 51 | 51 | template <class... _Args> |
| 52 | 52 | inline constexpr bool conjunction_v = conjunction<_Args...>::value; |
| 53 | 53 | |
| 54 | #endif // _LIBCPP_STD_VER > 14 | |
| 54 | #endif // _LIBCPP_STD_VER >= 17 | |
| 55 | 55 | |
| 56 | 56 | _LIBCPP_END_NAMESPACE_STD |
| 57 | 57 |
lib/libcxx/include/__type_traits/copy_cv.h+8-12| ... | ... | @@ -23,27 +23,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | // Let COPYCV(FROM, TO) be an alias for type TO with the addition of FROM's |
| 24 | 24 | // top-level cv-qualifiers. |
| 25 | 25 | template <class _From, class _To> |
| 26 | struct __copy_cv | |
| 27 | { | |
| 28 | using type = _To; | |
| 26 | struct __copy_cv { | |
| 27 | using type = _To; | |
| 29 | 28 | }; |
| 30 | 29 | |
| 31 | 30 | template <class _From, class _To> |
| 32 | struct __copy_cv<const _From, _To> | |
| 33 | { | |
| 34 | using type = typename add_const<_To>::type; | |
| 31 | struct __copy_cv<const _From, _To> { | |
| 32 | using type = typename add_const<_To>::type; | |
| 35 | 33 | }; |
| 36 | 34 | |
| 37 | 35 | template <class _From, class _To> |
| 38 | struct __copy_cv<volatile _From, _To> | |
| 39 | { | |
| 40 | using type = typename add_volatile<_To>::type; | |
| 36 | struct __copy_cv<volatile _From, _To> { | |
| 37 | using type = typename add_volatile<_To>::type; | |
| 41 | 38 | }; |
| 42 | 39 | |
| 43 | 40 | template <class _From, class _To> |
| 44 | struct __copy_cv<const volatile _From, _To> | |
| 45 | { | |
| 46 | using type = typename add_cv<_To>::type; | |
| 41 | struct __copy_cv<const volatile _From, _To> { | |
| 42 | using type = typename add_cv<_To>::type; | |
| 47 | 43 | }; |
| 48 | 44 | |
| 49 | 45 | template <class _From, class _To> |
lib/libcxx/include/__type_traits/copy_cvref.h+6-9| ... | ... | @@ -21,21 +21,18 @@ |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _From, class _To> |
| 24 | struct __copy_cvref | |
| 25 | { | |
| 26 | using type = __copy_cv_t<_From, _To>; | |
| 24 | struct __copy_cvref { | |
| 25 | using type = __copy_cv_t<_From, _To>; | |
| 27 | 26 | }; |
| 28 | 27 | |
| 29 | 28 | template <class _From, class _To> |
| 30 | struct __copy_cvref<_From&, _To> | |
| 31 | { | |
| 32 | using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >; | |
| 29 | struct __copy_cvref<_From&, _To> { | |
| 30 | using type = __add_lvalue_reference_t<__copy_cv_t<_From, _To> >; | |
| 33 | 31 | }; |
| 34 | 32 | |
| 35 | 33 | template <class _From, class _To> |
| 36 | struct __copy_cvref<_From&&, _To> | |
| 37 | { | |
| 38 | using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >; | |
| 34 | struct __copy_cvref<_From&&, _To> { | |
| 35 | using type = __add_rvalue_reference_t<__copy_cv_t<_From, _To> >; | |
| 39 | 36 | }; |
| 40 | 37 | |
| 41 | 38 | template <class _From, class _To> |
lib/libcxx/include/__type_traits/datasizeof.h created+55| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_DATASIZEOF_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_DATASIZEOF_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/is_class.h> | |
| 14 | #include <__type_traits/is_final.h> | |
| 15 | #include <cstddef> | |
| 16 | ||
| 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 18 | # pragma GCC system_header | |
| 19 | #endif | |
| 20 | ||
| 21 | // This trait provides the size of a type excluding any tail padding. | |
| 22 | // | |
| 23 | // It is useful in contexts where performing an operation using the full size of the class (including padding) may | |
| 24 | // have unintended side effects, such as overwriting a derived class' member when writing the tail padding of a class | |
| 25 | // through a pointer-to-base. | |
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct __libcpp_datasizeof { | |
| 31 | #if __has_cpp_attribute(__no_unique_address__) | |
| 32 | template <class = char> | |
| 33 | struct _FirstPaddingByte { | |
| 34 | [[__no_unique_address__]] _Tp __v_; | |
| 35 | char __first_padding_byte_; | |
| 36 | }; | |
| 37 | #else | |
| 38 | template <bool = __libcpp_is_final<_Tp>::value || !is_class<_Tp>::value> | |
| 39 | struct _FirstPaddingByte : _Tp { | |
| 40 | char __first_padding_byte_; | |
| 41 | }; | |
| 42 | ||
| 43 | template <> | |
| 44 | struct _FirstPaddingByte<true> { | |
| 45 | _Tp __v_; | |
| 46 | char __first_padding_byte_; | |
| 47 | }; | |
| 48 | #endif | |
| 49 | ||
| 50 | static const size_t value = offsetof(_FirstPaddingByte<>, __first_padding_byte_); | |
| 51 | }; | |
| 52 | ||
| 53 | _LIBCPP_END_NAMESPACE_STD | |
| 54 | ||
| 55 | #endif // _LIBCPP___TYPE_TRAITS_DATASIZEOF_H |
lib/libcxx/include/__type_traits/decay.h+20-18| ... | ... | @@ -26,44 +26,46 @@ |
| 26 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | |
| 28 | 28 | #if __has_builtin(__decay) |
| 29 | template <class _Tp> | |
| 30 | using __decay_t _LIBCPP_NODEBUG = __decay(_Tp); | |
| 31 | ||
| 29 | 32 | template <class _Tp> |
| 30 | 33 | struct decay { |
| 31 | using type _LIBCPP_NODEBUG = __decay(_Tp); | |
| 34 | using type _LIBCPP_NODEBUG = __decay_t<_Tp>; | |
| 32 | 35 | }; |
| 36 | ||
| 33 | 37 | #else |
| 34 | 38 | template <class _Up, bool> |
| 35 | 39 | struct __decay { |
| 36 | typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type; | |
| 40 | typedef _LIBCPP_NODEBUG __remove_cv_t<_Up> type; | |
| 37 | 41 | }; |
| 38 | 42 | |
| 39 | 43 | template <class _Up> |
| 40 | 44 | struct __decay<_Up, true> { |
| 41 | 45 | public: |
| 42 | typedef _LIBCPP_NODEBUG typename conditional | |
| 43 | < | |
| 44 | is_array<_Up>::value, | |
| 45 | __add_pointer_t<__remove_extent_t<_Up> >, | |
| 46 | typename conditional | |
| 47 | < | |
| 48 | is_function<_Up>::value, | |
| 49 | typename add_pointer<_Up>::type, | |
| 50 | __remove_cv_t<_Up> | |
| 51 | >::type | |
| 52 | >::type type; | |
| 46 | typedef _LIBCPP_NODEBUG typename conditional< | |
| 47 | is_array<_Up>::value, | |
| 48 | __add_pointer_t<__remove_extent_t<_Up> >, | |
| 49 | typename conditional<is_function<_Up>::value, typename add_pointer<_Up>::type, __remove_cv_t<_Up> >::type >::type | |
| 50 | type; | |
| 53 | 51 | }; |
| 54 | 52 | |
| 55 | 53 | template <class _Tp> |
| 56 | struct _LIBCPP_TEMPLATE_VIS decay | |
| 57 | { | |
| 54 | struct _LIBCPP_TEMPLATE_VIS decay { | |
| 58 | 55 | private: |
| 59 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up; | |
| 56 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tp> _Up; | |
| 57 | ||
| 60 | 58 | public: |
| 61 | 59 | typedef _LIBCPP_NODEBUG typename __decay<_Up, __libcpp_is_referenceable<_Up>::value>::type type; |
| 62 | 60 | }; |
| 61 | ||
| 62 | template <class _Tp> | |
| 63 | using __decay_t = typename decay<_Tp>::type; | |
| 63 | 64 | #endif // __has_builtin(__decay) |
| 64 | 65 | |
| 65 | #if _LIBCPP_STD_VER > 11 | |
| 66 | template <class _Tp> using decay_t = typename decay<_Tp>::type; | |
| 66 | #if _LIBCPP_STD_VER >= 14 | |
| 67 | template <class _Tp> | |
| 68 | using decay_t = __decay_t<_Tp>; | |
| 67 | 69 | #endif |
| 68 | 70 | |
| 69 | 71 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/disjunction.h+2-2| ... | ... | @@ -43,7 +43,7 @@ struct _OrImpl<false> { |
| 43 | 43 | template <class... _Args> |
| 44 | 44 | using _Or _LIBCPP_NODEBUG = typename _OrImpl<sizeof...(_Args) != 0>::template _Result<false_type, _Args...>; |
| 45 | 45 | |
| 46 | #if _LIBCPP_STD_VER > 14 | |
| 46 | #if _LIBCPP_STD_VER >= 17 | |
| 47 | 47 | |
| 48 | 48 | template <class... _Args> |
| 49 | 49 | struct disjunction : _Or<_Args...> {}; |
| ... | ... | @@ -51,7 +51,7 @@ struct disjunction : _Or<_Args...> {}; |
| 51 | 51 | template <class... _Args> |
| 52 | 52 | inline constexpr bool disjunction_v = _Or<_Args...>::value; |
| 53 | 53 | |
| 54 | #endif // _LIBCPP_STD_VER > 14 | |
| 54 | #endif // _LIBCPP_STD_VER >= 17 | |
| 55 | 55 | |
| 56 | 56 | _LIBCPP_END_NAMESPACE_STD |
| 57 | 57 |
lib/libcxx/include/__type_traits/enable_if.h+13-7| ... | ... | @@ -17,13 +17,19 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | template <bool, class _Tp = void> struct _LIBCPP_TEMPLATE_VIS enable_if {}; | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> {typedef _Tp type;}; | |
| 22 | ||
| 23 | template <bool _Bp, class _Tp = void> using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type; | |
| 24 | ||
| 25 | #if _LIBCPP_STD_VER > 11 | |
| 26 | template <bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type; | |
| 20 | template <bool, class _Tp = void> | |
| 21 | struct _LIBCPP_TEMPLATE_VIS enable_if {}; | |
| 22 | template <class _Tp> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS enable_if<true, _Tp> { | |
| 24 | typedef _Tp type; | |
| 25 | }; | |
| 26 | ||
| 27 | template <bool _Bp, class _Tp = void> | |
| 28 | using __enable_if_t _LIBCPP_NODEBUG = typename enable_if<_Bp, _Tp>::type; | |
| 29 | ||
| 30 | #if _LIBCPP_STD_VER >= 14 | |
| 31 | template <bool _Bp, class _Tp = void> | |
| 32 | using enable_if_t = typename enable_if<_Bp, _Tp>::type; | |
| 27 | 33 | #endif |
| 28 | 34 | |
| 29 | 35 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/extent.h+17-18| ... | ... | @@ -21,32 +21,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if __has_builtin(__array_extent) |
| 23 | 23 | |
| 24 | template<class _Tp, size_t _Dim = 0> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS extent | |
| 26 | : integral_constant<size_t, __array_extent(_Tp, _Dim)> { }; | |
| 24 | template <class _Tp, size_t _Dim = 0> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS extent : integral_constant<size_t, __array_extent(_Tp, _Dim)> {}; | |
| 27 | 26 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 27 | # if _LIBCPP_STD_VER >= 17 | |
| 29 | 28 | template <class _Tp, unsigned _Ip = 0> |
| 30 | 29 | inline constexpr size_t extent_v = __array_extent(_Tp, _Ip); |
| 31 | #endif | |
| 30 | # endif | |
| 32 | 31 | |
| 33 | 32 | #else // __has_builtin(__array_extent) |
| 34 | 33 | |
| 35 | template <class _Tp, unsigned _Ip = 0> struct _LIBCPP_TEMPLATE_VIS extent | |
| 36 | : public integral_constant<size_t, 0> {}; | |
| 37 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> | |
| 38 | : public integral_constant<size_t, 0> {}; | |
| 39 | template <class _Tp, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip> | |
| 40 | : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {}; | |
| 41 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0> | |
| 42 | : public integral_constant<size_t, _Np> {}; | |
| 43 | template <class _Tp, size_t _Np, unsigned _Ip> struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> | |
| 44 | : public integral_constant<size_t, extent<_Tp, _Ip-1>::value> {}; | |
| 45 | ||
| 46 | #if _LIBCPP_STD_VER > 14 | |
| 34 | template <class _Tp, unsigned _Ip = 0> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS extent : public integral_constant<size_t, 0> {}; | |
| 36 | template <class _Tp> | |
| 37 | struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> : public integral_constant<size_t, 0> {}; | |
| 38 | template <class _Tp, unsigned _Ip> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {}; | |
| 40 | template <class _Tp, size_t _Np> | |
| 41 | struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0> : public integral_constant<size_t, _Np> {}; | |
| 42 | template <class _Tp, size_t _Np, unsigned _Ip> | |
| 43 | struct _LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> : public integral_constant<size_t, extent<_Tp, _Ip - 1>::value> {}; | |
| 44 | ||
| 45 | # if _LIBCPP_STD_VER >= 17 | |
| 47 | 46 | template <class _Tp, unsigned _Ip = 0> |
| 48 | 47 | inline constexpr size_t extent_v = extent<_Tp, _Ip>::value; |
| 49 | #endif | |
| 48 | # endif | |
| 50 | 49 | |
| 51 | 50 | #endif // __has_builtin(__array_extent) |
| 52 | 51 |
lib/libcxx/include/__type_traits/has_unique_object_representation.h+4-4| ... | ... | @@ -20,11 +20,11 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 24 | |
| 25 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations | |
| 26 | : public integral_constant<bool, | |
| 27 | __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {}; | |
| 25 | template <class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS has_unique_object_representations | |
| 27 | : public integral_constant<bool, __has_unique_object_representations(remove_cv_t<remove_all_extents_t<_Tp>>)> {}; | |
| 28 | 28 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; |
lib/libcxx/include/__type_traits/has_virtual_destructor.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor | |
| 22 | : public integral_constant<bool, __has_virtual_destructor(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS has_virtual_destructor : public integral_constant<bool, __has_virtual_destructor(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool has_virtual_destructor_v = __has_virtual_destructor(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/integral_constant.h+8-11| ... | ... | @@ -18,29 +18,26 @@ |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | 20 | template <class _Tp, _Tp __v> |
| 21 | struct _LIBCPP_TEMPLATE_VIS integral_constant | |
| 22 | { | |
| 23 | static _LIBCPP_CONSTEXPR const _Tp value = __v; | |
| 24 | typedef _Tp value_type; | |
| 21 | struct _LIBCPP_TEMPLATE_VIS integral_constant { | |
| 22 | static _LIBCPP_CONSTEXPR const _Tp value = __v; | |
| 23 | typedef _Tp value_type; | |
| 25 | 24 | typedef integral_constant type; |
| 26 | _LIBCPP_INLINE_VISIBILITY | |
| 27 | _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT {return value;} | |
| 28 | #if _LIBCPP_STD_VER > 11 | |
| 29 | _LIBCPP_INLINE_VISIBILITY | |
| 30 | constexpr value_type operator ()() const _NOEXCEPT {return value;} | |
| 25 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator value_type() const _NOEXCEPT { return value; } | |
| 26 | #if _LIBCPP_STD_VER >= 14 | |
| 27 | _LIBCPP_INLINE_VISIBILITY constexpr value_type operator()() const _NOEXCEPT { return value; } | |
| 31 | 28 | #endif |
| 32 | 29 | }; |
| 33 | 30 | |
| 34 | 31 | template <class _Tp, _Tp __v> |
| 35 | 32 | _LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; |
| 36 | 33 | |
| 37 | typedef integral_constant<bool, true> true_type; | |
| 34 | typedef integral_constant<bool, true> true_type; | |
| 38 | 35 | typedef integral_constant<bool, false> false_type; |
| 39 | 36 | |
| 40 | 37 | template <bool _Val> |
| 41 | 38 | using _BoolConstant _LIBCPP_NODEBUG = integral_constant<bool, _Val>; |
| 42 | 39 | |
| 43 | #if _LIBCPP_STD_VER > 14 | |
| 40 | #if _LIBCPP_STD_VER >= 17 | |
| 44 | 41 | template <bool __b> |
| 45 | 42 | using bool_constant = integral_constant<bool, __b>; |
| 46 | 43 | #endif |
lib/libcxx/include/__type_traits/invoke.h created+461| ... | ... | @@ -0,0 +1,461 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP___TYPE_TRAITS_INVOKE_H | |
| 11 | #define _LIBCPP___TYPE_TRAITS_INVOKE_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__type_traits/add_lvalue_reference.h> | |
| 15 | #include <__type_traits/apply_cv.h> | |
| 16 | #include <__type_traits/conditional.h> | |
| 17 | #include <__type_traits/decay.h> | |
| 18 | #include <__type_traits/enable_if.h> | |
| 19 | #include <__type_traits/integral_constant.h> | |
| 20 | #include <__type_traits/is_base_of.h> | |
| 21 | #include <__type_traits/is_core_convertible.h> | |
| 22 | #include <__type_traits/is_member_function_pointer.h> | |
| 23 | #include <__type_traits/is_member_object_pointer.h> | |
| 24 | #include <__type_traits/is_reference_wrapper.h> | |
| 25 | #include <__type_traits/is_same.h> | |
| 26 | #include <__type_traits/is_void.h> | |
| 27 | #include <__type_traits/nat.h> | |
| 28 | #include <__type_traits/remove_cv.h> | |
| 29 | #include <__utility/declval.h> | |
| 30 | #include <__utility/forward.h> | |
| 31 | ||
| 32 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 33 | # pragma GCC system_header | |
| 34 | #endif | |
| 35 | ||
| 36 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 37 | ||
| 38 | struct __any { | |
| 39 | __any(...); | |
| 40 | }; | |
| 41 | ||
| 42 | template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> | |
| 43 | struct __member_pointer_traits_imp {}; | |
| 44 | ||
| 45 | template <class _Rp, class _Class, class... _Param> | |
| 46 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> { | |
| 47 | typedef _Class _ClassType; | |
| 48 | typedef _Rp _ReturnType; | |
| 49 | typedef _Rp(_FnType)(_Param...); | |
| 50 | }; | |
| 51 | ||
| 52 | template <class _Rp, class _Class, class... _Param> | |
| 53 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> { | |
| 54 | typedef _Class _ClassType; | |
| 55 | typedef _Rp _ReturnType; | |
| 56 | typedef _Rp(_FnType)(_Param..., ...); | |
| 57 | }; | |
| 58 | ||
| 59 | template <class _Rp, class _Class, class... _Param> | |
| 60 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> { | |
| 61 | typedef _Class const _ClassType; | |
| 62 | typedef _Rp _ReturnType; | |
| 63 | typedef _Rp(_FnType)(_Param...); | |
| 64 | }; | |
| 65 | ||
| 66 | template <class _Rp, class _Class, class... _Param> | |
| 67 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> { | |
| 68 | typedef _Class const _ClassType; | |
| 69 | typedef _Rp _ReturnType; | |
| 70 | typedef _Rp(_FnType)(_Param..., ...); | |
| 71 | }; | |
| 72 | ||
| 73 | template <class _Rp, class _Class, class... _Param> | |
| 74 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> { | |
| 75 | typedef _Class volatile _ClassType; | |
| 76 | typedef _Rp _ReturnType; | |
| 77 | typedef _Rp(_FnType)(_Param...); | |
| 78 | }; | |
| 79 | ||
| 80 | template <class _Rp, class _Class, class... _Param> | |
| 81 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> { | |
| 82 | typedef _Class volatile _ClassType; | |
| 83 | typedef _Rp _ReturnType; | |
| 84 | typedef _Rp(_FnType)(_Param..., ...); | |
| 85 | }; | |
| 86 | ||
| 87 | template <class _Rp, class _Class, class... _Param> | |
| 88 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> { | |
| 89 | typedef _Class const volatile _ClassType; | |
| 90 | typedef _Rp _ReturnType; | |
| 91 | typedef _Rp(_FnType)(_Param...); | |
| 92 | }; | |
| 93 | ||
| 94 | template <class _Rp, class _Class, class... _Param> | |
| 95 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> { | |
| 96 | typedef _Class const volatile _ClassType; | |
| 97 | typedef _Rp _ReturnType; | |
| 98 | typedef _Rp(_FnType)(_Param..., ...); | |
| 99 | }; | |
| 100 | ||
| 101 | template <class _Rp, class _Class, class... _Param> | |
| 102 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&, true, false> { | |
| 103 | typedef _Class& _ClassType; | |
| 104 | typedef _Rp _ReturnType; | |
| 105 | typedef _Rp(_FnType)(_Param...); | |
| 106 | }; | |
| 107 | ||
| 108 | template <class _Rp, class _Class, class... _Param> | |
| 109 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&, true, false> { | |
| 110 | typedef _Class& _ClassType; | |
| 111 | typedef _Rp _ReturnType; | |
| 112 | typedef _Rp(_FnType)(_Param..., ...); | |
| 113 | }; | |
| 114 | ||
| 115 | template <class _Rp, class _Class, class... _Param> | |
| 116 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> { | |
| 117 | typedef _Class const& _ClassType; | |
| 118 | typedef _Rp _ReturnType; | |
| 119 | typedef _Rp(_FnType)(_Param...); | |
| 120 | }; | |
| 121 | ||
| 122 | template <class _Rp, class _Class, class... _Param> | |
| 123 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> { | |
| 124 | typedef _Class const& _ClassType; | |
| 125 | typedef _Rp _ReturnType; | |
| 126 | typedef _Rp(_FnType)(_Param..., ...); | |
| 127 | }; | |
| 128 | ||
| 129 | template <class _Rp, class _Class, class... _Param> | |
| 130 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> { | |
| 131 | typedef _Class volatile& _ClassType; | |
| 132 | typedef _Rp _ReturnType; | |
| 133 | typedef _Rp(_FnType)(_Param...); | |
| 134 | }; | |
| 135 | ||
| 136 | template <class _Rp, class _Class, class... _Param> | |
| 137 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> { | |
| 138 | typedef _Class volatile& _ClassType; | |
| 139 | typedef _Rp _ReturnType; | |
| 140 | typedef _Rp(_FnType)(_Param..., ...); | |
| 141 | }; | |
| 142 | ||
| 143 | template <class _Rp, class _Class, class... _Param> | |
| 144 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> { | |
| 145 | typedef _Class const volatile& _ClassType; | |
| 146 | typedef _Rp _ReturnType; | |
| 147 | typedef _Rp(_FnType)(_Param...); | |
| 148 | }; | |
| 149 | ||
| 150 | template <class _Rp, class _Class, class... _Param> | |
| 151 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> { | |
| 152 | typedef _Class const volatile& _ClassType; | |
| 153 | typedef _Rp _ReturnType; | |
| 154 | typedef _Rp(_FnType)(_Param..., ...); | |
| 155 | }; | |
| 156 | ||
| 157 | template <class _Rp, class _Class, class... _Param> | |
| 158 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...)&&, true, false> { | |
| 159 | typedef _Class&& _ClassType; | |
| 160 | typedef _Rp _ReturnType; | |
| 161 | typedef _Rp(_FnType)(_Param...); | |
| 162 | }; | |
| 163 | ||
| 164 | template <class _Rp, class _Class, class... _Param> | |
| 165 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...)&&, true, false> { | |
| 166 | typedef _Class&& _ClassType; | |
| 167 | typedef _Rp _ReturnType; | |
| 168 | typedef _Rp(_FnType)(_Param..., ...); | |
| 169 | }; | |
| 170 | ||
| 171 | template <class _Rp, class _Class, class... _Param> | |
| 172 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> { | |
| 173 | typedef _Class const&& _ClassType; | |
| 174 | typedef _Rp _ReturnType; | |
| 175 | typedef _Rp(_FnType)(_Param...); | |
| 176 | }; | |
| 177 | ||
| 178 | template <class _Rp, class _Class, class... _Param> | |
| 179 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> { | |
| 180 | typedef _Class const&& _ClassType; | |
| 181 | typedef _Rp _ReturnType; | |
| 182 | typedef _Rp(_FnType)(_Param..., ...); | |
| 183 | }; | |
| 184 | ||
| 185 | template <class _Rp, class _Class, class... _Param> | |
| 186 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> { | |
| 187 | typedef _Class volatile&& _ClassType; | |
| 188 | typedef _Rp _ReturnType; | |
| 189 | typedef _Rp(_FnType)(_Param...); | |
| 190 | }; | |
| 191 | ||
| 192 | template <class _Rp, class _Class, class... _Param> | |
| 193 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> { | |
| 194 | typedef _Class volatile&& _ClassType; | |
| 195 | typedef _Rp _ReturnType; | |
| 196 | typedef _Rp(_FnType)(_Param..., ...); | |
| 197 | }; | |
| 198 | ||
| 199 | template <class _Rp, class _Class, class... _Param> | |
| 200 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> { | |
| 201 | typedef _Class const volatile&& _ClassType; | |
| 202 | typedef _Rp _ReturnType; | |
| 203 | typedef _Rp(_FnType)(_Param...); | |
| 204 | }; | |
| 205 | ||
| 206 | template <class _Rp, class _Class, class... _Param> | |
| 207 | struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> { | |
| 208 | typedef _Class const volatile&& _ClassType; | |
| 209 | typedef _Rp _ReturnType; | |
| 210 | typedef _Rp(_FnType)(_Param..., ...); | |
| 211 | }; | |
| 212 | ||
| 213 | template <class _Rp, class _Class> | |
| 214 | struct __member_pointer_traits_imp<_Rp _Class::*, false, true> { | |
| 215 | typedef _Class _ClassType; | |
| 216 | typedef _Rp _ReturnType; | |
| 217 | }; | |
| 218 | ||
| 219 | template <class _MP> | |
| 220 | struct __member_pointer_traits | |
| 221 | : public __member_pointer_traits_imp<__remove_cv_t<_MP>, | |
| 222 | is_member_function_pointer<_MP>::value, | |
| 223 | is_member_object_pointer<_MP>::value> { | |
| 224 | // typedef ... _ClassType; | |
| 225 | // typedef ... _ReturnType; | |
| 226 | // typedef ... _FnType; | |
| 227 | }; | |
| 228 | ||
| 229 | template <class _DecayedFp> | |
| 230 | struct __member_pointer_class_type {}; | |
| 231 | ||
| 232 | template <class _Ret, class _ClassType> | |
| 233 | struct __member_pointer_class_type<_Ret _ClassType::*> { | |
| 234 | typedef _ClassType type; | |
| 235 | }; | |
| 236 | ||
| 237 | template <class _Fp, | |
| 238 | class _A0, | |
| 239 | class _DecayFp = __decay_t<_Fp>, | |
| 240 | class _DecayA0 = __decay_t<_A0>, | |
| 241 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 242 | using __enable_if_bullet1 = | |
| 243 | typename enable_if<is_member_function_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type; | |
| 244 | ||
| 245 | template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> > | |
| 246 | using __enable_if_bullet2 = | |
| 247 | typename enable_if<is_member_function_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type; | |
| 248 | ||
| 249 | template <class _Fp, | |
| 250 | class _A0, | |
| 251 | class _DecayFp = __decay_t<_Fp>, | |
| 252 | class _DecayA0 = __decay_t<_A0>, | |
| 253 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 254 | using __enable_if_bullet3 = | |
| 255 | typename enable_if<is_member_function_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value && | |
| 256 | !__is_reference_wrapper<_DecayA0>::value >::type; | |
| 257 | ||
| 258 | template <class _Fp, | |
| 259 | class _A0, | |
| 260 | class _DecayFp = __decay_t<_Fp>, | |
| 261 | class _DecayA0 = __decay_t<_A0>, | |
| 262 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 263 | using __enable_if_bullet4 = | |
| 264 | typename enable_if<is_member_object_pointer<_DecayFp>::value && is_base_of<_ClassT, _DecayA0>::value >::type; | |
| 265 | ||
| 266 | template <class _Fp, class _A0, class _DecayFp = __decay_t<_Fp>, class _DecayA0 = __decay_t<_A0> > | |
| 267 | using __enable_if_bullet5 = | |
| 268 | typename enable_if<is_member_object_pointer<_DecayFp>::value && __is_reference_wrapper<_DecayA0>::value >::type; | |
| 269 | ||
| 270 | template <class _Fp, | |
| 271 | class _A0, | |
| 272 | class _DecayFp = __decay_t<_Fp>, | |
| 273 | class _DecayA0 = __decay_t<_A0>, | |
| 274 | class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> | |
| 275 | using __enable_if_bullet6 = | |
| 276 | typename enable_if<is_member_object_pointer<_DecayFp>::value && !is_base_of<_ClassT, _DecayA0>::value && | |
| 277 | !__is_reference_wrapper<_DecayA0>::value >::type; | |
| 278 | ||
| 279 | // __invoke forward declarations | |
| 280 | ||
| 281 | // fall back - none of the bullets | |
| 282 | ||
| 283 | template <class... _Args> | |
| 284 | __nat __invoke(__any, _Args&&... __args); | |
| 285 | ||
| 286 | // bullets 1, 2 and 3 | |
| 287 | ||
| 288 | // clang-format off | |
| 289 | template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet1<_Fp, _A0> > | |
| 290 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 291 | decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 292 | __invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) | |
| 293 | _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) | |
| 294 | { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } | |
| 295 | ||
| 296 | template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet2<_Fp, _A0> > | |
| 297 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 298 | decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 299 | __invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) | |
| 300 | _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) | |
| 301 | { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } | |
| 302 | ||
| 303 | template <class _Fp, class _A0, class... _Args, class = __enable_if_bullet3<_Fp, _A0> > | |
| 304 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 305 | decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) | |
| 306 | __invoke(_Fp&& __f, _A0&& __a0, _Args&&... __args) | |
| 307 | _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) | |
| 308 | { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } | |
| 309 | ||
| 310 | // bullets 4, 5 and 6 | |
| 311 | ||
| 312 | template <class _Fp, class _A0, class = __enable_if_bullet4<_Fp, _A0> > | |
| 313 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 314 | decltype(std::declval<_A0>().*std::declval<_Fp>()) | |
| 315 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 316 | _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) | |
| 317 | { return static_cast<_A0&&>(__a0).*__f; } | |
| 318 | ||
| 319 | template <class _Fp, class _A0, class = __enable_if_bullet5<_Fp, _A0> > | |
| 320 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 321 | decltype(std::declval<_A0>().get().*std::declval<_Fp>()) | |
| 322 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 323 | _NOEXCEPT_(noexcept(__a0.get().*__f)) | |
| 324 | { return __a0.get().*__f; } | |
| 325 | ||
| 326 | template <class _Fp, class _A0, class = __enable_if_bullet6<_Fp, _A0> > | |
| 327 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 328 | decltype((*std::declval<_A0>()).*std::declval<_Fp>()) | |
| 329 | __invoke(_Fp&& __f, _A0&& __a0) | |
| 330 | _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) | |
| 331 | { return (*static_cast<_A0&&>(__a0)).*__f; } | |
| 332 | ||
| 333 | // bullet 7 | |
| 334 | ||
| 335 | template <class _Fp, class... _Args> | |
| 336 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 337 | decltype(std::declval<_Fp>()(std::declval<_Args>()...)) | |
| 338 | __invoke(_Fp&& __f, _Args&&... __args) | |
| 339 | _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) | |
| 340 | { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } | |
| 341 | // clang-format on | |
| 342 | ||
| 343 | // __invokable | |
| 344 | template <class _Ret, class _Fp, class... _Args> | |
| 345 | struct __invokable_r { | |
| 346 | template <class _XFp, class... _XArgs> | |
| 347 | static decltype(std::__invoke(std::declval<_XFp>(), std::declval<_XArgs>()...)) __try_call(int); | |
| 348 | template <class _XFp, class... _XArgs> | |
| 349 | static __nat __try_call(...); | |
| 350 | ||
| 351 | // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, | |
| 352 | // or incomplete array types as required by the standard. | |
| 353 | using _Result = decltype(__try_call<_Fp, _Args...>(0)); | |
| 354 | ||
| 355 | using type = __conditional_t<_IsNotSame<_Result, __nat>::value, | |
| 356 | __conditional_t<is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >, | |
| 357 | false_type>; | |
| 358 | static const bool value = type::value; | |
| 359 | }; | |
| 360 | template <class _Fp, class... _Args> | |
| 361 | using __invokable = __invokable_r<void, _Fp, _Args...>; | |
| 362 | ||
| 363 | template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class... _Args> | |
| 364 | struct __nothrow_invokable_r_imp { | |
| 365 | static const bool value = false; | |
| 366 | }; | |
| 367 | ||
| 368 | template <class _Ret, class _Fp, class... _Args> | |
| 369 | struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> { | |
| 370 | typedef __nothrow_invokable_r_imp _ThisT; | |
| 371 | ||
| 372 | template <class _Tp> | |
| 373 | static void __test_noexcept(_Tp) _NOEXCEPT; | |
| 374 | ||
| 375 | #ifdef _LIBCPP_CXX03_LANG | |
| 376 | static const bool value = false; | |
| 377 | #else | |
| 378 | static const bool value = | |
| 379 | noexcept(_ThisT::__test_noexcept<_Ret>(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...))); | |
| 380 | #endif | |
| 381 | }; | |
| 382 | ||
| 383 | template <class _Ret, class _Fp, class... _Args> | |
| 384 | struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> { | |
| 385 | #ifdef _LIBCPP_CXX03_LANG | |
| 386 | static const bool value = false; | |
| 387 | #else | |
| 388 | static const bool value = noexcept(_VSTD::__invoke(std::declval<_Fp>(), std::declval<_Args>()...)); | |
| 389 | #endif | |
| 390 | }; | |
| 391 | ||
| 392 | template <class _Ret, class _Fp, class... _Args> | |
| 393 | using __nothrow_invokable_r = | |
| 394 | __nothrow_invokable_r_imp<__invokable_r<_Ret, _Fp, _Args...>::value, is_void<_Ret>::value, _Ret, _Fp, _Args...>; | |
| 395 | ||
| 396 | template <class _Fp, class... _Args> | |
| 397 | using __nothrow_invokable = __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; | |
| 398 | ||
| 399 | template <class _Fp, class... _Args> | |
| 400 | struct __invoke_of | |
| 401 | : public enable_if<__invokable<_Fp, _Args...>::value, typename __invokable_r<void, _Fp, _Args...>::_Result> {}; | |
| 402 | ||
| 403 | template <class _Ret, bool = is_void<_Ret>::value> | |
| 404 | struct __invoke_void_return_wrapper { | |
| 405 | template <class... _Args> | |
| 406 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static _Ret __call(_Args&&... __args) { | |
| 407 | return std::__invoke(std::forward<_Args>(__args)...); | |
| 408 | } | |
| 409 | }; | |
| 410 | ||
| 411 | template <class _Ret> | |
| 412 | struct __invoke_void_return_wrapper<_Ret, true> { | |
| 413 | template <class... _Args> | |
| 414 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static void __call(_Args&&... __args) { | |
| 415 | std::__invoke(std::forward<_Args>(__args)...); | |
| 416 | } | |
| 417 | }; | |
| 418 | ||
| 419 | #if _LIBCPP_STD_VER >= 17 | |
| 420 | ||
| 421 | // is_invocable | |
| 422 | ||
| 423 | template <class _Fn, class... _Args> | |
| 424 | struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant<bool, __invokable<_Fn, _Args...>::value> {}; | |
| 425 | ||
| 426 | template <class _Ret, class _Fn, class... _Args> | |
| 427 | struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {}; | |
| 428 | ||
| 429 | template <class _Fn, class... _Args> | |
| 430 | inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; | |
| 431 | ||
| 432 | template <class _Ret, class _Fn, class... _Args> | |
| 433 | inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; | |
| 434 | ||
| 435 | // is_nothrow_invocable | |
| 436 | ||
| 437 | template <class _Fn, class... _Args> | |
| 438 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> { | |
| 439 | }; | |
| 440 | ||
| 441 | template <class _Ret, class _Fn, class... _Args> | |
| 442 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r | |
| 443 | : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {}; | |
| 444 | ||
| 445 | template <class _Fn, class... _Args> | |
| 446 | inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; | |
| 447 | ||
| 448 | template <class _Ret, class _Fn, class... _Args> | |
| 449 | inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; | |
| 450 | ||
| 451 | template <class _Fn, class... _Args> | |
| 452 | struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {}; | |
| 453 | ||
| 454 | template <class _Fn, class... _Args> | |
| 455 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; | |
| 456 | ||
| 457 | #endif // _LIBCPP_STD_VER >= 17 | |
| 458 | ||
| 459 | _LIBCPP_END_NAMESPACE_STD | |
| 460 | ||
| 461 | #endif // _LIBCPP___TYPE_TRAITS_INVOKE_H |
lib/libcxx/include/__type_traits/is_abstract.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_abstract | |
| 22 | : public integral_constant<bool, __is_abstract(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_abstract : public integral_constant<bool, __is_abstract(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool is_abstract_v = __is_abstract(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_aggregate.h+4-4| ... | ... | @@ -18,15 +18,15 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if _LIBCPP_STD_VER > 14 | |
| 21 | #if _LIBCPP_STD_VER >= 17 | |
| 22 | 22 | |
| 23 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS | |
| 24 | is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {}; | |
| 23 | template <class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_aggregate : public integral_constant<bool, __is_aggregate(_Tp)> {}; | |
| 25 | 25 | |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | inline constexpr bool is_aggregate_v = __is_aggregate(_Tp); |
| 28 | 28 | |
| 29 | #endif // _LIBCPP_STD_VER > 14 | |
| 29 | #endif // _LIBCPP_STD_VER >= 17 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 32 |
lib/libcxx/include/__type_traits/is_allocator.h+4-6| ... | ... | @@ -21,15 +21,13 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | template<typename _Alloc, typename = void, typename = void> | |
| 24 | template <typename _Alloc, typename = void, typename = void> | |
| 25 | 25 | struct __is_allocator : false_type {}; |
| 26 | 26 | |
| 27 | template<typename _Alloc> | |
| 27 | template <typename _Alloc> | |
| 28 | 28 | struct __is_allocator<_Alloc, |
| 29 | __void_t<typename _Alloc::value_type>, | |
| 30 | __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))> | |
| 31 | > | |
| 32 | : true_type {}; | |
| 29 | __void_t<typename _Alloc::value_type>, | |
| 30 | __void_t<decltype(std::declval<_Alloc&>().allocate(size_t(0)))> > : true_type {}; | |
| 33 | 31 | |
| 34 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 35 | 33 |
lib/libcxx/include/__type_traits/is_always_bitcastable.h+43-40| ... | ... | @@ -32,49 +32,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | template <class _From, class _To> |
| 33 | 33 | struct __is_always_bitcastable { |
| 34 | 34 | using _UnqualFrom = __remove_cv_t<_From>; |
| 35 | using _UnqualTo = __remove_cv_t<_To>; | |
| 35 | using _UnqualTo = __remove_cv_t<_To>; | |
| 36 | 36 | |
| 37 | // clang-format off | |
| 37 | 38 | static const bool value = |
| 38 | // First, the simple case -- `From` and `To` are the same object type. | |
| 39 | (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) || | |
| 39 | // First, the simple case -- `From` and `To` are the same object type. | |
| 40 | (is_same<_UnqualFrom, _UnqualTo>::value && is_trivially_copyable<_UnqualFrom>::value) || | |
| 40 | 41 | |
| 41 | // Beyond the simple case, we say that one type is "always bit-castable" to another if: | |
| 42 | // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has | |
| 43 | // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of | |
| 44 | // values of `From`); | |
| 45 | // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed | |
| 46 | // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed | |
| 47 | // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be produced | |
| 48 | // by the built-in assignment (if it were defined for the two types, to which there are minor exceptions, e.g. | |
| 49 | // built-in arrays). | |
| 50 | // | |
| 51 | // In practice, that means: | |
| 52 | // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and | |
| 53 | // unsigned... | |
| 54 | // - as well as arrays of such types... | |
| 55 | // - ...that have the same size. | |
| 56 | // | |
| 57 | // Other trivially-copyable types can't be validly bit-cast outside of their own type: | |
| 58 | // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails #1); | |
| 59 | // - integral types and floating-point types use different representations, so for example bit-casting an integral | |
| 60 | // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0` | |
| 61 | // (fails #2); | |
| 62 | // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean | |
| 63 | // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2). | |
| 64 | // Bit-casting from a boolean into an integer, however, is valid; | |
| 65 | // - enumeration types may have different ranges of possible values (fails #1); | |
| 66 | // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent | |
| 67 | // addresses, and the conversion results are explicitly unspecified for types with different alignments | |
| 68 | // (fails #1); | |
| 69 | // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of | |
| 70 | // the other (fails #1); | |
| 71 | // - there is no need to consider `nullptr_t` for practical purposes. | |
| 72 | ( | |
| 73 | sizeof(_From) == sizeof(_To) && | |
| 74 | is_integral<_From>::value && | |
| 75 | is_integral<_To>::value && | |
| 76 | !is_same<_UnqualTo, bool>::value | |
| 77 | ); | |
| 42 | // Beyond the simple case, we say that one type is "always bit-castable" to another if: | |
| 43 | // - (1) `From` and `To` have the same value representation, and in addition every possible value of `From` has | |
| 44 | // a corresponding value in the `To` type (in other words, the set of values of `To` is a superset of the set of | |
| 45 | // values of `From`); | |
| 46 | // - (2) When the corresponding values are not the same value (as, for example, between an unsigned and a signed | |
| 47 | // integer, where a large positive value of the unsigned integer corresponds to a negative value in the signed | |
| 48 | // integer type), the value of `To` that results from a bitwise copy of `From` is the same what would be | |
| 49 | // produced by the built-in assignment (if it were defined for the two types, to which there are minor | |
| 50 | // exceptions, e.g. built-in arrays). | |
| 51 | // | |
| 52 | // In practice, that means: | |
| 53 | // - all integral types (except `bool`, see below) -- that is, character types and `int` types, both signed and | |
| 54 | // unsigned... | |
| 55 | // - as well as arrays of such types... | |
| 56 | // - ...that have the same size. | |
| 57 | // | |
| 58 | // Other trivially-copyable types can't be validly bit-cast outside of their own type: | |
| 59 | // - floating-point types normally have different sizes and thus aren't bit-castable between each other (fails | |
| 60 | // #1); | |
| 61 | // - integral types and floating-point types use different representations, so for example bit-casting an integral | |
| 62 | // `1` to `float` results in a very small less-than-one value, unlike built-in assignment that produces `1.0` | |
| 63 | // (fails #2); | |
| 64 | // - booleans normally use only a single bit of their object representation; bit-casting an integer to a boolean | |
| 65 | // will result in a boolean object with an incorrect representation, which is undefined behavior (fails #2). | |
| 66 | // Bit-casting from a boolean into an integer, however, is valid; | |
| 67 | // - enumeration types may have different ranges of possible values (fails #1); | |
| 68 | // - for pointers, it is not guaranteed that pointers to different types use the same set of values to represent | |
| 69 | // addresses, and the conversion results are explicitly unspecified for types with different alignments | |
| 70 | // (fails #1); | |
| 71 | // - for structs and unions it is impossible to determine whether the set of values of one of them is a subset of | |
| 72 | // the other (fails #1); | |
| 73 | // - there is no need to consider `nullptr_t` for practical purposes. | |
| 74 | ( | |
| 75 | sizeof(_From) == sizeof(_To) && | |
| 76 | is_integral<_From>::value && | |
| 77 | is_integral<_To>::value && | |
| 78 | !is_same<_UnqualTo, bool>::value | |
| 79 | ); | |
| 80 | // clang-format on | |
| 78 | 81 | }; |
| 79 | 82 | |
| 80 | 83 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/is_arithmetic.h+4-4| ... | ... | @@ -20,11 +20,11 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_arithmetic | |
| 24 | : public integral_constant<bool, is_integral<_Tp>::value || | |
| 25 | is_floating_point<_Tp>::value> {}; | |
| 23 | template <class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_arithmetic | |
| 25 | : public integral_constant<bool, is_integral<_Tp>::value || is_floating_point<_Tp>::value> {}; | |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 27 | #if _LIBCPP_STD_VER >= 17 | |
| 28 | 28 | template <class _Tp> |
| 29 | 29 | inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; |
| 30 | 30 | #endif |
lib/libcxx/include/__type_traits/is_array.h+11-11| ... | ... | @@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | #if __has_builtin(__is_array) && 0 |
| 25 | 25 | |
| 26 | 26 | template <class _Tp> |
| 27 | struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> { }; | |
| 27 | struct _LIBCPP_TEMPLATE_VIS is_array : _BoolConstant<__is_array(_Tp)> {}; | |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 29 | # if _LIBCPP_STD_VER >= 17 | |
| 30 | 30 | template <class _Tp> |
| 31 | 31 | inline constexpr bool is_array_v = __is_array(_Tp); |
| 32 | #endif | |
| 32 | # endif | |
| 33 | 33 | |
| 34 | 34 | #else |
| 35 | 35 | |
| 36 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array | |
| 37 | : public false_type {}; | |
| 38 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> | |
| 39 | : public true_type {}; | |
| 40 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> | |
| 41 | : public true_type {}; | |
| 36 | template <class _Tp> | |
| 37 | struct _LIBCPP_TEMPLATE_VIS is_array : public false_type {}; | |
| 38 | template <class _Tp> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[]> : public true_type {}; | |
| 40 | template <class _Tp, size_t _Np> | |
| 41 | struct _LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> : public true_type {}; | |
| 42 | 42 | |
| 43 | #if _LIBCPP_STD_VER > 14 | |
| 43 | # if _LIBCPP_STD_VER >= 17 | |
| 44 | 44 | template <class _Tp> |
| 45 | 45 | inline constexpr bool is_array_v = is_array<_Tp>::value; |
| 46 | #endif | |
| 46 | # endif | |
| 47 | 47 | |
| 48 | 48 | #endif // __has_builtin(__is_array) |
| 49 | 49 |
lib/libcxx/include/__type_traits/is_assignable.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template<class _Tp, class _Up> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> { }; | |
| 21 | template <class _Tp, class _Up> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_assignable : _BoolConstant<__is_assignable(_Tp, _Up)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp, class _Arg> |
| 26 | 26 | inline constexpr bool is_assignable_v = __is_assignable(_Tp, _Arg); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_base_of.h+2-3| ... | ... | @@ -19,10 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Bp, class _Dp> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_base_of | |
| 23 | : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {}; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_base_of : public integral_constant<bool, __is_base_of(_Bp, _Dp)> {}; | |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | template <class _Bp, class _Dp> |
| 27 | 26 | inline constexpr bool is_base_of_v = __is_base_of(_Bp, _Dp); |
| 28 | 27 | #endif |
lib/libcxx/include/__type_traits/is_bounded_array.h+10-7| ... | ... | @@ -19,17 +19,20 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {}; | |
| 23 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {}; | |
| 22 | template <class> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array : false_type {}; | |
| 24 | template <class _Tp, size_t _Np> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS __libcpp_is_bounded_array<_Tp[_Np]> : true_type {}; | |
| 24 | 26 | |
| 25 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 26 | 28 | |
| 27 | template <class> struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {}; | |
| 28 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {}; | |
| 29 | template <class> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS is_bounded_array : false_type {}; | |
| 31 | template <class _Tp, size_t _Np> | |
| 32 | struct _LIBCPP_TEMPLATE_VIS is_bounded_array<_Tp[_Np]> : true_type {}; | |
| 29 | 33 | |
| 30 | 34 | template <class _Tp> |
| 31 | inline constexpr | |
| 32 | bool is_bounded_array_v = is_bounded_array<_Tp>::value; | |
| 35 | inline constexpr bool is_bounded_array_v = is_bounded_array<_Tp>::value; | |
| 33 | 36 | |
| 34 | 37 | #endif |
| 35 | 38 |
lib/libcxx/include/__type_traits/is_callable.h+3-3| ... | ... | @@ -19,12 +19,12 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template<class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))> | |
| 22 | template <class _Func, class... _Args, class = decltype(std::declval<_Func>()(std::declval<_Args>()...))> | |
| 23 | 23 | true_type __is_callable_helper(int); |
| 24 | template<class...> | |
| 24 | template <class...> | |
| 25 | 25 | false_type __is_callable_helper(...); |
| 26 | 26 | |
| 27 | template<class _Func, class... _Args> | |
| 27 | template <class _Func, class... _Args> | |
| 28 | 28 | struct __is_callable : decltype(std::__is_callable_helper<_Func, _Args...>(0)) {}; |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/is_class.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_class | |
| 22 | : public integral_constant<bool, __is_class(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_class : public integral_constant<bool, __is_class(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool is_class_v = __is_class(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_compound.h+8-8| ... | ... | @@ -21,23 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if __has_builtin(__is_compound) |
| 23 | 23 | |
| 24 | template<class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> { }; | |
| 24 | template <class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_compound : _BoolConstant<__is_compound(_Tp)> {}; | |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 27 | # if _LIBCPP_STD_VER >= 17 | |
| 28 | 28 | template <class _Tp> |
| 29 | 29 | inline constexpr bool is_compound_v = __is_compound(_Tp); |
| 30 | #endif | |
| 30 | # endif | |
| 31 | 31 | |
| 32 | 32 | #else // __has_builtin(__is_compound) |
| 33 | 33 | |
| 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_compound | |
| 35 | : public integral_constant<bool, !is_fundamental<_Tp>::value> {}; | |
| 34 | template <class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS is_compound : public integral_constant<bool, !is_fundamental<_Tp>::value> {}; | |
| 36 | 36 | |
| 37 | #if _LIBCPP_STD_VER > 14 | |
| 37 | # if _LIBCPP_STD_VER >= 17 | |
| 38 | 38 | template <class _Tp> |
| 39 | 39 | inline constexpr bool is_compound_v = is_compound<_Tp>::value; |
| 40 | #endif | |
| 40 | # endif | |
| 41 | 41 | |
| 42 | 42 | #endif // __has_builtin(__is_compound) |
| 43 | 43 |
lib/libcxx/include/__type_traits/is_const.h+9-7| ... | ... | @@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | #if __has_builtin(__is_const) |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> { }; | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_const : _BoolConstant<__is_const(_Tp)> {}; | |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | # if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | inline constexpr bool is_const_v = __is_const(_Tp); |
| 29 | #endif | |
| 29 | # endif | |
| 30 | 30 | |
| 31 | 31 | #else |
| 32 | 32 | |
| 33 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {}; | |
| 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; | |
| 33 | template <class _Tp> | |
| 34 | struct _LIBCPP_TEMPLATE_VIS is_const : public false_type {}; | |
| 35 | template <class _Tp> | |
| 36 | struct _LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; | |
| 35 | 37 | |
| 36 | #if _LIBCPP_STD_VER > 14 | |
| 38 | # if _LIBCPP_STD_VER >= 17 | |
| 37 | 39 | template <class _Tp> |
| 38 | 40 | inline constexpr bool is_const_v = is_const<_Tp>::value; |
| 39 | #endif | |
| 41 | # endif | |
| 40 | 42 | |
| 41 | 43 | #endif // __has_builtin(__is_const) |
| 42 | 44 |
lib/libcxx/include/__type_traits/is_constant_evaluated.h+5-5| ... | ... | @@ -17,15 +17,15 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | #if _LIBCPP_STD_VER > 17 | |
| 21 | _LIBCPP_INLINE_VISIBILITY | |
| 22 | inline constexpr bool is_constant_evaluated() noexcept { | |
| 20 | #if _LIBCPP_STD_VER >= 20 | |
| 21 | _LIBCPP_INLINE_VISIBILITY inline constexpr bool is_constant_evaluated() noexcept { | |
| 23 | 22 | return __builtin_is_constant_evaluated(); |
| 24 | 23 | } |
| 25 | 24 | #endif |
| 26 | 25 | |
| 27 | _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR | |
| 28 | bool __libcpp_is_constant_evaluated() _NOEXCEPT { return __builtin_is_constant_evaluated(); } | |
| 26 | _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR bool __libcpp_is_constant_evaluated() _NOEXCEPT { | |
| 27 | return __builtin_is_constant_evaluated(); | |
| 28 | } | |
| 29 | 29 | |
| 30 | 30 | _LIBCPP_END_NAMESPACE_STD |
| 31 | 31 |
lib/libcxx/include/__type_traits/is_constructible.h+4-6| ... | ... | @@ -18,13 +18,11 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp, class ..._Args> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_constructible | |
| 23 | : public integral_constant<bool, __is_constructible(_Tp, _Args...)> | |
| 24 | { }; | |
| 21 | template <class _Tp, class... _Args> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_constructible : public integral_constant<bool, __is_constructible(_Tp, _Args...)> {}; | |
| 25 | 23 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 27 | template <class _Tp, class ..._Args> | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | template <class _Tp, class... _Args> | |
| 28 | 26 | inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); |
| 29 | 27 | #endif |
| 30 | 28 |
lib/libcxx/include/__type_traits/is_convertible.h+61-55| ... | ... | @@ -24,81 +24,87 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
| 27 | #if __has_builtin(__is_convertible) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
| 28 | 28 | |
| 29 | template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible | |
| 30 | : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {}; | |
| 29 | template <class _T1, class _T2> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible(_T1, _T2)> {}; | |
| 31 | 31 | |
| 32 | #else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
| 32 | #elif __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
| 33 | 33 | |
| 34 | namespace __is_convertible_imp | |
| 35 | { | |
| 36 | template <class _Tp> void __test_convert(_Tp); | |
| 34 | template <class _T1, class _T2> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS is_convertible : public integral_constant<bool, __is_convertible_to(_T1, _T2)> {}; | |
| 36 | ||
| 37 | // TODO: Remove this fallback when GCC < 13 support is no longer required. | |
| 38 | // GCC 13 has the __is_convertible built-in. | |
| 39 | #else // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) | |
| 40 | ||
| 41 | namespace __is_convertible_imp { | |
| 42 | template <class _Tp> | |
| 43 | void __test_convert(_Tp); | |
| 37 | 44 | |
| 38 | 45 | template <class _From, class _To, class = void> |
| 39 | 46 | struct __is_convertible_test : public false_type {}; |
| 40 | 47 | |
| 41 | 48 | template <class _From, class _To> |
| 42 | struct __is_convertible_test<_From, _To, | |
| 43 | decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> : public true_type | |
| 44 | {}; | |
| 45 | ||
| 46 | template <class _Tp, bool _IsArray = is_array<_Tp>::value, | |
| 47 | bool _IsFunction = is_function<_Tp>::value, | |
| 48 | bool _IsVoid = is_void<_Tp>::value> | |
| 49 | struct __is_array_function_or_void {enum {value = 0};}; | |
| 50 | template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};}; | |
| 51 | template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};}; | |
| 52 | template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};}; | |
| 53 | } | |
| 49 | struct __is_convertible_test<_From, _To, decltype(__is_convertible_imp::__test_convert<_To>(std::declval<_From>()))> | |
| 50 | : public true_type {}; | |
| 51 | ||
| 52 | // clang-format off | |
| 53 | template <class _Tp, | |
| 54 | bool _IsArray = is_array<_Tp>::value, | |
| 55 | bool _IsFunction = is_function<_Tp>::value, | |
| 56 | bool _IsVoid = is_void<_Tp>::value> | |
| 57 | struct __is_array_function_or_void { enum { value = 0 }; }; | |
| 58 | template <class _Tp> struct __is_array_function_or_void<_Tp, true, false, false> { enum { value = 1 }; }; | |
| 59 | template <class _Tp> struct __is_array_function_or_void<_Tp, false, true, false> { enum { value = 2 }; }; | |
| 60 | template <class _Tp> struct __is_array_function_or_void<_Tp, false, false, true> { enum { value = 3 }; }; | |
| 61 | // clang-format on | |
| 62 | } // namespace __is_convertible_imp | |
| 54 | 63 | |
| 55 | 64 | template <class _Tp, |
| 56 | unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value> | |
| 57 | struct __is_convertible_check | |
| 58 | { | |
| 59 | static const size_t __v = 0; | |
| 65 | unsigned = __is_convertible_imp::__is_array_function_or_void<__libcpp_remove_reference_t<_Tp> >::value> | |
| 66 | struct __is_convertible_check { | |
| 67 | static const size_t __v = 0; | |
| 60 | 68 | }; |
| 61 | 69 | |
| 62 | 70 | template <class _Tp> |
| 63 | struct __is_convertible_check<_Tp, 0> | |
| 64 | { | |
| 65 | static const size_t __v = sizeof(_Tp); | |
| 71 | struct __is_convertible_check<_Tp, 0> { | |
| 72 | static const size_t __v = sizeof(_Tp); | |
| 66 | 73 | }; |
| 67 | 74 | |
| 68 | template <class _T1, class _T2, | |
| 69 | unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value, | |
| 70 | unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value> | |
| 75 | template <class _T1, | |
| 76 | class _T2, | |
| 77 | unsigned _T1_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T1>::value, | |
| 78 | unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value> | |
| 71 | 79 | struct __is_convertible |
| 72 | : public integral_constant<bool, | |
| 73 | __is_convertible_imp::__is_convertible_test<_T1, _T2>::value | |
| 74 | > | |
| 75 | {}; | |
| 76 | ||
| 77 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; | |
| 78 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; | |
| 79 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; | |
| 80 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type {}; | |
| 81 | ||
| 82 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type {}; | |
| 83 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type {}; | |
| 84 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type {}; | |
| 85 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type {}; | |
| 86 | ||
| 87 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type {}; | |
| 88 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type {}; | |
| 89 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type {}; | |
| 90 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type {}; | |
| 91 | ||
| 92 | template <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS is_convertible | |
| 93 | : public __is_convertible<_T1, _T2> | |
| 94 | { | |
| 95 | static const size_t __complete_check1 = __is_convertible_check<_T1>::__v; | |
| 96 | static const size_t __complete_check2 = __is_convertible_check<_T2>::__v; | |
| 80 | : public integral_constant<bool, __is_convertible_imp::__is_convertible_test<_T1, _T2>::value >{}; | |
| 81 | ||
| 82 | // clang-format off | |
| 83 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 1> : public false_type{}; | |
| 84 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 1> : public false_type{}; | |
| 85 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 1> : public false_type{}; | |
| 86 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 1> : public false_type{}; | |
| 87 | ||
| 88 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 2> : public false_type{}; | |
| 89 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 2> : public false_type{}; | |
| 90 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 2> : public false_type{}; | |
| 91 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 2> : public false_type{}; | |
| 92 | ||
| 93 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 0, 3> : public false_type{}; | |
| 94 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 1, 3> : public false_type{}; | |
| 95 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 2, 3> : public false_type{}; | |
| 96 | template <class _T1, class _T2> struct __is_convertible<_T1, _T2, 3, 3> : public true_type{}; | |
| 97 | // clang-format on | |
| 98 | ||
| 99 | template <class _T1, class _T2> | |
| 100 | struct _LIBCPP_TEMPLATE_VIS is_convertible : public __is_convertible<_T1, _T2> { | |
| 101 | static const size_t __complete_check1 = __is_convertible_check<_T1>::__v; | |
| 102 | static const size_t __complete_check2 = __is_convertible_check<_T2>::__v; | |
| 97 | 103 | }; |
| 98 | 104 | |
| 99 | 105 | #endif // __has_builtin(__is_convertible_to) && !defined(_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) |
| 100 | 106 | |
| 101 | #if _LIBCPP_STD_VER > 14 | |
| 107 | #if _LIBCPP_STD_VER >= 17 | |
| 102 | 108 | template <class _From, class _To> |
| 103 | 109 | inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; |
| 104 | 110 | #endif |
lib/libcxx/include/__type_traits/is_copy_assignable.h+2-3| ... | ... | @@ -24,10 +24,9 @@ template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_copy_assignable |
| 25 | 25 | : public integral_constant< |
| 26 | 26 | bool, |
| 27 | __is_assignable(__add_lvalue_reference_t<_Tp>, | |
| 28 | __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 27 | __is_assignable(__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 29 | 28 | |
| 30 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 31 | 30 | template <class _Tp> |
| 32 | 31 | inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; |
| 33 | 32 | #endif |
lib/libcxx/include/__type_traits/is_copy_constructible.h+3-4| ... | ... | @@ -22,11 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_copy_constructible |
| 25 | : public integral_constant< | |
| 26 | bool, | |
| 27 | __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 25 | : public integral_constant<bool, __is_constructible(_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type>)> { | |
| 26 | }; | |
| 28 | 27 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 28 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | 29 | template <class _Tp> |
| 31 | 30 | inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value; |
| 32 | 31 | #endif |
lib/libcxx/include/__type_traits/is_core_convertible.h+2-3| ... | ... | @@ -27,9 +27,8 @@ template <class _Tp, class _Up, class = void> |
| 27 | 27 | struct __is_core_convertible : public false_type {}; |
| 28 | 28 | |
| 29 | 29 | template <class _Tp, class _Up> |
| 30 | struct __is_core_convertible<_Tp, _Up, decltype( | |
| 31 | static_cast<void(*)(_Up)>(0) ( static_cast<_Tp(*)()>(0)() ) | |
| 32 | )> : public true_type {}; | |
| 30 | struct __is_core_convertible<_Tp, _Up, decltype(static_cast<void (*)(_Up)>(0)(static_cast<_Tp (*)()>(0)()))> | |
| 31 | : public true_type {}; | |
| 33 | 32 | |
| 34 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 35 | 34 |
lib/libcxx/include/__type_traits/is_default_constructible.h+2-4| ... | ... | @@ -19,11 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_default_constructible | |
| 23 | : public integral_constant<bool, __is_constructible(_Tp)> | |
| 24 | {}; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_default_constructible : public integral_constant<bool, __is_constructible(_Tp)> {}; | |
| 25 | 23 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 25 | template <class _Tp> |
| 28 | 26 | inline constexpr bool is_default_constructible_v = __is_constructible(_Tp); |
| 29 | 27 | #endif |
lib/libcxx/include/__type_traits/is_destructible.h+19-24| ... | ... | @@ -24,13 +24,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | 25 | #if __has_builtin(__is_destructible) |
| 26 | 26 | |
| 27 | template<class _Tp> | |
| 28 | struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> { }; | |
| 27 | template <class _Tp> | |
| 28 | struct _LIBCPP_TEMPLATE_VIS is_destructible : _BoolConstant<__is_destructible(_Tp)> {}; | |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 14 | |
| 30 | # if _LIBCPP_STD_VER >= 17 | |
| 31 | 31 | template <class _Tp> |
| 32 | 32 | inline constexpr bool is_destructible_v = __is_destructible(_Tp); |
| 33 | #endif | |
| 33 | # endif | |
| 34 | 34 | |
| 35 | 35 | #else // __has_builtin(__is_destructible) |
| 36 | 36 | |
| ... | ... | @@ -42,19 +42,19 @@ inline constexpr bool is_destructible_v = __is_destructible(_Tp); |
| 42 | 42 | // where _Up is remove_all_extents<_Tp>::type |
| 43 | 43 | |
| 44 | 44 | template <class> |
| 45 | struct __is_destructible_apply { typedef int type; }; | |
| 45 | struct __is_destructible_apply { | |
| 46 | typedef int type; | |
| 47 | }; | |
| 46 | 48 | |
| 47 | 49 | template <typename _Tp> |
| 48 | 50 | struct __is_destructor_wellformed { |
| 49 | template <typename _Tp1> | |
| 50 | static true_type __test ( | |
| 51 | typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type | |
| 52 | ); | |
| 51 | template <typename _Tp1> | |
| 52 | static true_type __test(typename __is_destructible_apply<decltype(std::declval<_Tp1&>().~_Tp1())>::type); | |
| 53 | 53 | |
| 54 | template <typename _Tp1> | |
| 55 | static false_type __test (...); | |
| 54 | template <typename _Tp1> | |
| 55 | static false_type __test(...); | |
| 56 | 56 | |
| 57 | static const bool value = decltype(__test<_Tp>(12))::value; | |
| 57 | static const bool value = decltype(__test<_Tp>(12))::value; | |
| 58 | 58 | }; |
| 59 | 59 | |
| 60 | 60 | template <class _Tp, bool> |
| ... | ... | @@ -62,12 +62,10 @@ struct __destructible_imp; |
| 62 | 62 | |
| 63 | 63 | template <class _Tp> |
| 64 | 64 | struct __destructible_imp<_Tp, false> |
| 65 | : public integral_constant<bool, | |
| 66 | __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {}; | |
| 65 | : public integral_constant<bool, __is_destructor_wellformed<__remove_all_extents_t<_Tp> >::value> {}; | |
| 67 | 66 | |
| 68 | 67 | template <class _Tp> |
| 69 | struct __destructible_imp<_Tp, true> | |
| 70 | : public true_type {}; | |
| 68 | struct __destructible_imp<_Tp, true> : public true_type {}; | |
| 71 | 69 | |
| 72 | 70 | template <class _Tp, bool> |
| 73 | 71 | struct __destructible_false; |
| ... | ... | @@ -79,21 +77,18 @@ template <class _Tp> |
| 79 | 77 | struct __destructible_false<_Tp, true> : public false_type {}; |
| 80 | 78 | |
| 81 | 79 | template <class _Tp> |
| 82 | struct is_destructible | |
| 83 | : public __destructible_false<_Tp, is_function<_Tp>::value> {}; | |
| 80 | struct is_destructible : public __destructible_false<_Tp, is_function<_Tp>::value> {}; | |
| 84 | 81 | |
| 85 | 82 | template <class _Tp> |
| 86 | struct is_destructible<_Tp[]> | |
| 87 | : public false_type {}; | |
| 83 | struct is_destructible<_Tp[]> : public false_type {}; | |
| 88 | 84 | |
| 89 | 85 | template <> |
| 90 | struct is_destructible<void> | |
| 91 | : public false_type {}; | |
| 86 | struct is_destructible<void> : public false_type {}; | |
| 92 | 87 | |
| 93 | #if _LIBCPP_STD_VER > 14 | |
| 88 | # if _LIBCPP_STD_VER >= 17 | |
| 94 | 89 | template <class _Tp> |
| 95 | 90 | inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; |
| 96 | #endif | |
| 91 | # endif | |
| 97 | 92 | |
| 98 | 93 | #endif // __has_builtin(__is_destructible) |
| 99 | 94 |
lib/libcxx/include/__type_traits/is_empty.h+2-3| ... | ... | @@ -19,10 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_empty | |
| 23 | : public integral_constant<bool, __is_empty(_Tp)> {}; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_empty : public integral_constant<bool, __is_empty(_Tp)> {}; | |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | template <class _Tp> |
| 27 | 26 | inline constexpr bool is_empty_v = __is_empty(_Tp); |
| 28 | 27 | #endif |
lib/libcxx/include/__type_traits/is_enum.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_enum | |
| 22 | : public integral_constant<bool, __is_enum(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_enum : public integral_constant<bool, __is_enum(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool is_enum_v = __is_enum(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_equality_comparable.h created+78| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/integral_constant.h> | |
| 14 | #include <__type_traits/is_integral.h> | |
| 15 | #include <__type_traits/is_same.h> | |
| 16 | #include <__type_traits/is_void.h> | |
| 17 | #include <__type_traits/remove_cv.h> | |
| 18 | #include <__type_traits/remove_cvref.h> | |
| 19 | #include <__type_traits/void_t.h> | |
| 20 | #include <__utility/declval.h> | |
| 21 | ||
| 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 23 | # pragma GCC system_header | |
| 24 | #endif | |
| 25 | ||
| 26 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 27 | ||
| 28 | template <class _Tp, class _Up, class = void> | |
| 29 | struct __is_equality_comparable : false_type {}; | |
| 30 | ||
| 31 | template <class _Tp, class _Up> | |
| 32 | struct __is_equality_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() == std::declval<_Up>())> > : true_type { | |
| 33 | }; | |
| 34 | ||
| 35 | // A type is_trivially_equality_comparable if the expression `a == b` is equivalent to `std::memcmp(&a, &b, sizeof(T))` | |
| 36 | // (with `a` and `b` being of type `T`). For the case where we compare two object of the same type, we can use | |
| 37 | // __is_trivially_equality_comparable. We have special-casing for pointers which point to the same type ignoring | |
| 38 | // cv-qualifications and comparing to void-pointers. | |
| 39 | // | |
| 40 | // The following types are not trivially equality comparable: | |
| 41 | // floating-point types: different bit-patterns can compare equal. (e.g 0.0 and -0.0) | |
| 42 | // enums: The user is allowed to specialize operator== for enums | |
| 43 | // pointers that don't have the same type (ignoring cv-qualifiers): pointers to virtual bases are equality comparable, | |
| 44 | // but don't have the same bit-pattern. An exception to this is comparing to a void-pointer. There the bit-pattern is | |
| 45 | // always compared. | |
| 46 | ||
| 47 | template <class _Tp, class _Up> | |
| 48 | struct __libcpp_is_trivially_equality_comparable_impl : false_type {}; | |
| 49 | ||
| 50 | template <class _Tp> | |
| 51 | struct __libcpp_is_trivially_equality_comparable_impl<_Tp, _Tp> | |
| 52 | #if __has_builtin(__is_trivially_equality_comparable) | |
| 53 | : integral_constant<bool, __is_trivially_equality_comparable(_Tp) && __is_equality_comparable<_Tp, _Tp>::value> { | |
| 54 | }; | |
| 55 | #else | |
| 56 | : is_integral<_Tp> { | |
| 57 | }; | |
| 58 | #endif // __has_builtin(__is_trivially_equality_comparable) | |
| 59 | ||
| 60 | template <class _Tp> | |
| 61 | struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Tp*> : true_type {}; | |
| 62 | ||
| 63 | // TODO: Use is_pointer_inverconvertible_base_of | |
| 64 | template <class _Tp, class _Up> | |
| 65 | struct __libcpp_is_trivially_equality_comparable_impl<_Tp*, _Up*> | |
| 66 | : integral_constant< | |
| 67 | bool, | |
| 68 | __is_equality_comparable<_Tp*, _Up*>::value && | |
| 69 | (is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value || is_void<_Tp>::value || is_void<_Up>::value)> { | |
| 70 | }; | |
| 71 | ||
| 72 | template <class _Tp, class _Up> | |
| 73 | using __libcpp_is_trivially_equality_comparable = | |
| 74 | __libcpp_is_trivially_equality_comparable_impl<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >; | |
| 75 | ||
| 76 | _LIBCPP_END_NAMESPACE_STD | |
| 77 | ||
| 78 | #endif // _LIBCPP___TYPE_TRAITS_IS_EQUALITY_COMPARABLE_H |
lib/libcxx/include/__type_traits/is_execution_policy.h created+59| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/remove_cvref.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | #if _LIBCPP_STD_VER >= 17 | |
| 20 | ||
| 21 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 22 | ||
| 23 | template <class> | |
| 24 | inline constexpr bool is_execution_policy_v = false; | |
| 25 | ||
| 26 | template <class> | |
| 27 | inline constexpr bool __is_unsequenced_execution_policy_impl = false; | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | inline constexpr bool __is_unsequenced_execution_policy_v = | |
| 31 | __is_unsequenced_execution_policy_impl<__remove_cvref_t<_Tp>>; | |
| 32 | ||
| 33 | template <class> | |
| 34 | inline constexpr bool __is_parallel_execution_policy_impl = false; | |
| 35 | ||
| 36 | template <class _Tp> | |
| 37 | inline constexpr bool __is_parallel_execution_policy_v = __is_parallel_execution_policy_impl<__remove_cvref_t<_Tp>>; | |
| 38 | ||
| 39 | namespace execution { | |
| 40 | struct __disable_user_instantiations_tag { | |
| 41 | explicit __disable_user_instantiations_tag() = default; | |
| 42 | }; | |
| 43 | } // namespace execution | |
| 44 | ||
| 45 | // TODO: Remove default argument once algorithms are using the new backend dispatching | |
| 46 | template <class _ExecutionPolicy> | |
| 47 | _LIBCPP_HIDE_FROM_ABI auto | |
| 48 | __remove_parallel_policy(const _ExecutionPolicy& = _ExecutionPolicy{execution::__disable_user_instantiations_tag{}}); | |
| 49 | ||
| 50 | // Removes the "parallel" part of an execution policy. | |
| 51 | // For example, turns par_unseq into unseq, and par into seq. | |
| 52 | template <class _ExecutionPolicy> | |
| 53 | using __remove_parallel_policy_t = decltype(std::__remove_parallel_policy<_ExecutionPolicy>()); | |
| 54 | ||
| 55 | _LIBCPP_END_NAMESPACE_STD | |
| 56 | ||
| 57 | #endif // _LIBCPP_STD_VER >= 17 | |
| 58 | ||
| 59 | #endif // _LIBCPP___TYPE_TRAITS_IS_EXECUTION_POLICY_H |
lib/libcxx/include/__type_traits/is_final.h+6-6| ... | ... | @@ -18,15 +18,15 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS | |
| 22 | __libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS __libcpp_is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 25 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS | |
| 26 | is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
| 24 | #if _LIBCPP_STD_VER >= 14 | |
| 25 | template <class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_final : public integral_constant<bool, __is_final(_Tp)> {}; | |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | 30 | template <class _Tp> |
| 31 | 31 | inline constexpr bool is_final_v = __is_final(_Tp); |
| 32 | 32 | #endif |
lib/libcxx/include/__type_traits/is_floating_point.h+5-3| ... | ... | @@ -19,15 +19,17 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | // clang-format off | |
| 22 | 23 | template <class _Tp> struct __libcpp_is_floating_point : public false_type {}; |
| 23 | 24 | template <> struct __libcpp_is_floating_point<float> : public true_type {}; |
| 24 | 25 | template <> struct __libcpp_is_floating_point<double> : public true_type {}; |
| 25 | 26 | template <> struct __libcpp_is_floating_point<long double> : public true_type {}; |
| 27 | // clang-format on | |
| 26 | 28 | |
| 27 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_floating_point | |
| 28 | : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {}; | |
| 29 | template <class _Tp> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS is_floating_point : public __libcpp_is_floating_point<__remove_cv_t<_Tp> > {}; | |
| 29 | 31 | |
| 30 | #if _LIBCPP_STD_VER > 14 | |
| 32 | #if _LIBCPP_STD_VER >= 17 | |
| 31 | 33 | template <class _Tp> |
| 32 | 34 | inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; |
| 33 | 35 | #endif |
lib/libcxx/include/__type_traits/is_function.h+1-1| ... | ... | @@ -33,7 +33,7 @@ struct _LIBCPP_TEMPLATE_VIS is_function |
| 33 | 33 | |
| 34 | 34 | #endif // __has_builtin(__is_function) |
| 35 | 35 | |
| 36 | #if _LIBCPP_STD_VER > 14 | |
| 36 | #if _LIBCPP_STD_VER >= 17 | |
| 37 | 37 | template <class _Tp> |
| 38 | 38 | inline constexpr bool is_function_v = is_function<_Tp>::value; |
| 39 | 39 | #endif |
lib/libcxx/include/__type_traits/is_fundamental.h+9-10| ... | ... | @@ -22,25 +22,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | #if __has_builtin(__is_fundamental) |
| 24 | 24 | |
| 25 | template<class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> { }; | |
| 25 | template <class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_fundamental : _BoolConstant<__is_fundamental(_Tp)> {}; | |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 28 | # if _LIBCPP_STD_VER >= 17 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | inline constexpr bool is_fundamental_v = __is_fundamental(_Tp); |
| 31 | #endif | |
| 31 | # endif | |
| 32 | 32 | |
| 33 | 33 | #else // __has_builtin(__is_fundamental) |
| 34 | 34 | |
| 35 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_fundamental | |
| 36 | : public integral_constant<bool, is_void<_Tp>::value || | |
| 37 | __is_nullptr_t<_Tp>::value || | |
| 38 | is_arithmetic<_Tp>::value> {}; | |
| 35 | template <class _Tp> | |
| 36 | struct _LIBCPP_TEMPLATE_VIS is_fundamental | |
| 37 | : public integral_constant<bool, is_void<_Tp>::value || __is_nullptr_t<_Tp>::value || is_arithmetic<_Tp>::value> {}; | |
| 39 | 38 | |
| 40 | #if _LIBCPP_STD_VER > 14 | |
| 39 | # if _LIBCPP_STD_VER >= 17 | |
| 41 | 40 | template <class _Tp> |
| 42 | 41 | inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; |
| 43 | #endif | |
| 42 | # endif | |
| 44 | 43 | |
| 45 | 44 | #endif // __has_builtin(__is_fundamental) |
| 46 | 45 |
lib/libcxx/include/__type_traits/is_implicitly_default_constructible.h+7-9| ... | ... | @@ -28,19 +28,17 @@ template <class _Tp> |
| 28 | 28 | void __test_implicit_default_constructible(_Tp); |
| 29 | 29 | |
| 30 | 30 | template <class _Tp, class = void, class = typename is_default_constructible<_Tp>::type> |
| 31 | struct __is_implicitly_default_constructible | |
| 32 | : false_type | |
| 33 | { }; | |
| 31 | struct __is_implicitly_default_constructible : false_type {}; | |
| 34 | 32 | |
| 35 | 33 | template <class _Tp> |
| 36 | struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), true_type> | |
| 37 | : true_type | |
| 38 | { }; | |
| 34 | struct __is_implicitly_default_constructible<_Tp, | |
| 35 | decltype(std::__test_implicit_default_constructible<_Tp const&>({})), | |
| 36 | true_type> : true_type {}; | |
| 39 | 37 | |
| 40 | 38 | template <class _Tp> |
| 41 | struct __is_implicitly_default_constructible<_Tp, decltype(std::__test_implicit_default_constructible<_Tp const&>({})), false_type> | |
| 42 | : false_type | |
| 43 | { }; | |
| 39 | struct __is_implicitly_default_constructible<_Tp, | |
| 40 | decltype(std::__test_implicit_default_constructible<_Tp const&>({})), | |
| 41 | false_type> : false_type {}; | |
| 44 | 42 | #endif // !C++03 |
| 45 | 43 | |
| 46 | 44 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/is_integral.h+9-7| ... | ... | @@ -19,6 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | // clang-format off | |
| 22 | 23 | template <class _Tp> struct __libcpp_is_integral { enum { value = 0 }; }; |
| 23 | 24 | template <> struct __libcpp_is_integral<bool> { enum { value = 1 }; }; |
| 24 | 25 | template <> struct __libcpp_is_integral<char> { enum { value = 1 }; }; |
| ... | ... | @@ -44,26 +45,27 @@ template <> struct __libcpp_is_integral<unsigned long long> { enum { va |
| 44 | 45 | template <> struct __libcpp_is_integral<__int128_t> { enum { value = 1 }; }; |
| 45 | 46 | template <> struct __libcpp_is_integral<__uint128_t> { enum { value = 1 }; }; |
| 46 | 47 | #endif |
| 48 | // clang-format on | |
| 47 | 49 | |
| 48 | 50 | #if __has_builtin(__is_integral) |
| 49 | 51 | |
| 50 | 52 | template <class _Tp> |
| 51 | struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> { }; | |
| 53 | struct _LIBCPP_TEMPLATE_VIS is_integral : _BoolConstant<__is_integral(_Tp)> {}; | |
| 52 | 54 | |
| 53 | #if _LIBCPP_STD_VER > 14 | |
| 55 | # if _LIBCPP_STD_VER >= 17 | |
| 54 | 56 | template <class _Tp> |
| 55 | 57 | inline constexpr bool is_integral_v = __is_integral(_Tp); |
| 56 | #endif | |
| 58 | # endif | |
| 57 | 59 | |
| 58 | 60 | #else |
| 59 | 61 | |
| 60 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_integral | |
| 61 | : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {}; | |
| 62 | template <class _Tp> | |
| 63 | struct _LIBCPP_TEMPLATE_VIS is_integral : public _BoolConstant<__libcpp_is_integral<__remove_cv_t<_Tp> >::value> {}; | |
| 62 | 64 | |
| 63 | #if _LIBCPP_STD_VER > 14 | |
| 65 | # if _LIBCPP_STD_VER >= 17 | |
| 64 | 66 | template <class _Tp> |
| 65 | 67 | inline constexpr bool is_integral_v = is_integral<_Tp>::value; |
| 66 | #endif | |
| 68 | # endif | |
| 67 | 69 | |
| 68 | 70 | #endif // __has_builtin(__is_integral) |
| 69 | 71 |
lib/libcxx/include/__type_traits/is_literal_type.h+6-6| ... | ... | @@ -19,15 +19,15 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) |
| 22 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type | |
| 23 | : public integral_constant<bool, __is_literal_type(_Tp)> | |
| 24 | {}; | |
| 22 | template <class _Tp> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type | |
| 24 | : public integral_constant<bool, __is_literal_type(_Tp)> {}; | |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | # if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | _LIBCPP_DEPRECATED_IN_CXX17 inline constexpr bool is_literal_type_v = __is_literal_type(_Tp); |
| 29 | #endif // _LIBCPP_STD_VER > 14 | |
| 30 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) | |
| 29 | # endif // _LIBCPP_STD_VER >= 17 | |
| 30 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 33 | 33 |
lib/libcxx/include/__type_traits/is_member_function_pointer.h+16-18| ... | ... | @@ -21,41 +21,39 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | template <class _Tp> struct __libcpp_is_member_pointer { | |
| 25 | enum { | |
| 26 | __is_member = false, | |
| 27 | __is_func = false, | |
| 28 | __is_obj = false | |
| 29 | }; | |
| 24 | template <class _Tp> | |
| 25 | struct __libcpp_is_member_pointer { | |
| 26 | enum { __is_member = false, __is_func = false, __is_obj = false }; | |
| 30 | 27 | }; |
| 31 | template <class _Tp, class _Up> struct __libcpp_is_member_pointer<_Tp _Up::*> { | |
| 28 | template <class _Tp, class _Up> | |
| 29 | struct __libcpp_is_member_pointer<_Tp _Up::*> { | |
| 32 | 30 | enum { |
| 33 | 31 | __is_member = true, |
| 34 | __is_func = is_function<_Tp>::value, | |
| 35 | __is_obj = !__is_func, | |
| 32 | __is_func = is_function<_Tp>::value, | |
| 33 | __is_obj = !__is_func, | |
| 36 | 34 | }; |
| 37 | 35 | }; |
| 38 | 36 | |
| 39 | 37 | #if __has_builtin(__is_member_function_pointer) |
| 40 | 38 | |
| 41 | template<class _Tp> | |
| 42 | struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer | |
| 43 | : _BoolConstant<__is_member_function_pointer(_Tp)> { }; | |
| 39 | template <class _Tp> | |
| 40 | struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer : _BoolConstant<__is_member_function_pointer(_Tp)> {}; | |
| 44 | 41 | |
| 45 | #if _LIBCPP_STD_VER > 14 | |
| 42 | # if _LIBCPP_STD_VER >= 17 | |
| 46 | 43 | template <class _Tp> |
| 47 | 44 | inline constexpr bool is_member_function_pointer_v = __is_member_function_pointer(_Tp); |
| 48 | #endif | |
| 45 | # endif | |
| 49 | 46 | |
| 50 | 47 | #else // __has_builtin(__is_member_function_pointer) |
| 51 | 48 | |
| 52 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer | |
| 53 | : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func > {}; | |
| 49 | template <class _Tp> | |
| 50 | struct _LIBCPP_TEMPLATE_VIS is_member_function_pointer | |
| 51 | : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_func> {}; | |
| 54 | 52 | |
| 55 | #if _LIBCPP_STD_VER > 14 | |
| 53 | # if _LIBCPP_STD_VER >= 17 | |
| 56 | 54 | template <class _Tp> |
| 57 | 55 | inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; |
| 58 | #endif | |
| 56 | # endif | |
| 59 | 57 | |
| 60 | 58 | #endif // __has_builtin(__is_member_function_pointer) |
| 61 | 59 |
lib/libcxx/include/__type_traits/is_member_object_pointer.h+9-9| ... | ... | @@ -20,24 +20,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | #if __has_builtin(__is_member_object_pointer) |
| 22 | 22 | |
| 23 | template<class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer | |
| 25 | : _BoolConstant<__is_member_object_pointer(_Tp)> { }; | |
| 23 | template <class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer : _BoolConstant<__is_member_object_pointer(_Tp)> {}; | |
| 26 | 25 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 26 | # if _LIBCPP_STD_VER >= 17 | |
| 28 | 27 | template <class _Tp> |
| 29 | 28 | inline constexpr bool is_member_object_pointer_v = __is_member_object_pointer(_Tp); |
| 30 | #endif | |
| 29 | # endif | |
| 31 | 30 | |
| 32 | 31 | #else // __has_builtin(__is_member_object_pointer) |
| 33 | 32 | |
| 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer | |
| 35 | : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj > {}; | |
| 33 | template <class _Tp> | |
| 34 | struct _LIBCPP_TEMPLATE_VIS is_member_object_pointer | |
| 35 | : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_obj> {}; | |
| 36 | 36 | |
| 37 | #if _LIBCPP_STD_VER > 14 | |
| 37 | # if _LIBCPP_STD_VER >= 17 | |
| 38 | 38 | template <class _Tp> |
| 39 | 39 | inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; |
| 40 | #endif | |
| 40 | # endif | |
| 41 | 41 | |
| 42 | 42 | #endif // __has_builtin(__is_member_object_pointer) |
| 43 | 43 |
lib/libcxx/include/__type_traits/is_member_pointer.h+9-8| ... | ... | @@ -21,23 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if __has_builtin(__is_member_pointer) |
| 23 | 23 | |
| 24 | template<class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> { }; | |
| 24 | template <class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_member_pointer : _BoolConstant<__is_member_pointer(_Tp)> {}; | |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 27 | # if _LIBCPP_STD_VER >= 17 | |
| 28 | 28 | template <class _Tp> |
| 29 | 29 | inline constexpr bool is_member_pointer_v = __is_member_pointer(_Tp); |
| 30 | #endif | |
| 30 | # endif | |
| 31 | 31 | |
| 32 | 32 | #else // __has_builtin(__is_member_pointer) |
| 33 | 33 | |
| 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_member_pointer | |
| 35 | : public _BoolConstant< __libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member > {}; | |
| 34 | template <class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS is_member_pointer | |
| 36 | : public _BoolConstant<__libcpp_is_member_pointer<__remove_cv_t<_Tp> >::__is_member> {}; | |
| 36 | 37 | |
| 37 | #if _LIBCPP_STD_VER > 14 | |
| 38 | # if _LIBCPP_STD_VER >= 17 | |
| 38 | 39 | template <class _Tp> |
| 39 | 40 | inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; |
| 40 | #endif | |
| 41 | # endif | |
| 41 | 42 | |
| 42 | 43 | #endif // __has_builtin(__is_member_pointer) |
| 43 | 44 |
lib/libcxx/include/__type_traits/is_move_assignable.h+2-4| ... | ... | @@ -22,11 +22,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_move_assignable |
| 25 | : public integral_constant< | |
| 26 | bool, | |
| 27 | __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {}; | |
| 25 | : public integral_constant<bool, __is_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {}; | |
| 28 | 26 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 27 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | 28 | template <class _Tp> |
| 31 | 29 | inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; |
| 32 | 30 | #endif |
lib/libcxx/include/__type_traits/is_move_constructible.h+2-3| ... | ... | @@ -21,10 +21,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | template <class _Tp> |
| 23 | 23 | struct _LIBCPP_TEMPLATE_VIS is_move_constructible |
| 24 | : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> | |
| 25 | {}; | |
| 24 | : public integral_constant<bool, __is_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {}; | |
| 26 | 25 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 26 | #if _LIBCPP_STD_VER >= 17 | |
| 28 | 27 | template <class _Tp> |
| 29 | 28 | inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value; |
| 30 | 29 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_assignable.h+3-3| ... | ... | @@ -19,10 +19,10 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp, class _Arg> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable | |
| 23 | : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> {}; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_assignable : public integral_constant<bool, __is_nothrow_assignable(_Tp, _Arg)> { | |
| 23 | }; | |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 26 | template <class _Tp, class _Arg> |
| 27 | 27 | inline constexpr bool is_nothrow_assignable_v = __is_nothrow_assignable(_Tp, _Arg); |
| 28 | 28 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_constructible.h+16-24| ... | ... | @@ -24,52 +24,44 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | 25 | #if __has_builtin(__is_nothrow_constructible) |
| 26 | 26 | |
| 27 | template < | |
| 28 | class _Tp, class... _Args> | |
| 27 | template < class _Tp, class... _Args> | |
| 29 | 28 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible |
| 30 | 29 | : public integral_constant<bool, __is_nothrow_constructible(_Tp, _Args...)> {}; |
| 31 | 30 | #else |
| 32 | 31 | |
| 33 | template <bool, bool, class _Tp, class... _Args> struct __libcpp_is_nothrow_constructible; | |
| 32 | template <bool, bool, class _Tp, class... _Args> | |
| 33 | struct __libcpp_is_nothrow_constructible; | |
| 34 | 34 | |
| 35 | 35 | template <class _Tp, class... _Args> |
| 36 | struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/false, _Tp, _Args...> | |
| 37 | : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))> | |
| 38 | { | |
| 39 | }; | |
| 36 | struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ false, _Tp, _Args...> | |
| 37 | : public integral_constant<bool, noexcept(_Tp(std::declval<_Args>()...))> {}; | |
| 40 | 38 | |
| 41 | 39 | template <class _Tp> |
| 42 | void __implicit_conversion_to(_Tp) noexcept { } | |
| 40 | void __implicit_conversion_to(_Tp) noexcept {} | |
| 43 | 41 | |
| 44 | 42 | template <class _Tp, class _Arg> |
| 45 | struct __libcpp_is_nothrow_constructible</*is constructible*/true, /*is reference*/true, _Tp, _Arg> | |
| 46 | : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))> | |
| 47 | { | |
| 48 | }; | |
| 43 | struct __libcpp_is_nothrow_constructible</*is constructible*/ true, /*is reference*/ true, _Tp, _Arg> | |
| 44 | : public integral_constant<bool, noexcept(_VSTD::__implicit_conversion_to<_Tp>(std::declval<_Arg>()))> {}; | |
| 49 | 45 | |
| 50 | 46 | template <class _Tp, bool _IsReference, class... _Args> |
| 51 | struct __libcpp_is_nothrow_constructible</*is constructible*/false, _IsReference, _Tp, _Args...> | |
| 52 | : public false_type | |
| 53 | { | |
| 47 | struct __libcpp_is_nothrow_constructible</*is constructible*/ false, _IsReference, _Tp, _Args...> : public false_type { | |
| 54 | 48 | }; |
| 55 | 49 | |
| 56 | 50 | template <class _Tp, class... _Args> |
| 57 | 51 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible |
| 58 | : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, is_reference<_Tp>::value, _Tp, _Args...> | |
| 59 | { | |
| 60 | }; | |
| 52 | : __libcpp_is_nothrow_constructible<is_constructible<_Tp, _Args...>::value, | |
| 53 | is_reference<_Tp>::value, | |
| 54 | _Tp, | |
| 55 | _Args...> {}; | |
| 61 | 56 | |
| 62 | 57 | template <class _Tp, size_t _Ns> |
| 63 | 58 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]> |
| 64 | : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> | |
| 65 | { | |
| 66 | }; | |
| 59 | : __libcpp_is_nothrow_constructible<is_constructible<_Tp>::value, is_reference<_Tp>::value, _Tp> {}; | |
| 67 | 60 | |
| 68 | 61 | #endif // __has_builtin(__is_nothrow_constructible) |
| 69 | 62 | |
| 70 | ||
| 71 | #if _LIBCPP_STD_VER > 14 | |
| 72 | template <class _Tp, class ..._Args> | |
| 63 | #if _LIBCPP_STD_VER >= 17 | |
| 64 | template <class _Tp, class... _Args> | |
| 73 | 65 | inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value; |
| 74 | 66 | #endif |
| 75 | 67 |
lib/libcxx/include/__type_traits/is_nothrow_convertible.h+9-12| ... | ... | @@ -24,29 +24,26 @@ |
| 24 | 24 | |
| 25 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 17 | |
| 27 | #if _LIBCPP_STD_VER >= 20 | |
| 28 | 28 | |
| 29 | 29 | template <typename _Tp> |
| 30 | static void __test_noexcept(_Tp) noexcept; | |
| 30 | void __test_noexcept(_Tp) noexcept; | |
| 31 | 31 | |
| 32 | template<typename _Fm, typename _To> | |
| 33 | static bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))> | |
| 34 | __is_nothrow_convertible_test(); | |
| 32 | template <typename _Fm, typename _To> | |
| 33 | bool_constant<noexcept(_VSTD::__test_noexcept<_To>(std::declval<_Fm>()))> __is_nothrow_convertible_test(); | |
| 35 | 34 | |
| 36 | 35 | template <typename _Fm, typename _To> |
| 37 | struct __is_nothrow_convertible_helper: decltype(__is_nothrow_convertible_test<_Fm, _To>()) | |
| 38 | { }; | |
| 36 | struct __is_nothrow_convertible_helper : decltype(__is_nothrow_convertible_test<_Fm, _To>()) {}; | |
| 39 | 37 | |
| 40 | 38 | template <typename _Fm, typename _To> |
| 41 | struct is_nothrow_convertible : _Or< | |
| 42 | _And<is_void<_To>, is_void<_Fm>>, | |
| 43 | _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To>> | |
| 44 | >::type { }; | |
| 39 | struct is_nothrow_convertible | |
| 40 | : _Or<_And<is_void<_To>, is_void<_Fm>>, | |
| 41 | _Lazy<_And, is_convertible<_Fm, _To>, __is_nothrow_convertible_helper<_Fm, _To> > >::type {}; | |
| 45 | 42 | |
| 46 | 43 | template <typename _Fm, typename _To> |
| 47 | 44 | inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_Fm, _To>::value; |
| 48 | 45 | |
| 49 | #endif // _LIBCPP_STD_VER > 17 | |
| 46 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | 47 | |
| 51 | 48 | _LIBCPP_END_NAMESPACE_STD |
| 52 | 49 |
lib/libcxx/include/__type_traits/is_nothrow_copy_assignable.h+4-6| ... | ... | @@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable |
| 25 | : public integral_constant< | |
| 26 | bool, | |
| 27 | __is_nothrow_assignable( | |
| 28 | __add_lvalue_reference_t<_Tp>, | |
| 29 | __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 25 | : public integral_constant<bool, | |
| 26 | __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, | |
| 27 | __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 30 | 28 | |
| 31 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 32 | 30 | template <class _Tp> |
| 33 | 31 | inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value; |
| 34 | 32 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_copy_constructible.h+4-4| ... | ... | @@ -24,9 +24,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | // TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed |
| 25 | 25 | #ifdef _LIBCPP_COMPILER_GCC |
| 26 | 26 | |
| 27 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible | |
| 28 | : public is_nothrow_constructible<_Tp, | |
| 29 | __add_lvalue_reference_t<typename add_const<_Tp>::type> > {}; | |
| 27 | template <class _Tp> | |
| 28 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible | |
| 29 | : public is_nothrow_constructible<_Tp, __add_lvalue_reference_t<typename add_const<_Tp>::type> > {}; | |
| 30 | 30 | |
| 31 | 31 | #else // _LIBCPP_COMPILER_GCC |
| 32 | 32 | |
| ... | ... | @@ -38,7 +38,7 @@ struct _LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible |
| 38 | 38 | |
| 39 | 39 | #endif // _LIBCPP_COMPILER_GCC |
| 40 | 40 | |
| 41 | #if _LIBCPP_STD_VER > 14 | |
| 41 | #if _LIBCPP_STD_VER >= 17 | |
| 42 | 42 | template <class _Tp> |
| 43 | 43 | inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value; |
| 44 | 44 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_default_constructible.h+4-4| ... | ... | @@ -18,11 +18,11 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible | |
| 22 | : public integral_constant<bool, __is_nothrow_constructible(_Tp)> | |
| 23 | {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible | |
| 23 | : public integral_constant<bool, __is_nothrow_constructible(_Tp)> {}; | |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | inline constexpr bool is_nothrow_default_constructible_v = __is_nothrow_constructible(_Tp); |
| 28 | 28 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_destructible.h+16-31| ... | ... | @@ -26,60 +26,45 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | 27 | #if !defined(_LIBCPP_CXX03_LANG) |
| 28 | 28 | |
| 29 | template <bool, class _Tp> struct __libcpp_is_nothrow_destructible; | |
| 29 | template <bool, class _Tp> | |
| 30 | struct __libcpp_is_nothrow_destructible; | |
| 30 | 31 | |
| 31 | 32 | template <class _Tp> |
| 32 | struct __libcpp_is_nothrow_destructible<false, _Tp> | |
| 33 | : public false_type | |
| 34 | { | |
| 35 | }; | |
| 33 | struct __libcpp_is_nothrow_destructible<false, _Tp> : public false_type {}; | |
| 36 | 34 | |
| 37 | 35 | template <class _Tp> |
| 38 | 36 | struct __libcpp_is_nothrow_destructible<true, _Tp> |
| 39 | : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) > | |
| 40 | { | |
| 41 | }; | |
| 37 | : public integral_constant<bool, noexcept(std::declval<_Tp>().~_Tp()) > {}; | |
| 42 | 38 | |
| 43 | 39 | template <class _Tp> |
| 44 | 40 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible |
| 45 | : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp> | |
| 46 | { | |
| 47 | }; | |
| 41 | : public __libcpp_is_nothrow_destructible<is_destructible<_Tp>::value, _Tp> {}; | |
| 48 | 42 | |
| 49 | 43 | template <class _Tp, size_t _Ns> |
| 50 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]> | |
| 51 | : public is_nothrow_destructible<_Tp> | |
| 52 | { | |
| 53 | }; | |
| 44 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]> : public is_nothrow_destructible<_Tp> {}; | |
| 54 | 45 | |
| 55 | 46 | template <class _Tp> |
| 56 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&> | |
| 57 | : public true_type | |
| 58 | { | |
| 59 | }; | |
| 47 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&> : public true_type {}; | |
| 60 | 48 | |
| 61 | 49 | template <class _Tp> |
| 62 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> | |
| 63 | : public true_type | |
| 64 | { | |
| 65 | }; | |
| 50 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> : public true_type {}; | |
| 66 | 51 | |
| 67 | 52 | #else |
| 68 | 53 | |
| 69 | template <class _Tp> struct __libcpp_nothrow_destructor | |
| 70 | : public integral_constant<bool, is_scalar<_Tp>::value || | |
| 71 | is_reference<_Tp>::value> {}; | |
| 54 | template <class _Tp> | |
| 55 | struct __libcpp_nothrow_destructor : public integral_constant<bool, is_scalar<_Tp>::value || is_reference<_Tp>::value> { | |
| 56 | }; | |
| 72 | 57 | |
| 73 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible | |
| 74 | : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > {}; | |
| 58 | template <class _Tp> | |
| 59 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible : public __libcpp_nothrow_destructor<__remove_all_extents_t<_Tp> > { | |
| 60 | }; | |
| 75 | 61 | |
| 76 | 62 | template <class _Tp> |
| 77 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]> | |
| 78 | : public false_type {}; | |
| 63 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]> : public false_type {}; | |
| 79 | 64 | |
| 80 | 65 | #endif |
| 81 | 66 | |
| 82 | #if _LIBCPP_STD_VER > 14 | |
| 67 | #if _LIBCPP_STD_VER >= 17 | |
| 83 | 68 | template <class _Tp> |
| 84 | 69 | inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; |
| 85 | 70 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_move_assignable.h+3-4| ... | ... | @@ -22,12 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable |
| 25 | : public integral_constant< | |
| 26 | bool, | |
| 27 | __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> { | |
| 25 | : public integral_constant<bool, | |
| 26 | __is_nothrow_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> { | |
| 28 | 27 | }; |
| 29 | 28 | |
| 30 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 31 | 30 | template <class _Tp> |
| 32 | 31 | inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value; |
| 33 | 32 | #endif |
lib/libcxx/include/__type_traits/is_nothrow_move_constructible.h+7-7| ... | ... | @@ -23,19 +23,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | // TODO: remove this implementation once https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106611 is fixed |
| 24 | 24 | #ifndef _LIBCPP_COMPILER_GCC |
| 25 | 25 | |
| 26 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible | |
| 27 | : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> | |
| 28 | {}; | |
| 26 | template <class _Tp> | |
| 27 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible | |
| 28 | : public integral_constant<bool, __is_nothrow_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {}; | |
| 29 | 29 | |
| 30 | 30 | #else // _LIBCPP_COMPILER_GCC |
| 31 | 31 | |
| 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible | |
| 33 | : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> > | |
| 34 | {}; | |
| 32 | template <class _Tp> | |
| 33 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible | |
| 34 | : public is_nothrow_constructible<_Tp, __add_rvalue_reference_t<_Tp> > {}; | |
| 35 | 35 | |
| 36 | 36 | #endif // _LIBCPP_COMPILER_GCC |
| 37 | 37 | |
| 38 | #if _LIBCPP_STD_VER > 14 | |
| 38 | #if _LIBCPP_STD_VER >= 17 | |
| 39 | 39 | template <class _Tp> |
| 40 | 40 | inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value; |
| 41 | 41 | #endif |
lib/libcxx/include/__type_traits/is_null_pointer.h+12-10| ... | ... | @@ -20,21 +20,23 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | template <class _Tp> struct __is_nullptr_t_impl : public false_type {}; | |
| 24 | template <> struct __is_nullptr_t_impl<nullptr_t> : public true_type {}; | |
| 23 | template <class _Tp> | |
| 24 | struct __is_nullptr_t_impl : public false_type {}; | |
| 25 | template <> | |
| 26 | struct __is_nullptr_t_impl<nullptr_t> : public true_type {}; | |
| 25 | 27 | |
| 26 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t | |
| 27 | : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {}; | |
| 28 | template <class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS __is_nullptr_t : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {}; | |
| 28 | 30 | |
| 29 | #if _LIBCPP_STD_VER > 11 | |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_null_pointer | |
| 31 | : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {}; | |
| 31 | #if _LIBCPP_STD_VER >= 14 | |
| 32 | template <class _Tp> | |
| 33 | struct _LIBCPP_TEMPLATE_VIS is_null_pointer : public __is_nullptr_t_impl<__remove_cv_t<_Tp> > {}; | |
| 32 | 34 | |
| 33 | #if _LIBCPP_STD_VER > 14 | |
| 35 | # if _LIBCPP_STD_VER >= 17 | |
| 34 | 36 | template <class _Tp> |
| 35 | 37 | inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value; |
| 36 | #endif | |
| 37 | #endif // _LIBCPP_STD_VER > 11 | |
| 38 | # endif | |
| 39 | #endif // _LIBCPP_STD_VER >= 14 | |
| 38 | 40 | |
| 39 | 41 | _LIBCPP_END_NAMESPACE_STD |
| 40 | 42 |
lib/libcxx/include/__type_traits/is_object.h+11-11| ... | ... | @@ -24,26 +24,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | 25 | #if __has_builtin(__is_object) |
| 26 | 26 | |
| 27 | template<class _Tp> | |
| 28 | struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> { }; | |
| 27 | template <class _Tp> | |
| 28 | struct _LIBCPP_TEMPLATE_VIS is_object : _BoolConstant<__is_object(_Tp)> {}; | |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 14 | |
| 30 | # if _LIBCPP_STD_VER >= 17 | |
| 31 | 31 | template <class _Tp> |
| 32 | 32 | inline constexpr bool is_object_v = __is_object(_Tp); |
| 33 | #endif | |
| 33 | # endif | |
| 34 | 34 | |
| 35 | 35 | #else // __has_builtin(__is_object) |
| 36 | 36 | |
| 37 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_object | |
| 38 | : public integral_constant<bool, is_scalar<_Tp>::value || | |
| 39 | is_array<_Tp>::value || | |
| 40 | is_union<_Tp>::value || | |
| 41 | is_class<_Tp>::value > {}; | |
| 37 | template <class _Tp> | |
| 38 | struct _LIBCPP_TEMPLATE_VIS is_object | |
| 39 | : public integral_constant<bool, | |
| 40 | is_scalar<_Tp>::value || is_array<_Tp>::value || is_union<_Tp>::value || | |
| 41 | is_class<_Tp>::value > {}; | |
| 42 | 42 | |
| 43 | #if _LIBCPP_STD_VER > 14 | |
| 43 | # if _LIBCPP_STD_VER >= 17 | |
| 44 | 44 | template <class _Tp> |
| 45 | 45 | inline constexpr bool is_object_v = is_object<_Tp>::value; |
| 46 | #endif | |
| 46 | # endif | |
| 47 | 47 | |
| 48 | 48 | #endif // __has_builtin(__is_object) |
| 49 | 49 |
lib/libcxx/include/__type_traits/is_pod.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pod | |
| 22 | : public integral_constant<bool, __is_pod(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_pod : public integral_constant<bool, __is_pod(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool is_pod_v = __is_pod(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_pointer.h+20-12| ... | ... | @@ -21,34 +21,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if __has_builtin(__is_pointer) |
| 23 | 23 | |
| 24 | template<class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> { }; | |
| 24 | template <class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_pointer : _BoolConstant<__is_pointer(_Tp)> {}; | |
| 26 | 26 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 27 | # if _LIBCPP_STD_VER >= 17 | |
| 28 | 28 | template <class _Tp> |
| 29 | 29 | inline constexpr bool is_pointer_v = __is_pointer(_Tp); |
| 30 | #endif | |
| 30 | # endif | |
| 31 | 31 | |
| 32 | 32 | #else // __has_builtin(__is_pointer) |
| 33 | 33 | |
| 34 | template <class _Tp> struct __libcpp_is_pointer : public false_type {}; | |
| 35 | template <class _Tp> struct __libcpp_is_pointer<_Tp*> : public true_type {}; | |
| 34 | template <class _Tp> | |
| 35 | struct __libcpp_is_pointer : public false_type {}; | |
| 36 | template <class _Tp> | |
| 37 | struct __libcpp_is_pointer<_Tp*> : public true_type {}; | |
| 36 | 38 | |
| 37 | template <class _Tp> struct __libcpp_remove_objc_qualifiers { typedef _Tp type; }; | |
| 38 | #if defined(_LIBCPP_HAS_OBJC_ARC) | |
| 39 | template <class _Tp> | |
| 40 | struct __libcpp_remove_objc_qualifiers { | |
| 41 | typedef _Tp type; | |
| 42 | }; | |
| 43 | # if defined(_LIBCPP_HAS_OBJC_ARC) | |
| 44 | // clang-format off | |
| 39 | 45 | template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __strong> { typedef _Tp type; }; |
| 40 | 46 | template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __weak> { typedef _Tp type; }; |
| 41 | 47 | template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __autoreleasing> { typedef _Tp type; }; |
| 42 | 48 | template <class _Tp> struct __libcpp_remove_objc_qualifiers<_Tp __unsafe_unretained> { typedef _Tp type; }; |
| 43 | #endif | |
| 49 | // clang-format on | |
| 50 | # endif | |
| 44 | 51 | |
| 45 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_pointer | |
| 52 | template <class _Tp> | |
| 53 | struct _LIBCPP_TEMPLATE_VIS is_pointer | |
| 46 | 54 | : public __libcpp_is_pointer<typename __libcpp_remove_objc_qualifiers<__remove_cv_t<_Tp> >::type> {}; |
| 47 | 55 | |
| 48 | #if _LIBCPP_STD_VER > 14 | |
| 56 | # if _LIBCPP_STD_VER >= 17 | |
| 49 | 57 | template <class _Tp> |
| 50 | 58 | inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; |
| 51 | #endif | |
| 59 | # endif | |
| 52 | 60 | |
| 53 | 61 | #endif // __has_builtin(__is_pointer) |
| 54 | 62 |
lib/libcxx/include/__type_traits/is_polymorphic.h+2-3| ... | ... | @@ -19,10 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_polymorphic | |
| 23 | : public integral_constant<bool, __is_polymorphic(_Tp)> {}; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_polymorphic : public integral_constant<bool, __is_polymorphic(_Tp)> {}; | |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | template <class _Tp> |
| 27 | 26 | inline constexpr bool is_polymorphic_v = __is_polymorphic(_Tp); |
| 28 | 27 | #endif |
lib/libcxx/include/__type_traits/is_primary_template.h+3-6| ... | ... | @@ -21,13 +21,10 @@ |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | using __test_for_primary_template = __enable_if_t< | |
| 25 | _IsSame<_Tp, typename _Tp::__primary_template>::value | |
| 26 | >; | |
| 24 | using __test_for_primary_template = __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>; | |
| 25 | ||
| 27 | 26 | template <class _Tp> |
| 28 | using __is_primary_template = _IsValidExpansion< | |
| 29 | __test_for_primary_template, _Tp | |
| 30 | >; | |
| 27 | using __is_primary_template = _IsValidExpansion<__test_for_primary_template, _Tp>; | |
| 31 | 28 | |
| 32 | 29 | _LIBCPP_END_NAMESPACE_STD |
| 33 | 30 |
lib/libcxx/include/__type_traits/is_reference.h+25-20| ... | ... | @@ -18,41 +18,46 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | #if __has_builtin(__is_lvalue_reference) && \ | |
| 22 | __has_builtin(__is_rvalue_reference) && \ | |
| 23 | __has_builtin(__is_reference) | |
| 21 | #if __has_builtin(__is_lvalue_reference) && __has_builtin(__is_rvalue_reference) && __has_builtin(__is_reference) | |
| 24 | 22 | |
| 25 | template<class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> { }; | |
| 23 | template <class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : _BoolConstant<__is_lvalue_reference(_Tp)> {}; | |
| 27 | 25 | |
| 28 | template<class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> { }; | |
| 26 | template <class _Tp> | |
| 27 | struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : _BoolConstant<__is_rvalue_reference(_Tp)> {}; | |
| 30 | 28 | |
| 31 | template<class _Tp> | |
| 32 | struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> { }; | |
| 29 | template <class _Tp> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS is_reference : _BoolConstant<__is_reference(_Tp)> {}; | |
| 33 | 31 | |
| 34 | #if _LIBCPP_STD_VER > 14 | |
| 32 | # if _LIBCPP_STD_VER >= 17 | |
| 35 | 33 | template <class _Tp> |
| 36 | 34 | inline constexpr bool is_reference_v = __is_reference(_Tp); |
| 37 | 35 | template <class _Tp> |
| 38 | 36 | inline constexpr bool is_lvalue_reference_v = __is_lvalue_reference(_Tp); |
| 39 | 37 | template <class _Tp> |
| 40 | 38 | inline constexpr bool is_rvalue_reference_v = __is_rvalue_reference(_Tp); |
| 41 | #endif | |
| 39 | # endif | |
| 42 | 40 | |
| 43 | 41 | #else // __has_builtin(__is_lvalue_reference) && etc... |
| 44 | 42 | |
| 45 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; | |
| 46 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; | |
| 43 | template <class _Tp> | |
| 44 | struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; | |
| 45 | template <class _Tp> | |
| 46 | struct _LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; | |
| 47 | 47 | |
| 48 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {}; | |
| 49 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {}; | |
| 48 | template <class _Tp> | |
| 49 | struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {}; | |
| 50 | template <class _Tp> | |
| 51 | struct _LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {}; | |
| 50 | 52 | |
| 51 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {}; | |
| 52 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; | |
| 53 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; | |
| 53 | template <class _Tp> | |
| 54 | struct _LIBCPP_TEMPLATE_VIS is_reference : public false_type {}; | |
| 55 | template <class _Tp> | |
| 56 | struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; | |
| 57 | template <class _Tp> | |
| 58 | struct _LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; | |
| 54 | 59 | |
| 55 | #if _LIBCPP_STD_VER > 14 | |
| 60 | # if _LIBCPP_STD_VER >= 17 | |
| 56 | 61 | template <class _Tp> |
| 57 | 62 | inline constexpr bool is_reference_v = is_reference<_Tp>::value; |
| 58 | 63 | |
| ... | ... | @@ -61,7 +66,7 @@ inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value; |
| 61 | 66 | |
| 62 | 67 | template <class _Tp> |
| 63 | 68 | inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; |
| 64 | #endif | |
| 69 | # endif | |
| 65 | 70 | |
| 66 | 71 | #endif // __has_builtin(__is_lvalue_reference) && etc... |
| 67 | 72 |
lib/libcxx/include/__type_traits/is_reference_wrapper.h+9-6| ... | ... | @@ -19,12 +19,15 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template <class _Tp> class _LIBCPP_TEMPLATE_VIS reference_wrapper; | |
| 23 | ||
| 24 | template <class _Tp> struct __is_reference_wrapper_impl : public false_type {}; | |
| 25 | template <class _Tp> struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {}; | |
| 26 | template <class _Tp> struct __is_reference_wrapper | |
| 27 | : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {}; | |
| 22 | template <class _Tp> | |
| 23 | class _LIBCPP_TEMPLATE_VIS reference_wrapper; | |
| 24 | ||
| 25 | template <class _Tp> | |
| 26 | struct __is_reference_wrapper_impl : public false_type {}; | |
| 27 | template <class _Tp> | |
| 28 | struct __is_reference_wrapper_impl<reference_wrapper<_Tp> > : public true_type {}; | |
| 29 | template <class _Tp> | |
| 30 | struct __is_reference_wrapper : public __is_reference_wrapper_impl<__remove_cv_t<_Tp> > {}; | |
| 28 | 31 | |
| 29 | 32 | _LIBCPP_END_NAMESPACE_STD |
| 30 | 33 |
lib/libcxx/include/__type_traits/is_same.h+2-2| ... | ... | @@ -19,9 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp, class _Up> |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> { }; | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_same : _BoolConstant<__is_same(_Tp, _Up)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp, class _Up> |
| 26 | 26 | inline constexpr bool is_same_v = __is_same(_Tp, _Up); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_scalar.h+25-18| ... | ... | @@ -25,35 +25,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 25 | 25 | |
| 26 | 26 | #if __has_builtin(__is_scalar) |
| 27 | 27 | |
| 28 | template<class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> { }; | |
| 28 | template <class _Tp> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS is_scalar : _BoolConstant<__is_scalar(_Tp)> {}; | |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 14 | |
| 31 | # if _LIBCPP_STD_VER >= 17 | |
| 32 | 32 | template <class _Tp> |
| 33 | 33 | inline constexpr bool is_scalar_v = __is_scalar(_Tp); |
| 34 | #endif | |
| 34 | # endif | |
| 35 | 35 | |
| 36 | 36 | #else // __has_builtin(__is_scalar) |
| 37 | 37 | |
| 38 | template <class _Tp> struct __is_block : false_type {}; | |
| 39 | #if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) | |
| 40 | template <class _Rp, class ..._Args> struct __is_block<_Rp (^)(_Args...)> : true_type {}; | |
| 41 | #endif | |
| 38 | template <class _Tp> | |
| 39 | struct __is_block : false_type {}; | |
| 40 | # if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) | |
| 41 | template <class _Rp, class... _Args> | |
| 42 | struct __is_block<_Rp (^)(_Args...)> : true_type {}; | |
| 43 | # endif | |
| 42 | 44 | |
| 43 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_scalar | |
| 44 | : public integral_constant<bool, is_arithmetic<_Tp>::value || | |
| 45 | is_member_pointer<_Tp>::value || | |
| 46 | is_pointer<_Tp>::value || | |
| 47 | __is_nullptr_t<_Tp>::value || | |
| 48 | __is_block<_Tp>::value || | |
| 49 | is_enum<_Tp>::value > {}; | |
| 45 | // clang-format off | |
| 46 | template <class _Tp> | |
| 47 | struct _LIBCPP_TEMPLATE_VIS is_scalar | |
| 48 | : public integral_constant< | |
| 49 | bool, is_arithmetic<_Tp>::value || | |
| 50 | is_member_pointer<_Tp>::value || | |
| 51 | is_pointer<_Tp>::value || | |
| 52 | __is_nullptr_t<_Tp>::value || | |
| 53 | __is_block<_Tp>::value || | |
| 54 | is_enum<_Tp>::value> {}; | |
| 55 | // clang-format on | |
| 50 | 56 | |
| 51 | template <> struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {}; | |
| 57 | template <> | |
| 58 | struct _LIBCPP_TEMPLATE_VIS is_scalar<nullptr_t> : public true_type {}; | |
| 52 | 59 | |
| 53 | #if _LIBCPP_STD_VER > 14 | |
| 60 | # if _LIBCPP_STD_VER >= 17 | |
| 54 | 61 | template <class _Tp> |
| 55 | 62 | inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; |
| 56 | #endif | |
| 63 | # endif | |
| 57 | 64 | |
| 58 | 65 | #endif // __has_builtin(__is_scalar) |
| 59 | 66 |
lib/libcxx/include/__type_traits/is_scoped_enum.h+3-5| ... | ... | @@ -21,17 +21,15 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 20 | |
| 24 | #if _LIBCPP_STD_VER >= 23 | |
| 25 | 25 | template <class _Tp, bool = is_enum_v<_Tp> > |
| 26 | 26 | struct __is_scoped_enum_helper : false_type {}; |
| 27 | 27 | |
| 28 | 28 | template <class _Tp> |
| 29 | struct __is_scoped_enum_helper<_Tp, true> | |
| 30 | : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {}; | |
| 29 | struct __is_scoped_enum_helper<_Tp, true> : public bool_constant<!is_convertible_v<_Tp, underlying_type_t<_Tp> > > {}; | |
| 31 | 30 | |
| 32 | 31 | template <class _Tp> |
| 33 | struct _LIBCPP_TEMPLATE_VIS is_scoped_enum | |
| 34 | : public __is_scoped_enum_helper<_Tp> {}; | |
| 32 | struct _LIBCPP_TEMPLATE_VIS is_scoped_enum : public __is_scoped_enum_helper<_Tp> {}; | |
| 35 | 33 | |
| 36 | 34 | template <class _Tp> |
| 37 | 35 | inline constexpr bool is_scoped_enum_v = is_scoped_enum<_Tp>::value; |
lib/libcxx/include/__type_traits/is_signed.h+11-9| ... | ... | @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | #if __has_builtin(__is_signed) |
| 24 | 24 | |
| 25 | template<class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> { }; | |
| 25 | template <class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_signed : _BoolConstant<__is_signed(_Tp)> {}; | |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 28 | # if _LIBCPP_STD_VER >= 17 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | inline constexpr bool is_signed_v = __is_signed(_Tp); |
| 31 | #endif | |
| 31 | # endif | |
| 32 | 32 | |
| 33 | 33 | #else // __has_builtin(__is_signed) |
| 34 | 34 | |
| ... | ... | @@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value> |
| 36 | 36 | struct __libcpp_is_signed_impl : public _BoolConstant<(_Tp(-1) < _Tp(0))> {}; |
| 37 | 37 | |
| 38 | 38 | template <class _Tp> |
| 39 | struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point | |
| 39 | struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point | |
| 40 | 40 | |
| 41 | 41 | template <class _Tp, bool = is_arithmetic<_Tp>::value> |
| 42 | 42 | struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {}; |
| 43 | 43 | |
| 44 | template <class _Tp> struct __libcpp_is_signed<_Tp, false> : public false_type {}; | |
| 44 | template <class _Tp> | |
| 45 | struct __libcpp_is_signed<_Tp, false> : public false_type {}; | |
| 45 | 46 | |
| 46 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {}; | |
| 47 | template <class _Tp> | |
| 48 | struct _LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {}; | |
| 47 | 49 | |
| 48 | #if _LIBCPP_STD_VER > 14 | |
| 50 | # if _LIBCPP_STD_VER >= 17 | |
| 49 | 51 | template <class _Tp> |
| 50 | 52 | inline constexpr bool is_signed_v = is_signed<_Tp>::value; |
| 51 | #endif | |
| 53 | # endif | |
| 52 | 54 | |
| 53 | 55 | #endif // __has_builtin(__is_signed) |
| 54 | 56 |
lib/libcxx/include/__type_traits/is_signed_integer.h+9-7| ... | ... | @@ -18,15 +18,17 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct __libcpp_is_signed_integer : public false_type {}; | |
| 22 | template <> struct __libcpp_is_signed_integer<signed char> : public true_type {}; | |
| 23 | template <> struct __libcpp_is_signed_integer<signed short> : public true_type {}; | |
| 24 | template <> struct __libcpp_is_signed_integer<signed int> : public true_type {}; | |
| 25 | template <> struct __libcpp_is_signed_integer<signed long> : public true_type {}; | |
| 26 | template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {}; | |
| 21 | // clang-format off | |
| 22 | template <class _Tp> struct __libcpp_is_signed_integer : public false_type {}; | |
| 23 | template <> struct __libcpp_is_signed_integer<signed char> : public true_type {}; | |
| 24 | template <> struct __libcpp_is_signed_integer<signed short> : public true_type {}; | |
| 25 | template <> struct __libcpp_is_signed_integer<signed int> : public true_type {}; | |
| 26 | template <> struct __libcpp_is_signed_integer<signed long> : public true_type {}; | |
| 27 | template <> struct __libcpp_is_signed_integer<signed long long> : public true_type {}; | |
| 27 | 28 | #ifndef _LIBCPP_HAS_NO_INT128 |
| 28 | template <> struct __libcpp_is_signed_integer<__int128_t> : public true_type {}; | |
| 29 | template <> struct __libcpp_is_signed_integer<__int128_t> : public true_type {}; | |
| 29 | 30 | #endif |
| 31 | // clang-format on | |
| 30 | 32 | |
| 31 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 34 |
lib/libcxx/include/__type_traits/is_specialization.h+2-2| ... | ... | @@ -30,7 +30,7 @@ |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | #if _LIBCPP_STD_VER > 14 | |
| 33 | #if _LIBCPP_STD_VER >= 17 | |
| 34 | 34 | |
| 35 | 35 | template <class _Tp, template <class...> class _Template> |
| 36 | 36 | inline constexpr bool __is_specialization_v = false; // true if and only if _Tp is a specialization of _Template |
| ... | ... | @@ -38,7 +38,7 @@ inline constexpr bool __is_specialization_v = false; // true if and only if _Tp |
| 38 | 38 | template <template <class...> class _Template, class... _Args> |
| 39 | 39 | inline constexpr bool __is_specialization_v<_Template<_Args...>, _Template> = true; |
| 40 | 40 | |
| 41 | #endif // _LIBCPP_STD_VER > 14 | |
| 41 | #endif // _LIBCPP_STD_VER >= 17 | |
| 42 | 42 | |
| 43 | 43 | _LIBCPP_END_NAMESPACE_STD |
| 44 | 44 |
lib/libcxx/include/__type_traits/is_standard_layout.h+3-4| ... | ... | @@ -18,11 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_standard_layout | |
| 22 | : public integral_constant<bool, __is_standard_layout(_Tp)> | |
| 23 | {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_standard_layout : public integral_constant<bool, __is_standard_layout(_Tp)> {}; | |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | template <class _Tp> |
| 27 | 26 | inline constexpr bool is_standard_layout_v = __is_standard_layout(_Tp); |
| 28 | 27 | #endif |
lib/libcxx/include/__type_traits/is_swappable.h+37-67| ... | ... | @@ -30,9 +30,10 @@ |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 32 | 32 | |
| 33 | template <class _Tp> struct __is_swappable; | |
| 34 | template <class _Tp> struct __is_nothrow_swappable; | |
| 35 | ||
| 33 | template <class _Tp> | |
| 34 | struct __is_swappable; | |
| 35 | template <class _Tp> | |
| 36 | struct __is_nothrow_swappable; | |
| 36 | 37 | |
| 37 | 38 | #ifndef _LIBCPP_CXX03_LANG |
| 38 | 39 | template <class _Tp> |
| ... | ... | @@ -43,49 +44,40 @@ using __swap_result_t = void; |
| 43 | 44 | #endif |
| 44 | 45 | |
| 45 | 46 | template <class _Tp> |
| 46 | inline _LIBCPP_INLINE_VISIBILITY | |
| 47 | _LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp> | |
| 48 | swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && | |
| 49 | is_nothrow_move_assignable<_Tp>::value); | |
| 47 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __swap_result_t<_Tp> swap(_Tp& __x, _Tp& __y) | |
| 48 | _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value&& is_nothrow_move_assignable<_Tp>::value); | |
| 50 | 49 | |
| 51 | template<class _Tp, size_t _Np> | |
| 50 | template <class _Tp, size_t _Np> | |
| 52 | 51 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 53 | typename enable_if< | |
| 54 | __is_swappable<_Tp>::value | |
| 55 | >::type | |
| 56 | swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); | |
| 52 | typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) | |
| 53 | _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); | |
| 57 | 54 | |
| 58 | namespace __detail | |
| 59 | { | |
| 55 | namespace __detail { | |
| 60 | 56 | // ALL generic swap overloads MUST already have a declaration available at this point. |
| 61 | 57 | |
| 62 | template <class _Tp, class _Up = _Tp, | |
| 63 | bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> | |
| 64 | struct __swappable_with | |
| 65 | { | |
| 66 | template <class _LHS, class _RHS> | |
| 67 | static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>())) | |
| 68 | __test_swap(int); | |
| 69 | template <class, class> | |
| 70 | static __nat __test_swap(long); | |
| 71 | ||
| 72 | // Extra parens are needed for the C++03 definition of decltype. | |
| 73 | typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; | |
| 74 | typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; | |
| 75 | ||
| 76 | static const bool value = _IsNotSame<__swap1, __nat>::value | |
| 77 | && _IsNotSame<__swap2, __nat>::value; | |
| 58 | template <class _Tp, class _Up = _Tp, bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> | |
| 59 | struct __swappable_with { | |
| 60 | template <class _LHS, class _RHS> | |
| 61 | static decltype(swap(std::declval<_LHS>(), std::declval<_RHS>())) __test_swap(int); | |
| 62 | template <class, class> | |
| 63 | static __nat __test_swap(long); | |
| 64 | ||
| 65 | // Extra parens are needed for the C++03 definition of decltype. | |
| 66 | typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; | |
| 67 | typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; | |
| 68 | ||
| 69 | static const bool value = _IsNotSame<__swap1, __nat>::value && _IsNotSame<__swap2, __nat>::value; | |
| 78 | 70 | }; |
| 79 | 71 | |
| 80 | 72 | template <class _Tp, class _Up> |
| 81 | struct __swappable_with<_Tp, _Up, false> : false_type {}; | |
| 73 | struct __swappable_with<_Tp, _Up, false> : false_type {}; | |
| 82 | 74 | |
| 83 | 75 | template <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value> |
| 84 | 76 | struct __nothrow_swappable_with { |
| 85 | 77 | static const bool value = |
| 86 | 78 | #ifndef _LIBCPP_HAS_NO_NOEXCEPT |
| 87 | noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())) | |
| 88 | && noexcept(swap(std::declval<_Up>(), std::declval<_Tp>())); | |
| 79 | noexcept(swap(std::declval<_Tp>(), std::declval<_Up>()))&& noexcept( | |
| 80 | swap(std::declval<_Up>(), std::declval<_Tp>())); | |
| 89 | 81 | #else |
| 90 | 82 | false; |
| 91 | 83 | #endif |
| ... | ... | @@ -97,54 +89,32 @@ struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; |
| 97 | 89 | } // namespace __detail |
| 98 | 90 | |
| 99 | 91 | template <class _Tp> |
| 100 | struct __is_swappable | |
| 101 | : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> | |
| 102 | { | |
| 103 | }; | |
| 92 | struct __is_swappable : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> {}; | |
| 104 | 93 | |
| 105 | 94 | template <class _Tp> |
| 106 | struct __is_nothrow_swappable | |
| 107 | : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> | |
| 108 | { | |
| 109 | }; | |
| 95 | struct __is_nothrow_swappable : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> {}; | |
| 110 | 96 | |
| 111 | #if _LIBCPP_STD_VER > 14 | |
| 97 | #if _LIBCPP_STD_VER >= 17 | |
| 112 | 98 | |
| 113 | 99 | template <class _Tp, class _Up> |
| 114 | 100 | struct _LIBCPP_TEMPLATE_VIS is_swappable_with |
| 115 | : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> | |
| 116 | { | |
| 117 | }; | |
| 101 | : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> {}; | |
| 118 | 102 | |
| 119 | 103 | template <class _Tp> |
| 120 | 104 | struct _LIBCPP_TEMPLATE_VIS is_swappable |
| 121 | : public __conditional_t< | |
| 122 | __libcpp_is_referenceable<_Tp>::value, | |
| 123 | is_swappable_with< | |
| 124 | __add_lvalue_reference_t<_Tp>, | |
| 125 | __add_lvalue_reference_t<_Tp> >, | |
| 126 | false_type | |
| 127 | > | |
| 128 | { | |
| 129 | }; | |
| 105 | : public __conditional_t<__libcpp_is_referenceable<_Tp>::value, | |
| 106 | is_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >, | |
| 107 | false_type> {}; | |
| 130 | 108 | |
| 131 | 109 | template <class _Tp, class _Up> |
| 132 | 110 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with |
| 133 | : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> | |
| 134 | { | |
| 135 | }; | |
| 111 | : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> {}; | |
| 136 | 112 | |
| 137 | 113 | template <class _Tp> |
| 138 | 114 | struct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable |
| 139 | : public __conditional_t< | |
| 140 | __libcpp_is_referenceable<_Tp>::value, | |
| 141 | is_nothrow_swappable_with< | |
| 142 | __add_lvalue_reference_t<_Tp>, | |
| 143 | __add_lvalue_reference_t<_Tp> >, | |
| 144 | false_type | |
| 145 | > | |
| 146 | { | |
| 147 | }; | |
| 115 | : public __conditional_t<__libcpp_is_referenceable<_Tp>::value, | |
| 116 | is_nothrow_swappable_with<__add_lvalue_reference_t<_Tp>, __add_lvalue_reference_t<_Tp> >, | |
| 117 | false_type> {}; | |
| 148 | 118 | |
| 149 | 119 | template <class _Tp, class _Up> |
| 150 | 120 | inline constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; |
| ... | ... | @@ -158,7 +128,7 @@ inline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_T |
| 158 | 128 | template <class _Tp> |
| 159 | 129 | inline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; |
| 160 | 130 | |
| 161 | #endif // _LIBCPP_STD_VER > 14 | |
| 131 | #endif // _LIBCPP_STD_VER >= 17 | |
| 162 | 132 | |
| 163 | 133 | _LIBCPP_END_NAMESPACE_STD |
| 164 | 134 |
lib/libcxx/include/__type_traits/is_trivial.h+3-4| ... | ... | @@ -18,11 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivial | |
| 22 | : public integral_constant<bool, __is_trivial(_Tp)> | |
| 23 | {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_trivial : public integral_constant<bool, __is_trivial(_Tp)> {}; | |
| 24 | 23 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 25 | template <class _Tp> |
| 27 | 26 | inline constexpr bool is_trivial_v = __is_trivial(_Tp); |
| 28 | 27 | #endif |
lib/libcxx/include/__type_traits/is_trivially_assignable.h+2-4| ... | ... | @@ -19,11 +19,9 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp, class _Arg> |
| 22 | struct is_trivially_assignable | |
| 23 | : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> | |
| 24 | { }; | |
| 22 | struct is_trivially_assignable : integral_constant<bool, __is_trivially_assignable(_Tp, _Arg)> {}; | |
| 25 | 23 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 25 | template <class _Tp, class _Arg> |
| 28 | 26 | inline constexpr bool is_trivially_assignable_v = __is_trivially_assignable(_Tp, _Arg); |
| 29 | 27 | #endif |
lib/libcxx/include/__type_traits/is_trivially_constructible.h+2-4| ... | ... | @@ -20,11 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Tp, class... _Args> |
| 22 | 22 | struct _LIBCPP_TEMPLATE_VIS is_trivially_constructible |
| 23 | : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> | |
| 24 | { | |
| 25 | }; | |
| 23 | : integral_constant<bool, __is_trivially_constructible(_Tp, _Args...)> {}; | |
| 26 | 24 | |
| 27 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 28 | 26 | template <class _Tp, class... _Args> |
| 29 | 27 | inline constexpr bool is_trivially_constructible_v = __is_trivially_constructible(_Tp, _Args...); |
| 30 | 28 | #endif |
lib/libcxx/include/__type_traits/is_trivially_copy_assignable.h+4-6| ... | ... | @@ -22,13 +22,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable |
| 25 | : public integral_constant< | |
| 26 | bool, | |
| 27 | __is_trivially_assignable( | |
| 28 | __add_lvalue_reference_t<_Tp>, | |
| 29 | __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 25 | : public integral_constant<bool, | |
| 26 | __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, | |
| 27 | __add_lvalue_reference_t<typename add_const<_Tp>::type>)> {}; | |
| 30 | 28 | |
| 31 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 32 | 30 | template <class _Tp> |
| 33 | 31 | inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value; |
| 34 | 32 | #endif |
lib/libcxx/include/__type_traits/is_trivially_copy_constructible.h+4-4| ... | ... | @@ -19,11 +19,11 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible | |
| 23 | : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> | |
| 24 | {}; | |
| 22 | template <class _Tp> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible | |
| 24 | : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_lvalue_reference_t<const _Tp>)> {}; | |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value; |
| 29 | 29 | #endif |
lib/libcxx/include/__type_traits/is_trivially_copyable.h+9-4| ... | ... | @@ -11,6 +11,7 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__config> |
| 13 | 13 | #include <__type_traits/integral_constant.h> |
| 14 | #include <cstdint> | |
| 14 | 15 | |
| 15 | 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 16 | 17 | # pragma GCC system_header |
| ... | ... | @@ -18,15 +19,19 @@ |
| 18 | 19 | |
| 19 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 21 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable | |
| 22 | : public integral_constant<bool, __is_trivially_copyable(_Tp)> | |
| 23 | {}; | |
| 22 | template <class _Tp> | |
| 23 | struct _LIBCPP_TEMPLATE_VIS is_trivially_copyable : public integral_constant<bool, __is_trivially_copyable(_Tp)> {}; | |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | inline constexpr bool is_trivially_copyable_v = __is_trivially_copyable(_Tp); |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | template <class _Tp> | |
| 32 | inline constexpr bool __is_cheap_to_copy = is_trivially_copyable_v<_Tp> && sizeof(_Tp) <= sizeof(std::intmax_t); | |
| 33 | #endif | |
| 34 | ||
| 30 | 35 | _LIBCPP_END_NAMESPACE_STD |
| 31 | 36 | |
| 32 | 37 | #endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_H |
lib/libcxx/include/__type_traits/is_trivially_default_constructible.h+4-4| ... | ... | @@ -18,11 +18,11 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible | |
| 22 | : public integral_constant<bool, __is_trivially_constructible(_Tp)> | |
| 23 | {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_trivially_default_constructible | |
| 23 | : public integral_constant<bool, __is_trivially_constructible(_Tp)> {}; | |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 14 | |
| 25 | #if _LIBCPP_STD_VER >= 17 | |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | inline constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(_Tp); |
| 28 | 28 | #endif |
lib/libcxx/include/__type_traits/is_trivially_destructible.h+7-5| ... | ... | @@ -21,21 +21,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | #if __has_builtin(__is_trivially_destructible) |
| 23 | 23 | |
| 24 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible | |
| 24 | template <class _Tp> | |
| 25 | struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible | |
| 25 | 26 | : public integral_constant<bool, __is_trivially_destructible(_Tp)> {}; |
| 26 | 27 | |
| 27 | 28 | #elif __has_builtin(__has_trivial_destructor) |
| 28 | 29 | |
| 29 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible | |
| 30 | : public integral_constant<bool, is_destructible<_Tp>::value && __has_trivial_destructor(_Tp)> {}; | |
| 30 | template <class _Tp> | |
| 31 | struct _LIBCPP_TEMPLATE_VIS is_trivially_destructible | |
| 32 | : public integral_constant<bool, is_destructible<_Tp>::value&& __has_trivial_destructor(_Tp)> {}; | |
| 31 | 33 | |
| 32 | 34 | #else |
| 33 | 35 | |
| 34 | #error is_trivially_destructible is not implemented | |
| 36 | # error is_trivially_destructible is not implemented | |
| 35 | 37 | |
| 36 | 38 | #endif // __has_builtin(__is_trivially_destructible) |
| 37 | 39 | |
| 38 | #if _LIBCPP_STD_VER > 14 | |
| 40 | #if _LIBCPP_STD_VER >= 17 | |
| 39 | 41 | template <class _Tp> |
| 40 | 42 | inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; |
| 41 | 43 | #endif |
lib/libcxx/include/__type_traits/is_trivially_lexicographically_comparable.h created+53| ... | ... | @@ -0,0 +1,53 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/integral_constant.h> | |
| 14 | #include <__type_traits/is_same.h> | |
| 15 | #include <__type_traits/is_unsigned.h> | |
| 16 | #include <__type_traits/remove_cv.h> | |
| 17 | #include <__type_traits/void_t.h> | |
| 18 | #include <__utility/declval.h> | |
| 19 | ||
| 20 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 21 | # pragma GCC system_header | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | // A type is_trivially_lexicographically_comparable if the expression `a <=> b` (or their pre-C++20 equivalents) is | |
| 27 | // equivalent to `std::memcmp(&a, &b, sizeof(T))` (with `a` and `b` being of type `T`). There is currently no builtin to | |
| 28 | // tell us whether that's the case for arbitrary types, so we can only do this for known types. Specifically, these are | |
| 29 | // currently unsigned integer types with a sizeof(T) == 1. | |
| 30 | // | |
| 31 | // bool is trivially lexicographically comparable, because e.g. false <=> true is valid code. Furthermore, the standard | |
| 32 | // says that [basic.fundamental] "Type bool is a distinct type that has the same object representation, value | |
| 33 | // representation, and alignment requirements as an implementation-defined unsigned integer type. The values of type | |
| 34 | // bool are true and false." | |
| 35 | // This means that bool has to be unsigned and has exactly two values. This means that having anything other than the | |
| 36 | // `true` or `false` value representations in a bool is UB. | |
| 37 | // | |
| 38 | // The following types are not trivially lexicographically comparable: | |
| 39 | // signed integer types: `char(-1) < char(1)`, but memcmp compares `unsigned char`s | |
| 40 | // unsigned integer types with sizeof(T) > 1: depending on the endianness, the LSB might be the first byte to be | |
| 41 | // compared. This means that when comparing unsigned(129) and unsigned(2) | |
| 42 | // using memcmp(), the result would be that 2 > 129. | |
| 43 | // TODO: Do we want to enable this on big-endian systems? | |
| 44 | ||
| 45 | template <class _Tp, class _Up> | |
| 46 | struct __libcpp_is_trivially_lexicographically_comparable | |
| 47 | : integral_constant<bool, | |
| 48 | is_same<__remove_cv_t<_Tp>, __remove_cv_t<_Up> >::value && sizeof(_Tp) == 1 && | |
| 49 | is_unsigned<_Tp>::value> {}; | |
| 50 | ||
| 51 | _LIBCPP_END_NAMESPACE_STD | |
| 52 | ||
| 53 | #endif // _LIBCPP___TYPE_TRAITS_IS_TRIVIALLY_LEXICOGRAPHICALLY_COMPARABLE_H |
lib/libcxx/include/__type_traits/is_trivially_move_assignable.h+1-1| ... | ... | @@ -26,7 +26,7 @@ struct _LIBCPP_TEMPLATE_VIS is_trivially_move_assignable |
| 26 | 26 | bool, |
| 27 | 27 | __is_trivially_assignable(__add_lvalue_reference_t<_Tp>, __add_rvalue_reference_t<_Tp>)> {}; |
| 28 | 28 | |
| 29 | #if _LIBCPP_STD_VER > 14 | |
| 29 | #if _LIBCPP_STD_VER >= 17 | |
| 30 | 30 | template <class _Tp> |
| 31 | 31 | inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value; |
| 32 | 32 | #endif |
lib/libcxx/include/__type_traits/is_trivially_move_constructible.h+1-1| ... | ... | @@ -23,7 +23,7 @@ template <class _Tp> |
| 23 | 23 | struct _LIBCPP_TEMPLATE_VIS is_trivially_move_constructible |
| 24 | 24 | : public integral_constant<bool, __is_trivially_constructible(_Tp, __add_rvalue_reference_t<_Tp>)> {}; |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | #if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value; |
| 29 | 29 | #endif |
lib/libcxx/include/__type_traits/is_unbounded_array.h+10-7| ... | ... | @@ -18,17 +18,20 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {}; | |
| 22 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {}; | |
| 21 | template <class> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array : false_type {}; | |
| 23 | template <class _Tp> | |
| 24 | struct _LIBCPP_TEMPLATE_VIS __libcpp_is_unbounded_array<_Tp[]> : true_type {}; | |
| 23 | 25 | |
| 24 | #if _LIBCPP_STD_VER > 17 | |
| 26 | #if _LIBCPP_STD_VER >= 20 | |
| 25 | 27 | |
| 26 | template <class> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {}; | |
| 27 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {}; | |
| 28 | template <class> | |
| 29 | struct _LIBCPP_TEMPLATE_VIS is_unbounded_array : false_type {}; | |
| 30 | template <class _Tp> | |
| 31 | struct _LIBCPP_TEMPLATE_VIS is_unbounded_array<_Tp[]> : true_type {}; | |
| 28 | 32 | |
| 29 | 33 | template <class _Tp> |
| 30 | inline constexpr | |
| 31 | bool is_unbounded_array_v = is_unbounded_array<_Tp>::value; | |
| 34 | inline constexpr bool is_unbounded_array_v = is_unbounded_array<_Tp>::value; | |
| 32 | 35 | |
| 33 | 36 | #endif |
| 34 | 37 |
lib/libcxx/include/__type_traits/is_union.h+3-3| ... | ... | @@ -18,10 +18,10 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_union | |
| 22 | : public integral_constant<bool, __is_union(_Tp)> {}; | |
| 21 | template <class _Tp> | |
| 22 | struct _LIBCPP_TEMPLATE_VIS is_union : public integral_constant<bool, __is_union(_Tp)> {}; | |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | inline constexpr bool is_union_v = __is_union(_Tp); |
| 27 | 27 | #endif |
lib/libcxx/include/__type_traits/is_unsigned.h+11-9| ... | ... | @@ -22,13 +22,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | 23 | #if __has_builtin(__is_unsigned) |
| 24 | 24 | |
| 25 | template<class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> { }; | |
| 25 | template <class _Tp> | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {}; | |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 28 | # if _LIBCPP_STD_VER >= 17 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | inline constexpr bool is_unsigned_v = __is_unsigned(_Tp); |
| 31 | #endif | |
| 31 | # endif | |
| 32 | 32 | |
| 33 | 33 | #else // __has_builtin(__is_unsigned) |
| 34 | 34 | |
| ... | ... | @@ -36,19 +36,21 @@ template <class _Tp, bool = is_integral<_Tp>::value> |
| 36 | 36 | struct __libcpp_is_unsigned_impl : public _BoolConstant<(_Tp(0) < _Tp(-1))> {}; |
| 37 | 37 | |
| 38 | 38 | template <class _Tp> |
| 39 | struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point | |
| 39 | struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point | |
| 40 | 40 | |
| 41 | 41 | template <class _Tp, bool = is_arithmetic<_Tp>::value> |
| 42 | 42 | struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {}; |
| 43 | 43 | |
| 44 | template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {}; | |
| 44 | template <class _Tp> | |
| 45 | struct __libcpp_is_unsigned<_Tp, false> : public false_type {}; | |
| 45 | 46 | |
| 46 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {}; | |
| 47 | template <class _Tp> | |
| 48 | struct _LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {}; | |
| 47 | 49 | |
| 48 | #if _LIBCPP_STD_VER > 14 | |
| 50 | # if _LIBCPP_STD_VER >= 17 | |
| 49 | 51 | template <class _Tp> |
| 50 | 52 | inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; |
| 51 | #endif | |
| 53 | # endif | |
| 52 | 54 | |
| 53 | 55 | #endif // __has_builtin(__is_unsigned) |
| 54 | 56 |
lib/libcxx/include/__type_traits/is_unsigned_integer.h+9-7| ... | ... | @@ -18,15 +18,17 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {}; | |
| 22 | template <> struct __libcpp_is_unsigned_integer<unsigned char> : public true_type {}; | |
| 23 | template <> struct __libcpp_is_unsigned_integer<unsigned short> : public true_type {}; | |
| 24 | template <> struct __libcpp_is_unsigned_integer<unsigned int> : public true_type {}; | |
| 25 | template <> struct __libcpp_is_unsigned_integer<unsigned long> : public true_type {}; | |
| 26 | template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {}; | |
| 21 | // clang-format off | |
| 22 | template <class _Tp> struct __libcpp_is_unsigned_integer : public false_type {}; | |
| 23 | template <> struct __libcpp_is_unsigned_integer<unsigned char> : public true_type {}; | |
| 24 | template <> struct __libcpp_is_unsigned_integer<unsigned short> : public true_type {}; | |
| 25 | template <> struct __libcpp_is_unsigned_integer<unsigned int> : public true_type {}; | |
| 26 | template <> struct __libcpp_is_unsigned_integer<unsigned long> : public true_type {}; | |
| 27 | template <> struct __libcpp_is_unsigned_integer<unsigned long long> : public true_type {}; | |
| 27 | 28 | #ifndef _LIBCPP_HAS_NO_INT128 |
| 28 | template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {}; | |
| 29 | template <> struct __libcpp_is_unsigned_integer<__uint128_t> : public true_type {}; | |
| 29 | 30 | #endif |
| 31 | // clang-format on | |
| 30 | 32 | |
| 31 | 33 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 34 |
lib/libcxx/include/__type_traits/is_valid_expansion.h+3-3| ... | ... | @@ -18,12 +18,12 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <template <class...> class _Templ, class ..._Args, class = _Templ<_Args...> > | |
| 21 | template <template <class...> class _Templ, class... _Args, class = _Templ<_Args...> > | |
| 22 | 22 | true_type __sfinae_test_impl(int); |
| 23 | template <template <class...> class, class ...> | |
| 23 | template <template <class...> class, class...> | |
| 24 | 24 | false_type __sfinae_test_impl(...); |
| 25 | 25 | |
| 26 | template <template <class ...> class _Templ, class ..._Args> | |
| 26 | template <template <class...> class _Templ, class... _Args> | |
| 27 | 27 | using _IsValidExpansion _LIBCPP_NODEBUG = decltype(std::__sfinae_test_impl<_Templ, _Args...>(0)); |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/is_void.h+7-7| ... | ... | @@ -23,22 +23,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | #if __has_builtin(__is_void) |
| 24 | 24 | |
| 25 | 25 | template <class _Tp> |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> { }; | |
| 26 | struct _LIBCPP_TEMPLATE_VIS is_void : _BoolConstant<__is_void(_Tp)> {}; | |
| 27 | 27 | |
| 28 | #if _LIBCPP_STD_VER > 14 | |
| 28 | # if _LIBCPP_STD_VER >= 17 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | inline constexpr bool is_void_v = __is_void(_Tp); |
| 31 | #endif | |
| 31 | # endif | |
| 32 | 32 | |
| 33 | 33 | #else |
| 34 | 34 | |
| 35 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_void | |
| 36 | : public is_same<__remove_cv_t<_Tp>, void> {}; | |
| 35 | template <class _Tp> | |
| 36 | struct _LIBCPP_TEMPLATE_VIS is_void : public is_same<__remove_cv_t<_Tp>, void> {}; | |
| 37 | 37 | |
| 38 | #if _LIBCPP_STD_VER > 14 | |
| 38 | # if _LIBCPP_STD_VER >= 17 | |
| 39 | 39 | template <class _Tp> |
| 40 | 40 | inline constexpr bool is_void_v = is_void<_Tp>::value; |
| 41 | #endif | |
| 41 | # endif | |
| 42 | 42 | |
| 43 | 43 | #endif // __has_builtin(__is_void) |
| 44 | 44 |
lib/libcxx/include/__type_traits/is_volatile.h+9-7| ... | ... | @@ -21,22 +21,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | #if __has_builtin(__is_volatile) |
| 22 | 22 | |
| 23 | 23 | template <class _Tp> |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> { }; | |
| 24 | struct _LIBCPP_TEMPLATE_VIS is_volatile : _BoolConstant<__is_volatile(_Tp)> {}; | |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 26 | # if _LIBCPP_STD_VER >= 17 | |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | inline constexpr bool is_volatile_v = __is_volatile(_Tp); |
| 29 | #endif | |
| 29 | # endif | |
| 30 | 30 | |
| 31 | 31 | #else |
| 32 | 32 | |
| 33 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; | |
| 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; | |
| 33 | template <class _Tp> | |
| 34 | struct _LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; | |
| 35 | template <class _Tp> | |
| 36 | struct _LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; | |
| 35 | 37 | |
| 36 | #if _LIBCPP_STD_VER > 14 | |
| 38 | # if _LIBCPP_STD_VER >= 17 | |
| 37 | 39 | template <class _Tp> |
| 38 | 40 | inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; |
| 39 | #endif | |
| 41 | # endif | |
| 40 | 42 | |
| 41 | 43 | #endif // __has_builtin(__is_volatile) |
| 42 | 44 |
lib/libcxx/include/__type_traits/lazy.h+1-1| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | template <template <class...> class _Func, class ..._Args> | |
| 20 | template <template <class...> class _Func, class... _Args> | |
| 21 | 21 | struct _Lazy : _Func<_Args...> {}; |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/make_32_64_or_128_bit.h+11-10| ... | ... | @@ -27,21 +27,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | /// |
| 28 | 28 | /// The restriction is the same as the integral version of to_char. |
| 29 | 29 | template <class _Tp> |
| 30 | #if _LIBCPP_STD_VER > 17 | |
| 31 | requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>) | |
| 30 | #if _LIBCPP_STD_VER >= 20 | |
| 31 | requires(is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>) | |
| 32 | 32 | #endif |
| 33 | // clang-format off | |
| 33 | 34 | using __make_32_64_or_128_bit_t = |
| 34 | __copy_unsigned_t<_Tp, | |
| 35 | __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t, | |
| 36 | __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t, | |
| 35 | __copy_unsigned_t<_Tp, | |
| 36 | __conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t, | |
| 37 | __conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t, | |
| 37 | 38 | #ifndef _LIBCPP_HAS_NO_INT128 |
| 38 | __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t, | |
| 39 | /* else */ void> | |
| 39 | __conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t, | |
| 40 | /* else */ void> | |
| 40 | 41 | #else |
| 41 | /* else */ void | |
| 42 | /* else */ void | |
| 42 | 43 | #endif |
| 43 | > > | |
| 44 | >; | |
| 44 | > > >; | |
| 45 | // clang-format on | |
| 45 | 46 | |
| 46 | 47 | _LIBCPP_END_NAMESPACE_STD |
| 47 | 48 |
lib/libcxx/include/__type_traits/make_const_lvalue_ref.h+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template<class _Tp> | |
| 21 | template <class _Tp> | |
| 22 | 22 | using __make_const_lvalue_ref = const __libcpp_remove_reference_t<_Tp>&; |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/make_signed.h+20-17| ... | ... | @@ -29,30 +29,31 @@ template <class _Tp> |
| 29 | 29 | using __make_signed_t = __make_signed(_Tp); |
| 30 | 30 | |
| 31 | 31 | #else |
| 32 | typedef | |
| 33 | __type_list<signed char, | |
| 34 | __type_list<signed short, | |
| 35 | __type_list<signed int, | |
| 36 | __type_list<signed long, | |
| 37 | __type_list<signed long long, | |
| 32 | // clang-format off | |
| 33 | typedef __type_list<signed char, | |
| 34 | __type_list<signed short, | |
| 35 | __type_list<signed int, | |
| 36 | __type_list<signed long, | |
| 37 | __type_list<signed long long, | |
| 38 | 38 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 39 | __type_list<__int128_t, | |
| 39 | __type_list<__int128_t, | |
| 40 | 40 | # endif |
| 41 | __nat | |
| 41 | __nat | |
| 42 | 42 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 43 | > | |
| 43 | > | |
| 44 | 44 | # endif |
| 45 | > > > > > __signed_types; | |
| 45 | > > > > > __signed_types; | |
| 46 | // clang-format on | |
| 46 | 47 | |
| 47 | 48 | template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> |
| 48 | struct __make_signed {}; | |
| 49 | struct __make_signed{}; | |
| 49 | 50 | |
| 50 | 51 | template <class _Tp> |
| 51 | struct __make_signed<_Tp, true> | |
| 52 | { | |
| 53 | typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type; | |
| 52 | struct __make_signed<_Tp, true> { | |
| 53 | typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type; | |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | // clang-format off | |
| 56 | 57 | template <> struct __make_signed<bool, true> {}; |
| 57 | 58 | template <> struct __make_signed< signed short, true> {typedef short type;}; |
| 58 | 59 | template <> struct __make_signed<unsigned short, true> {typedef short type;}; |
| ... | ... | @@ -66,9 +67,10 @@ template <> struct __make_signed<unsigned long long, true> {typedef long long ty |
| 66 | 67 | template <> struct __make_signed<__int128_t, true> {typedef __int128_t type;}; |
| 67 | 68 | template <> struct __make_signed<__uint128_t, true> {typedef __int128_t type;}; |
| 68 | 69 | # endif |
| 70 | // clang-format on | |
| 69 | 71 | |
| 70 | 72 | template <class _Tp> |
| 71 | using __make_signed_t = typename __apply_cv<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>::type; | |
| 73 | using __make_signed_t = __apply_cv_t<_Tp, typename __make_signed<__remove_cv_t<_Tp> >::type>; | |
| 72 | 74 | |
| 73 | 75 | #endif // __has_builtin(__make_signed) |
| 74 | 76 | |
| ... | ... | @@ -77,8 +79,9 @@ struct make_signed { |
| 77 | 79 | using type _LIBCPP_NODEBUG = __make_signed_t<_Tp>; |
| 78 | 80 | }; |
| 79 | 81 | |
| 80 | #if _LIBCPP_STD_VER > 11 | |
| 81 | template <class _Tp> using make_signed_t = __make_signed_t<_Tp>; | |
| 82 | #if _LIBCPP_STD_VER >= 14 | |
| 83 | template <class _Tp> | |
| 84 | using make_signed_t = __make_signed_t<_Tp>; | |
| 82 | 85 | #endif |
| 83 | 86 | |
| 84 | 87 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/make_unsigned.h+22-20| ... | ... | @@ -31,30 +31,31 @@ template <class _Tp> |
| 31 | 31 | using __make_unsigned_t = __make_unsigned(_Tp); |
| 32 | 32 | |
| 33 | 33 | #else |
| 34 | typedef | |
| 35 | __type_list<unsigned char, | |
| 36 | __type_list<unsigned short, | |
| 37 | __type_list<unsigned int, | |
| 38 | __type_list<unsigned long, | |
| 39 | __type_list<unsigned long long, | |
| 34 | // clang-format off | |
| 35 | typedef __type_list<unsigned char, | |
| 36 | __type_list<unsigned short, | |
| 37 | __type_list<unsigned int, | |
| 38 | __type_list<unsigned long, | |
| 39 | __type_list<unsigned long long, | |
| 40 | 40 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 41 | __type_list<__uint128_t, | |
| 41 | __type_list<__uint128_t, | |
| 42 | 42 | # endif |
| 43 | __nat | |
| 43 | __nat | |
| 44 | 44 | # ifndef _LIBCPP_HAS_NO_INT128 |
| 45 | > | |
| 45 | > | |
| 46 | 46 | # endif |
| 47 | > > > > > __unsigned_types; | |
| 47 | > > > > > __unsigned_types; | |
| 48 | // clang-format on | |
| 48 | 49 | |
| 49 | 50 | template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value> |
| 50 | struct __make_unsigned {}; | |
| 51 | struct __make_unsigned{}; | |
| 51 | 52 | |
| 52 | 53 | template <class _Tp> |
| 53 | struct __make_unsigned<_Tp, true> | |
| 54 | { | |
| 55 | typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type; | |
| 54 | struct __make_unsigned<_Tp, true> { | |
| 55 | typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type; | |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | // clang-format off | |
| 58 | 59 | template <> struct __make_unsigned<bool, true> {}; |
| 59 | 60 | template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;}; |
| 60 | 61 | template <> struct __make_unsigned<unsigned short, true> {typedef unsigned short type;}; |
| ... | ... | @@ -68,9 +69,10 @@ template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned l |
| 68 | 69 | template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;}; |
| 69 | 70 | template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;}; |
| 70 | 71 | # endif |
| 72 | // clang-format on | |
| 71 | 73 | |
| 72 | 74 | template <class _Tp> |
| 73 | using __make_unsigned_t = typename __apply_cv<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>::type; | |
| 75 | using __make_unsigned_t = __apply_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp> >::type>; | |
| 74 | 76 | |
| 75 | 77 | #endif // __has_builtin(__make_unsigned) |
| 76 | 78 | |
| ... | ... | @@ -79,15 +81,15 @@ struct make_unsigned { |
| 79 | 81 | using type _LIBCPP_NODEBUG = __make_unsigned_t<_Tp>; |
| 80 | 82 | }; |
| 81 | 83 | |
| 82 | #if _LIBCPP_STD_VER > 11 | |
| 83 | template <class _Tp> using make_unsigned_t = __make_unsigned_t<_Tp>; | |
| 84 | #if _LIBCPP_STD_VER >= 14 | |
| 85 | template <class _Tp> | |
| 86 | using make_unsigned_t = __make_unsigned_t<_Tp>; | |
| 84 | 87 | #endif |
| 85 | 88 | |
| 86 | 89 | #ifndef _LIBCPP_CXX03_LANG |
| 87 | 90 | template <class _Tp> |
| 88 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 89 | __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept { | |
| 90 | return static_cast<__make_unsigned_t<_Tp> >(__x); | |
| 91 | _LIBCPP_HIDE_FROM_ABI constexpr __make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) noexcept { | |
| 92 | return static_cast<__make_unsigned_t<_Tp> >(__x); | |
| 91 | 93 | } |
| 92 | 94 | #endif |
| 93 | 95 |
lib/libcxx/include/__type_traits/maybe_const.h+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template<bool _Const, class _Tp> | |
| 21 | template <bool _Const, class _Tp> | |
| 22 | 22 | using __maybe_const = __conditional_t<_Const, const _Tp, _Tp>; |
| 23 | 23 | |
| 24 | 24 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/nat.h+5-6| ... | ... | @@ -17,13 +17,12 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | struct __nat | |
| 21 | { | |
| 20 | struct __nat { | |
| 22 | 21 | #ifndef _LIBCPP_CXX03_LANG |
| 23 | __nat() = delete; | |
| 24 | __nat(const __nat&) = delete; | |
| 25 | __nat& operator=(const __nat&) = delete; | |
| 26 | ~__nat() = delete; | |
| 22 | __nat() = delete; | |
| 23 | __nat(const __nat&) = delete; | |
| 24 | __nat& operator=(const __nat&) = delete; | |
| 25 | ~__nat() = delete; | |
| 27 | 26 | #endif |
| 28 | 27 | }; |
| 29 | 28 |
lib/libcxx/include/__type_traits/negation.h+3-3| ... | ... | @@ -21,12 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | template <class _Pred> |
| 22 | 22 | struct _Not : _BoolConstant<!_Pred::value> {}; |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | template <class _Tp> |
| 26 | 26 | struct negation : _Not<_Tp> {}; |
| 27 | template<class _Tp> | |
| 27 | template <class _Tp> | |
| 28 | 28 | inline constexpr bool negation_v = !_Tp::value; |
| 29 | #endif // _LIBCPP_STD_VER > 14 | |
| 29 | #endif // _LIBCPP_STD_VER >= 17 | |
| 30 | 30 | |
| 31 | 31 | _LIBCPP_END_NAMESPACE_STD |
| 32 | 32 |
lib/libcxx/include/__type_traits/noexcept_move_assign_container.h+9-7| ... | ... | @@ -20,15 +20,17 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> > | |
| 24 | struct __noexcept_move_assign_container : public integral_constant<bool, | |
| 25 | _Traits::propagate_on_container_move_assignment::value | |
| 26 | #if _LIBCPP_STD_VER > 14 | |
| 27 | || _Traits::is_always_equal::value | |
| 23 | template <typename _Alloc, typename _Traits = allocator_traits<_Alloc> > | |
| 24 | struct __noexcept_move_assign_container | |
| 25 | : public integral_constant<bool, | |
| 26 | _Traits::propagate_on_container_move_assignment::value | |
| 27 | #if _LIBCPP_STD_VER >= 17 | |
| 28 | || _Traits::is_always_equal::value | |
| 28 | 29 | #else |
| 29 | && is_nothrow_move_assignable<_Alloc>::value | |
| 30 | && is_nothrow_move_assignable<_Alloc>::value | |
| 30 | 31 | #endif |
| 31 | > {}; | |
| 32 | > { | |
| 33 | }; | |
| 32 | 34 | |
| 33 | 35 | _LIBCPP_END_NAMESPACE_STD |
| 34 | 36 |
lib/libcxx/include/__type_traits/operation_traits.h created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/integral_constant.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _Pred, class _Lhs, class _Rhs> | |
| 22 | struct __is_trivial_plus_operation : false_type {}; | |
| 23 | ||
| 24 | _LIBCPP_END_NAMESPACE_STD | |
| 25 | ||
| 26 | #endif // _LIBCPP___TYPE_TRAITS_OPERATION_TRAITS_H |
lib/libcxx/include/__type_traits/predicate_traits.h created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS | |
| 10 | #define _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/integral_constant.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _Pred, class _Lhs, class _Rhs> | |
| 22 | struct __is_trivial_equality_predicate : false_type {}; | |
| 23 | ||
| 24 | _LIBCPP_END_NAMESPACE_STD | |
| 25 | ||
| 26 | #endif // _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS |
lib/libcxx/include/__type_traits/promote.h+40-45| ... | ... | @@ -13,7 +13,6 @@ |
| 13 | 13 | #include <__type_traits/integral_constant.h> |
| 14 | 14 | #include <__type_traits/is_same.h> |
| 15 | 15 | #include <__utility/declval.h> |
| 16 | #include <cstddef> | |
| 17 | 16 | |
| 18 | 17 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 19 | 18 | # pragma GCC system_header |
| ... | ... | @@ -22,73 +21,69 @@ |
| 22 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 22 | |
| 24 | 23 | template <class _Tp> |
| 25 | struct __numeric_type | |
| 26 | { | |
| 27 | static void __test(...); | |
| 28 | static float __test(float); | |
| 29 | static double __test(char); | |
| 30 | static double __test(int); | |
| 31 | static double __test(unsigned); | |
| 32 | static double __test(long); | |
| 33 | static double __test(unsigned long); | |
| 34 | static double __test(long long); | |
| 35 | static double __test(unsigned long long); | |
| 24 | struct __numeric_type { | |
| 25 | static void __test(...); | |
| 26 | static float __test(float); | |
| 27 | static double __test(char); | |
| 28 | static double __test(int); | |
| 29 | static double __test(unsigned); | |
| 30 | static double __test(long); | |
| 31 | static double __test(unsigned long); | |
| 32 | static double __test(long long); | |
| 33 | static double __test(unsigned long long); | |
| 36 | 34 | #ifndef _LIBCPP_HAS_NO_INT128 |
| 37 | static double __test(__int128_t); | |
| 38 | static double __test(__uint128_t); | |
| 35 | static double __test(__int128_t); | |
| 36 | static double __test(__uint128_t); | |
| 39 | 37 | #endif |
| 40 | static double __test(double); | |
| 41 | static long double __test(long double); | |
| 38 | static double __test(double); | |
| 39 | static long double __test(long double); | |
| 42 | 40 | |
| 43 | typedef decltype(__test(std::declval<_Tp>())) type; | |
| 44 | static const bool value = _IsNotSame<type, void>::value; | |
| 41 | typedef decltype(__test(std::declval<_Tp>())) type; | |
| 42 | static const bool value = _IsNotSame<type, void>::value; | |
| 45 | 43 | }; |
| 46 | 44 | |
| 47 | 45 | template <> |
| 48 | struct __numeric_type<void> | |
| 49 | { | |
| 50 | static const bool value = true; | |
| 46 | struct __numeric_type<void> { | |
| 47 | static const bool value = true; | |
| 51 | 48 | }; |
| 52 | 49 | |
| 53 | template <class _A1, class _A2 = void, class _A3 = void, | |
| 54 | bool = __numeric_type<_A1>::value && | |
| 55 | __numeric_type<_A2>::value && | |
| 56 | __numeric_type<_A3>::value> | |
| 57 | class __promote_imp | |
| 58 | { | |
| 50 | template <class _A1, | |
| 51 | class _A2 = void, | |
| 52 | class _A3 = void, | |
| 53 | bool = __numeric_type<_A1>::value&& __numeric_type<_A2>::value&& __numeric_type<_A3>::value> | |
| 54 | class __promote_imp { | |
| 59 | 55 | public: |
| 60 | static const bool value = false; | |
| 56 | static const bool value = false; | |
| 61 | 57 | }; |
| 62 | 58 | |
| 63 | 59 | template <class _A1, class _A2, class _A3> |
| 64 | class __promote_imp<_A1, _A2, _A3, true> | |
| 65 | { | |
| 60 | class __promote_imp<_A1, _A2, _A3, true> { | |
| 66 | 61 | private: |
| 67 | typedef typename __promote_imp<_A1>::type __type1; | |
| 68 | typedef typename __promote_imp<_A2>::type __type2; | |
| 69 | typedef typename __promote_imp<_A3>::type __type3; | |
| 62 | typedef typename __promote_imp<_A1>::type __type1; | |
| 63 | typedef typename __promote_imp<_A2>::type __type2; | |
| 64 | typedef typename __promote_imp<_A3>::type __type3; | |
| 65 | ||
| 70 | 66 | public: |
| 71 | typedef decltype(__type1() + __type2() + __type3()) type; | |
| 72 | static const bool value = true; | |
| 67 | typedef decltype(__type1() + __type2() + __type3()) type; | |
| 68 | static const bool value = true; | |
| 73 | 69 | }; |
| 74 | 70 | |
| 75 | 71 | template <class _A1, class _A2> |
| 76 | class __promote_imp<_A1, _A2, void, true> | |
| 77 | { | |
| 72 | class __promote_imp<_A1, _A2, void, true> { | |
| 78 | 73 | private: |
| 79 | typedef typename __promote_imp<_A1>::type __type1; | |
| 80 | typedef typename __promote_imp<_A2>::type __type2; | |
| 74 | typedef typename __promote_imp<_A1>::type __type1; | |
| 75 | typedef typename __promote_imp<_A2>::type __type2; | |
| 76 | ||
| 81 | 77 | public: |
| 82 | typedef decltype(__type1() + __type2()) type; | |
| 83 | static const bool value = true; | |
| 78 | typedef decltype(__type1() + __type2()) type; | |
| 79 | static const bool value = true; | |
| 84 | 80 | }; |
| 85 | 81 | |
| 86 | 82 | template <class _A1> |
| 87 | class __promote_imp<_A1, void, void, true> | |
| 88 | { | |
| 83 | class __promote_imp<_A1, void, void, true> { | |
| 89 | 84 | public: |
| 90 | typedef typename __numeric_type<_A1>::type type; | |
| 91 | static const bool value = true; | |
| 85 | typedef typename __numeric_type<_A1>::type type; | |
| 86 | static const bool value = true; | |
| 92 | 87 | }; |
| 93 | 88 | |
| 94 | 89 | template <class _A1, class _A2 = void, class _A3 = void> |
lib/libcxx/include/__type_traits/rank.h+7-7| ... | ... | @@ -27,16 +27,16 @@ struct rank : integral_constant<size_t, __array_rank(_Tp)> {}; |
| 27 | 27 | |
| 28 | 28 | #else |
| 29 | 29 | |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank | |
| 31 | : public integral_constant<size_t, 0> {}; | |
| 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]> | |
| 33 | : public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
| 34 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> | |
| 35 | : public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
| 30 | template <class _Tp> | |
| 31 | struct _LIBCPP_TEMPLATE_VIS rank : public integral_constant<size_t, 0> {}; | |
| 32 | template <class _Tp> | |
| 33 | struct _LIBCPP_TEMPLATE_VIS rank<_Tp[]> : public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
| 34 | template <class _Tp, size_t _Np> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> : public integral_constant<size_t, rank<_Tp>::value + 1> {}; | |
| 36 | 36 | |
| 37 | 37 | #endif // __has_builtin(__array_rank) |
| 38 | 38 | |
| 39 | #if _LIBCPP_STD_VER > 14 | |
| 39 | #if _LIBCPP_STD_VER >= 17 | |
| 40 | 40 | template <class _Tp> |
| 41 | 41 | inline constexpr size_t rank_v = rank<_Tp>::value; |
| 42 | 42 | #endif |
lib/libcxx/include/__type_traits/remove_all_extents.h+15-8| ... | ... | @@ -27,19 +27,26 @@ struct remove_all_extents { |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | using __remove_all_extents_t = __remove_all_extents(_Tp); |
| 29 | 29 | #else |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents | |
| 31 | {typedef _Tp type;}; | |
| 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]> | |
| 33 | {typedef typename remove_all_extents<_Tp>::type type;}; | |
| 34 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]> | |
| 35 | {typedef typename remove_all_extents<_Tp>::type type;}; | |
| 30 | template <class _Tp> | |
| 31 | struct _LIBCPP_TEMPLATE_VIS remove_all_extents { | |
| 32 | typedef _Tp type; | |
| 33 | }; | |
| 34 | template <class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]> { | |
| 36 | typedef typename remove_all_extents<_Tp>::type type; | |
| 37 | }; | |
| 38 | template <class _Tp, size_t _Np> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]> { | |
| 40 | typedef typename remove_all_extents<_Tp>::type type; | |
| 41 | }; | |
| 36 | 42 | |
| 37 | 43 | template <class _Tp> |
| 38 | 44 | using __remove_all_extents_t = typename remove_all_extents<_Tp>::type; |
| 39 | 45 | #endif // __has_builtin(__remove_all_extents) |
| 40 | 46 | |
| 41 | #if _LIBCPP_STD_VER > 11 | |
| 42 | template <class _Tp> using remove_all_extents_t = __remove_all_extents_t<_Tp>; | |
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | template <class _Tp> | |
| 49 | using remove_all_extents_t = __remove_all_extents_t<_Tp>; | |
| 43 | 50 | #endif |
| 44 | 51 | |
| 45 | 52 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_const.h+11-4| ... | ... | @@ -26,15 +26,22 @@ struct remove_const { |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | using __remove_const_t = __remove_const(_Tp); |
| 28 | 28 | #else |
| 29 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; | |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> {typedef _Tp type;}; | |
| 29 | template <class _Tp> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS remove_const { | |
| 31 | typedef _Tp type; | |
| 32 | }; | |
| 33 | template <class _Tp> | |
| 34 | struct _LIBCPP_TEMPLATE_VIS remove_const<const _Tp> { | |
| 35 | typedef _Tp type; | |
| 36 | }; | |
| 31 | 37 | |
| 32 | 38 | template <class _Tp> |
| 33 | 39 | using __remove_const_t = typename remove_const<_Tp>::type; |
| 34 | 40 | #endif // __has_builtin(__remove_const) |
| 35 | 41 | |
| 36 | #if _LIBCPP_STD_VER > 11 | |
| 37 | template <class _Tp> using remove_const_t = __remove_const_t<_Tp>; | |
| 42 | #if _LIBCPP_STD_VER >= 14 | |
| 43 | template <class _Tp> | |
| 44 | using remove_const_t = __remove_const_t<_Tp>; | |
| 38 | 45 | #endif |
| 39 | 46 | |
| 40 | 47 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_cv.h+8-5| ... | ... | @@ -19,7 +19,7 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if __has_builtin(__remove_cv) | |
| 22 | #if __has_builtin(__remove_cv) && !defined(_LIBCPP_COMPILER_GCC) | |
| 23 | 23 | template <class _Tp> |
| 24 | 24 | struct remove_cv { |
| 25 | 25 | using type _LIBCPP_NODEBUG = __remove_cv(_Tp); |
| ... | ... | @@ -28,15 +28,18 @@ struct remove_cv { |
| 28 | 28 | template <class _Tp> |
| 29 | 29 | using __remove_cv_t = __remove_cv(_Tp); |
| 30 | 30 | #else |
| 31 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv | |
| 32 | {typedef __remove_volatile_t<__remove_const_t<_Tp> > type;}; | |
| 31 | template <class _Tp> | |
| 32 | struct _LIBCPP_TEMPLATE_VIS remove_cv { | |
| 33 | typedef __remove_volatile_t<__remove_const_t<_Tp> > type; | |
| 34 | }; | |
| 33 | 35 | |
| 34 | 36 | template <class _Tp> |
| 35 | 37 | using __remove_cv_t = __remove_volatile_t<__remove_const_t<_Tp> >; |
| 36 | 38 | #endif // __has_builtin(__remove_cv) |
| 37 | 39 | |
| 38 | #if _LIBCPP_STD_VER > 11 | |
| 39 | template <class _Tp> using remove_cv_t = __remove_cv_t<_Tp>; | |
| 40 | #if _LIBCPP_STD_VER >= 14 | |
| 41 | template <class _Tp> | |
| 42 | using remove_cv_t = __remove_cv_t<_Tp>; | |
| 40 | 43 | #endif |
| 41 | 44 | |
| 42 | 45 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_cvref.h+5-4| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if __has_builtin(__remove_cvref) | |
| 23 | #if __has_builtin(__remove_cvref) && !defined(_LIBCPP_COMPILER_GCC) | |
| 24 | 24 | template <class _Tp> |
| 25 | 25 | using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cvref(_Tp); |
| 26 | 26 | #else |
| ... | ... | @@ -31,13 +31,14 @@ using __remove_cvref_t _LIBCPP_NODEBUG = __remove_cv_t<__libcpp_remove_reference |
| 31 | 31 | template <class _Tp, class _Up> |
| 32 | 32 | struct __is_same_uncvref : _IsSame<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up> > {}; |
| 33 | 33 | |
| 34 | #if _LIBCPP_STD_VER > 17 | |
| 34 | #if _LIBCPP_STD_VER >= 20 | |
| 35 | 35 | template <class _Tp> |
| 36 | 36 | struct remove_cvref { |
| 37 | using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>; | |
| 37 | using type _LIBCPP_NODEBUG = __remove_cvref_t<_Tp>; | |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | template <class _Tp> using remove_cvref_t = __remove_cvref_t<_Tp>; | |
| 40 | template <class _Tp> | |
| 41 | using remove_cvref_t = __remove_cvref_t<_Tp>; | |
| 41 | 42 | #endif |
| 42 | 43 | |
| 43 | 44 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_extent.h+15-8| ... | ... | @@ -27,19 +27,26 @@ struct remove_extent { |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | using __remove_extent_t = __remove_extent(_Tp); |
| 29 | 29 | #else |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent | |
| 31 | {typedef _Tp type;}; | |
| 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]> | |
| 33 | {typedef _Tp type;}; | |
| 34 | template <class _Tp, size_t _Np> struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]> | |
| 35 | {typedef _Tp type;}; | |
| 30 | template <class _Tp> | |
| 31 | struct _LIBCPP_TEMPLATE_VIS remove_extent { | |
| 32 | typedef _Tp type; | |
| 33 | }; | |
| 34 | template <class _Tp> | |
| 35 | struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]> { | |
| 36 | typedef _Tp type; | |
| 37 | }; | |
| 38 | template <class _Tp, size_t _Np> | |
| 39 | struct _LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]> { | |
| 40 | typedef _Tp type; | |
| 41 | }; | |
| 36 | 42 | |
| 37 | 43 | template <class _Tp> |
| 38 | 44 | using __remove_extent_t = typename remove_extent<_Tp>::type; |
| 39 | 45 | #endif // __has_builtin(__remove_extent) |
| 40 | 46 | |
| 41 | #if _LIBCPP_STD_VER > 11 | |
| 42 | template <class _Tp> using remove_extent_t = __remove_extent_t<_Tp>; | |
| 47 | #if _LIBCPP_STD_VER >= 14 | |
| 48 | template <class _Tp> | |
| 49 | using remove_extent_t = __remove_extent_t<_Tp>; | |
| 43 | 50 | #endif |
| 44 | 51 | |
| 45 | 52 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_pointer.h+5-2| ... | ... | @@ -26,18 +26,21 @@ struct remove_pointer { |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | using __remove_pointer_t = __remove_pointer(_Tp); |
| 28 | 28 | #else |
| 29 | // clang-format off | |
| 29 | 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 30 | 31 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 31 | 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 32 | 33 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 33 | 34 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 35 | // clang-format on | |
| 34 | 36 | |
| 35 | 37 | template <class _Tp> |
| 36 | 38 | using __remove_pointer_t = typename remove_pointer<_Tp>::type; |
| 37 | 39 | #endif // !defined(_LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS) && __has_builtin(__remove_pointer) |
| 38 | 40 | |
| 39 | #if _LIBCPP_STD_VER > 11 | |
| 40 | template <class _Tp> using remove_pointer_t = __remove_pointer_t<_Tp>; | |
| 41 | #if _LIBCPP_STD_VER >= 14 | |
| 42 | template <class _Tp> | |
| 43 | using remove_pointer_t = __remove_pointer_t<_Tp>; | |
| 41 | 44 | #endif |
| 42 | 45 | |
| 43 | 46 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_reference.h+5-2| ... | ... | @@ -27,16 +27,19 @@ struct remove_reference { |
| 27 | 27 | template <class _Tp> |
| 28 | 28 | using __libcpp_remove_reference_t = __remove_reference_t(_Tp); |
| 29 | 29 | #else |
| 30 | // clang-format off | |
| 30 | 31 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 31 | 32 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 32 | 33 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _LIBCPP_NODEBUG _Tp type;}; |
| 34 | // clang-format on | |
| 33 | 35 | |
| 34 | 36 | template <class _Tp> |
| 35 | 37 | using __libcpp_remove_reference_t = typename remove_reference<_Tp>::type; |
| 36 | 38 | #endif // __has_builtin(__remove_reference_t) |
| 37 | 39 | |
| 38 | #if _LIBCPP_STD_VER > 11 | |
| 39 | template <class _Tp> using remove_reference_t = __libcpp_remove_reference_t<_Tp>; | |
| 40 | #if _LIBCPP_STD_VER >= 14 | |
| 41 | template <class _Tp> | |
| 42 | using remove_reference_t = __libcpp_remove_reference_t<_Tp>; | |
| 40 | 43 | #endif |
| 41 | 44 | |
| 42 | 45 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/remove_volatile.h+11-4| ... | ... | @@ -26,15 +26,22 @@ struct remove_volatile { |
| 26 | 26 | template <class _Tp> |
| 27 | 27 | using __remove_volatile_t = __remove_volatile(_Tp); |
| 28 | 28 | #else |
| 29 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; | |
| 30 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> {typedef _Tp type;}; | |
| 29 | template <class _Tp> | |
| 30 | struct _LIBCPP_TEMPLATE_VIS remove_volatile { | |
| 31 | typedef _Tp type; | |
| 32 | }; | |
| 33 | template <class _Tp> | |
| 34 | struct _LIBCPP_TEMPLATE_VIS remove_volatile<volatile _Tp> { | |
| 35 | typedef _Tp type; | |
| 36 | }; | |
| 31 | 37 | |
| 32 | 38 | template <class _Tp> |
| 33 | 39 | using __remove_volatile_t = typename remove_volatile<_Tp>::type; |
| 34 | 40 | #endif // __has_builtin(__remove_volatile) |
| 35 | 41 | |
| 36 | #if _LIBCPP_STD_VER > 11 | |
| 37 | template <class _Tp> using remove_volatile_t = __remove_volatile_t<_Tp>; | |
| 42 | #if _LIBCPP_STD_VER >= 14 | |
| 43 | template <class _Tp> | |
| 44 | using remove_volatile_t = __remove_volatile_t<_Tp>; | |
| 38 | 45 | #endif |
| 39 | 46 | |
| 40 | 47 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/result_of.h+11-12| ... | ... | @@ -21,18 +21,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | // result_of |
| 22 | 22 | |
| 23 | 23 | #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) |
| 24 | template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of; | |
| 25 | ||
| 26 | template <class _Fp, class ..._Args> | |
| 27 | class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> | |
| 28 | : public __invoke_of<_Fp, _Args...> | |
| 29 | { | |
| 30 | }; | |
| 31 | ||
| 32 | #if _LIBCPP_STD_VER > 11 | |
| 33 | template <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type; | |
| 34 | #endif // _LIBCPP_STD_VER > 11 | |
| 35 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) | |
| 24 | template <class _Callable> | |
| 25 | class _LIBCPP_DEPRECATED_IN_CXX17 result_of; | |
| 26 | ||
| 27 | template <class _Fp, class... _Args> | |
| 28 | class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> {}; | |
| 29 | ||
| 30 | # if _LIBCPP_STD_VER >= 14 | |
| 31 | template <class _Tp> | |
| 32 | using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type; | |
| 33 | # endif // _LIBCPP_STD_VER >= 14 | |
| 34 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) | |
| 36 | 35 | |
| 37 | 36 | _LIBCPP_END_NAMESPACE_STD |
| 38 | 37 |
lib/libcxx/include/__type_traits/strip_signature.h+5-3| ... | ... | @@ -19,23 +19,24 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | template<class _Fp> | |
| 22 | template <class _Fp> | |
| 23 | 23 | struct __strip_signature; |
| 24 | 24 | |
| 25 | 25 | # if defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L |
| 26 | 26 | |
| 27 | 27 | template <class _Rp, class... _Args> |
| 28 | struct __strip_signature<_Rp(*)(_Args...)> { | |
| 28 | struct __strip_signature<_Rp (*)(_Args...)> { | |
| 29 | 29 | using type = _Rp(_Args...); |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | template <class _Rp, class... _Args> |
| 33 | struct __strip_signature<_Rp(*)(_Args...) noexcept> { | |
| 33 | struct __strip_signature<_Rp (*)(_Args...) noexcept> { | |
| 34 | 34 | using type = _Rp(_Args...); |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | 37 | # endif // defined(__cpp_static_call_operator) && __cpp_static_call_operator >= 202207L |
| 38 | 38 | |
| 39 | // clang-format off | |
| 39 | 40 | template<class _Rp, class _Gp, class ..._Ap> |
| 40 | 41 | struct __strip_signature<_Rp (_Gp::*) (_Ap...)> { using type = _Rp(_Ap...); }; |
| 41 | 42 | template<class _Rp, class _Gp, class ..._Ap> |
| ... | ... | @@ -71,6 +72,7 @@ template<class _Rp, class _Gp, class ..._Ap> |
| 71 | 72 | struct __strip_signature<_Rp (_Gp::*) (_Ap...) volatile & noexcept> { using type = _Rp(_Ap...); }; |
| 72 | 73 | template<class _Rp, class _Gp, class ..._Ap> |
| 73 | 74 | struct __strip_signature<_Rp (_Gp::*) (_Ap...) const volatile & noexcept> { using type = _Rp(_Ap...); }; |
| 75 | // clang-format on | |
| 74 | 76 | |
| 75 | 77 | _LIBCPP_END_NAMESPACE_STD |
| 76 | 78 |
lib/libcxx/include/__type_traits/type_identity.h+10-4| ... | ... | @@ -18,14 +18,20 @@ |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | 20 | template <class _Tp> |
| 21 | struct __type_identity { typedef _Tp type; }; | |
| 21 | struct __type_identity { | |
| 22 | typedef _Tp type; | |
| 23 | }; | |
| 22 | 24 | |
| 23 | 25 | template <class _Tp> |
| 24 | 26 | using __type_identity_t _LIBCPP_NODEBUG = typename __type_identity<_Tp>::type; |
| 25 | 27 | |
| 26 | #if _LIBCPP_STD_VER > 17 | |
| 27 | template<class _Tp> struct type_identity { typedef _Tp type; }; | |
| 28 | template<class _Tp> using type_identity_t = typename type_identity<_Tp>::type; | |
| 28 | #if _LIBCPP_STD_VER >= 20 | |
| 29 | template <class _Tp> | |
| 30 | struct type_identity { | |
| 31 | typedef _Tp type; | |
| 32 | }; | |
| 33 | template <class _Tp> | |
| 34 | using type_identity_t = typename type_identity<_Tp>::type; | |
| 29 | 35 | #endif |
| 30 | 36 | |
| 31 | 37 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/type_list.h+9-11| ... | ... | @@ -19,24 +19,22 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | template <class _Hp, class _Tp> |
| 22 | struct __type_list | |
| 23 | { | |
| 24 | typedef _Hp _Head; | |
| 25 | typedef _Tp _Tail; | |
| 22 | struct __type_list { | |
| 23 | typedef _Hp _Head; | |
| 24 | typedef _Tp _Tail; | |
| 26 | 25 | }; |
| 27 | 26 | |
| 28 | template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> struct __find_first; | |
| 27 | template <class _TypeList, size_t _Size, bool = _Size <= sizeof(typename _TypeList::_Head)> | |
| 28 | struct __find_first; | |
| 29 | 29 | |
| 30 | 30 | template <class _Hp, class _Tp, size_t _Size> |
| 31 | struct __find_first<__type_list<_Hp, _Tp>, _Size, true> | |
| 32 | { | |
| 33 | typedef _LIBCPP_NODEBUG _Hp type; | |
| 31 | struct __find_first<__type_list<_Hp, _Tp>, _Size, true> { | |
| 32 | typedef _LIBCPP_NODEBUG _Hp type; | |
| 34 | 33 | }; |
| 35 | 34 | |
| 36 | 35 | template <class _Hp, class _Tp, size_t _Size> |
| 37 | struct __find_first<__type_list<_Hp, _Tp>, _Size, false> | |
| 38 | { | |
| 39 | typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type; | |
| 36 | struct __find_first<__type_list<_Hp, _Tp>, _Size, false> { | |
| 37 | typedef _LIBCPP_NODEBUG typename __find_first<_Tp, _Size>::type type; | |
| 40 | 38 | }; |
| 41 | 39 | |
| 42 | 40 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/underlying_type.h+7-6| ... | ... | @@ -18,22 +18,23 @@ |
| 18 | 18 | |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | template <class _Tp, bool = is_enum<_Tp>::value> struct __underlying_type_impl; | |
| 21 | template <class _Tp, bool = is_enum<_Tp>::value> | |
| 22 | struct __underlying_type_impl; | |
| 22 | 23 | |
| 23 | 24 | template <class _Tp> |
| 24 | 25 | struct __underlying_type_impl<_Tp, false> {}; |
| 25 | 26 | |
| 26 | 27 | template <class _Tp> |
| 27 | struct __underlying_type_impl<_Tp, true> | |
| 28 | { | |
| 29 | typedef __underlying_type(_Tp) type; | |
| 28 | struct __underlying_type_impl<_Tp, true> { | |
| 29 | typedef __underlying_type(_Tp) type; | |
| 30 | 30 | }; |
| 31 | 31 | |
| 32 | 32 | template <class _Tp> |
| 33 | 33 | struct underlying_type : __underlying_type_impl<_Tp, is_enum<_Tp>::value> {}; |
| 34 | 34 | |
| 35 | #if _LIBCPP_STD_VER > 11 | |
| 36 | template <class _Tp> using underlying_type_t = typename underlying_type<_Tp>::type; | |
| 35 | #if _LIBCPP_STD_VER >= 14 | |
| 36 | template <class _Tp> | |
| 37 | using underlying_type_t = typename underlying_type<_Tp>::type; | |
| 37 | 38 | #endif |
| 38 | 39 | |
| 39 | 40 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__type_traits/unwrap_ref.h created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H | |
| 10 | #define _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__type_traits/decay.h> | |
| 14 | ||
| 15 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 16 | # pragma GCC system_header | |
| 17 | #endif | |
| 18 | ||
| 19 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 20 | ||
| 21 | template <class _Tp> | |
| 22 | struct __unwrap_reference { | |
| 23 | typedef _LIBCPP_NODEBUG _Tp type; | |
| 24 | }; | |
| 25 | ||
| 26 | template <class _Tp> | |
| 27 | class reference_wrapper; | |
| 28 | ||
| 29 | template <class _Tp> | |
| 30 | struct __unwrap_reference<reference_wrapper<_Tp> > { | |
| 31 | typedef _LIBCPP_NODEBUG _Tp& type; | |
| 32 | }; | |
| 33 | ||
| 34 | template <class _Tp> | |
| 35 | struct decay; | |
| 36 | ||
| 37 | #if _LIBCPP_STD_VER >= 20 | |
| 38 | template <class _Tp> | |
| 39 | struct unwrap_reference : __unwrap_reference<_Tp> {}; | |
| 40 | ||
| 41 | template <class _Tp> | |
| 42 | using unwrap_reference_t = typename unwrap_reference<_Tp>::type; | |
| 43 | ||
| 44 | template <class _Tp> | |
| 45 | struct unwrap_ref_decay : unwrap_reference<__decay_t<_Tp> > {}; | |
| 46 | ||
| 47 | template <class _Tp> | |
| 48 | using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; | |
| 49 | #endif // _LIBCPP_STD_VER >= 20 | |
| 50 | ||
| 51 | template <class _Tp> | |
| 52 | struct __unwrap_ref_decay | |
| 53 | #if _LIBCPP_STD_VER >= 20 | |
| 54 | : unwrap_ref_decay<_Tp> | |
| 55 | #else | |
| 56 | : __unwrap_reference<__decay_t<_Tp> > | |
| 57 | #endif | |
| 58 | { | |
| 59 | }; | |
| 60 | ||
| 61 | _LIBCPP_END_NAMESPACE_STD | |
| 62 | ||
| 63 | #endif // _LIBCPP___TYPE_TRAITS_UNWRAP_REF_H |
lib/libcxx/include/__type_traits/void_t.h+3-2| ... | ... | @@ -17,8 +17,9 @@ |
| 17 | 17 | |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | #if _LIBCPP_STD_VER > 14 | |
| 21 | template <class...> using void_t = void; | |
| 20 | #if _LIBCPP_STD_VER >= 17 | |
| 21 | template <class...> | |
| 22 | using void_t = void; | |
| 22 | 23 | #endif |
| 23 | 24 | |
| 24 | 25 | template <class...> |
lib/libcxx/include/__undef_macros+12| ... | ... | @@ -14,3 +14,15 @@ |
| 14 | 14 | #ifdef max |
| 15 | 15 | # undef max |
| 16 | 16 | #endif |
| 17 | ||
| 18 | #ifdef refresh | |
| 19 | # undef refresh | |
| 20 | #endif | |
| 21 | ||
| 22 | #ifdef move | |
| 23 | # undef move | |
| 24 | #endif | |
| 25 | ||
| 26 | #ifdef erase | |
| 27 | # undef erase | |
| 28 | #endif |
lib/libcxx/include/__utility/as_const.h+1-1| ... | ... | @@ -20,7 +20,7 @@ |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 22 | 22 | |
| 23 | #if _LIBCPP_STD_VER > 14 | |
| 23 | #if _LIBCPP_STD_VER >= 17 | |
| 24 | 24 | template <class _Tp> |
| 25 | 25 | _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } |
| 26 | 26 |
lib/libcxx/include/__utility/auto_cast.h+1-1| ... | ... | @@ -17,6 +17,6 @@ |
| 17 | 17 | # pragma GCC system_header |
| 18 | 18 | #endif |
| 19 | 19 | |
| 20 | #define _LIBCPP_AUTO_CAST(expr) static_cast<typename decay<decltype((expr))>::type>(expr) | |
| 20 | #define _LIBCPP_AUTO_CAST(expr) static_cast<::std::__decay_t<decltype((expr))> >(expr) | |
| 21 | 21 | |
| 22 | 22 | #endif // _LIBCPP___UTILITY_AUTO_CAST_H |
lib/libcxx/include/__utility/cmp.h+2-2| ... | ... | @@ -28,7 +28,7 @@ _LIBCPP_PUSH_MACROS |
| 28 | 28 | |
| 29 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 30 | 30 | |
| 31 | #if _LIBCPP_STD_VER > 17 | |
| 31 | #if _LIBCPP_STD_VER >= 20 | |
| 32 | 32 | template<class _Tp, class... _Up> |
| 33 | 33 | struct _IsSameAsAny : _Or<_IsSame<_Tp, _Up>...> {}; |
| 34 | 34 | |
| ... | ... | @@ -102,7 +102,7 @@ bool in_range(_Up __u) noexcept |
| 102 | 102 | return _VSTD::cmp_less_equal(__u, numeric_limits<_Tp>::max()) && |
| 103 | 103 | _VSTD::cmp_greater_equal(__u, numeric_limits<_Tp>::min()); |
| 104 | 104 | } |
| 105 | #endif // _LIBCPP_STD_VER > 17 | |
| 105 | #endif // _LIBCPP_STD_VER >= 20 | |
| 106 | 106 | |
| 107 | 107 | _LIBCPP_END_NAMESPACE_STD |
| 108 | 108 |
lib/libcxx/include/__utility/exception_guard.h+12-7| ... | ... | @@ -19,6 +19,9 @@ |
| 19 | 19 | # pragma GCC system_header |
| 20 | 20 | #endif |
| 21 | 21 | |
| 22 | _LIBCPP_PUSH_MACROS | |
| 23 | #include <__undef_macros> | |
| 24 | ||
| 22 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 26 | |
| 24 | 27 | // __exception_guard is a helper class for writing code with the strong exception guarantee. |
| ... | ... | @@ -41,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 41 | 44 | // less common, especially one that tries to catch an exception through -fno-exceptions code. |
| 42 | 45 | // |
| 43 | 46 | // __exception_guard can help greatly simplify code that would normally be cluttered by |
| 44 | // `#if _LIBCPP_NO_EXCEPTIONS`. For example: | |
| 47 | // `#if _LIBCPP_HAS_NO_EXCEPTIONS`. For example: | |
| 45 | 48 | // |
| 46 | 49 | // template <class Iterator, class Size, class OutputIterator> |
| 47 | 50 | // Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) { |
| ... | ... | @@ -58,7 +61,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 58 | 61 | // } |
| 59 | 62 | // |
| 60 | 63 | |
| 61 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 62 | 64 | template <class _Rollback> |
| 63 | 65 | struct __exception_guard_exceptions { |
| 64 | 66 | __exception_guard_exceptions() = delete; |
| ... | ... | @@ -91,9 +93,6 @@ private: |
| 91 | 93 | |
| 92 | 94 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_exceptions); |
| 93 | 95 | |
| 94 | template <class _Rollback> | |
| 95 | using __exception_guard = __exception_guard_exceptions<_Rollback>; | |
| 96 | #else // _LIBCPP_NO_EXCEPTIONS | |
| 97 | 96 | template <class _Rollback> |
| 98 | 97 | struct __exception_guard_noexceptions { |
| 99 | 98 | __exception_guard_noexceptions() = delete; |
| ... | ... | @@ -116,7 +115,7 @@ struct __exception_guard_noexceptions { |
| 116 | 115 | } |
| 117 | 116 | |
| 118 | 117 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NODEBUG ~__exception_guard_noexceptions() { |
| 119 | _LIBCPP_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled"); | |
| 118 | _LIBCPP_ASSERT_UNCATEGORIZED(__completed_, "__exception_guard not completed with exceptions disabled"); | |
| 120 | 119 | } |
| 121 | 120 | |
| 122 | 121 | private: |
| ... | ... | @@ -125,9 +124,13 @@ private: |
| 125 | 124 | |
| 126 | 125 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions); |
| 127 | 126 | |
| 127 | #ifdef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 128 | 128 | template <class _Rollback> |
| 129 | 129 | using __exception_guard = __exception_guard_noexceptions<_Rollback>; |
| 130 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 130 | #else | |
| 131 | template <class _Rollback> | |
| 132 | using __exception_guard = __exception_guard_exceptions<_Rollback>; | |
| 133 | #endif | |
| 131 | 134 | |
| 132 | 135 | template <class _Rollback> |
| 133 | 136 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback) { |
| ... | ... | @@ -136,4 +139,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __exception_guard<_Rollback> __make_exce |
| 136 | 139 | |
| 137 | 140 | _LIBCPP_END_NAMESPACE_STD |
| 138 | 141 | |
| 142 | _LIBCPP_POP_MACROS | |
| 143 | ||
| 139 | 144 | #endif // _LIBCPP___UTILITY_TRANSACTION_H |
lib/libcxx/include/__utility/exchange.h+7-2| ... | ... | @@ -19,9 +19,12 @@ |
| 19 | 19 | # pragma GCC system_header |
| 20 | 20 | #endif |
| 21 | 21 | |
| 22 | _LIBCPP_PUSH_MACROS | |
| 23 | #include <__undef_macros> | |
| 24 | ||
| 22 | 25 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 26 | |
| 24 | #if _LIBCPP_STD_VER > 11 | |
| 27 | #if _LIBCPP_STD_VER >= 14 | |
| 25 | 28 | template<class _T1, class _T2 = _T1> |
| 26 | 29 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 27 | 30 | _T1 exchange(_T1& __obj, _T2&& __new_value) |
| ... | ... | @@ -31,8 +34,10 @@ _T1 exchange(_T1& __obj, _T2&& __new_value) |
| 31 | 34 | __obj = _VSTD::forward<_T2>(__new_value); |
| 32 | 35 | return __old_value; |
| 33 | 36 | } |
| 34 | #endif // _LIBCPP_STD_VER > 11 | |
| 37 | #endif // _LIBCPP_STD_VER >= 14 | |
| 35 | 38 | |
| 36 | 39 | _LIBCPP_END_NAMESPACE_STD |
| 37 | 40 | |
| 41 | _LIBCPP_POP_MACROS | |
| 42 | ||
| 38 | 43 | #endif // _LIBCPP___UTILITY_EXCHANGE_H |
lib/libcxx/include/__utility/forward_like.h+2-2| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | #if _LIBCPP_STD_VER > 20 | |
| 25 | #if _LIBCPP_STD_VER >= 23 | |
| 26 | 26 | |
| 27 | 27 | template <class _Ap, class _Bp> |
| 28 | 28 | using _CopyConst = _If<is_const_v<_Ap>, const _Bp, _Bp>; |
| ... | ... | @@ -39,7 +39,7 @@ template <class _Tp, class _Up> |
| 39 | 39 | return static_cast<_ForwardLike<_Tp, _Up>>(__ux); |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | #endif // _LIBCPP_STD_VER > 20 | |
| 42 | #endif // _LIBCPP_STD_VER >= 23 | |
| 43 | 43 | |
| 44 | 44 | _LIBCPP_END_NAMESPACE_STD |
| 45 | 45 |
lib/libcxx/include/__utility/in_place.h+6-6| ... | ... | @@ -19,23 +19,23 @@ |
| 19 | 19 | |
| 20 | 20 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | #if _LIBCPP_STD_VER > 14 | |
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | 23 | |
| 24 | struct _LIBCPP_TYPE_VIS in_place_t { | |
| 25 | explicit in_place_t() = default; | |
| 24 | struct _LIBCPP_EXPORTED_FROM_ABI in_place_t { | |
| 25 | explicit in_place_t() = default; | |
| 26 | 26 | }; |
| 27 | 27 | inline constexpr in_place_t in_place{}; |
| 28 | 28 | |
| 29 | 29 | template <class _Tp> |
| 30 | 30 | struct _LIBCPP_TEMPLATE_VIS in_place_type_t { |
| 31 | explicit in_place_type_t() = default; | |
| 31 | _LIBCPP_HIDE_FROM_ABI explicit in_place_type_t() = default; | |
| 32 | 32 | }; |
| 33 | 33 | template <class _Tp> |
| 34 | 34 | inline constexpr in_place_type_t<_Tp> in_place_type{}; |
| 35 | 35 | |
| 36 | 36 | template <size_t _Idx> |
| 37 | 37 | struct _LIBCPP_TEMPLATE_VIS in_place_index_t { |
| 38 | explicit in_place_index_t() = default; | |
| 38 | _LIBCPP_HIDE_FROM_ABI explicit in_place_index_t() = default; | |
| 39 | 39 | }; |
| 40 | 40 | template <size_t _Idx> |
| 41 | 41 | inline constexpr in_place_index_t<_Idx> in_place_index{}; |
| ... | ... | @@ -52,7 +52,7 @@ template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : t |
| 52 | 52 | template <class _Tp> |
| 53 | 53 | using __is_inplace_index = __is_inplace_index_imp<__remove_cvref_t<_Tp>>; |
| 54 | 54 | |
| 55 | #endif // _LIBCPP_STD_VER > 14 | |
| 55 | #endif // _LIBCPP_STD_VER >= 17 | |
| 56 | 56 | |
| 57 | 57 | _LIBCPP_END_NAMESPACE_STD |
| 58 | 58 |
lib/libcxx/include/__utility/integer_sequence.h+4-4| ... | ... | @@ -85,7 +85,7 @@ using __make_indices_imp = |
| 85 | 85 | |
| 86 | 86 | #endif |
| 87 | 87 | |
| 88 | #if _LIBCPP_STD_VER > 11 | |
| 88 | #if _LIBCPP_STD_VER >= 14 | |
| 89 | 89 | |
| 90 | 90 | template<class _Tp, _Tp... _Ip> |
| 91 | 91 | struct _LIBCPP_TEMPLATE_VIS integer_sequence |
| ... | ... | @@ -138,15 +138,15 @@ template<size_t _Np> |
| 138 | 138 | template<class... _Tp> |
| 139 | 139 | using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; |
| 140 | 140 | |
| 141 | # if _LIBCPP_STD_VER > 17 | |
| 141 | # if _LIBCPP_STD_VER >= 20 | |
| 142 | 142 | // Executes __func for every element in an index_sequence. |
| 143 | 143 | template <size_t... _Index, class _Function> |
| 144 | 144 | _LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) { |
| 145 | 145 | (__func.template operator()<_Index>(), ...); |
| 146 | 146 | } |
| 147 | # endif // _LIBCPP_STD_VER > 17 | |
| 147 | # endif // _LIBCPP_STD_VER >= 20 | |
| 148 | 148 | |
| 149 | #endif // _LIBCPP_STD_VER > 11 | |
| 149 | #endif // _LIBCPP_STD_VER >= 14 | |
| 150 | 150 | |
| 151 | 151 | _LIBCPP_END_NAMESPACE_STD |
| 152 | 152 |
lib/libcxx/include/__utility/is_pointer_in_range.h created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H | |
| 10 | #define _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H | |
| 11 | ||
| 12 | #include <__algorithm/comp.h> | |
| 13 | #include <__assert> | |
| 14 | #include <__config> | |
| 15 | #include <__type_traits/enable_if.h> | |
| 16 | #include <__type_traits/integral_constant.h> | |
| 17 | #include <__type_traits/is_constant_evaluated.h> | |
| 18 | #include <__type_traits/void_t.h> | |
| 19 | #include <__utility/declval.h> | |
| 20 | ||
| 21 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 22 | # pragma GCC system_header | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | template <class _Tp, class _Up, class = void> | |
| 28 | struct __is_less_than_comparable : false_type {}; | |
| 29 | ||
| 30 | template <class _Tp, class _Up> | |
| 31 | struct __is_less_than_comparable<_Tp, _Up, __void_t<decltype(std::declval<_Tp>() < std::declval<_Up>())> > : true_type { | |
| 32 | }; | |
| 33 | ||
| 34 | template <class _Tp, class _Up, __enable_if_t<__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0> | |
| 35 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range( | |
| 36 | const _Tp* __begin, const _Tp* __end, const _Up* __ptr) { | |
| 37 | if (__libcpp_is_constant_evaluated()) { | |
| 38 | _LIBCPP_ASSERT_UNCATEGORIZED(__builtin_constant_p(__begin <= __end), "__begin and __end do not form a range"); | |
| 39 | ||
| 40 | // If this is not a constant during constant evaluation we know that __ptr is not part of the allocation where | |
| 41 | // [__begin, __end) is. | |
| 42 | if (!__builtin_constant_p(__begin <= __ptr && __ptr < __end)) | |
| 43 | return false; | |
| 44 | } | |
| 45 | ||
| 46 | // Checking this for unrelated pointers is technically UB, but no compiler optimizes based on it (currently). | |
| 47 | return !__less<>()(__ptr, __begin) && __less<>()(__ptr, __end); | |
| 48 | } | |
| 49 | ||
| 50 | template <class _Tp, class _Up, __enable_if_t<!__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0> | |
| 51 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool __is_pointer_in_range( | |
| 52 | const _Tp* __begin, const _Tp* __end, const _Up* __ptr) { | |
| 53 | if (__libcpp_is_constant_evaluated()) | |
| 54 | return false; | |
| 55 | ||
| 56 | return reinterpret_cast<const char*>(__begin) <= reinterpret_cast<const char*>(__ptr) && | |
| 57 | reinterpret_cast<const char*>(__ptr) < reinterpret_cast<const char*>(__end); | |
| 58 | } | |
| 59 | ||
| 60 | _LIBCPP_END_NAMESPACE_STD | |
| 61 | ||
| 62 | #endif // _LIBCPP___UTILITY_IS_POINTER_IN_RANGE_H |
lib/libcxx/include/__utility/move.h+5| ... | ... | @@ -20,6 +20,9 @@ |
| 20 | 20 | # pragma GCC system_header |
| 21 | 21 | #endif |
| 22 | 22 | |
| 23 | _LIBCPP_PUSH_MACROS | |
| 24 | #include <__undef_macros> | |
| 25 | ||
| 23 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 27 | |
| 25 | 28 | template <class _Tp> |
| ... | ... | @@ -41,4 +44,6 @@ move_if_noexcept(_LIBCPP_LIFETIMEBOUND _Tp& __x) _NOEXCEPT { |
| 41 | 44 | |
| 42 | 45 | _LIBCPP_END_NAMESPACE_STD |
| 43 | 46 | |
| 47 | _LIBCPP_POP_MACROS | |
| 48 | ||
| 44 | 49 | #endif // _LIBCPP___UTILITY_MOVE_H |
lib/libcxx/include/__utility/pair.h+349-168| ... | ... | @@ -11,17 +11,23 @@ |
| 11 | 11 | |
| 12 | 12 | #include <__compare/common_comparison_category.h> |
| 13 | 13 | #include <__compare/synth_three_way.h> |
| 14 | #include <__concepts/different_from.h> | |
| 14 | 15 | #include <__config> |
| 15 | #include <__functional/unwrap_ref.h> | |
| 16 | #include <__fwd/array.h> | |
| 16 | 17 | #include <__fwd/get.h> |
| 18 | #include <__fwd/pair.h> | |
| 19 | #include <__fwd/subrange.h> | |
| 17 | 20 | #include <__fwd/tuple.h> |
| 18 | #include <__tuple_dir/sfinae_helpers.h> | |
| 19 | #include <__tuple_dir/tuple_element.h> | |
| 20 | #include <__tuple_dir/tuple_indices.h> | |
| 21 | #include <__tuple_dir/tuple_size.h> | |
| 21 | #include <__tuple/pair_like.h> | |
| 22 | #include <__tuple/sfinae_helpers.h> | |
| 23 | #include <__tuple/tuple_element.h> | |
| 24 | #include <__tuple/tuple_indices.h> | |
| 25 | #include <__tuple/tuple_size.h> | |
| 22 | 26 | #include <__type_traits/common_reference.h> |
| 23 | 27 | #include <__type_traits/common_type.h> |
| 24 | 28 | #include <__type_traits/conditional.h> |
| 29 | #include <__type_traits/decay.h> | |
| 30 | #include <__type_traits/integral_constant.h> | |
| 25 | 31 | #include <__type_traits/is_assignable.h> |
| 26 | 32 | #include <__type_traits/is_constructible.h> |
| 27 | 33 | #include <__type_traits/is_convertible.h> |
| ... | ... | @@ -38,6 +44,9 @@ |
| 38 | 44 | #include <__type_traits/is_same.h> |
| 39 | 45 | #include <__type_traits/is_swappable.h> |
| 40 | 46 | #include <__type_traits/nat.h> |
| 47 | #include <__type_traits/remove_cvref.h> | |
| 48 | #include <__type_traits/unwrap_ref.h> | |
| 49 | #include <__utility/declval.h> | |
| 41 | 50 | #include <__utility/forward.h> |
| 42 | 51 | #include <__utility/move.h> |
| 43 | 52 | #include <__utility/piecewise_construct.h> |
| ... | ... | @@ -47,16 +56,25 @@ |
| 47 | 56 | # pragma GCC system_header |
| 48 | 57 | #endif |
| 49 | 58 | |
| 59 | _LIBCPP_PUSH_MACROS | |
| 60 | #include <__undef_macros> | |
| 61 | ||
| 50 | 62 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 51 | 63 | |
| 52 | #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) | |
| 53 | 64 | template <class, class> |
| 54 | 65 | struct __non_trivially_copyable_base { |
| 55 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY | |
| 66 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI | |
| 56 | 67 | __non_trivially_copyable_base() _NOEXCEPT {} |
| 57 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY | |
| 68 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI | |
| 58 | 69 | __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} |
| 59 | 70 | }; |
| 71 | ||
| 72 | #if _LIBCPP_STD_VER >= 23 | |
| 73 | template <class _Tp> | |
| 74 | struct __is_specialization_of_subrange : false_type {}; | |
| 75 | ||
| 76 | template <class _Iter, class _Sent, ranges::subrange_kind _Kind> | |
| 77 | struct __is_specialization_of_subrange<ranges::subrange<_Iter, _Sent, _Kind>> : true_type {}; | |
| 60 | 78 | #endif |
| 61 | 79 | |
| 62 | 80 | template <class _T1, class _T2> |
| ... | ... | @@ -65,66 +83,80 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 65 | 83 | : private __non_trivially_copyable_base<_T1, _T2> |
| 66 | 84 | #endif |
| 67 | 85 | { |
| 68 | typedef _T1 first_type; | |
| 69 | typedef _T2 second_type; | |
| 86 | using first_type = _T1; | |
| 87 | using second_type = _T2; | |
| 70 | 88 | |
| 71 | 89 | _T1 first; |
| 72 | 90 | _T2 second; |
| 73 | 91 | |
| 74 | pair(pair const&) = default; | |
| 75 | pair(pair&&) = default; | |
| 92 | _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default; | |
| 93 | _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default; | |
| 76 | 94 | |
| 77 | 95 | #ifdef _LIBCPP_CXX03_LANG |
| 78 | _LIBCPP_INLINE_VISIBILITY | |
| 96 | _LIBCPP_HIDE_FROM_ABI | |
| 79 | 97 | pair() : first(), second() {} |
| 80 | 98 | |
| 81 | _LIBCPP_INLINE_VISIBILITY | |
| 99 | _LIBCPP_HIDE_FROM_ABI | |
| 82 | 100 | pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} |
| 83 | 101 | |
| 84 | 102 | template <class _U1, class _U2> |
| 85 | _LIBCPP_INLINE_VISIBILITY | |
| 103 | _LIBCPP_HIDE_FROM_ABI | |
| 86 | 104 | pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} |
| 87 | 105 | |
| 88 | _LIBCPP_INLINE_VISIBILITY | |
| 106 | _LIBCPP_HIDE_FROM_ABI | |
| 89 | 107 | pair& operator=(pair const& __p) { |
| 90 | 108 | first = __p.first; |
| 91 | 109 | second = __p.second; |
| 92 | 110 | return *this; |
| 93 | 111 | } |
| 112 | ||
| 113 | // Extension: This is provided in C++03 because it allows properly handling the | |
| 114 | // assignment to a pair containing references, which would be a hard | |
| 115 | // error otherwise. | |
| 116 | template <class _U1, class _U2, class = __enable_if_t< | |
| 117 | is_assignable<first_type&, _U1 const&>::value && | |
| 118 | is_assignable<second_type&, _U2 const&>::value | |
| 119 | > > | |
| 120 | _LIBCPP_HIDE_FROM_ABI | |
| 121 | pair& operator=(pair<_U1, _U2> const& __p) { | |
| 122 | first = __p.first; | |
| 123 | second = __p.second; | |
| 124 | return *this; | |
| 125 | } | |
| 94 | 126 | #else |
| 95 | 127 | struct _CheckArgs { |
| 96 | 128 | template <int&...> |
| 97 | static constexpr bool __enable_explicit_default() { | |
| 129 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit_default() { | |
| 98 | 130 | return is_default_constructible<_T1>::value |
| 99 | 131 | && is_default_constructible<_T2>::value |
| 100 | 132 | && !__enable_implicit_default<>(); |
| 101 | 133 | } |
| 102 | 134 | |
| 103 | 135 | template <int&...> |
| 104 | static constexpr bool __enable_implicit_default() { | |
| 136 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit_default() { | |
| 105 | 137 | return __is_implicitly_default_constructible<_T1>::value |
| 106 | 138 | && __is_implicitly_default_constructible<_T2>::value; |
| 107 | 139 | } |
| 108 | 140 | |
| 109 | 141 | template <class _U1, class _U2> |
| 110 | static constexpr bool __is_pair_constructible() { | |
| 142 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_pair_constructible() { | |
| 111 | 143 | return is_constructible<first_type, _U1>::value |
| 112 | 144 | && is_constructible<second_type, _U2>::value; |
| 113 | 145 | } |
| 114 | 146 | |
| 115 | 147 | template <class _U1, class _U2> |
| 116 | static constexpr bool __is_implicit() { | |
| 148 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __is_implicit() { | |
| 117 | 149 | return is_convertible<_U1, first_type>::value |
| 118 | 150 | && is_convertible<_U2, second_type>::value; |
| 119 | 151 | } |
| 120 | 152 | |
| 121 | 153 | template <class _U1, class _U2> |
| 122 | static constexpr bool __enable_explicit() { | |
| 154 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_explicit() { | |
| 123 | 155 | return __is_pair_constructible<_U1, _U2>() && !__is_implicit<_U1, _U2>(); |
| 124 | 156 | } |
| 125 | 157 | |
| 126 | 158 | template <class _U1, class _U2> |
| 127 | static constexpr bool __enable_implicit() { | |
| 159 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __enable_implicit() { | |
| 128 | 160 | return __is_pair_constructible<_U1, _U2>() && __is_implicit<_U1, _U2>(); |
| 129 | 161 | } |
| 130 | 162 | }; |
| ... | ... | @@ -133,36 +165,10 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 133 | 165 | using _CheckArgsDep _LIBCPP_NODEBUG = typename conditional< |
| 134 | 166 | _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; |
| 135 | 167 | |
| 136 | struct _CheckTupleLikeConstructor { | |
| 137 | template <class _Tuple> | |
| 138 | static constexpr bool __enable_implicit() { | |
| 139 | return __tuple_convertible<_Tuple, pair>::value; | |
| 140 | } | |
| 141 | ||
| 142 | template <class _Tuple> | |
| 143 | static constexpr bool __enable_explicit() { | |
| 144 | return __tuple_constructible<_Tuple, pair>::value | |
| 145 | && !__tuple_convertible<_Tuple, pair>::value; | |
| 146 | } | |
| 147 | ||
| 148 | template <class _Tuple> | |
| 149 | static constexpr bool __enable_assign() { | |
| 150 | return __tuple_assignable<_Tuple, pair>::value; | |
| 151 | } | |
| 152 | }; | |
| 153 | ||
| 154 | template <class _Tuple> | |
| 155 | using _CheckTLC _LIBCPP_NODEBUG = __conditional_t< | |
| 156 | __tuple_like_with_size<_Tuple, 2>::value | |
| 157 | && !is_same<typename decay<_Tuple>::type, pair>::value, | |
| 158 | _CheckTupleLikeConstructor, | |
| 159 | __check_tuple_constructor_fail | |
| 160 | >; | |
| 161 | ||
| 162 | 168 | template<bool _Dummy = true, typename enable_if< |
| 163 | 169 | _CheckArgsDep<_Dummy>::__enable_explicit_default() |
| 164 | 170 | >::type* = nullptr> |
| 165 | explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 171 | explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 166 | 172 | pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && |
| 167 | 173 | is_nothrow_default_constructible<second_type>::value) |
| 168 | 174 | : first(), second() {} |
| ... | ... | @@ -170,7 +176,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 170 | 176 | template<bool _Dummy = true, typename enable_if< |
| 171 | 177 | _CheckArgsDep<_Dummy>::__enable_implicit_default() |
| 172 | 178 | >::type* = nullptr> |
| 173 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 179 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR | |
| 174 | 180 | pair() _NOEXCEPT_(is_nothrow_default_constructible<first_type>::value && |
| 175 | 181 | is_nothrow_default_constructible<second_type>::value) |
| 176 | 182 | : first(), second() {} |
| ... | ... | @@ -178,7 +184,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 178 | 184 | template <bool _Dummy = true, typename enable_if< |
| 179 | 185 | _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>() |
| 180 | 186 | >::type* = nullptr> |
| 181 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 187 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 182 | 188 | explicit pair(_T1 const& __t1, _T2 const& __t2) |
| 183 | 189 | _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && |
| 184 | 190 | is_nothrow_copy_constructible<second_type>::value) |
| ... | ... | @@ -187,41 +193,41 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 187 | 193 | template<bool _Dummy = true, typename enable_if< |
| 188 | 194 | _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>() |
| 189 | 195 | >::type* = nullptr> |
| 190 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 196 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 191 | 197 | pair(_T1 const& __t1, _T2 const& __t2) |
| 192 | 198 | _NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value && |
| 193 | 199 | is_nothrow_copy_constructible<second_type>::value) |
| 194 | 200 | : first(__t1), second(__t2) {} |
| 195 | 201 | |
| 196 | 202 | template < |
| 197 | #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951 | |
| 203 | #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 | |
| 198 | 204 | class _U1 = _T1, class _U2 = _T2, |
| 199 | 205 | #else |
| 200 | 206 | class _U1, class _U2, |
| 201 | 207 | #endif |
| 202 | 208 | typename enable_if<_CheckArgs::template __enable_explicit<_U1, _U2>()>::type* = nullptr |
| 203 | 209 | > |
| 204 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 210 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 205 | 211 | explicit pair(_U1&& __u1, _U2&& __u2) |
| 206 | 212 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && |
| 207 | 213 | is_nothrow_constructible<second_type, _U2>::value)) |
| 208 | : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} | |
| 214 | : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} | |
| 209 | 215 | |
| 210 | 216 | template < |
| 211 | #if _LIBCPP_STD_VER > 20 // http://wg21.link/P1951 | |
| 217 | #if _LIBCPP_STD_VER >= 23 // http://wg21.link/P1951 | |
| 212 | 218 | class _U1 = _T1, class _U2 = _T2, |
| 213 | 219 | #else |
| 214 | 220 | class _U1, class _U2, |
| 215 | 221 | #endif |
| 216 | 222 | typename enable_if<_CheckArgs::template __enable_implicit<_U1, _U2>()>::type* = nullptr |
| 217 | 223 | > |
| 218 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 224 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 219 | 225 | pair(_U1&& __u1, _U2&& __u2) |
| 220 | 226 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1>::value && |
| 221 | 227 | is_nothrow_constructible<second_type, _U2>::value)) |
| 222 | : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} | |
| 228 | : first(std::forward<_U1>(__u1)), second(std::forward<_U2>(__u2)) {} | |
| 223 | 229 | |
| 224 | #if _LIBCPP_STD_VER > 20 | |
| 230 | #if _LIBCPP_STD_VER >= 23 | |
| 225 | 231 | template<class _U1, class _U2, __enable_if_t< |
| 226 | 232 | _CheckArgs::template __is_pair_constructible<_U1&, _U2&>() |
| 227 | 233 | >* = nullptr> |
| ... | ... | @@ -235,7 +241,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 235 | 241 | template<class _U1, class _U2, typename enable_if< |
| 236 | 242 | _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>() |
| 237 | 243 | >::type* = nullptr> |
| 238 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 244 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 239 | 245 | explicit pair(pair<_U1, _U2> const& __p) |
| 240 | 246 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && |
| 241 | 247 | is_nothrow_constructible<second_type, _U2 const&>::value)) |
| ... | ... | @@ -244,7 +250,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 244 | 250 | template<class _U1, class _U2, typename enable_if< |
| 245 | 251 | _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>() |
| 246 | 252 | >::type* = nullptr> |
| 247 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 253 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 248 | 254 | pair(pair<_U1, _U2> const& __p) |
| 249 | 255 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1 const&>::value && |
| 250 | 256 | is_nothrow_constructible<second_type, _U2 const&>::value)) |
| ... | ... | @@ -253,22 +259,22 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 253 | 259 | template<class _U1, class _U2, typename enable_if< |
| 254 | 260 | _CheckArgs::template __enable_explicit<_U1, _U2>() |
| 255 | 261 | >::type* = nullptr> |
| 256 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 262 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 257 | 263 | explicit pair(pair<_U1, _U2>&&__p) |
| 258 | 264 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && |
| 259 | 265 | is_nothrow_constructible<second_type, _U2&&>::value)) |
| 260 | : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} | |
| 266 | : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} | |
| 261 | 267 | |
| 262 | 268 | template<class _U1, class _U2, typename enable_if< |
| 263 | 269 | _CheckArgs::template __enable_implicit<_U1, _U2>() |
| 264 | 270 | >::type* = nullptr> |
| 265 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 271 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 266 | 272 | pair(pair<_U1, _U2>&& __p) |
| 267 | 273 | _NOEXCEPT_((is_nothrow_constructible<first_type, _U1&&>::value && |
| 268 | 274 | is_nothrow_constructible<second_type, _U2&&>::value)) |
| 269 | : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} | |
| 275 | : first(std::forward<_U1>(__p.first)), second(std::forward<_U2>(__p.second)) {} | |
| 270 | 276 | |
| 271 | #if _LIBCPP_STD_VER > 20 | |
| 277 | #if _LIBCPP_STD_VER >= 23 | |
| 272 | 278 | template<class _U1, class _U2, __enable_if_t< |
| 273 | 279 | _CheckArgs::template __is_pair_constructible<const _U1&&, const _U2&&>() |
| 274 | 280 | >* = nullptr> |
| ... | ... | @@ -280,24 +286,27 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 280 | 286 | : first(std::move(__p.first)), second(std::move(__p.second)) {} |
| 281 | 287 | #endif |
| 282 | 288 | |
| 283 | template<class _Tuple, typename enable_if< | |
| 284 | _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>() | |
| 285 | >::type* = nullptr> | |
| 286 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 287 | explicit pair(_Tuple&& __p) | |
| 288 | : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), | |
| 289 | second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} | |
| 289 | # if _LIBCPP_STD_VER >= 23 | |
| 290 | // This is a workaround for http://llvm.org/PR60710. We should be able to remove it once Clang is fixed. | |
| 291 | template <class _PairLike, bool _Enable = tuple_size<remove_cvref_t<_PairLike>>::value == 2> | |
| 292 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __pair_like_explicit_wknd() { | |
| 293 | if constexpr (tuple_size<remove_cvref_t<_PairLike>>::value == 2) { | |
| 294 | return !is_convertible_v<decltype(std::get<0>(std::declval<_PairLike&&>())), first_type> || | |
| 295 | !is_convertible_v<decltype(std::get<1>(std::declval<_PairLike&&>())), second_type>; | |
| 296 | } | |
| 297 | return false; | |
| 298 | } | |
| 290 | 299 | |
| 291 | template<class _Tuple, typename enable_if< | |
| 292 | _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>() | |
| 293 | >::type* = nullptr> | |
| 294 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 295 | pair(_Tuple&& __p) | |
| 296 | : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), | |
| 297 | second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} | |
| 300 | template <__pair_like _PairLike> | |
| 301 | requires(is_constructible_v<first_type, decltype(std::get<0>(std::declval<_PairLike&&>()))> && | |
| 302 | is_constructible_v<second_type, decltype(std::get<1>(std::declval<_PairLike&&>()))>) | |
| 303 | _LIBCPP_HIDE_FROM_ABI constexpr explicit(__pair_like_explicit_wknd<_PairLike>()) | |
| 304 | pair(_PairLike&& __p) | |
| 305 | : first(std::get<0>(std::forward<_PairLike>(__p))), second(std::get<1>(std::forward<_PairLike>(__p))) {} | |
| 306 | # endif | |
| 298 | 307 | |
| 299 | 308 | template <class... _Args1, class... _Args2> |
| 300 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 309 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 301 | 310 | pair(piecewise_construct_t __pc, |
| 302 | 311 | tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) |
| 303 | 312 | _NOEXCEPT_((is_nothrow_constructible<first_type, _Args1...>::value && |
| ... | ... | @@ -306,7 +315,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 306 | 315 | typename __make_tuple_indices<sizeof...(_Args1)>::type(), |
| 307 | 316 | typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} |
| 308 | 317 | |
| 309 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 318 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 310 | 319 | pair& operator=(__conditional_t< |
| 311 | 320 | is_copy_assignable<first_type>::value && |
| 312 | 321 | is_copy_assignable<second_type>::value, |
| ... | ... | @@ -319,7 +328,7 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 319 | 328 | return *this; |
| 320 | 329 | } |
| 321 | 330 | |
| 322 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 331 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 323 | 332 | pair& operator=(__conditional_t< |
| 324 | 333 | is_move_assignable<first_type>::value && |
| 325 | 334 | is_move_assignable<second_type>::value, |
| ... | ... | @@ -327,12 +336,34 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 327 | 336 | _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && |
| 328 | 337 | is_nothrow_move_assignable<second_type>::value) |
| 329 | 338 | { |
| 330 | first = _VSTD::forward<first_type>(__p.first); | |
| 331 | second = _VSTD::forward<second_type>(__p.second); | |
| 339 | first = std::forward<first_type>(__p.first); | |
| 340 | second = std::forward<second_type>(__p.second); | |
| 332 | 341 | return *this; |
| 333 | 342 | } |
| 334 | 343 | |
| 335 | #if _LIBCPP_STD_VER > 20 | |
| 344 | template <class _U1, class _U2, __enable_if_t< | |
| 345 | is_assignable<first_type&, _U1 const&>::value && | |
| 346 | is_assignable<second_type&, _U2 const&>::value | |
| 347 | >* = nullptr> | |
| 348 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 349 | pair& operator=(pair<_U1, _U2> const& __p) { | |
| 350 | first = __p.first; | |
| 351 | second = __p.second; | |
| 352 | return *this; | |
| 353 | } | |
| 354 | ||
| 355 | template <class _U1, class _U2, __enable_if_t< | |
| 356 | is_assignable<first_type&, _U1>::value && | |
| 357 | is_assignable<second_type&, _U2>::value | |
| 358 | >* = nullptr> | |
| 359 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 360 | pair& operator=(pair<_U1, _U2>&& __p) { | |
| 361 | first = std::forward<_U1>(__p.first); | |
| 362 | second = std::forward<_U2>(__p.second); | |
| 363 | return *this; | |
| 364 | } | |
| 365 | ||
| 366 | # if _LIBCPP_STD_VER >= 23 | |
| 336 | 367 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 337 | 368 | const pair& operator=(pair const& __p) const |
| 338 | 369 | noexcept(is_nothrow_copy_assignable_v<const first_type> && |
| ... | ... | @@ -374,30 +405,178 @@ struct _LIBCPP_TEMPLATE_VIS pair |
| 374 | 405 | second = std::forward<_U2>(__p.second); |
| 375 | 406 | return *this; |
| 376 | 407 | } |
| 377 | #endif // _LIBCPP_STD_VER > 20 | |
| 378 | ||
| 379 | template <class _Tuple, typename enable_if< | |
| 380 | _CheckTLC<_Tuple>::template __enable_assign<_Tuple>() | |
| 381 | >::type* = nullptr> | |
| 382 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 383 | pair& operator=(_Tuple&& __p) { | |
| 384 | first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p)); | |
| 385 | second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p)); | |
| 408 | ||
| 409 | template <__pair_like _PairLike> | |
| 410 | requires(__different_from<_PairLike, pair> && | |
| 411 | !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && | |
| 412 | is_assignable_v<first_type&, decltype(std::get<0>(std::declval<_PairLike>()))> && | |
| 413 | is_assignable_v<second_type&, decltype(std::get<1>(std::declval<_PairLike>()))>) | |
| 414 | _LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(_PairLike&& __p) { | |
| 415 | first = std::get<0>(std::forward<_PairLike>(__p)); | |
| 416 | second = std::get<1>(std::forward<_PairLike>(__p)); | |
| 386 | 417 | return *this; |
| 387 | 418 | } |
| 388 | #endif | |
| 389 | 419 | |
| 390 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 420 | template <__pair_like _PairLike> | |
| 421 | requires(__different_from<_PairLike, pair> && | |
| 422 | !__is_specialization_of_subrange<remove_cvref_t<_PairLike>>::value && | |
| 423 | is_assignable_v<first_type const&, decltype(std::get<0>(std::declval<_PairLike>()))> && | |
| 424 | is_assignable_v<second_type const&, decltype(std::get<1>(std::declval<_PairLike>()))>) | |
| 425 | _LIBCPP_HIDE_FROM_ABI constexpr pair const& operator=(_PairLike&& __p) const { | |
| 426 | first = std::get<0>(std::forward<_PairLike>(__p)); | |
| 427 | second = std::get<1>(std::forward<_PairLike>(__p)); | |
| 428 | return *this; | |
| 429 | } | |
| 430 | # endif // _LIBCPP_STD_VER >= 23 | |
| 431 | ||
| 432 | // Prior to C++23, we provide an approximation of constructors and assignment operators from | |
| 433 | // pair-like types. This was historically provided as an extension. | |
| 434 | #if _LIBCPP_STD_VER < 23 | |
| 435 | // from std::tuple | |
| 436 | template<class _U1, class _U2, __enable_if_t< | |
| 437 | is_convertible<_U1 const&, _T1>::value && | |
| 438 | is_convertible<_U2 const&, _T2>::value | |
| 439 | >* = nullptr> | |
| 440 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 441 | pair(tuple<_U1, _U2> const& __p) | |
| 442 | : first(std::get<0>(__p)), | |
| 443 | second(std::get<1>(__p)) {} | |
| 444 | ||
| 445 | template<class _U1, class _U2, __enable_if_t< | |
| 446 | is_constructible<_T1, _U1 const&>::value && | |
| 447 | is_constructible<_T2, _U2 const&>::value && | |
| 448 | !(is_convertible<_U1 const&, _T1>::value && | |
| 449 | is_convertible<_U2 const&, _T2>::value) | |
| 450 | >* = nullptr> | |
| 451 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 452 | explicit | |
| 453 | pair(tuple<_U1, _U2> const& __p) | |
| 454 | : first(std::get<0>(__p)), | |
| 455 | second(std::get<1>(__p)) {} | |
| 456 | ||
| 457 | template<class _U1, class _U2, __enable_if_t< | |
| 458 | is_convertible<_U1, _T1>::value && | |
| 459 | is_convertible<_U2, _T2>::value | |
| 460 | >* = nullptr> | |
| 461 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 462 | pair(tuple<_U1, _U2>&& __p) | |
| 463 | : first(std::get<0>(std::move(__p))), | |
| 464 | second(std::get<1>(std::move(__p))) {} | |
| 465 | ||
| 466 | template<class _U1, class _U2, __enable_if_t< | |
| 467 | is_constructible<_T1, _U1>::value && | |
| 468 | is_constructible<_T2, _U2>::value && | |
| 469 | !(is_convertible<_U1, _T1>::value && | |
| 470 | is_convertible<_U2, _T2>::value) | |
| 471 | >* = nullptr> | |
| 472 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 473 | explicit | |
| 474 | pair(tuple<_U1, _U2>&& __p) | |
| 475 | : first(std::get<0>(std::move(__p))), | |
| 476 | second(std::get<1>(std::move(__p))) {} | |
| 477 | ||
| 478 | ||
| 479 | template<class _U1, class _U2, __enable_if_t< | |
| 480 | is_assignable<_T1&, _U1 const&>::value && | |
| 481 | is_assignable<_T2&, _U2 const&>::value | |
| 482 | >* = nullptr> | |
| 483 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 484 | pair& operator=(tuple<_U1, _U2> const& __p) { | |
| 485 | first = std::get<0>(__p); | |
| 486 | second = std::get<1>(__p); | |
| 487 | return *this; | |
| 488 | } | |
| 489 | ||
| 490 | template<class _U1, class _U2, __enable_if_t< | |
| 491 | is_assignable<_T1&, _U1&&>::value && | |
| 492 | is_assignable<_T2&, _U2&&>::value | |
| 493 | >* = nullptr> | |
| 494 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 495 | pair& operator=(tuple<_U1, _U2>&& __p) { | |
| 496 | first = std::get<0>(std::move(__p)); | |
| 497 | second = std::get<1>(std::move(__p)); | |
| 498 | return *this; | |
| 499 | } | |
| 500 | ||
| 501 | // from std::array | |
| 502 | template<class _Up, __enable_if_t< | |
| 503 | is_convertible<_Up const&, _T1>::value && | |
| 504 | is_convertible<_Up const&, _T2>::value | |
| 505 | >* = nullptr> | |
| 506 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 507 | pair(array<_Up, 2> const& __p) | |
| 508 | : first(__p[0]), | |
| 509 | second(__p[1]) {} | |
| 510 | ||
| 511 | template<class _Up, __enable_if_t< | |
| 512 | is_constructible<_T1, _Up const&>::value && | |
| 513 | is_constructible<_T2, _Up const&>::value && | |
| 514 | !(is_convertible<_Up const&, _T1>::value && | |
| 515 | is_convertible<_Up const&, _T2>::value) | |
| 516 | >* = nullptr> | |
| 517 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 518 | explicit | |
| 519 | pair(array<_Up, 2> const& __p) | |
| 520 | : first(__p[0]), | |
| 521 | second(__p[1]) {} | |
| 522 | ||
| 523 | template<class _Up, __enable_if_t< | |
| 524 | is_convertible<_Up, _T1>::value && | |
| 525 | is_convertible<_Up, _T2>::value | |
| 526 | >* = nullptr> | |
| 527 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 528 | pair(array<_Up, 2>&& __p) | |
| 529 | : first(std::move(__p)[0]), | |
| 530 | second(std::move(__p)[1]) {} | |
| 531 | ||
| 532 | template<class _Up, __enable_if_t< | |
| 533 | is_constructible<_T1, _Up>::value && | |
| 534 | is_constructible<_T2, _Up>::value && | |
| 535 | !(is_convertible<_Up, _T1>::value && | |
| 536 | is_convertible<_Up, _T2>::value) | |
| 537 | >* = nullptr> | |
| 538 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 539 | explicit | |
| 540 | pair(array<_Up, 2>&& __p) | |
| 541 | : first(std::move(__p)[0]), | |
| 542 | second(std::move(__p)[1]) {} | |
| 543 | ||
| 544 | ||
| 545 | template<class _Up, __enable_if_t< | |
| 546 | is_assignable<_T1&, _Up const&>::value && | |
| 547 | is_assignable<_T2&, _Up const&>::value | |
| 548 | >* = nullptr> | |
| 549 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 550 | pair& operator=(array<_Up, 2> const& __p) { | |
| 551 | first = std::get<0>(__p); | |
| 552 | second = std::get<1>(__p); | |
| 553 | return *this; | |
| 554 | } | |
| 555 | ||
| 556 | template<class _Up, __enable_if_t< | |
| 557 | is_assignable<_T1&, _Up>::value && | |
| 558 | is_assignable<_T2&, _Up>::value | |
| 559 | >* = nullptr> | |
| 560 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 561 | pair& operator=(array<_Up, 2>&& __p) { | |
| 562 | first = std::get<0>(std::move(__p)); | |
| 563 | second = std::get<1>(std::move(__p)); | |
| 564 | return *this; | |
| 565 | } | |
| 566 | #endif // _LIBCPP_STD_VER < 23 | |
| 567 | #endif // _LIBCPP_CXX03_LANG | |
| 568 | ||
| 569 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 391 | 570 | void |
| 392 | 571 | swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && |
| 393 | 572 | __is_nothrow_swappable<second_type>::value) |
| 394 | 573 | { |
| 395 | using _VSTD::swap; | |
| 574 | using std::swap; | |
| 396 | 575 | swap(first, __p.first); |
| 397 | 576 | swap(second, __p.second); |
| 398 | 577 | } |
| 399 | 578 | |
| 400 | #if _LIBCPP_STD_VER > 20 | |
| 579 | #if _LIBCPP_STD_VER >= 23 | |
| 401 | 580 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 402 | 581 | void swap(const pair& __p) const |
| 403 | 582 | noexcept(__is_nothrow_swappable<const first_type>::value && |
| ... | ... | @@ -412,88 +591,88 @@ private: |
| 412 | 591 | |
| 413 | 592 | #ifndef _LIBCPP_CXX03_LANG |
| 414 | 593 | template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> |
| 415 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 594 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 416 | 595 | pair(piecewise_construct_t, |
| 417 | 596 | tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, |
| 418 | 597 | __tuple_indices<_I1...>, __tuple_indices<_I2...>); |
| 419 | 598 | #endif |
| 420 | 599 | }; |
| 421 | 600 | |
| 422 | #if _LIBCPP_STD_VER > 14 | |
| 601 | #if _LIBCPP_STD_VER >= 17 | |
| 423 | 602 | template<class _T1, class _T2> |
| 424 | 603 | pair(_T1, _T2) -> pair<_T1, _T2>; |
| 425 | 604 | #endif |
| 426 | 605 | |
| 427 | 606 | // [pairs.spec], specialized algorithms |
| 428 | 607 | |
| 429 | template <class _T1, class _T2> | |
| 430 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 608 | template <class _T1, class _T2, class _U1, class _U2> | |
| 609 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 431 | 610 | bool |
| 432 | operator==(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 611 | operator==(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 433 | 612 | { |
| 434 | 613 | return __x.first == __y.first && __x.second == __y.second; |
| 435 | 614 | } |
| 436 | 615 | |
| 437 | #if _LIBCPP_STD_VER > 17 | |
| 616 | #if _LIBCPP_STD_VER >= 20 | |
| 438 | 617 | |
| 439 | template <class _T1, class _T2> | |
| 618 | template <class _T1, class _T2, class _U1, class _U2> | |
| 440 | 619 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 441 | 620 | common_comparison_category_t< |
| 442 | __synth_three_way_result<_T1>, | |
| 443 | __synth_three_way_result<_T2> > | |
| 444 | operator<=>(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 621 | __synth_three_way_result<_T1, _U1>, | |
| 622 | __synth_three_way_result<_T2, _U2> > | |
| 623 | operator<=>(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 445 | 624 | { |
| 446 | if (auto __c = _VSTD::__synth_three_way(__x.first, __y.first); __c != 0) { | |
| 625 | if (auto __c = std::__synth_three_way(__x.first, __y.first); __c != 0) { | |
| 447 | 626 | return __c; |
| 448 | 627 | } |
| 449 | return _VSTD::__synth_three_way(__x.second, __y.second); | |
| 628 | return std::__synth_three_way(__x.second, __y.second); | |
| 450 | 629 | } |
| 451 | 630 | |
| 452 | #else // _LIBCPP_STD_VER > 17 | |
| 631 | #else // _LIBCPP_STD_VER >= 20 | |
| 453 | 632 | |
| 454 | template <class _T1, class _T2> | |
| 455 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 633 | template <class _T1, class _T2, class _U1, class _U2> | |
| 634 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 456 | 635 | bool |
| 457 | operator!=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 636 | operator!=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 458 | 637 | { |
| 459 | 638 | return !(__x == __y); |
| 460 | 639 | } |
| 461 | 640 | |
| 462 | template <class _T1, class _T2> | |
| 463 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 641 | template <class _T1, class _T2, class _U1, class _U2> | |
| 642 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 464 | 643 | bool |
| 465 | operator< (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 644 | operator< (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 466 | 645 | { |
| 467 | 646 | return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second); |
| 468 | 647 | } |
| 469 | 648 | |
| 470 | template <class _T1, class _T2> | |
| 471 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 649 | template <class _T1, class _T2, class _U1, class _U2> | |
| 650 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 472 | 651 | bool |
| 473 | operator> (const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 652 | operator> (const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 474 | 653 | { |
| 475 | 654 | return __y < __x; |
| 476 | 655 | } |
| 477 | 656 | |
| 478 | template <class _T1, class _T2> | |
| 479 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 657 | template <class _T1, class _T2, class _U1, class _U2> | |
| 658 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 480 | 659 | bool |
| 481 | operator>=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 660 | operator>=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 482 | 661 | { |
| 483 | 662 | return !(__x < __y); |
| 484 | 663 | } |
| 485 | 664 | |
| 486 | template <class _T1, class _T2> | |
| 487 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 665 | template <class _T1, class _T2, class _U1, class _U2> | |
| 666 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 488 | 667 | bool |
| 489 | operator<=(const pair<_T1,_T2>& __x, const pair<_T1,_T2>& __y) | |
| 668 | operator<=(const pair<_T1,_T2>& __x, const pair<_U1,_U2>& __y) | |
| 490 | 669 | { |
| 491 | 670 | return !(__y < __x); |
| 492 | 671 | } |
| 493 | 672 | |
| 494 | #endif // _LIBCPP_STD_VER > 17 | |
| 673 | #endif // _LIBCPP_STD_VER >= 20 | |
| 495 | 674 | |
| 496 | #if _LIBCPP_STD_VER > 20 | |
| 675 | #if _LIBCPP_STD_VER >= 23 | |
| 497 | 676 | template <class _T1, class _T2, class _U1, class _U2, template<class> class _TQual, template<class> class _UQual> |
| 498 | 677 | requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, |
| 499 | 678 | common_reference_t<_TQual<_T2>, _UQual<_U2>>>; } |
| ... | ... | @@ -507,10 +686,10 @@ template <class _T1, class _T2, class _U1, class _U2> |
| 507 | 686 | struct common_type<pair<_T1, _T2>, pair<_U1, _U2>> { |
| 508 | 687 | using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; |
| 509 | 688 | }; |
| 510 | #endif // _LIBCPP_STD_VER > 20 | |
| 689 | #endif // _LIBCPP_STD_VER >= 23 | |
| 511 | 690 | |
| 512 | 691 | template <class _T1, class _T2> |
| 513 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 692 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 514 | 693 | typename enable_if |
| 515 | 694 | < |
| 516 | 695 | __is_swappable<_T1>::value && |
| ... | ... | @@ -524,7 +703,7 @@ swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) |
| 524 | 703 | __x.swap(__y); |
| 525 | 704 | } |
| 526 | 705 | |
| 527 | #if _LIBCPP_STD_VER > 20 | |
| 706 | #if _LIBCPP_STD_VER >= 23 | |
| 528 | 707 | template <class _T1, class _T2> |
| 529 | 708 | requires (__is_swappable<const _T1>::value && |
| 530 | 709 | __is_swappable<const _T2>::value) |
| ... | ... | @@ -537,12 +716,12 @@ void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) |
| 537 | 716 | #endif |
| 538 | 717 | |
| 539 | 718 | template <class _T1, class _T2> |
| 540 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 719 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 541 | 720 | pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> |
| 542 | 721 | make_pair(_T1&& __t1, _T2&& __t2) |
| 543 | 722 | { |
| 544 | 723 | return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type> |
| 545 | (_VSTD::forward<_T1>(__t1), _VSTD::forward<_T2>(__t2)); | |
| 724 | (std::forward<_T1>(__t1), std::forward<_T2>(__t2)); | |
| 546 | 725 | } |
| 547 | 726 | |
| 548 | 727 | template <class _T1, class _T2> |
| ... | ... | @@ -558,13 +737,13 @@ struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > |
| 558 | 737 | template <class _T1, class _T2> |
| 559 | 738 | struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > |
| 560 | 739 | { |
| 561 | typedef _LIBCPP_NODEBUG _T1 type; | |
| 740 | using type _LIBCPP_NODEBUG = _T1; | |
| 562 | 741 | }; |
| 563 | 742 | |
| 564 | 743 | template <class _T1, class _T2> |
| 565 | 744 | struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > |
| 566 | 745 | { |
| 567 | typedef _LIBCPP_NODEBUG _T2 type; | |
| 746 | using type _LIBCPP_NODEBUG = _T2; | |
| 568 | 747 | }; |
| 569 | 748 | |
| 570 | 749 | template <size_t _Ip> struct __get_pair; |
| ... | ... | @@ -574,27 +753,27 @@ struct __get_pair<0> |
| 574 | 753 | { |
| 575 | 754 | template <class _T1, class _T2> |
| 576 | 755 | static |
| 577 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 756 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 578 | 757 | _T1& |
| 579 | 758 | get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} |
| 580 | 759 | |
| 581 | 760 | template <class _T1, class _T2> |
| 582 | 761 | static |
| 583 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 762 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 584 | 763 | const _T1& |
| 585 | 764 | get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} |
| 586 | 765 | |
| 587 | 766 | template <class _T1, class _T2> |
| 588 | 767 | static |
| 589 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 768 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 590 | 769 | _T1&& |
| 591 | get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);} | |
| 770 | get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T1>(__p.first);} | |
| 592 | 771 | |
| 593 | 772 | template <class _T1, class _T2> |
| 594 | 773 | static |
| 595 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 774 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 596 | 775 | const _T1&& |
| 597 | get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T1>(__p.first);} | |
| 776 | get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T1>(__p.first);} | |
| 598 | 777 | }; |
| 599 | 778 | |
| 600 | 779 | template <> |
| ... | ... | @@ -602,31 +781,31 @@ struct __get_pair<1> |
| 602 | 781 | { |
| 603 | 782 | template <class _T1, class _T2> |
| 604 | 783 | static |
| 605 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 784 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 606 | 785 | _T2& |
| 607 | 786 | get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} |
| 608 | 787 | |
| 609 | 788 | template <class _T1, class _T2> |
| 610 | 789 | static |
| 611 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 790 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 612 | 791 | const _T2& |
| 613 | 792 | get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} |
| 614 | 793 | |
| 615 | 794 | template <class _T1, class _T2> |
| 616 | 795 | static |
| 617 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 796 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 618 | 797 | _T2&& |
| 619 | get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);} | |
| 798 | get(pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<_T2>(__p.second);} | |
| 620 | 799 | |
| 621 | 800 | template <class _T1, class _T2> |
| 622 | 801 | static |
| 623 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 802 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 624 | 803 | const _T2&& |
| 625 | get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<const _T2>(__p.second);} | |
| 804 | get(const pair<_T1, _T2>&& __p) _NOEXCEPT {return std::forward<const _T2>(__p.second);} | |
| 626 | 805 | }; |
| 627 | 806 | |
| 628 | 807 | template <size_t _Ip, class _T1, class _T2> |
| 629 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 808 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 630 | 809 | typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
| 631 | 810 | get(pair<_T1, _T2>& __p) _NOEXCEPT |
| 632 | 811 | { |
| ... | ... | @@ -634,7 +813,7 @@ get(pair<_T1, _T2>& __p) _NOEXCEPT |
| 634 | 813 | } |
| 635 | 814 | |
| 636 | 815 | template <size_t _Ip, class _T1, class _T2> |
| 637 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 816 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 638 | 817 | const typename tuple_element<_Ip, pair<_T1, _T2> >::type& |
| 639 | 818 | get(const pair<_T1, _T2>& __p) _NOEXCEPT |
| 640 | 819 | { |
| ... | ... | @@ -642,80 +821,82 @@ get(const pair<_T1, _T2>& __p) _NOEXCEPT |
| 642 | 821 | } |
| 643 | 822 | |
| 644 | 823 | template <size_t _Ip, class _T1, class _T2> |
| 645 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 824 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 646 | 825 | typename tuple_element<_Ip, pair<_T1, _T2> >::type&& |
| 647 | 826 | get(pair<_T1, _T2>&& __p) _NOEXCEPT |
| 648 | 827 | { |
| 649 | return __get_pair<_Ip>::get(_VSTD::move(__p)); | |
| 828 | return __get_pair<_Ip>::get(std::move(__p)); | |
| 650 | 829 | } |
| 651 | 830 | |
| 652 | 831 | template <size_t _Ip, class _T1, class _T2> |
| 653 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 832 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 | |
| 654 | 833 | const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& |
| 655 | 834 | get(const pair<_T1, _T2>&& __p) _NOEXCEPT |
| 656 | 835 | { |
| 657 | return __get_pair<_Ip>::get(_VSTD::move(__p)); | |
| 836 | return __get_pair<_Ip>::get(std::move(__p)); | |
| 658 | 837 | } |
| 659 | 838 | |
| 660 | #if _LIBCPP_STD_VER > 11 | |
| 839 | #if _LIBCPP_STD_VER >= 14 | |
| 661 | 840 | template <class _T1, class _T2> |
| 662 | inline _LIBCPP_INLINE_VISIBILITY | |
| 841 | inline _LIBCPP_HIDE_FROM_ABI | |
| 663 | 842 | constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT |
| 664 | 843 | { |
| 665 | 844 | return __get_pair<0>::get(__p); |
| 666 | 845 | } |
| 667 | 846 | |
| 668 | 847 | template <class _T1, class _T2> |
| 669 | inline _LIBCPP_INLINE_VISIBILITY | |
| 848 | inline _LIBCPP_HIDE_FROM_ABI | |
| 670 | 849 | constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT |
| 671 | 850 | { |
| 672 | 851 | return __get_pair<0>::get(__p); |
| 673 | 852 | } |
| 674 | 853 | |
| 675 | 854 | template <class _T1, class _T2> |
| 676 | inline _LIBCPP_INLINE_VISIBILITY | |
| 855 | inline _LIBCPP_HIDE_FROM_ABI | |
| 677 | 856 | constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT |
| 678 | 857 | { |
| 679 | return __get_pair<0>::get(_VSTD::move(__p)); | |
| 858 | return __get_pair<0>::get(std::move(__p)); | |
| 680 | 859 | } |
| 681 | 860 | |
| 682 | 861 | template <class _T1, class _T2> |
| 683 | inline _LIBCPP_INLINE_VISIBILITY | |
| 862 | inline _LIBCPP_HIDE_FROM_ABI | |
| 684 | 863 | constexpr _T1 const && get(pair<_T1, _T2> const&& __p) _NOEXCEPT |
| 685 | 864 | { |
| 686 | return __get_pair<0>::get(_VSTD::move(__p)); | |
| 865 | return __get_pair<0>::get(std::move(__p)); | |
| 687 | 866 | } |
| 688 | 867 | |
| 689 | 868 | template <class _T1, class _T2> |
| 690 | inline _LIBCPP_INLINE_VISIBILITY | |
| 869 | inline _LIBCPP_HIDE_FROM_ABI | |
| 691 | 870 | constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT |
| 692 | 871 | { |
| 693 | 872 | return __get_pair<1>::get(__p); |
| 694 | 873 | } |
| 695 | 874 | |
| 696 | 875 | template <class _T1, class _T2> |
| 697 | inline _LIBCPP_INLINE_VISIBILITY | |
| 876 | inline _LIBCPP_HIDE_FROM_ABI | |
| 698 | 877 | constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT |
| 699 | 878 | { |
| 700 | 879 | return __get_pair<1>::get(__p); |
| 701 | 880 | } |
| 702 | 881 | |
| 703 | 882 | template <class _T1, class _T2> |
| 704 | inline _LIBCPP_INLINE_VISIBILITY | |
| 883 | inline _LIBCPP_HIDE_FROM_ABI | |
| 705 | 884 | constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT |
| 706 | 885 | { |
| 707 | return __get_pair<1>::get(_VSTD::move(__p)); | |
| 886 | return __get_pair<1>::get(std::move(__p)); | |
| 708 | 887 | } |
| 709 | 888 | |
| 710 | 889 | template <class _T1, class _T2> |
| 711 | inline _LIBCPP_INLINE_VISIBILITY | |
| 890 | inline _LIBCPP_HIDE_FROM_ABI | |
| 712 | 891 | constexpr _T1 const && get(pair<_T2, _T1> const&& __p) _NOEXCEPT |
| 713 | 892 | { |
| 714 | return __get_pair<1>::get(_VSTD::move(__p)); | |
| 893 | return __get_pair<1>::get(std::move(__p)); | |
| 715 | 894 | } |
| 716 | 895 | |
| 717 | #endif // _LIBCPP_STD_VER > 11 | |
| 896 | #endif // _LIBCPP_STD_VER >= 14 | |
| 718 | 897 | |
| 719 | 898 | _LIBCPP_END_NAMESPACE_STD |
| 720 | 899 | |
| 900 | _LIBCPP_POP_MACROS | |
| 901 | ||
| 721 | 902 | #endif // _LIBCPP___UTILITY_PAIR_H |
lib/libcxx/include/__utility/piecewise_construct.h+5-4| ... | ... | @@ -18,10 +18,11 @@ |
| 18 | 18 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 19 | |
| 20 | 20 | struct _LIBCPP_TEMPLATE_VIS piecewise_construct_t { explicit piecewise_construct_t() = default; }; |
| 21 | #if defined(_LIBCPP_CXX03_LANG) || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 22 | extern _LIBCPP_EXPORTED_FROM_ABI const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); | |
| 23 | #else | |
| 24 | /* inline */ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); | |
| 21 | ||
| 22 | #if _LIBCPP_STD_VER >= 17 | |
| 23 | inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); | |
| 24 | #elif !defined(_LIBCPP_CXX03_LANG) | |
| 25 | constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); | |
| 25 | 26 | #endif |
| 26 | 27 | |
| 27 | 28 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/__utility/swap.h+5| ... | ... | @@ -23,6 +23,9 @@ |
| 23 | 23 | # pragma GCC system_header |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | _LIBCPP_PUSH_MACROS | |
| 27 | #include <__undef_macros> | |
| 28 | ||
| 26 | 29 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 30 | |
| 28 | 31 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -51,4 +54,6 @@ swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::v |
| 51 | 54 | |
| 52 | 55 | _LIBCPP_END_NAMESPACE_STD |
| 53 | 56 | |
| 57 | _LIBCPP_POP_MACROS | |
| 58 | ||
| 54 | 59 | #endif // _LIBCPP___UTILITY_SWAP_H |
lib/libcxx/include/__utility/terminate_on_exception.h created+48| ... | ... | @@ -0,0 +1,48 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H | |
| 10 | #define _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__exception/terminate.h> | |
| 14 | #include <new> | |
| 15 | ||
| 16 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 17 | # pragma GCC system_header | |
| 18 | #endif | |
| 19 | ||
| 20 | #if _LIBCPP_STD_VER >= 17 | |
| 21 | ||
| 22 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 23 | ||
| 24 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 25 | ||
| 26 | template <class _Func> | |
| 27 | _LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) { | |
| 28 | try { | |
| 29 | return __func(); | |
| 30 | } catch (...) { | |
| 31 | std::terminate(); | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 35 | # else // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 36 | ||
| 37 | template <class _Func> | |
| 38 | _LIBCPP_HIDE_FROM_ABI auto __terminate_on_exception(_Func __func) { | |
| 39 | return __func(); | |
| 40 | } | |
| 41 | ||
| 42 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 43 | ||
| 44 | _LIBCPP_END_NAMESPACE_STD | |
| 45 | ||
| 46 | #endif // _LIBCPP_STD_VER >= 17 | |
| 47 | ||
| 48 | #endif // _LIBCPP___UTILITY_TERMINATE_ON_EXCEPTION_H |
lib/libcxx/include/__utility/to_underlying.h+1-1| ... | ... | @@ -27,7 +27,7 @@ __to_underlying(_Tp __val) noexcept { |
| 27 | 27 | } |
| 28 | 28 | #endif // !_LIBCPP_CXX03_LANG |
| 29 | 29 | |
| 30 | #if _LIBCPP_STD_VER > 20 | |
| 30 | #if _LIBCPP_STD_VER >= 23 | |
| 31 | 31 | template <class _Tp> |
| 32 | 32 | _LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY constexpr underlying_type_t<_Tp> |
| 33 | 33 | to_underlying(_Tp __val) noexcept { |
lib/libcxx/include/__utility/unreachable.h+2-2| ... | ... | @@ -19,11 +19,11 @@ |
| 19 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 20 | 20 | |
| 21 | 21 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __libcpp_unreachable() { |
| 22 | _LIBCPP_ASSERT(false, "std::unreachable() was reached"); | |
| 22 | _LIBCPP_ASSERT_UNCATEGORIZED(false, "std::unreachable() was reached"); | |
| 23 | 23 | __builtin_unreachable(); |
| 24 | 24 | } |
| 25 | 25 | |
| 26 | #if _LIBCPP_STD_VER > 20 | |
| 26 | #if _LIBCPP_STD_VER >= 23 | |
| 27 | 27 | |
| 28 | 28 | [[noreturn]] _LIBCPP_HIDE_FROM_ABI inline void unreachable() { __libcpp_unreachable(); } |
| 29 | 29 |
lib/libcxx/include/__variant/monostate.h+5-5| ... | ... | @@ -21,19 +21,19 @@ |
| 21 | 21 | |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 23 | 23 | |
| 24 | #if _LIBCPP_STD_VER > 14 | |
| 24 | #if _LIBCPP_STD_VER >= 17 | |
| 25 | 25 | |
| 26 | 26 | struct _LIBCPP_TEMPLATE_VIS monostate {}; |
| 27 | 27 | |
| 28 | 28 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(monostate, monostate) noexcept { return true; } |
| 29 | 29 | |
| 30 | # if _LIBCPP_STD_VER > 17 | |
| 30 | # if _LIBCPP_STD_VER >= 20 | |
| 31 | 31 | |
| 32 | 32 | _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(monostate, monostate) noexcept { |
| 33 | 33 | return strong_ordering::equal; |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | # else // _LIBCPP_STD_VER > 17 | |
| 36 | # else // _LIBCPP_STD_VER >= 20 | |
| 37 | 37 | |
| 38 | 38 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator!=(monostate, monostate) noexcept { return false; } |
| 39 | 39 | |
| ... | ... | @@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(monostate, monostate) noexcept { |
| 45 | 45 | |
| 46 | 46 | _LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(monostate, monostate) noexcept { return true; } |
| 47 | 47 | |
| 48 | # endif // _LIBCPP_STD_VER > 17 | |
| 48 | # endif // _LIBCPP_STD_VER >= 20 | |
| 49 | 49 | |
| 50 | 50 | template <> |
| 51 | 51 | struct _LIBCPP_TEMPLATE_VIS hash<monostate> { |
| ... | ... | @@ -57,7 +57,7 @@ struct _LIBCPP_TEMPLATE_VIS hash<monostate> { |
| 57 | 57 | } |
| 58 | 58 | }; |
| 59 | 59 | |
| 60 | #endif // _LIBCPP_STD_VER > 14 | |
| 60 | #endif // _LIBCPP_STD_VER >= 17 | |
| 61 | 61 | |
| 62 | 62 | _LIBCPP_END_NAMESPACE_STD |
| 63 | 63 |
lib/libcxx/include/__verbose_abort+8-5| ... | ... | @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 21 | 21 | |
| 22 | 22 | // This function should never be called directly from the code -- it should only be called through |
| 23 | 23 | // the _LIBCPP_VERBOSE_ABORT macro. |
| 24 | _LIBCPP_NORETURN _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) | |
| 24 | _LIBCPP_NORETURN _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) | |
| 25 | 25 | void __libcpp_verbose_abort(const char *__format, ...); |
| 26 | 26 | |
| 27 | 27 | // _LIBCPP_VERBOSE_ABORT(format, args...) |
| ... | ... | @@ -40,16 +40,19 @@ void __libcpp_verbose_abort(const char *__format, ...); |
| 40 | 40 | |
| 41 | 41 | // Support _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED until LLVM 18, but tell people |
| 42 | 42 | // to move to customizing _LIBCPP_VERBOSE_ABORT instead. |
| 43 | # if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED) | |
| 44 | # undef _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY | |
| 43 | # if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT) && defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED) | |
| 44 | # undef _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT | |
| 45 | 45 | # warning _LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED is deprecated, please customize _LIBCPP_VERBOSE_ABORT instead |
| 46 | 46 | # endif |
| 47 | 47 | |
| 48 | # if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) | |
| 49 | # define _LIBCPP_VERBOSE_ABORT(...) __builtin_abort() | |
| 48 | # if defined(_LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT) | |
| 49 | // The decltype is there to suppress -Wunused warnings in this configuration. | |
| 50 | void __use(const char*, ...); | |
| 51 | # define _LIBCPP_VERBOSE_ABORT(...) (decltype(::std::__use(__VA_ARGS__))(), __builtin_abort()) | |
| 50 | 52 | # else |
| 51 | 53 | # define _LIBCPP_VERBOSE_ABORT(...) ::std::__libcpp_verbose_abort(__VA_ARGS__) |
| 52 | 54 | # endif |
| 55 | ||
| 53 | 56 | #endif // !defined(_LIBCPP_VERBOSE_ABORT) |
| 54 | 57 | |
| 55 | 58 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/algorithm+162-121| ... | ... | @@ -22,41 +22,41 @@ namespace ranges { |
| 22 | 22 | |
| 23 | 23 | // [algorithms.results], algorithm result types |
| 24 | 24 | template <class I, class F> |
| 25 | struct in_fun_result; // since C++20 | |
| 25 | struct in_fun_result; // since C++20 | |
| 26 | 26 | |
| 27 | 27 | template <class I1, class I2> |
| 28 | struct in_in_result; // since C++20 | |
| 28 | struct in_in_result; // since C++20 | |
| 29 | 29 | |
| 30 | 30 | template <class I, class O> |
| 31 | struct in_out_result; // since C++20 | |
| 31 | struct in_out_result; // since C++20 | |
| 32 | 32 | |
| 33 | 33 | template <class I1, class I2, class O> |
| 34 | struct in_in_out_result; // since C++20 | |
| 34 | struct in_in_out_result; // since C++20 | |
| 35 | 35 | |
| 36 | 36 | template <class I, class O1, class O2> |
| 37 | struct in_out_out_result; // since C++20 | |
| 37 | struct in_out_out_result; // since C++20 | |
| 38 | 38 | |
| 39 | 39 | template <class I1, class I2> |
| 40 | struct min_max_result; // since C++20 | |
| 40 | struct min_max_result; // since C++20 | |
| 41 | 41 | |
| 42 | 42 | template <class I> |
| 43 | struct in_found_result; // since C++20 | |
| 43 | struct in_found_result; // since C++20 | |
| 44 | 44 | |
| 45 | 45 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 46 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20 | |
| 46 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> // since C++20 | |
| 47 | 47 | constexpr I min_element(I first, S last, Comp comp = {}, Proj proj = {}); |
| 48 | 48 | |
| 49 | 49 | template<forward_range R, class Proj = identity, |
| 50 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20 | |
| 50 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> // since C++20 | |
| 51 | 51 | constexpr borrowed_iterator_t<R> min_element(R&& r, Comp comp = {}, Proj proj = {}); |
| 52 | 52 | |
| 53 | 53 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 54 | 54 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> |
| 55 | constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 55 | constexpr I ranges::max_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 56 | 56 | |
| 57 | 57 | template<forward_range R, class Proj = identity, |
| 58 | 58 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 59 | constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 59 | constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 60 | 60 | |
| 61 | 61 | template<class I1, class I2> |
| 62 | 62 | using mismatch_result = in_in_result<I1, I2>; |
| ... | ... | @@ -64,86 +64,86 @@ namespace ranges { |
| 64 | 64 | template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2, |
| 65 | 65 | class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> |
| 66 | 66 | requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2> |
| 67 | constexpr mismatch_result<_I1, _I2> | |
| 68 | mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20 | |
| 67 | constexpr mismatch_result<_I1, _I2> // since C++20 | |
| 68 | mismatch()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) | |
| 69 | 69 | |
| 70 | 70 | template <input_range R1, input_range R2, |
| 71 | 71 | class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> |
| 72 | 72 | requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2> |
| 73 | 73 | constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>> |
| 74 | mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20 | |
| 74 | mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {}) // since C++20 | |
| 75 | 75 | |
| 76 | 76 | requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*> |
| 77 | constexpr I find(I first, S last, const T& value, Proj proj = {}); // since C++20 | |
| 77 | constexpr I find(I first, S last, const T& value, Proj proj = {}); // since C++20 | |
| 78 | 78 | |
| 79 | 79 | template<input_range R, class T, class Proj = identity> |
| 80 | 80 | requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*> |
| 81 | 81 | constexpr borrowed_iterator_t<R> |
| 82 | find(R&& r, const T& value, Proj proj = {}); // since C++20 | |
| 82 | find(R&& r, const T& value, Proj proj = {}); // since C++20 | |
| 83 | 83 | |
| 84 | 84 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 85 | 85 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 86 | constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 86 | constexpr I find_if(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 87 | 87 | |
| 88 | 88 | template<input_range R, class Proj = identity, |
| 89 | 89 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 90 | 90 | constexpr borrowed_iterator_t<R> |
| 91 | find_if(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 91 | find_if(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 92 | 92 | |
| 93 | 93 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 94 | 94 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 95 | constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 95 | constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 96 | 96 | |
| 97 | 97 | template<input_range R, class Proj = identity, |
| 98 | 98 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 99 | 99 | constexpr borrowed_iterator_t<R> |
| 100 | find_if_not(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 100 | find_if_not(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 101 | 101 | |
| 102 | 102 | template<class T, class Proj = identity, |
| 103 | 103 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 104 | constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 104 | constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 105 | 105 | |
| 106 | 106 | template<copyable T, class Proj = identity, |
| 107 | 107 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 108 | constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 108 | constexpr T min(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 109 | 109 | |
| 110 | 110 | template<input_range R, class Proj = identity, |
| 111 | 111 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 112 | 112 | requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> |
| 113 | 113 | constexpr range_value_t<R> |
| 114 | min(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 114 | min(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 115 | 115 | |
| 116 | 116 | template<class T, class Proj = identity, |
| 117 | 117 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 118 | constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 118 | constexpr const T& max(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 119 | 119 | |
| 120 | 120 | template<copyable T, class Proj = identity, |
| 121 | 121 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 122 | constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 122 | constexpr T max(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 123 | 123 | |
| 124 | 124 | template<input_range R, class Proj = identity, |
| 125 | 125 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 126 | 126 | requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> |
| 127 | 127 | constexpr range_value_t<R> |
| 128 | max(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 128 | max(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 129 | 129 | |
| 130 | 130 | template<class I, class O> |
| 131 | using unary_transform_result = in_out_result<I, O>; // since C++20 | |
| 131 | using unary_transform_result = in_out_result<I, O>; // since C++20 | |
| 132 | 132 | |
| 133 | 133 | template<class I1, class I2, class O> |
| 134 | using binary_transform_result = in_in_out_result<I1, I2, O>; // since C++20 | |
| 134 | using binary_transform_result = in_in_out_result<I1, I2, O>; // since C++20 | |
| 135 | 135 | |
| 136 | 136 | template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, |
| 137 | 137 | copy_constructible F, class Proj = identity> |
| 138 | 138 | requires indirectly_writable<O, indirect_result_t<F&, projected<I, Proj>>> |
| 139 | 139 | constexpr ranges::unary_transform_result<I, O> |
| 140 | transform(I first1, S last1, O result, F op, Proj proj = {}); // since C++20 | |
| 140 | transform(I first1, S last1, O result, F op, Proj proj = {}); // since C++20 | |
| 141 | 141 | |
| 142 | 142 | template<input_range R, weakly_incrementable O, copy_constructible F, |
| 143 | 143 | class Proj = identity> |
| 144 | 144 | requires indirectly_writable<O, indirect_result_t<F&, projected<iterator_t<R>, Proj>>> |
| 145 | 145 | constexpr ranges::unary_transform_result<borrowed_iterator_t<R>, O> |
| 146 | transform(R&& r, O result, F op, Proj proj = {}); // since C++20 | |
| 146 | transform(R&& r, O result, F op, Proj proj = {}); // since C++20 | |
| 147 | 147 | |
| 148 | 148 | template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2, |
| 149 | 149 | weakly_incrementable O, copy_constructible F, class Proj1 = identity, |
| ... | ... | @@ -152,7 +152,7 @@ namespace ranges { |
| 152 | 152 | projected<I2, Proj2>>> |
| 153 | 153 | constexpr ranges::binary_transform_result<I1, I2, O> |
| 154 | 154 | transform(I1 first1, S1 last1, I2 first2, S2 last2, O result, |
| 155 | F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 155 | F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 156 | 156 | |
| 157 | 157 | template<input_range R1, input_range R2, weakly_incrementable O, |
| 158 | 158 | copy_constructible F, class Proj1 = identity, class Proj2 = identity> |
| ... | ... | @@ -160,27 +160,27 @@ namespace ranges { |
| 160 | 160 | projected<iterator_t<R2>, Proj2>>> |
| 161 | 161 | constexpr ranges::binary_transform_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O> |
| 162 | 162 | transform(R1&& r1, R2&& r2, O result, |
| 163 | F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 163 | F binary_op, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 164 | 164 | |
| 165 | 165 | template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity> |
| 166 | 166 | requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*> |
| 167 | 167 | constexpr iter_difference_t<I> |
| 168 | count(I first, S last, const T& value, Proj proj = {}); // since C++20 | |
| 168 | count(I first, S last, const T& value, Proj proj = {}); // since C++20 | |
| 169 | 169 | |
| 170 | 170 | template<input_range R, class T, class Proj = identity> |
| 171 | 171 | requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*> |
| 172 | 172 | constexpr range_difference_t<R> |
| 173 | count(R&& r, const T& value, Proj proj = {}); // since C++20 | |
| 173 | count(R&& r, const T& value, Proj proj = {}); // since C++20 | |
| 174 | 174 | |
| 175 | 175 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 176 | 176 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 177 | 177 | constexpr iter_difference_t<I> |
| 178 | count_if(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 178 | count_if(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 179 | 179 | |
| 180 | 180 | template<input_range R, class Proj = identity, |
| 181 | 181 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 182 | 182 | constexpr range_difference_t<R> |
| 183 | count_if(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 183 | count_if(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 184 | 184 | |
| 185 | 185 | template<class T> |
| 186 | 186 | using minmax_result = min_max_result<T>; |
| ... | ... | @@ -188,18 +188,18 @@ namespace ranges { |
| 188 | 188 | template<class T, class Proj = identity, |
| 189 | 189 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 190 | 190 | constexpr ranges::minmax_result<const T&> |
| 191 | minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 191 | minmax(const T& a, const T& b, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 192 | 192 | |
| 193 | 193 | template<copyable T, class Proj = identity, |
| 194 | 194 | indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less> |
| 195 | 195 | constexpr ranges::minmax_result<T> |
| 196 | minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 196 | minmax(initializer_list<T> r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 197 | 197 | |
| 198 | 198 | template<input_range R, class Proj = identity, |
| 199 | 199 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 200 | 200 | requires indirectly_copyable_storable<iterator_t<R>, range_value_t<R>*> |
| 201 | 201 | constexpr ranges::minmax_result<range_value_t<R>> |
| 202 | minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 202 | minmax(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 203 | 203 | |
| 204 | 204 | template<class I> |
| 205 | 205 | using minmax_element_result = min_max_result<I>; |
| ... | ... | @@ -207,18 +207,18 @@ namespace ranges { |
| 207 | 207 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 208 | 208 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> |
| 209 | 209 | constexpr ranges::minmax_element_result<I> |
| 210 | minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 210 | minmax_element(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 211 | 211 | |
| 212 | 212 | template<forward_range R, class Proj = identity, |
| 213 | 213 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 214 | 214 | constexpr ranges::minmax_element_result<borrowed_iterator_t<R>> |
| 215 | minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 215 | minmax_element(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 216 | 216 | |
| 217 | 217 | template<class I, class O> |
| 218 | using copy_result = in_out_result<I, O>; // since C++20 | |
| 218 | using copy_result = in_out_result<I, O>; // since C++20 | |
| 219 | 219 | |
| 220 | 220 | template<class I, class O> |
| 221 | using copy_n_result = in_out_result<I, O>; // since C++20 | |
| 221 | using copy_n_result = in_out_result<I, O>; // since C++20 | |
| 222 | 222 | |
| 223 | 223 | template<class I, class O> |
| 224 | 224 | using copy_if_result = in_out_result<I, O>; // since C++20 |
| ... | ... | @@ -333,20 +333,20 @@ namespace ranges { |
| 333 | 333 | |
| 334 | 334 | template<random_access_iterator I, sentinel_for<I> S, class Proj = identity, |
| 335 | 335 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> |
| 336 | constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 336 | constexpr bool is_heap(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 337 | 337 | |
| 338 | 338 | template<random_access_range R, class Proj = identity, |
| 339 | 339 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 340 | constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 340 | constexpr bool is_heap(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 341 | 341 | |
| 342 | 342 | template<random_access_iterator I, sentinel_for<I> S, class Proj = identity, |
| 343 | 343 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> |
| 344 | constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 344 | constexpr I is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 345 | 345 | |
| 346 | 346 | template<random_access_range R, class Proj = identity, |
| 347 | 347 | indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> |
| 348 | 348 | constexpr borrowed_iterator_t<R> |
| 349 | is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 349 | is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 350 | 350 | |
| 351 | 351 | template<bidirectional_iterator I, sentinel_for<I> S> |
| 352 | 352 | requires permutable<I> |
| ... | ... | @@ -399,15 +399,24 @@ namespace ranges { |
| 399 | 399 | |
| 400 | 400 | template<input_or_output_iterator O, sentinel_for<O> S, copy_constructible F> |
| 401 | 401 | requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>> |
| 402 | constexpr O generate(O first, S last, F gen); // Since C++20 | |
| 402 | constexpr O generate(O first, S last, F gen); // since C++20 | |
| 403 | ||
| 404 | template<class ExecutionPolicy, class ForwardIterator, class Generator> | |
| 405 | void generate(ExecutionPolicy&& exec, | |
| 406 | ForwardIterator first, ForwardIterator last, | |
| 407 | Generator gen); // since C++17 | |
| 403 | 408 | |
| 404 | 409 | template<class R, copy_constructible F> |
| 405 | 410 | requires invocable<F&> && output_range<R, invoke_result_t<F&>> |
| 406 | constexpr borrowed_iterator_t<R> generate(R&& r, F gen); // Since C++20 | |
| 411 | constexpr borrowed_iterator_t<R> generate(R&& r, F gen); // since C++20 | |
| 407 | 412 | |
| 408 | 413 | template<input_or_output_iterator O, copy_constructible F> |
| 409 | 414 | requires invocable<F&> && indirectly_writable<O, invoke_result_t<F&>> |
| 410 | constexpr O generate_n(O first, iter_difference_t<O> n, F gen); // Since C++20 | |
| 415 | constexpr O generate_n(O first, iter_difference_t<O> n, F gen); // since C++20 | |
| 416 | ||
| 417 | template<class ExecutionPolicy, class ForwardIterator, class Size, class Generator> | |
| 418 | ForwardIterator generate_n(ExecutionPolicy&& exec, | |
| 419 | ForwardIterator first, Size n, Generator gen); // since C++17 | |
| 411 | 420 | |
| 412 | 421 | template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2, |
| 413 | 422 | class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> |
| ... | ... | @@ -424,27 +433,39 @@ namespace ranges { |
| 424 | 433 | |
| 425 | 434 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 426 | 435 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 427 | constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 436 | constexpr bool ranges::all_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 428 | 437 | |
| 429 | 438 | template<input_range R, class Proj = identity, |
| 430 | 439 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 431 | constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 440 | constexpr bool ranges::all_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 432 | 441 | |
| 433 | 442 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 434 | 443 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 435 | constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 444 | constexpr bool ranges::any_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 436 | 445 | |
| 437 | 446 | template<input_range R, class Proj = identity, |
| 438 | 447 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 439 | constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 448 | constexpr bool ranges::any_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 440 | 449 | |
| 441 | 450 | template<input_iterator I, sentinel_for<I> S, class Proj = identity, |
| 442 | 451 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 443 | constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 452 | constexpr bool ranges::none_of(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 444 | 453 | |
| 445 | 454 | template<input_range R, class Proj = identity, |
| 446 | 455 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 447 | constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 456 | constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 457 | ||
| 458 | template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2, | |
| 459 | class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> | |
| 460 | requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2> | |
| 461 | constexpr bool ranges::starts_with(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {}, | |
| 462 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23 | |
| 463 | ||
| 464 | template<input_range R1, input_range R2, class Pred = ranges::equal_to, class Proj1 = identity, | |
| 465 | class Proj2 = identity> | |
| 466 | requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2> | |
| 467 | constexpr bool ranges::starts_with(R1&& r1, R2&& r2, Pred pred = {}, | |
| 468 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++23 | |
| 448 | 469 | |
| 449 | 470 | template<input_iterator I1, sentinel_for<I1> S1, |
| 450 | 471 | random_access_iterator I2, sentinel_for<I2> S2, |
| ... | ... | @@ -453,7 +474,7 @@ namespace ranges { |
| 453 | 474 | indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>> |
| 454 | 475 | constexpr partial_sort_copy_result<I1, I2> |
| 455 | 476 | partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last, |
| 456 | Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 477 | Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 457 | 478 | |
| 458 | 479 | template<input_range R1, random_access_range R2, class Comp = ranges::less, |
| 459 | 480 | class Proj1 = identity, class Proj2 = identity> |
| ... | ... | @@ -463,7 +484,7 @@ namespace ranges { |
| 463 | 484 | projected<iterator_t<R2>, Proj2>> |
| 464 | 485 | constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>> |
| 465 | 486 | partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {}, |
| 466 | Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 487 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 467 | 488 | |
| 468 | 489 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 469 | 490 | indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> |
| ... | ... | @@ -486,64 +507,64 @@ namespace ranges { |
| 486 | 507 | class Proj = identity> |
| 487 | 508 | requires sortable<I, Comp, Proj> |
| 488 | 509 | constexpr I |
| 489 | ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 510 | ranges::nth_element(I first, I nth, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 490 | 511 | |
| 491 | 512 | template<random_access_range R, class Comp = ranges::less, class Proj = identity> |
| 492 | 513 | requires sortable<iterator_t<R>, Comp, Proj> |
| 493 | 514 | constexpr borrowed_iterator_t<R> |
| 494 | ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 515 | ranges::nth_element(R&& r, iterator_t<R> nth, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 495 | 516 | |
| 496 | 517 | template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity, |
| 497 | indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less> | |
| 498 | constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 518 | indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less> // since C++20 | |
| 519 | constexpr I upper_bound(I first, S last, const T& value, Comp comp = {}, Proj proj = {}); | |
| 499 | 520 | |
| 500 | 521 | template<forward_range R, class T, class Proj = identity, |
| 501 | 522 | indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp = |
| 502 | 523 | ranges::less> |
| 503 | 524 | constexpr borrowed_iterator_t<R> |
| 504 | upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 525 | upper_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 505 | 526 | |
| 506 | 527 | template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity, |
| 507 | 528 | indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less> |
| 508 | 529 | constexpr I lower_bound(I first, S last, const T& value, Comp comp = {}, |
| 509 | Proj proj = {}); // since C++20 | |
| 530 | Proj proj = {}); // since C++20 | |
| 510 | 531 | template<forward_range R, class T, class Proj = identity, |
| 511 | 532 | indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp = |
| 512 | 533 | ranges::less> |
| 513 | 534 | constexpr borrowed_iterator_t<R> |
| 514 | lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 535 | lower_bound(R&& r, const T& value, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 515 | 536 | |
| 516 | 537 | template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity, |
| 517 | 538 | indirect_strict_weak_order<const T*, projected<I, Proj>> Comp = ranges::less> |
| 518 | 539 | constexpr bool binary_search(I first, S last, const T& value, Comp comp = {}, |
| 519 | Proj proj = {}); // since C++20 | |
| 540 | Proj proj = {}); // since C++20 | |
| 520 | 541 | |
| 521 | 542 | template<forward_range R, class T, class Proj = identity, |
| 522 | 543 | indirect_strict_weak_order<const T*, projected<iterator_t<R>, Proj>> Comp = |
| 523 | 544 | ranges::less> |
| 524 | 545 | constexpr bool binary_search(R&& r, const T& value, Comp comp = {}, |
| 525 | Proj proj = {}); // since C++20 | |
| 546 | Proj proj = {}); // since C++20 | |
| 526 | 547 | |
| 527 | 548 | template<permutable I, sentinel_for<I> S, class Proj = identity, |
| 528 | 549 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 529 | 550 | constexpr subrange<I> |
| 530 | partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20 | |
| 551 | partition(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 531 | 552 | |
| 532 | 553 | template<forward_range R, class Proj = identity, |
| 533 | 554 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 534 | 555 | requires permutable<iterator_t<R>> |
| 535 | 556 | constexpr borrowed_subrange_t<R> |
| 536 | partition(R&& r, Pred pred, Proj proj = {}); // Since C++20 | |
| 557 | partition(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 537 | 558 | |
| 538 | 559 | template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity, |
| 539 | 560 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 540 | 561 | requires permutable<I> |
| 541 | subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {}); // Since C++20 | |
| 562 | subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 542 | 563 | |
| 543 | 564 | template<bidirectional_range R, class Proj = identity, |
| 544 | 565 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 545 | 566 | requires permutable<iterator_t<R>> |
| 546 | borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {}); // Since C++20 | |
| 567 | borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 547 | 568 | |
| 548 | 569 | template<input_iterator I1, sentinel_for<I1> S1, forward_iterator I2, sentinel_for<I2> S2, |
| 549 | 570 | class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity> |
| ... | ... | @@ -563,7 +584,7 @@ namespace ranges { |
| 563 | 584 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 564 | 585 | indirect_binary_predicate<projected<I, Proj>, |
| 565 | 586 | projected<I, Proj>> Pred = ranges::equal_to> |
| 566 | constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C+20 | |
| 587 | constexpr I ranges::adjacent_find(I first, S last, Pred pred = {}, Proj proj = {}); // since C++20 | |
| 567 | 588 | |
| 568 | 589 | template<forward_range R, class Proj = identity, |
| 569 | 590 | indirect_binary_predicate<projected<iterator_t<R>, Proj>, |
| ... | ... | @@ -604,7 +625,7 @@ namespace ranges { |
| 604 | 625 | projected<I2, Proj2>> Comp = ranges::less> |
| 605 | 626 | constexpr bool |
| 606 | 627 | ranges::lexicographical_compare(I1 first1, S1 last1, I2 first2, S2 last2, |
| 607 | Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 628 | Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 608 | 629 | |
| 609 | 630 | template<input_range R1, input_range R2, class Proj1 = identity, |
| 610 | 631 | class Proj2 = identity, |
| ... | ... | @@ -612,7 +633,7 @@ namespace ranges { |
| 612 | 633 | projected<iterator_t<R2>, Proj2>> Comp = ranges::less> |
| 613 | 634 | constexpr bool |
| 614 | 635 | ranges::lexicographical_compare(R1&& r1, R2&& r2, Comp comp = {}, |
| 615 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 636 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 616 | 637 | |
| 617 | 638 | template<bidirectional_iterator I1, sentinel_for<I1> S1, bidirectional_iterator I2> |
| 618 | 639 | requires indirectly_movable<I1, I2> |
| ... | ... | @@ -643,7 +664,7 @@ namespace ranges { |
| 643 | 664 | requires indirectly_copyable<I, O1> && indirectly_copyable<I, O2> |
| 644 | 665 | constexpr partition_copy_result<I, O1, O2> |
| 645 | 666 | partition_copy(I first, S last, O1 out_true, O2 out_false, Pred pred, |
| 646 | Proj proj = {}); // Since C++20 | |
| 667 | Proj proj = {}); // since C++20 | |
| 647 | 668 | |
| 648 | 669 | template<input_range R, weakly_incrementable O1, weakly_incrementable O2, |
| 649 | 670 | class Proj = identity, |
| ... | ... | @@ -651,16 +672,16 @@ namespace ranges { |
| 651 | 672 | requires indirectly_copyable<iterator_t<R>, O1> && |
| 652 | 673 | indirectly_copyable<iterator_t<R>, O2> |
| 653 | 674 | constexpr partition_copy_result<borrowed_iterator_t<R>, O1, O2> |
| 654 | partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); // Since C++20 | |
| 675 | partition_copy(R&& r, O1 out_true, O2 out_false, Pred pred, Proj proj = {}); // since C++20 | |
| 655 | 676 | |
| 656 | 677 | template<forward_iterator I, sentinel_for<I> S, class Proj = identity, |
| 657 | 678 | indirect_unary_predicate<projected<I, Proj>> Pred> |
| 658 | constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); // Since C++20 | |
| 679 | constexpr I partition_point(I first, S last, Pred pred, Proj proj = {}); // since C++20 | |
| 659 | 680 | |
| 660 | 681 | template<forward_range R, class Proj = identity, |
| 661 | 682 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 662 | 683 | constexpr borrowed_iterator_t<R> |
| 663 | partition_point(R&& r, Pred pred, Proj proj = {}); // Since C++20 | |
| 684 | partition_point(R&& r, Pred pred, Proj proj = {}); // since C++20 | |
| 664 | 685 | |
| 665 | 686 | template<class I1, class I2, class O> |
| 666 | 687 | using merge_result = in_in_out_result<I1, I2, O>; // since C++20 |
| ... | ... | @@ -755,7 +776,7 @@ namespace ranges { |
| 755 | 776 | |
| 756 | 777 | template<forward_range R> |
| 757 | 778 | requires permutable<iterator_t<R>> |
| 758 | constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle); // Since C++20 | |
| 779 | constexpr borrowed_subrange_t<R> rotate(R&& r, iterator_t<R> middle); // since C++20 | |
| 759 | 780 | |
| 760 | 781 | template <class _InIter, class _OutIter> |
| 761 | 782 | using rotate_copy_result = in_out_result<_InIter, _OutIter>; // since C++20 |
| ... | ... | @@ -774,23 +795,23 @@ namespace ranges { |
| 774 | 795 | requires (forward_iterator<I> || random_access_iterator<O>) && |
| 775 | 796 | indirectly_copyable<I, O> && |
| 776 | 797 | uniform_random_bit_generator<remove_reference_t<Gen>> |
| 777 | O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g); // Since C++20 | |
| 798 | O sample(I first, S last, O out, iter_difference_t<I> n, Gen&& g); // since C++20 | |
| 778 | 799 | |
| 779 | 800 | template<input_range R, weakly_incrementable O, class Gen> |
| 780 | 801 | requires (forward_range<R> || random_access_iterator<O>) && |
| 781 | 802 | indirectly_copyable<iterator_t<R>, O> && |
| 782 | 803 | uniform_random_bit_generator<remove_reference_t<Gen>> |
| 783 | O sample(R&& r, O out, range_difference_t<R> n, Gen&& g); // Since C++20 | |
| 804 | O sample(R&& r, O out, range_difference_t<R> n, Gen&& g); // since C++20 | |
| 784 | 805 | |
| 785 | 806 | template<random_access_iterator I, sentinel_for<I> S, class Gen> |
| 786 | 807 | requires permutable<I> && |
| 787 | 808 | uniform_random_bit_generator<remove_reference_t<Gen>> |
| 788 | I shuffle(I first, S last, Gen&& g); // Since C++20 | |
| 809 | I shuffle(I first, S last, Gen&& g); // since C++20 | |
| 789 | 810 | |
| 790 | 811 | template<random_access_range R, class Gen> |
| 791 | 812 | requires permutable<iterator_t<R>> && |
| 792 | 813 | uniform_random_bit_generator<remove_reference_t<Gen>> |
| 793 | borrowed_iterator_t<R> shuffle(R&& r, Gen&& g); // Since C++20 | |
| 814 | borrowed_iterator_t<R> shuffle(R&& r, Gen&& g); // since C++20 | |
| 794 | 815 | |
| 795 | 816 | template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2, |
| 796 | 817 | sentinel_for<I2> S2, class Proj1 = identity, class Proj2 = identity, |
| ... | ... | @@ -798,14 +819,14 @@ namespace ranges { |
| 798 | 819 | projected<I2, Proj2>> Pred = ranges::equal_to> |
| 799 | 820 | constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2, |
| 800 | 821 | Pred pred = {}, |
| 801 | Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 822 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 802 | 823 | |
| 803 | 824 | template<forward_range R1, forward_range R2, |
| 804 | 825 | class Proj1 = identity, class Proj2 = identity, |
| 805 | 826 | indirect_equivalence_relation<projected<iterator_t<R1>, Proj1>, |
| 806 | 827 | projected<iterator_t<R2>, Proj2>> Pred = ranges::equal_to> |
| 807 | 828 | constexpr bool ranges::is_permutation(R1&& r1, R2&& r2, Pred pred = {}, |
| 808 | Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 829 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 809 | 830 | |
| 810 | 831 | template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2, |
| 811 | 832 | sentinel_for<I2> S2, class Pred = ranges::equal_to, |
| ... | ... | @@ -904,35 +925,35 @@ namespace ranges { |
| 904 | 925 | indirect_strict_weak_order<projected<I1, Proj1>, projected<I2, Proj2>> Comp = |
| 905 | 926 | ranges::less> |
| 906 | 927 | constexpr bool includes(I1 first1, S1 last1, I2 first2, S2 last2, Comp comp = {}, |
| 907 | Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 928 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 908 | 929 | |
| 909 | 930 | template<input_range R1, input_range R2, class Proj1 = identity, |
| 910 | 931 | class Proj2 = identity, |
| 911 | 932 | indirect_strict_weak_order<projected<iterator_t<R1>, Proj1>, |
| 912 | 933 | projected<iterator_t<R2>, Proj2>> Comp = ranges::less> |
| 913 | 934 | constexpr bool includes(R1&& r1, R2&& r2, Comp comp = {}, |
| 914 | Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20 | |
| 935 | Proj1 proj1 = {}, Proj2 proj2 = {}); // since C++20 | |
| 915 | 936 | |
| 916 | 937 | template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less, |
| 917 | 938 | class Proj = identity> |
| 918 | 939 | requires sortable<I, Comp, Proj> |
| 919 | I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 940 | I inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 920 | 941 | |
| 921 | 942 | template<bidirectional_range R, class Comp = ranges::less, class Proj = identity> |
| 922 | 943 | requires sortable<iterator_t<R>, Comp, Proj> |
| 923 | 944 | borrowed_iterator_t<R> |
| 924 | 945 | inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {}, |
| 925 | Proj proj = {}); // Since C++20 | |
| 946 | Proj proj = {}); // since C++20 | |
| 926 | 947 | |
| 927 | 948 | template<permutable I, sentinel_for<I> S, class Proj = identity, |
| 928 | 949 | indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to> |
| 929 | constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {}); // Since C++20 | |
| 950 | constexpr subrange<I> unique(I first, S last, C comp = {}, Proj proj = {}); // since C++20 | |
| 930 | 951 | |
| 931 | 952 | template<forward_range R, class Proj = identity, |
| 932 | 953 | indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to> |
| 933 | 954 | requires permutable<iterator_t<R>> |
| 934 | 955 | constexpr borrowed_subrange_t<R> |
| 935 | unique(R&& r, C comp = {}, Proj proj = {}); // Since C++20 | |
| 956 | unique(R&& r, C comp = {}, Proj proj = {}); // since C++20 | |
| 936 | 957 | |
| 937 | 958 | template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class Proj = identity, |
| 938 | 959 | indirect_equivalence_relation<projected<I, Proj>> C = ranges::equal_to> |
| ... | ... | @@ -941,7 +962,7 @@ namespace ranges { |
| 941 | 962 | (input_iterator<O> && same_as<iter_value_t<I>, iter_value_t<O>>) || |
| 942 | 963 | indirectly_copyable_storable<I, O>) |
| 943 | 964 | constexpr unique_copy_result<I, O> |
| 944 | unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); // Since C++20 | |
| 965 | unique_copy(I first, S last, O result, C comp = {}, Proj proj = {}); // since C++20 | |
| 945 | 966 | |
| 946 | 967 | template<input_range R, weakly_incrementable O, class Proj = identity, |
| 947 | 968 | indirect_equivalence_relation<projected<iterator_t<R>, Proj>> C = ranges::equal_to> |
| ... | ... | @@ -950,41 +971,41 @@ namespace ranges { |
| 950 | 971 | (input_iterator<O> && same_as<range_value_t<R>, iter_value_t<O>>) || |
| 951 | 972 | indirectly_copyable_storable<iterator_t<R>, O>) |
| 952 | 973 | constexpr unique_copy_result<borrowed_iterator_t<R>, O> |
| 953 | unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); // Since C++20 | |
| 974 | unique_copy(R&& r, O result, C comp = {}, Proj proj = {}); // since C++20 | |
| 954 | 975 | |
| 955 | 976 | template<class I, class O> |
| 956 | using remove_copy_result = in_out_result<I, O>; // Since C++20 | |
| 977 | using remove_copy_result = in_out_result<I, O>; // since C++20 | |
| 957 | 978 | |
| 958 | 979 | template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, class T, |
| 959 | 980 | class Proj = identity> |
| 960 | 981 | indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*> |
| 961 | 982 | constexpr remove_copy_result<I, O> |
| 962 | remove_copy(I first, S last, O result, const T& value, Proj proj = {}); // Since C++20 | |
| 983 | remove_copy(I first, S last, O result, const T& value, Proj proj = {}); // since C++20 | |
| 963 | 984 | |
| 964 | 985 | template<input_range R, weakly_incrementable O, class T, class Proj = identity> |
| 965 | 986 | requires indirectly_copyable<iterator_t<R>, O> && |
| 966 | 987 | indirect_binary_predicate<ranges::equal_to, |
| 967 | 988 | projected<iterator_t<R>, Proj>, const T*> |
| 968 | 989 | constexpr remove_copy_result<borrowed_iterator_t<R>, O> |
| 969 | remove_copy(R&& r, O result, const T& value, Proj proj = {}); // Since C++20 | |
| 990 | remove_copy(R&& r, O result, const T& value, Proj proj = {}); // since C++20 | |
| 970 | 991 | |
| 971 | 992 | template<class I, class O> |
| 972 | using remove_copy_if_result = in_out_result<I, O>; // Since C++20 | |
| 993 | using remove_copy_if_result = in_out_result<I, O>; // since C++20 | |
| 973 | 994 | |
| 974 | 995 | template<input_iterator I, sentinel_for<I> S, weakly_incrementable O, |
| 975 | 996 | class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred> |
| 976 | 997 | requires indirectly_copyable<I, O> |
| 977 | 998 | constexpr remove_copy_if_result<I, O> |
| 978 | remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // Since C++20 | |
| 999 | remove_copy_if(I first, S last, O result, Pred pred, Proj proj = {}); // since C++20 | |
| 979 | 1000 | |
| 980 | 1001 | template<input_range R, weakly_incrementable O, class Proj = identity, |
| 981 | 1002 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 982 | 1003 | requires indirectly_copyable<iterator_t<R>, O> |
| 983 | 1004 | constexpr remove_copy_if_result<borrowed_iterator_t<R>, O> |
| 984 | remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); // Since C++20 | |
| 1005 | remove_copy_if(R&& r, O result, Pred pred, Proj proj = {}); // since C++20 | |
| 985 | 1006 | |
| 986 | 1007 | template<class I, class O> |
| 987 | using replace_copy_result = in_out_result<I, O>; // Since C++20 | |
| 1008 | using replace_copy_result = in_out_result<I, O>; // since C++20 | |
| 988 | 1009 | |
| 989 | 1010 | template<input_iterator I, sentinel_for<I> S, class T1, class T2, |
| 990 | 1011 | output_iterator<const T2&> O, class Proj = identity> |
| ... | ... | @@ -992,7 +1013,7 @@ namespace ranges { |
| 992 | 1013 | indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*> |
| 993 | 1014 | constexpr replace_copy_result<I, O> |
| 994 | 1015 | replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value, |
| 995 | Proj proj = {}); // Since C++20 | |
| 1016 | Proj proj = {}); // since C++20 | |
| 996 | 1017 | |
| 997 | 1018 | template<input_range R, class T1, class T2, output_iterator<const T2&> O, |
| 998 | 1019 | class Proj = identity> |
| ... | ... | @@ -1001,54 +1022,54 @@ namespace ranges { |
| 1001 | 1022 | projected<iterator_t<R>, Proj>, const T1*> |
| 1002 | 1023 | constexpr replace_copy_result<borrowed_iterator_t<R>, O> |
| 1003 | 1024 | replace_copy(R&& r, O result, const T1& old_value, const T2& new_value, |
| 1004 | Proj proj = {}); // Since C++20 | |
| 1025 | Proj proj = {}); // since C++20 | |
| 1005 | 1026 | |
| 1006 | 1027 | template<class I, class O> |
| 1007 | using replace_copy_if_result = in_out_result<I, O>; // Since C++20 | |
| 1028 | using replace_copy_if_result = in_out_result<I, O>; // since C++20 | |
| 1008 | 1029 | |
| 1009 | 1030 | template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O, |
| 1010 | 1031 | class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred> |
| 1011 | 1032 | requires indirectly_copyable<I, O> |
| 1012 | 1033 | constexpr replace_copy_if_result<I, O> |
| 1013 | 1034 | replace_copy_if(I first, S last, O result, Pred pred, const T& new_value, |
| 1014 | Proj proj = {}); // Since C++20 | |
| 1035 | Proj proj = {}); // since C++20 | |
| 1015 | 1036 | |
| 1016 | 1037 | template<input_range R, class T, output_iterator<const T&> O, class Proj = identity, |
| 1017 | 1038 | indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred> |
| 1018 | 1039 | requires indirectly_copyable<iterator_t<R>, O> |
| 1019 | 1040 | constexpr replace_copy_if_result<borrowed_iterator_t<R>, O> |
| 1020 | 1041 | replace_copy_if(R&& r, O result, Pred pred, const T& new_value, |
| 1021 | Proj proj = {}); // Since C++20 | |
| 1042 | Proj proj = {}); // since C++20 | |
| 1022 | 1043 | |
| 1023 | 1044 | template<class I> |
| 1024 | using prev_permutation_result = in_found_result<I>; // Since C++20 | |
| 1045 | using prev_permutation_result = in_found_result<I>; // since C++20 | |
| 1025 | 1046 | |
| 1026 | 1047 | template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less, |
| 1027 | 1048 | class Proj = identity> |
| 1028 | 1049 | requires sortable<I, Comp, Proj> |
| 1029 | 1050 | constexpr ranges::prev_permutation_result<I> |
| 1030 | ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 1051 | ranges::prev_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 1031 | 1052 | |
| 1032 | 1053 | template<bidirectional_range R, class Comp = ranges::less, |
| 1033 | 1054 | class Proj = identity> |
| 1034 | 1055 | requires sortable<iterator_t<R>, Comp, Proj> |
| 1035 | 1056 | constexpr ranges::prev_permutation_result<borrowed_iterator_t<R>> |
| 1036 | ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 1057 | ranges::prev_permutation(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 1037 | 1058 | |
| 1038 | 1059 | template<class I> |
| 1039 | using next_permutation_result = in_found_result<I>; // Since C++20 | |
| 1060 | using next_permutation_result = in_found_result<I>; // since C++20 | |
| 1040 | 1061 | |
| 1041 | 1062 | template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less, |
| 1042 | 1063 | class Proj = identity> |
| 1043 | 1064 | requires sortable<I, Comp, Proj> |
| 1044 | 1065 | constexpr ranges::next_permutation_result<I> |
| 1045 | ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 1066 | ranges::next_permutation(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 1046 | 1067 | |
| 1047 | 1068 | template<bidirectional_range R, class Comp = ranges::less, |
| 1048 | 1069 | class Proj = identity> |
| 1049 | 1070 | requires sortable<iterator_t<R>, Comp, Proj> |
| 1050 | 1071 | constexpr ranges::next_permutation_result<borrowed_iterator_t<R>> |
| 1051 | ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); // Since C++20 | |
| 1072 | ranges::next_permutation(R&& r, Comp comp = {}, Proj proj = {}); // since C++20 | |
| 1052 | 1073 | |
| 1053 | 1074 | } |
| 1054 | 1075 | |
| ... | ... | @@ -1684,6 +1705,18 @@ template <class InputIterator1, class InputIterator2, class Compare> |
| 1684 | 1705 | lexicographical_compare(InputIterator1 first1, InputIterator1 last1, |
| 1685 | 1706 | InputIterator2 first2, InputIterator2 last2, Compare comp); |
| 1686 | 1707 | |
| 1708 | template<class InputIterator1, class InputIterator2, class Cmp> | |
| 1709 | constexpr auto | |
| 1710 | lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1, | |
| 1711 | InputIterator2 first2, InputIterator2 last2, | |
| 1712 | Cmp comp) | |
| 1713 | -> decltype(comp(*b1, *b2)); // since C++20 | |
| 1714 | ||
| 1715 | template<class InputIterator1, class InputIterator2> | |
| 1716 | constexpr auto | |
| 1717 | lexicographical_compare_three_way(InputIterator1 first1, InputIterator1 last1, | |
| 1718 | InputIterator2 first2, InputIterator2 last2); // since C++20 | |
| 1719 | ||
| 1687 | 1720 | template <class BidirectionalIterator> |
| 1688 | 1721 | constexpr bool // constexpr in C++20 |
| 1689 | 1722 | next_permutation(BidirectionalIterator first, BidirectionalIterator last); |
| ... | ... | @@ -1705,9 +1738,7 @@ template <class BidirectionalIterator, class Compare> |
| 1705 | 1738 | |
| 1706 | 1739 | #include <__assert> // all public C++ headers provide the assertion handler |
| 1707 | 1740 | #include <__config> |
| 1708 | #include <__debug> | |
| 1709 | 1741 | #include <cstddef> |
| 1710 | #include <type_traits> | |
| 1711 | 1742 | #include <version> |
| 1712 | 1743 | |
| 1713 | 1744 | #include <__algorithm/adjacent_find.h> |
| ... | ... | @@ -1753,6 +1784,7 @@ template <class BidirectionalIterator, class Compare> |
| 1753 | 1784 | #include <__algorithm/is_sorted_until.h> |
| 1754 | 1785 | #include <__algorithm/iter_swap.h> |
| 1755 | 1786 | #include <__algorithm/lexicographical_compare.h> |
| 1787 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 1756 | 1788 | #include <__algorithm/lower_bound.h> |
| 1757 | 1789 | #include <__algorithm/make_heap.h> |
| 1758 | 1790 | #include <__algorithm/max.h> |
| ... | ... | @@ -1776,6 +1808,19 @@ template <class BidirectionalIterator, class Compare> |
| 1776 | 1808 | #include <__algorithm/partition_point.h> |
| 1777 | 1809 | #include <__algorithm/pop_heap.h> |
| 1778 | 1810 | #include <__algorithm/prev_permutation.h> |
| 1811 | #include <__algorithm/pstl_any_all_none_of.h> | |
| 1812 | #include <__algorithm/pstl_copy.h> | |
| 1813 | #include <__algorithm/pstl_count.h> | |
| 1814 | #include <__algorithm/pstl_fill.h> | |
| 1815 | #include <__algorithm/pstl_find.h> | |
| 1816 | #include <__algorithm/pstl_for_each.h> | |
| 1817 | #include <__algorithm/pstl_generate.h> | |
| 1818 | #include <__algorithm/pstl_is_partitioned.h> | |
| 1819 | #include <__algorithm/pstl_merge.h> | |
| 1820 | #include <__algorithm/pstl_replace.h> | |
| 1821 | #include <__algorithm/pstl_sort.h> | |
| 1822 | #include <__algorithm/pstl_stable_sort.h> | |
| 1823 | #include <__algorithm/pstl_transform.h> | |
| 1779 | 1824 | #include <__algorithm/push_heap.h> |
| 1780 | 1825 | #include <__algorithm/ranges_adjacent_find.h> |
| 1781 | 1826 | #include <__algorithm/ranges_all_of.h> |
| ... | ... | @@ -1857,6 +1902,7 @@ template <class BidirectionalIterator, class Compare> |
| 1857 | 1902 | #include <__algorithm/ranges_sort_heap.h> |
| 1858 | 1903 | #include <__algorithm/ranges_stable_partition.h> |
| 1859 | 1904 | #include <__algorithm/ranges_stable_sort.h> |
| 1905 | #include <__algorithm/ranges_starts_with.h> | |
| 1860 | 1906 | #include <__algorithm/ranges_swap_ranges.h> |
| 1861 | 1907 | #include <__algorithm/ranges_transform.h> |
| 1862 | 1908 | #include <__algorithm/ranges_unique.h> |
| ... | ... | @@ -1905,21 +1951,16 @@ template <class BidirectionalIterator, class Compare> |
| 1905 | 1951 | # pragma GCC system_header |
| 1906 | 1952 | #endif |
| 1907 | 1953 | |
| 1908 | #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 | |
| 1909 | # include <__pstl_algorithm> | |
| 1910 | #endif | |
| 1911 | ||
| 1912 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 | |
| 1913 | # include <chrono> | |
| 1914 | #endif | |
| 1915 | ||
| 1916 | 1954 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1917 | 1955 | # include <atomic> |
| 1956 | # include <bit> | |
| 1918 | 1957 | # include <concepts> |
| 1958 | # include <cstdlib> | |
| 1919 | 1959 | # include <cstring> |
| 1920 | 1960 | # include <iterator> |
| 1921 | 1961 | # include <memory> |
| 1922 | 1962 | # include <stdexcept> |
| 1963 | # include <type_traits> | |
| 1923 | 1964 | # include <utility> |
| 1924 | 1965 | #endif |
| 1925 | 1966 |
lib/libcxx/include/any+30-8| ... | ... | @@ -87,13 +87,27 @@ namespace std { |
| 87 | 87 | #include <__memory/allocator_destructor.h> |
| 88 | 88 | #include <__memory/allocator_traits.h> |
| 89 | 89 | #include <__memory/unique_ptr.h> |
| 90 | #include <__type_traits/add_const.h> | |
| 91 | #include <__type_traits/add_pointer.h> | |
| 92 | #include <__type_traits/aligned_storage.h> | |
| 93 | #include <__type_traits/alignment_of.h> | |
| 94 | #include <__type_traits/conditional.h> | |
| 95 | #include <__type_traits/decay.h> | |
| 96 | #include <__type_traits/is_constructible.h> | |
| 97 | #include <__type_traits/is_copy_constructible.h> | |
| 98 | #include <__type_traits/is_function.h> | |
| 99 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 100 | #include <__type_traits/is_reference.h> | |
| 101 | #include <__type_traits/is_same.h> | |
| 102 | #include <__type_traits/remove_cv.h> | |
| 103 | #include <__type_traits/remove_cvref.h> | |
| 104 | #include <__type_traits/remove_reference.h> | |
| 90 | 105 | #include <__utility/forward.h> |
| 91 | 106 | #include <__utility/in_place.h> |
| 92 | 107 | #include <__utility/move.h> |
| 93 | 108 | #include <__utility/unreachable.h> |
| 94 | #include <cstdlib> | |
| 109 | #include <__verbose_abort> | |
| 95 | 110 | #include <initializer_list> |
| 96 | #include <type_traits> | |
| 97 | 111 | #include <typeinfo> |
| 98 | 112 | #include <version> |
| 99 | 113 | |
| ... | ... | @@ -101,8 +115,11 @@ namespace std { |
| 101 | 115 | # pragma GCC system_header |
| 102 | 116 | #endif |
| 103 | 117 | |
| 118 | _LIBCPP_PUSH_MACROS | |
| 119 | #include <__undef_macros> | |
| 120 | ||
| 104 | 121 | namespace std { |
| 105 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast | |
| 122 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast | |
| 106 | 123 | { |
| 107 | 124 | public: |
| 108 | 125 | const char* what() const _NOEXCEPT override; |
| ... | ... | @@ -111,16 +128,16 @@ public: |
| 111 | 128 | |
| 112 | 129 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 113 | 130 | |
| 114 | #if _LIBCPP_STD_VER > 14 | |
| 131 | #if _LIBCPP_STD_VER >= 17 | |
| 115 | 132 | |
| 116 | 133 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 117 | 134 | _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST |
| 118 | 135 | void __throw_bad_any_cast() |
| 119 | 136 | { |
| 120 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 137 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 121 | 138 | throw bad_any_cast(); |
| 122 | 139 | #else |
| 123 | _VSTD::abort(); | |
| 140 | _LIBCPP_VERBOSE_ABORT("bad_any_cast was thrown in -fno-exceptions mode"); | |
| 124 | 141 | #endif |
| 125 | 142 | } |
| 126 | 143 | |
| ... | ... | @@ -311,7 +328,7 @@ private: |
| 311 | 328 | const void* __fallback_info); |
| 312 | 329 | |
| 313 | 330 | union _Storage { |
| 314 | constexpr _Storage() : __ptr(nullptr) {} | |
| 331 | _LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {} | |
| 315 | 332 | void * __ptr; |
| 316 | 333 | __any_imp::_Buffer __buf; |
| 317 | 334 | }; |
| ... | ... | @@ -692,10 +709,12 @@ any_cast(any * __any) _NOEXCEPT |
| 692 | 709 | return nullptr; |
| 693 | 710 | } |
| 694 | 711 | |
| 695 | #endif // _LIBCPP_STD_VER > 14 | |
| 712 | #endif // _LIBCPP_STD_VER >= 17 | |
| 696 | 713 | |
| 697 | 714 | _LIBCPP_END_NAMESPACE_STD |
| 698 | 715 | |
| 716 | _LIBCPP_POP_MACROS | |
| 717 | ||
| 699 | 718 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 |
| 700 | 719 | # include <chrono> |
| 701 | 720 | #endif |
| ... | ... | @@ -703,9 +722,12 @@ _LIBCPP_END_NAMESPACE_STD |
| 703 | 722 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 704 | 723 | # include <atomic> |
| 705 | 724 | # include <concepts> |
| 725 | # include <cstdlib> | |
| 706 | 726 | # include <iosfwd> |
| 707 | 727 | # include <iterator> |
| 708 | 728 | # include <memory> |
| 729 | # include <stdexcept> | |
| 730 | # include <type_traits> | |
| 709 | 731 | # include <variant> |
| 710 | 732 | #endif |
| 711 | 733 |
lib/libcxx/include/array+57-44| ... | ... | @@ -77,15 +77,18 @@ template <class T, class... U> |
| 77 | 77 | template <class T, size_t N> |
| 78 | 78 | bool operator==(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 |
| 79 | 79 | template <class T, size_t N> |
| 80 | bool operator!=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 | |
| 80 | bool operator!=(const array<T,N>& x, const array<T,N>& y); // removed in C++20 | |
| 81 | 81 | template <class T, size_t N> |
| 82 | bool operator<(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 | |
| 82 | bool operator<(const array<T,N>& x, const array<T,N>& y); // removed in C++20 | |
| 83 | 83 | template <class T, size_t N> |
| 84 | bool operator>(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 | |
| 84 | bool operator>(const array<T,N>& x, const array<T,N>& y); // removed in C++20 | |
| 85 | 85 | template <class T, size_t N> |
| 86 | bool operator<=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 | |
| 86 | bool operator<=(const array<T,N>& x, const array<T,N>& y); // removed in C++20 | |
| 87 | 87 | template <class T, size_t N> |
| 88 | bool operator>=(const array<T,N>& x, const array<T,N>& y); // constexpr in C++20 | |
| 88 | bool operator>=(const array<T,N>& x, const array<T,N>& y); // removed in C++20 | |
| 89 | template<class T, size_t N> | |
| 90 | constexpr synth-three-way-result<T> | |
| 91 | operator<=>(const array<T, N>& x, const array<T, N>& y); // since C++20 | |
| 89 | 92 | |
| 90 | 93 | template <class T, size_t N > |
| 91 | 94 | void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20 |
| ... | ... | @@ -111,16 +114,27 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce |
| 111 | 114 | #include <__algorithm/equal.h> |
| 112 | 115 | #include <__algorithm/fill_n.h> |
| 113 | 116 | #include <__algorithm/lexicographical_compare.h> |
| 117 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 114 | 118 | #include <__algorithm/swap_ranges.h> |
| 115 | 119 | #include <__assert> // all public C++ headers provide the assertion handler |
| 116 | 120 | #include <__config> |
| 121 | #include <__fwd/array.h> | |
| 117 | 122 | #include <__iterator/reverse_iterator.h> |
| 118 | #include <__tuple_dir/sfinae_helpers.h> | |
| 123 | #include <__tuple/sfinae_helpers.h> | |
| 124 | #include <__type_traits/conditional.h> | |
| 125 | #include <__type_traits/is_array.h> | |
| 126 | #include <__type_traits/is_const.h> | |
| 127 | #include <__type_traits/is_constructible.h> | |
| 128 | #include <__type_traits/is_move_constructible.h> | |
| 129 | #include <__type_traits/is_nothrow_constructible.h> | |
| 130 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 131 | #include <__type_traits/is_same.h> | |
| 132 | #include <__type_traits/is_swappable.h> | |
| 133 | #include <__type_traits/remove_cv.h> | |
| 119 | 134 | #include <__utility/integer_sequence.h> |
| 120 | 135 | #include <__utility/move.h> |
| 121 | 136 | #include <__utility/unreachable.h> |
| 122 | 137 | #include <stdexcept> |
| 123 | #include <type_traits> | |
| 124 | 138 | #include <version> |
| 125 | 139 | |
| 126 | 140 | // standard-mandated includes |
| ... | ... | @@ -137,8 +151,8 @@ template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexce |
| 137 | 151 | #include <initializer_list> |
| 138 | 152 | |
| 139 | 153 | // [tuple.helper] |
| 140 | #include <__tuple_dir/tuple_element.h> | |
| 141 | #include <__tuple_dir/tuple_size.h> | |
| 154 | #include <__tuple/tuple_element.h> | |
| 155 | #include <__tuple/tuple_size.h> | |
| 142 | 156 | |
| 143 | 157 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 144 | 158 | # pragma GCC system_header |
| ... | ... | @@ -215,23 +229,23 @@ struct _LIBCPP_TEMPLATE_VIS array |
| 215 | 229 | // element access: |
| 216 | 230 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 217 | 231 | reference operator[](size_type __n) _NOEXCEPT { |
| 218 | _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>"); | |
| 232 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); | |
| 219 | 233 | return __elems_[__n]; |
| 220 | 234 | } |
| 221 | 235 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 222 | 236 | const_reference operator[](size_type __n) const _NOEXCEPT { |
| 223 | _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>"); | |
| 237 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); | |
| 224 | 238 | return __elems_[__n]; |
| 225 | 239 | } |
| 226 | 240 | |
| 227 | _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) | |
| 241 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) | |
| 228 | 242 | { |
| 229 | 243 | if (__n >= _Size) |
| 230 | 244 | __throw_out_of_range("array::at"); |
| 231 | 245 | return __elems_[__n]; |
| 232 | 246 | } |
| 233 | 247 | |
| 234 | _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const | |
| 248 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const | |
| 235 | 249 | { |
| 236 | 250 | if (__n >= _Size) |
| 237 | 251 | __throw_out_of_range("array::at"); |
| ... | ... | @@ -328,13 +342,13 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> |
| 328 | 342 | // element access: |
| 329 | 343 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 330 | 344 | reference operator[](size_type) _NOEXCEPT { |
| 331 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); | |
| 345 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); | |
| 332 | 346 | __libcpp_unreachable(); |
| 333 | 347 | } |
| 334 | 348 | |
| 335 | 349 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 336 | 350 | const_reference operator[](size_type) const _NOEXCEPT { |
| 337 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); | |
| 351 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); | |
| 338 | 352 | __libcpp_unreachable(); |
| 339 | 353 | } |
| 340 | 354 | |
| ... | ... | @@ -352,31 +366,31 @@ struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> |
| 352 | 366 | |
| 353 | 367 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 354 | 368 | reference front() _NOEXCEPT { |
| 355 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array"); | |
| 369 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); | |
| 356 | 370 | __libcpp_unreachable(); |
| 357 | 371 | } |
| 358 | 372 | |
| 359 | 373 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 360 | 374 | const_reference front() const _NOEXCEPT { |
| 361 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array"); | |
| 375 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); | |
| 362 | 376 | __libcpp_unreachable(); |
| 363 | 377 | } |
| 364 | 378 | |
| 365 | 379 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 |
| 366 | 380 | reference back() _NOEXCEPT { |
| 367 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array"); | |
| 381 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); | |
| 368 | 382 | __libcpp_unreachable(); |
| 369 | 383 | } |
| 370 | 384 | |
| 371 | 385 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 372 | 386 | const_reference back() const _NOEXCEPT { |
| 373 | _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array"); | |
| 387 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); | |
| 374 | 388 | __libcpp_unreachable(); |
| 375 | 389 | } |
| 376 | 390 | }; |
| 377 | 391 | |
| 378 | 392 | |
| 379 | #if _LIBCPP_STD_VER > 14 | |
| 393 | #if _LIBCPP_STD_VER >= 17 | |
| 380 | 394 | template<class _Tp, class... _Args, |
| 381 | 395 | class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value> |
| 382 | 396 | > |
| ... | ... | @@ -392,47 +406,44 @@ operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) |
| 392 | 406 | return _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 393 | 407 | } |
| 394 | 408 | |
| 409 | #if _LIBCPP_STD_VER <= 17 | |
| 410 | ||
| 395 | 411 | template <class _Tp, size_t _Size> |
| 396 | inline _LIBCPP_INLINE_VISIBILITY | |
| 397 | _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 398 | operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) | |
| 399 | { | |
| 412 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 400 | 413 | return !(__x == __y); |
| 401 | 414 | } |
| 402 | 415 | |
| 403 | 416 | template <class _Tp, size_t _Size> |
| 404 | inline _LIBCPP_INLINE_VISIBILITY | |
| 405 | _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 406 | operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) | |
| 407 | { | |
| 408 | return _VSTD::lexicographical_compare(__x.begin(), __x.end(), | |
| 409 | __y.begin(), __y.end()); | |
| 417 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 418 | return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); | |
| 410 | 419 | } |
| 411 | 420 | |
| 412 | 421 | template <class _Tp, size_t _Size> |
| 413 | inline _LIBCPP_INLINE_VISIBILITY | |
| 414 | _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 415 | operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) | |
| 416 | { | |
| 422 | inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 417 | 423 | return __y < __x; |
| 418 | 424 | } |
| 419 | 425 | |
| 420 | 426 | template <class _Tp, size_t _Size> |
| 421 | inline _LIBCPP_INLINE_VISIBILITY | |
| 422 | _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 423 | operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) | |
| 424 | { | |
| 427 | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 425 | 428 | return !(__y < __x); |
| 426 | 429 | } |
| 427 | 430 | |
| 428 | 431 | template <class _Tp, size_t _Size> |
| 429 | inline _LIBCPP_INLINE_VISIBILITY | |
| 430 | _LIBCPP_CONSTEXPR_SINCE_CXX20 bool | |
| 431 | operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) | |
| 432 | { | |
| 432 | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 433 | 433 | return !(__x < __y); |
| 434 | 434 | } |
| 435 | 435 | |
| 436 | #else // _LIBCPP_STD_VER <= 17 | |
| 437 | ||
| 438 | template <class _Tp, size_t _Size> | |
| 439 | _LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp> | |
| 440 | operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { | |
| 441 | return std::lexicographical_compare_three_way( | |
| 442 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); | |
| 443 | } | |
| 444 | ||
| 445 | #endif // _LIBCPP_STD_VER <= 17 | |
| 446 | ||
| 436 | 447 | template <class _Tp, size_t _Size> |
| 437 | 448 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 438 | 449 | __enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void> |
| ... | ... | @@ -489,7 +500,7 @@ get(const array<_Tp, _Size>&& __a) _NOEXCEPT |
| 489 | 500 | return _VSTD::move(__a.__elems_[_Ip]); |
| 490 | 501 | } |
| 491 | 502 | |
| 492 | #if _LIBCPP_STD_VER > 17 | |
| 503 | #if _LIBCPP_STD_VER >= 20 | |
| 493 | 504 | |
| 494 | 505 | template <typename _Tp, size_t _Size, size_t... _Index> |
| 495 | 506 | _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size> |
| ... | ... | @@ -528,14 +539,16 @@ to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { |
| 528 | 539 | make_index_sequence<_Size>()); |
| 529 | 540 | } |
| 530 | 541 | |
| 531 | #endif // _LIBCPP_STD_VER > 17 | |
| 542 | #endif // _LIBCPP_STD_VER >= 20 | |
| 532 | 543 | |
| 533 | 544 | _LIBCPP_END_NAMESPACE_STD |
| 534 | 545 | |
| 535 | 546 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 536 | 547 | # include <algorithm> |
| 537 | 548 | # include <concepts> |
| 549 | # include <cstdlib> | |
| 538 | 550 | # include <iterator> |
| 551 | # include <type_traits> | |
| 539 | 552 | # include <utility> |
| 540 | 553 | #endif |
| 541 | 554 |
lib/libcxx/include/atomic+18-2133| ... | ... | @@ -519,2154 +519,39 @@ template <class T> |
| 519 | 519 | */ |
| 520 | 520 | |
| 521 | 521 | #include <__assert> // all public C++ headers provide the assertion handler |
| 522 | #include <__availability> | |
| 523 | #include <__chrono/duration.h> | |
| 522 | #include <__atomic/aliases.h> | |
| 523 | #include <__atomic/atomic.h> | |
| 524 | #include <__atomic/atomic_base.h> | |
| 525 | #include <__atomic/atomic_flag.h> | |
| 526 | #include <__atomic/atomic_init.h> | |
| 527 | #include <__atomic/atomic_lock_free.h> | |
| 528 | #include <__atomic/atomic_sync.h> | |
| 529 | #include <__atomic/check_memory_order.h> | |
| 530 | #include <__atomic/contention_t.h> | |
| 531 | #include <__atomic/cxx_atomic_impl.h> | |
| 532 | #include <__atomic/fence.h> | |
| 533 | #include <__atomic/is_always_lock_free.h> | |
| 534 | #include <__atomic/kill_dependency.h> | |
| 535 | #include <__atomic/memory_order.h> | |
| 524 | 536 | #include <__config> |
| 525 | #include <__thread/poll_with_backoff.h> | |
| 526 | #include <__thread/timed_backoff_policy.h> | |
| 527 | #include <__type_traits/conditional.h> | |
| 528 | #include <__type_traits/decay.h> | |
| 529 | #include <__type_traits/is_assignable.h> | |
| 530 | #include <__type_traits/is_function.h> | |
| 531 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 532 | #include <__type_traits/is_same.h> | |
| 533 | #include <__type_traits/is_trivially_copyable.h> | |
| 534 | #include <__type_traits/remove_const.h> | |
| 535 | #include <__type_traits/remove_pointer.h> | |
| 536 | #include <__type_traits/underlying_type.h> | |
| 537 | #include <cstddef> | |
| 538 | #include <cstdint> | |
| 539 | #include <cstring> | |
| 540 | 537 | #include <version> |
| 541 | 538 | |
| 542 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 543 | # include <__threading_support> | |
| 544 | #endif | |
| 545 | ||
| 546 | 539 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 547 | 540 | # pragma GCC system_header |
| 548 | 541 | #endif |
| 549 | 542 | |
| 550 | 543 | #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER |
| 551 | # error <atomic> is not implemented | |
| 552 | #endif | |
| 553 | #ifdef kill_dependency | |
| 554 | # error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23. | |
| 544 | # error <atomic> is not implemented | |
| 555 | 545 | #endif |
| 556 | 546 | |
| 557 | #define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ | |
| 558 | _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ | |
| 559 | __m == memory_order_acquire || \ | |
| 560 | __m == memory_order_acq_rel, \ | |
| 561 | "memory order argument to atomic operation is invalid") | |
| 562 | ||
| 563 | #define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ | |
| 564 | _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ | |
| 565 | __m == memory_order_acq_rel, \ | |
| 566 | "memory order argument to atomic operation is invalid") | |
| 567 | ||
| 568 | #define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ | |
| 569 | _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ | |
| 570 | __f == memory_order_acq_rel, \ | |
| 571 | "memory order argument to atomic operation is invalid") | |
| 572 | ||
| 573 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 574 | ||
| 575 | // Figure out what the underlying type for `memory_order` would be if it were | |
| 576 | // declared as an unscoped enum (accounting for -fshort-enums). Use this result | |
| 577 | // to pin the underlying type in C++20. | |
| 578 | enum __legacy_memory_order { | |
| 579 | __mo_relaxed, | |
| 580 | __mo_consume, | |
| 581 | __mo_acquire, | |
| 582 | __mo_release, | |
| 583 | __mo_acq_rel, | |
| 584 | __mo_seq_cst | |
| 585 | }; | |
| 586 | ||
| 587 | typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t; | |
| 588 | ||
| 589 | #if _LIBCPP_STD_VER > 17 | |
| 590 | ||
| 591 | enum class memory_order : __memory_order_underlying_t { | |
| 592 | relaxed = __mo_relaxed, | |
| 593 | consume = __mo_consume, | |
| 594 | acquire = __mo_acquire, | |
| 595 | release = __mo_release, | |
| 596 | acq_rel = __mo_acq_rel, | |
| 597 | seq_cst = __mo_seq_cst | |
| 598 | }; | |
| 599 | ||
| 600 | inline constexpr auto memory_order_relaxed = memory_order::relaxed; | |
| 601 | inline constexpr auto memory_order_consume = memory_order::consume; | |
| 602 | inline constexpr auto memory_order_acquire = memory_order::acquire; | |
| 603 | inline constexpr auto memory_order_release = memory_order::release; | |
| 604 | inline constexpr auto memory_order_acq_rel = memory_order::acq_rel; | |
| 605 | inline constexpr auto memory_order_seq_cst = memory_order::seq_cst; | |
| 606 | ||
| 607 | #else | |
| 608 | ||
| 609 | typedef enum memory_order { | |
| 610 | memory_order_relaxed = __mo_relaxed, | |
| 611 | memory_order_consume = __mo_consume, | |
| 612 | memory_order_acquire = __mo_acquire, | |
| 613 | memory_order_release = __mo_release, | |
| 614 | memory_order_acq_rel = __mo_acq_rel, | |
| 615 | memory_order_seq_cst = __mo_seq_cst, | |
| 616 | } memory_order; | |
| 617 | ||
| 618 | #endif // _LIBCPP_STD_VER > 17 | |
| 619 | ||
| 620 | template <typename _Tp> _LIBCPP_INLINE_VISIBILITY | |
| 621 | bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { | |
| 622 | return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0; | |
| 623 | } | |
| 624 | ||
| 625 | static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value), | |
| 626 | "unexpected underlying type for std::memory_order"); | |
| 627 | ||
| 628 | #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ | |
| 629 | defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) | |
| 630 | ||
| 631 | // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because | |
| 632 | // the default operator= in an object is not volatile, a byte-by-byte copy | |
| 633 | // is required. | |
| 634 | template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY | |
| 635 | typename enable_if<is_assignable<_Tp&, _Tv>::value>::type | |
| 636 | __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { | |
| 637 | __a_value = __val; | |
| 638 | } | |
| 639 | template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY | |
| 640 | typename enable_if<is_assignable<_Tp&, _Tv>::value>::type | |
| 641 | __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { | |
| 642 | volatile char* __to = reinterpret_cast<volatile char*>(&__a_value); | |
| 643 | volatile char* __end = __to + sizeof(_Tp); | |
| 644 | volatile const char* __from = reinterpret_cast<volatile const char*>(&__val); | |
| 645 | while (__to != __end) | |
| 646 | *__to++ = *__from++; | |
| 647 | } | |
| 648 | ||
| 649 | #endif | |
| 650 | ||
| 651 | #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) | |
| 652 | ||
| 653 | template <typename _Tp> | |
| 654 | struct __cxx_atomic_base_impl { | |
| 655 | ||
| 656 | _LIBCPP_INLINE_VISIBILITY | |
| 657 | #ifndef _LIBCPP_CXX03_LANG | |
| 658 | __cxx_atomic_base_impl() _NOEXCEPT = default; | |
| 659 | #else | |
| 660 | __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} | |
| 661 | #endif // _LIBCPP_CXX03_LANG | |
| 662 | _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT | |
| 663 | : __a_value(value) {} | |
| 664 | _Tp __a_value; | |
| 665 | }; | |
| 666 | ||
| 667 | _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { | |
| 668 | // Avoid switch statement to make this a constexpr. | |
| 669 | return __order == memory_order_relaxed ? __ATOMIC_RELAXED: | |
| 670 | (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: | |
| 671 | (__order == memory_order_release ? __ATOMIC_RELEASE: | |
| 672 | (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: | |
| 673 | (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: | |
| 674 | __ATOMIC_CONSUME)))); | |
| 675 | } | |
| 676 | ||
| 677 | _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { | |
| 678 | // Avoid switch statement to make this a constexpr. | |
| 679 | return __order == memory_order_relaxed ? __ATOMIC_RELAXED: | |
| 680 | (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: | |
| 681 | (__order == memory_order_release ? __ATOMIC_RELAXED: | |
| 682 | (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: | |
| 683 | (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: | |
| 684 | __ATOMIC_CONSUME)))); | |
| 685 | } | |
| 686 | ||
| 687 | template <typename _Tp> | |
| 688 | _LIBCPP_INLINE_VISIBILITY | |
| 689 | void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { | |
| 690 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 691 | } | |
| 692 | ||
| 693 | template <typename _Tp> | |
| 694 | _LIBCPP_INLINE_VISIBILITY | |
| 695 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { | |
| 696 | __a->__a_value = __val; | |
| 697 | } | |
| 698 | ||
| 699 | _LIBCPP_INLINE_VISIBILITY inline | |
| 700 | void __cxx_atomic_thread_fence(memory_order __order) { | |
| 701 | __atomic_thread_fence(__to_gcc_order(__order)); | |
| 702 | } | |
| 703 | ||
| 704 | _LIBCPP_INLINE_VISIBILITY inline | |
| 705 | void __cxx_atomic_signal_fence(memory_order __order) { | |
| 706 | __atomic_signal_fence(__to_gcc_order(__order)); | |
| 707 | } | |
| 708 | ||
| 709 | template <typename _Tp> | |
| 710 | _LIBCPP_INLINE_VISIBILITY | |
| 711 | void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, | |
| 712 | memory_order __order) { | |
| 713 | __atomic_store(&__a->__a_value, &__val, | |
| 714 | __to_gcc_order(__order)); | |
| 715 | } | |
| 716 | ||
| 717 | template <typename _Tp> | |
| 718 | _LIBCPP_INLINE_VISIBILITY | |
| 719 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, | |
| 720 | memory_order __order) { | |
| 721 | __atomic_store(&__a->__a_value, &__val, | |
| 722 | __to_gcc_order(__order)); | |
| 723 | } | |
| 724 | ||
| 725 | template <typename _Tp> | |
| 726 | _LIBCPP_INLINE_VISIBILITY | |
| 727 | _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 728 | memory_order __order) { | |
| 729 | _Tp __ret; | |
| 730 | __atomic_load(&__a->__a_value, &__ret, | |
| 731 | __to_gcc_order(__order)); | |
| 732 | return __ret; | |
| 733 | } | |
| 734 | ||
| 735 | template <typename _Tp> | |
| 736 | _LIBCPP_INLINE_VISIBILITY | |
| 737 | _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { | |
| 738 | _Tp __ret; | |
| 739 | __atomic_load(&__a->__a_value, &__ret, | |
| 740 | __to_gcc_order(__order)); | |
| 741 | return __ret; | |
| 742 | } | |
| 743 | ||
| 744 | template <typename _Tp> | |
| 745 | _LIBCPP_INLINE_VISIBILITY | |
| 746 | _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 747 | _Tp __value, memory_order __order) { | |
| 748 | _Tp __ret; | |
| 749 | __atomic_exchange(&__a->__a_value, &__value, &__ret, | |
| 750 | __to_gcc_order(__order)); | |
| 751 | return __ret; | |
| 752 | } | |
| 753 | ||
| 754 | template <typename _Tp> | |
| 755 | _LIBCPP_INLINE_VISIBILITY | |
| 756 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, | |
| 757 | memory_order __order) { | |
| 758 | _Tp __ret; | |
| 759 | __atomic_exchange(&__a->__a_value, &__value, &__ret, | |
| 760 | __to_gcc_order(__order)); | |
| 761 | return __ret; | |
| 762 | } | |
| 763 | ||
| 764 | template <typename _Tp> | |
| 765 | _LIBCPP_INLINE_VISIBILITY | |
| 766 | bool __cxx_atomic_compare_exchange_strong( | |
| 767 | volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, | |
| 768 | memory_order __success, memory_order __failure) { | |
| 769 | return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, | |
| 770 | false, | |
| 771 | __to_gcc_order(__success), | |
| 772 | __to_gcc_failure_order(__failure)); | |
| 773 | } | |
| 774 | ||
| 775 | template <typename _Tp> | |
| 776 | _LIBCPP_INLINE_VISIBILITY | |
| 777 | bool __cxx_atomic_compare_exchange_strong( | |
| 778 | __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, | |
| 779 | memory_order __failure) { | |
| 780 | return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, | |
| 781 | false, | |
| 782 | __to_gcc_order(__success), | |
| 783 | __to_gcc_failure_order(__failure)); | |
| 784 | } | |
| 785 | ||
| 786 | template <typename _Tp> | |
| 787 | _LIBCPP_INLINE_VISIBILITY | |
| 788 | bool __cxx_atomic_compare_exchange_weak( | |
| 789 | volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, | |
| 790 | memory_order __success, memory_order __failure) { | |
| 791 | return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, | |
| 792 | true, | |
| 793 | __to_gcc_order(__success), | |
| 794 | __to_gcc_failure_order(__failure)); | |
| 795 | } | |
| 796 | ||
| 797 | template <typename _Tp> | |
| 798 | _LIBCPP_INLINE_VISIBILITY | |
| 799 | bool __cxx_atomic_compare_exchange_weak( | |
| 800 | __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, | |
| 801 | memory_order __failure) { | |
| 802 | return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, | |
| 803 | true, | |
| 804 | __to_gcc_order(__success), | |
| 805 | __to_gcc_failure_order(__failure)); | |
| 806 | } | |
| 807 | ||
| 808 | template <typename _Tp> | |
| 809 | struct __skip_amt { enum {value = 1}; }; | |
| 810 | ||
| 811 | template <typename _Tp> | |
| 812 | struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; | |
| 813 | ||
| 814 | // FIXME: Haven't figured out what the spec says about using arrays with | |
| 815 | // atomic_fetch_add. Force a failure rather than creating bad behavior. | |
| 816 | template <typename _Tp> | |
| 817 | struct __skip_amt<_Tp[]> { }; | |
| 818 | template <typename _Tp, int n> | |
| 819 | struct __skip_amt<_Tp[n]> { }; | |
| 820 | ||
| 821 | template <typename _Tp, typename _Td> | |
| 822 | _LIBCPP_INLINE_VISIBILITY | |
| 823 | _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 824 | _Td __delta, memory_order __order) { | |
| 825 | return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, | |
| 826 | __to_gcc_order(__order)); | |
| 827 | } | |
| 828 | ||
| 829 | template <typename _Tp, typename _Td> | |
| 830 | _LIBCPP_INLINE_VISIBILITY | |
| 831 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, | |
| 832 | memory_order __order) { | |
| 833 | return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, | |
| 834 | __to_gcc_order(__order)); | |
| 835 | } | |
| 836 | ||
| 837 | template <typename _Tp, typename _Td> | |
| 838 | _LIBCPP_INLINE_VISIBILITY | |
| 839 | _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 840 | _Td __delta, memory_order __order) { | |
| 841 | return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, | |
| 842 | __to_gcc_order(__order)); | |
| 843 | } | |
| 844 | ||
| 845 | template <typename _Tp, typename _Td> | |
| 846 | _LIBCPP_INLINE_VISIBILITY | |
| 847 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, | |
| 848 | memory_order __order) { | |
| 849 | return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, | |
| 850 | __to_gcc_order(__order)); | |
| 851 | } | |
| 852 | ||
| 853 | template <typename _Tp> | |
| 854 | _LIBCPP_INLINE_VISIBILITY | |
| 855 | _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 856 | _Tp __pattern, memory_order __order) { | |
| 857 | return __atomic_fetch_and(&__a->__a_value, __pattern, | |
| 858 | __to_gcc_order(__order)); | |
| 859 | } | |
| 860 | ||
| 861 | template <typename _Tp> | |
| 862 | _LIBCPP_INLINE_VISIBILITY | |
| 863 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, | |
| 864 | _Tp __pattern, memory_order __order) { | |
| 865 | return __atomic_fetch_and(&__a->__a_value, __pattern, | |
| 866 | __to_gcc_order(__order)); | |
| 867 | } | |
| 868 | ||
| 869 | template <typename _Tp> | |
| 870 | _LIBCPP_INLINE_VISIBILITY | |
| 871 | _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 872 | _Tp __pattern, memory_order __order) { | |
| 873 | return __atomic_fetch_or(&__a->__a_value, __pattern, | |
| 874 | __to_gcc_order(__order)); | |
| 875 | } | |
| 876 | ||
| 877 | template <typename _Tp> | |
| 878 | _LIBCPP_INLINE_VISIBILITY | |
| 879 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, | |
| 880 | memory_order __order) { | |
| 881 | return __atomic_fetch_or(&__a->__a_value, __pattern, | |
| 882 | __to_gcc_order(__order)); | |
| 883 | } | |
| 884 | ||
| 885 | template <typename _Tp> | |
| 886 | _LIBCPP_INLINE_VISIBILITY | |
| 887 | _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, | |
| 888 | _Tp __pattern, memory_order __order) { | |
| 889 | return __atomic_fetch_xor(&__a->__a_value, __pattern, | |
| 890 | __to_gcc_order(__order)); | |
| 891 | } | |
| 892 | ||
| 893 | template <typename _Tp> | |
| 894 | _LIBCPP_INLINE_VISIBILITY | |
| 895 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, | |
| 896 | memory_order __order) { | |
| 897 | return __atomic_fetch_xor(&__a->__a_value, __pattern, | |
| 898 | __to_gcc_order(__order)); | |
| 899 | } | |
| 900 | ||
| 901 | #define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) | |
| 902 | ||
| 903 | #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) | |
| 904 | ||
| 905 | template <typename _Tp> | |
| 906 | struct __cxx_atomic_base_impl { | |
| 907 | ||
| 908 | _LIBCPP_INLINE_VISIBILITY | |
| 909 | #ifndef _LIBCPP_CXX03_LANG | |
| 910 | __cxx_atomic_base_impl() _NOEXCEPT = default; | |
| 911 | #else | |
| 912 | __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} | |
| 913 | #endif // _LIBCPP_CXX03_LANG | |
| 914 | _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT | |
| 915 | : __a_value(__value) {} | |
| 916 | _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; | |
| 917 | }; | |
| 918 | ||
| 919 | #define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) | |
| 920 | ||
| 921 | _LIBCPP_INLINE_VISIBILITY inline | |
| 922 | void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { | |
| 923 | __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); | |
| 924 | } | |
| 925 | ||
| 926 | _LIBCPP_INLINE_VISIBILITY inline | |
| 927 | void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { | |
| 928 | __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); | |
| 929 | } | |
| 930 | ||
| 931 | template<class _Tp> | |
| 932 | _LIBCPP_INLINE_VISIBILITY | |
| 933 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { | |
| 934 | __c11_atomic_init(&__a->__a_value, __val); | |
| 935 | } | |
| 936 | template<class _Tp> | |
| 937 | _LIBCPP_INLINE_VISIBILITY | |
| 938 | void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { | |
| 939 | __c11_atomic_init(&__a->__a_value, __val); | |
| 940 | } | |
| 941 | ||
| 942 | template<class _Tp> | |
| 943 | _LIBCPP_INLINE_VISIBILITY | |
| 944 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { | |
| 945 | __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); | |
| 946 | } | |
| 947 | template<class _Tp> | |
| 948 | _LIBCPP_INLINE_VISIBILITY | |
| 949 | void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { | |
| 950 | __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); | |
| 951 | } | |
| 952 | ||
| 953 | template<class _Tp> | |
| 954 | _LIBCPP_INLINE_VISIBILITY | |
| 955 | _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { | |
| 956 | using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; | |
| 957 | return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); | |
| 958 | } | |
| 959 | template<class _Tp> | |
| 960 | _LIBCPP_INLINE_VISIBILITY | |
| 961 | _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { | |
| 962 | using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; | |
| 963 | return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); | |
| 964 | } | |
| 965 | ||
| 966 | template<class _Tp> | |
| 967 | _LIBCPP_INLINE_VISIBILITY | |
| 968 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { | |
| 969 | return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); | |
| 970 | } | |
| 971 | template<class _Tp> | |
| 972 | _LIBCPP_INLINE_VISIBILITY | |
| 973 | _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { | |
| 974 | return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); | |
| 975 | } | |
| 976 | ||
| 977 | _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) { | |
| 978 | // Avoid switch statement to make this a constexpr. | |
| 979 | return __order == memory_order_release ? memory_order_relaxed: | |
| 980 | (__order == memory_order_acq_rel ? memory_order_acquire: | |
| 981 | __order); | |
| 982 | } | |
| 983 | ||
| 984 | template<class _Tp> | |
| 985 | _LIBCPP_INLINE_VISIBILITY | |
| 986 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 987 | return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 988 | } | |
| 989 | template<class _Tp> | |
| 990 | _LIBCPP_INLINE_VISIBILITY | |
| 991 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 992 | return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 993 | } | |
| 994 | ||
| 995 | template<class _Tp> | |
| 996 | _LIBCPP_INLINE_VISIBILITY | |
| 997 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 998 | return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 999 | } | |
| 1000 | template<class _Tp> | |
| 1001 | _LIBCPP_INLINE_VISIBILITY | |
| 1002 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { | |
| 1003 | return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); | |
| 1004 | } | |
| 1005 | ||
| 1006 | template<class _Tp> | |
| 1007 | _LIBCPP_INLINE_VISIBILITY | |
| 1008 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 1009 | return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1010 | } | |
| 1011 | template<class _Tp> | |
| 1012 | _LIBCPP_INLINE_VISIBILITY | |
| 1013 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 1014 | return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1015 | } | |
| 1016 | ||
| 1017 | template<class _Tp> | |
| 1018 | _LIBCPP_INLINE_VISIBILITY | |
| 1019 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 1020 | return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1021 | } | |
| 1022 | template<class _Tp> | |
| 1023 | _LIBCPP_INLINE_VISIBILITY | |
| 1024 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 1025 | return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1026 | } | |
| 1027 | ||
| 1028 | template<class _Tp> | |
| 1029 | _LIBCPP_INLINE_VISIBILITY | |
| 1030 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 1031 | return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1032 | } | |
| 1033 | template<class _Tp> | |
| 1034 | _LIBCPP_INLINE_VISIBILITY | |
| 1035 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { | |
| 1036 | return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1037 | } | |
| 1038 | template<class _Tp> | |
| 1039 | _LIBCPP_INLINE_VISIBILITY | |
| 1040 | _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 1041 | return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1042 | } | |
| 1043 | template<class _Tp> | |
| 1044 | _LIBCPP_INLINE_VISIBILITY | |
| 1045 | _Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { | |
| 1046 | return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); | |
| 1047 | } | |
| 1048 | ||
| 1049 | template<class _Tp> | |
| 1050 | _LIBCPP_INLINE_VISIBILITY | |
| 1051 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1052 | return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1053 | } | |
| 1054 | template<class _Tp> | |
| 1055 | _LIBCPP_INLINE_VISIBILITY | |
| 1056 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1057 | return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1058 | } | |
| 1059 | ||
| 1060 | template<class _Tp> | |
| 1061 | _LIBCPP_INLINE_VISIBILITY | |
| 1062 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1063 | return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1064 | } | |
| 1065 | template<class _Tp> | |
| 1066 | _LIBCPP_INLINE_VISIBILITY | |
| 1067 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1068 | return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1069 | } | |
| 1070 | ||
| 1071 | template<class _Tp> | |
| 1072 | _LIBCPP_INLINE_VISIBILITY | |
| 1073 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1074 | return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1075 | } | |
| 1076 | template<class _Tp> | |
| 1077 | _LIBCPP_INLINE_VISIBILITY | |
| 1078 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { | |
| 1079 | return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); | |
| 1080 | } | |
| 1081 | ||
| 1082 | #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP | |
| 1083 | ||
| 1084 | template <class _Tp> | |
| 1085 | _LIBCPP_INLINE_VISIBILITY | |
| 1086 | _Tp kill_dependency(_Tp __y) _NOEXCEPT | |
| 1087 | { | |
| 1088 | return __y; | |
| 1089 | } | |
| 1090 | ||
| 1091 | #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) | |
| 1092 | # define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE | |
| 1093 | # define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE | |
| 1094 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 1095 | # define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE | |
| 1096 | #endif | |
| 1097 | # define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE | |
| 1098 | # define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE | |
| 1099 | # define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE | |
| 1100 | # define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE | |
| 1101 | # define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE | |
| 1102 | # define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE | |
| 1103 | # define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE | |
| 1104 | # define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE | |
| 1105 | #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) | |
| 1106 | # define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE | |
| 1107 | # define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE | |
| 1108 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 1109 | # define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE | |
| 1110 | #endif | |
| 1111 | # define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE | |
| 1112 | # define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE | |
| 1113 | # define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE | |
| 1114 | # define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE | |
| 1115 | # define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE | |
| 1116 | # define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE | |
| 1117 | # define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE | |
| 1118 | # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE | |
| 1119 | #endif | |
| 1120 | ||
| 1121 | template <class _Tp> | |
| 1122 | struct __libcpp_is_always_lock_free { | |
| 1123 | // __atomic_always_lock_free is available in all Standard modes | |
| 1124 | static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); | |
| 1125 | }; | |
| 1126 | ||
| 1127 | #ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS | |
| 1128 | ||
| 1129 | template<typename _Tp> | |
| 1130 | struct __cxx_atomic_lock_impl { | |
| 1131 | ||
| 1132 | _LIBCPP_INLINE_VISIBILITY | |
| 1133 | __cxx_atomic_lock_impl() _NOEXCEPT | |
| 1134 | : __a_value(), __a_lock(0) {} | |
| 1135 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit | |
| 1136 | __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT | |
| 1137 | : __a_value(value), __a_lock(0) {} | |
| 1138 | ||
| 1139 | _Tp __a_value; | |
| 1140 | mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; | |
| 1141 | ||
| 1142 | _LIBCPP_INLINE_VISIBILITY void __lock() const volatile { | |
| 1143 | while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) | |
| 1144 | /*spin*/; | |
| 1145 | } | |
| 1146 | _LIBCPP_INLINE_VISIBILITY void __lock() const { | |
| 1147 | while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) | |
| 1148 | /*spin*/; | |
| 1149 | } | |
| 1150 | _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile { | |
| 1151 | __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); | |
| 1152 | } | |
| 1153 | _LIBCPP_INLINE_VISIBILITY void __unlock() const { | |
| 1154 | __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); | |
| 1155 | } | |
| 1156 | _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile { | |
| 1157 | __lock(); | |
| 1158 | _Tp __old; | |
| 1159 | __cxx_atomic_assign_volatile(__old, __a_value); | |
| 1160 | __unlock(); | |
| 1161 | return __old; | |
| 1162 | } | |
| 1163 | _LIBCPP_INLINE_VISIBILITY _Tp __read() const { | |
| 1164 | __lock(); | |
| 1165 | _Tp __old = __a_value; | |
| 1166 | __unlock(); | |
| 1167 | return __old; | |
| 1168 | } | |
| 1169 | }; | |
| 1170 | ||
| 1171 | template <typename _Tp> | |
| 1172 | _LIBCPP_INLINE_VISIBILITY | |
| 1173 | void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { | |
| 1174 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 1175 | } | |
| 1176 | template <typename _Tp> | |
| 1177 | _LIBCPP_INLINE_VISIBILITY | |
| 1178 | void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { | |
| 1179 | __a->__a_value = __val; | |
| 1180 | } | |
| 1181 | ||
| 1182 | template <typename _Tp> | |
| 1183 | _LIBCPP_INLINE_VISIBILITY | |
| 1184 | void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { | |
| 1185 | __a->__lock(); | |
| 1186 | __cxx_atomic_assign_volatile(__a->__a_value, __val); | |
| 1187 | __a->__unlock(); | |
| 1188 | } | |
| 1189 | template <typename _Tp> | |
| 1190 | _LIBCPP_INLINE_VISIBILITY | |
| 1191 | void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { | |
| 1192 | __a->__lock(); | |
| 1193 | __a->__a_value = __val; | |
| 1194 | __a->__unlock(); | |
| 1195 | } | |
| 1196 | ||
| 1197 | template <typename _Tp> | |
| 1198 | _LIBCPP_INLINE_VISIBILITY | |
| 1199 | _Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { | |
| 1200 | return __a->__read(); | |
| 1201 | } | |
| 1202 | template <typename _Tp> | |
| 1203 | _LIBCPP_INLINE_VISIBILITY | |
| 1204 | _Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { | |
| 1205 | return __a->__read(); | |
| 1206 | } | |
| 1207 | ||
| 1208 | template <typename _Tp> | |
| 1209 | _LIBCPP_INLINE_VISIBILITY | |
| 1210 | _Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { | |
| 1211 | __a->__lock(); | |
| 1212 | _Tp __old; | |
| 1213 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1214 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 1215 | __a->__unlock(); | |
| 1216 | return __old; | |
| 1217 | } | |
| 1218 | template <typename _Tp> | |
| 1219 | _LIBCPP_INLINE_VISIBILITY | |
| 1220 | _Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { | |
| 1221 | __a->__lock(); | |
| 1222 | _Tp __old = __a->__a_value; | |
| 1223 | __a->__a_value = __value; | |
| 1224 | __a->__unlock(); | |
| 1225 | return __old; | |
| 1226 | } | |
| 1227 | ||
| 1228 | template <typename _Tp> | |
| 1229 | _LIBCPP_INLINE_VISIBILITY | |
| 1230 | bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1231 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 1232 | _Tp __temp; | |
| 1233 | __a->__lock(); | |
| 1234 | __cxx_atomic_assign_volatile(__temp, __a->__a_value); | |
| 1235 | bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); | |
| 1236 | if(__ret) | |
| 1237 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 1238 | else | |
| 1239 | __cxx_atomic_assign_volatile(*__expected, __a->__a_value); | |
| 1240 | __a->__unlock(); | |
| 1241 | return __ret; | |
| 1242 | } | |
| 1243 | template <typename _Tp> | |
| 1244 | _LIBCPP_INLINE_VISIBILITY | |
| 1245 | bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1246 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 1247 | __a->__lock(); | |
| 1248 | bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); | |
| 1249 | if(__ret) | |
| 1250 | _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); | |
| 1251 | else | |
| 1252 | _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); | |
| 1253 | __a->__unlock(); | |
| 1254 | return __ret; | |
| 1255 | } | |
| 1256 | ||
| 1257 | template <typename _Tp> | |
| 1258 | _LIBCPP_INLINE_VISIBILITY | |
| 1259 | bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1260 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 1261 | _Tp __temp; | |
| 1262 | __a->__lock(); | |
| 1263 | __cxx_atomic_assign_volatile(__temp, __a->__a_value); | |
| 1264 | bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); | |
| 1265 | if(__ret) | |
| 1266 | __cxx_atomic_assign_volatile(__a->__a_value, __value); | |
| 1267 | else | |
| 1268 | __cxx_atomic_assign_volatile(*__expected, __a->__a_value); | |
| 1269 | __a->__unlock(); | |
| 1270 | return __ret; | |
| 1271 | } | |
| 1272 | template <typename _Tp> | |
| 1273 | _LIBCPP_INLINE_VISIBILITY | |
| 1274 | bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1275 | _Tp* __expected, _Tp __value, memory_order, memory_order) { | |
| 1276 | __a->__lock(); | |
| 1277 | bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); | |
| 1278 | if(__ret) | |
| 1279 | _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); | |
| 1280 | else | |
| 1281 | _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); | |
| 1282 | __a->__unlock(); | |
| 1283 | return __ret; | |
| 1284 | } | |
| 1285 | ||
| 1286 | template <typename _Tp, typename _Td> | |
| 1287 | _LIBCPP_INLINE_VISIBILITY | |
| 1288 | _Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1289 | _Td __delta, memory_order) { | |
| 1290 | __a->__lock(); | |
| 1291 | _Tp __old; | |
| 1292 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1293 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta)); | |
| 1294 | __a->__unlock(); | |
| 1295 | return __old; | |
| 1296 | } | |
| 1297 | template <typename _Tp, typename _Td> | |
| 1298 | _LIBCPP_INLINE_VISIBILITY | |
| 1299 | _Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1300 | _Td __delta, memory_order) { | |
| 1301 | __a->__lock(); | |
| 1302 | _Tp __old = __a->__a_value; | |
| 1303 | __a->__a_value += __delta; | |
| 1304 | __a->__unlock(); | |
| 1305 | return __old; | |
| 1306 | } | |
| 1307 | ||
| 1308 | template <typename _Tp, typename _Td> | |
| 1309 | _LIBCPP_INLINE_VISIBILITY | |
| 1310 | _Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, | |
| 1311 | ptrdiff_t __delta, memory_order) { | |
| 1312 | __a->__lock(); | |
| 1313 | _Tp* __old; | |
| 1314 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1315 | __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta); | |
| 1316 | __a->__unlock(); | |
| 1317 | return __old; | |
| 1318 | } | |
| 1319 | template <typename _Tp, typename _Td> | |
| 1320 | _LIBCPP_INLINE_VISIBILITY | |
| 1321 | _Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, | |
| 1322 | ptrdiff_t __delta, memory_order) { | |
| 1323 | __a->__lock(); | |
| 1324 | _Tp* __old = __a->__a_value; | |
| 1325 | __a->__a_value += __delta; | |
| 1326 | __a->__unlock(); | |
| 1327 | return __old; | |
| 1328 | } | |
| 1329 | ||
| 1330 | template <typename _Tp, typename _Td> | |
| 1331 | _LIBCPP_INLINE_VISIBILITY | |
| 1332 | _Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1333 | _Td __delta, memory_order) { | |
| 1334 | __a->__lock(); | |
| 1335 | _Tp __old; | |
| 1336 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1337 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta)); | |
| 1338 | __a->__unlock(); | |
| 1339 | return __old; | |
| 1340 | } | |
| 1341 | template <typename _Tp, typename _Td> | |
| 1342 | _LIBCPP_INLINE_VISIBILITY | |
| 1343 | _Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1344 | _Td __delta, memory_order) { | |
| 1345 | __a->__lock(); | |
| 1346 | _Tp __old = __a->__a_value; | |
| 1347 | __a->__a_value -= __delta; | |
| 1348 | __a->__unlock(); | |
| 1349 | return __old; | |
| 1350 | } | |
| 1351 | ||
| 1352 | template <typename _Tp> | |
| 1353 | _LIBCPP_INLINE_VISIBILITY | |
| 1354 | _Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1355 | _Tp __pattern, memory_order) { | |
| 1356 | __a->__lock(); | |
| 1357 | _Tp __old; | |
| 1358 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1359 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern)); | |
| 1360 | __a->__unlock(); | |
| 1361 | return __old; | |
| 1362 | } | |
| 1363 | template <typename _Tp> | |
| 1364 | _LIBCPP_INLINE_VISIBILITY | |
| 1365 | _Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1366 | _Tp __pattern, memory_order) { | |
| 1367 | __a->__lock(); | |
| 1368 | _Tp __old = __a->__a_value; | |
| 1369 | __a->__a_value &= __pattern; | |
| 1370 | __a->__unlock(); | |
| 1371 | return __old; | |
| 1372 | } | |
| 1373 | ||
| 1374 | template <typename _Tp> | |
| 1375 | _LIBCPP_INLINE_VISIBILITY | |
| 1376 | _Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1377 | _Tp __pattern, memory_order) { | |
| 1378 | __a->__lock(); | |
| 1379 | _Tp __old; | |
| 1380 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1381 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern)); | |
| 1382 | __a->__unlock(); | |
| 1383 | return __old; | |
| 1384 | } | |
| 1385 | template <typename _Tp> | |
| 1386 | _LIBCPP_INLINE_VISIBILITY | |
| 1387 | _Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1388 | _Tp __pattern, memory_order) { | |
| 1389 | __a->__lock(); | |
| 1390 | _Tp __old = __a->__a_value; | |
| 1391 | __a->__a_value |= __pattern; | |
| 1392 | __a->__unlock(); | |
| 1393 | return __old; | |
| 1394 | } | |
| 1395 | ||
| 1396 | template <typename _Tp> | |
| 1397 | _LIBCPP_INLINE_VISIBILITY | |
| 1398 | _Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, | |
| 1399 | _Tp __pattern, memory_order) { | |
| 1400 | __a->__lock(); | |
| 1401 | _Tp __old; | |
| 1402 | __cxx_atomic_assign_volatile(__old, __a->__a_value); | |
| 1403 | __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern)); | |
| 1404 | __a->__unlock(); | |
| 1405 | return __old; | |
| 1406 | } | |
| 1407 | template <typename _Tp> | |
| 1408 | _LIBCPP_INLINE_VISIBILITY | |
| 1409 | _Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, | |
| 1410 | _Tp __pattern, memory_order) { | |
| 1411 | __a->__lock(); | |
| 1412 | _Tp __old = __a->__a_value; | |
| 1413 | __a->__a_value ^= __pattern; | |
| 1414 | __a->__unlock(); | |
| 1415 | return __old; | |
| 1416 | } | |
| 1417 | ||
| 1418 | template <typename _Tp, | |
| 1419 | typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value, | |
| 1420 | __cxx_atomic_base_impl<_Tp>, | |
| 1421 | __cxx_atomic_lock_impl<_Tp> >::type> | |
| 1422 | #else | |
| 1423 | template <typename _Tp, | |
| 1424 | typename _Base = __cxx_atomic_base_impl<_Tp> > | |
| 1425 | #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS | |
| 1426 | struct __cxx_atomic_impl : public _Base { | |
| 1427 | static_assert(is_trivially_copyable<_Tp>::value, | |
| 1428 | "std::atomic<T> requires that 'T' be a trivially copyable type"); | |
| 1429 | ||
| 1430 | _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default; | |
| 1431 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT | |
| 1432 | : _Base(__value) {} | |
| 1433 | }; | |
| 1434 | ||
| 1435 | #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) | |
| 1436 | using __cxx_contention_t = int32_t; | |
| 1437 | #else | |
| 1438 | using __cxx_contention_t = int64_t; | |
| 1439 | #endif // __linux__ || (_AIX && !__64BIT__) | |
| 1440 | ||
| 1441 | using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; | |
| 1442 | ||
| 1443 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 1444 | ||
| 1445 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); | |
| 1446 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); | |
| 1447 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); | |
| 1448 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); | |
| 1449 | ||
| 1450 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); | |
| 1451 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); | |
| 1452 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); | |
| 1453 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); | |
| 1454 | ||
| 1455 | template <class _Atp, class _Fn> | |
| 1456 | struct __libcpp_atomic_wait_backoff_impl { | |
| 1457 | _Atp* __a; | |
| 1458 | _Fn __test_fn; | |
| 1459 | _LIBCPP_AVAILABILITY_SYNC | |
| 1460 | _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const | |
| 1461 | { | |
| 1462 | if(__elapsed > chrono::microseconds(64)) | |
| 1463 | { | |
| 1464 | auto const __monitor = std::__libcpp_atomic_monitor(__a); | |
| 1465 | if(__test_fn()) | |
| 1466 | return true; | |
| 1467 | std::__libcpp_atomic_wait(__a, __monitor); | |
| 1468 | } | |
| 1469 | else if(__elapsed > chrono::microseconds(4)) | |
| 1470 | __libcpp_thread_yield(); | |
| 1471 | else | |
| 1472 | {} // poll | |
| 1473 | return false; | |
| 1474 | } | |
| 1475 | }; | |
| 1476 | ||
| 1477 | template <class _Atp, class _Fn> | |
| 1478 | _LIBCPP_AVAILABILITY_SYNC | |
| 1479 | _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) | |
| 1480 | { | |
| 1481 | __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn}; | |
| 1482 | return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); | |
| 1483 | } | |
| 1484 | ||
| 1485 | #else // _LIBCPP_HAS_NO_THREADS | |
| 1486 | ||
| 1487 | template <class _Tp> | |
| 1488 | _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } | |
| 1489 | template <class _Tp> | |
| 1490 | _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } | |
| 1491 | template <class _Atp, class _Fn> | |
| 1492 | _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) | |
| 1493 | { | |
| 1494 | return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); | |
| 1495 | } | |
| 1496 | ||
| 1497 | #endif // _LIBCPP_HAS_NO_THREADS | |
| 1498 | ||
| 1499 | template <class _Atp, class _Tp> | |
| 1500 | struct __cxx_atomic_wait_test_fn_impl { | |
| 1501 | _Atp* __a; | |
| 1502 | _Tp __val; | |
| 1503 | memory_order __order; | |
| 1504 | _LIBCPP_INLINE_VISIBILITY bool operator()() const | |
| 1505 | { | |
| 1506 | return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); | |
| 1507 | } | |
| 1508 | }; | |
| 1509 | ||
| 1510 | template <class _Atp, class _Tp> | |
| 1511 | _LIBCPP_AVAILABILITY_SYNC | |
| 1512 | _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) | |
| 1513 | { | |
| 1514 | __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; | |
| 1515 | return std::__cxx_atomic_wait(__a, __test_fn); | |
| 1516 | } | |
| 1517 | ||
| 1518 | // general atomic<T> | |
| 1519 | ||
| 1520 | template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> | |
| 1521 | struct __atomic_base // false | |
| 1522 | { | |
| 1523 | mutable __cxx_atomic_impl<_Tp> __a_; | |
| 1524 | ||
| 1525 | #if defined(__cpp_lib_atomic_is_always_lock_free) | |
| 1526 | static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; | |
| 1527 | #endif | |
| 1528 | ||
| 1529 | _LIBCPP_INLINE_VISIBILITY | |
| 1530 | bool is_lock_free() const volatile _NOEXCEPT | |
| 1531 | {return __cxx_atomic_is_lock_free(sizeof(_Tp));} | |
| 1532 | _LIBCPP_INLINE_VISIBILITY | |
| 1533 | bool is_lock_free() const _NOEXCEPT | |
| 1534 | {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} | |
| 1535 | _LIBCPP_INLINE_VISIBILITY | |
| 1536 | void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1537 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 1538 | {std::__cxx_atomic_store(&__a_, __d, __m);} | |
| 1539 | _LIBCPP_INLINE_VISIBILITY | |
| 1540 | void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1541 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 1542 | {std::__cxx_atomic_store(&__a_, __d, __m);} | |
| 1543 | _LIBCPP_INLINE_VISIBILITY | |
| 1544 | _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 1545 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 1546 | {return std::__cxx_atomic_load(&__a_, __m);} | |
| 1547 | _LIBCPP_INLINE_VISIBILITY | |
| 1548 | _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 1549 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 1550 | {return std::__cxx_atomic_load(&__a_, __m);} | |
| 1551 | _LIBCPP_INLINE_VISIBILITY | |
| 1552 | operator _Tp() const volatile _NOEXCEPT {return load();} | |
| 1553 | _LIBCPP_INLINE_VISIBILITY | |
| 1554 | operator _Tp() const _NOEXCEPT {return load();} | |
| 1555 | _LIBCPP_INLINE_VISIBILITY | |
| 1556 | _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1557 | {return std::__cxx_atomic_exchange(&__a_, __d, __m);} | |
| 1558 | _LIBCPP_INLINE_VISIBILITY | |
| 1559 | _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1560 | {return std::__cxx_atomic_exchange(&__a_, __d, __m);} | |
| 1561 | _LIBCPP_INLINE_VISIBILITY | |
| 1562 | bool compare_exchange_weak(_Tp& __e, _Tp __d, | |
| 1563 | memory_order __s, memory_order __f) volatile _NOEXCEPT | |
| 1564 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 1565 | {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} | |
| 1566 | _LIBCPP_INLINE_VISIBILITY | |
| 1567 | bool compare_exchange_weak(_Tp& __e, _Tp __d, | |
| 1568 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 1569 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 1570 | {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} | |
| 1571 | _LIBCPP_INLINE_VISIBILITY | |
| 1572 | bool compare_exchange_strong(_Tp& __e, _Tp __d, | |
| 1573 | memory_order __s, memory_order __f) volatile _NOEXCEPT | |
| 1574 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 1575 | {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} | |
| 1576 | _LIBCPP_INLINE_VISIBILITY | |
| 1577 | bool compare_exchange_strong(_Tp& __e, _Tp __d, | |
| 1578 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 1579 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 1580 | {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} | |
| 1581 | _LIBCPP_INLINE_VISIBILITY | |
| 1582 | bool compare_exchange_weak(_Tp& __e, _Tp __d, | |
| 1583 | memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1584 | {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} | |
| 1585 | _LIBCPP_INLINE_VISIBILITY | |
| 1586 | bool compare_exchange_weak(_Tp& __e, _Tp __d, | |
| 1587 | memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1588 | {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} | |
| 1589 | _LIBCPP_INLINE_VISIBILITY | |
| 1590 | bool compare_exchange_strong(_Tp& __e, _Tp __d, | |
| 1591 | memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1592 | {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} | |
| 1593 | _LIBCPP_INLINE_VISIBILITY | |
| 1594 | bool compare_exchange_strong(_Tp& __e, _Tp __d, | |
| 1595 | memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1596 | {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} | |
| 1597 | ||
| 1598 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 1599 | {std::__cxx_atomic_wait(&__a_, __v, __m);} | |
| 1600 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 1601 | {std::__cxx_atomic_wait(&__a_, __v, __m);} | |
| 1602 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT | |
| 1603 | {std::__cxx_atomic_notify_one(&__a_);} | |
| 1604 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT | |
| 1605 | {std::__cxx_atomic_notify_one(&__a_);} | |
| 1606 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT | |
| 1607 | {std::__cxx_atomic_notify_all(&__a_);} | |
| 1608 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT | |
| 1609 | {std::__cxx_atomic_notify_all(&__a_);} | |
| 1610 | ||
| 1611 | #if _LIBCPP_STD_VER > 17 | |
| 1612 | _LIBCPP_INLINE_VISIBILITY constexpr | |
| 1613 | __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} | |
| 1614 | #else | |
| 1615 | _LIBCPP_INLINE_VISIBILITY | |
| 1616 | __atomic_base() _NOEXCEPT = default; | |
| 1617 | #endif | |
| 1618 | ||
| 1619 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 1620 | __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} | |
| 1621 | ||
| 1622 | __atomic_base(const __atomic_base&) = delete; | |
| 1623 | }; | |
| 1624 | ||
| 1625 | #if defined(__cpp_lib_atomic_is_always_lock_free) | |
| 1626 | template <class _Tp, bool __b> | |
| 1627 | _LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; | |
| 1628 | #endif | |
| 1629 | ||
| 1630 | // atomic<Integral> | |
| 1631 | ||
| 1632 | template <class _Tp> | |
| 1633 | struct __atomic_base<_Tp, true> | |
| 1634 | : public __atomic_base<_Tp, false> | |
| 1635 | { | |
| 1636 | typedef __atomic_base<_Tp, false> __base; | |
| 1637 | ||
| 1638 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1639 | __atomic_base() _NOEXCEPT = default; | |
| 1640 | ||
| 1641 | _LIBCPP_INLINE_VISIBILITY | |
| 1642 | _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} | |
| 1643 | ||
| 1644 | _LIBCPP_INLINE_VISIBILITY | |
| 1645 | _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1646 | {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);} | |
| 1647 | _LIBCPP_INLINE_VISIBILITY | |
| 1648 | _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1649 | {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);} | |
| 1650 | _LIBCPP_INLINE_VISIBILITY | |
| 1651 | _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1652 | {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);} | |
| 1653 | _LIBCPP_INLINE_VISIBILITY | |
| 1654 | _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1655 | {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);} | |
| 1656 | _LIBCPP_INLINE_VISIBILITY | |
| 1657 | _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1658 | {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);} | |
| 1659 | _LIBCPP_INLINE_VISIBILITY | |
| 1660 | _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1661 | {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);} | |
| 1662 | _LIBCPP_INLINE_VISIBILITY | |
| 1663 | _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1664 | {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);} | |
| 1665 | _LIBCPP_INLINE_VISIBILITY | |
| 1666 | _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1667 | {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);} | |
| 1668 | _LIBCPP_INLINE_VISIBILITY | |
| 1669 | _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 1670 | {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);} | |
| 1671 | _LIBCPP_INLINE_VISIBILITY | |
| 1672 | _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 1673 | {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);} | |
| 1674 | ||
| 1675 | _LIBCPP_INLINE_VISIBILITY | |
| 1676 | _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} | |
| 1677 | _LIBCPP_INLINE_VISIBILITY | |
| 1678 | _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} | |
| 1679 | _LIBCPP_INLINE_VISIBILITY | |
| 1680 | _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} | |
| 1681 | _LIBCPP_INLINE_VISIBILITY | |
| 1682 | _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} | |
| 1683 | _LIBCPP_INLINE_VISIBILITY | |
| 1684 | _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} | |
| 1685 | _LIBCPP_INLINE_VISIBILITY | |
| 1686 | _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} | |
| 1687 | _LIBCPP_INLINE_VISIBILITY | |
| 1688 | _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} | |
| 1689 | _LIBCPP_INLINE_VISIBILITY | |
| 1690 | _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} | |
| 1691 | _LIBCPP_INLINE_VISIBILITY | |
| 1692 | _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 1693 | _LIBCPP_INLINE_VISIBILITY | |
| 1694 | _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 1695 | _LIBCPP_INLINE_VISIBILITY | |
| 1696 | _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 1697 | _LIBCPP_INLINE_VISIBILITY | |
| 1698 | _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 1699 | _LIBCPP_INLINE_VISIBILITY | |
| 1700 | _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} | |
| 1701 | _LIBCPP_INLINE_VISIBILITY | |
| 1702 | _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} | |
| 1703 | _LIBCPP_INLINE_VISIBILITY | |
| 1704 | _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} | |
| 1705 | _LIBCPP_INLINE_VISIBILITY | |
| 1706 | _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} | |
| 1707 | _LIBCPP_INLINE_VISIBILITY | |
| 1708 | _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} | |
| 1709 | _LIBCPP_INLINE_VISIBILITY | |
| 1710 | _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} | |
| 1711 | }; | |
| 1712 | ||
| 1713 | // atomic<T> | |
| 1714 | ||
| 1715 | template <class _Tp> | |
| 1716 | struct atomic | |
| 1717 | : public __atomic_base<_Tp> | |
| 1718 | { | |
| 1719 | typedef __atomic_base<_Tp> __base; | |
| 1720 | typedef _Tp value_type; | |
| 1721 | typedef value_type difference_type; | |
| 1722 | ||
| 1723 | #if _LIBCPP_STD_VER > 17 | |
| 1724 | _LIBCPP_INLINE_VISIBILITY | |
| 1725 | atomic() = default; | |
| 1726 | #else | |
| 1727 | _LIBCPP_INLINE_VISIBILITY | |
| 1728 | atomic() _NOEXCEPT = default; | |
| 1729 | #endif | |
| 1730 | ||
| 1731 | _LIBCPP_INLINE_VISIBILITY | |
| 1732 | _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} | |
| 1733 | ||
| 1734 | _LIBCPP_INLINE_VISIBILITY | |
| 1735 | _Tp operator=(_Tp __d) volatile _NOEXCEPT | |
| 1736 | {__base::store(__d); return __d;} | |
| 1737 | _LIBCPP_INLINE_VISIBILITY | |
| 1738 | _Tp operator=(_Tp __d) _NOEXCEPT | |
| 1739 | {__base::store(__d); return __d;} | |
| 1740 | ||
| 1741 | atomic& operator=(const atomic&) = delete; | |
| 1742 | atomic& operator=(const atomic&) volatile = delete; | |
| 1743 | }; | |
| 1744 | ||
| 1745 | // atomic<T*> | |
| 1746 | ||
| 1747 | template <class _Tp> | |
| 1748 | struct atomic<_Tp*> | |
| 1749 | : public __atomic_base<_Tp*> | |
| 1750 | { | |
| 1751 | typedef __atomic_base<_Tp*> __base; | |
| 1752 | typedef _Tp* value_type; | |
| 1753 | typedef ptrdiff_t difference_type; | |
| 1754 | ||
| 1755 | _LIBCPP_INLINE_VISIBILITY | |
| 1756 | atomic() _NOEXCEPT = default; | |
| 1757 | ||
| 1758 | _LIBCPP_INLINE_VISIBILITY | |
| 1759 | _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} | |
| 1760 | ||
| 1761 | _LIBCPP_INLINE_VISIBILITY | |
| 1762 | _Tp* operator=(_Tp* __d) volatile _NOEXCEPT | |
| 1763 | {__base::store(__d); return __d;} | |
| 1764 | _LIBCPP_INLINE_VISIBILITY | |
| 1765 | _Tp* operator=(_Tp* __d) _NOEXCEPT | |
| 1766 | {__base::store(__d); return __d;} | |
| 1767 | ||
| 1768 | _LIBCPP_INLINE_VISIBILITY | |
| 1769 | _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 1770 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 1771 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 1772 | return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m); | |
| 1773 | } | |
| 1774 | ||
| 1775 | _LIBCPP_INLINE_VISIBILITY | |
| 1776 | _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 1777 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 1778 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 1779 | return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m); | |
| 1780 | } | |
| 1781 | ||
| 1782 | _LIBCPP_INLINE_VISIBILITY | |
| 1783 | _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { | |
| 1784 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 1785 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 1786 | return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m); | |
| 1787 | } | |
| 1788 | ||
| 1789 | _LIBCPP_INLINE_VISIBILITY | |
| 1790 | _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { | |
| 1791 | // __atomic_fetch_add accepts function pointers, guard against them. | |
| 1792 | static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); | |
| 1793 | return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m); | |
| 1794 | } | |
| 1795 | ||
| 1796 | _LIBCPP_INLINE_VISIBILITY | |
| 1797 | _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} | |
| 1798 | _LIBCPP_INLINE_VISIBILITY | |
| 1799 | _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} | |
| 1800 | _LIBCPP_INLINE_VISIBILITY | |
| 1801 | _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} | |
| 1802 | _LIBCPP_INLINE_VISIBILITY | |
| 1803 | _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} | |
| 1804 | _LIBCPP_INLINE_VISIBILITY | |
| 1805 | _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} | |
| 1806 | _LIBCPP_INLINE_VISIBILITY | |
| 1807 | _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} | |
| 1808 | _LIBCPP_INLINE_VISIBILITY | |
| 1809 | _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} | |
| 1810 | _LIBCPP_INLINE_VISIBILITY | |
| 1811 | _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} | |
| 1812 | _LIBCPP_INLINE_VISIBILITY | |
| 1813 | _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 1814 | _LIBCPP_INLINE_VISIBILITY | |
| 1815 | _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} | |
| 1816 | _LIBCPP_INLINE_VISIBILITY | |
| 1817 | _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 1818 | _LIBCPP_INLINE_VISIBILITY | |
| 1819 | _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} | |
| 1820 | ||
| 1821 | atomic& operator=(const atomic&) = delete; | |
| 1822 | atomic& operator=(const atomic&) volatile = delete; | |
| 1823 | }; | |
| 1824 | ||
| 1825 | // atomic_is_lock_free | |
| 1826 | ||
| 1827 | template <class _Tp> | |
| 1828 | _LIBCPP_INLINE_VISIBILITY | |
| 1829 | bool | |
| 1830 | atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 1831 | { | |
| 1832 | return __o->is_lock_free(); | |
| 1833 | } | |
| 1834 | ||
| 1835 | template <class _Tp> | |
| 1836 | _LIBCPP_INLINE_VISIBILITY | |
| 1837 | bool | |
| 1838 | atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT | |
| 1839 | { | |
| 1840 | return __o->is_lock_free(); | |
| 1841 | } | |
| 1842 | ||
| 1843 | // atomic_init | |
| 1844 | ||
| 1845 | template <class _Tp> | |
| 1846 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY | |
| 1847 | void | |
| 1848 | atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1849 | { | |
| 1850 | std::__cxx_atomic_init(&__o->__a_, __d); | |
| 1851 | } | |
| 1852 | ||
| 1853 | template <class _Tp> | |
| 1854 | _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY | |
| 1855 | void | |
| 1856 | atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1857 | { | |
| 1858 | std::__cxx_atomic_init(&__o->__a_, __d); | |
| 1859 | } | |
| 1860 | ||
| 1861 | // atomic_store | |
| 1862 | ||
| 1863 | template <class _Tp> | |
| 1864 | _LIBCPP_INLINE_VISIBILITY | |
| 1865 | void | |
| 1866 | atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1867 | { | |
| 1868 | __o->store(__d); | |
| 1869 | } | |
| 1870 | ||
| 1871 | template <class _Tp> | |
| 1872 | _LIBCPP_INLINE_VISIBILITY | |
| 1873 | void | |
| 1874 | atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1875 | { | |
| 1876 | __o->store(__d); | |
| 1877 | } | |
| 1878 | ||
| 1879 | // atomic_store_explicit | |
| 1880 | ||
| 1881 | template <class _Tp> | |
| 1882 | _LIBCPP_INLINE_VISIBILITY | |
| 1883 | void | |
| 1884 | atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 1885 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 1886 | { | |
| 1887 | __o->store(__d, __m); | |
| 1888 | } | |
| 1889 | ||
| 1890 | template <class _Tp> | |
| 1891 | _LIBCPP_INLINE_VISIBILITY | |
| 1892 | void | |
| 1893 | atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 1894 | _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) | |
| 1895 | { | |
| 1896 | __o->store(__d, __m); | |
| 1897 | } | |
| 1898 | ||
| 1899 | // atomic_load | |
| 1900 | ||
| 1901 | template <class _Tp> | |
| 1902 | _LIBCPP_INLINE_VISIBILITY | |
| 1903 | _Tp | |
| 1904 | atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 1905 | { | |
| 1906 | return __o->load(); | |
| 1907 | } | |
| 1908 | ||
| 1909 | template <class _Tp> | |
| 1910 | _LIBCPP_INLINE_VISIBILITY | |
| 1911 | _Tp | |
| 1912 | atomic_load(const atomic<_Tp>* __o) _NOEXCEPT | |
| 1913 | { | |
| 1914 | return __o->load(); | |
| 1915 | } | |
| 1916 | ||
| 1917 | // atomic_load_explicit | |
| 1918 | ||
| 1919 | template <class _Tp> | |
| 1920 | _LIBCPP_INLINE_VISIBILITY | |
| 1921 | _Tp | |
| 1922 | atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT | |
| 1923 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 1924 | { | |
| 1925 | return __o->load(__m); | |
| 1926 | } | |
| 1927 | ||
| 1928 | template <class _Tp> | |
| 1929 | _LIBCPP_INLINE_VISIBILITY | |
| 1930 | _Tp | |
| 1931 | atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT | |
| 1932 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 1933 | { | |
| 1934 | return __o->load(__m); | |
| 1935 | } | |
| 1936 | ||
| 1937 | // atomic_exchange | |
| 1938 | ||
| 1939 | template <class _Tp> | |
| 1940 | _LIBCPP_INLINE_VISIBILITY | |
| 1941 | _Tp | |
| 1942 | atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1943 | { | |
| 1944 | return __o->exchange(__d); | |
| 1945 | } | |
| 1946 | ||
| 1947 | template <class _Tp> | |
| 1948 | _LIBCPP_INLINE_VISIBILITY | |
| 1949 | _Tp | |
| 1950 | atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1951 | { | |
| 1952 | return __o->exchange(__d); | |
| 1953 | } | |
| 1954 | ||
| 1955 | // atomic_exchange_explicit | |
| 1956 | ||
| 1957 | template <class _Tp> | |
| 1958 | _LIBCPP_INLINE_VISIBILITY | |
| 1959 | _Tp | |
| 1960 | atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 1961 | { | |
| 1962 | return __o->exchange(__d, __m); | |
| 1963 | } | |
| 1964 | ||
| 1965 | template <class _Tp> | |
| 1966 | _LIBCPP_INLINE_VISIBILITY | |
| 1967 | _Tp | |
| 1968 | atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT | |
| 1969 | { | |
| 1970 | return __o->exchange(__d, __m); | |
| 1971 | } | |
| 1972 | ||
| 1973 | // atomic_compare_exchange_weak | |
| 1974 | ||
| 1975 | template <class _Tp> | |
| 1976 | _LIBCPP_INLINE_VISIBILITY | |
| 1977 | bool | |
| 1978 | atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1979 | { | |
| 1980 | return __o->compare_exchange_weak(*__e, __d); | |
| 1981 | } | |
| 1982 | ||
| 1983 | template <class _Tp> | |
| 1984 | _LIBCPP_INLINE_VISIBILITY | |
| 1985 | bool | |
| 1986 | atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1987 | { | |
| 1988 | return __o->compare_exchange_weak(*__e, __d); | |
| 1989 | } | |
| 1990 | ||
| 1991 | // atomic_compare_exchange_strong | |
| 1992 | ||
| 1993 | template <class _Tp> | |
| 1994 | _LIBCPP_INLINE_VISIBILITY | |
| 1995 | bool | |
| 1996 | atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 1997 | { | |
| 1998 | return __o->compare_exchange_strong(*__e, __d); | |
| 1999 | } | |
| 2000 | ||
| 2001 | template <class _Tp> | |
| 2002 | _LIBCPP_INLINE_VISIBILITY | |
| 2003 | bool | |
| 2004 | atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT | |
| 2005 | { | |
| 2006 | return __o->compare_exchange_strong(*__e, __d); | |
| 2007 | } | |
| 2008 | ||
| 2009 | // atomic_compare_exchange_weak_explicit | |
| 2010 | ||
| 2011 | template <class _Tp> | |
| 2012 | _LIBCPP_INLINE_VISIBILITY | |
| 2013 | bool | |
| 2014 | atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, | |
| 2015 | typename atomic<_Tp>::value_type __d, | |
| 2016 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 2017 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 2018 | { | |
| 2019 | return __o->compare_exchange_weak(*__e, __d, __s, __f); | |
| 2020 | } | |
| 2021 | ||
| 2022 | template <class _Tp> | |
| 2023 | _LIBCPP_INLINE_VISIBILITY | |
| 2024 | bool | |
| 2025 | atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, | |
| 2026 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 2027 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 2028 | { | |
| 2029 | return __o->compare_exchange_weak(*__e, __d, __s, __f); | |
| 2030 | } | |
| 2031 | ||
| 2032 | // atomic_compare_exchange_strong_explicit | |
| 2033 | ||
| 2034 | template <class _Tp> | |
| 2035 | _LIBCPP_INLINE_VISIBILITY | |
| 2036 | bool | |
| 2037 | atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, | |
| 2038 | typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, | |
| 2039 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 2040 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 2041 | { | |
| 2042 | return __o->compare_exchange_strong(*__e, __d, __s, __f); | |
| 2043 | } | |
| 2044 | ||
| 2045 | template <class _Tp> | |
| 2046 | _LIBCPP_INLINE_VISIBILITY | |
| 2047 | bool | |
| 2048 | atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, | |
| 2049 | typename atomic<_Tp>::value_type __d, | |
| 2050 | memory_order __s, memory_order __f) _NOEXCEPT | |
| 2051 | _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) | |
| 2052 | { | |
| 2053 | return __o->compare_exchange_strong(*__e, __d, __s, __f); | |
| 2054 | } | |
| 2055 | ||
| 2056 | // atomic_wait | |
| 2057 | ||
| 2058 | template <class _Tp> | |
| 2059 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2060 | void atomic_wait(const volatile atomic<_Tp>* __o, | |
| 2061 | typename atomic<_Tp>::value_type __v) _NOEXCEPT | |
| 2062 | { | |
| 2063 | return __o->wait(__v); | |
| 2064 | } | |
| 2065 | ||
| 2066 | template <class _Tp> | |
| 2067 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2068 | void atomic_wait(const atomic<_Tp>* __o, | |
| 2069 | typename atomic<_Tp>::value_type __v) _NOEXCEPT | |
| 2070 | { | |
| 2071 | return __o->wait(__v); | |
| 2072 | } | |
| 2073 | ||
| 2074 | // atomic_wait_explicit | |
| 2075 | ||
| 2076 | template <class _Tp> | |
| 2077 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2078 | void atomic_wait_explicit(const volatile atomic<_Tp>* __o, | |
| 2079 | typename atomic<_Tp>::value_type __v, | |
| 2080 | memory_order __m) _NOEXCEPT | |
| 2081 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 2082 | { | |
| 2083 | return __o->wait(__v, __m); | |
| 2084 | } | |
| 2085 | ||
| 2086 | template <class _Tp> | |
| 2087 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2088 | void atomic_wait_explicit(const atomic<_Tp>* __o, | |
| 2089 | typename atomic<_Tp>::value_type __v, | |
| 2090 | memory_order __m) _NOEXCEPT | |
| 2091 | _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) | |
| 2092 | { | |
| 2093 | return __o->wait(__v, __m); | |
| 2094 | } | |
| 2095 | ||
| 2096 | // atomic_notify_one | |
| 2097 | ||
| 2098 | template <class _Tp> | |
| 2099 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2100 | void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 2101 | { | |
| 2102 | __o->notify_one(); | |
| 2103 | } | |
| 2104 | template <class _Tp> | |
| 2105 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2106 | void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT | |
| 2107 | { | |
| 2108 | __o->notify_one(); | |
| 2109 | } | |
| 2110 | ||
| 2111 | // atomic_notify_all | |
| 2112 | ||
| 2113 | template <class _Tp> | |
| 2114 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2115 | void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT | |
| 2116 | { | |
| 2117 | __o->notify_all(); | |
| 2118 | } | |
| 2119 | template <class _Tp> | |
| 2120 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2121 | void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT | |
| 2122 | { | |
| 2123 | __o->notify_all(); | |
| 2124 | } | |
| 2125 | ||
| 2126 | // atomic_fetch_add | |
| 2127 | ||
| 2128 | template <class _Tp> | |
| 2129 | _LIBCPP_INLINE_VISIBILITY | |
| 2130 | _Tp | |
| 2131 | atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 2132 | { | |
| 2133 | return __o->fetch_add(__op); | |
| 2134 | } | |
| 2135 | ||
| 2136 | template <class _Tp> | |
| 2137 | _LIBCPP_INLINE_VISIBILITY | |
| 2138 | _Tp | |
| 2139 | atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 2140 | { | |
| 2141 | return __o->fetch_add(__op); | |
| 2142 | } | |
| 2143 | ||
| 2144 | // atomic_fetch_add_explicit | |
| 2145 | ||
| 2146 | template <class _Tp> | |
| 2147 | _LIBCPP_INLINE_VISIBILITY | |
| 2148 | _Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 2149 | { | |
| 2150 | return __o->fetch_add(__op, __m); | |
| 2151 | } | |
| 2152 | ||
| 2153 | template <class _Tp> | |
| 2154 | _LIBCPP_INLINE_VISIBILITY | |
| 2155 | _Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 2156 | { | |
| 2157 | return __o->fetch_add(__op, __m); | |
| 2158 | } | |
| 2159 | ||
| 2160 | // atomic_fetch_sub | |
| 2161 | ||
| 2162 | template <class _Tp> | |
| 2163 | _LIBCPP_INLINE_VISIBILITY | |
| 2164 | _Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 2165 | { | |
| 2166 | return __o->fetch_sub(__op); | |
| 2167 | } | |
| 2168 | ||
| 2169 | template <class _Tp> | |
| 2170 | _LIBCPP_INLINE_VISIBILITY | |
| 2171 | _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT | |
| 2172 | { | |
| 2173 | return __o->fetch_sub(__op); | |
| 2174 | } | |
| 2175 | ||
| 2176 | // atomic_fetch_sub_explicit | |
| 2177 | ||
| 2178 | template <class _Tp> | |
| 2179 | _LIBCPP_INLINE_VISIBILITY | |
| 2180 | _Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 2181 | { | |
| 2182 | return __o->fetch_sub(__op, __m); | |
| 2183 | } | |
| 2184 | ||
| 2185 | template <class _Tp> | |
| 2186 | _LIBCPP_INLINE_VISIBILITY | |
| 2187 | _Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT | |
| 2188 | { | |
| 2189 | return __o->fetch_sub(__op, __m); | |
| 2190 | } | |
| 2191 | ||
| 2192 | // atomic_fetch_and | |
| 2193 | ||
| 2194 | template <class _Tp> | |
| 2195 | _LIBCPP_INLINE_VISIBILITY | |
| 2196 | typename enable_if | |
| 2197 | < | |
| 2198 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2199 | _Tp | |
| 2200 | >::type | |
| 2201 | atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2202 | { | |
| 2203 | return __o->fetch_and(__op); | |
| 2204 | } | |
| 2205 | ||
| 2206 | template <class _Tp> | |
| 2207 | _LIBCPP_INLINE_VISIBILITY | |
| 2208 | typename enable_if | |
| 2209 | < | |
| 2210 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2211 | _Tp | |
| 2212 | >::type | |
| 2213 | atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2214 | { | |
| 2215 | return __o->fetch_and(__op); | |
| 2216 | } | |
| 2217 | ||
| 2218 | // atomic_fetch_and_explicit | |
| 2219 | ||
| 2220 | template <class _Tp> | |
| 2221 | _LIBCPP_INLINE_VISIBILITY | |
| 2222 | typename enable_if | |
| 2223 | < | |
| 2224 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2225 | _Tp | |
| 2226 | >::type | |
| 2227 | atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2228 | { | |
| 2229 | return __o->fetch_and(__op, __m); | |
| 2230 | } | |
| 2231 | ||
| 2232 | template <class _Tp> | |
| 2233 | _LIBCPP_INLINE_VISIBILITY | |
| 2234 | typename enable_if | |
| 2235 | < | |
| 2236 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2237 | _Tp | |
| 2238 | >::type | |
| 2239 | atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2240 | { | |
| 2241 | return __o->fetch_and(__op, __m); | |
| 2242 | } | |
| 2243 | ||
| 2244 | // atomic_fetch_or | |
| 2245 | ||
| 2246 | template <class _Tp> | |
| 2247 | _LIBCPP_INLINE_VISIBILITY | |
| 2248 | typename enable_if | |
| 2249 | < | |
| 2250 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2251 | _Tp | |
| 2252 | >::type | |
| 2253 | atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2254 | { | |
| 2255 | return __o->fetch_or(__op); | |
| 2256 | } | |
| 2257 | ||
| 2258 | template <class _Tp> | |
| 2259 | _LIBCPP_INLINE_VISIBILITY | |
| 2260 | typename enable_if | |
| 2261 | < | |
| 2262 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2263 | _Tp | |
| 2264 | >::type | |
| 2265 | atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2266 | { | |
| 2267 | return __o->fetch_or(__op); | |
| 2268 | } | |
| 2269 | ||
| 2270 | // atomic_fetch_or_explicit | |
| 2271 | ||
| 2272 | template <class _Tp> | |
| 2273 | _LIBCPP_INLINE_VISIBILITY | |
| 2274 | typename enable_if | |
| 2275 | < | |
| 2276 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2277 | _Tp | |
| 2278 | >::type | |
| 2279 | atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2280 | { | |
| 2281 | return __o->fetch_or(__op, __m); | |
| 2282 | } | |
| 2283 | ||
| 2284 | template <class _Tp> | |
| 2285 | _LIBCPP_INLINE_VISIBILITY | |
| 2286 | typename enable_if | |
| 2287 | < | |
| 2288 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2289 | _Tp | |
| 2290 | >::type | |
| 2291 | atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2292 | { | |
| 2293 | return __o->fetch_or(__op, __m); | |
| 2294 | } | |
| 2295 | ||
| 2296 | // atomic_fetch_xor | |
| 2297 | ||
| 2298 | template <class _Tp> | |
| 2299 | _LIBCPP_INLINE_VISIBILITY | |
| 2300 | typename enable_if | |
| 2301 | < | |
| 2302 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2303 | _Tp | |
| 2304 | >::type | |
| 2305 | atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2306 | { | |
| 2307 | return __o->fetch_xor(__op); | |
| 2308 | } | |
| 2309 | ||
| 2310 | template <class _Tp> | |
| 2311 | _LIBCPP_INLINE_VISIBILITY | |
| 2312 | typename enable_if | |
| 2313 | < | |
| 2314 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2315 | _Tp | |
| 2316 | >::type | |
| 2317 | atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT | |
| 2318 | { | |
| 2319 | return __o->fetch_xor(__op); | |
| 2320 | } | |
| 2321 | ||
| 2322 | // atomic_fetch_xor_explicit | |
| 2323 | ||
| 2324 | template <class _Tp> | |
| 2325 | _LIBCPP_INLINE_VISIBILITY | |
| 2326 | typename enable_if | |
| 2327 | < | |
| 2328 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2329 | _Tp | |
| 2330 | >::type | |
| 2331 | atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2332 | { | |
| 2333 | return __o->fetch_xor(__op, __m); | |
| 2334 | } | |
| 2335 | ||
| 2336 | template <class _Tp> | |
| 2337 | _LIBCPP_INLINE_VISIBILITY | |
| 2338 | typename enable_if | |
| 2339 | < | |
| 2340 | is_integral<_Tp>::value && !is_same<_Tp, bool>::value, | |
| 2341 | _Tp | |
| 2342 | >::type | |
| 2343 | atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT | |
| 2344 | { | |
| 2345 | return __o->fetch_xor(__op, __m); | |
| 2346 | } | |
| 2347 | ||
| 2348 | // flag type and operations | |
| 2349 | ||
| 2350 | typedef struct atomic_flag | |
| 2351 | { | |
| 2352 | __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; | |
| 2353 | ||
| 2354 | _LIBCPP_INLINE_VISIBILITY | |
| 2355 | bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 2356 | {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} | |
| 2357 | _LIBCPP_INLINE_VISIBILITY | |
| 2358 | bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 2359 | {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} | |
| 2360 | ||
| 2361 | _LIBCPP_INLINE_VISIBILITY | |
| 2362 | bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 2363 | {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} | |
| 2364 | _LIBCPP_INLINE_VISIBILITY | |
| 2365 | bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 2366 | {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} | |
| 2367 | _LIBCPP_INLINE_VISIBILITY | |
| 2368 | void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT | |
| 2369 | {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} | |
| 2370 | _LIBCPP_INLINE_VISIBILITY | |
| 2371 | void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT | |
| 2372 | {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} | |
| 2373 | ||
| 2374 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2375 | void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT | |
| 2376 | {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} | |
| 2377 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2378 | void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT | |
| 2379 | {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} | |
| 2380 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2381 | void notify_one() volatile _NOEXCEPT | |
| 2382 | {__cxx_atomic_notify_one(&__a_);} | |
| 2383 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2384 | void notify_one() _NOEXCEPT | |
| 2385 | {__cxx_atomic_notify_one(&__a_);} | |
| 2386 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2387 | void notify_all() volatile _NOEXCEPT | |
| 2388 | {__cxx_atomic_notify_all(&__a_);} | |
| 2389 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 2390 | void notify_all() _NOEXCEPT | |
| 2391 | {__cxx_atomic_notify_all(&__a_);} | |
| 2392 | ||
| 2393 | #if _LIBCPP_STD_VER > 17 | |
| 2394 | _LIBCPP_INLINE_VISIBILITY constexpr | |
| 2395 | atomic_flag() _NOEXCEPT : __a_(false) {} | |
| 2396 | #else | |
| 2397 | _LIBCPP_INLINE_VISIBILITY | |
| 2398 | atomic_flag() _NOEXCEPT = default; | |
| 2399 | #endif | |
| 2400 | ||
| 2401 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR | |
| 2402 | atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION | |
| 2403 | ||
| 2404 | atomic_flag(const atomic_flag&) = delete; | |
| 2405 | atomic_flag& operator=(const atomic_flag&) = delete; | |
| 2406 | atomic_flag& operator=(const atomic_flag&) volatile = delete; | |
| 2407 | ||
| 2408 | } atomic_flag; | |
| 2409 | ||
| 2410 | ||
| 2411 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2412 | bool | |
| 2413 | atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT | |
| 2414 | { | |
| 2415 | return __o->test(); | |
| 2416 | } | |
| 2417 | ||
| 2418 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2419 | bool | |
| 2420 | atomic_flag_test(const atomic_flag* __o) _NOEXCEPT | |
| 2421 | { | |
| 2422 | return __o->test(); | |
| 2423 | } | |
| 2424 | ||
| 2425 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2426 | bool | |
| 2427 | atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2428 | { | |
| 2429 | return __o->test(__m); | |
| 2430 | } | |
| 2431 | ||
| 2432 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2433 | bool | |
| 2434 | atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2435 | { | |
| 2436 | return __o->test(__m); | |
| 2437 | } | |
| 2438 | ||
| 2439 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2440 | bool | |
| 2441 | atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT | |
| 2442 | { | |
| 2443 | return __o->test_and_set(); | |
| 2444 | } | |
| 2445 | ||
| 2446 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2447 | bool | |
| 2448 | atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT | |
| 2449 | { | |
| 2450 | return __o->test_and_set(); | |
| 2451 | } | |
| 2452 | ||
| 2453 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2454 | bool | |
| 2455 | atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2456 | { | |
| 2457 | return __o->test_and_set(__m); | |
| 2458 | } | |
| 2459 | ||
| 2460 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2461 | bool | |
| 2462 | atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2463 | { | |
| 2464 | return __o->test_and_set(__m); | |
| 2465 | } | |
| 2466 | ||
| 2467 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2468 | void | |
| 2469 | atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT | |
| 2470 | { | |
| 2471 | __o->clear(); | |
| 2472 | } | |
| 2473 | ||
| 2474 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2475 | void | |
| 2476 | atomic_flag_clear(atomic_flag* __o) _NOEXCEPT | |
| 2477 | { | |
| 2478 | __o->clear(); | |
| 2479 | } | |
| 2480 | ||
| 2481 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2482 | void | |
| 2483 | atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2484 | { | |
| 2485 | __o->clear(__m); | |
| 2486 | } | |
| 2487 | ||
| 2488 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2489 | void | |
| 2490 | atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT | |
| 2491 | { | |
| 2492 | __o->clear(__m); | |
| 2493 | } | |
| 2494 | ||
| 2495 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2496 | void | |
| 2497 | atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT | |
| 2498 | { | |
| 2499 | __o->wait(__v); | |
| 2500 | } | |
| 2501 | ||
| 2502 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2503 | void | |
| 2504 | atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT | |
| 2505 | { | |
| 2506 | __o->wait(__v); | |
| 2507 | } | |
| 2508 | ||
| 2509 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2510 | void | |
| 2511 | atomic_flag_wait_explicit(const volatile atomic_flag* __o, | |
| 2512 | bool __v, memory_order __m) _NOEXCEPT | |
| 2513 | { | |
| 2514 | __o->wait(__v, __m); | |
| 2515 | } | |
| 2516 | ||
| 2517 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2518 | void | |
| 2519 | atomic_flag_wait_explicit(const atomic_flag* __o, | |
| 2520 | bool __v, memory_order __m) _NOEXCEPT | |
| 2521 | { | |
| 2522 | __o->wait(__v, __m); | |
| 2523 | } | |
| 2524 | ||
| 2525 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2526 | void | |
| 2527 | atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT | |
| 2528 | { | |
| 2529 | __o->notify_one(); | |
| 2530 | } | |
| 2531 | ||
| 2532 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2533 | void | |
| 2534 | atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT | |
| 2535 | { | |
| 2536 | __o->notify_one(); | |
| 2537 | } | |
| 2538 | ||
| 2539 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2540 | void | |
| 2541 | atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT | |
| 2542 | { | |
| 2543 | __o->notify_all(); | |
| 2544 | } | |
| 2545 | ||
| 2546 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC | |
| 2547 | void | |
| 2548 | atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT | |
| 2549 | { | |
| 2550 | __o->notify_all(); | |
| 2551 | } | |
| 2552 | ||
| 2553 | // fences | |
| 2554 | ||
| 2555 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2556 | void | |
| 2557 | atomic_thread_fence(memory_order __m) _NOEXCEPT | |
| 2558 | { | |
| 2559 | __cxx_atomic_thread_fence(__m); | |
| 2560 | } | |
| 2561 | ||
| 2562 | inline _LIBCPP_INLINE_VISIBILITY | |
| 2563 | void | |
| 2564 | atomic_signal_fence(memory_order __m) _NOEXCEPT | |
| 2565 | { | |
| 2566 | __cxx_atomic_signal_fence(__m); | |
| 2567 | } | |
| 2568 | ||
| 2569 | // Atomics for standard typedef types | |
| 2570 | ||
| 2571 | typedef atomic<bool> atomic_bool; | |
| 2572 | typedef atomic<char> atomic_char; | |
| 2573 | typedef atomic<signed char> atomic_schar; | |
| 2574 | typedef atomic<unsigned char> atomic_uchar; | |
| 2575 | typedef atomic<short> atomic_short; | |
| 2576 | typedef atomic<unsigned short> atomic_ushort; | |
| 2577 | typedef atomic<int> atomic_int; | |
| 2578 | typedef atomic<unsigned int> atomic_uint; | |
| 2579 | typedef atomic<long> atomic_long; | |
| 2580 | typedef atomic<unsigned long> atomic_ulong; | |
| 2581 | typedef atomic<long long> atomic_llong; | |
| 2582 | typedef atomic<unsigned long long> atomic_ullong; | |
| 2583 | #ifndef _LIBCPP_HAS_NO_CHAR8_T | |
| 2584 | typedef atomic<char8_t> atomic_char8_t; | |
| 2585 | #endif | |
| 2586 | typedef atomic<char16_t> atomic_char16_t; | |
| 2587 | typedef atomic<char32_t> atomic_char32_t; | |
| 2588 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 2589 | typedef atomic<wchar_t> atomic_wchar_t; | |
| 2590 | #endif | |
| 2591 | ||
| 2592 | typedef atomic<int_least8_t> atomic_int_least8_t; | |
| 2593 | typedef atomic<uint_least8_t> atomic_uint_least8_t; | |
| 2594 | typedef atomic<int_least16_t> atomic_int_least16_t; | |
| 2595 | typedef atomic<uint_least16_t> atomic_uint_least16_t; | |
| 2596 | typedef atomic<int_least32_t> atomic_int_least32_t; | |
| 2597 | typedef atomic<uint_least32_t> atomic_uint_least32_t; | |
| 2598 | typedef atomic<int_least64_t> atomic_int_least64_t; | |
| 2599 | typedef atomic<uint_least64_t> atomic_uint_least64_t; | |
| 2600 | ||
| 2601 | typedef atomic<int_fast8_t> atomic_int_fast8_t; | |
| 2602 | typedef atomic<uint_fast8_t> atomic_uint_fast8_t; | |
| 2603 | typedef atomic<int_fast16_t> atomic_int_fast16_t; | |
| 2604 | typedef atomic<uint_fast16_t> atomic_uint_fast16_t; | |
| 2605 | typedef atomic<int_fast32_t> atomic_int_fast32_t; | |
| 2606 | typedef atomic<uint_fast32_t> atomic_uint_fast32_t; | |
| 2607 | typedef atomic<int_fast64_t> atomic_int_fast64_t; | |
| 2608 | typedef atomic<uint_fast64_t> atomic_uint_fast64_t; | |
| 2609 | ||
| 2610 | typedef atomic< int8_t> atomic_int8_t; | |
| 2611 | typedef atomic<uint8_t> atomic_uint8_t; | |
| 2612 | typedef atomic< int16_t> atomic_int16_t; | |
| 2613 | typedef atomic<uint16_t> atomic_uint16_t; | |
| 2614 | typedef atomic< int32_t> atomic_int32_t; | |
| 2615 | typedef atomic<uint32_t> atomic_uint32_t; | |
| 2616 | typedef atomic< int64_t> atomic_int64_t; | |
| 2617 | typedef atomic<uint64_t> atomic_uint64_t; | |
| 2618 | ||
| 2619 | typedef atomic<intptr_t> atomic_intptr_t; | |
| 2620 | typedef atomic<uintptr_t> atomic_uintptr_t; | |
| 2621 | typedef atomic<size_t> atomic_size_t; | |
| 2622 | typedef atomic<ptrdiff_t> atomic_ptrdiff_t; | |
| 2623 | typedef atomic<intmax_t> atomic_intmax_t; | |
| 2624 | typedef atomic<uintmax_t> atomic_uintmax_t; | |
| 2625 | ||
| 2626 | // atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type | |
| 2627 | ||
| 2628 | #ifdef __cpp_lib_atomic_is_always_lock_free | |
| 2629 | # define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value | |
| 2630 | #else | |
| 2631 | # define _LIBCPP_CONTENTION_LOCK_FREE false | |
| 2632 | #endif | |
| 2633 | ||
| 2634 | #if ATOMIC_LLONG_LOCK_FREE == 2 | |
| 2635 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long> __libcpp_signed_lock_free; | |
| 2636 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long> __libcpp_unsigned_lock_free; | |
| 2637 | #elif ATOMIC_INT_LOCK_FREE == 2 | |
| 2638 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int> __libcpp_signed_lock_free; | |
| 2639 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int> __libcpp_unsigned_lock_free; | |
| 2640 | #elif ATOMIC_SHORT_LOCK_FREE == 2 | |
| 2641 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short> __libcpp_signed_lock_free; | |
| 2642 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short> __libcpp_unsigned_lock_free; | |
| 2643 | #elif ATOMIC_CHAR_LOCK_FREE == 2 | |
| 2644 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char> __libcpp_signed_lock_free; | |
| 2645 | typedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char> __libcpp_unsigned_lock_free; | |
| 2646 | #else | |
| 2647 | // No signed/unsigned lock-free types | |
| 2648 | #define _LIBCPP_NO_LOCK_FREE_TYPES | |
| 2649 | #endif | |
| 2650 | ||
| 2651 | #if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) | |
| 2652 | typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free; | |
| 2653 | typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free; | |
| 547 | #ifdef kill_dependency | |
| 548 | # error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23. | |
| 2654 | 549 | #endif |
| 2655 | 550 | |
| 2656 | #define ATOMIC_FLAG_INIT {false} | |
| 2657 | #define ATOMIC_VAR_INIT(__v) {__v} | |
| 2658 | ||
| 2659 | #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) | |
| 2660 | # if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400 | |
| 2661 | # pragma clang deprecated(ATOMIC_VAR_INIT) | |
| 2662 | # endif | |
| 2663 | #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) | |
| 2664 | ||
| 2665 | _LIBCPP_END_NAMESPACE_STD | |
| 2666 | ||
| 2667 | 551 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 2668 | 552 | # include <cmath> |
| 2669 | 553 | # include <compare> |
| 554 | # include <cstring> | |
| 2670 | 555 | # include <type_traits> |
| 2671 | 556 | #endif |
| 2672 | 557 |
lib/libcxx/include/barrier+33-8| ... | ... | @@ -46,13 +46,18 @@ namespace std |
| 46 | 46 | */ |
| 47 | 47 | |
| 48 | 48 | #include <__assert> // all public C++ headers provide the assertion handler |
| 49 | #include <__atomic/atomic_base.h> | |
| 50 | #include <__atomic/memory_order.h> | |
| 49 | 51 | #include <__availability> |
| 50 | 52 | #include <__config> |
| 51 | 53 | #include <__memory/unique_ptr.h> |
| 54 | #include <__thread/poll_with_backoff.h> | |
| 52 | 55 | #include <__thread/timed_backoff_policy.h> |
| 53 | 56 | #include <__utility/move.h> |
| 54 | #include <atomic> | |
| 57 | #include <cstddef> | |
| 58 | #include <cstdint> | |
| 55 | 59 | #include <limits> |
| 60 | #include <version> | |
| 56 | 61 | |
| 57 | 62 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 58 | 63 | # pragma GCC system_header |
| ... | ... | @@ -119,7 +124,7 @@ class __barrier_base { |
| 119 | 124 | public: |
| 120 | 125 | using arrival_token = __barrier_phase_t; |
| 121 | 126 | |
| 122 | static constexpr ptrdiff_t max() noexcept { | |
| 127 | static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { | |
| 123 | 128 | return numeric_limits<ptrdiff_t>::max(); |
| 124 | 129 | } |
| 125 | 130 | |
| ... | ... | @@ -130,9 +135,12 @@ public: |
| 130 | 135 | __expected_adjustment_(0), __completion_(std::move(__completion)), __phase_(0) |
| 131 | 136 | { |
| 132 | 137 | } |
| 133 | [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 138 | [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 134 | 139 | arrival_token arrive(ptrdiff_t __update) |
| 135 | 140 | { |
| 141 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 142 | __update <= __expected_, "update is greater than the expected count for the current barrier phase"); | |
| 143 | ||
| 136 | 144 | auto const __old_phase = __phase_.load(memory_order_relaxed); |
| 137 | 145 | for(; __update; --__update) |
| 138 | 146 | if(__arrive_barrier_algorithm_base(__base_.get(), __old_phase)) { |
| ... | ... | @@ -200,7 +208,11 @@ public: |
| 200 | 208 | auto const __old_phase = __phase.load(memory_order_relaxed); |
| 201 | 209 | auto const __result = __arrived.fetch_sub(update, memory_order_acq_rel) - update; |
| 202 | 210 | auto const new_expected = __expected.load(memory_order_relaxed); |
| 203 | if(0 == __result) { | |
| 211 | ||
| 212 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 213 | update <= new_expected, "update is greater than the expected count for the current barrier phase"); | |
| 214 | ||
| 215 | if (0 == __result) { | |
| 204 | 216 | __completion(); |
| 205 | 217 | __arrived.store(new_expected, memory_order_relaxed); |
| 206 | 218 | __phase.store(!__old_phase, memory_order_release); |
| ... | ... | @@ -256,7 +268,11 @@ public: |
| 256 | 268 | { |
| 257 | 269 | auto const __inc = __arrived_unit * update; |
| 258 | 270 | auto const __old = __phase_arrived_expected.fetch_add(__inc, memory_order_acq_rel); |
| 259 | if((__old ^ (__old + __inc)) & __phase_bit) { | |
| 271 | ||
| 272 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 273 | update <= __old, "update is greater than the expected count for the current barrier phase"); | |
| 274 | ||
| 275 | if ((__old ^ (__old + __inc)) & __phase_bit) { | |
| 260 | 276 | __phase_arrived_expected.fetch_add((__old & __expected_mask) << 32, memory_order_relaxed); |
| 261 | 277 | __phase_arrived_expected.notify_all(); |
| 262 | 278 | } |
| ... | ... | @@ -288,21 +304,29 @@ class barrier { |
| 288 | 304 | public: |
| 289 | 305 | using arrival_token = typename __barrier_base<_CompletionF>::arrival_token; |
| 290 | 306 | |
| 291 | static constexpr ptrdiff_t max() noexcept { | |
| 307 | static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { | |
| 292 | 308 | return __barrier_base<_CompletionF>::max(); |
| 293 | 309 | } |
| 294 | 310 | |
| 295 | 311 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 296 | barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF()) | |
| 312 | explicit barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF()) | |
| 297 | 313 | : __b_(__count, _VSTD::move(__completion)) { |
| 314 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 315 | __count >= 0, | |
| 316 | "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with a negative value"); | |
| 317 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 318 | __count <= max(), | |
| 319 | "barrier::barrier(ptrdiff_t, CompletionFunction): barrier cannot be initialized with " | |
| 320 | "a value greater than max()"); | |
| 298 | 321 | } |
| 299 | 322 | |
| 300 | 323 | barrier(barrier const&) = delete; |
| 301 | 324 | barrier& operator=(barrier const&) = delete; |
| 302 | 325 | |
| 303 | [[nodiscard]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 326 | [[__nodiscard__]] _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY | |
| 304 | 327 | arrival_token arrive(ptrdiff_t __update = 1) |
| 305 | 328 | { |
| 329 | _LIBCPP_ASSERT_UNCATEGORIZED(__update > 0, "barrier:arrive must be called with a value greater than 0"); | |
| 306 | 330 | return __b_.arrive(__update); |
| 307 | 331 | } |
| 308 | 332 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -329,6 +353,7 @@ _LIBCPP_END_NAMESPACE_STD |
| 329 | 353 | _LIBCPP_POP_MACROS |
| 330 | 354 | |
| 331 | 355 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 356 | # include <atomic> | |
| 332 | 357 | # include <concepts> |
| 333 | 358 | # include <iterator> |
| 334 | 359 | # include <memory> |
lib/libcxx/include/bit+1| ... | ... | @@ -83,6 +83,7 @@ namespace std { |
| 83 | 83 | #endif |
| 84 | 84 | |
| 85 | 85 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 86 | # include <cstdlib> | |
| 86 | 87 | # include <iosfwd> |
| 87 | 88 | # include <limits> |
| 88 | 89 | # include <type_traits> |
lib/libcxx/include/bitset+54-65| ... | ... | @@ -79,7 +79,7 @@ public: |
| 79 | 79 | size_t count() const noexcept; // constexpr since C++23 |
| 80 | 80 | constexpr size_t size() const noexcept; // constexpr since C++23 |
| 81 | 81 | bool operator==(const bitset& rhs) const noexcept; // constexpr since C++23 |
| 82 | bool operator!=(const bitset& rhs) const noexcept; // constexpr since C++23 | |
| 82 | bool operator!=(const bitset& rhs) const noexcept; // removed in C++20 | |
| 83 | 83 | bool test(size_t pos) const; // constexpr since C++23 |
| 84 | 84 | bool all() const noexcept; // constexpr since C++23 |
| 85 | 85 | bool any() const noexcept; // constexpr since C++23 |
| ... | ... | @@ -122,6 +122,7 @@ template <size_t N> struct hash<std::bitset<N>>; |
| 122 | 122 | #include <climits> |
| 123 | 123 | #include <cstddef> |
| 124 | 124 | #include <stdexcept> |
| 125 | #include <string_view> | |
| 125 | 126 | #include <version> |
| 126 | 127 | |
| 127 | 128 | // standard-mandated includes |
| ... | ... | @@ -691,18 +692,30 @@ public: |
| 691 | 692 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {} |
| 692 | 693 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 693 | 694 | bitset(unsigned long long __v) _NOEXCEPT : base(__v) {} |
| 694 | template<class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> > | |
| 695 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 696 | explicit bitset(const _CharT* __str, | |
| 697 | typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos, | |
| 698 | _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); | |
| 699 | template<class _CharT, class _Traits, class _Allocator> | |
| 700 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 701 | explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, | |
| 702 | typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0, | |
| 703 | typename basic_string<_CharT,_Traits,_Allocator>::size_type __n = | |
| 704 | (basic_string<_CharT,_Traits,_Allocator>::npos), | |
| 705 | _CharT __zero = _CharT('0'), _CharT __one = _CharT('1')); | |
| 695 | template <class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> > | |
| 696 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset( | |
| 697 | const _CharT* __str, | |
| 698 | typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos, | |
| 699 | _CharT __zero = _CharT('0'), | |
| 700 | _CharT __one = _CharT('1')) { | |
| 701 | ||
| 702 | size_t __rlen = std::min(__n, char_traits<_CharT>::length(__str)); | |
| 703 | __init_from_string_view(basic_string_view<_CharT>(__str, __rlen), __zero, __one); | |
| 704 | } | |
| 705 | template <class _CharT, class _Traits, class _Allocator> | |
| 706 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset( | |
| 707 | const basic_string<_CharT, _Traits, _Allocator>& __str, | |
| 708 | typename basic_string<_CharT, _Traits, _Allocator>::size_type __pos = 0, | |
| 709 | typename basic_string<_CharT, _Traits, _Allocator>::size_type __n = | |
| 710 | basic_string<_CharT, _Traits, _Allocator>::npos, | |
| 711 | _CharT __zero = _CharT('0'), | |
| 712 | _CharT __one = _CharT('1')) { | |
| 713 | if (__pos > __str.size()) | |
| 714 | std::__throw_out_of_range("bitset string pos out of range"); | |
| 715 | ||
| 716 | size_t __rlen = std::min(__n, __str.size() - __pos); | |
| 717 | __init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one); | |
| 718 | } | |
| 706 | 719 | |
| 707 | 720 | // 23.3.5.2 bitset operations: |
| 708 | 721 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| ... | ... | @@ -761,8 +774,10 @@ public: |
| 761 | 774 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;} |
| 762 | 775 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| 763 | 776 | bool operator==(const bitset& __rhs) const _NOEXCEPT; |
| 764 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 777 | #if _LIBCPP_STD_VER <= 17 | |
| 778 | _LIBCPP_INLINE_VISIBILITY | |
| 765 | 779 | bool operator!=(const bitset& __rhs) const _NOEXCEPT; |
| 780 | #endif | |
| 766 | 781 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| 767 | 782 | bool test(size_t __pos) const; |
| 768 | 783 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| ... | ... | @@ -776,6 +791,22 @@ public: |
| 776 | 791 | bitset operator>>(size_t __pos) const _NOEXCEPT; |
| 777 | 792 | |
| 778 | 793 | private: |
| 794 | template <class _CharT, class _Traits> | |
| 795 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void | |
| 796 | __init_from_string_view(basic_string_view<_CharT, _Traits> __str, _CharT __zero, _CharT __one) { | |
| 797 | ||
| 798 | for (size_t __i = 0; __i < __str.size(); ++__i) | |
| 799 | if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one)) | |
| 800 | std::__throw_invalid_argument("bitset string ctor has invalid argument"); | |
| 801 | ||
| 802 | size_t __mp = std::min(__str.size(), _Size); | |
| 803 | size_t __i = 0; | |
| 804 | for (; __i < __mp; ++__i) { | |
| 805 | _CharT __c = __str[__mp - 1 - __i]; | |
| 806 | (*this)[__i] = _Traits::eq(__c, __one); | |
| 807 | } | |
| 808 | std::fill(base::__make_iter(__i), base::__make_iter(_Size), false); | |
| 809 | } | |
| 779 | 810 | |
| 780 | 811 | _LIBCPP_INLINE_VISIBILITY |
| 781 | 812 | size_t __hash_code() const _NOEXCEPT {return base::__hash_code();} |
| ... | ... | @@ -783,54 +814,6 @@ private: |
| 783 | 814 | friend struct hash<bitset>; |
| 784 | 815 | }; |
| 785 | 816 | |
| 786 | template <size_t _Size> | |
| 787 | template<class _CharT, class> | |
| 788 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 789 | bitset<_Size>::bitset(const _CharT* __str, | |
| 790 | typename basic_string<_CharT>::size_type __n, | |
| 791 | _CharT __zero, _CharT __one) | |
| 792 | { | |
| 793 | size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str)); | |
| 794 | for (size_t __i = 0; __i < __rlen; ++__i) | |
| 795 | if (__str[__i] != __zero && __str[__i] != __one) | |
| 796 | __throw_invalid_argument("bitset string ctor has invalid argument"); | |
| 797 | ||
| 798 | size_t _Mp = _VSTD::min(__rlen, _Size); | |
| 799 | size_t __i = 0; | |
| 800 | for (; __i < _Mp; ++__i) | |
| 801 | { | |
| 802 | _CharT __c = __str[_Mp - 1 - __i]; | |
| 803 | (*this)[__i] = (__c == __one); | |
| 804 | } | |
| 805 | _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); | |
| 806 | } | |
| 807 | ||
| 808 | template <size_t _Size> | |
| 809 | template<class _CharT, class _Traits, class _Allocator> | |
| 810 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 811 | bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str, | |
| 812 | typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos, | |
| 813 | typename basic_string<_CharT,_Traits,_Allocator>::size_type __n, | |
| 814 | _CharT __zero, _CharT __one) | |
| 815 | { | |
| 816 | if (__pos > __str.size()) | |
| 817 | __throw_out_of_range("bitset string pos out of range"); | |
| 818 | ||
| 819 | size_t __rlen = _VSTD::min(__n, __str.size() - __pos); | |
| 820 | for (size_t __i = __pos; __i < __pos + __rlen; ++__i) | |
| 821 | if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one)) | |
| 822 | __throw_invalid_argument("bitset string ctor has invalid argument"); | |
| 823 | ||
| 824 | size_t _Mp = _VSTD::min(__rlen, _Size); | |
| 825 | size_t __i = 0; | |
| 826 | for (; __i < _Mp; ++__i) | |
| 827 | { | |
| 828 | _CharT __c = __str[__pos + _Mp - 1 - __i]; | |
| 829 | (*this)[__i] = _Traits::eq(__c, __one); | |
| 830 | } | |
| 831 | _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false); | |
| 832 | } | |
| 833 | ||
| 834 | 817 | template <size_t _Size> |
| 835 | 818 | inline |
| 836 | 819 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| ... | ... | @@ -956,8 +939,8 @@ bitset<_Size>::flip(size_t __pos) |
| 956 | 939 | if (__pos >= _Size) |
| 957 | 940 | __throw_out_of_range("bitset flip argument out of range"); |
| 958 | 941 | |
| 959 | reference r = base::__make_ref(__pos); | |
| 960 | r = ~r; | |
| 942 | reference __r = base::__make_ref(__pos); | |
| 943 | __r = ~__r; | |
| 961 | 944 | return *this; |
| 962 | 945 | } |
| 963 | 946 | |
| ... | ... | @@ -1041,15 +1024,19 @@ bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT |
| 1041 | 1024 | return _VSTD::equal(base::__make_iter(0), base::__make_iter(_Size), __rhs.__make_iter(0)); |
| 1042 | 1025 | } |
| 1043 | 1026 | |
| 1027 | #if _LIBCPP_STD_VER <= 17 | |
| 1028 | ||
| 1044 | 1029 | template <size_t _Size> |
| 1045 | 1030 | inline |
| 1046 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 1031 | _LIBCPP_HIDE_FROM_ABI | |
| 1047 | 1032 | bool |
| 1048 | 1033 | bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT |
| 1049 | 1034 | { |
| 1050 | 1035 | return !(*this == __rhs); |
| 1051 | 1036 | } |
| 1052 | 1037 | |
| 1038 | #endif | |
| 1039 | ||
| 1053 | 1040 | template <size_t _Size> |
| 1054 | 1041 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 |
| 1055 | 1042 | bool |
| ... | ... | @@ -1154,6 +1141,8 @@ _LIBCPP_POP_MACROS |
| 1154 | 1141 | |
| 1155 | 1142 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1156 | 1143 | # include <concepts> |
| 1144 | # include <cstdlib> | |
| 1145 | # include <type_traits> | |
| 1157 | 1146 | #endif |
| 1158 | 1147 | |
| 1159 | 1148 | #endif // _LIBCPP_BITSET |
lib/libcxx/include/charconv+9-753| ... | ... | @@ -63,785 +63,41 @@ namespace std { |
| 63 | 63 | constexpr from_chars_result from_chars(const char* first, const char* last, |
| 64 | 64 | see below& value, int base = 10); // constexpr since C++23 |
| 65 | 65 | |
| 66 | from_chars_result from_chars(const char* first, const char* last, | |
| 67 | float& value, | |
| 68 | chars_format fmt = chars_format::general); | |
| 69 | from_chars_result from_chars(const char* first, const char* last, | |
| 70 | double& value, | |
| 71 | chars_format fmt = chars_format::general); | |
| 72 | from_chars_result from_chars(const char* first, const char* last, | |
| 73 | long double& value, | |
| 74 | chars_format fmt = chars_format::general); | |
| 75 | ||
| 76 | 66 | } // namespace std |
| 77 | 67 | |
| 78 | 68 | */ |
| 79 | 69 | |
| 80 | #include <__algorithm/copy_n.h> | |
| 81 | 70 | #include <__assert> // all public C++ headers provide the assertion handler |
| 82 | #include <__availability> | |
| 83 | #include <__bit/countl.h> | |
| 84 | 71 | #include <__charconv/chars_format.h> |
| 72 | #include <__charconv/from_chars_integral.h> | |
| 85 | 73 | #include <__charconv/from_chars_result.h> |
| 86 | 74 | #include <__charconv/tables.h> |
| 75 | #include <__charconv/to_chars.h> | |
| 87 | 76 | #include <__charconv/to_chars_base_10.h> |
| 77 | #include <__charconv/to_chars_floating_point.h> | |
| 78 | #include <__charconv/to_chars_integral.h> | |
| 88 | 79 | #include <__charconv/to_chars_result.h> |
| 80 | #include <__charconv/traits.h> | |
| 89 | 81 | #include <__config> |
| 90 | #include <__debug> | |
| 91 | #include <__errc> | |
| 92 | #include <__memory/addressof.h> | |
| 93 | #include <__type_traits/make_32_64_or_128_bit.h> | |
| 94 | #include <__utility/unreachable.h> | |
| 82 | #include <__system_error/errc.h> | |
| 95 | 83 | #include <cmath> // for log2f |
| 96 | 84 | #include <cstdint> |
| 97 | #include <cstdlib> | |
| 98 | #include <cstring> | |
| 99 | 85 | #include <limits> |
| 100 | #include <type_traits> | |
| 101 | 86 | |
| 102 | 87 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 103 | 88 | # pragma GCC system_header |
| 104 | 89 | #endif |
| 105 | 90 | |
| 106 | _LIBCPP_PUSH_MACROS | |
| 107 | #include <__undef_macros> | |
| 108 | ||
| 109 | 91 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 110 | 92 | |
| 111 | #if _LIBCPP_STD_VER > 14 | |
| 112 | ||
| 113 | to_chars_result to_chars(char*, char*, bool, int = 10) = delete; | |
| 114 | from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete; | |
| 115 | ||
| 116 | namespace __itoa | |
| 117 | { | |
| 118 | ||
| 119 | template <typename _Tp, typename = void> | |
| 120 | struct _LIBCPP_HIDDEN __traits_base; | |
| 121 | ||
| 122 | template <typename _Tp> | |
| 123 | struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t<sizeof(_Tp) <= sizeof(uint32_t)>> | |
| 124 | { | |
| 125 | using type = uint32_t; | |
| 126 | ||
| 127 | /// The width estimation using a log10 algorithm. | |
| 128 | /// | |
| 129 | /// The algorithm is based on | |
| 130 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 131 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 132 | /// function requires its input to have at least one bit set the value of | |
| 133 | /// zero is set to one. This means the first element of the lookup table is | |
| 134 | /// zero. | |
| 135 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) | |
| 136 | { | |
| 137 | auto __t = (32 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; | |
| 138 | return __t - (__v < __itoa::__pow10_32[__t]) + 1; | |
| 139 | } | |
| 140 | ||
| 141 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) | |
| 142 | { | |
| 143 | return __itoa::__base_10_u32(__p, __v); | |
| 144 | } | |
| 145 | ||
| 146 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_32)& __pow() { return __itoa::__pow10_32; } | |
| 147 | }; | |
| 148 | ||
| 149 | template <typename _Tp> | |
| 150 | struct _LIBCPP_HIDDEN | |
| 151 | __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(uint64_t)>> { | |
| 152 | using type = uint64_t; | |
| 153 | ||
| 154 | /// The width estimation using a log10 algorithm. | |
| 155 | /// | |
| 156 | /// The algorithm is based on | |
| 157 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 158 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 159 | /// function requires its input to have at least one bit set the value of | |
| 160 | /// zero is set to one. This means the first element of the lookup table is | |
| 161 | /// zero. | |
| 162 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { | |
| 163 | auto __t = (64 - std::__libcpp_clz(static_cast<type>(__v | 1))) * 1233 >> 12; | |
| 164 | return __t - (__v < __itoa::__pow10_64[__t]) + 1; | |
| 165 | } | |
| 166 | ||
| 167 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u64(__p, __v); } | |
| 168 | ||
| 169 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_64)& __pow() { return __itoa::__pow10_64; } | |
| 170 | }; | |
| 171 | ||
| 172 | ||
| 173 | # ifndef _LIBCPP_HAS_NO_INT128 | |
| 174 | template <typename _Tp> | |
| 175 | struct _LIBCPP_HIDDEN | |
| 176 | __traits_base<_Tp, __enable_if_t<sizeof(_Tp) == sizeof(__uint128_t)> > { | |
| 177 | using type = __uint128_t; | |
| 178 | ||
| 179 | /// The width estimation using a log10 algorithm. | |
| 180 | /// | |
| 181 | /// The algorithm is based on | |
| 182 | /// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | |
| 183 | /// Instead of using IntegerLogBase2 it uses __libcpp_clz. Since that | |
| 184 | /// function requires its input to have at least one bit set the value of | |
| 185 | /// zero is set to one. This means the first element of the lookup table is | |
| 186 | /// zero. | |
| 187 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __width(_Tp __v) { | |
| 188 | _LIBCPP_ASSERT(__v > numeric_limits<uint64_t>::max(), "The optimizations for this algorithm fail when this isn't true."); | |
| 189 | // There's always a bit set in the upper 64-bits. | |
| 190 | auto __t = (128 - std::__libcpp_clz(static_cast<uint64_t>(__v >> 64))) * 1233 >> 12; | |
| 191 | _LIBCPP_ASSERT(__t >= __itoa::__pow10_128_offset, "Index out of bounds"); | |
| 192 | // __t is adjusted since the lookup table misses the lower entries. | |
| 193 | return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1; | |
| 194 | } | |
| 195 | ||
| 196 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char* __convert(char* __p, _Tp __v) { return __itoa::__base_10_u128(__p, __v); } | |
| 197 | ||
| 198 | // TODO FMT This pow function should get an index. | |
| 199 | // By moving this to its own header it can be reused by the pow function in to_chars_base_10. | |
| 200 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI decltype(__pow10_128)& __pow() { return __itoa::__pow10_128; } | |
| 201 | }; | |
| 202 | #endif | |
| 203 | ||
| 204 | template <typename _Tp> | |
| 205 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 206 | __mul_overflowed(unsigned char __a, _Tp __b, unsigned char& __r) | |
| 207 | { | |
| 208 | auto __c = __a * __b; | |
| 209 | __r = __c; | |
| 210 | return __c > numeric_limits<unsigned char>::max(); | |
| 211 | } | |
| 212 | ||
| 213 | template <typename _Tp> | |
| 214 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 215 | __mul_overflowed(unsigned short __a, _Tp __b, unsigned short& __r) | |
| 216 | { | |
| 217 | auto __c = __a * __b; | |
| 218 | __r = __c; | |
| 219 | return __c > numeric_limits<unsigned short>::max(); | |
| 220 | } | |
| 221 | ||
| 222 | template <typename _Tp> | |
| 223 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 224 | __mul_overflowed(_Tp __a, _Tp __b, _Tp& __r) | |
| 225 | { | |
| 226 | static_assert(is_unsigned<_Tp>::value, ""); | |
| 227 | return __builtin_mul_overflow(__a, __b, &__r); | |
| 228 | } | |
| 229 | ||
| 230 | template <typename _Tp, typename _Up> | |
| 231 | inline _LIBCPP_HIDE_FROM_ABI bool | |
| 232 | _LIBCPP_CONSTEXPR_SINCE_CXX23 __mul_overflowed(_Tp __a, _Up __b, _Tp& __r) | |
| 233 | { | |
| 234 | return __itoa::__mul_overflowed(__a, static_cast<_Tp>(__b), __r); | |
| 235 | } | |
| 236 | ||
| 237 | template <typename _Tp> | |
| 238 | struct _LIBCPP_HIDDEN __traits : __traits_base<_Tp> | |
| 239 | { | |
| 240 | static constexpr int digits = numeric_limits<_Tp>::digits10 + 1; | |
| 241 | using __traits_base<_Tp>::__pow; | |
| 242 | using typename __traits_base<_Tp>::type; | |
| 243 | ||
| 244 | // precondition: at least one non-zero character available | |
| 245 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI char const* | |
| 246 | __read(char const* __p, char const* __ep, type& __a, type& __b) | |
| 247 | { | |
| 248 | type __cprod[digits]; | |
| 249 | int __j = digits - 1; | |
| 250 | int __i = digits; | |
| 251 | do | |
| 252 | { | |
| 253 | if (*__p < '0' || *__p > '9') | |
| 254 | break; | |
| 255 | __cprod[--__i] = *__p++ - '0'; | |
| 256 | } while (__p != __ep && __i != 0); | |
| 257 | ||
| 258 | __a = __inner_product(__cprod + __i + 1, __cprod + __j, __pow() + 1, | |
| 259 | __cprod[__i]); | |
| 260 | if (__itoa::__mul_overflowed(__cprod[__j], __pow()[__j - __i], __b)) | |
| 261 | --__p; | |
| 262 | return __p; | |
| 263 | } | |
| 264 | ||
| 265 | template <typename _It1, typename _It2, class _Up> | |
| 266 | static _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Up | |
| 267 | __inner_product(_It1 __first1, _It1 __last1, _It2 __first2, _Up __init) | |
| 268 | { | |
| 269 | for (; __first1 < __last1; ++__first1, ++__first2) | |
| 270 | __init = __init + *__first1 * *__first2; | |
| 271 | return __init; | |
| 272 | } | |
| 273 | }; | |
| 274 | ||
| 275 | } // namespace __itoa | |
| 276 | ||
| 277 | template <typename _Tp> | |
| 278 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI _Tp | |
| 279 | __complement(_Tp __x) | |
| 280 | { | |
| 281 | static_assert(is_unsigned<_Tp>::value, "cast to unsigned first"); | |
| 282 | return _Tp(~__x + 1); | |
| 283 | } | |
| 284 | ||
| 285 | template <typename _Tp> | |
| 286 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 287 | __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type); | |
| 288 | ||
| 289 | template <typename _Tp> | |
| 290 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 291 | __to_chars_itoa(char* __first, char* __last, _Tp __value, true_type) | |
| 292 | { | |
| 293 | auto __x = std::__to_unsigned_like(__value); | |
| 294 | if (__value < 0 && __first != __last) | |
| 295 | { | |
| 296 | *__first++ = '-'; | |
| 297 | __x = std::__complement(__x); | |
| 298 | } | |
| 299 | ||
| 300 | return std::__to_chars_itoa(__first, __last, __x, false_type()); | |
| 301 | } | |
| 302 | ||
| 303 | template <typename _Tp> | |
| 304 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 305 | __to_chars_itoa(char* __first, char* __last, _Tp __value, false_type) | |
| 306 | { | |
| 307 | using __tx = __itoa::__traits<_Tp>; | |
| 308 | auto __diff = __last - __first; | |
| 309 | ||
| 310 | if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) | |
| 311 | return {__tx::__convert(__first, __value), errc(0)}; | |
| 312 | else | |
| 313 | return {__last, errc::value_too_large}; | |
| 314 | } | |
| 315 | ||
| 316 | # ifndef _LIBCPP_HAS_NO_INT128 | |
| 317 | template <> | |
| 318 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 319 | __to_chars_itoa(char* __first, char* __last, __uint128_t __value, false_type) | |
| 320 | { | |
| 321 | // When the value fits in 64-bits use the 64-bit code path. This reduces | |
| 322 | // the number of expensive calculations on 128-bit values. | |
| 323 | // | |
| 324 | // NOTE the 128-bit code path requires this optimization. | |
| 325 | if(__value <= numeric_limits<uint64_t>::max()) | |
| 326 | return __to_chars_itoa(__first, __last, static_cast<uint64_t>(__value), false_type()); | |
| 327 | ||
| 328 | using __tx = __itoa::__traits<__uint128_t>; | |
| 329 | auto __diff = __last - __first; | |
| 330 | ||
| 331 | if (__tx::digits <= __diff || __tx::__width(__value) <= __diff) | |
| 332 | return {__tx::__convert(__first, __value), errc(0)}; | |
| 333 | else | |
| 334 | return {__last, errc::value_too_large}; | |
| 335 | } | |
| 336 | #endif | |
| 337 | ||
| 338 | template <class _Tp> | |
| 339 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 340 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_type); | |
| 341 | ||
| 342 | template <typename _Tp> | |
| 343 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 344 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, | |
| 345 | true_type) | |
| 346 | { | |
| 347 | auto __x = std::__to_unsigned_like(__value); | |
| 348 | if (__value < 0 && __first != __last) | |
| 349 | { | |
| 350 | *__first++ = '-'; | |
| 351 | __x = std::__complement(__x); | |
| 352 | } | |
| 353 | ||
| 354 | return std::__to_chars_integral(__first, __last, __x, __base, false_type()); | |
| 355 | } | |
| 356 | ||
| 357 | namespace __itoa { | |
| 358 | ||
| 359 | template <unsigned _Base> | |
| 360 | struct _LIBCPP_HIDDEN __integral; | |
| 361 | ||
| 362 | template <> | |
| 363 | struct _LIBCPP_HIDDEN __integral<2> { | |
| 364 | template <typename _Tp> | |
| 365 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 366 | // If value == 0 still need one digit. If the value != this has no | |
| 367 | // effect since the code scans for the most significant bit set. (Note | |
| 368 | // that __libcpp_clz doesn't work for 0.) | |
| 369 | return numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1); | |
| 370 | } | |
| 371 | ||
| 372 | template <typename _Tp> | |
| 373 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { | |
| 374 | ptrdiff_t __cap = __last - __first; | |
| 375 | int __n = __width(__value); | |
| 376 | if (__n > __cap) | |
| 377 | return {__last, errc::value_too_large}; | |
| 378 | ||
| 379 | __last = __first + __n; | |
| 380 | char* __p = __last; | |
| 381 | const unsigned __divisor = 16; | |
| 382 | while (__value > __divisor) { | |
| 383 | unsigned __c = __value % __divisor; | |
| 384 | __value /= __divisor; | |
| 385 | __p -= 4; | |
| 386 | std::copy_n(&__base_2_lut[4 * __c], 4, __p); | |
| 387 | } | |
| 388 | do { | |
| 389 | unsigned __c = __value % 2; | |
| 390 | __value /= 2; | |
| 391 | *--__p = "01"[__c]; | |
| 392 | } while (__value != 0); | |
| 393 | return {__last, errc(0)}; | |
| 394 | } | |
| 395 | }; | |
| 396 | ||
| 397 | template <> | |
| 398 | struct _LIBCPP_HIDDEN __integral<8> { | |
| 399 | template <typename _Tp> | |
| 400 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 401 | // If value == 0 still need one digit. If the value != this has no | |
| 402 | // effect since the code scans for the most significat bit set. (Note | |
| 403 | // that __libcpp_clz doesn't work for 0.) | |
| 404 | return ((numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1)) + 2) / 3; | |
| 405 | } | |
| 406 | ||
| 407 | template <typename _Tp> | |
| 408 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { | |
| 409 | ptrdiff_t __cap = __last - __first; | |
| 410 | int __n = __width(__value); | |
| 411 | if (__n > __cap) | |
| 412 | return {__last, errc::value_too_large}; | |
| 413 | ||
| 414 | __last = __first + __n; | |
| 415 | char* __p = __last; | |
| 416 | unsigned __divisor = 64; | |
| 417 | while (__value > __divisor) { | |
| 418 | unsigned __c = __value % __divisor; | |
| 419 | __value /= __divisor; | |
| 420 | __p -= 2; | |
| 421 | std::copy_n(&__base_8_lut[2 * __c], 2, __p); | |
| 422 | } | |
| 423 | do { | |
| 424 | unsigned __c = __value % 8; | |
| 425 | __value /= 8; | |
| 426 | *--__p = "01234567"[__c]; | |
| 427 | } while (__value != 0); | |
| 428 | return {__last, errc(0)}; | |
| 429 | } | |
| 430 | ||
| 431 | }; | |
| 432 | ||
| 433 | template <> | |
| 434 | struct _LIBCPP_HIDDEN __integral<16> { | |
| 435 | template <typename _Tp> | |
| 436 | _LIBCPP_HIDE_FROM_ABI static constexpr int __width(_Tp __value) noexcept { | |
| 437 | // If value == 0 still need one digit. If the value != this has no | |
| 438 | // effect since the code scans for the most significat bit set. (Note | |
| 439 | // that __libcpp_clz doesn't work for 0.) | |
| 440 | return (numeric_limits<_Tp>::digits - std::__libcpp_clz(__value | 1) + 3) / 4; | |
| 441 | } | |
| 442 | ||
| 443 | template <typename _Tp> | |
| 444 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI static to_chars_result __to_chars(char* __first, char* __last, _Tp __value) { | |
| 445 | ptrdiff_t __cap = __last - __first; | |
| 446 | int __n = __width(__value); | |
| 447 | if (__n > __cap) | |
| 448 | return {__last, errc::value_too_large}; | |
| 449 | ||
| 450 | __last = __first + __n; | |
| 451 | char* __p = __last; | |
| 452 | unsigned __divisor = 256; | |
| 453 | while (__value > __divisor) { | |
| 454 | unsigned __c = __value % __divisor; | |
| 455 | __value /= __divisor; | |
| 456 | __p -= 2; | |
| 457 | std::copy_n(&__base_16_lut[2 * __c], 2, __p); | |
| 458 | } | |
| 459 | if (__first != __last) | |
| 460 | do { | |
| 461 | unsigned __c = __value % 16; | |
| 462 | __value /= 16; | |
| 463 | *--__p = "0123456789abcdef"[__c]; | |
| 464 | } while (__value != 0); | |
| 465 | return {__last, errc(0)}; | |
| 466 | } | |
| 467 | }; | |
| 468 | ||
| 469 | } // namespace __itoa | |
| 470 | ||
| 471 | template <unsigned _Base, typename _Tp, | |
| 472 | typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> | |
| 473 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int | |
| 474 | __to_chars_integral_width(_Tp __value) { | |
| 475 | return __itoa::__integral<_Base>::__width(__value); | |
| 476 | } | |
| 477 | ||
| 478 | template <unsigned _Base, typename _Tp, | |
| 479 | typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> | |
| 480 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int | |
| 481 | __to_chars_integral_width(_Tp __value) { | |
| 482 | return std::__to_chars_integral_width<_Base>(static_cast<unsigned>(__value)); | |
| 483 | } | |
| 484 | ||
| 485 | template <unsigned _Base, typename _Tp, | |
| 486 | typename enable_if<(sizeof(_Tp) >= sizeof(unsigned)), int>::type = 0> | |
| 487 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 488 | __to_chars_integral(char* __first, char* __last, _Tp __value) { | |
| 489 | return __itoa::__integral<_Base>::__to_chars(__first, __last, __value); | |
| 490 | } | |
| 491 | ||
| 492 | template <unsigned _Base, typename _Tp, | |
| 493 | typename enable_if<(sizeof(_Tp) < sizeof(unsigned)), int>::type = 0> | |
| 494 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 495 | __to_chars_integral(char* __first, char* __last, _Tp __value) { | |
| 496 | return std::__to_chars_integral<_Base>(__first, __last, static_cast<unsigned>(__value)); | |
| 497 | } | |
| 498 | ||
| 499 | template <typename _Tp> | |
| 500 | _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int | |
| 501 | __to_chars_integral_width(_Tp __value, unsigned __base) { | |
| 502 | _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value."); | |
| 503 | ||
| 504 | unsigned __base_2 = __base * __base; | |
| 505 | unsigned __base_3 = __base_2 * __base; | |
| 506 | unsigned __base_4 = __base_2 * __base_2; | |
| 507 | ||
| 508 | int __r = 0; | |
| 509 | while (true) { | |
| 510 | if (__value < __base) | |
| 511 | return __r + 1; | |
| 512 | if (__value < __base_2) | |
| 513 | return __r + 2; | |
| 514 | if (__value < __base_3) | |
| 515 | return __r + 3; | |
| 516 | if (__value < __base_4) | |
| 517 | return __r + 4; | |
| 518 | ||
| 519 | __value /= __base_4; | |
| 520 | __r += 4; | |
| 521 | } | |
| 522 | ||
| 523 | __libcpp_unreachable(); | |
| 524 | } | |
| 525 | ||
| 526 | template <typename _Tp> | |
| 527 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 528 | __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, | |
| 529 | false_type) | |
| 530 | { | |
| 531 | if (__base == 10) [[likely]] | |
| 532 | return std::__to_chars_itoa(__first, __last, __value, false_type()); | |
| 533 | ||
| 534 | switch (__base) { | |
| 535 | case 2: | |
| 536 | return std::__to_chars_integral<2>(__first, __last, __value); | |
| 537 | case 8: | |
| 538 | return std::__to_chars_integral<8>(__first, __last, __value); | |
| 539 | case 16: | |
| 540 | return std::__to_chars_integral<16>(__first, __last, __value); | |
| 541 | } | |
| 542 | ||
| 543 | ptrdiff_t __cap = __last - __first; | |
| 544 | int __n = std::__to_chars_integral_width(__value, __base); | |
| 545 | if (__n > __cap) | |
| 546 | return {__last, errc::value_too_large}; | |
| 547 | ||
| 548 | __last = __first + __n; | |
| 549 | char* __p = __last; | |
| 550 | do { | |
| 551 | unsigned __c = __value % __base; | |
| 552 | __value /= __base; | |
| 553 | *--__p = "0123456789abcdefghijklmnopqrstuvwxyz"[__c]; | |
| 554 | } while (__value != 0); | |
| 555 | return {__last, errc(0)}; | |
| 556 | } | |
| 557 | ||
| 558 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 559 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 560 | to_chars(char* __first, char* __last, _Tp __value) | |
| 561 | { | |
| 562 | using _Type = __make_32_64_or_128_bit_t<_Tp>; | |
| 563 | static_assert(!is_same<_Type, void>::value, "unsupported integral type used in to_chars"); | |
| 564 | return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>()); | |
| 565 | } | |
| 566 | ||
| 567 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 568 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result | |
| 569 | to_chars(char* __first, char* __last, _Tp __value, int __base) | |
| 570 | { | |
| 571 | _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); | |
| 572 | ||
| 573 | using _Type = __make_32_64_or_128_bit_t<_Tp>; | |
| 574 | return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>()); | |
| 575 | } | |
| 576 | ||
| 577 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> | |
| 578 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 579 | __sign_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... __args) | |
| 580 | { | |
| 581 | using __tl = numeric_limits<_Tp>; | |
| 582 | decltype(std::__to_unsigned_like(__value)) __x; | |
| 583 | ||
| 584 | bool __neg = (__first != __last && *__first == '-'); | |
| 585 | auto __r = __f(__neg ? __first + 1 : __first, __last, __x, __args...); | |
| 586 | switch (__r.ec) | |
| 587 | { | |
| 588 | case errc::invalid_argument: | |
| 589 | return {__first, __r.ec}; | |
| 590 | case errc::result_out_of_range: | |
| 591 | return __r; | |
| 592 | default: | |
| 593 | break; | |
| 594 | } | |
| 595 | ||
| 596 | if (__neg) | |
| 597 | { | |
| 598 | if (__x <= std::__complement(std::__to_unsigned_like(__tl::min()))) | |
| 599 | { | |
| 600 | __x = std::__complement(__x); | |
| 601 | std::copy_n(std::addressof(__x), 1, std::addressof(__value)); | |
| 602 | return __r; | |
| 603 | } | |
| 604 | } | |
| 605 | else | |
| 606 | { | |
| 607 | if (__x <= std::__to_unsigned_like(__tl::max())) | |
| 608 | { | |
| 609 | __value = __x; | |
| 610 | return __r; | |
| 611 | } | |
| 612 | } | |
| 613 | ||
| 614 | return {__r.ptr, errc::result_out_of_range}; | |
| 615 | } | |
| 616 | ||
| 617 | template <typename _Tp> | |
| 618 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI bool | |
| 619 | __in_pattern(_Tp __c) | |
| 620 | { | |
| 621 | return '0' <= __c && __c <= '9'; | |
| 622 | } | |
| 623 | ||
| 624 | struct _LIBCPP_HIDDEN __in_pattern_result | |
| 625 | { | |
| 626 | bool __ok; | |
| 627 | int __val; | |
| 628 | ||
| 629 | explicit _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI operator bool() const { return __ok; } | |
| 630 | }; | |
| 631 | ||
| 632 | template <typename _Tp> | |
| 633 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI __in_pattern_result | |
| 634 | __in_pattern(_Tp __c, int __base) | |
| 635 | { | |
| 636 | if (__base <= 10) | |
| 637 | return {'0' <= __c && __c < '0' + __base, __c - '0'}; | |
| 638 | else if (std::__in_pattern(__c)) | |
| 639 | return {true, __c - '0'}; | |
| 640 | else if ('a' <= __c && __c < 'a' + __base - 10) | |
| 641 | return {true, __c - 'a' + 10}; | |
| 642 | else | |
| 643 | return {'A' <= __c && __c < 'A' + __base - 10, __c - 'A' + 10}; | |
| 644 | } | |
| 645 | ||
| 646 | template <typename _It, typename _Tp, typename _Fn, typename... _Ts> | |
| 647 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 648 | __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, | |
| 649 | _Ts... __args) | |
| 650 | { | |
| 651 | auto __find_non_zero = [](_It __firstit, _It __lastit) { | |
| 652 | for (; __firstit != __lastit; ++__firstit) | |
| 653 | if (*__firstit != '0') | |
| 654 | break; | |
| 655 | return __firstit; | |
| 656 | }; | |
| 657 | ||
| 658 | auto __p = __find_non_zero(__first, __last); | |
| 659 | if (__p == __last || !std::__in_pattern(*__p, __args...)) | |
| 660 | { | |
| 661 | if (__p == __first) | |
| 662 | return {__first, errc::invalid_argument}; | |
| 663 | else | |
| 664 | { | |
| 665 | __value = 0; | |
| 666 | return {__p, {}}; | |
| 667 | } | |
| 668 | } | |
| 669 | ||
| 670 | auto __r = __f(__p, __last, __value, __args...); | |
| 671 | if (__r.ec == errc::result_out_of_range) | |
| 672 | { | |
| 673 | for (; __r.ptr != __last; ++__r.ptr) | |
| 674 | { | |
| 675 | if (!std::__in_pattern(*__r.ptr, __args...)) | |
| 676 | break; | |
| 677 | } | |
| 678 | } | |
| 679 | ||
| 680 | return __r; | |
| 681 | } | |
| 682 | ||
| 683 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> | |
| 684 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 685 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) | |
| 686 | { | |
| 687 | using __tx = __itoa::__traits<_Tp>; | |
| 688 | using __output_type = typename __tx::type; | |
| 689 | ||
| 690 | return std::__subject_seq_combinator( | |
| 691 | __first, __last, __value, | |
| 692 | [](const char* __f, const char* __l, | |
| 693 | _Tp& __val) -> from_chars_result { | |
| 694 | __output_type __a, __b; | |
| 695 | auto __p = __tx::__read(__f, __l, __a, __b); | |
| 696 | if (__p == __l || !std::__in_pattern(*__p)) | |
| 697 | { | |
| 698 | __output_type __m = numeric_limits<_Tp>::max(); | |
| 699 | if (__m >= __a && __m - __a >= __b) | |
| 700 | { | |
| 701 | __val = __a + __b; | |
| 702 | return {__p, {}}; | |
| 703 | } | |
| 704 | } | |
| 705 | return {__p, errc::result_out_of_range}; | |
| 706 | }); | |
| 707 | } | |
| 708 | ||
| 709 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> | |
| 710 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 711 | __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) | |
| 712 | { | |
| 713 | using __t = decltype(std::__to_unsigned_like(__value)); | |
| 714 | return std::__sign_combinator(__first, __last, __value, __from_chars_atoi<__t>); | |
| 715 | } | |
| 716 | ||
| 717 | ||
| 718 | /* | |
| 719 | // Code used to generate __from_chars_log2f_lut. | |
| 720 | #include <cmath> | |
| 721 | #include <iostream> | |
| 722 | #include <format> | |
| 723 | ||
| 724 | int main() { | |
| 725 | for (int i = 2; i <= 36; ++i) | |
| 726 | std::cout << std::format("{},\n", log2f(i)); | |
| 727 | } | |
| 728 | */ | |
| 729 | /// log2f table for bases [2, 36]. | |
| 730 | inline constexpr float __from_chars_log2f_lut[35] = { | |
| 731 | 1, 1.5849625, 2, 2.321928, 2.5849626, 2.807355, 3, 3.169925, 3.321928, | |
| 732 | 3.4594316, 3.5849626, 3.7004397, 3.807355, 3.9068906, 4, 4.087463, 4.169925, 4.2479277, | |
| 733 | 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355, | |
| 734 | 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925}; | |
| 735 | ||
| 736 | template <typename _Tp, typename enable_if<is_unsigned<_Tp>::value, int>::type = 0> | |
| 737 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 738 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, | |
| 739 | int __base) | |
| 740 | { | |
| 741 | if (__base == 10) | |
| 742 | return std::__from_chars_atoi(__first, __last, __value); | |
| 743 | ||
| 744 | return std::__subject_seq_combinator( | |
| 745 | __first, __last, __value, | |
| 746 | [](const char* __p, const char* __lastp, _Tp& __val, | |
| 747 | int __b) -> from_chars_result { | |
| 748 | using __tl = numeric_limits<_Tp>; | |
| 749 | // __base is always between 2 and 36 inclusive. | |
| 750 | auto __digits = __tl::digits / __from_chars_log2f_lut[__b - 2]; | |
| 751 | _Tp __x = __in_pattern(*__p++, __b).__val, __y = 0; | |
| 752 | ||
| 753 | for (int __i = 1; __p != __lastp; ++__i, ++__p) | |
| 754 | { | |
| 755 | if (auto __c = __in_pattern(*__p, __b)) | |
| 756 | { | |
| 757 | if (__i < __digits - 1) | |
| 758 | __x = __x * __b + __c.__val; | |
| 759 | else | |
| 760 | { | |
| 761 | if (!__itoa::__mul_overflowed(__x, __b, __x)) | |
| 762 | ++__p; | |
| 763 | __y = __c.__val; | |
| 764 | break; | |
| 765 | } | |
| 766 | } | |
| 767 | else | |
| 768 | break; | |
| 769 | } | |
| 770 | ||
| 771 | if (__p == __lastp || !__in_pattern(*__p, __b)) | |
| 772 | { | |
| 773 | if (__tl::max() - __x >= __y) | |
| 774 | { | |
| 775 | __val = __x + __y; | |
| 776 | return {__p, {}}; | |
| 777 | } | |
| 778 | } | |
| 779 | return {__p, errc::result_out_of_range}; | |
| 780 | }, | |
| 781 | __base); | |
| 782 | } | |
| 783 | ||
| 784 | template <typename _Tp, typename enable_if<is_signed<_Tp>::value, int>::type = 0> | |
| 785 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 786 | __from_chars_integral(const char* __first, const char* __last, _Tp& __value, | |
| 787 | int __base) | |
| 788 | { | |
| 789 | using __t = decltype(std::__to_unsigned_like(__value)); | |
| 790 | return std::__sign_combinator(__first, __last, __value, | |
| 791 | __from_chars_integral<__t>, __base); | |
| 792 | } | |
| 793 | ||
| 794 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 795 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 796 | from_chars(const char* __first, const char* __last, _Tp& __value) | |
| 797 | { | |
| 798 | return std::__from_chars_atoi(__first, __last, __value); | |
| 799 | } | |
| 800 | ||
| 801 | template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type = 0> | |
| 802 | inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result | |
| 803 | from_chars(const char* __first, const char* __last, _Tp& __value, int __base) | |
| 804 | { | |
| 805 | _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); | |
| 806 | return std::__from_chars_integral(__first, __last, __value, __base); | |
| 807 | } | |
| 808 | ||
| 809 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 810 | to_chars_result to_chars(char* __first, char* __last, float __value); | |
| 811 | ||
| 812 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 813 | to_chars_result to_chars(char* __first, char* __last, double __value); | |
| 814 | ||
| 815 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 816 | to_chars_result to_chars(char* __first, char* __last, long double __value); | |
| 817 | ||
| 818 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 819 | to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt); | |
| 820 | ||
| 821 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 822 | to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt); | |
| 823 | ||
| 824 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 825 | to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt); | |
| 826 | ||
| 827 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 828 | to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision); | |
| 829 | ||
| 830 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 831 | to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision); | |
| 832 | ||
| 833 | _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS | |
| 834 | to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision); | |
| 835 | ||
| 836 | #endif // _LIBCPP_STD_VER > 14 | |
| 837 | ||
| 838 | 93 | _LIBCPP_END_NAMESPACE_STD |
| 839 | 94 | |
| 840 | _LIBCPP_POP_MACROS | |
| 841 | ||
| 842 | 95 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 843 | 96 | # include <concepts> |
| 97 | # include <cstdlib> | |
| 98 | # include <cstring> | |
| 844 | 99 | # include <iosfwd> |
| 100 | # include <type_traits> | |
| 845 | 101 | #endif |
| 846 | 102 | |
| 847 | 103 | #endif // _LIBCPP_CHARCONV |
lib/libcxx/include/chrono+41-12| ... | ... | @@ -182,7 +182,7 @@ template <class Rep1, class Period1, class Rep2, class Period2> |
| 182 | 182 | bool operator==(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); |
| 183 | 183 | template <class Rep1, class Period1, class Rep2, class Period2> |
| 184 | 184 | constexpr |
| 185 | bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); | |
| 185 | bool operator!=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); // removed in C++20 | |
| 186 | 186 | template <class Rep1, class Period1, class Rep2, class Period2> |
| 187 | 187 | constexpr |
| 188 | 188 | bool operator< (const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); |
| ... | ... | @@ -195,6 +195,10 @@ template <class Rep1, class Period1, class Rep2, class Period2> |
| 195 | 195 | template <class Rep1, class Period1, class Rep2, class Period2> |
| 196 | 196 | constexpr |
| 197 | 197 | bool operator>=(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs); |
| 198 | template<class Rep1, class Period1, class Rep2, class Period2> | |
| 199 | requires three_way_comparable<typename CT::rep> | |
| 200 | constexpr auto operator<=>(const duration<Rep1, Period1>& lhs, | |
| 201 | const duration<Rep2, Period2>& rhs); // since C++20 | |
| 198 | 202 | |
| 199 | 203 | // duration_cast |
| 200 | 204 | template <class ToDuration, class Rep, class Period> |
| ... | ... | @@ -231,7 +235,7 @@ template <class Clock, class Duration1, class Duration2> |
| 231 | 235 | template <class Clock, class Duration1, class Duration2> |
| 232 | 236 | bool operator==(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); |
| 233 | 237 | template <class Clock, class Duration1, class Duration2> |
| 234 | bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); | |
| 238 | bool operator!=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); // removed in C++20 | |
| 235 | 239 | template <class Clock, class Duration1, class Duration2> |
| 236 | 240 | bool operator< (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); |
| 237 | 241 | template <class Clock, class Duration1, class Duration2> |
| ... | ... | @@ -240,6 +244,10 @@ template <class Clock, class Duration1, class Duration2> |
| 240 | 244 | bool operator> (const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); |
| 241 | 245 | template <class Clock, class Duration1, class Duration2> |
| 242 | 246 | bool operator>=(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs); |
| 247 | template<class Clock, class Duration1, | |
| 248 | three_way_comparable_with<Duration1> Duration2> | |
| 249 | constexpr auto operator<=>(const time_point<Clock, Duration1>& lhs, | |
| 250 | const time_point<Clock, Duration2>& rhs); // since C++20 | |
| 243 | 251 | |
| 244 | 252 | // time_point_cast (constexpr in C++14) |
| 245 | 253 | |
| ... | ... | @@ -282,6 +290,10 @@ template <class Duration> |
| 282 | 290 | using sys_seconds = sys_time<seconds>; // C++20 |
| 283 | 291 | using sys_days = sys_time<days>; // C++20 |
| 284 | 292 | |
| 293 | template<class charT, class traits, class Duration> // C++20 | |
| 294 | basic_ostream<charT, traits>& | |
| 295 | operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp); | |
| 296 | ||
| 285 | 297 | class file_clock // C++20 |
| 286 | 298 | { |
| 287 | 299 | public: |
| ... | ... | @@ -303,6 +315,10 @@ public: |
| 303 | 315 | template<class Duration> |
| 304 | 316 | using file_time = time_point<file_clock, Duration>; // C++20 |
| 305 | 317 | |
| 318 | template<class charT, class traits, class Duration> // C++20 | |
| 319 | basic_ostream<charT, traits>& | |
| 320 | operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& tp); | |
| 321 | ||
| 306 | 322 | class steady_clock |
| 307 | 323 | { |
| 308 | 324 | public: |
| ... | ... | @@ -324,6 +340,10 @@ template<class Duration> |
| 324 | 340 | using local_seconds = local_time<seconds>; |
| 325 | 341 | using local_days = local_time<days>; |
| 326 | 342 | |
| 343 | template<class charT, class traits, class Duration> // C++20 | |
| 344 | basic_ostream<charT, traits>& | |
| 345 | operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& tp); | |
| 346 | ||
| 327 | 347 | // 25.8.2, class last_spec // C++20 |
| 328 | 348 | struct last_spec; |
| 329 | 349 | |
| ... | ... | @@ -370,7 +390,6 @@ template<class charT, class traits> |
| 370 | 390 | class weekday; |
| 371 | 391 | |
| 372 | 392 | constexpr bool operator==(const weekday& x, const weekday& y) noexcept; |
| 373 | constexpr bool operator!=(const weekday& x, const weekday& y) noexcept; | |
| 374 | 393 | constexpr weekday operator+(const weekday& x, const days& y) noexcept; |
| 375 | 394 | constexpr weekday operator+(const days& x, const weekday& y) noexcept; |
| 376 | 395 | constexpr weekday operator-(const weekday& x, const days& y) noexcept; |
| ... | ... | @@ -383,7 +402,6 @@ template<class charT, class traits> |
| 383 | 402 | |
| 384 | 403 | class weekday_indexed; |
| 385 | 404 | constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept; |
| 386 | constexpr bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept; | |
| 387 | 405 | |
| 388 | 406 | template<class charT, class traits> |
| 389 | 407 | basic_ostream<charT, traits>& |
| ... | ... | @@ -393,7 +411,6 @@ template<class charT, class traits> |
| 393 | 411 | class weekday_last; |
| 394 | 412 | |
| 395 | 413 | constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept; |
| 396 | constexpr bool operator!=(const weekday_last& x, const weekday_last& y) noexcept; | |
| 397 | 414 | |
| 398 | 415 | template<class charT, class traits> |
| 399 | 416 | basic_ostream<charT, traits>& |
| ... | ... | @@ -423,7 +440,6 @@ template<class charT, class traits> |
| 423 | 440 | class month_weekday; |
| 424 | 441 | |
| 425 | 442 | constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept; |
| 426 | constexpr bool operator!=(const month_weekday& x, const month_weekday& y) noexcept; | |
| 427 | 443 | |
| 428 | 444 | template<class charT, class traits> |
| 429 | 445 | basic_ostream<charT, traits>& |
| ... | ... | @@ -433,7 +449,6 @@ template<class charT, class traits> |
| 433 | 449 | class month_weekday_last; |
| 434 | 450 | |
| 435 | 451 | constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept; |
| 436 | constexpr bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept; | |
| 437 | 452 | |
| 438 | 453 | template<class charT, class traits> |
| 439 | 454 | basic_ostream<charT, traits>& |
| ... | ... | @@ -503,8 +518,6 @@ class year_month_weekday; |
| 503 | 518 | |
| 504 | 519 | constexpr bool operator==(const year_month_weekday& x, |
| 505 | 520 | const year_month_weekday& y) noexcept; |
| 506 | constexpr bool operator!=(const year_month_weekday& x, | |
| 507 | const year_month_weekday& y) noexcept; | |
| 508 | 521 | |
| 509 | 522 | constexpr year_month_weekday |
| 510 | 523 | operator+(const year_month_weekday& ymwd, const months& dm) noexcept; |
| ... | ... | @@ -528,8 +541,6 @@ class year_month_weekday_last; |
| 528 | 541 | |
| 529 | 542 | constexpr bool operator==(const year_month_weekday_last& x, |
| 530 | 543 | const year_month_weekday_last& y) noexcept; |
| 531 | constexpr bool operator!=(const year_month_weekday_last& x, | |
| 532 | const year_month_weekday_last& y) noexcept; | |
| 533 | 544 | constexpr year_month_weekday_last |
| 534 | 545 | operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept; |
| 535 | 546 | constexpr year_month_weekday_last |
| ... | ... | @@ -656,6 +667,10 @@ public: |
| 656 | 667 | constexpr precision to_duration() const noexcept; |
| 657 | 668 | }; |
| 658 | 669 | |
| 670 | template<class charT, class traits, class Duration> | |
| 671 | basic_ostream<charT, traits>& | |
| 672 | operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms); // C++20 | |
| 673 | ||
| 659 | 674 | // 26.10, 12/24 hour functions |
| 660 | 675 | constexpr bool is_am(hours const& h) noexcept; |
| 661 | 676 | constexpr bool is_pm(hours const& h) noexcept; |
| ... | ... | @@ -674,6 +689,12 @@ bool operator>=(const time_zone& x, const time_zone& y) noexcept; |
| 674 | 689 | } // chrono |
| 675 | 690 | |
| 676 | 691 | namespace std { |
| 692 | template<class Duration, class charT> | |
| 693 | struct formatter<chrono::sys_time<Duration>, charT>; // C++20 | |
| 694 | template<class Duration, class charT> | |
| 695 | struct formatter<chrono::filetime<Duration>, charT>; // C++20 | |
| 696 | template<class Duration, class charT> | |
| 697 | struct formatter<chrono::local_time<Duration>, charT>; // C++20 | |
| 677 | 698 | template<class Rep, class Period, class charT> |
| 678 | 699 | struct formatter<chrono::duration<Rep, Period>, charT>; // C++20 |
| 679 | 700 | template<class charT> struct formatter<chrono::day, charT>; // C++20 |
| ... | ... | @@ -691,6 +712,8 @@ namespace std { |
| 691 | 712 | template<class charT> struct formatter<chrono::year_month_day_last, charT>; // C++20 |
| 692 | 713 | template<class charT> struct formatter<chrono::year_month_weekday, charT>; // C++20 |
| 693 | 714 | template<class charT> struct formatter<chrono::year_month_weekday_last, charT>; // C++20 |
| 715 | template<class Rep, class Period, class charT> | |
| 716 | struct formatter<chrono::hh_mm_ss<duration<Rep, Period>>, charT>; // C++20 | |
| 694 | 717 | } // namespace std |
| 695 | 718 | |
| 696 | 719 | namespace chrono { |
| ... | ... | @@ -769,7 +792,7 @@ constexpr chrono::year operator ""y(unsigned lo |
| 769 | 792 | // [time.syn] |
| 770 | 793 | #include <compare> |
| 771 | 794 | |
| 772 | #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) && _LIBCPP_STD_VER > 17 | |
| 795 | #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) && _LIBCPP_STD_VER >= 20 | |
| 773 | 796 | # include <__chrono/formatter.h> |
| 774 | 797 | # include <__chrono/ostream.h> |
| 775 | 798 | # include <__chrono/parser_std_format_spec.h> |
| ... | ... | @@ -782,7 +805,13 @@ constexpr chrono::year operator ""y(unsigned lo |
| 782 | 805 | #endif |
| 783 | 806 | |
| 784 | 807 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 808 | # include <bit> | |
| 785 | 809 | # include <concepts> |
| 810 | # include <cstring> | |
| 811 | #endif | |
| 812 | ||
| 813 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER == 20 | |
| 814 | # include <charconv> | |
| 786 | 815 | #endif |
| 787 | 816 | |
| 788 | 817 | #endif // _LIBCPP_CHRONO |
lib/libcxx/include/cmath+4-3| ... | ... | @@ -311,6 +311,7 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept |
| 311 | 311 | #include <__type_traits/is_constant_evaluated.h> |
| 312 | 312 | #include <__type_traits/is_floating_point.h> |
| 313 | 313 | #include <__type_traits/is_same.h> |
| 314 | #include <__type_traits/promote.h> | |
| 314 | 315 | #include <__type_traits/remove_cv.h> |
| 315 | 316 | #include <version> |
| 316 | 317 | |
| ... | ... | @@ -543,7 +544,7 @@ using ::scalbnl _LIBCPP_USING_IF_EXISTS; |
| 543 | 544 | using ::tgammal _LIBCPP_USING_IF_EXISTS; |
| 544 | 545 | using ::truncl _LIBCPP_USING_IF_EXISTS; |
| 545 | 546 | |
| 546 | #if _LIBCPP_STD_VER > 14 | |
| 547 | #if _LIBCPP_STD_VER >= 17 | |
| 547 | 548 | inline _LIBCPP_INLINE_VISIBILITY float hypot( float __x, float __y, float __z ) { return sqrt(__x*__x + __y*__y + __z*__z); } |
| 548 | 549 | inline _LIBCPP_INLINE_VISIBILITY double hypot( double __x, double __y, double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); } |
| 549 | 550 | inline _LIBCPP_INLINE_VISIBILITY long double hypot( long double __x, long double __y, long double __z ) { return sqrt(__x*__x + __y*__y + __z*__z); } |
| ... | ... | @@ -782,7 +783,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp __constexpr_scalbn(_Tp _ |
| 782 | 783 | return __builtin_scalbn(__x, __exp); |
| 783 | 784 | } |
| 784 | 785 | |
| 785 | #if _LIBCPP_STD_VER > 17 | |
| 786 | #if _LIBCPP_STD_VER >= 20 | |
| 786 | 787 | template <typename _Fp> |
| 787 | 788 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 788 | 789 | _Fp __lerp(_Fp __a, _Fp __b, _Fp __t) noexcept { |
| ... | ... | @@ -823,7 +824,7 @@ lerp(_A1 __a, _A2 __b, _A3 __t) noexcept |
| 823 | 824 | _IsSame<_A3, __result_type>::value)); |
| 824 | 825 | return std::__lerp((__result_type)__a, (__result_type)__b, (__result_type)__t); |
| 825 | 826 | } |
| 826 | #endif // _LIBCPP_STD_VER > 17 | |
| 827 | #endif // _LIBCPP_STD_VER >= 20 | |
| 827 | 828 | |
| 828 | 829 | _LIBCPP_END_NAMESPACE_STD |
| 829 | 830 |
lib/libcxx/include/codecvt+12-12| ... | ... | @@ -78,7 +78,7 @@ template <class _Elem> class __codecvt_utf8; |
| 78 | 78 | |
| 79 | 79 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 80 | 80 | template <> |
| 81 | class _LIBCPP_TYPE_VIS __codecvt_utf8<wchar_t> | |
| 81 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<wchar_t> | |
| 82 | 82 | : public codecvt<wchar_t, char, mbstate_t> |
| 83 | 83 | { |
| 84 | 84 | unsigned long __maxcode_; |
| ... | ... | @@ -115,7 +115,7 @@ protected: |
| 115 | 115 | |
| 116 | 116 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 117 | 117 | template <> |
| 118 | class _LIBCPP_TYPE_VIS __codecvt_utf8<char16_t> | |
| 118 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char16_t> | |
| 119 | 119 | : public codecvt<char16_t, char, mbstate_t> |
| 120 | 120 | { |
| 121 | 121 | unsigned long __maxcode_; |
| ... | ... | @@ -149,7 +149,7 @@ protected: |
| 149 | 149 | |
| 150 | 150 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 151 | 151 | template <> |
| 152 | class _LIBCPP_TYPE_VIS __codecvt_utf8<char32_t> | |
| 152 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8<char32_t> | |
| 153 | 153 | : public codecvt<char32_t, char, mbstate_t> |
| 154 | 154 | { |
| 155 | 155 | unsigned long __maxcode_; |
| ... | ... | @@ -203,7 +203,7 @@ template <class _Elem, bool _LittleEndian> class __codecvt_utf16; |
| 203 | 203 | |
| 204 | 204 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 205 | 205 | template <> |
| 206 | class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, false> | |
| 206 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, false> | |
| 207 | 207 | : public codecvt<wchar_t, char, mbstate_t> |
| 208 | 208 | { |
| 209 | 209 | unsigned long __maxcode_; |
| ... | ... | @@ -239,7 +239,7 @@ protected: |
| 239 | 239 | }; |
| 240 | 240 | |
| 241 | 241 | template <> |
| 242 | class _LIBCPP_TYPE_VIS __codecvt_utf16<wchar_t, true> | |
| 242 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<wchar_t, true> | |
| 243 | 243 | : public codecvt<wchar_t, char, mbstate_t> |
| 244 | 244 | { |
| 245 | 245 | unsigned long __maxcode_; |
| ... | ... | @@ -276,7 +276,7 @@ protected: |
| 276 | 276 | |
| 277 | 277 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 278 | 278 | template <> |
| 279 | class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, false> | |
| 279 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, false> | |
| 280 | 280 | : public codecvt<char16_t, char, mbstate_t> |
| 281 | 281 | { |
| 282 | 282 | unsigned long __maxcode_; |
| ... | ... | @@ -310,7 +310,7 @@ protected: |
| 310 | 310 | |
| 311 | 311 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 312 | 312 | template <> |
| 313 | class _LIBCPP_TYPE_VIS __codecvt_utf16<char16_t, true> | |
| 313 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char16_t, true> | |
| 314 | 314 | : public codecvt<char16_t, char, mbstate_t> |
| 315 | 315 | { |
| 316 | 316 | unsigned long __maxcode_; |
| ... | ... | @@ -344,7 +344,7 @@ protected: |
| 344 | 344 | |
| 345 | 345 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 346 | 346 | template <> |
| 347 | class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, false> | |
| 347 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, false> | |
| 348 | 348 | : public codecvt<char32_t, char, mbstate_t> |
| 349 | 349 | { |
| 350 | 350 | unsigned long __maxcode_; |
| ... | ... | @@ -378,7 +378,7 @@ protected: |
| 378 | 378 | |
| 379 | 379 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 380 | 380 | template <> |
| 381 | class _LIBCPP_TYPE_VIS __codecvt_utf16<char32_t, true> | |
| 381 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf16<char32_t, true> | |
| 382 | 382 | : public codecvt<char32_t, char, mbstate_t> |
| 383 | 383 | { |
| 384 | 384 | unsigned long __maxcode_; |
| ... | ... | @@ -432,7 +432,7 @@ template <class _Elem> class __codecvt_utf8_utf16; |
| 432 | 432 | |
| 433 | 433 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 434 | 434 | template <> |
| 435 | class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<wchar_t> | |
| 435 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<wchar_t> | |
| 436 | 436 | : public codecvt<wchar_t, char, mbstate_t> |
| 437 | 437 | { |
| 438 | 438 | unsigned long __maxcode_; |
| ... | ... | @@ -469,7 +469,7 @@ protected: |
| 469 | 469 | |
| 470 | 470 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 471 | 471 | template <> |
| 472 | class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char32_t> | |
| 472 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char32_t> | |
| 473 | 473 | : public codecvt<char32_t, char, mbstate_t> |
| 474 | 474 | { |
| 475 | 475 | unsigned long __maxcode_; |
| ... | ... | @@ -503,7 +503,7 @@ protected: |
| 503 | 503 | |
| 504 | 504 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 505 | 505 | template <> |
| 506 | class _LIBCPP_TYPE_VIS __codecvt_utf8_utf16<char16_t> | |
| 506 | class _LIBCPP_EXPORTED_FROM_ABI __codecvt_utf8_utf16<char16_t> | |
| 507 | 507 | : public codecvt<char16_t, char, mbstate_t> |
| 508 | 508 | { |
| 509 | 509 | unsigned long __maxcode_; |
lib/libcxx/include/compare+1| ... | ... | @@ -151,6 +151,7 @@ namespace std { |
| 151 | 151 | #include <__compare/ordering.h> |
| 152 | 152 | #include <__compare/partial_order.h> |
| 153 | 153 | #include <__compare/strong_order.h> |
| 154 | #include <__compare/synth_three_way.h> | |
| 154 | 155 | #include <__compare/three_way_comparable.h> |
| 155 | 156 | #include <__compare/weak_order.h> |
| 156 | 157 | #include <__config> |
lib/libcxx/include/complex+15-8| ... | ... | @@ -148,12 +148,12 @@ template<class T> complex<T> operator/(const complex<T>&, const T&); // |
| 148 | 148 | template<class T> complex<T> operator/(const T&, const complex<T>&); // constexpr in C++20 |
| 149 | 149 | template<class T> complex<T> operator+(const complex<T>&); // constexpr in C++20 |
| 150 | 150 | template<class T> complex<T> operator-(const complex<T>&); // constexpr in C++20 |
| 151 | template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14 | |
| 152 | template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14 | |
| 153 | template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14 | |
| 154 | template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14 | |
| 155 | template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14 | |
| 156 | template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14 | |
| 151 | template<class T> bool operator==(const complex<T>&, const complex<T>&); // constexpr in C++14 | |
| 152 | template<class T> bool operator==(const complex<T>&, const T&); // constexpr in C++14 | |
| 153 | template<class T> bool operator==(const T&, const complex<T>&); // constexpr in C++14, removed in C++20 | |
| 154 | template<class T> bool operator!=(const complex<T>&, const complex<T>&); // constexpr in C++14, removed in C++20 | |
| 155 | template<class T> bool operator!=(const complex<T>&, const T&); // constexpr in C++14, removed in C++20 | |
| 156 | template<class T> bool operator!=(const T&, const complex<T>&); // constexpr in C++14, removed in C++20 | |
| 157 | 157 | |
| 158 | 158 | template<class T, class charT, class traits> |
| 159 | 159 | basic_istream<charT, traits>& |
| ... | ... | @@ -236,7 +236,6 @@ template<class T> complex<T> tanh (const complex<T>&); |
| 236 | 236 | #include <cmath> |
| 237 | 237 | #include <iosfwd> |
| 238 | 238 | #include <stdexcept> |
| 239 | #include <type_traits> | |
| 240 | 239 | #include <version> |
| 241 | 240 | |
| 242 | 241 | #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) |
| ... | ... | @@ -828,6 +827,8 @@ operator==(const complex<_Tp>& __x, const _Tp& __y) |
| 828 | 827 | return __x.real() == __y && __x.imag() == 0; |
| 829 | 828 | } |
| 830 | 829 | |
| 830 | #if _LIBCPP_STD_VER <= 17 | |
| 831 | ||
| 831 | 832 | template<class _Tp> |
| 832 | 833 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 833 | 834 | bool |
| ... | ... | @@ -860,6 +861,8 @@ operator!=(const _Tp& __x, const complex<_Tp>& __y) |
| 860 | 861 | return !(__x == __y); |
| 861 | 862 | } |
| 862 | 863 | |
| 864 | #endif | |
| 865 | ||
| 863 | 866 | // 26.3.7 values: |
| 864 | 867 | |
| 865 | 868 | template <class _Tp, bool = is_integral<_Tp>::value, |
| ... | ... | @@ -1522,7 +1525,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) |
| 1522 | 1525 | } |
| 1523 | 1526 | #endif // !_LIBCPP_HAS_NO_LOCALIZATION |
| 1524 | 1527 | |
| 1525 | #if _LIBCPP_STD_VER > 11 | |
| 1528 | #if _LIBCPP_STD_VER >= 14 | |
| 1526 | 1529 | // Literal suffix for complex number literals [complex.literals] |
| 1527 | 1530 | inline namespace literals |
| 1528 | 1531 | { |
| ... | ... | @@ -1565,4 +1568,8 @@ inline namespace literals |
| 1565 | 1568 | |
| 1566 | 1569 | _LIBCPP_END_NAMESPACE_STD |
| 1567 | 1570 | |
| 1571 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 1572 | # include <type_traits> | |
| 1573 | #endif | |
| 1574 | ||
| 1568 | 1575 | #endif // _LIBCPP_COMPLEX |
lib/libcxx/include/condition_variable+23-7| ... | ... | @@ -107,10 +107,18 @@ public: |
| 107 | 107 | */ |
| 108 | 108 | |
| 109 | 109 | #include <__assert> // all public C++ headers provide the assertion handler |
| 110 | #include <__chrono/duration.h> | |
| 111 | #include <__chrono/steady_clock.h> | |
| 112 | #include <__chrono/time_point.h> | |
| 113 | #include <__condition_variable/condition_variable.h> | |
| 110 | 114 | #include <__config> |
| 111 | 115 | #include <__memory/shared_ptr.h> |
| 112 | 116 | #include <__memory/unique_ptr.h> |
| 113 | #include <__mutex_base> | |
| 117 | #include <__mutex/lock_guard.h> | |
| 118 | #include <__mutex/mutex.h> | |
| 119 | #include <__mutex/tag_types.h> | |
| 120 | #include <__mutex/unique_lock.h> | |
| 121 | #include <__utility/move.h> | |
| 114 | 122 | #include <version> |
| 115 | 123 | |
| 116 | 124 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -121,7 +129,7 @@ public: |
| 121 | 129 | |
| 122 | 130 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 123 | 131 | |
| 124 | class _LIBCPP_TYPE_VIS condition_variable_any | |
| 132 | class _LIBCPP_EXPORTED_FROM_ABI condition_variable_any | |
| 125 | 133 | { |
| 126 | 134 | condition_variable __cv_; |
| 127 | 135 | shared_ptr<mutex> __mut_; |
| ... | ... | @@ -191,7 +199,7 @@ condition_variable_any::notify_all() _NOEXCEPT |
| 191 | 199 | struct __lock_external |
| 192 | 200 | { |
| 193 | 201 | template <class _Lock> |
| 194 | void operator()(_Lock* __m) {__m->lock();} | |
| 202 | _LIBCPP_HIDE_FROM_ABI void operator()(_Lock* __m) {__m->lock();} | |
| 195 | 203 | }; |
| 196 | 204 | |
| 197 | 205 | template <class _Lock> |
| ... | ... | @@ -202,7 +210,7 @@ condition_variable_any::wait(_Lock& __lock) |
| 202 | 210 | unique_lock<mutex> __lk(*__mut); |
| 203 | 211 | __lock.unlock(); |
| 204 | 212 | unique_ptr<_Lock, __lock_external> __lxx(&__lock); |
| 205 | lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); | |
| 213 | lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t()); | |
| 206 | 214 | __cv_.wait(__lk); |
| 207 | 215 | } // __mut_.unlock(), __lock.lock() |
| 208 | 216 | |
| ... | ... | @@ -224,7 +232,7 @@ condition_variable_any::wait_until(_Lock& __lock, |
| 224 | 232 | unique_lock<mutex> __lk(*__mut); |
| 225 | 233 | __lock.unlock(); |
| 226 | 234 | unique_ptr<_Lock, __lock_external> __lxx(&__lock); |
| 227 | lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock); | |
| 235 | lock_guard<unique_lock<mutex> > __lx(__lk, adopt_lock_t()); | |
| 228 | 236 | return __cv_.wait_until(__lk, __t); |
| 229 | 237 | } // __mut_.unlock(), __lock.lock() |
| 230 | 238 | |
| ... | ... | @@ -261,16 +269,24 @@ condition_variable_any::wait_for(_Lock& __lock, |
| 261 | 269 | _VSTD::move(__pred)); |
| 262 | 270 | } |
| 263 | 271 | |
| 264 | _LIBCPP_FUNC_VIS | |
| 265 | void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>); | |
| 272 | _LIBCPP_EXPORTED_FROM_ABI void notify_all_at_thread_exit(condition_variable&, unique_lock<mutex>); | |
| 266 | 273 | |
| 267 | 274 | _LIBCPP_END_NAMESPACE_STD |
| 268 | 275 | |
| 269 | 276 | #endif // !_LIBCPP_HAS_NO_THREADS |
| 270 | 277 | |
| 271 | 278 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 279 | # include <atomic> | |
| 272 | 280 | # include <concepts> |
| 281 | # include <cstdint> | |
| 282 | # include <cstdlib> | |
| 283 | # include <cstring> | |
| 284 | # include <initializer_list> | |
| 285 | # include <new> | |
| 286 | # include <stdexcept> | |
| 287 | # include <system_error> | |
| 273 | 288 | # include <type_traits> |
| 289 | # include <typeinfo> | |
| 274 | 290 | #endif |
| 275 | 291 | |
| 276 | 292 | #endif // _LIBCPP_CONDITION_VARIABLE |
lib/libcxx/include/cstddef+1-1| ... | ... | @@ -66,7 +66,7 @@ using ::max_align_t _LIBCPP_USING_IF_EXISTS; |
| 66 | 66 | |
| 67 | 67 | _LIBCPP_END_NAMESPACE_STD |
| 68 | 68 | |
| 69 | #if _LIBCPP_STD_VER > 14 | |
| 69 | #if _LIBCPP_STD_VER >= 17 | |
| 70 | 70 | namespace std // purposefully not versioned |
| 71 | 71 | { |
| 72 | 72 | enum class byte : unsigned char {}; |
lib/libcxx/include/cstdlib+1-1| ... | ... | @@ -144,7 +144,7 @@ using ::wcstombs _LIBCPP_USING_IF_EXISTS; |
| 144 | 144 | using ::at_quick_exit _LIBCPP_USING_IF_EXISTS; |
| 145 | 145 | using ::quick_exit _LIBCPP_USING_IF_EXISTS; |
| 146 | 146 | #endif |
| 147 | #if _LIBCPP_STD_VER > 14 | |
| 147 | #if _LIBCPP_STD_VER >= 17 | |
| 148 | 148 | using ::aligned_alloc _LIBCPP_USING_IF_EXISTS; |
| 149 | 149 | #endif |
| 150 | 150 |
lib/libcxx/include/cstring-47| ... | ... | @@ -100,53 +100,6 @@ using ::memset _LIBCPP_USING_IF_EXISTS; |
| 100 | 100 | using ::strerror _LIBCPP_USING_IF_EXISTS; |
| 101 | 101 | using ::strlen _LIBCPP_USING_IF_EXISTS; |
| 102 | 102 | |
| 103 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 size_t __constexpr_strlen(const char* __str) { | |
| 104 | // GCC currently doesn't support __builtin_strlen for heap-allocated memory during constant evaluation. | |
| 105 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70816 | |
| 106 | #ifdef _LIBCPP_COMPILER_GCC | |
| 107 | if (__libcpp_is_constant_evaluated()) { | |
| 108 | size_t __i = 0; | |
| 109 | for (; __str[__i] != '\0'; ++__i) | |
| 110 | ; | |
| 111 | return __i; | |
| 112 | } | |
| 113 | #endif | |
| 114 | return __builtin_strlen(__str); | |
| 115 | } | |
| 116 | ||
| 117 | template <class _Tp> | |
| 118 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int | |
| 119 | __constexpr_memcmp(const _Tp* __lhs, const _Tp* __rhs, size_t __count) { | |
| 120 | #ifdef _LIBCPP_COMPILER_GCC | |
| 121 | if (__libcpp_is_constant_evaluated()) { | |
| 122 | for (; __count; --__count, ++__lhs, ++__rhs) { | |
| 123 | if (*__lhs < *__rhs) | |
| 124 | return -1; | |
| 125 | if (*__rhs < *__lhs) | |
| 126 | return 1; | |
| 127 | } | |
| 128 | return 0; | |
| 129 | } | |
| 130 | #endif | |
| 131 | return __builtin_memcmp(__lhs, __rhs, __count); | |
| 132 | } | |
| 133 | ||
| 134 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const char* | |
| 135 | __constexpr_char_memchr(const char* __str, int __char, size_t __count) { | |
| 136 | #if __has_builtin(__builtin_char_memchr) | |
| 137 | return __builtin_char_memchr(__str, __char, __count); | |
| 138 | #else | |
| 139 | if (!__libcpp_is_constant_evaluated()) | |
| 140 | return static_cast<const char*>(std::memchr(__str, __char, __count)); | |
| 141 | for (; __count; --__count) { | |
| 142 | if (*__str == __char) | |
| 143 | return __str; | |
| 144 | ++__str; | |
| 145 | } | |
| 146 | return nullptr; | |
| 147 | #endif | |
| 148 | } | |
| 149 | ||
| 150 | 103 | _LIBCPP_END_NAMESPACE_STD |
| 151 | 104 | |
| 152 | 105 | #endif // _LIBCPP_CSTRING |
lib/libcxx/include/ctime+2-2| ... | ... | @@ -66,7 +66,7 @@ using ::clock_t _LIBCPP_USING_IF_EXISTS; |
| 66 | 66 | using ::size_t _LIBCPP_USING_IF_EXISTS; |
| 67 | 67 | using ::time_t _LIBCPP_USING_IF_EXISTS; |
| 68 | 68 | using ::tm _LIBCPP_USING_IF_EXISTS; |
| 69 | #if _LIBCPP_STD_VER > 14 | |
| 69 | #if _LIBCPP_STD_VER >= 17 | |
| 70 | 70 | using ::timespec _LIBCPP_USING_IF_EXISTS; |
| 71 | 71 | #endif |
| 72 | 72 | using ::clock _LIBCPP_USING_IF_EXISTS; |
| ... | ... | @@ -78,7 +78,7 @@ using ::ctime _LIBCPP_USING_IF_EXISTS; |
| 78 | 78 | using ::gmtime _LIBCPP_USING_IF_EXISTS; |
| 79 | 79 | using ::localtime _LIBCPP_USING_IF_EXISTS; |
| 80 | 80 | using ::strftime _LIBCPP_USING_IF_EXISTS; |
| 81 | #if _LIBCPP_STD_VER > 14 | |
| 81 | #if _LIBCPP_STD_VER >= 17 | |
| 82 | 82 | using ::timespec_get _LIBCPP_USING_IF_EXISTS; |
| 83 | 83 | #endif |
| 84 | 84 |
lib/libcxx/include/cwchar+23-9| ... | ... | @@ -104,7 +104,11 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, |
| 104 | 104 | |
| 105 | 105 | #include <__assert> // all public C++ headers provide the assertion handler |
| 106 | 106 | #include <__config> |
| 107 | #include <__type_traits/apply_cv.h> | |
| 107 | 108 | #include <__type_traits/is_constant_evaluated.h> |
| 109 | #include <__type_traits/is_equality_comparable.h> | |
| 110 | #include <__type_traits/is_same.h> | |
| 111 | #include <__type_traits/remove_cv.h> | |
| 108 | 112 | #include <cwctype> |
| 109 | 113 | |
| 110 | 114 | #include <wchar.h> |
| ... | ... | @@ -222,21 +226,31 @@ __constexpr_wmemcmp(const wchar_t* __lhs, const wchar_t* __rhs, size_t __count) |
| 222 | 226 | #endif |
| 223 | 227 | } |
| 224 | 228 | |
| 225 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const wchar_t* | |
| 226 | __constexpr_wmemchr(const wchar_t* __str, wchar_t __char, size_t __count) { | |
| 227 | #if __has_feature(cxx_constexpr_string_builtins) | |
| 228 | return __builtin_wmemchr(__str, __char, __count); | |
| 229 | #else | |
| 230 | if (!__libcpp_is_constant_evaluated()) | |
| 231 | return std::wmemchr(__str, __char, __count); | |
| 229 | template <class _Tp, class _Up> | |
| 230 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __constexpr_wmemchr(_Tp* __str, _Up __value, size_t __count) { | |
| 231 | static_assert(sizeof(_Tp) == sizeof(wchar_t)&& _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t) && | |
| 232 | __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value, | |
| 233 | "Calling wmemchr on non-trivially equality comparable types is unsafe."); | |
| 234 | ||
| 235 | #if __has_builtin(__builtin_wmemchr) | |
| 236 | if (!__libcpp_is_constant_evaluated()) { | |
| 237 | wchar_t __value_buffer = 0; | |
| 238 | __builtin_memcpy(&__value_buffer, &__value, sizeof(wchar_t)); | |
| 239 | return reinterpret_cast<_Tp*>( | |
| 240 | __builtin_wmemchr(reinterpret_cast<__apply_cv_t<_Tp, wchar_t>*>(__str), __value_buffer, __count)); | |
| 241 | } | |
| 242 | # if _LIBCPP_STD_VER >= 17 | |
| 243 | else if constexpr (is_same_v<remove_cv_t<_Tp>, wchar_t>) | |
| 244 | return __builtin_wmemchr(__str, __value, __count); | |
| 245 | # endif | |
| 246 | #endif // __has_builtin(__builtin_wmemchr) | |
| 232 | 247 | |
| 233 | 248 | for (; __count; --__count) { |
| 234 | if (*__str == __char) | |
| 249 | if (*__str == __value) | |
| 235 | 250 | return __str; |
| 236 | 251 | ++__str; |
| 237 | 252 | } |
| 238 | 253 | return nullptr; |
| 239 | #endif | |
| 240 | 254 | } |
| 241 | 255 | |
| 242 | 256 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/deque+629-66| ... | ... | @@ -47,6 +47,8 @@ public: |
| 47 | 47 | deque(InputIterator f, InputIterator l); |
| 48 | 48 | template <class InputIterator> |
| 49 | 49 | deque(InputIterator f, InputIterator l, const allocator_type& a); |
| 50 | template<container-compatible-range<T> R> | |
| 51 | deque(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 | |
| 50 | 52 | deque(const deque& c); |
| 51 | 53 | deque(deque&& c) |
| 52 | 54 | noexcept(is_nothrow_move_constructible<allocator_type>::value); |
| ... | ... | @@ -64,6 +66,8 @@ public: |
| 64 | 66 | |
| 65 | 67 | template <class InputIterator> |
| 66 | 68 | void assign(InputIterator f, InputIterator l); |
| 69 | template<container-compatible-range<T> R> | |
| 70 | void assign_range(R&& rg); // C++23 | |
| 67 | 71 | void assign(size_type n, const value_type& v); |
| 68 | 72 | void assign(initializer_list<value_type> il); |
| 69 | 73 | |
| ... | ... | @@ -107,8 +111,12 @@ public: |
| 107 | 111 | // modifiers: |
| 108 | 112 | void push_front(const value_type& v); |
| 109 | 113 | void push_front(value_type&& v); |
| 114 | template<container-compatible-range<T> R> | |
| 115 | void prepend_range(R&& rg); // C++23 | |
| 110 | 116 | void push_back(const value_type& v); |
| 111 | 117 | void push_back(value_type&& v); |
| 118 | template<container-compatible-range<T> R> | |
| 119 | void append_range(R&& rg); // C++23 | |
| 112 | 120 | template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 |
| 113 | 121 | template <class... Args> reference emplace_back(Args&&... args); // reference in C++17 |
| 114 | 122 | template <class... Args> iterator emplace(const_iterator p, Args&&... args); |
| ... | ... | @@ -117,6 +125,8 @@ public: |
| 117 | 125 | iterator insert(const_iterator p, size_type n, const value_type& v); |
| 118 | 126 | template <class InputIterator> |
| 119 | 127 | iterator insert(const_iterator p, InputIterator f, InputIterator l); |
| 128 | template<container-compatible-range<T> R> | |
| 129 | iterator insert_range(const_iterator position, R&& rg); // C++23 | |
| 120 | 130 | iterator insert(const_iterator p, initializer_list<value_type> il); |
| 121 | 131 | void pop_front(); |
| 122 | 132 | void pop_back(); |
| ... | ... | @@ -131,18 +141,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra |
| 131 | 141 | deque(InputIterator, InputIterator, Allocator = Allocator()) |
| 132 | 142 | -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 |
| 133 | 143 | |
| 144 | template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> | |
| 145 | deque(from_range_t, R&&, Allocator = Allocator()) | |
| 146 | -> deque<ranges::range_value_t<R>, Allocator>; // C++23 | |
| 147 | ||
| 134 | 148 | template <class T, class Allocator> |
| 135 | 149 | bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y); |
| 136 | 150 | template <class T, class Allocator> |
| 137 | bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); | |
| 151 | bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 | |
| 138 | 152 | template <class T, class Allocator> |
| 139 | bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); | |
| 153 | bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 | |
| 140 | 154 | template <class T, class Allocator> |
| 141 | bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); | |
| 155 | bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 | |
| 142 | 156 | template <class T, class Allocator> |
| 143 | bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); | |
| 157 | bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 | |
| 144 | 158 | template <class T, class Allocator> |
| 145 | bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); | |
| 159 | bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y); // removed in C++20 | |
| 160 | template<class T, class Allocator> | |
| 161 | synth-three-way-result<T> operator<=>(const deque<T, Allocator>& x, | |
| 162 | const deque<T, Allocator>& y); // since C++20 | |
| 146 | 163 | |
| 147 | 164 | // specialized algorithms: |
| 148 | 165 | template <class T, class Allocator> |
| ... | ... | @@ -162,34 +179,47 @@ template <class T, class Allocator, class Predicate> |
| 162 | 179 | |
| 163 | 180 | #include <__algorithm/copy.h> |
| 164 | 181 | #include <__algorithm/copy_backward.h> |
| 182 | #include <__algorithm/copy_n.h> | |
| 165 | 183 | #include <__algorithm/equal.h> |
| 166 | 184 | #include <__algorithm/fill_n.h> |
| 167 | 185 | #include <__algorithm/lexicographical_compare.h> |
| 186 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 168 | 187 | #include <__algorithm/min.h> |
| 169 | 188 | #include <__algorithm/remove.h> |
| 170 | 189 | #include <__algorithm/remove_if.h> |
| 171 | 190 | #include <__algorithm/unwrap_iter.h> |
| 172 | 191 | #include <__assert> // all public C++ headers provide the assertion handler |
| 192 | #include <__availability> | |
| 173 | 193 | #include <__config> |
| 174 | 194 | #include <__format/enable_insertable.h> |
| 195 | #include <__iterator/distance.h> | |
| 175 | 196 | #include <__iterator/iterator_traits.h> |
| 176 | 197 | #include <__iterator/next.h> |
| 177 | 198 | #include <__iterator/prev.h> |
| 178 | 199 | #include <__iterator/reverse_iterator.h> |
| 179 | 200 | #include <__iterator/segmented_iterator.h> |
| 201 | #include <__memory/addressof.h> | |
| 180 | 202 | #include <__memory/allocator_destructor.h> |
| 181 | 203 | #include <__memory/pointer_traits.h> |
| 182 | 204 | #include <__memory/temp_value.h> |
| 183 | 205 | #include <__memory/unique_ptr.h> |
| 184 | 206 | #include <__memory_resource/polymorphic_allocator.h> |
| 207 | #include <__ranges/access.h> | |
| 208 | #include <__ranges/concepts.h> | |
| 209 | #include <__ranges/container_compatible_range.h> | |
| 210 | #include <__ranges/from_range.h> | |
| 211 | #include <__ranges/size.h> | |
| 185 | 212 | #include <__split_buffer> |
| 186 | 213 | #include <__type_traits/is_allocator.h> |
| 214 | #include <__type_traits/is_convertible.h> | |
| 215 | #include <__type_traits/is_same.h> | |
| 216 | #include <__type_traits/type_identity.h> | |
| 187 | 217 | #include <__utility/forward.h> |
| 188 | 218 | #include <__utility/move.h> |
| 219 | #include <__utility/pair.h> | |
| 189 | 220 | #include <__utility/swap.h> |
| 190 | 221 | #include <limits> |
| 191 | 222 | #include <stdexcept> |
| 192 | #include <type_traits> | |
| 193 | 223 | #include <version> |
| 194 | 224 | |
| 195 | 225 | // standard-mandated includes |
| ... | ... | @@ -249,7 +279,7 @@ public: |
| 249 | 279 | typedef _Reference reference; |
| 250 | 280 | |
| 251 | 281 | _LIBCPP_HIDE_FROM_ABI __deque_iterator() _NOEXCEPT |
| 252 | #if _LIBCPP_STD_VER > 11 | |
| 282 | #if _LIBCPP_STD_VER >= 14 | |
| 253 | 283 | : __m_iter_(nullptr), __ptr_(nullptr) |
| 254 | 284 | #endif |
| 255 | 285 | {} |
| ... | ... | @@ -451,6 +481,7 @@ public: |
| 451 | 481 | using __map_alloc_traits = allocator_traits<__pointer_allocator>; |
| 452 | 482 | using __map_pointer = typename __map_alloc_traits::pointer; |
| 453 | 483 | using __map_const_pointer = typename allocator_traits<__const_pointer_allocator>::const_pointer; |
| 484 | using __map_const_iterator = typename __map::const_iterator; | |
| 454 | 485 | |
| 455 | 486 | using reference = value_type&; |
| 456 | 487 | using const_reference = const value_type&; |
| ... | ... | @@ -550,10 +581,13 @@ public: |
| 550 | 581 | // construct/copy/destroy: |
| 551 | 582 | _LIBCPP_HIDE_FROM_ABI |
| 552 | 583 | deque() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) |
| 553 | : __start_(0), __size_(0, __default_init_tag()) {} | |
| 584 | : __start_(0), __size_(0, __default_init_tag()) { | |
| 585 | __annotate_new(0); | |
| 586 | } | |
| 554 | 587 | |
| 555 | 588 | _LIBCPP_HIDE_FROM_ABI ~deque() { |
| 556 | 589 | clear(); |
| 590 | __annotate_delete(); | |
| 557 | 591 | typename __map::iterator __i = __map_.begin(); |
| 558 | 592 | typename __map::iterator __e = __map_.end(); |
| 559 | 593 | for (; __i != __e; ++__i) |
| ... | ... | @@ -561,10 +595,12 @@ public: |
| 561 | 595 | } |
| 562 | 596 | |
| 563 | 597 | _LIBCPP_HIDE_FROM_ABI explicit deque(const allocator_type& __a) |
| 564 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) {} | |
| 598 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { | |
| 599 | __annotate_new(0); | |
| 600 | } | |
| 565 | 601 | |
| 566 | 602 | explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); |
| 567 | #if _LIBCPP_STD_VER > 11 | |
| 603 | #if _LIBCPP_STD_VER >= 14 | |
| 568 | 604 | explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); |
| 569 | 605 | #endif |
| 570 | 606 | _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); |
| ... | ... | @@ -573,16 +609,34 @@ public: |
| 573 | 609 | _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v, const allocator_type& __a) |
| 574 | 610 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) |
| 575 | 611 | { |
| 612 | __annotate_new(0); | |
| 576 | 613 | if (__n > 0) |
| 577 | 614 | __append(__n, __v); |
| 578 | 615 | } |
| 579 | 616 | |
| 580 | 617 | template <class _InputIter> |
| 581 | 618 | _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, |
| 582 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); | |
| 619 | typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); | |
| 583 | 620 | template <class _InputIter> |
| 584 | 621 | _LIBCPP_HIDE_FROM_ABI deque(_InputIter __f, _InputIter __l, const allocator_type& __a, |
| 585 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0); | |
| 622 | typename enable_if<__has_input_iterator_category<_InputIter>::value>::type* = 0); | |
| 623 | ||
| 624 | #if _LIBCPP_STD_VER >= 23 | |
| 625 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 626 | _LIBCPP_HIDE_FROM_ABI deque(from_range_t, _Range&& __range, | |
| 627 | const allocator_type& __a = allocator_type()) | |
| 628 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) { | |
| 629 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 630 | __append_with_size(ranges::begin(__range), ranges::distance(__range)); | |
| 631 | ||
| 632 | } else { | |
| 633 | for (auto&& __e : __range) { | |
| 634 | emplace_back(std::forward<decltype(__e)>(__e)); | |
| 635 | } | |
| 636 | } | |
| 637 | } | |
| 638 | #endif | |
| 639 | ||
| 586 | 640 | _LIBCPP_HIDE_FROM_ABI deque(const deque& __c); |
| 587 | 641 | _LIBCPP_HIDE_FROM_ABI deque(const deque& __c, const __type_identity_t<allocator_type>& __a); |
| 588 | 642 | |
| ... | ... | @@ -610,11 +664,30 @@ public: |
| 610 | 664 | |
| 611 | 665 | template <class _InputIter> |
| 612 | 666 | _LIBCPP_HIDE_FROM_ABI void assign(_InputIter __f, _InputIter __l, |
| 613 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value && | |
| 614 | !__is_cpp17_random_access_iterator<_InputIter>::value>::type* = 0); | |
| 667 | typename enable_if<__has_input_iterator_category<_InputIter>::value && | |
| 668 | !__has_random_access_iterator_category<_InputIter>::value>::type* = 0); | |
| 615 | 669 | template <class _RAIter> |
| 616 | 670 | _LIBCPP_HIDE_FROM_ABI void assign(_RAIter __f, _RAIter __l, |
| 617 | typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type* = 0); | |
| 671 | typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type* = 0); | |
| 672 | ||
| 673 | #if _LIBCPP_STD_VER >= 23 | |
| 674 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 675 | _LIBCPP_HIDE_FROM_ABI | |
| 676 | void assign_range(_Range&& __range) { | |
| 677 | if constexpr (ranges::random_access_range<_Range>) { | |
| 678 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 679 | __assign_with_size_random_access(ranges::begin(__range), __n); | |
| 680 | ||
| 681 | } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 682 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 683 | __assign_with_size(ranges::begin(__range), __n); | |
| 684 | ||
| 685 | } else { | |
| 686 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 687 | } | |
| 688 | } | |
| 689 | #endif | |
| 690 | ||
| 618 | 691 | _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); |
| 619 | 692 | |
| 620 | 693 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -713,7 +786,7 @@ public: |
| 713 | 786 | _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); |
| 714 | 787 | _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __v); |
| 715 | 788 | #ifndef _LIBCPP_CXX03_LANG |
| 716 | #if _LIBCPP_STD_VER > 14 | |
| 789 | #if _LIBCPP_STD_VER >= 17 | |
| 717 | 790 | template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); |
| 718 | 791 | template <class... _Args> _LIBCPP_HIDE_FROM_ABI reference emplace_back (_Args&&... __args); |
| 719 | 792 | #else |
| ... | ... | @@ -724,6 +797,21 @@ public: |
| 724 | 797 | |
| 725 | 798 | _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); |
| 726 | 799 | _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __v); |
| 800 | ||
| 801 | #if _LIBCPP_STD_VER >= 23 | |
| 802 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 803 | _LIBCPP_HIDE_FROM_ABI | |
| 804 | void prepend_range(_Range&& __range) { | |
| 805 | insert_range(begin(), std::forward<_Range>(__range)); | |
| 806 | } | |
| 807 | ||
| 808 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 809 | _LIBCPP_HIDE_FROM_ABI | |
| 810 | void append_range(_Range&& __range) { | |
| 811 | insert_range(end(), std::forward<_Range>(__range)); | |
| 812 | } | |
| 813 | #endif | |
| 814 | ||
| 727 | 815 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v); |
| 728 | 816 | |
| 729 | 817 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -734,13 +822,31 @@ public: |
| 734 | 822 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __v); |
| 735 | 823 | template <class _InputIter> |
| 736 | 824 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InputIter __f, _InputIter __l, |
| 737 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type* = 0); | |
| 825 | typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type* = 0); | |
| 738 | 826 | template <class _ForwardIterator> |
| 739 | 827 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, |
| 740 | typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); | |
| 828 | typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type* = 0); | |
| 741 | 829 | template <class _BiIter> |
| 742 | 830 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _BiIter __f, _BiIter __l, |
| 743 | typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type* = 0); | |
| 831 | typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type* = 0); | |
| 832 | ||
| 833 | #if _LIBCPP_STD_VER >= 23 | |
| 834 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 835 | _LIBCPP_HIDE_FROM_ABI | |
| 836 | iterator insert_range(const_iterator __position, _Range&& __range) { | |
| 837 | if constexpr (ranges::bidirectional_range<_Range>) { | |
| 838 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 839 | return __insert_bidirectional(__position, ranges::begin(__range), ranges::end(__range), __n); | |
| 840 | ||
| 841 | } else if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 842 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 843 | return __insert_with_size(__position, ranges::begin(__range), __n); | |
| 844 | ||
| 845 | } else { | |
| 846 | return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); | |
| 847 | } | |
| 848 | } | |
| 849 | #endif | |
| 744 | 850 | |
| 745 | 851 | _LIBCPP_HIDE_FROM_ABI void pop_front(); |
| 746 | 852 | _LIBCPP_HIDE_FROM_ABI void pop_back(); |
| ... | ... | @@ -764,7 +870,7 @@ public: |
| 764 | 870 | return false; |
| 765 | 871 | if (__map_.size() >= size_type(-1) / __block_size) |
| 766 | 872 | return false; |
| 767 | for (typename __map::const_iterator __i = __map_.begin(), __e = __map_.end(); | |
| 873 | for (__map_const_iterator __i = __map_.begin(), __e = __map_.end(); | |
| 768 | 874 | __i != __e; ++__i) |
| 769 | 875 | if (*__i == nullptr) |
| 770 | 876 | return false; |
| ... | ... | @@ -851,9 +957,264 @@ public: |
| 851 | 957 | } |
| 852 | 958 | |
| 853 | 959 | private: |
| 960 | enum __asan_annotation_type { | |
| 961 | __asan_unposion, | |
| 962 | __asan_poison | |
| 963 | }; | |
| 964 | ||
| 965 | enum __asan_annotation_place { | |
| 966 | __asan_front_moved, | |
| 967 | __asan_back_moved, | |
| 968 | }; | |
| 969 | ||
| 970 | // The following functions are no-ops outside of AddressSanitizer mode. | |
| 971 | // We call annotations for every allocator, unless explicitly disabled. | |
| 972 | // | |
| 973 | // To disable annotations for a particular allocator, change value of | |
| 974 | // __asan_annotate_container_with_allocator to false. | |
| 975 | // For more details, see the "Using libc++" documentation page or | |
| 976 | // the documentation for __sanitizer_annotate_contiguous_container. | |
| 977 | #if !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 | |
| 978 | // TODO LLVM18: Remove the special-casing | |
| 979 | _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( | |
| 980 | const void* __beg, | |
| 981 | const void* __end, | |
| 982 | const void* __old_con_beg, | |
| 983 | const void* __old_con_end, | |
| 984 | const void* __new_con_beg, | |
| 985 | const void* __new_con_end) const { | |
| 986 | if (__beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) | |
| 987 | __sanitizer_annotate_double_ended_contiguous_container( | |
| 988 | __beg, __end, __old_con_beg, __old_con_end, __new_con_beg, __new_con_end); | |
| 989 | } | |
| 990 | #else | |
| 991 | _LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( | |
| 992 | const void*, const void*, const void*, const void*, const void*, const void*) const _NOEXCEPT {} | |
| 993 | #endif // !defined(_LIBCPP_HAS_NO_ASAN) && _LIBCPP_CLANG_VER >= 1600 | |
| 994 | ||
| 995 | _LIBCPP_HIDE_FROM_ABI | |
| 996 | void __annotate_from_to(size_type __beg, size_type __end, __asan_annotation_type __annotation_type, __asan_annotation_place __place) const _NOEXCEPT { | |
| 997 | // __beg - index of the first item to annotate | |
| 998 | // __end - index behind the last item to annotate (so last item + 1) | |
| 999 | // __annotation_type - __asan_unposion or __asan_poison | |
| 1000 | // __place - __asan_front_moved or __asan_back_moved | |
| 1001 | // Note: All indexes in __map_ | |
| 1002 | if (__beg == __end) | |
| 1003 | return; | |
| 1004 | // __annotations_beg_map - first chunk which annotations we want to modify | |
| 1005 | // __annotations_end_map - last chunk which annotations we want to modify | |
| 1006 | // NOTE: if __end % __block_size == 0, __annotations_end_map points at the next block, which may not exist | |
| 1007 | __map_const_iterator __annotations_beg_map = __map_.begin() + __beg / __block_size; | |
| 1008 | __map_const_iterator __annotations_end_map = __map_.begin() + __end / __block_size; | |
| 1009 | ||
| 1010 | bool const __poisoning = __annotation_type == __asan_poison; | |
| 1011 | // __old_c_beg_index - index of the first element in old container | |
| 1012 | // __old_c_end_index - index of the end of old container (last + 1) | |
| 1013 | // Note: may be outside the area we are annotating | |
| 1014 | size_t __old_c_beg_index = (__poisoning && __place == __asan_front_moved) ? __beg : __start_; | |
| 1015 | size_t __old_c_end_index = (__poisoning && __place == __asan_back_moved) ? __end : __start_ + size(); | |
| 1016 | bool const __front = __place == __asan_front_moved; | |
| 1017 | ||
| 1018 | if (__poisoning && empty()) { | |
| 1019 | // Special case: we shouldn't trust __start_ | |
| 1020 | __old_c_beg_index = __beg; | |
| 1021 | __old_c_end_index = __end; | |
| 1022 | } | |
| 1023 | // __old_c_beg_map - memory block (chunk) with first element | |
| 1024 | // __old_c_end_map - memory block (chunk) with end of old container | |
| 1025 | // Note: if __old_c_end_index % __block_size == 0, __old_c_end_map points at the next block, | |
| 1026 | // which may not exist | |
| 1027 | __map_const_iterator __old_c_beg_map = __map_.begin() + __old_c_beg_index / __block_size; | |
| 1028 | __map_const_iterator __old_c_end_map = __map_.begin() + __old_c_end_index / __block_size; | |
| 1029 | ||
| 1030 | // One edge (front/end) of the container was moved and one was not modified. | |
| 1031 | // __new_edge_index - index of new edge | |
| 1032 | // __new_edge_map - memory block (chunk) with new edge, it always equals to | |
| 1033 | // __annotations_beg_map or __annotations_end_map | |
| 1034 | // __old_edge_map - memory block (chunk) with old edge, it always equals to | |
| 1035 | // __old_c_beg_map or __old_c_end_map | |
| 1036 | size_t __new_edge_index = (__poisoning ^ __front) ? __beg : __end; | |
| 1037 | __map_const_iterator __new_edge_map = __map_.begin() + __new_edge_index / __block_size; | |
| 1038 | __map_const_iterator __old_edge_map = __front ? __old_c_end_map : __old_c_beg_map; | |
| 1039 | ||
| 1040 | // We iterate over map pointers (chunks) and fully poison all memory blocks between the first and the last. | |
| 1041 | // First and last chunk may be partially poisoned. | |
| 1042 | // __annotate_end_map may point at not existing chunk, therefore we have to have a check for it. | |
| 1043 | for (__map_const_iterator __map_it = __annotations_beg_map; __map_it <= __annotations_end_map; ++__map_it) { | |
| 1044 | if (__map_it == __annotations_end_map && __end % __block_size == 0) | |
| 1045 | // Chunk may not exist, but nothing to do here anyway | |
| 1046 | break; | |
| 1047 | ||
| 1048 | // The beginning and the end of the current memory block | |
| 1049 | const void* __mem_beg = std::__to_address(*__map_it); | |
| 1050 | const void* __mem_end = std::__to_address(*__map_it + __block_size); | |
| 1051 | ||
| 1052 | // The beginning of memory-in-use in the memory block before container modification | |
| 1053 | const void* __old_beg = | |
| 1054 | (__map_it == __old_c_beg_map) ? std::__to_address(*__map_it + (__old_c_beg_index % __block_size)) : __mem_beg; | |
| 1055 | ||
| 1056 | // The end of memory-in-use in the memory block before container modification | |
| 1057 | const void* __old_end; | |
| 1058 | if (__map_it < __old_c_beg_map || __map_it > __old_c_end_map || (!__poisoning && empty())) | |
| 1059 | __old_end = __old_beg; | |
| 1060 | else | |
| 1061 | __old_end = (__map_it == __old_c_end_map) ? std::__to_address(*__map_it + (__old_c_end_index % __block_size)) | |
| 1062 | : __mem_end; | |
| 1063 | ||
| 1064 | // New edge of the container in current memory block | |
| 1065 | // If the edge is in a different chunk it points on corresponding end of the memory block | |
| 1066 | const void* __new_edge; | |
| 1067 | if (__map_it == __new_edge_map) | |
| 1068 | __new_edge = std::__to_address(*__map_it + (__new_edge_index % __block_size)); | |
| 1069 | else | |
| 1070 | __new_edge = (__poisoning ^ __front) ? __mem_beg : __mem_end; | |
| 1071 | ||
| 1072 | // Not modified edge of the container | |
| 1073 | // If the edge is in a different chunk it points on corresponding end of the memory block | |
| 1074 | const void* __old_edge; | |
| 1075 | if (__map_it == __old_edge_map) | |
| 1076 | __old_edge = __front ? __old_end : __old_beg; | |
| 1077 | else | |
| 1078 | __old_edge = __front ? __mem_end : __mem_beg; | |
| 1079 | ||
| 1080 | // __new_beg - the beginning of memory-in-use in the memory block after container modification | |
| 1081 | // __new_end - the end of memory-in-use in the memory block after container modification | |
| 1082 | const void* __new_beg = __front ? __new_edge : __old_edge; | |
| 1083 | const void* __new_end = __front ? __old_edge : __new_edge; | |
| 1084 | ||
| 1085 | __annotate_double_ended_contiguous_container(__mem_beg, __mem_end, __old_beg, __old_end, __new_beg, __new_end); | |
| 1086 | } | |
| 1087 | } | |
| 1088 | ||
| 1089 | _LIBCPP_HIDE_FROM_ABI | |
| 1090 | void __annotate_new(size_type __current_size) const _NOEXCEPT { | |
| 1091 | if (__current_size == 0) | |
| 1092 | __annotate_from_to(0, __map_.size() * __block_size, __asan_poison, __asan_back_moved); | |
| 1093 | else { | |
| 1094 | __annotate_from_to(0, __start_, __asan_poison, __asan_front_moved); | |
| 1095 | __annotate_from_to(__start_ + __current_size, __map_.size() * __block_size, __asan_poison, __asan_back_moved); | |
| 1096 | } | |
| 1097 | } | |
| 1098 | ||
| 1099 | _LIBCPP_HIDE_FROM_ABI | |
| 1100 | void __annotate_delete() const _NOEXCEPT { | |
| 1101 | if (empty()) { | |
| 1102 | for(size_t __i = 0; __i < __map_.size(); ++__i) { | |
| 1103 | __annotate_whole_block(__i, __asan_unposion); | |
| 1104 | } | |
| 1105 | } | |
| 1106 | else { | |
| 1107 | __annotate_from_to(0, __start_, __asan_unposion, __asan_front_moved); | |
| 1108 | __annotate_from_to(__start_ + size(), __map_.size() * __block_size, __asan_unposion, __asan_back_moved); | |
| 1109 | } | |
| 1110 | } | |
| 1111 | ||
| 1112 | _LIBCPP_HIDE_FROM_ABI | |
| 1113 | void __annotate_increase_front(size_type __n) const _NOEXCEPT { | |
| 1114 | __annotate_from_to(__start_ - __n, __start_, __asan_unposion, __asan_front_moved); | |
| 1115 | } | |
| 1116 | ||
| 1117 | _LIBCPP_HIDE_FROM_ABI | |
| 1118 | void __annotate_increase_back(size_type __n) const _NOEXCEPT { | |
| 1119 | __annotate_from_to(__start_ + size(), __start_ + size() + __n, __asan_unposion, __asan_back_moved); | |
| 1120 | } | |
| 1121 | ||
| 1122 | _LIBCPP_HIDE_FROM_ABI | |
| 1123 | void __annotate_shrink_front(size_type __old_size, size_type __old_start) const _NOEXCEPT { | |
| 1124 | __annotate_from_to(__old_start, __old_start + (__old_size - size()), __asan_poison, __asan_front_moved); | |
| 1125 | } | |
| 1126 | ||
| 1127 | _LIBCPP_HIDE_FROM_ABI | |
| 1128 | void __annotate_shrink_back(size_type __old_size, size_type __old_start) const _NOEXCEPT { | |
| 1129 | __annotate_from_to(__old_start + size(), __old_start + __old_size, __asan_poison, __asan_back_moved); | |
| 1130 | } | |
| 1131 | ||
| 1132 | _LIBCPP_HIDE_FROM_ABI | |
| 1133 | void __annotate_poison_block(const void *__beginning, const void *__end) const _NOEXCEPT { | |
| 1134 | __annotate_double_ended_contiguous_container(__beginning, __end, __beginning, __end, __end, __end); | |
| 1135 | } | |
| 1136 | ||
| 1137 | _LIBCPP_HIDE_FROM_ABI | |
| 1138 | void __annotate_whole_block(size_t __block_index, __asan_annotation_type __annotation_type) const _NOEXCEPT { | |
| 1139 | __map_const_iterator __block_it = __map_.begin() + __block_index; | |
| 1140 | const void* __block_start = std::__to_address(*__block_it); | |
| 1141 | const void* __block_end = std::__to_address(*__block_it + __block_size); | |
| 1142 | ||
| 1143 | if(__annotation_type == __asan_poison) | |
| 1144 | __annotate_poison_block(__block_start, __block_end); | |
| 1145 | else { | |
| 1146 | __annotate_double_ended_contiguous_container( | |
| 1147 | __block_start, __block_end, __block_start, __block_start, __block_start, __block_end); | |
| 1148 | } | |
| 1149 | } | |
| 1150 | #if !defined(_LIBCPP_HAS_NO_ASAN) | |
| 1151 | ||
| 1152 | public: | |
| 1153 | _LIBCPP_HIDE_FROM_ABI | |
| 1154 | bool __verify_asan_annotations() const _NOEXCEPT { | |
| 1155 | // This function tests deque object annotations. | |
| 1156 | if (empty()) { | |
| 1157 | for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { | |
| 1158 | if (!__sanitizer_verify_double_ended_contiguous_container( | |
| 1159 | std::__to_address(*__it), | |
| 1160 | std::__to_address(*__it), | |
| 1161 | std::__to_address(*__it), | |
| 1162 | std::__to_address(*__it + __block_size))) | |
| 1163 | return false; | |
| 1164 | } | |
| 1165 | ||
| 1166 | return true; | |
| 1167 | } | |
| 1168 | ||
| 1169 | size_type __end = __start_ + size(); | |
| 1170 | __map_const_iterator __first_mp = __map_.begin() + __start_ / __block_size; | |
| 1171 | __map_const_iterator __last_mp = __map_.begin() + (__end - 1) / __block_size; | |
| 1172 | ||
| 1173 | // Pointers to first and after last elements | |
| 1174 | // Those can be in different deque blocks | |
| 1175 | const void* __p_beg = std::__to_address(*__first_mp + (__start_ % __block_size)); | |
| 1176 | const void* __p_end = | |
| 1177 | std::__to_address(*__last_mp + ((__end % __block_size == 0) ? __block_size : __end % __block_size)); | |
| 1178 | ||
| 1179 | for (__map_const_iterator __it = __map_.begin(); __it != __map_.end(); ++__it) { | |
| 1180 | // Go over all blocks, find the place we are in and verify its annotations | |
| 1181 | // Note that __p_end points *behind* the last item. | |
| 1182 | ||
| 1183 | // - blocks before the first block with container elements | |
| 1184 | // - first block with items | |
| 1185 | // - last block with items | |
| 1186 | // - blocks after last block with ciontainer elements | |
| 1187 | ||
| 1188 | // Is the block before or after deque blocks that contain elements? | |
| 1189 | if (__it < __first_mp || __it > __last_mp) { | |
| 1190 | if (!__sanitizer_verify_double_ended_contiguous_container( | |
| 1191 | std::__to_address(*__it), | |
| 1192 | std::__to_address(*__it), | |
| 1193 | std::__to_address(*__it), | |
| 1194 | std::__to_address(*__it + __block_size))) | |
| 1195 | return false; | |
| 1196 | } else { | |
| 1197 | const void* __containers_buffer_beg = (__it == __first_mp) ? __p_beg : (const void*)std::__to_address(*__it); | |
| 1198 | const void* __containers_buffer_end = | |
| 1199 | (__it == __last_mp) ? __p_end : (const void*)std::__to_address(*__it + __block_size); | |
| 1200 | if (!__sanitizer_verify_double_ended_contiguous_container( | |
| 1201 | std::__to_address(*__it), | |
| 1202 | __containers_buffer_beg, | |
| 1203 | __containers_buffer_end, | |
| 1204 | std::__to_address(*__it + __block_size))) { | |
| 1205 | return false; | |
| 1206 | } | |
| 1207 | } | |
| 1208 | } | |
| 1209 | return true; | |
| 1210 | } | |
| 1211 | ||
| 1212 | private: | |
| 1213 | #endif // _LIBCPP_VERIFY_ASAN_DEQUE_ANNOTATIONS | |
| 854 | 1214 | _LIBCPP_HIDE_FROM_ABI |
| 855 | 1215 | bool __maybe_remove_front_spare(bool __keep_one = true) { |
| 856 | 1216 | if (__front_spare_blocks() >= 2 || (!__keep_one && __front_spare_blocks())) { |
| 1217 | __annotate_whole_block(0, __asan_unposion); | |
| 857 | 1218 | __alloc_traits::deallocate(__alloc(), __map_.front(), |
| 858 | 1219 | __block_size); |
| 859 | 1220 | __map_.pop_front(); |
| ... | ... | @@ -866,6 +1227,7 @@ public: |
| 866 | 1227 | _LIBCPP_HIDE_FROM_ABI |
| 867 | 1228 | bool __maybe_remove_back_spare(bool __keep_one = true) { |
| 868 | 1229 | if (__back_spare_blocks() >= 2 || (!__keep_one && __back_spare_blocks())) { |
| 1230 | __annotate_whole_block(__map_.size() - 1, __asan_unposion); | |
| 869 | 1231 | __alloc_traits::deallocate(__alloc(), __map_.back(), |
| 870 | 1232 | __block_size); |
| 871 | 1233 | __map_.pop_back(); |
| ... | ... | @@ -874,12 +1236,44 @@ public: |
| 874 | 1236 | return false; |
| 875 | 1237 | } |
| 876 | 1238 | |
| 1239 | template <class _Iterator, class _Sentinel> | |
| 1240 | _LIBCPP_HIDE_FROM_ABI | |
| 1241 | void __assign_with_sentinel(_Iterator __f, _Sentinel __l); | |
| 1242 | ||
| 1243 | template <class _RandomAccessIterator> | |
| 1244 | _LIBCPP_HIDE_FROM_ABI | |
| 1245 | void __assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n); | |
| 1246 | template <class _Iterator> | |
| 1247 | _LIBCPP_HIDE_FROM_ABI | |
| 1248 | void __assign_with_size(_Iterator __f, difference_type __n); | |
| 1249 | ||
| 1250 | template <class _Iterator, class _Sentinel> | |
| 1251 | _LIBCPP_HIDE_FROM_ABI | |
| 1252 | iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); | |
| 1253 | ||
| 1254 | template <class _Iterator> | |
| 1255 | _LIBCPP_HIDE_FROM_ABI | |
| 1256 | iterator __insert_with_size(const_iterator __p, _Iterator __f, size_type __n); | |
| 1257 | ||
| 1258 | template <class _BiIter, class _Sentinel> | |
| 1259 | _LIBCPP_HIDE_FROM_ABI | |
| 1260 | iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel __sent, size_type __n); | |
| 1261 | template <class _BiIter> | |
| 1262 | _LIBCPP_HIDE_FROM_ABI | |
| 1263 | iterator __insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n); | |
| 1264 | ||
| 877 | 1265 | template <class _InpIter> |
| 878 | 1266 | _LIBCPP_HIDE_FROM_ABI void __append(_InpIter __f, _InpIter __l, |
| 879 | typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type* = 0); | |
| 1267 | typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type* = 0); | |
| 880 | 1268 | template <class _ForIter> |
| 881 | 1269 | _LIBCPP_HIDE_FROM_ABI void __append(_ForIter __f, _ForIter __l, |
| 882 | typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type* = 0); | |
| 1270 | typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type* = 0); | |
| 1271 | ||
| 1272 | template <class _InputIterator> | |
| 1273 | _LIBCPP_HIDE_FROM_ABI void __append_with_size(_InputIterator __from, size_type __n); | |
| 1274 | template <class _InputIterator, class _Sentinel> | |
| 1275 | _LIBCPP_HIDE_FROM_ABI void __append_with_sentinel(_InputIterator __f, _Sentinel __l); | |
| 1276 | ||
| 883 | 1277 | _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); |
| 884 | 1278 | _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const value_type& __v); |
| 885 | 1279 | _LIBCPP_HIDE_FROM_ABI void __erase_to_end(const_iterator __f); |
| ... | ... | @@ -929,7 +1323,7 @@ _LIBCPP_CONSTEXPR const typename allocator_traits<_Alloc>::difference_type deque |
| 929 | 1323 | #if _LIBCPP_STD_VER >= 17 |
| 930 | 1324 | template<class _InputIterator, |
| 931 | 1325 | class _Alloc = allocator<__iter_value_type<_InputIterator>>, |
| 932 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1326 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 933 | 1327 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 934 | 1328 | > |
| 935 | 1329 | deque(_InputIterator, _InputIterator) |
| ... | ... | @@ -937,26 +1331,37 @@ deque(_InputIterator, _InputIterator) |
| 937 | 1331 | |
| 938 | 1332 | template<class _InputIterator, |
| 939 | 1333 | class _Alloc, |
| 940 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1334 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 941 | 1335 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 942 | 1336 | > |
| 943 | 1337 | deque(_InputIterator, _InputIterator, _Alloc) |
| 944 | 1338 | -> deque<__iter_value_type<_InputIterator>, _Alloc>; |
| 945 | 1339 | #endif |
| 946 | 1340 | |
| 1341 | #if _LIBCPP_STD_VER >= 23 | |
| 1342 | template <ranges::input_range _Range, | |
| 1343 | class _Alloc = allocator<ranges::range_value_t<_Range>>, | |
| 1344 | class = enable_if_t<__is_allocator<_Alloc>::value> | |
| 1345 | > | |
| 1346 | deque(from_range_t, _Range&&, _Alloc = _Alloc()) | |
| 1347 | -> deque<ranges::range_value_t<_Range>, _Alloc>; | |
| 1348 | #endif | |
| 1349 | ||
| 947 | 1350 | template <class _Tp, class _Allocator> |
| 948 | 1351 | deque<_Tp, _Allocator>::deque(size_type __n) |
| 949 | 1352 | : __start_(0), __size_(0, __default_init_tag()) |
| 950 | 1353 | { |
| 1354 | __annotate_new(0); | |
| 951 | 1355 | if (__n > 0) |
| 952 | 1356 | __append(__n); |
| 953 | 1357 | } |
| 954 | 1358 | |
| 955 | #if _LIBCPP_STD_VER > 11 | |
| 1359 | #if _LIBCPP_STD_VER >= 14 | |
| 956 | 1360 | template <class _Tp, class _Allocator> |
| 957 | 1361 | deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) |
| 958 | 1362 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) |
| 959 | 1363 | { |
| 1364 | __annotate_new(0); | |
| 960 | 1365 | if (__n > 0) |
| 961 | 1366 | __append(__n); |
| 962 | 1367 | } |
| ... | ... | @@ -966,6 +1371,7 @@ template <class _Tp, class _Allocator> |
| 966 | 1371 | deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) |
| 967 | 1372 | : __start_(0), __size_(0, __default_init_tag()) |
| 968 | 1373 | { |
| 1374 | __annotate_new(0); | |
| 969 | 1375 | if (__n > 0) |
| 970 | 1376 | __append(__n, __v); |
| 971 | 1377 | } |
| ... | ... | @@ -973,18 +1379,20 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) |
| 973 | 1379 | template <class _Tp, class _Allocator> |
| 974 | 1380 | template <class _InputIter> |
| 975 | 1381 | deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, |
| 976 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*) | |
| 1382 | typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) | |
| 977 | 1383 | : __start_(0), __size_(0, __default_init_tag()) |
| 978 | 1384 | { |
| 1385 | __annotate_new(0); | |
| 979 | 1386 | __append(__f, __l); |
| 980 | 1387 | } |
| 981 | 1388 | |
| 982 | 1389 | template <class _Tp, class _Allocator> |
| 983 | 1390 | template <class _InputIter> |
| 984 | 1391 | deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l, const allocator_type& __a, |
| 985 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type*) | |
| 1392 | typename enable_if<__has_input_iterator_category<_InputIter>::value>::type*) | |
| 986 | 1393 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) |
| 987 | 1394 | { |
| 1395 | __annotate_new(0); | |
| 988 | 1396 | __append(__f, __l); |
| 989 | 1397 | } |
| 990 | 1398 | |
| ... | ... | @@ -994,6 +1402,7 @@ deque<_Tp, _Allocator>::deque(const deque& __c) |
| 994 | 1402 | __start_(0), |
| 995 | 1403 | __size_(0, __map_.__alloc()) |
| 996 | 1404 | { |
| 1405 | __annotate_new(0); | |
| 997 | 1406 | __append(__c.begin(), __c.end()); |
| 998 | 1407 | } |
| 999 | 1408 | |
| ... | ... | @@ -1001,6 +1410,7 @@ template <class _Tp, class _Allocator> |
| 1001 | 1410 | deque<_Tp, _Allocator>::deque(const deque& __c, const __type_identity_t<allocator_type>& __a) |
| 1002 | 1411 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) |
| 1003 | 1412 | { |
| 1413 | __annotate_new(0); | |
| 1004 | 1414 | __append(__c.begin(), __c.end()); |
| 1005 | 1415 | } |
| 1006 | 1416 | |
| ... | ... | @@ -1022,6 +1432,7 @@ template <class _Tp, class _Allocator> |
| 1022 | 1432 | deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il) |
| 1023 | 1433 | : __start_(0), __size_(0, __default_init_tag()) |
| 1024 | 1434 | { |
| 1435 | __annotate_new(0); | |
| 1025 | 1436 | __append(__il.begin(), __il.end()); |
| 1026 | 1437 | } |
| 1027 | 1438 | |
| ... | ... | @@ -1029,6 +1440,7 @@ template <class _Tp, class _Allocator> |
| 1029 | 1440 | deque<_Tp, _Allocator>::deque(initializer_list<value_type> __il, const allocator_type& __a) |
| 1030 | 1441 | : __map_(__pointer_allocator(__a)), __start_(0), __size_(0, __a) |
| 1031 | 1442 | { |
| 1443 | __annotate_new(0); | |
| 1032 | 1444 | __append(__il.begin(), __il.end()); |
| 1033 | 1445 | } |
| 1034 | 1446 | |
| ... | ... | @@ -1105,15 +1517,22 @@ template <class _Tp, class _Allocator> |
| 1105 | 1517 | template <class _InputIter> |
| 1106 | 1518 | void |
| 1107 | 1519 | deque<_Tp, _Allocator>::assign(_InputIter __f, _InputIter __l, |
| 1108 | typename enable_if<__is_cpp17_input_iterator<_InputIter>::value && | |
| 1109 | !__is_cpp17_random_access_iterator<_InputIter>::value>::type*) | |
| 1520 | typename enable_if<__has_input_iterator_category<_InputIter>::value && | |
| 1521 | !__has_random_access_iterator_category<_InputIter>::value>::type*) | |
| 1110 | 1522 | { |
| 1523 | __assign_with_sentinel(__f, __l); | |
| 1524 | } | |
| 1525 | ||
| 1526 | template <class _Tp, class _Allocator> | |
| 1527 | template <class _Iterator, class _Sentinel> | |
| 1528 | _LIBCPP_HIDE_FROM_ABI | |
| 1529 | void deque<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { | |
| 1111 | 1530 | iterator __i = begin(); |
| 1112 | 1531 | iterator __e = end(); |
| 1113 | 1532 | for (; __f != __l && __i != __e; ++__f, (void) ++__i) |
| 1114 | 1533 | *__i = *__f; |
| 1115 | 1534 | if (__f != __l) |
| 1116 | __append(__f, __l); | |
| 1535 | __append_with_sentinel(std::move(__f), std::move(__l)); | |
| 1117 | 1536 | else |
| 1118 | 1537 | __erase_to_end(__i); |
| 1119 | 1538 | } |
| ... | ... | @@ -1122,16 +1541,42 @@ template <class _Tp, class _Allocator> |
| 1122 | 1541 | template <class _RAIter> |
| 1123 | 1542 | void |
| 1124 | 1543 | deque<_Tp, _Allocator>::assign(_RAIter __f, _RAIter __l, |
| 1125 | typename enable_if<__is_cpp17_random_access_iterator<_RAIter>::value>::type*) | |
| 1544 | typename enable_if<__has_random_access_iterator_category<_RAIter>::value>::type*) | |
| 1126 | 1545 | { |
| 1127 | if (static_cast<size_type>(__l - __f) > size()) | |
| 1546 | __assign_with_size_random_access(__f, __l - __f); | |
| 1547 | } | |
| 1548 | ||
| 1549 | template <class _Tp, class _Allocator> | |
| 1550 | template <class _RandomAccessIterator> | |
| 1551 | _LIBCPP_HIDE_FROM_ABI | |
| 1552 | void deque<_Tp, _Allocator>::__assign_with_size_random_access(_RandomAccessIterator __f, difference_type __n) { | |
| 1553 | if (static_cast<size_type>(__n) > size()) | |
| 1128 | 1554 | { |
| 1129 | _RAIter __m = __f + size(); | |
| 1130 | _VSTD::copy(__f, __m, begin()); | |
| 1131 | __append(__m, __l); | |
| 1555 | auto __l = __f + size(); | |
| 1556 | std::copy(__f, __l, begin()); | |
| 1557 | __append_with_size(__l, __n - size()); | |
| 1132 | 1558 | } |
| 1133 | 1559 | else |
| 1134 | __erase_to_end(_VSTD::copy(__f, __l, begin())); | |
| 1560 | __erase_to_end(std::copy_n(__f, __n, begin())); | |
| 1561 | } | |
| 1562 | ||
| 1563 | template <class _Tp, class _Allocator> | |
| 1564 | template <class _Iterator> | |
| 1565 | _LIBCPP_HIDE_FROM_ABI | |
| 1566 | void deque<_Tp, _Allocator>::__assign_with_size(_Iterator __f, difference_type __n) { | |
| 1567 | if (static_cast<size_type>(__n) > size()) { | |
| 1568 | auto __added_size = __n - size(); | |
| 1569 | ||
| 1570 | auto __i = begin(); | |
| 1571 | for (auto __count = size(); __count != 0; --__count) { | |
| 1572 | *__i++ = *__f++; | |
| 1573 | } | |
| 1574 | ||
| 1575 | __append_with_size(__f, __added_size); | |
| 1576 | ||
| 1577 | } else { | |
| 1578 | __erase_to_end(std::copy_n(__f, __n, begin())); | |
| 1579 | } | |
| 1135 | 1580 | } |
| 1136 | 1581 | |
| 1137 | 1582 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1183,6 +1628,7 @@ deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT |
| 1183 | 1628 | allocator_type& __a = __alloc(); |
| 1184 | 1629 | if (empty()) |
| 1185 | 1630 | { |
| 1631 | __annotate_delete(); | |
| 1186 | 1632 | while (__map_.size() > 0) |
| 1187 | 1633 | { |
| 1188 | 1634 | __alloc_traits::deallocate(__a, __map_.back(), __block_size); |
| ... | ... | @@ -1282,6 +1728,7 @@ deque<_Tp, _Allocator>::push_back(const value_type& __v) |
| 1282 | 1728 | if (__back_spare() == 0) |
| 1283 | 1729 | __add_back_capacity(); |
| 1284 | 1730 | // __back_spare() >= 1 |
| 1731 | __annotate_increase_back(1); | |
| 1285 | 1732 | __alloc_traits::construct(__a, _VSTD::addressof(*end()), __v); |
| 1286 | 1733 | ++__size(); |
| 1287 | 1734 | } |
| ... | ... | @@ -1294,6 +1741,7 @@ deque<_Tp, _Allocator>::push_front(const value_type& __v) |
| 1294 | 1741 | if (__front_spare() == 0) |
| 1295 | 1742 | __add_front_capacity(); |
| 1296 | 1743 | // __front_spare() >= 1 |
| 1744 | __annotate_increase_front(1); | |
| 1297 | 1745 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); |
| 1298 | 1746 | --__start_; |
| 1299 | 1747 | ++__size(); |
| ... | ... | @@ -1308,13 +1756,14 @@ deque<_Tp, _Allocator>::push_back(value_type&& __v) |
| 1308 | 1756 | if (__back_spare() == 0) |
| 1309 | 1757 | __add_back_capacity(); |
| 1310 | 1758 | // __back_spare() >= 1 |
| 1759 | __annotate_increase_back(1); | |
| 1311 | 1760 | __alloc_traits::construct(__a, _VSTD::addressof(*end()), _VSTD::move(__v)); |
| 1312 | 1761 | ++__size(); |
| 1313 | 1762 | } |
| 1314 | 1763 | |
| 1315 | 1764 | template <class _Tp, class _Allocator> |
| 1316 | 1765 | template <class... _Args> |
| 1317 | #if _LIBCPP_STD_VER > 14 | |
| 1766 | #if _LIBCPP_STD_VER >= 17 | |
| 1318 | 1767 | typename deque<_Tp, _Allocator>::reference |
| 1319 | 1768 | #else |
| 1320 | 1769 | void |
| ... | ... | @@ -1325,10 +1774,11 @@ deque<_Tp, _Allocator>::emplace_back(_Args&&... __args) |
| 1325 | 1774 | if (__back_spare() == 0) |
| 1326 | 1775 | __add_back_capacity(); |
| 1327 | 1776 | // __back_spare() >= 1 |
| 1777 | __annotate_increase_back(1); | |
| 1328 | 1778 | __alloc_traits::construct(__a, _VSTD::addressof(*end()), |
| 1329 | 1779 | _VSTD::forward<_Args>(__args)...); |
| 1330 | 1780 | ++__size(); |
| 1331 | #if _LIBCPP_STD_VER > 14 | |
| 1781 | #if _LIBCPP_STD_VER >= 17 | |
| 1332 | 1782 | return *--end(); |
| 1333 | 1783 | #endif |
| 1334 | 1784 | } |
| ... | ... | @@ -1341,6 +1791,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v) |
| 1341 | 1791 | if (__front_spare() == 0) |
| 1342 | 1792 | __add_front_capacity(); |
| 1343 | 1793 | // __front_spare() >= 1 |
| 1794 | __annotate_increase_front(1); | |
| 1344 | 1795 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); |
| 1345 | 1796 | --__start_; |
| 1346 | 1797 | ++__size(); |
| ... | ... | @@ -1349,7 +1800,7 @@ deque<_Tp, _Allocator>::push_front(value_type&& __v) |
| 1349 | 1800 | |
| 1350 | 1801 | template <class _Tp, class _Allocator> |
| 1351 | 1802 | template <class... _Args> |
| 1352 | #if _LIBCPP_STD_VER > 14 | |
| 1803 | #if _LIBCPP_STD_VER >= 17 | |
| 1353 | 1804 | typename deque<_Tp, _Allocator>::reference |
| 1354 | 1805 | #else |
| 1355 | 1806 | void |
| ... | ... | @@ -1360,10 +1811,11 @@ deque<_Tp, _Allocator>::emplace_front(_Args&&... __args) |
| 1360 | 1811 | if (__front_spare() == 0) |
| 1361 | 1812 | __add_front_capacity(); |
| 1362 | 1813 | // __front_spare() >= 1 |
| 1814 | __annotate_increase_front(1); | |
| 1363 | 1815 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); |
| 1364 | 1816 | --__start_; |
| 1365 | 1817 | ++__size(); |
| 1366 | #if _LIBCPP_STD_VER > 14 | |
| 1818 | #if _LIBCPP_STD_VER >= 17 | |
| 1367 | 1819 | return *begin(); |
| 1368 | 1820 | #endif |
| 1369 | 1821 | } |
| ... | ... | @@ -1380,6 +1832,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) |
| 1380 | 1832 | if (__front_spare() == 0) |
| 1381 | 1833 | __add_front_capacity(); |
| 1382 | 1834 | // __front_spare() >= 1 |
| 1835 | __annotate_increase_front(1); | |
| 1383 | 1836 | if (__pos == 0) |
| 1384 | 1837 | { |
| 1385 | 1838 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::move(__v)); |
| ... | ... | @@ -1403,6 +1856,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, value_type&& __v) |
| 1403 | 1856 | if (__back_spare() == 0) |
| 1404 | 1857 | __add_back_capacity(); |
| 1405 | 1858 | // __back_capacity >= 1 |
| 1859 | __annotate_increase_back(1); | |
| 1406 | 1860 | size_type __de = size() - __pos; |
| 1407 | 1861 | if (__de == 0) |
| 1408 | 1862 | { |
| ... | ... | @@ -1436,6 +1890,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) |
| 1436 | 1890 | if (__front_spare() == 0) |
| 1437 | 1891 | __add_front_capacity(); |
| 1438 | 1892 | // __front_spare() >= 1 |
| 1893 | __annotate_increase_front(1); | |
| 1439 | 1894 | if (__pos == 0) |
| 1440 | 1895 | { |
| 1441 | 1896 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), _VSTD::forward<_Args>(__args)...); |
| ... | ... | @@ -1460,6 +1915,7 @@ deque<_Tp, _Allocator>::emplace(const_iterator __p, _Args&&... __args) |
| 1460 | 1915 | if (__back_spare() == 0) |
| 1461 | 1916 | __add_back_capacity(); |
| 1462 | 1917 | // __back_capacity >= 1 |
| 1918 | __annotate_increase_back(1); | |
| 1463 | 1919 | size_type __de = size() - __pos; |
| 1464 | 1920 | if (__de == 0) |
| 1465 | 1921 | { |
| ... | ... | @@ -1496,6 +1952,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) |
| 1496 | 1952 | if (__front_spare() == 0) |
| 1497 | 1953 | __add_front_capacity(); |
| 1498 | 1954 | // __front_spare() >= 1 |
| 1955 | __annotate_increase_front(1); | |
| 1499 | 1956 | if (__pos == 0) |
| 1500 | 1957 | { |
| 1501 | 1958 | __alloc_traits::construct(__a, _VSTD::addressof(*--begin()), __v); |
| ... | ... | @@ -1522,6 +1979,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, const value_type& __v) |
| 1522 | 1979 | if (__back_spare() == 0) |
| 1523 | 1980 | __add_back_capacity(); |
| 1524 | 1981 | // __back_capacity >= 1 |
| 1982 | __annotate_increase_back(1); | |
| 1525 | 1983 | size_type __de = size() - __pos; |
| 1526 | 1984 | if (__de == 0) |
| 1527 | 1985 | { |
| ... | ... | @@ -1557,6 +2015,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty |
| 1557 | 2015 | if (__n > __front_spare()) |
| 1558 | 2016 | __add_front_capacity(__n - __front_spare()); |
| 1559 | 2017 | // __n <= __front_spare() |
| 2018 | __annotate_increase_front(__n); | |
| 1560 | 2019 | iterator __old_begin = begin(); |
| 1561 | 2020 | iterator __i = __old_begin; |
| 1562 | 2021 | if (__n > __pos) |
| ... | ... | @@ -1581,6 +2040,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, size_type __n, const value_ty |
| 1581 | 2040 | if (__n > __back_capacity) |
| 1582 | 2041 | __add_back_capacity(__n - __back_capacity); |
| 1583 | 2042 | // __n <= __back_capacity |
| 2043 | __annotate_increase_back(__n); | |
| 1584 | 2044 | iterator __old_end = end(); |
| 1585 | 2045 | iterator __i = __old_end; |
| 1586 | 2046 | size_type __de = size() - __pos; |
| ... | ... | @@ -1607,10 +2067,18 @@ template <class _Tp, class _Allocator> |
| 1607 | 2067 | template <class _InputIter> |
| 1608 | 2068 | typename deque<_Tp, _Allocator>::iterator |
| 1609 | 2069 | deque<_Tp, _Allocator>::insert(const_iterator __p, _InputIter __f, _InputIter __l, |
| 1610 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIter>::value>::type*) | |
| 2070 | typename enable_if<__has_exactly_input_iterator_category<_InputIter>::value>::type*) | |
| 1611 | 2071 | { |
| 2072 | return __insert_with_sentinel(__p, __f, __l); | |
| 2073 | } | |
| 2074 | ||
| 2075 | template <class _Tp, class _Allocator> | |
| 2076 | template <class _Iterator, class _Sentinel> | |
| 2077 | _LIBCPP_HIDE_FROM_ABI | |
| 2078 | typename deque<_Tp, _Allocator>::iterator | |
| 2079 | deque<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { | |
| 1612 | 2080 | __split_buffer<value_type, allocator_type&> __buf(__alloc()); |
| 1613 | __buf.__construct_at_end(__f, __l); | |
| 2081 | __buf.__construct_at_end_with_sentinel(std::move(__f), std::move(__l)); | |
| 1614 | 2082 | typedef typename __split_buffer<value_type, allocator_type&>::iterator __bi; |
| 1615 | 2083 | return insert(__p, move_iterator<__bi>(__buf.begin()), move_iterator<__bi>(__buf.end())); |
| 1616 | 2084 | } |
| ... | ... | @@ -1619,11 +2087,18 @@ template <class _Tp, class _Allocator> |
| 1619 | 2087 | template <class _ForwardIterator> |
| 1620 | 2088 | typename deque<_Tp, _Allocator>::iterator |
| 1621 | 2089 | deque<_Tp, _Allocator>::insert(const_iterator __p, _ForwardIterator __f, _ForwardIterator __l, |
| 1622 | typename enable_if<__is_exactly_cpp17_forward_iterator<_ForwardIterator>::value>::type*) | |
| 2090 | typename enable_if<__has_exactly_forward_iterator_category<_ForwardIterator>::value>::type*) | |
| 1623 | 2091 | { |
| 1624 | size_type __n = _VSTD::distance(__f, __l); | |
| 2092 | return __insert_with_size(__p, __f, std::distance(__f, __l)); | |
| 2093 | } | |
| 2094 | ||
| 2095 | template <class _Tp, class _Allocator> | |
| 2096 | template <class _Iterator> | |
| 2097 | _LIBCPP_HIDE_FROM_ABI | |
| 2098 | typename deque<_Tp, _Allocator>::iterator | |
| 2099 | deque<_Tp, _Allocator>::__insert_with_size(const_iterator __p, _Iterator __f, size_type __n) { | |
| 1625 | 2100 | __split_buffer<value_type, allocator_type&> __buf(__n, 0, __alloc()); |
| 1626 | __buf.__construct_at_end(__f, __l); | |
| 2101 | __buf.__construct_at_end_with_size(__f, __n); | |
| 1627 | 2102 | typedef typename __split_buffer<value_type, allocator_type&>::iterator __fwd; |
| 1628 | 2103 | return insert(__p, move_iterator<__fwd>(__buf.begin()), move_iterator<__fwd>(__buf.end())); |
| 1629 | 2104 | } |
| ... | ... | @@ -1632,9 +2107,24 @@ template <class _Tp, class _Allocator> |
| 1632 | 2107 | template <class _BiIter> |
| 1633 | 2108 | typename deque<_Tp, _Allocator>::iterator |
| 1634 | 2109 | deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, |
| 1635 | typename enable_if<__is_cpp17_bidirectional_iterator<_BiIter>::value>::type*) | |
| 2110 | typename enable_if<__has_bidirectional_iterator_category<_BiIter>::value>::type*) | |
| 1636 | 2111 | { |
| 1637 | size_type __n = _VSTD::distance(__f, __l); | |
| 2112 | return __insert_bidirectional(__p, __f, __l, std::distance(__f, __l)); | |
| 2113 | } | |
| 2114 | ||
| 2115 | template <class _Tp, class _Allocator> | |
| 2116 | template <class _BiIter, class _Sentinel> | |
| 2117 | _LIBCPP_HIDE_FROM_ABI | |
| 2118 | typename deque<_Tp, _Allocator>::iterator | |
| 2119 | deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _Sentinel, size_type __n) { | |
| 2120 | return __insert_bidirectional(__p, __f, std::next(__f, __n), __n); | |
| 2121 | } | |
| 2122 | ||
| 2123 | template <class _Tp, class _Allocator> | |
| 2124 | template <class _BiIter> | |
| 2125 | _LIBCPP_HIDE_FROM_ABI | |
| 2126 | typename deque<_Tp, _Allocator>::iterator | |
| 2127 | deque<_Tp, _Allocator>::__insert_bidirectional(const_iterator __p, _BiIter __f, _BiIter __l, size_type __n) { | |
| 1638 | 2128 | size_type __pos = __p - begin(); |
| 1639 | 2129 | size_type __to_end = size() - __pos; |
| 1640 | 2130 | allocator_type& __a = __alloc(); |
| ... | ... | @@ -1643,6 +2133,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, |
| 1643 | 2133 | if (__n > __front_spare()) |
| 1644 | 2134 | __add_front_capacity(__n - __front_spare()); |
| 1645 | 2135 | // __n <= __front_spare() |
| 2136 | __annotate_increase_front(__n); | |
| 1646 | 2137 | iterator __old_begin = begin(); |
| 1647 | 2138 | iterator __i = __old_begin; |
| 1648 | 2139 | _BiIter __m = __f; |
| ... | ... | @@ -1673,6 +2164,7 @@ deque<_Tp, _Allocator>::insert(const_iterator __p, _BiIter __f, _BiIter __l, |
| 1673 | 2164 | if (__n > __back_capacity) |
| 1674 | 2165 | __add_back_capacity(__n - __back_capacity); |
| 1675 | 2166 | // __n <= __back_capacity |
| 2167 | __annotate_increase_back(__n); | |
| 1676 | 2168 | iterator __old_end = end(); |
| 1677 | 2169 | iterator __i = __old_end; |
| 1678 | 2170 | _BiIter __m = __l; |
| ... | ... | @@ -1701,8 +2193,15 @@ template <class _Tp, class _Allocator> |
| 1701 | 2193 | template <class _InpIter> |
| 1702 | 2194 | void |
| 1703 | 2195 | deque<_Tp, _Allocator>::__append(_InpIter __f, _InpIter __l, |
| 1704 | typename enable_if<__is_exactly_cpp17_input_iterator<_InpIter>::value>::type*) | |
| 2196 | typename enable_if<__has_exactly_input_iterator_category<_InpIter>::value>::type*) | |
| 1705 | 2197 | { |
| 2198 | __append_with_sentinel(__f, __l); | |
| 2199 | } | |
| 2200 | ||
| 2201 | template <class _Tp, class _Allocator> | |
| 2202 | template <class _InputIterator, class _Sentinel> | |
| 2203 | _LIBCPP_HIDE_FROM_ABI | |
| 2204 | void deque<_Tp, _Allocator>::__append_with_sentinel(_InputIterator __f, _Sentinel __l) { | |
| 1706 | 2205 | for (; __f != __l; ++__f) |
| 1707 | 2206 | #ifdef _LIBCPP_CXX03_LANG |
| 1708 | 2207 | push_back(*__f); |
| ... | ... | @@ -1715,14 +2214,22 @@ template <class _Tp, class _Allocator> |
| 1715 | 2214 | template <class _ForIter> |
| 1716 | 2215 | void |
| 1717 | 2216 | deque<_Tp, _Allocator>::__append(_ForIter __f, _ForIter __l, |
| 1718 | typename enable_if<__is_cpp17_forward_iterator<_ForIter>::value>::type*) | |
| 2217 | typename enable_if<__has_forward_iterator_category<_ForIter>::value>::type*) | |
| 1719 | 2218 | { |
| 1720 | size_type __n = _VSTD::distance(__f, __l); | |
| 2219 | __append_with_size(__f, std::distance(__f, __l)); | |
| 2220 | } | |
| 2221 | ||
| 2222 | template <class _Tp, class _Allocator> | |
| 2223 | template <class _InputIterator> | |
| 2224 | _LIBCPP_HIDE_FROM_ABI | |
| 2225 | void deque<_Tp, _Allocator>::__append_with_size(_InputIterator __f, size_type __n) { | |
| 1721 | 2226 | allocator_type& __a = __alloc(); |
| 1722 | 2227 | size_type __back_capacity = __back_spare(); |
| 1723 | 2228 | if (__n > __back_capacity) |
| 1724 | 2229 | __add_back_capacity(__n - __back_capacity); |
| 2230 | ||
| 1725 | 2231 | // __n <= __back_capacity |
| 2232 | __annotate_increase_back(__n); | |
| 1726 | 2233 | for (__deque_block_range __br : __deque_range(end(), end() + __n)) { |
| 1727 | 2234 | _ConstructTransaction __tx(this, __br); |
| 1728 | 2235 | for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__f) { |
| ... | ... | @@ -1740,6 +2247,7 @@ deque<_Tp, _Allocator>::__append(size_type __n) |
| 1740 | 2247 | if (__n > __back_capacity) |
| 1741 | 2248 | __add_back_capacity(__n - __back_capacity); |
| 1742 | 2249 | // __n <= __back_capacity |
| 2250 | __annotate_increase_back(__n); | |
| 1743 | 2251 | for (__deque_block_range __br : __deque_range(end(), end() + __n)) { |
| 1744 | 2252 | _ConstructTransaction __tx(this, __br); |
| 1745 | 2253 | for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { |
| ... | ... | @@ -1757,6 +2265,7 @@ deque<_Tp, _Allocator>::__append(size_type __n, const value_type& __v) |
| 1757 | 2265 | if (__n > __back_capacity) |
| 1758 | 2266 | __add_back_capacity(__n - __back_capacity); |
| 1759 | 2267 | // __n <= __back_capacity |
| 2268 | __annotate_increase_back(__n); | |
| 1760 | 2269 | for (__deque_block_range __br : __deque_range(end(), end() + __n)) { |
| 1761 | 2270 | _ConstructTransaction __tx(this, __br); |
| 1762 | 2271 | for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { |
| ... | ... | @@ -1824,6 +2333,7 @@ deque<_Tp, _Allocator>::__add_front_capacity() |
| 1824 | 2333 | __block_size / 2 : |
| 1825 | 2334 | __start_ + __block_size; |
| 1826 | 2335 | } |
| 2336 | __annotate_whole_block(0, __asan_poison); | |
| 1827 | 2337 | } |
| 1828 | 2338 | |
| 1829 | 2339 | // Create front capacity for __n elements. |
| ... | ... | @@ -1859,6 +2369,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) |
| 1859 | 2369 | if (__map_.__front_spare() == 0) |
| 1860 | 2370 | break; |
| 1861 | 2371 | __map_.push_front(__alloc_traits::allocate(__a, __block_size)); |
| 2372 | __annotate_whole_block(0, __asan_poison); | |
| 1862 | 2373 | } |
| 1863 | 2374 | for (; __nb > 0; --__nb, ++__back_capacity) |
| 1864 | 2375 | __map_.push_back(__alloc_traits::allocate(__a, __block_size)); |
| ... | ... | @@ -1869,6 +2380,7 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) |
| 1869 | 2380 | pointer __pt = __map_.back(); |
| 1870 | 2381 | __map_.pop_back(); |
| 1871 | 2382 | __map_.push_front(__pt); |
| 2383 | __annotate_whole_block(0, __asan_poison); | |
| 1872 | 2384 | } |
| 1873 | 2385 | } |
| 1874 | 2386 | // Else need to allocate __nb buffers, *and* we need to reallocate __map_. |
| ... | ... | @@ -1879,22 +2391,28 @@ deque<_Tp, _Allocator>::__add_front_capacity(size_type __n) |
| 1879 | 2391 | __buf(std::max<size_type>(2* __map_.capacity(), |
| 1880 | 2392 | __nb + __map_.size()), |
| 1881 | 2393 | 0, __map_.__alloc()); |
| 1882 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2394 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1883 | 2395 | try |
| 1884 | 2396 | { |
| 1885 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1886 | for (; __nb > 0; --__nb) | |
| 2397 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2398 | for (; __nb > 0; --__nb) { | |
| 1887 | 2399 | __buf.push_back(__alloc_traits::allocate(__a, __block_size)); |
| 1888 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2400 | // ASan: this is empty container, we have to poison whole block | |
| 2401 | __annotate_poison_block( | |
| 2402 | std::__to_address(__buf.back()), | |
| 2403 | std::__to_address(__buf.back() + __block_size)); | |
| 2404 | } | |
| 2405 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1889 | 2406 | } |
| 1890 | 2407 | catch (...) |
| 1891 | 2408 | { |
| 2409 | __annotate_delete(); | |
| 1892 | 2410 | for (__map_pointer __i = __buf.begin(); |
| 1893 | 2411 | __i != __buf.end(); ++__i) |
| 1894 | 2412 | __alloc_traits::deallocate(__a, *__i, __block_size); |
| 1895 | 2413 | throw; |
| 1896 | 2414 | } |
| 1897 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2415 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1898 | 2416 | for (; __back_capacity > 0; --__back_capacity) |
| 1899 | 2417 | { |
| 1900 | 2418 | __buf.push_back(__map_.back()); |
| ... | ... | @@ -1940,6 +2458,7 @@ deque<_Tp, _Allocator>::__add_back_capacity() |
| 1940 | 2458 | __map_.pop_front(); |
| 1941 | 2459 | __map_.push_back(__pt); |
| 1942 | 2460 | } |
| 2461 | __annotate_whole_block(__map_.size() - 1, __asan_poison); | |
| 1943 | 2462 | } |
| 1944 | 2463 | // Else need to allocate 1 buffer, *and* we need to reallocate __map_. |
| 1945 | 2464 | else |
| ... | ... | @@ -1963,6 +2482,7 @@ deque<_Tp, _Allocator>::__add_back_capacity() |
| 1963 | 2482 | _VSTD::swap(__map_.__begin_, __buf.__begin_); |
| 1964 | 2483 | _VSTD::swap(__map_.__end_, __buf.__end_); |
| 1965 | 2484 | _VSTD::swap(__map_.__end_cap(), __buf.__end_cap()); |
| 2485 | __annotate_whole_block(__map_.size() - 1, __asan_poison); | |
| 1966 | 2486 | } |
| 1967 | 2487 | } |
| 1968 | 2488 | |
| ... | ... | @@ -1999,10 +2519,13 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) |
| 1999 | 2519 | if (__map_.__back_spare() == 0) |
| 2000 | 2520 | break; |
| 2001 | 2521 | __map_.push_back(__alloc_traits::allocate(__a, __block_size)); |
| 2522 | __annotate_whole_block(__map_.size() - 1, __asan_poison); | |
| 2002 | 2523 | } |
| 2003 | 2524 | for (; __nb > 0; --__nb, ++__front_capacity, __start_ += |
| 2004 | __block_size - (__map_.size() == 1)) | |
| 2525 | __block_size - (__map_.size() == 1)) { | |
| 2005 | 2526 | __map_.push_front(__alloc_traits::allocate(__a, __block_size)); |
| 2527 | __annotate_whole_block(0, __asan_poison); | |
| 2528 | } | |
| 2006 | 2529 | // Done allocating, reorder capacity |
| 2007 | 2530 | __start_ -= __block_size * __front_capacity; |
| 2008 | 2531 | for (; __front_capacity > 0; --__front_capacity) |
| ... | ... | @@ -2021,22 +2544,28 @@ deque<_Tp, _Allocator>::__add_back_capacity(size_type __n) |
| 2021 | 2544 | __nb + __map_.size()), |
| 2022 | 2545 | __map_.size() - __front_capacity, |
| 2023 | 2546 | __map_.__alloc()); |
| 2024 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2547 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2025 | 2548 | try |
| 2026 | 2549 | { |
| 2027 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2028 | for (; __nb > 0; --__nb) | |
| 2550 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2551 | for (; __nb > 0; --__nb) { | |
| 2029 | 2552 | __buf.push_back(__alloc_traits::allocate(__a, __block_size)); |
| 2030 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2553 | // ASan: this is an empty container, we have to poison the whole block | |
| 2554 | __annotate_poison_block( | |
| 2555 | std::__to_address(__buf.back()), | |
| 2556 | std::__to_address(__buf.back() + __block_size)); | |
| 2557 | } | |
| 2558 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2031 | 2559 | } |
| 2032 | 2560 | catch (...) |
| 2033 | 2561 | { |
| 2562 | __annotate_delete(); | |
| 2034 | 2563 | for (__map_pointer __i = __buf.begin(); |
| 2035 | 2564 | __i != __buf.end(); ++__i) |
| 2036 | 2565 | __alloc_traits::deallocate(__a, *__i, __block_size); |
| 2037 | 2566 | throw; |
| 2038 | 2567 | } |
| 2039 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2568 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2040 | 2569 | for (; __front_capacity > 0; --__front_capacity) |
| 2041 | 2570 | { |
| 2042 | 2571 | __buf.push_back(__map_.front()); |
| ... | ... | @@ -2057,12 +2586,15 @@ template <class _Tp, class _Allocator> |
| 2057 | 2586 | void |
| 2058 | 2587 | deque<_Tp, _Allocator>::pop_front() |
| 2059 | 2588 | { |
| 2589 | size_type __old_sz = size(); | |
| 2590 | size_type __old_start = __start_; | |
| 2060 | 2591 | allocator_type& __a = __alloc(); |
| 2061 | 2592 | __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + |
| 2062 | 2593 | __start_ / __block_size) + |
| 2063 | 2594 | __start_ % __block_size)); |
| 2064 | 2595 | --__size(); |
| 2065 | 2596 | ++__start_; |
| 2597 | __annotate_shrink_front(__old_sz, __old_start); | |
| 2066 | 2598 | __maybe_remove_front_spare(); |
| 2067 | 2599 | } |
| 2068 | 2600 | |
| ... | ... | @@ -2070,13 +2602,16 @@ template <class _Tp, class _Allocator> |
| 2070 | 2602 | void |
| 2071 | 2603 | deque<_Tp, _Allocator>::pop_back() |
| 2072 | 2604 | { |
| 2073 | _LIBCPP_ASSERT(!empty(), "deque::pop_back called on an empty deque"); | |
| 2605 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "deque::pop_back called on an empty deque"); | |
| 2606 | size_type __old_sz = size(); | |
| 2607 | size_type __old_start = __start_; | |
| 2074 | 2608 | allocator_type& __a = __alloc(); |
| 2075 | 2609 | size_type __p = size() + __start_ - 1; |
| 2076 | 2610 | __alloc_traits::destroy(__a, _VSTD::__to_address(*(__map_.begin() + |
| 2077 | 2611 | __p / __block_size) + |
| 2078 | 2612 | __p % __block_size)); |
| 2079 | 2613 | --__size(); |
| 2614 | __annotate_shrink_back(__old_sz, __old_start); | |
| 2080 | 2615 | __maybe_remove_back_spare(); |
| 2081 | 2616 | } |
| 2082 | 2617 | |
| ... | ... | @@ -2216,6 +2751,8 @@ template <class _Tp, class _Allocator> |
| 2216 | 2751 | typename deque<_Tp, _Allocator>::iterator |
| 2217 | 2752 | deque<_Tp, _Allocator>::erase(const_iterator __f) |
| 2218 | 2753 | { |
| 2754 | size_type __old_sz = size(); | |
| 2755 | size_type __old_start = __start_; | |
| 2219 | 2756 | iterator __b = begin(); |
| 2220 | 2757 | difference_type __pos = __f - __b; |
| 2221 | 2758 | iterator __p = __b + __pos; |
| ... | ... | @@ -2226,6 +2763,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f) |
| 2226 | 2763 | __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); |
| 2227 | 2764 | --__size(); |
| 2228 | 2765 | ++__start_; |
| 2766 | __annotate_shrink_front(__old_sz, __old_start); | |
| 2229 | 2767 | __maybe_remove_front_spare(); |
| 2230 | 2768 | } |
| 2231 | 2769 | else |
| ... | ... | @@ -2233,6 +2771,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f) |
| 2233 | 2771 | iterator __i = _VSTD::move(_VSTD::next(__p), end(), __p); |
| 2234 | 2772 | __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); |
| 2235 | 2773 | --__size(); |
| 2774 | __annotate_shrink_back(__old_sz, __old_start); | |
| 2236 | 2775 | __maybe_remove_back_spare(); |
| 2237 | 2776 | } |
| 2238 | 2777 | return begin() + __pos; |
| ... | ... | @@ -2242,6 +2781,8 @@ template <class _Tp, class _Allocator> |
| 2242 | 2781 | typename deque<_Tp, _Allocator>::iterator |
| 2243 | 2782 | deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) |
| 2244 | 2783 | { |
| 2784 | size_type __old_sz = size(); | |
| 2785 | size_type __old_start = __start_; | |
| 2245 | 2786 | difference_type __n = __l - __f; |
| 2246 | 2787 | iterator __b = begin(); |
| 2247 | 2788 | difference_type __pos = __f - __b; |
| ... | ... | @@ -2256,6 +2797,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) |
| 2256 | 2797 | __alloc_traits::destroy(__a, _VSTD::addressof(*__b)); |
| 2257 | 2798 | __size() -= __n; |
| 2258 | 2799 | __start_ += __n; |
| 2800 | __annotate_shrink_front(__old_sz, __old_start); | |
| 2259 | 2801 | while (__maybe_remove_front_spare()) { |
| 2260 | 2802 | } |
| 2261 | 2803 | } |
| ... | ... | @@ -2265,6 +2807,7 @@ deque<_Tp, _Allocator>::erase(const_iterator __f, const_iterator __l) |
| 2265 | 2807 | for (iterator __e = end(); __i != __e; ++__i) |
| 2266 | 2808 | __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); |
| 2267 | 2809 | __size() -= __n; |
| 2810 | __annotate_shrink_back(__old_sz, __old_start); | |
| 2268 | 2811 | while (__maybe_remove_back_spare()) { |
| 2269 | 2812 | } |
| 2270 | 2813 | } |
| ... | ... | @@ -2276,6 +2819,8 @@ template <class _Tp, class _Allocator> |
| 2276 | 2819 | void |
| 2277 | 2820 | deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) |
| 2278 | 2821 | { |
| 2822 | size_type __old_sz = size(); | |
| 2823 | size_type __old_start = __start_; | |
| 2279 | 2824 | iterator __e = end(); |
| 2280 | 2825 | difference_type __n = __e - __f; |
| 2281 | 2826 | if (__n > 0) |
| ... | ... | @@ -2286,6 +2831,7 @@ deque<_Tp, _Allocator>::__erase_to_end(const_iterator __f) |
| 2286 | 2831 | for (iterator __p = __b + __pos; __p != __e; ++__p) |
| 2287 | 2832 | __alloc_traits::destroy(__a, _VSTD::addressof(*__p)); |
| 2288 | 2833 | __size() -= __n; |
| 2834 | __annotate_shrink_back(__old_sz, __old_start); | |
| 2289 | 2835 | while (__maybe_remove_back_spare()) { |
| 2290 | 2836 | } |
| 2291 | 2837 | } |
| ... | ... | @@ -2313,6 +2859,7 @@ inline |
| 2313 | 2859 | void |
| 2314 | 2860 | deque<_Tp, _Allocator>::clear() _NOEXCEPT |
| 2315 | 2861 | { |
| 2862 | __annotate_delete(); | |
| 2316 | 2863 | allocator_type& __a = __alloc(); |
| 2317 | 2864 | for (iterator __i = begin(), __e = end(); __i != __e; ++__i) |
| 2318 | 2865 | __alloc_traits::destroy(__a, _VSTD::addressof(*__i)); |
| ... | ... | @@ -2331,6 +2878,7 @@ deque<_Tp, _Allocator>::clear() _NOEXCEPT |
| 2331 | 2878 | __start_ = __block_size; |
| 2332 | 2879 | break; |
| 2333 | 2880 | } |
| 2881 | __annotate_new(0); | |
| 2334 | 2882 | } |
| 2335 | 2883 | |
| 2336 | 2884 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -2342,6 +2890,8 @@ operator==(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) |
| 2342 | 2890 | return __sz == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 2343 | 2891 | } |
| 2344 | 2892 | |
| 2893 | #if _LIBCPP_STD_VER <= 17 | |
| 2894 | ||
| 2345 | 2895 | template <class _Tp, class _Allocator> |
| 2346 | 2896 | inline _LIBCPP_HIDE_FROM_ABI |
| 2347 | 2897 | bool |
| ... | ... | @@ -2382,6 +2932,17 @@ operator<=(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) |
| 2382 | 2932 | return !(__y < __x); |
| 2383 | 2933 | } |
| 2384 | 2934 | |
| 2935 | #else // _LIBCPP_STD_VER <= 17 | |
| 2936 | ||
| 2937 | template <class _Tp, class _Allocator> | |
| 2938 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> | |
| 2939 | operator<=>(const deque<_Tp, _Allocator>& __x, const deque<_Tp, _Allocator>& __y) { | |
| 2940 | return std::lexicographical_compare_three_way( | |
| 2941 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); | |
| 2942 | } | |
| 2943 | ||
| 2944 | #endif // _LIBCPP_STD_VER <= 17 | |
| 2945 | ||
| 2385 | 2946 | template <class _Tp, class _Allocator> |
| 2386 | 2947 | inline _LIBCPP_HIDE_FROM_ABI |
| 2387 | 2948 | void |
| ... | ... | @@ -2391,7 +2952,7 @@ swap(deque<_Tp, _Allocator>& __x, deque<_Tp, _Allocator>& __y) |
| 2391 | 2952 | __x.swap(__y); |
| 2392 | 2953 | } |
| 2393 | 2954 | |
| 2394 | #if _LIBCPP_STD_VER > 17 | |
| 2955 | #if _LIBCPP_STD_VER >= 20 | |
| 2395 | 2956 | template <class _Tp, class _Allocator, class _Up> |
| 2396 | 2957 | inline _LIBCPP_HIDE_FROM_ABI typename deque<_Tp, _Allocator>::size_type |
| 2397 | 2958 | erase(deque<_Tp, _Allocator>& __c, const _Up& __v) { |
| ... | ... | @@ -2415,15 +2976,15 @@ template <> |
| 2415 | 2976 | inline constexpr bool __format::__enable_insertable<std::deque<wchar_t>> = true; |
| 2416 | 2977 | #endif |
| 2417 | 2978 | |
| 2418 | #endif // _LIBCPP_STD_VER > 17 | |
| 2979 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2419 | 2980 | |
| 2420 | 2981 | _LIBCPP_END_NAMESPACE_STD |
| 2421 | 2982 | |
| 2422 | #if _LIBCPP_STD_VER > 14 | |
| 2983 | #if _LIBCPP_STD_VER >= 17 | |
| 2423 | 2984 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 2424 | 2985 | namespace pmr { |
| 2425 | 2986 | template <class _ValueT> |
| 2426 | using deque = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 2987 | using deque _LIBCPP_AVAILABILITY_PMR = std::deque<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 2427 | 2988 | } // namespace pmr |
| 2428 | 2989 | _LIBCPP_END_NAMESPACE_STD |
| 2429 | 2990 | #endif |
| ... | ... | @@ -2434,9 +2995,11 @@ _LIBCPP_POP_MACROS |
| 2434 | 2995 | # include <algorithm> |
| 2435 | 2996 | # include <atomic> |
| 2436 | 2997 | # include <concepts> |
| 2998 | # include <cstdlib> | |
| 2437 | 2999 | # include <functional> |
| 2438 | 3000 | # include <iosfwd> |
| 2439 | 3001 | # include <iterator> |
| 3002 | # include <type_traits> | |
| 2440 | 3003 | # include <typeinfo> |
| 2441 | 3004 | #endif |
| 2442 | 3005 |
lib/libcxx/include/exception+6-293| ... | ... | @@ -77,307 +77,20 @@ template <class E> void rethrow_if_nested(const E& e); |
| 77 | 77 | */ |
| 78 | 78 | |
| 79 | 79 | #include <__assert> // all public C++ headers provide the assertion handler |
| 80 | #include <__availability> | |
| 81 | 80 | #include <__config> |
| 82 | #include <__memory/addressof.h> | |
| 83 | #include <__type_traits/decay.h> | |
| 84 | #include <__type_traits/is_base_of.h> | |
| 85 | #include <__type_traits/is_class.h> | |
| 86 | #include <__type_traits/is_convertible.h> | |
| 87 | #include <__type_traits/is_copy_constructible.h> | |
| 88 | #include <__type_traits/is_final.h> | |
| 89 | #include <__type_traits/is_polymorphic.h> | |
| 90 | #include <cstddef> | |
| 91 | #include <cstdlib> | |
| 81 | #include <__exception/exception.h> | |
| 82 | #include <__exception/exception_ptr.h> | |
| 83 | #include <__exception/nested_exception.h> | |
| 84 | #include <__exception/operations.h> | |
| 85 | #include <__exception/terminate.h> | |
| 92 | 86 | #include <version> |
| 93 | 87 | |
| 94 | // <vcruntime_exception.h> defines its own std::exception and std::bad_exception types, | |
| 95 | // which we use in order to be ABI-compatible with other STLs on Windows. | |
| 96 | #if defined(_LIBCPP_ABI_VCRUNTIME) | |
| 97 | # include <vcruntime_exception.h> | |
| 98 | #endif | |
| 99 | ||
| 100 | 88 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 101 | 89 | # pragma GCC system_header |
| 102 | 90 | #endif |
| 103 | 91 | |
| 104 | namespace std // purposefully not using versioning namespace | |
| 105 | { | |
| 106 | ||
| 107 | #if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0) | |
| 108 | // The std::exception class was already included above, but we're explicit about this condition here for clarity. | |
| 109 | ||
| 110 | #elif defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 | |
| 111 | // However, <vcruntime_exception.h> does not define std::exception and std::bad_exception | |
| 112 | // when _HAS_EXCEPTIONS == 0. | |
| 113 | // | |
| 114 | // Since libc++ still wants to provide the std::exception hierarchy even when _HAS_EXCEPTIONS == 0 | |
| 115 | // (after all those are simply types like any other), we define an ABI-compatible version | |
| 116 | // of the VCRuntime std::exception and std::bad_exception types in that mode. | |
| 117 | ||
| 118 | struct __std_exception_data { | |
| 119 | char const* _What; | |
| 120 | bool _DoFree; | |
| 121 | }; | |
| 122 | ||
| 123 | class exception { // base of all library exceptions | |
| 124 | public: | |
| 125 | exception() _NOEXCEPT : __data_() {} | |
| 126 | ||
| 127 | explicit exception(char const* __message) _NOEXCEPT : __data_() { | |
| 128 | __data_._What = __message; | |
| 129 | __data_._DoFree = true; | |
| 130 | } | |
| 131 | ||
| 132 | exception(exception const&) _NOEXCEPT {} | |
| 133 | ||
| 134 | exception& operator=(exception const&) _NOEXCEPT { return *this; } | |
| 135 | ||
| 136 | virtual ~exception() _NOEXCEPT {} | |
| 137 | ||
| 138 | virtual char const* what() const _NOEXCEPT { return __data_._What ? __data_._What : "Unknown exception"; } | |
| 139 | ||
| 140 | private: | |
| 141 | __std_exception_data __data_; | |
| 142 | }; | |
| 143 | ||
| 144 | class bad_exception : public exception { | |
| 145 | public: | |
| 146 | bad_exception() _NOEXCEPT : exception("bad exception") {} | |
| 147 | }; | |
| 148 | ||
| 149 | #else // !defined(_LIBCPP_ABI_VCRUNTIME) | |
| 150 | // On all other platforms, we define our own std::exception and std::bad_exception types | |
| 151 | // regardless of whether exceptions are turned on as a language feature. | |
| 152 | ||
| 153 | class _LIBCPP_EXCEPTION_ABI exception { | |
| 154 | public: | |
| 155 | _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} | |
| 156 | _LIBCPP_INLINE_VISIBILITY exception(const exception&) _NOEXCEPT = default; | |
| 157 | ||
| 158 | virtual ~exception() _NOEXCEPT; | |
| 159 | virtual const char* what() const _NOEXCEPT; | |
| 160 | }; | |
| 161 | ||
| 162 | class _LIBCPP_EXCEPTION_ABI bad_exception : public exception { | |
| 163 | public: | |
| 164 | _LIBCPP_INLINE_VISIBILITY bad_exception() _NOEXCEPT {} | |
| 165 | ~bad_exception() _NOEXCEPT override; | |
| 166 | const char* what() const _NOEXCEPT override; | |
| 167 | }; | |
| 168 | #endif // !_LIBCPP_ABI_VCRUNTIME | |
| 169 | ||
| 170 | #if _LIBCPP_STD_VER <= 14 \ | |
| 171 | || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) \ | |
| 172 | || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 173 | typedef void (*unexpected_handler)(); | |
| 174 | _LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; | |
| 175 | _LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; | |
| 176 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); | |
| 177 | #endif | |
| 178 | ||
| 179 | typedef void (*terminate_handler)(); | |
| 180 | _LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; | |
| 181 | _LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; | |
| 182 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; | |
| 183 | ||
| 184 | _LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; | |
| 185 | _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT; | |
| 186 | ||
| 187 | class _LIBCPP_TYPE_VIS exception_ptr; | |
| 188 | ||
| 189 | _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; | |
| 190 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); | |
| 191 | ||
| 192 | #ifndef _LIBCPP_ABI_MICROSOFT | |
| 193 | ||
| 194 | class _LIBCPP_TYPE_VIS exception_ptr | |
| 195 | { | |
| 196 | void* __ptr_; | |
| 197 | public: | |
| 198 | _LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {} | |
| 199 | _LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} | |
| 200 | ||
| 201 | exception_ptr(const exception_ptr&) _NOEXCEPT; | |
| 202 | exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; | |
| 203 | ~exception_ptr() _NOEXCEPT; | |
| 204 | ||
| 205 | _LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT | |
| 206 | {return __ptr_ != nullptr;} | |
| 207 | ||
| 208 | friend _LIBCPP_INLINE_VISIBILITY | |
| 209 | bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT | |
| 210 | {return __x.__ptr_ == __y.__ptr_;} | |
| 211 | ||
| 212 | friend _LIBCPP_INLINE_VISIBILITY | |
| 213 | bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT | |
| 214 | {return !(__x == __y);} | |
| 215 | ||
| 216 | friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; | |
| 217 | friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); | |
| 218 | }; | |
| 219 | ||
| 220 | template<class _Ep> | |
| 221 | _LIBCPP_INLINE_VISIBILITY exception_ptr | |
| 222 | make_exception_ptr(_Ep __e) _NOEXCEPT | |
| 223 | { | |
| 224 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 225 | try | |
| 226 | { | |
| 227 | throw __e; | |
| 228 | } | |
| 229 | catch (...) | |
| 230 | { | |
| 231 | return current_exception(); | |
| 232 | } | |
| 233 | #else | |
| 234 | ((void)__e); | |
| 235 | _VSTD::abort(); | |
| 236 | #endif | |
| 237 | } | |
| 238 | ||
| 239 | #else // _LIBCPP_ABI_MICROSOFT | |
| 240 | ||
| 241 | class _LIBCPP_TYPE_VIS exception_ptr | |
| 242 | { | |
| 243 | _LIBCPP_DIAGNOSTIC_PUSH | |
| 244 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") | |
| 245 | void* __ptr1_; | |
| 246 | void* __ptr2_; | |
| 247 | _LIBCPP_DIAGNOSTIC_POP | |
| 248 | public: | |
| 249 | exception_ptr() _NOEXCEPT; | |
| 250 | exception_ptr(nullptr_t) _NOEXCEPT; | |
| 251 | exception_ptr(const exception_ptr& __other) _NOEXCEPT; | |
| 252 | exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT; | |
| 253 | exception_ptr& operator=(nullptr_t) _NOEXCEPT; | |
| 254 | ~exception_ptr() _NOEXCEPT; | |
| 255 | explicit operator bool() const _NOEXCEPT; | |
| 256 | }; | |
| 257 | ||
| 258 | _LIBCPP_FUNC_VIS | |
| 259 | bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; | |
| 260 | ||
| 261 | inline _LIBCPP_INLINE_VISIBILITY | |
| 262 | bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT | |
| 263 | {return !(__x == __y);} | |
| 264 | ||
| 265 | _LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; | |
| 266 | ||
| 267 | _LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr); | |
| 268 | _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; | |
| 269 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); | |
| 270 | ||
| 271 | // This is a built-in template function which automagically extracts the required | |
| 272 | // information. | |
| 273 | template <class _E> void *__GetExceptionInfo(_E); | |
| 274 | ||
| 275 | template<class _Ep> | |
| 276 | _LIBCPP_INLINE_VISIBILITY exception_ptr | |
| 277 | make_exception_ptr(_Ep __e) _NOEXCEPT | |
| 278 | { | |
| 279 | return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e)); | |
| 280 | } | |
| 281 | ||
| 282 | #endif // _LIBCPP_ABI_MICROSOFT | |
| 283 | // nested_exception | |
| 284 | ||
| 285 | class _LIBCPP_EXCEPTION_ABI nested_exception | |
| 286 | { | |
| 287 | exception_ptr __ptr_; | |
| 288 | public: | |
| 289 | nested_exception() _NOEXCEPT; | |
| 290 | // nested_exception(const nested_exception&) noexcept = default; | |
| 291 | // nested_exception& operator=(const nested_exception&) noexcept = default; | |
| 292 | virtual ~nested_exception() _NOEXCEPT; | |
| 293 | ||
| 294 | // access functions | |
| 295 | _LIBCPP_NORETURN void rethrow_nested() const; | |
| 296 | _LIBCPP_INLINE_VISIBILITY exception_ptr nested_ptr() const _NOEXCEPT {return __ptr_;} | |
| 297 | }; | |
| 298 | ||
| 299 | template <class _Tp> | |
| 300 | struct __nested | |
| 301 | : public _Tp, | |
| 302 | public nested_exception | |
| 303 | { | |
| 304 | _LIBCPP_INLINE_VISIBILITY explicit __nested(const _Tp& __t) : _Tp(__t) {} | |
| 305 | }; | |
| 306 | ||
| 307 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 308 | template <class _Tp, class _Up, bool> | |
| 309 | struct __throw_with_nested; | |
| 310 | ||
| 311 | template <class _Tp, class _Up> | |
| 312 | struct __throw_with_nested<_Tp, _Up, true> { | |
| 313 | _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void | |
| 314 | __do_throw(_Tp&& __t) | |
| 315 | { | |
| 316 | throw __nested<_Up>(static_cast<_Tp&&>(__t)); | |
| 317 | } | |
| 318 | }; | |
| 319 | ||
| 320 | template <class _Tp, class _Up> | |
| 321 | struct __throw_with_nested<_Tp, _Up, false> { | |
| 322 | _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void | |
| 323 | #ifndef _LIBCPP_CXX03_LANG | |
| 324 | __do_throw(_Tp&& __t) | |
| 325 | #else | |
| 326 | __do_throw (_Tp& __t) | |
| 327 | #endif // _LIBCPP_CXX03_LANG | |
| 328 | { | |
| 329 | throw static_cast<_Tp&&>(__t); | |
| 330 | } | |
| 331 | }; | |
| 332 | #endif | |
| 333 | ||
| 334 | template <class _Tp> | |
| 335 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI | |
| 336 | void | |
| 337 | throw_with_nested(_Tp&& __t) | |
| 338 | { | |
| 339 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 340 | typedef typename decay<_Tp>::type _Up; | |
| 341 | static_assert( is_copy_constructible<_Up>::value, "type thrown must be CopyConstructible"); | |
| 342 | __throw_with_nested<_Tp, _Up, | |
| 343 | is_class<_Up>::value && | |
| 344 | !is_base_of<nested_exception, _Up>::value && | |
| 345 | !__libcpp_is_final<_Up>::value>:: | |
| 346 | __do_throw(static_cast<_Tp&&>(__t)); | |
| 347 | #else | |
| 348 | ((void)__t); | |
| 349 | // FIXME: Make this abort | |
| 350 | #endif | |
| 351 | } | |
| 352 | ||
| 353 | template <class _From, class _To> | |
| 354 | struct __can_dynamic_cast : _BoolConstant< | |
| 355 | is_polymorphic<_From>::value && | |
| 356 | (!is_base_of<_To, _From>::value || | |
| 357 | is_convertible<const _From*, const _To*>::value)> {}; | |
| 358 | ||
| 359 | template <class _Ep> | |
| 360 | inline _LIBCPP_INLINE_VISIBILITY | |
| 361 | void | |
| 362 | rethrow_if_nested(const _Ep& __e, | |
| 363 | __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) | |
| 364 | { | |
| 365 | const nested_exception* __nep = dynamic_cast<const nested_exception*>(_VSTD::addressof(__e)); | |
| 366 | if (__nep) | |
| 367 | __nep->rethrow_nested(); | |
| 368 | } | |
| 369 | ||
| 370 | template <class _Ep> | |
| 371 | inline _LIBCPP_INLINE_VISIBILITY | |
| 372 | void | |
| 373 | rethrow_if_nested(const _Ep&, | |
| 374 | __enable_if_t<!__can_dynamic_cast<_Ep, nested_exception>::value>* = 0) | |
| 375 | { | |
| 376 | } | |
| 377 | ||
| 378 | } // namespace std | |
| 379 | ||
| 380 | 92 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 93 | # include <cstdlib> | |
| 381 | 94 | # include <type_traits> |
| 382 | 95 | #endif |
| 383 | 96 |
lib/libcxx/include/execution+125-4| ... | ... | @@ -10,16 +10,137 @@ |
| 10 | 10 | #ifndef _LIBCPP_EXECUTION |
| 11 | 11 | #define _LIBCPP_EXECUTION |
| 12 | 12 | |
| 13 | /* | |
| 14 | namespace std::execution { | |
| 15 | struct sequenced_policy; | |
| 16 | struct parallel_policy; | |
| 17 | struct parallel_unsequenced_policy; | |
| 18 | struct unsequenced_policy; // since C++20 | |
| 19 | ||
| 20 | inline constexpr sequenced_policy seq = implementation-defined; | |
| 21 | inline constexpr parallel_policy par = implementation-defined; | |
| 22 | inline constexpr parallel_unsequenced_policy par_unseq = implementation-defined; | |
| 23 | inline constexpr unsequenced_policy unseq = implementation-defined; // since C++20 | |
| 24 | } | |
| 25 | ||
| 26 | namespace std { | |
| 27 | template <class T> | |
| 28 | struct is_execution_policy; | |
| 29 | ||
| 30 | template <class T> | |
| 31 | inline constexpr bool is_execution_policy_v; | |
| 32 | } | |
| 33 | */ | |
| 34 | ||
| 13 | 35 | #include <__assert> // all public C++ headers provide the assertion handler |
| 14 | 36 | #include <__config> |
| 37 | #include <__type_traits/is_execution_policy.h> | |
| 38 | #include <__type_traits/is_same.h> | |
| 39 | #include <__type_traits/remove_cvref.h> | |
| 15 | 40 | #include <version> |
| 16 | 41 | |
| 17 | #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 | |
| 18 | # include <__pstl_execution> | |
| 19 | #endif | |
| 20 | ||
| 21 | 42 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 22 | 43 | # pragma GCC system_header |
| 23 | 44 | #endif |
| 24 | 45 | |
| 46 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 47 | ||
| 48 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 49 | ||
| 50 | namespace execution { | |
| 51 | struct sequenced_policy { | |
| 52 | _LIBCPP_HIDE_FROM_ABI constexpr explicit sequenced_policy(__disable_user_instantiations_tag) {} | |
| 53 | sequenced_policy(const sequenced_policy&) = delete; | |
| 54 | sequenced_policy& operator=(const sequenced_policy&) = delete; | |
| 55 | }; | |
| 56 | ||
| 57 | inline constexpr sequenced_policy seq{__disable_user_instantiations_tag{}}; | |
| 58 | ||
| 59 | struct parallel_policy { | |
| 60 | _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_policy(__disable_user_instantiations_tag) {} | |
| 61 | parallel_policy(const parallel_policy&) = delete; | |
| 62 | parallel_policy& operator=(const parallel_policy&) = delete; | |
| 63 | }; | |
| 64 | ||
| 65 | inline constexpr parallel_policy par{__disable_user_instantiations_tag{}}; | |
| 66 | ||
| 67 | struct parallel_unsequenced_policy { | |
| 68 | _LIBCPP_HIDE_FROM_ABI constexpr explicit parallel_unsequenced_policy(__disable_user_instantiations_tag) {} | |
| 69 | parallel_unsequenced_policy(const parallel_unsequenced_policy&) = delete; | |
| 70 | parallel_unsequenced_policy& operator=(const parallel_unsequenced_policy&) = delete; | |
| 71 | }; | |
| 72 | ||
| 73 | inline constexpr parallel_unsequenced_policy par_unseq{__disable_user_instantiations_tag{}}; | |
| 74 | ||
| 75 | struct __unsequenced_policy { | |
| 76 | _LIBCPP_HIDE_FROM_ABI constexpr explicit __unsequenced_policy(__disable_user_instantiations_tag) {} | |
| 77 | __unsequenced_policy(const __unsequenced_policy&) = delete; | |
| 78 | __unsequenced_policy& operator=(const __unsequenced_policy&) = delete; | |
| 79 | }; | |
| 80 | ||
| 81 | constexpr __unsequenced_policy __unseq{__disable_user_instantiations_tag{}}; | |
| 82 | ||
| 83 | # if _LIBCPP_STD_VER >= 20 | |
| 84 | ||
| 85 | struct unsequenced_policy { | |
| 86 | _LIBCPP_HIDE_FROM_ABI constexpr explicit unsequenced_policy(__disable_user_instantiations_tag) {} | |
| 87 | unsequenced_policy(const unsequenced_policy&) = delete; | |
| 88 | unsequenced_policy& operator=(const unsequenced_policy&) = delete; | |
| 89 | }; | |
| 90 | ||
| 91 | inline constexpr unsequenced_policy unseq{__disable_user_instantiations_tag{}}; | |
| 92 | ||
| 93 | # endif // _LIBCPP_STD_VER >= 20 | |
| 94 | ||
| 95 | } // namespace execution | |
| 96 | ||
| 97 | template <> | |
| 98 | inline constexpr bool is_execution_policy_v<execution::sequenced_policy> = true; | |
| 99 | ||
| 100 | template <> | |
| 101 | inline constexpr bool is_execution_policy_v<execution::parallel_policy> = true; | |
| 102 | ||
| 103 | template <> | |
| 104 | inline constexpr bool is_execution_policy_v<execution::parallel_unsequenced_policy> = true; | |
| 105 | ||
| 106 | template <> | |
| 107 | inline constexpr bool is_execution_policy_v<execution::__unsequenced_policy> = true; | |
| 108 | ||
| 109 | template <> | |
| 110 | inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_policy> = true; | |
| 111 | ||
| 112 | template <> | |
| 113 | inline constexpr bool __is_parallel_execution_policy_impl<execution::parallel_unsequenced_policy> = true; | |
| 114 | ||
| 115 | template <> | |
| 116 | inline constexpr bool __is_unsequenced_execution_policy_impl<execution::__unsequenced_policy> = true; | |
| 117 | ||
| 118 | template <> | |
| 119 | inline constexpr bool __is_unsequenced_execution_policy_impl<execution::parallel_unsequenced_policy> = true; | |
| 120 | ||
| 121 | # if _LIBCPP_STD_VER >= 20 | |
| 122 | template <> | |
| 123 | inline constexpr bool is_execution_policy_v<execution::unsequenced_policy> = true; | |
| 124 | ||
| 125 | template <> | |
| 126 | inline constexpr bool __is_unsequenced_execution_policy_impl<execution::unsequenced_policy> = true; | |
| 127 | ||
| 128 | # endif | |
| 129 | ||
| 130 | template <class _Tp> | |
| 131 | struct is_execution_policy : bool_constant<is_execution_policy_v<_Tp>> {}; | |
| 132 | ||
| 133 | template <class _ExecutionPolicy> | |
| 134 | _LIBCPP_HIDE_FROM_ABI auto __remove_parallel_policy(const _ExecutionPolicy&) { | |
| 135 | if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_policy>) { | |
| 136 | return execution::sequenced_policy(execution::__disable_user_instantiations_tag{}); | |
| 137 | } else if constexpr (is_same_v<_ExecutionPolicy, execution::parallel_unsequenced_policy>) { | |
| 138 | return execution::__unsequenced_policy{execution::__disable_user_instantiations_tag{}}; | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | _LIBCPP_END_NAMESPACE_STD | |
| 143 | ||
| 144 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 | |
| 145 | ||
| 25 | 146 | #endif // _LIBCPP_EXECUTION |
lib/libcxx/include/experimental/__config-12| ... | ... | @@ -32,18 +32,6 @@ |
| 32 | 32 | #define _LIBCPP_END_NAMESPACE_LFTS_PMR _LIBCPP_END_NAMESPACE_LFTS } |
| 33 | 33 | #define _VSTD_LFTS_PMR _VSTD_LFTS::pmr |
| 34 | 34 | |
| 35 | #if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L | |
| 36 | #define _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES | |
| 37 | #endif | |
| 38 | ||
| 39 | #define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES \ | |
| 40 | _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace coroutines_v1 { | |
| 41 | ||
| 42 | #define _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES \ | |
| 43 | } _LIBCPP_END_NAMESPACE_EXPERIMENTAL | |
| 44 | ||
| 45 | #define _VSTD_CORO _VSTD_EXPERIMENTAL::coroutines_v1 | |
| 46 | ||
| 47 | 35 | #define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_SIMD \ |
| 48 | 36 | _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { |
| 49 | 37 |
lib/libcxx/include/experimental/__memory+5-2| ... | ... | @@ -12,9 +12,12 @@ |
| 12 | 12 | |
| 13 | 13 | #include <__memory/allocator_arg_t.h> |
| 14 | 14 | #include <__memory/uses_allocator.h> |
| 15 | #include <__type_traits/conditional.h> | |
| 16 | #include <__type_traits/is_constructible.h> | |
| 17 | #include <__type_traits/is_convertible.h> | |
| 18 | #include <__type_traits/is_same.h> | |
| 15 | 19 | #include <experimental/__config> |
| 16 | 20 | #include <experimental/utility> // for erased_type |
| 17 | #include <type_traits> | |
| 18 | 21 | |
| 19 | 22 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 20 | 23 | # pragma GCC system_header |
| ... | ... | @@ -90,7 +93,7 @@ template <class _Tp, class _Allocator, class... _Args> |
| 90 | 93 | inline _LIBCPP_INLINE_VISIBILITY |
| 91 | 94 | void __user_alloc_construct_impl (integral_constant<int, 1>, _Tp *__storage, const _Allocator &__a, _Args &&... __args ) |
| 92 | 95 | { |
| 93 | new (__storage) _Tp (allocator_arg, __a, _VSTD::forward<_Args>(__args)...); | |
| 96 | new (__storage) _Tp (allocator_arg_t(), __a, _VSTD::forward<_Args>(__args)...); | |
| 94 | 97 | } |
| 95 | 98 | |
| 96 | 99 | // FIXME: This should have a version which takes a non-const alloc. |
lib/libcxx/include/experimental/algorithm deleted-53| ... | ... | @@ -1,53 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_EXPERIMENTAL_ALGORITHM | |
| 11 | #define _LIBCPP_EXPERIMENTAL_ALGORITHM | |
| 12 | ||
| 13 | /* | |
| 14 | experimental/algorithm synopsis | |
| 15 | ||
| 16 | #include <algorithm> | |
| 17 | ||
| 18 | namespace std { | |
| 19 | namespace experimental { | |
| 20 | inline namespace fundamentals_v1 { | |
| 21 | ||
| 22 | template <class ForwardIterator, class Searcher> | |
| 23 | ForwardIterator search(ForwardIterator first, ForwardIterator last, | |
| 24 | const Searcher &searcher); | |
| 25 | ||
| 26 | // sample removed because it's now part of C++17 | |
| 27 | ||
| 28 | } // namespace fundamentals_v1 | |
| 29 | } // namespace experimental | |
| 30 | } // namespace std | |
| 31 | ||
| 32 | */ | |
| 33 | ||
| 34 | #include <__assert> // all public C++ headers provide the assertion handler | |
| 35 | #include <__debug> | |
| 36 | #include <algorithm> | |
| 37 | #include <experimental/__config> | |
| 38 | #include <type_traits> | |
| 39 | ||
| 40 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 41 | # pragma GCC system_header | |
| 42 | #endif | |
| 43 | ||
| 44 | _LIBCPP_BEGIN_NAMESPACE_LFTS | |
| 45 | ||
| 46 | template <class _ForwardIterator, class _Searcher> | |
| 47 | _LIBCPP_INLINE_VISIBILITY | |
| 48 | _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher &__s) | |
| 49 | { return __s(__f, __l).first; } | |
| 50 | ||
| 51 | _LIBCPP_END_NAMESPACE_LFTS | |
| 52 | ||
| 53 | #endif /* _LIBCPP_EXPERIMENTAL_ALGORITHM */ |
lib/libcxx/include/experimental/coroutine deleted-344| ... | ... | @@ -1,344 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_EXPERIMENTAL_COROUTINE | |
| 11 | #define _LIBCPP_EXPERIMENTAL_COROUTINE | |
| 12 | ||
| 13 | /** | |
| 14 | experimental/coroutine synopsis | |
| 15 | ||
| 16 | // C++next | |
| 17 | ||
| 18 | namespace std { | |
| 19 | namespace experimental { | |
| 20 | inline namespace coroutines_v1 { | |
| 21 | ||
| 22 | // 18.11.1 coroutine traits | |
| 23 | template <typename R, typename... ArgTypes> | |
| 24 | class coroutine_traits; | |
| 25 | // 18.11.2 coroutine handle | |
| 26 | template <typename Promise = void> | |
| 27 | class coroutine_handle; | |
| 28 | // 18.11.2.7 comparison operators: | |
| 29 | bool operator==(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 30 | bool operator!=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 31 | bool operator<(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 32 | bool operator<=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 33 | bool operator>=(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 34 | bool operator>(coroutine_handle<> x, coroutine_handle<> y) _NOEXCEPT; | |
| 35 | // 18.11.3 trivial awaitables | |
| 36 | struct suspend_never; | |
| 37 | struct suspend_always; | |
| 38 | // 18.11.2.8 hash support: | |
| 39 | template <class T> struct hash; | |
| 40 | template <class P> struct hash<coroutine_handle<P>>; | |
| 41 | ||
| 42 | } // namespace coroutines_v1 | |
| 43 | } // namespace experimental | |
| 44 | } // namespace std | |
| 45 | ||
| 46 | */ | |
| 47 | ||
| 48 | #include <__assert> // all public C++ headers provide the assertion handler | |
| 49 | #include <__functional/hash.h> | |
| 50 | #include <__functional/operations.h> | |
| 51 | #include <cstddef> | |
| 52 | #include <experimental/__config> | |
| 53 | #include <new> | |
| 54 | #include <type_traits> | |
| 55 | ||
| 56 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 57 | # include <atomic> | |
| 58 | # include <climits> | |
| 59 | # include <cmath> | |
| 60 | # include <compare> | |
| 61 | # include <concepts> | |
| 62 | # include <ctime> | |
| 63 | # include <initializer_list> | |
| 64 | # include <iosfwd> | |
| 65 | # include <iterator> | |
| 66 | # include <memory> | |
| 67 | # include <ratio> | |
| 68 | # include <stdexcept> | |
| 69 | # include <tuple> | |
| 70 | # include <typeinfo> | |
| 71 | # include <utility> | |
| 72 | # include <variant> | |
| 73 | #endif | |
| 74 | ||
| 75 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 76 | # pragma GCC system_header | |
| 77 | #endif | |
| 78 | ||
| 79 | #ifndef _LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES | |
| 80 | ||
| 81 | _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_COROUTINES | |
| 82 | ||
| 83 | template <class _Tp, class = void> | |
| 84 | struct __coroutine_traits_sfinae {}; | |
| 85 | ||
| 86 | template <class _Tp> | |
| 87 | struct __coroutine_traits_sfinae<_Tp, __void_t<typename _Tp::promise_type> > | |
| 88 | { | |
| 89 | using promise_type = typename _Tp::promise_type; | |
| 90 | }; | |
| 91 | ||
| 92 | template <typename _Ret, typename... _Args> | |
| 93 | struct coroutine_traits | |
| 94 | : public __coroutine_traits_sfinae<_Ret> | |
| 95 | { | |
| 96 | }; | |
| 97 | ||
| 98 | template <typename _Promise = void> | |
| 99 | class _LIBCPP_TEMPLATE_VIS coroutine_handle; | |
| 100 | ||
| 101 | template <> | |
| 102 | class _LIBCPP_TEMPLATE_VIS coroutine_handle<void> { | |
| 103 | public: | |
| 104 | _LIBCPP_INLINE_VISIBILITY | |
| 105 | _LIBCPP_CONSTEXPR coroutine_handle() _NOEXCEPT : __handle_(nullptr) {} | |
| 106 | ||
| 107 | _LIBCPP_INLINE_VISIBILITY | |
| 108 | _LIBCPP_CONSTEXPR coroutine_handle(nullptr_t) _NOEXCEPT : __handle_(nullptr) {} | |
| 109 | ||
| 110 | _LIBCPP_INLINE_VISIBILITY | |
| 111 | coroutine_handle& operator=(nullptr_t) _NOEXCEPT { | |
| 112 | __handle_ = nullptr; | |
| 113 | return *this; | |
| 114 | } | |
| 115 | ||
| 116 | _LIBCPP_INLINE_VISIBILITY | |
| 117 | _LIBCPP_CONSTEXPR void* address() const _NOEXCEPT { return __handle_; } | |
| 118 | ||
| 119 | _LIBCPP_INLINE_VISIBILITY | |
| 120 | _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return __handle_; } | |
| 121 | ||
| 122 | _LIBCPP_INLINE_VISIBILITY | |
| 123 | void operator()() { resume(); } | |
| 124 | ||
| 125 | _LIBCPP_INLINE_VISIBILITY | |
| 126 | void resume() { | |
| 127 | _LIBCPP_ASSERT(__is_suspended(), | |
| 128 | "resume() can only be called on suspended coroutines"); | |
| 129 | _LIBCPP_ASSERT(!done(), | |
| 130 | "resume() has undefined behavior when the coroutine is done"); | |
| 131 | __builtin_coro_resume(__handle_); | |
| 132 | } | |
| 133 | ||
| 134 | _LIBCPP_INLINE_VISIBILITY | |
| 135 | void destroy() { | |
| 136 | _LIBCPP_ASSERT(__is_suspended(), | |
| 137 | "destroy() can only be called on suspended coroutines"); | |
| 138 | __builtin_coro_destroy(__handle_); | |
| 139 | } | |
| 140 | ||
| 141 | _LIBCPP_INLINE_VISIBILITY | |
| 142 | bool done() const { | |
| 143 | _LIBCPP_ASSERT(__is_suspended(), | |
| 144 | "done() can only be called on suspended coroutines"); | |
| 145 | return __builtin_coro_done(__handle_); | |
| 146 | } | |
| 147 | ||
| 148 | public: | |
| 149 | _LIBCPP_INLINE_VISIBILITY | |
| 150 | static coroutine_handle from_address(void* __addr) _NOEXCEPT { | |
| 151 | coroutine_handle __tmp; | |
| 152 | __tmp.__handle_ = __addr; | |
| 153 | return __tmp; | |
| 154 | } | |
| 155 | ||
| 156 | // FIXME: Should from_address(nullptr) be allowed? | |
| 157 | _LIBCPP_INLINE_VISIBILITY | |
| 158 | static coroutine_handle from_address(nullptr_t) _NOEXCEPT { | |
| 159 | return coroutine_handle(nullptr); | |
| 160 | } | |
| 161 | ||
| 162 | template <class _Tp, bool _CallIsValid = false> | |
| 163 | static coroutine_handle from_address(_Tp*) { | |
| 164 | static_assert(_CallIsValid, | |
| 165 | "coroutine_handle<void>::from_address cannot be called with " | |
| 166 | "non-void pointers"); | |
| 167 | } | |
| 168 | ||
| 169 | private: | |
| 170 | bool __is_suspended() const _NOEXCEPT { | |
| 171 | // FIXME actually implement a check for if the coro is suspended. | |
| 172 | return __handle_; | |
| 173 | } | |
| 174 | ||
| 175 | template <class _PromiseT> friend class coroutine_handle; | |
| 176 | void* __handle_; | |
| 177 | }; | |
| 178 | ||
| 179 | // 18.11.2.7 comparison operators: | |
| 180 | inline _LIBCPP_INLINE_VISIBILITY | |
| 181 | bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 182 | return __x.address() == __y.address(); | |
| 183 | } | |
| 184 | inline _LIBCPP_INLINE_VISIBILITY | |
| 185 | bool operator!=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 186 | return !(__x == __y); | |
| 187 | } | |
| 188 | inline _LIBCPP_INLINE_VISIBILITY | |
| 189 | bool operator<(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 190 | return less<void*>()(__x.address(), __y.address()); | |
| 191 | } | |
| 192 | inline _LIBCPP_INLINE_VISIBILITY | |
| 193 | bool operator>(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 194 | return __y < __x; | |
| 195 | } | |
| 196 | inline _LIBCPP_INLINE_VISIBILITY | |
| 197 | bool operator<=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 198 | return !(__x > __y); | |
| 199 | } | |
| 200 | inline _LIBCPP_INLINE_VISIBILITY | |
| 201 | bool operator>=(coroutine_handle<> __x, coroutine_handle<> __y) _NOEXCEPT { | |
| 202 | return !(__x < __y); | |
| 203 | } | |
| 204 | ||
| 205 | template <typename _Promise> | |
| 206 | class _LIBCPP_TEMPLATE_VIS coroutine_handle : public coroutine_handle<> { | |
| 207 | using _Base = coroutine_handle<>; | |
| 208 | public: | |
| 209 | #ifndef _LIBCPP_CXX03_LANG | |
| 210 | // 18.11.2.1 construct/reset | |
| 211 | using coroutine_handle<>::coroutine_handle; | |
| 212 | #else | |
| 213 | _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT : _Base() {} | |
| 214 | _LIBCPP_INLINE_VISIBILITY coroutine_handle(nullptr_t) _NOEXCEPT : _Base(nullptr) {} | |
| 215 | #endif | |
| 216 | _LIBCPP_INLINE_VISIBILITY | |
| 217 | coroutine_handle& operator=(nullptr_t) _NOEXCEPT { | |
| 218 | _Base::operator=(nullptr); | |
| 219 | return *this; | |
| 220 | } | |
| 221 | ||
| 222 | _LIBCPP_INLINE_VISIBILITY | |
| 223 | _Promise& promise() const { | |
| 224 | return *static_cast<_Promise*>( | |
| 225 | __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); | |
| 226 | } | |
| 227 | ||
| 228 | public: | |
| 229 | _LIBCPP_INLINE_VISIBILITY | |
| 230 | static coroutine_handle from_address(void* __addr) _NOEXCEPT { | |
| 231 | coroutine_handle __tmp; | |
| 232 | __tmp.__handle_ = __addr; | |
| 233 | return __tmp; | |
| 234 | } | |
| 235 | ||
| 236 | // NOTE: this overload isn't required by the standard but is needed so | |
| 237 | // the deleted _Promise* overload doesn't make from_address(nullptr) | |
| 238 | // ambiguous. | |
| 239 | // FIXME: should from_address work with nullptr? | |
| 240 | _LIBCPP_INLINE_VISIBILITY | |
| 241 | static coroutine_handle from_address(nullptr_t) _NOEXCEPT { | |
| 242 | return coroutine_handle(nullptr); | |
| 243 | } | |
| 244 | ||
| 245 | template <class _Tp, bool _CallIsValid = false> | |
| 246 | static coroutine_handle from_address(_Tp*) { | |
| 247 | static_assert(_CallIsValid, | |
| 248 | "coroutine_handle<promise_type>::from_address cannot be called with " | |
| 249 | "non-void pointers"); | |
| 250 | } | |
| 251 | ||
| 252 | template <bool _CallIsValid = false> | |
| 253 | static coroutine_handle from_address(_Promise*) { | |
| 254 | static_assert(_CallIsValid, | |
| 255 | "coroutine_handle<promise_type>::from_address cannot be used with " | |
| 256 | "pointers to the coroutine's promise type; use 'from_promise' instead"); | |
| 257 | } | |
| 258 | ||
| 259 | _LIBCPP_INLINE_VISIBILITY | |
| 260 | static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT { | |
| 261 | typedef __remove_cv_t<_Promise> _RawPromise; | |
| 262 | coroutine_handle __tmp; | |
| 263 | __tmp.__handle_ = __builtin_coro_promise( | |
| 264 | _VSTD::addressof(const_cast<_RawPromise&>(__promise)), | |
| 265 | _LIBCPP_ALIGNOF(_Promise), true); | |
| 266 | return __tmp; | |
| 267 | } | |
| 268 | }; | |
| 269 | ||
| 270 | #if __has_builtin(__builtin_coro_noop) | |
| 271 | struct noop_coroutine_promise {}; | |
| 272 | ||
| 273 | template <> | |
| 274 | class _LIBCPP_TEMPLATE_VIS coroutine_handle<noop_coroutine_promise> | |
| 275 | : public coroutine_handle<> { | |
| 276 | using _Base = coroutine_handle<>; | |
| 277 | using _Promise = noop_coroutine_promise; | |
| 278 | public: | |
| 279 | ||
| 280 | _LIBCPP_INLINE_VISIBILITY | |
| 281 | _Promise& promise() const { | |
| 282 | return *static_cast<_Promise*>( | |
| 283 | __builtin_coro_promise(this->__handle_, _LIBCPP_ALIGNOF(_Promise), false)); | |
| 284 | } | |
| 285 | ||
| 286 | _LIBCPP_CONSTEXPR explicit operator bool() const _NOEXCEPT { return true; } | |
| 287 | _LIBCPP_CONSTEXPR bool done() const _NOEXCEPT { return false; } | |
| 288 | ||
| 289 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void operator()() const _NOEXCEPT {} | |
| 290 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void resume() const _NOEXCEPT {} | |
| 291 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void destroy() const _NOEXCEPT {} | |
| 292 | ||
| 293 | private: | |
| 294 | _LIBCPP_INLINE_VISIBILITY | |
| 295 | friend coroutine_handle<noop_coroutine_promise> noop_coroutine() _NOEXCEPT; | |
| 296 | ||
| 297 | _LIBCPP_INLINE_VISIBILITY coroutine_handle() _NOEXCEPT { | |
| 298 | this->__handle_ = __builtin_coro_noop(); | |
| 299 | } | |
| 300 | }; | |
| 301 | ||
| 302 | using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>; | |
| 303 | ||
| 304 | inline _LIBCPP_INLINE_VISIBILITY | |
| 305 | noop_coroutine_handle noop_coroutine() _NOEXCEPT { | |
| 306 | return noop_coroutine_handle(); | |
| 307 | } | |
| 308 | #endif // __has_builtin(__builtin_coro_noop) | |
| 309 | ||
| 310 | struct suspend_never { | |
| 311 | _LIBCPP_INLINE_VISIBILITY | |
| 312 | bool await_ready() const _NOEXCEPT { return true; } | |
| 313 | _LIBCPP_INLINE_VISIBILITY | |
| 314 | void await_suspend(coroutine_handle<>) const _NOEXCEPT {} | |
| 315 | _LIBCPP_INLINE_VISIBILITY | |
| 316 | void await_resume() const _NOEXCEPT {} | |
| 317 | }; | |
| 318 | ||
| 319 | struct suspend_always { | |
| 320 | _LIBCPP_INLINE_VISIBILITY | |
| 321 | bool await_ready() const _NOEXCEPT { return false; } | |
| 322 | _LIBCPP_INLINE_VISIBILITY | |
| 323 | void await_suspend(coroutine_handle<>) const _NOEXCEPT {} | |
| 324 | _LIBCPP_INLINE_VISIBILITY | |
| 325 | void await_resume() const _NOEXCEPT {} | |
| 326 | }; | |
| 327 | ||
| 328 | _LIBCPP_END_NAMESPACE_EXPERIMENTAL_COROUTINES | |
| 329 | ||
| 330 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 331 | ||
| 332 | template <class _Tp> | |
| 333 | struct hash<_VSTD_CORO::coroutine_handle<_Tp> > { | |
| 334 | using __arg_type = _VSTD_CORO::coroutine_handle<_Tp>; | |
| 335 | _LIBCPP_INLINE_VISIBILITY | |
| 336 | size_t operator()(__arg_type const& __v) const _NOEXCEPT | |
| 337 | {return hash<void*>()(__v.address());} | |
| 338 | }; | |
| 339 | ||
| 340 | _LIBCPP_END_NAMESPACE_STD | |
| 341 | ||
| 342 | #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_COROUTINES) | |
| 343 | ||
| 344 | #endif /* _LIBCPP_EXPERIMENTAL_COROUTINE */ |
lib/libcxx/include/experimental/functional deleted-436| ... | ... | @@ -1,436 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_EXPERIMENTAL_FUNCTIONAL | |
| 11 | #define _LIBCPP_EXPERIMENTAL_FUNCTIONAL | |
| 12 | ||
| 13 | /* | |
| 14 | experimental/functional synopsis | |
| 15 | ||
| 16 | #include <algorithm> | |
| 17 | ||
| 18 | namespace std { | |
| 19 | namespace experimental { | |
| 20 | inline namespace fundamentals_v1 { | |
| 21 | // 4.3, Searchers | |
| 22 | template<class ForwardIterator, class BinaryPredicate = equal_to<>> | |
| 23 | class default_searcher; | |
| 24 | ||
| 25 | template<class RandomAccessIterator, | |
| 26 | class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, | |
| 27 | class BinaryPredicate = equal_to<>> | |
| 28 | class boyer_moore_searcher; | |
| 29 | ||
| 30 | template<class RandomAccessIterator, | |
| 31 | class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, | |
| 32 | class BinaryPredicate = equal_to<>> | |
| 33 | class boyer_moore_horspool_searcher; | |
| 34 | ||
| 35 | template<class ForwardIterator, class BinaryPredicate = equal_to<>> | |
| 36 | default_searcher<ForwardIterator, BinaryPredicate> | |
| 37 | make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last, | |
| 38 | BinaryPredicate pred = BinaryPredicate()); | |
| 39 | ||
| 40 | template<class RandomAccessIterator, | |
| 41 | class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, | |
| 42 | class BinaryPredicate = equal_to<>> | |
| 43 | boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate> | |
| 44 | make_boyer_moore_searcher( | |
| 45 | RandomAccessIterator pat_first, RandomAccessIterator pat_last, | |
| 46 | Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); | |
| 47 | ||
| 48 | template<class RandomAccessIterator, | |
| 49 | class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>, | |
| 50 | class BinaryPredicate = equal_to<>> | |
| 51 | boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate> | |
| 52 | make_boyer_moore_horspool_searcher( | |
| 53 | RandomAccessIterator pat_first, RandomAccessIterator pat_last, | |
| 54 | Hash hf = Hash(), BinaryPredicate pred = BinaryPredicate()); | |
| 55 | ||
| 56 | } // namespace fundamentals_v1 | |
| 57 | } // namespace experimental | |
| 58 | ||
| 59 | } // namespace std | |
| 60 | ||
| 61 | */ | |
| 62 | ||
| 63 | #include <__assert> // all public C++ headers provide the assertion handler | |
| 64 | #include <__debug> | |
| 65 | #include <__functional/identity.h> | |
| 66 | #include <__memory/uses_allocator.h> | |
| 67 | #include <array> | |
| 68 | #include <experimental/__config> | |
| 69 | #include <functional> | |
| 70 | #include <type_traits> | |
| 71 | #include <unordered_map> | |
| 72 | #include <vector> | |
| 73 | ||
| 74 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 75 | # pragma GCC system_header | |
| 76 | #endif | |
| 77 | ||
| 78 | _LIBCPP_PUSH_MACROS | |
| 79 | #include <__undef_macros> | |
| 80 | ||
| 81 | _LIBCPP_BEGIN_NAMESPACE_LFTS | |
| 82 | ||
| 83 | #ifdef _LIBCPP_NO_EXPERIMENTAL_DEPRECATION_WARNING_SEARCHERS | |
| 84 | # define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER | |
| 85 | # define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER | |
| 86 | # define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER | |
| 87 | #else | |
| 88 | # define _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::default_searcher will be removed in LLVM 17. Use std::default_searcher instead") | |
| 89 | # define _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_searcher will be removed in LLVM 17. Use std::boyer_moore_searcher instead") | |
| 90 | # define _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_DEPRECATED_("std::experimental::boyer_moore_horspool_searcher will be removed in LLVM 17. Use std::boyer_moore_horspool_searcher instead") | |
| 91 | #endif | |
| 92 | ||
| 93 | #if _LIBCPP_STD_VER > 11 | |
| 94 | // default searcher | |
| 95 | template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> | |
| 96 | class _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_TEMPLATE_VIS default_searcher { | |
| 97 | public: | |
| 98 | _LIBCPP_INLINE_VISIBILITY | |
| 99 | default_searcher(_ForwardIterator __f, _ForwardIterator __l, | |
| 100 | _BinaryPredicate __p = _BinaryPredicate()) | |
| 101 | : __first_(__f), __last_(__l), __pred_(__p) {} | |
| 102 | ||
| 103 | template <typename _ForwardIterator2> | |
| 104 | _LIBCPP_INLINE_VISIBILITY | |
| 105 | pair<_ForwardIterator2, _ForwardIterator2> | |
| 106 | operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const | |
| 107 | { | |
| 108 | auto __proj = __identity(); | |
| 109 | return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); | |
| 110 | } | |
| 111 | ||
| 112 | private: | |
| 113 | _ForwardIterator __first_; | |
| 114 | _ForwardIterator __last_; | |
| 115 | _BinaryPredicate __pred_; | |
| 116 | }; | |
| 117 | ||
| 118 | template<class _ForwardIterator, class _BinaryPredicate = equal_to<>> | |
| 119 | _LIBCPP_DEPRECATED_DEFAULT_SEARCHER _LIBCPP_INLINE_VISIBILITY | |
| 120 | default_searcher<_ForwardIterator, _BinaryPredicate> | |
| 121 | make_default_searcher( _ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate ()) | |
| 122 | { | |
| 123 | return default_searcher<_ForwardIterator, _BinaryPredicate>(__f, __l, __p); | |
| 124 | } | |
| 125 | ||
| 126 | template<class _Key, class _Value, class _Hash, class _BinaryPredicate, bool /*useArray*/> class _BMSkipTable; | |
| 127 | ||
| 128 | // General case for BM data searching; use a map | |
| 129 | template<class _Key, typename _Value, class _Hash, class _BinaryPredicate> | |
| 130 | class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { | |
| 131 | typedef _Value value_type; | |
| 132 | typedef _Key key_type; | |
| 133 | ||
| 134 | const _Value __default_value_; | |
| 135 | std::unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; | |
| 136 | ||
| 137 | public: | |
| 138 | _LIBCPP_INLINE_VISIBILITY | |
| 139 | _BMSkipTable(size_t __sz, _Value __default, _Hash __hf, _BinaryPredicate __pred) | |
| 140 | : __default_value_(__default), __table_(__sz, __hf, __pred) {} | |
| 141 | ||
| 142 | _LIBCPP_INLINE_VISIBILITY | |
| 143 | void insert(const key_type &__key, value_type __val) | |
| 144 | { | |
| 145 | __table_ [__key] = __val; // Would skip_.insert (val) be better here? | |
| 146 | } | |
| 147 | ||
| 148 | _LIBCPP_INLINE_VISIBILITY | |
| 149 | value_type operator [](const key_type & __key) const | |
| 150 | { | |
| 151 | auto __it = __table_.find (__key); | |
| 152 | return __it == __table_.end() ? __default_value_ : __it->second; | |
| 153 | } | |
| 154 | }; | |
| 155 | ||
| 156 | ||
| 157 | // Special case small numeric values; use an array | |
| 158 | template<class _Key, typename _Value, class _Hash, class _BinaryPredicate> | |
| 159 | class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { | |
| 160 | private: | |
| 161 | typedef _Value value_type; | |
| 162 | typedef _Key key_type; | |
| 163 | ||
| 164 | typedef __make_unsigned_t<key_type> unsigned_key_type; | |
| 165 | typedef std::array<value_type, 256> skip_map; | |
| 166 | skip_map __table_; | |
| 167 | ||
| 168 | public: | |
| 169 | _LIBCPP_INLINE_VISIBILITY | |
| 170 | _BMSkipTable(size_t /*__sz*/, _Value __default, _Hash /*__hf*/, _BinaryPredicate /*__pred*/) | |
| 171 | { | |
| 172 | std::fill_n(__table_.begin(), __table_.size(), __default); | |
| 173 | } | |
| 174 | ||
| 175 | _LIBCPP_INLINE_VISIBILITY | |
| 176 | void insert(key_type __key, value_type __val) | |
| 177 | { | |
| 178 | __table_[static_cast<unsigned_key_type>(__key)] = __val; | |
| 179 | } | |
| 180 | ||
| 181 | _LIBCPP_INLINE_VISIBILITY | |
| 182 | value_type operator [](key_type __key) const | |
| 183 | { | |
| 184 | return __table_[static_cast<unsigned_key_type>(__key)]; | |
| 185 | } | |
| 186 | }; | |
| 187 | ||
| 188 | ||
| 189 | template <class _RandomAccessIterator1, | |
| 190 | class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, | |
| 191 | class _BinaryPredicate = equal_to<>> | |
| 192 | class _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { | |
| 193 | private: | |
| 194 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; | |
| 195 | typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; | |
| 196 | typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, | |
| 197 | is_integral<value_type>::value && // what about enums? | |
| 198 | sizeof(value_type) == 1 && | |
| 199 | is_same<_Hash, hash<value_type>>::value && | |
| 200 | is_same<_BinaryPredicate, equal_to<>>::value | |
| 201 | > skip_table_type; | |
| 202 | ||
| 203 | public: | |
| 204 | boyer_moore_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, | |
| 205 | _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) | |
| 206 | : __first_(__f), __last_(__l), __pred_(__pred), | |
| 207 | __pattern_length_(_VSTD::distance(__first_, __last_)), | |
| 208 | __skip_{std::make_shared<skip_table_type>(__pattern_length_, -1, __hf, __pred_)}, | |
| 209 | __suffix_{std::make_shared<vector<difference_type>>(__pattern_length_ + 1)} | |
| 210 | { | |
| 211 | // build the skip table | |
| 212 | for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) | |
| 213 | __skip_->insert(*__f, __i); | |
| 214 | ||
| 215 | this->__build_suffix_table ( __first_, __last_, __pred_ ); | |
| 216 | } | |
| 217 | ||
| 218 | template <typename _RandomAccessIterator2> | |
| 219 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 220 | operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const | |
| 221 | { | |
| 222 | static_assert(__is_same_uncvref<typename iterator_traits<_RandomAccessIterator1>::value_type, | |
| 223 | typename iterator_traits<_RandomAccessIterator2>::value_type>::value, | |
| 224 | "Corpus and Pattern iterators must point to the same type"); | |
| 225 | ||
| 226 | if (__f == __l ) return std::make_pair(__l, __l); // empty corpus | |
| 227 | if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern | |
| 228 | ||
| 229 | // If the pattern is larger than the corpus, we can't find it! | |
| 230 | if ( __pattern_length_ > _VSTD::distance(__f, __l)) | |
| 231 | return std::make_pair(__l, __l); | |
| 232 | ||
| 233 | // Do the search | |
| 234 | return this->__search(__f, __l); | |
| 235 | } | |
| 236 | ||
| 237 | private: | |
| 238 | _RandomAccessIterator1 __first_; | |
| 239 | _RandomAccessIterator1 __last_; | |
| 240 | _BinaryPredicate __pred_; | |
| 241 | difference_type __pattern_length_; | |
| 242 | shared_ptr<skip_table_type> __skip_; | |
| 243 | shared_ptr<vector<difference_type>> __suffix_; | |
| 244 | ||
| 245 | template <typename _RandomAccessIterator2> | |
| 246 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 247 | __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const | |
| 248 | { | |
| 249 | _RandomAccessIterator2 __cur = __f; | |
| 250 | const _RandomAccessIterator2 __last = __l - __pattern_length_; | |
| 251 | const skip_table_type & __skip = *__skip_.get(); | |
| 252 | const vector<difference_type> & __suffix = *__suffix_.get(); | |
| 253 | ||
| 254 | while (__cur <= __last) | |
| 255 | { | |
| 256 | ||
| 257 | // Do we match right where we are? | |
| 258 | difference_type __j = __pattern_length_; | |
| 259 | while (__pred_(__first_ [__j-1], __cur [__j-1])) { | |
| 260 | __j--; | |
| 261 | // We matched - we're done! | |
| 262 | if ( __j == 0 ) | |
| 263 | return std::make_pair(__cur, __cur + __pattern_length_); | |
| 264 | } | |
| 265 | ||
| 266 | // Since we didn't match, figure out how far to skip forward | |
| 267 | difference_type __k = __skip[__cur [ __j - 1 ]]; | |
| 268 | difference_type __m = __j - __k - 1; | |
| 269 | if (__k < __j && __m > __suffix[ __j ]) | |
| 270 | __cur += __m; | |
| 271 | else | |
| 272 | __cur += __suffix[ __j ]; | |
| 273 | } | |
| 274 | ||
| 275 | return std::make_pair(__l, __l); // We didn't find anything | |
| 276 | } | |
| 277 | ||
| 278 | ||
| 279 | template<typename _Iterator, typename _Container> | |
| 280 | void __compute_bm_prefix ( _Iterator __f, _Iterator __l, _BinaryPredicate __pred, _Container &__prefix ) | |
| 281 | { | |
| 282 | const size_t __count = _VSTD::distance(__f, __l); | |
| 283 | ||
| 284 | __prefix[0] = 0; | |
| 285 | size_t __k = 0; | |
| 286 | for ( size_t __i = 1; __i < __count; ++__i ) | |
| 287 | { | |
| 288 | while ( __k > 0 && !__pred ( __f[__k], __f[__i] )) | |
| 289 | __k = __prefix [ __k - 1 ]; | |
| 290 | ||
| 291 | if ( __pred ( __f[__k], __f[__i] )) | |
| 292 | __k++; | |
| 293 | __prefix [ __i ] = __k; | |
| 294 | } | |
| 295 | } | |
| 296 | ||
| 297 | void __build_suffix_table(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, | |
| 298 | _BinaryPredicate __pred) | |
| 299 | { | |
| 300 | const size_t __count = _VSTD::distance(__f, __l); | |
| 301 | vector<difference_type> & __suffix = *__suffix_.get(); | |
| 302 | if (__count > 0) | |
| 303 | { | |
| 304 | vector<difference_type> __scratch(__count); | |
| 305 | ||
| 306 | __compute_bm_prefix(__f, __l, __pred, __scratch); | |
| 307 | for ( size_t __i = 0; __i <= __count; __i++ ) | |
| 308 | __suffix[__i] = __count - __scratch[__count-1]; | |
| 309 | ||
| 310 | typedef reverse_iterator<_RandomAccessIterator1> _RevIter; | |
| 311 | __compute_bm_prefix(_RevIter(__l), _RevIter(__f), __pred, __scratch); | |
| 312 | ||
| 313 | for ( size_t __i = 0; __i < __count; __i++ ) | |
| 314 | { | |
| 315 | const size_t __j = __count - __scratch[__i]; | |
| 316 | const difference_type __k = __i - __scratch[__i] + 1; | |
| 317 | ||
| 318 | if (__suffix[__j] > __k) | |
| 319 | __suffix[__j] = __k; | |
| 320 | } | |
| 321 | } | |
| 322 | } | |
| 323 | ||
| 324 | }; | |
| 325 | ||
| 326 | template<class _RandomAccessIterator, | |
| 327 | class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, | |
| 328 | class _BinaryPredicate = equal_to<>> | |
| 329 | _LIBCPP_DEPRECATED_BOYER_MOORE_SEARCHER _LIBCPP_INLINE_VISIBILITY | |
| 330 | boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> | |
| 331 | make_boyer_moore_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, | |
| 332 | _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) | |
| 333 | { | |
| 334 | return boyer_moore_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); | |
| 335 | } | |
| 336 | ||
| 337 | // boyer-moore-horspool | |
| 338 | template <class _RandomAccessIterator1, | |
| 339 | class _Hash = hash<typename iterator_traits<_RandomAccessIterator1>::value_type>, | |
| 340 | class _BinaryPredicate = equal_to<>> | |
| 341 | class _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { | |
| 342 | private: | |
| 343 | typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type difference_type; | |
| 344 | typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type value_type; | |
| 345 | typedef _BMSkipTable<value_type, difference_type, _Hash, _BinaryPredicate, | |
| 346 | is_integral<value_type>::value && // what about enums? | |
| 347 | sizeof(value_type) == 1 && | |
| 348 | is_same<_Hash, hash<value_type>>::value && | |
| 349 | is_same<_BinaryPredicate, equal_to<>>::value | |
| 350 | > skip_table_type; | |
| 351 | ||
| 352 | public: | |
| 353 | boyer_moore_horspool_searcher(_RandomAccessIterator1 __f, _RandomAccessIterator1 __l, | |
| 354 | _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) | |
| 355 | : __first_(__f), __last_(__l), __pred_(__pred), | |
| 356 | __pattern_length_(_VSTD::distance(__first_, __last_)), | |
| 357 | __skip_{_VSTD::make_shared<skip_table_type>(__pattern_length_, __pattern_length_, __hf, __pred_)} | |
| 358 | { | |
| 359 | // build the skip table | |
| 360 | if ( __f != __l ) | |
| 361 | { | |
| 362 | __l = __l - 1; | |
| 363 | for ( difference_type __i = 0; __f != __l; ++__f, (void) ++__i ) | |
| 364 | __skip_->insert(*__f, __pattern_length_ - 1 - __i); | |
| 365 | } | |
| 366 | } | |
| 367 | ||
| 368 | template <typename _RandomAccessIterator2> | |
| 369 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 370 | operator ()(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const | |
| 371 | { | |
| 372 | static_assert(__is_same_uncvref<typename std::iterator_traits<_RandomAccessIterator1>::value_type, | |
| 373 | typename std::iterator_traits<_RandomAccessIterator2>::value_type>::value, | |
| 374 | "Corpus and Pattern iterators must point to the same type"); | |
| 375 | ||
| 376 | if (__f == __l ) return std::make_pair(__l, __l); // empty corpus | |
| 377 | if (__first_ == __last_) return std::make_pair(__f, __f); // empty pattern | |
| 378 | ||
| 379 | // If the pattern is larger than the corpus, we can't find it! | |
| 380 | if ( __pattern_length_ > _VSTD::distance(__f, __l)) | |
| 381 | return std::make_pair(__l, __l); | |
| 382 | ||
| 383 | // Do the search | |
| 384 | return this->__search(__f, __l); | |
| 385 | } | |
| 386 | ||
| 387 | private: | |
| 388 | _RandomAccessIterator1 __first_; | |
| 389 | _RandomAccessIterator1 __last_; | |
| 390 | _BinaryPredicate __pred_; | |
| 391 | difference_type __pattern_length_; | |
| 392 | shared_ptr<skip_table_type> __skip_; | |
| 393 | ||
| 394 | template <typename _RandomAccessIterator2> | |
| 395 | pair<_RandomAccessIterator2, _RandomAccessIterator2> | |
| 396 | __search ( _RandomAccessIterator2 __f, _RandomAccessIterator2 __l ) const { | |
| 397 | _RandomAccessIterator2 __cur = __f; | |
| 398 | const _RandomAccessIterator2 __last = __l - __pattern_length_; | |
| 399 | const skip_table_type & __skip = *__skip_.get(); | |
| 400 | ||
| 401 | while (__cur <= __last) | |
| 402 | { | |
| 403 | // Do we match right where we are? | |
| 404 | difference_type __j = __pattern_length_; | |
| 405 | while (__pred_(__first_[__j-1], __cur[__j-1])) | |
| 406 | { | |
| 407 | __j--; | |
| 408 | // We matched - we're done! | |
| 409 | if ( __j == 0 ) | |
| 410 | return std::make_pair(__cur, __cur + __pattern_length_); | |
| 411 | } | |
| 412 | __cur += __skip[__cur[__pattern_length_-1]]; | |
| 413 | } | |
| 414 | ||
| 415 | return std::make_pair(__l, __l); | |
| 416 | } | |
| 417 | }; | |
| 418 | ||
| 419 | template<class _RandomAccessIterator, | |
| 420 | class _Hash = hash<typename iterator_traits<_RandomAccessIterator>::value_type>, | |
| 421 | class _BinaryPredicate = equal_to<>> | |
| 422 | _LIBCPP_DEPRECATED_BOYER_MOORE_HORSPOOL_SEARCHER _LIBCPP_INLINE_VISIBILITY | |
| 423 | boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate> | |
| 424 | make_boyer_moore_horspool_searcher( _RandomAccessIterator __f, _RandomAccessIterator __l, | |
| 425 | _Hash __hf = _Hash(), _BinaryPredicate __p = _BinaryPredicate ()) | |
| 426 | { | |
| 427 | return boyer_moore_horspool_searcher<_RandomAccessIterator, _Hash, _BinaryPredicate>(__f, __l, __hf, __p); | |
| 428 | } | |
| 429 | ||
| 430 | #endif // _LIBCPP_STD_VER > 11 | |
| 431 | ||
| 432 | _LIBCPP_END_NAMESPACE_LFTS | |
| 433 | ||
| 434 | _LIBCPP_POP_MACROS | |
| 435 | ||
| 436 | #endif /* _LIBCPP_EXPERIMENTAL_FUNCTIONAL */ |
lib/libcxx/include/experimental/iterator+10-10| ... | ... | @@ -65,7 +65,7 @@ namespace std { |
| 65 | 65 | # pragma GCC system_header |
| 66 | 66 | #endif |
| 67 | 67 | |
| 68 | #if _LIBCPP_STD_VER > 11 | |
| 68 | #if _LIBCPP_STD_VER >= 14 | |
| 69 | 69 | |
| 70 | 70 | _LIBCPP_BEGIN_NAMESPACE_LFTS |
| 71 | 71 | |
| ... | ... | @@ -82,15 +82,15 @@ public: |
| 82 | 82 | typedef void pointer; |
| 83 | 83 | typedef void reference; |
| 84 | 84 | |
| 85 | ostream_joiner(ostream_type& __os, _Delim&& __d) | |
| 85 | _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, _Delim&& __d) | |
| 86 | 86 | : __output_iter_(_VSTD::addressof(__os)), __delim_(_VSTD::move(__d)), __first_(true) {} |
| 87 | 87 | |
| 88 | ostream_joiner(ostream_type& __os, const _Delim& __d) | |
| 88 | _LIBCPP_HIDE_FROM_ABI ostream_joiner(ostream_type& __os, const _Delim& __d) | |
| 89 | 89 | : __output_iter_(_VSTD::addressof(__os)), __delim_(__d), __first_(true) {} |
| 90 | 90 | |
| 91 | 91 | |
| 92 | 92 | template<typename _Tp> |
| 93 | ostream_joiner& operator=(const _Tp& __v) | |
| 93 | _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator=(const _Tp& __v) | |
| 94 | 94 | { |
| 95 | 95 | if (!__first_) |
| 96 | 96 | *__output_iter_ << __delim_; |
| ... | ... | @@ -99,9 +99,9 @@ public: |
| 99 | 99 | return *this; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | ostream_joiner& operator*() _NOEXCEPT { return *this; } | |
| 103 | ostream_joiner& operator++() _NOEXCEPT { return *this; } | |
| 104 | ostream_joiner& operator++(int) _NOEXCEPT { return *this; } | |
| 102 | _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator*() _NOEXCEPT { return *this; } | |
| 103 | _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++() _NOEXCEPT { return *this; } | |
| 104 | _LIBCPP_HIDE_FROM_ABI ostream_joiner& operator++(int) _NOEXCEPT { return *this; } | |
| 105 | 105 | |
| 106 | 106 | private: |
| 107 | 107 | ostream_type* __output_iter_; |
| ... | ... | @@ -111,13 +111,13 @@ private: |
| 111 | 111 | |
| 112 | 112 | |
| 113 | 113 | template <class _CharT, class _Traits, class _Delim> |
| 114 | _LIBCPP_HIDE_FROM_ABI ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits> | |
| 114 | _LIBCPP_HIDE_FROM_ABI ostream_joiner<__decay_t<_Delim>, _CharT, _Traits> | |
| 115 | 115 | make_ostream_joiner(basic_ostream<_CharT, _Traits>& __os, _Delim && __d) |
| 116 | { return ostream_joiner<typename decay<_Delim>::type, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } | |
| 116 | { return ostream_joiner<__decay_t<_Delim>, _CharT, _Traits>(__os, _VSTD::forward<_Delim>(__d)); } | |
| 117 | 117 | |
| 118 | 118 | _LIBCPP_END_NAMESPACE_LFTS |
| 119 | 119 | |
| 120 | #endif // _LIBCPP_STD_VER > 11 | |
| 120 | #endif // _LIBCPP_STD_VER >= 14 | |
| 121 | 121 | |
| 122 | 122 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 123 | 123 | # include <type_traits> |
lib/libcxx/include/experimental/memory_resource+21-20| ... | ... | @@ -66,16 +66,15 @@ namespace pmr { |
| 66 | 66 | |
| 67 | 67 | #include <__assert> // all public C++ headers provide the assertion handler |
| 68 | 68 | #include <__memory/allocator_traits.h> |
| 69 | #include <__type_traits/aligned_storage.h> | |
| 69 | 70 | #include <__utility/move.h> |
| 70 | 71 | #include <cstddef> |
| 71 | #include <cstdlib> | |
| 72 | 72 | #include <experimental/__config> |
| 73 | 73 | #include <experimental/__memory> |
| 74 | 74 | #include <limits> |
| 75 | 75 | #include <new> |
| 76 | 76 | #include <stdexcept> |
| 77 | 77 | #include <tuple> |
| 78 | #include <type_traits> | |
| 79 | 78 | |
| 80 | 79 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 81 | 80 | # pragma GCC system_header |
| ... | ... | @@ -96,18 +95,18 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR |
| 96 | 95 | inline _LIBCPP_INLINE_VISIBILITY |
| 97 | 96 | size_t __aligned_allocation_size(size_t __s, size_t __a) _NOEXCEPT |
| 98 | 97 | { |
| 99 | _LIBCPP_ASSERT(__s + __a > __s, "aligned allocation size overflows"); | |
| 98 | _LIBCPP_ASSERT_UNCATEGORIZED(__s + __a > __s, "aligned allocation size overflows"); | |
| 100 | 99 | return (__s + __a - 1) & ~(__a - 1); |
| 101 | 100 | } |
| 102 | 101 | |
| 103 | 102 | // 8.5, memory.resource |
| 104 | class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_TYPE_VIS memory_resource | |
| 103 | class _LIBCPP_DEPCREATED_MEMORY_RESOURCE("memory_resource") _LIBCPP_EXPORTED_FROM_ABI memory_resource | |
| 105 | 104 | { |
| 106 | 105 | static const size_t __max_align = _LIBCPP_ALIGNOF(max_align_t); |
| 107 | 106 | |
| 108 | 107 | // 8.5.2, memory.resource.public |
| 109 | 108 | public: |
| 110 | virtual ~memory_resource() = default; | |
| 109 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~memory_resource() = default; | |
| 111 | 110 | |
| 112 | 111 | _LIBCPP_INLINE_VISIBILITY |
| 113 | 112 | void* allocate(size_t __bytes, size_t __align = __max_align) |
| ... | ... | @@ -143,16 +142,16 @@ bool operator!=(memory_resource const & __lhs, |
| 143 | 142 | return !(__lhs == __rhs); |
| 144 | 143 | } |
| 145 | 144 | |
| 146 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_FUNC_VIS | |
| 145 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("new_delete_resource()") _LIBCPP_EXPORTED_FROM_ABI | |
| 147 | 146 | memory_resource * new_delete_resource() _NOEXCEPT; |
| 148 | 147 | |
| 149 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_FUNC_VIS | |
| 148 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("null_memory_resource()") _LIBCPP_EXPORTED_FROM_ABI | |
| 150 | 149 | memory_resource * null_memory_resource() _NOEXCEPT; |
| 151 | 150 | |
| 152 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_FUNC_VIS | |
| 151 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("get_default_resource()") _LIBCPP_EXPORTED_FROM_ABI | |
| 153 | 152 | memory_resource * get_default_resource() _NOEXCEPT; |
| 154 | 153 | |
| 155 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_FUNC_VIS | |
| 154 | _LIBCPP_DEPCREATED_MEMORY_RESOURCE("set_default_resource()") _LIBCPP_EXPORTED_FROM_ABI | |
| 156 | 155 | memory_resource * set_default_resource(memory_resource * __new_res) _NOEXCEPT; |
| 157 | 156 | |
| 158 | 157 | // 8.6, memory.polymorphic.allocator.class |
| ... | ... | @@ -175,7 +174,7 @@ public: |
| 175 | 174 | : __res_(__r) |
| 176 | 175 | {} |
| 177 | 176 | |
| 178 | polymorphic_allocator(polymorphic_allocator const &) = default; | |
| 177 | _LIBCPP_HIDE_FROM_ABI polymorphic_allocator(polymorphic_allocator const &) = default; | |
| 179 | 178 | |
| 180 | 179 | template <class _Tp> |
| 181 | 180 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -198,8 +197,8 @@ public: |
| 198 | 197 | |
| 199 | 198 | _LIBCPP_INLINE_VISIBILITY |
| 200 | 199 | void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT { |
| 201 | _LIBCPP_ASSERT(__n <= __max_size(), | |
| 202 | "deallocate called for size which exceeds max_size()"); | |
| 200 | _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __max_size(), | |
| 201 | "deallocate called for size which exceeds max_size()"); | |
| 203 | 202 | __res_->deallocate(__p, __n * sizeof(_ValueType), _LIBCPP_ALIGNOF(_ValueType)); |
| 204 | 203 | } |
| 205 | 204 | |
| ... | ... | @@ -363,9 +362,9 @@ class _LIBCPP_TEMPLATE_VIS __resource_adaptor_imp |
| 363 | 362 | public: |
| 364 | 363 | typedef _CharAlloc allocator_type; |
| 365 | 364 | |
| 366 | __resource_adaptor_imp() = default; | |
| 367 | __resource_adaptor_imp(__resource_adaptor_imp const &) = default; | |
| 368 | __resource_adaptor_imp(__resource_adaptor_imp &&) = default; | |
| 365 | _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp() = default; | |
| 366 | _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp const &) = default; | |
| 367 | _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp(__resource_adaptor_imp &&) = default; | |
| 369 | 368 | |
| 370 | 369 | // 8.7.2, memory.resource.adaptor.ctor |
| 371 | 370 | |
| ... | ... | @@ -379,7 +378,7 @@ public: |
| 379 | 378 | : __alloc_(_VSTD::move(__a)) |
| 380 | 379 | {} |
| 381 | 380 | |
| 382 | __resource_adaptor_imp & | |
| 381 | _LIBCPP_HIDE_FROM_ABI __resource_adaptor_imp & | |
| 383 | 382 | operator=(__resource_adaptor_imp const &) = default; |
| 384 | 383 | |
| 385 | 384 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -388,7 +387,7 @@ public: |
| 388 | 387 | |
| 389 | 388 | // 8.7.3, memory.resource.adaptor.mem |
| 390 | 389 | private: |
| 391 | void * do_allocate(size_t __bytes, size_t) override | |
| 390 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void * do_allocate(size_t __bytes, size_t) override | |
| 392 | 391 | { |
| 393 | 392 | if (__bytes > __max_size()) |
| 394 | 393 | __throw_bad_array_new_length(); |
| ... | ... | @@ -396,15 +395,15 @@ private: |
| 396 | 395 | return __alloc_.allocate(__s); |
| 397 | 396 | } |
| 398 | 397 | |
| 399 | void do_deallocate(void * __p, size_t __bytes, size_t) override | |
| 398 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void do_deallocate(void * __p, size_t __bytes, size_t) override | |
| 400 | 399 | { |
| 401 | _LIBCPP_ASSERT(__bytes <= __max_size(), | |
| 400 | _LIBCPP_ASSERT_UNCATEGORIZED(__bytes <= __max_size(), | |
| 402 | 401 | "do_deallocate called for size which exceeds the maximum allocation size"); |
| 403 | 402 | size_t __s = __aligned_allocation_size(__bytes, _MaxAlign) / _MaxAlign; |
| 404 | 403 | __alloc_.deallocate((_ValueType*)__p, __s); |
| 405 | 404 | } |
| 406 | 405 | |
| 407 | bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override { | |
| 406 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool do_is_equal(memory_resource const & __other) const _NOEXCEPT override { | |
| 408 | 407 | __resource_adaptor_imp const * __p |
| 409 | 408 | = dynamic_cast<__resource_adaptor_imp const *>(&__other); |
| 410 | 409 | return __p ? __alloc_ == __p->__alloc_ : false; |
| ... | ... | @@ -432,11 +431,13 @@ _LIBCPP_POP_MACROS |
| 432 | 431 | # include <atomic> |
| 433 | 432 | # include <climits> |
| 434 | 433 | # include <concepts> |
| 434 | # include <cstdlib> | |
| 435 | 435 | # include <cstring> |
| 436 | 436 | # include <ctime> |
| 437 | 437 | # include <iterator> |
| 438 | 438 | # include <memory> |
| 439 | 439 | # include <ratio> |
| 440 | # include <type_traits> | |
| 440 | 441 | # include <variant> |
| 441 | 442 | #endif |
| 442 | 443 |
lib/libcxx/include/experimental/propagate_const+63-38| ... | ... | @@ -110,17 +110,35 @@ |
| 110 | 110 | #include <__assert> // all public C++ headers provide the assertion handler |
| 111 | 111 | #include <__functional/operations.h> |
| 112 | 112 | #include <__fwd/hash.h> |
| 113 | #include <__type_traits/conditional.h> | |
| 114 | #include <__type_traits/decay.h> | |
| 115 | #include <__type_traits/enable_if.h> | |
| 116 | #include <__type_traits/is_array.h> | |
| 117 | #include <__type_traits/is_constructible.h> | |
| 118 | #include <__type_traits/is_convertible.h> | |
| 119 | #include <__type_traits/is_function.h> | |
| 120 | #include <__type_traits/is_pointer.h> | |
| 121 | #include <__type_traits/is_reference.h> | |
| 122 | #include <__type_traits/is_same.h> | |
| 123 | #include <__type_traits/is_swappable.h> | |
| 124 | #include <__type_traits/remove_cv.h> | |
| 125 | #include <__type_traits/remove_pointer.h> | |
| 126 | #include <__type_traits/remove_reference.h> | |
| 127 | #include <__utility/declval.h> | |
| 113 | 128 | #include <__utility/forward.h> |
| 114 | 129 | #include <__utility/move.h> |
| 115 | 130 | #include <__utility/swap.h> |
| 131 | #include <cstddef> | |
| 116 | 132 | #include <experimental/__config> |
| 117 | #include <type_traits> | |
| 118 | 133 | |
| 119 | 134 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 120 | 135 | # pragma GCC system_header |
| 121 | 136 | #endif |
| 122 | 137 | |
| 123 | #if _LIBCPP_STD_VER > 11 | |
| 138 | _LIBCPP_PUSH_MACROS | |
| 139 | #include <__undef_macros> | |
| 140 | ||
| 141 | #if _LIBCPP_STD_VER >= 14 | |
| 124 | 142 | |
| 125 | 143 | _LIBCPP_BEGIN_NAMESPACE_LFTS_V2 |
| 126 | 144 | |
| ... | ... | @@ -152,25 +170,25 @@ public: |
| 152 | 170 | |
| 153 | 171 | private: |
| 154 | 172 | template <class _Up> |
| 155 | static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) | |
| 173 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up* __u) | |
| 156 | 174 | { |
| 157 | 175 | return __u; |
| 158 | 176 | } |
| 159 | 177 | |
| 160 | 178 | template <class _Up> |
| 161 | static _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) | |
| 179 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* __get_pointer(_Up& __u) | |
| 162 | 180 | { |
| 163 | 181 | return __get_pointer(__u.get()); |
| 164 | 182 | } |
| 165 | 183 | |
| 166 | 184 | template <class _Up> |
| 167 | static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) | |
| 185 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up* __u) | |
| 168 | 186 | { |
| 169 | 187 | return __u; |
| 170 | 188 | } |
| 171 | 189 | |
| 172 | 190 | template <class _Up> |
| 173 | static _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) | |
| 191 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* __get_pointer(const _Up& __u) | |
| 174 | 192 | { |
| 175 | 193 | return __get_pointer(__u.get()); |
| 176 | 194 | } |
| ... | ... | @@ -192,22 +210,22 @@ public: |
| 192 | 210 | template <class _Up> friend _LIBCPP_CONSTEXPR const _Up& ::_VSTD_LFTS_V2::get_underlying(const propagate_const<_Up>& __pu) _NOEXCEPT; |
| 193 | 211 | template <class _Up> friend _LIBCPP_CONSTEXPR _Up& ::_VSTD_LFTS_V2::get_underlying(propagate_const<_Up>& __pu) _NOEXCEPT; |
| 194 | 212 | |
| 195 | _LIBCPP_CONSTEXPR propagate_const() = default; | |
| 213 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const() = default; | |
| 196 | 214 | |
| 197 | 215 | propagate_const(const propagate_const&) = delete; |
| 198 | 216 | |
| 199 | _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; | |
| 217 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const&&) = default; | |
| 200 | 218 | |
| 201 | 219 | template <class _Up, enable_if_t<!is_convertible<_Up, _Tp>::value && |
| 202 | 220 | is_constructible<_Tp, _Up&&>::value,bool> = true> |
| 203 | explicit _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) | |
| 221 | explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) | |
| 204 | 222 | : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) |
| 205 | 223 | { |
| 206 | 224 | } |
| 207 | 225 | |
| 208 | 226 | template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && |
| 209 | 227 | is_constructible<_Tp, _Up&&>::value,bool> = false> |
| 210 | _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) | |
| 228 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(propagate_const<_Up>&& __pu) | |
| 211 | 229 | : __t_(std::move(_VSTD_LFTS_V2::get_underlying(__pu))) |
| 212 | 230 | { |
| 213 | 231 | } |
| ... | ... | @@ -215,7 +233,7 @@ public: |
| 215 | 233 | template <class _Up, enable_if_t<!is_convertible<_Up&&, _Tp>::value && |
| 216 | 234 | is_constructible<_Tp, _Up&&>::value && |
| 217 | 235 | !__is_propagate_const<decay_t<_Up>>::value,bool> = true> |
| 218 | explicit _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) | |
| 236 | explicit _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) | |
| 219 | 237 | : __t_(std::forward<_Up>(__u)) |
| 220 | 238 | { |
| 221 | 239 | } |
| ... | ... | @@ -223,78 +241,78 @@ public: |
| 223 | 241 | template <class _Up, enable_if_t<is_convertible<_Up&&, _Tp>::value && |
| 224 | 242 | is_constructible<_Tp, _Up&&>::value && |
| 225 | 243 | !__is_propagate_const<decay_t<_Up>>::value,bool> = false> |
| 226 | _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) | |
| 244 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const(_Up&& __u) | |
| 227 | 245 | : __t_(std::forward<_Up>(__u)) |
| 228 | 246 | { |
| 229 | 247 | } |
| 230 | 248 | |
| 231 | 249 | propagate_const& operator=(const propagate_const&) = delete; |
| 232 | 250 | |
| 233 | _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; | |
| 251 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const&&) = default; | |
| 234 | 252 | |
| 235 | 253 | template <class _Up> |
| 236 | _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) | |
| 254 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(propagate_const<_Up>&& __pu) | |
| 237 | 255 | { |
| 238 | 256 | __t_ = std::move(_VSTD_LFTS_V2::get_underlying(__pu)); |
| 239 | 257 | return *this; |
| 240 | 258 | } |
| 241 | 259 | |
| 242 | 260 | template <class _Up, class _Vp = enable_if_t<!__is_propagate_const<decay_t<_Up>>::value>> |
| 243 | _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) | |
| 261 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR propagate_const& operator=(_Up&& __u) | |
| 244 | 262 | { |
| 245 | 263 | __t_ = std::forward<_Up>(__u); |
| 246 | 264 | return *this; |
| 247 | 265 | } |
| 248 | 266 | |
| 249 | _LIBCPP_CONSTEXPR const element_type* get() const | |
| 267 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* get() const | |
| 250 | 268 | { |
| 251 | 269 | return __get_pointer(__t_); |
| 252 | 270 | } |
| 253 | 271 | |
| 254 | _LIBCPP_CONSTEXPR element_type* get() | |
| 272 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* get() | |
| 255 | 273 | { |
| 256 | 274 | return __get_pointer(__t_); |
| 257 | 275 | } |
| 258 | 276 | |
| 259 | explicit _LIBCPP_CONSTEXPR operator bool() const | |
| 277 | _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR operator bool() const | |
| 260 | 278 | { |
| 261 | 279 | return get() != nullptr; |
| 262 | 280 | } |
| 263 | 281 | |
| 264 | _LIBCPP_CONSTEXPR const element_type* operator->() const | |
| 282 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type* operator->() const | |
| 265 | 283 | { |
| 266 | 284 | return get(); |
| 267 | 285 | } |
| 268 | 286 | |
| 269 | template <class _Tp_ = _Tp, class _Up = enable_if_t<is_convertible< | |
| 270 | const _Tp_, const element_type *>::value>> | |
| 271 | _LIBCPP_CONSTEXPR operator const element_type *() const { | |
| 287 | template <class _Dummy = _Tp, class _Up = enable_if_t<is_convertible< | |
| 288 | const _Dummy, const element_type *>::value>> | |
| 289 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator const element_type *() const { | |
| 272 | 290 | return get(); |
| 273 | 291 | } |
| 274 | 292 | |
| 275 | _LIBCPP_CONSTEXPR const element_type& operator*() const | |
| 293 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const element_type& operator*() const | |
| 276 | 294 | { |
| 277 | 295 | return *get(); |
| 278 | 296 | } |
| 279 | 297 | |
| 280 | _LIBCPP_CONSTEXPR element_type* operator->() | |
| 298 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type* operator->() | |
| 281 | 299 | { |
| 282 | 300 | return get(); |
| 283 | 301 | } |
| 284 | 302 | |
| 285 | template <class _Tp_ = _Tp, class _Up = enable_if_t< | |
| 286 | is_convertible<_Tp_, element_type *>::value>> | |
| 287 | _LIBCPP_CONSTEXPR operator element_type *() { | |
| 303 | template <class _Dummy = _Tp, class _Up = enable_if_t< | |
| 304 | is_convertible<_Dummy, element_type *>::value>> | |
| 305 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator element_type *() { | |
| 288 | 306 | return get(); |
| 289 | 307 | } |
| 290 | 308 | |
| 291 | _LIBCPP_CONSTEXPR element_type& operator*() | |
| 309 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR element_type& operator*() | |
| 292 | 310 | { |
| 293 | 311 | return *get(); |
| 294 | 312 | } |
| 295 | 313 | |
| 296 | _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) | |
| 297 | { | |
| 314 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR void swap(propagate_const& __pt) | |
| 315 | _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { | |
| 298 | 316 | using _VSTD::swap; |
| 299 | 317 | swap(__t_, __pt.__t_); |
| 300 | 318 | } |
| ... | ... | @@ -491,7 +509,7 @@ struct hash<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 491 | 509 | typedef size_t result_type; |
| 492 | 510 | typedef experimental::fundamentals_v2::propagate_const<_Tp> argument_type; |
| 493 | 511 | |
| 494 | size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const | |
| 512 | _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1) const | |
| 495 | 513 | { |
| 496 | 514 | return std::hash<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1)); |
| 497 | 515 | } |
| ... | ... | @@ -503,7 +521,7 @@ struct equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 503 | 521 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 504 | 522 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 505 | 523 | |
| 506 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 524 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 507 | 525 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 508 | 526 | { |
| 509 | 527 | return std::equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -516,7 +534,7 @@ struct not_equal_to<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 516 | 534 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 517 | 535 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 518 | 536 | |
| 519 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 537 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 520 | 538 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 521 | 539 | { |
| 522 | 540 | return std::not_equal_to<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -529,7 +547,7 @@ struct less<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 529 | 547 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 530 | 548 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 531 | 549 | |
| 532 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 550 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 533 | 551 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 534 | 552 | { |
| 535 | 553 | return std::less<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -542,7 +560,7 @@ struct greater<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 542 | 560 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 543 | 561 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 544 | 562 | |
| 545 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 563 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 546 | 564 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 547 | 565 | { |
| 548 | 566 | return std::greater<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -555,7 +573,7 @@ struct less_equal<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 555 | 573 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 556 | 574 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 557 | 575 | |
| 558 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 576 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 559 | 577 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 560 | 578 | { |
| 561 | 579 | return std::less_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -568,7 +586,7 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 568 | 586 | typedef experimental::fundamentals_v2::propagate_const<_Tp> first_argument_type; |
| 569 | 587 | typedef experimental::fundamentals_v2::propagate_const<_Tp> second_argument_type; |
| 570 | 588 | |
| 571 | bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 589 | _LIBCPP_HIDE_FROM_ABI bool operator()(const experimental::fundamentals_v2::propagate_const<_Tp>& __pc1, | |
| 572 | 590 | const experimental::fundamentals_v2::propagate_const<_Tp>& __pc2) const |
| 573 | 591 | { |
| 574 | 592 | return std::greater_equal<_Tp>()(_VSTD_LFTS_V2::get_underlying(__pc1), _VSTD_LFTS_V2::get_underlying(__pc2)); |
| ... | ... | @@ -577,5 +595,12 @@ struct greater_equal<experimental::fundamentals_v2::propagate_const<_Tp>> |
| 577 | 595 | |
| 578 | 596 | _LIBCPP_END_NAMESPACE_STD |
| 579 | 597 | |
| 580 | #endif // _LIBCPP_STD_VER > 11 | |
| 598 | #endif // _LIBCPP_STD_VER >= 14 | |
| 599 | ||
| 600 | _LIBCPP_POP_MACROS | |
| 601 | ||
| 602 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 603 | # include <type_traits> | |
| 604 | #endif | |
| 605 | ||
| 581 | 606 | #endif // _LIBCPP_EXPERIMENTAL_PROPAGATE_CONST |
lib/libcxx/include/experimental/simd+41-41| ... | ... | @@ -691,8 +691,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Array, __num_element>> { |
| 691 | 691 | friend struct simd_mask; |
| 692 | 692 | |
| 693 | 693 | public: |
| 694 | _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } | |
| 695 | void __set(size_t __index, _Tp __val) noexcept { | |
| 694 | _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } | |
| 695 | _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept { | |
| 696 | 696 | __storage_[__index] = __val; |
| 697 | 697 | } |
| 698 | 698 | }; |
| ... | ... | @@ -708,8 +708,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_Scalar, 1>> { |
| 708 | 708 | friend struct simd_mask; |
| 709 | 709 | |
| 710 | 710 | public: |
| 711 | _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; } | |
| 712 | void __set(size_t __index, _Tp __val) noexcept { | |
| 711 | _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return (&__storage_)[__index]; } | |
| 712 | _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept { | |
| 713 | 713 | (&__storage_)[__index] = __val; |
| 714 | 714 | } |
| 715 | 715 | }; |
| ... | ... | @@ -810,8 +810,8 @@ class __simd_storage<_Tp, __simd_abi<_StorageKind::_VecExt, __num_element>> { |
| 810 | 810 | friend struct simd_mask; |
| 811 | 811 | |
| 812 | 812 | public: |
| 813 | _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } | |
| 814 | void __set(size_t __index, _Tp __val) noexcept { | |
| 813 | _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __index) const noexcept { return __storage_[__index]; } | |
| 814 | _LIBCPP_HIDE_FROM_ABI void __set(size_t __index, _Tp __val) noexcept { | |
| 815 | 815 | __storage_[__index] = __val; |
| 816 | 816 | } |
| 817 | 817 | }; |
| ... | ... | @@ -831,79 +831,79 @@ class __simd_reference { |
| 831 | 831 | __simd_storage<_Tp, _Abi>* __ptr_; |
| 832 | 832 | size_t __index_; |
| 833 | 833 | |
| 834 | __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index) | |
| 834 | _LIBCPP_HIDE_FROM_ABI __simd_reference(__simd_storage<_Tp, _Abi>* __ptr, size_t __index) | |
| 835 | 835 | : __ptr_(__ptr), __index_(__index) {} |
| 836 | 836 | |
| 837 | __simd_reference(const __simd_reference&) = default; | |
| 837 | _LIBCPP_HIDE_FROM_ABI __simd_reference(const __simd_reference&) = default; | |
| 838 | 838 | |
| 839 | 839 | public: |
| 840 | 840 | __simd_reference() = delete; |
| 841 | 841 | __simd_reference& operator=(const __simd_reference&) = delete; |
| 842 | 842 | |
| 843 | operator _Vp() const { return __ptr_->__get(__index_); } | |
| 843 | _LIBCPP_HIDE_FROM_ABI operator _Vp() const { return __ptr_->__get(__index_); } | |
| 844 | 844 | |
| 845 | __simd_reference operator=(_Vp __value) && { | |
| 845 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator=(_Vp __value) && { | |
| 846 | 846 | __ptr_->__set(__index_, __value); |
| 847 | 847 | return *this; |
| 848 | 848 | } |
| 849 | 849 | |
| 850 | __simd_reference operator++() && { | |
| 850 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator++() && { | |
| 851 | 851 | return std::move(*this) = __ptr_->__get(__index_) + 1; |
| 852 | 852 | } |
| 853 | 853 | |
| 854 | _Vp operator++(int) && { | |
| 854 | _LIBCPP_HIDE_FROM_ABI _Vp operator++(int) && { | |
| 855 | 855 | auto __val = __ptr_->__get(__index_); |
| 856 | 856 | __ptr_->__set(__index_, __val + 1); |
| 857 | 857 | return __val; |
| 858 | 858 | } |
| 859 | 859 | |
| 860 | __simd_reference operator--() && { | |
| 860 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator--() && { | |
| 861 | 861 | return std::move(*this) = __ptr_->__get(__index_) - 1; |
| 862 | 862 | } |
| 863 | 863 | |
| 864 | _Vp operator--(int) && { | |
| 864 | _LIBCPP_HIDE_FROM_ABI _Vp operator--(int) && { | |
| 865 | 865 | auto __val = __ptr_->__get(__index_); |
| 866 | 866 | __ptr_->__set(__index_, __val - 1); |
| 867 | 867 | return __val; |
| 868 | 868 | } |
| 869 | 869 | |
| 870 | __simd_reference operator+=(_Vp __value) && { | |
| 870 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator+=(_Vp __value) && { | |
| 871 | 871 | return std::move(*this) = __ptr_->__get(__index_) + __value; |
| 872 | 872 | } |
| 873 | 873 | |
| 874 | __simd_reference operator-=(_Vp __value) && { | |
| 874 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator-=(_Vp __value) && { | |
| 875 | 875 | return std::move(*this) = __ptr_->__get(__index_) - __value; |
| 876 | 876 | } |
| 877 | 877 | |
| 878 | __simd_reference operator*=(_Vp __value) && { | |
| 878 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator*=(_Vp __value) && { | |
| 879 | 879 | return std::move(*this) = __ptr_->__get(__index_) * __value; |
| 880 | 880 | } |
| 881 | 881 | |
| 882 | __simd_reference operator/=(_Vp __value) && { | |
| 882 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator/=(_Vp __value) && { | |
| 883 | 883 | return std::move(*this) = __ptr_->__get(__index_) / __value; |
| 884 | 884 | } |
| 885 | 885 | |
| 886 | __simd_reference operator%=(_Vp __value) && { | |
| 886 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator%=(_Vp __value) && { | |
| 887 | 887 | return std::move(*this) = __ptr_->__get(__index_) % __value; |
| 888 | 888 | } |
| 889 | 889 | |
| 890 | __simd_reference operator>>=(_Vp __value) && { | |
| 890 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator>>=(_Vp __value) && { | |
| 891 | 891 | return std::move(*this) = __ptr_->__get(__index_) >> __value; |
| 892 | 892 | } |
| 893 | 893 | |
| 894 | __simd_reference operator<<=(_Vp __value) && { | |
| 894 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator<<=(_Vp __value) && { | |
| 895 | 895 | return std::move(*this) = __ptr_->__get(__index_) << __value; |
| 896 | 896 | } |
| 897 | 897 | |
| 898 | __simd_reference operator&=(_Vp __value) && { | |
| 898 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator&=(_Vp __value) && { | |
| 899 | 899 | return std::move(*this) = __ptr_->__get(__index_) & __value; |
| 900 | 900 | } |
| 901 | 901 | |
| 902 | __simd_reference operator|=(_Vp __value) && { | |
| 902 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator|=(_Vp __value) && { | |
| 903 | 903 | return std::move(*this) = __ptr_->__get(__index_) | __value; |
| 904 | 904 | } |
| 905 | 905 | |
| 906 | __simd_reference operator^=(_Vp __value) && { | |
| 906 | _LIBCPP_HIDE_FROM_ABI __simd_reference operator^=(_Vp __value) && { | |
| 907 | 907 | return std::move(*this) = __ptr_->__get(__index_) ^ __value; |
| 908 | 908 | } |
| 909 | 909 | }; |
| ... | ... | @@ -1350,11 +1350,11 @@ public: |
| 1350 | 1350 | using mask_type = simd_mask<_Tp, _Abi>; |
| 1351 | 1351 | using abi_type = _Abi; |
| 1352 | 1352 | |
| 1353 | simd() = default; | |
| 1354 | simd(const simd&) = default; | |
| 1355 | simd& operator=(const simd&) = default; | |
| 1353 | _LIBCPP_HIDE_FROM_ABI simd() = default; | |
| 1354 | _LIBCPP_HIDE_FROM_ABI simd(const simd&) = default; | |
| 1355 | _LIBCPP_HIDE_FROM_ABI simd& operator=(const simd&) = default; | |
| 1356 | 1356 | |
| 1357 | static constexpr size_t size() noexcept { | |
| 1357 | static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { | |
| 1358 | 1358 | return simd_size<_Tp, _Abi>::value; |
| 1359 | 1359 | } |
| 1360 | 1360 | |
| ... | ... | @@ -1362,7 +1362,7 @@ private: |
| 1362 | 1362 | __simd_storage<_Tp, _Abi> __s_; |
| 1363 | 1363 | |
| 1364 | 1364 | template <class _Up> |
| 1365 | static constexpr bool __can_broadcast() { | |
| 1365 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_broadcast() { | |
| 1366 | 1366 | return (std::is_arithmetic<_Up>::value && |
| 1367 | 1367 | __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()) || |
| 1368 | 1368 | (!std::is_arithmetic<_Up>::value && |
| ... | ... | @@ -1374,7 +1374,7 @@ private: |
| 1374 | 1374 | } |
| 1375 | 1375 | |
| 1376 | 1376 | template <class _Generator, size_t... __indicies> |
| 1377 | static constexpr decltype( | |
| 1377 | static _LIBCPP_HIDE_FROM_ABI constexpr decltype( | |
| 1378 | 1378 | std::forward_as_tuple(std::declval<_Generator>()( |
| 1379 | 1379 | std::integral_constant<size_t, __indicies>())...), |
| 1380 | 1380 | bool()) |
| ... | ... | @@ -1385,12 +1385,12 @@ private: |
| 1385 | 1385 | } |
| 1386 | 1386 | |
| 1387 | 1387 | template <class _Generator> |
| 1388 | static bool __can_generate(...) { | |
| 1388 | static _LIBCPP_HIDE_FROM_ABI bool __can_generate(...) { | |
| 1389 | 1389 | return false; |
| 1390 | 1390 | } |
| 1391 | 1391 | |
| 1392 | 1392 | template <class _Generator, size_t... __indicies> |
| 1393 | void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) { | |
| 1393 | _LIBCPP_HIDE_FROM_ABI void __generator_init(_Generator&& __g, std::index_sequence<__indicies...>) { | |
| 1394 | 1394 | int __not_used[]{((*this)[__indicies] = |
| 1395 | 1395 | __g(std::integral_constant<size_t, __indicies>()), |
| 1396 | 1396 | 0)...}; |
| ... | ... | @@ -1403,7 +1403,7 @@ public: |
| 1403 | 1403 | class = typename std::enable_if< |
| 1404 | 1404 | std::is_same<_Abi, simd_abi::fixed_size<size()>>::value && |
| 1405 | 1405 | __is_non_narrowing_arithmetic_convertible<_Up, _Tp>()>::type> |
| 1406 | simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) { | |
| 1406 | _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) { | |
| 1407 | 1407 | for (size_t __i = 0; __i < size(); __i++) { |
| 1408 | 1408 | (*this)[__i] = static_cast<_Tp>(__v[__i]); |
| 1409 | 1409 | } |
| ... | ... | @@ -1412,7 +1412,7 @@ public: |
| 1412 | 1412 | // implicit broadcast constructor |
| 1413 | 1413 | template <class _Up, |
| 1414 | 1414 | class = typename std::enable_if<__can_broadcast<_Up>()>::type> |
| 1415 | simd(_Up&& __rv) { | |
| 1415 | _LIBCPP_HIDE_FROM_ABI simd(_Up&& __rv) { | |
| 1416 | 1416 | auto __v = static_cast<_Tp>(__rv); |
| 1417 | 1417 | for (size_t __i = 0; __i < size(); __i++) { |
| 1418 | 1418 | (*this)[__i] = __v; |
| ... | ... | @@ -1424,7 +1424,7 @@ public: |
| 1424 | 1424 | int = typename std::enable_if< |
| 1425 | 1425 | __can_generate<_Generator>(std::make_index_sequence<size()>()), |
| 1426 | 1426 | int>::type()> |
| 1427 | explicit simd(_Generator&& __g) { | |
| 1427 | explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) { | |
| 1428 | 1428 | __generator_init(std::forward<_Generator>(__g), |
| 1429 | 1429 | std::make_index_sequence<size()>()); |
| 1430 | 1430 | } |
| ... | ... | @@ -1434,7 +1434,7 @@ public: |
| 1434 | 1434 | class _Up, class _Flags, |
| 1435 | 1435 | class = typename std::enable_if<__vectorizable<_Up>()>::type, |
| 1436 | 1436 | class = typename std::enable_if<is_simd_flag_type<_Flags>::value>::type> |
| 1437 | simd(const _Up* __buffer, _Flags) { | |
| 1437 | _LIBCPP_HIDE_FROM_ABI simd(const _Up* __buffer, _Flags) { | |
| 1438 | 1438 | // TODO: optimize for overaligned flags |
| 1439 | 1439 | for (size_t __i = 0; __i < size(); __i++) { |
| 1440 | 1440 | (*this)[__i] = static_cast<_Tp>(__buffer[__i]); |
| ... | ... | @@ -1445,7 +1445,7 @@ public: |
| 1445 | 1445 | template <class _Up, class _Flags> |
| 1446 | 1446 | typename std::enable_if<__vectorizable<_Up>() && |
| 1447 | 1447 | is_simd_flag_type<_Flags>::value>::type |
| 1448 | copy_from(const _Up* __buffer, _Flags) { | |
| 1448 | _LIBCPP_HIDE_FROM_ABI copy_from(const _Up* __buffer, _Flags) { | |
| 1449 | 1449 | *this = simd(__buffer, _Flags()); |
| 1450 | 1450 | } |
| 1451 | 1451 | |
| ... | ... | @@ -1453,7 +1453,7 @@ public: |
| 1453 | 1453 | template <class _Up, class _Flags> |
| 1454 | 1454 | typename std::enable_if<__vectorizable<_Up>() && |
| 1455 | 1455 | is_simd_flag_type<_Flags>::value>::type |
| 1456 | copy_to(_Up* __buffer, _Flags) const { | |
| 1456 | _LIBCPP_HIDE_FROM_ABI copy_to(_Up* __buffer, _Flags) const { | |
| 1457 | 1457 | // TODO: optimize for overaligned flags |
| 1458 | 1458 | for (size_t __i = 0; __i < size(); __i++) { |
| 1459 | 1459 | __buffer[__i] = static_cast<_Up>((*this)[__i]); |
| ... | ... | @@ -1461,9 +1461,9 @@ public: |
| 1461 | 1461 | } |
| 1462 | 1462 | |
| 1463 | 1463 | // scalar access [simd.subscr] |
| 1464 | reference operator[](size_t __i) { return reference(&__s_, __i); } | |
| 1464 | _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) { return reference(&__s_, __i); } | |
| 1465 | 1465 | |
| 1466 | value_type operator[](size_t __i) const { return __s_.__get(__i); } | |
| 1466 | _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const { return __s_.__get(__i); } | |
| 1467 | 1467 | |
| 1468 | 1468 | // unary operators [simd.unary] |
| 1469 | 1469 | simd& operator++(); |
| ... | ... | @@ -1526,7 +1526,7 @@ public: |
| 1526 | 1526 | using simd_type = simd<_Tp, _Abi>; |
| 1527 | 1527 | using abi_type = _Abi; |
| 1528 | 1528 | static constexpr size_t size() noexcept; |
| 1529 | simd_mask() = default; | |
| 1529 | _LIBCPP_HIDE_FROM_ABI simd_mask() = default; | |
| 1530 | 1530 | |
| 1531 | 1531 | // broadcast constructor |
| 1532 | 1532 | explicit simd_mask(value_type) noexcept; |
lib/libcxx/include/experimental/type_traits+14-14| ... | ... | @@ -71,7 +71,7 @@ inline namespace fundamentals_v1 { |
| 71 | 71 | #include <__assert> // all public C++ headers provide the assertion handler |
| 72 | 72 | #include <experimental/__config> |
| 73 | 73 | |
| 74 | #if _LIBCPP_STD_VER > 11 | |
| 74 | #if _LIBCPP_STD_VER >= 14 | |
| 75 | 75 | |
| 76 | 76 | #include <initializer_list> |
| 77 | 77 | #include <type_traits> |
| ... | ... | @@ -132,24 +132,24 @@ template <template<class...> class _Op, class... _Args> |
| 132 | 132 | template <template<class...> class _Op, class... _Args> |
| 133 | 133 | _LIBCPP_CONSTEXPR bool is_detected_v = is_detected<_Op, _Args...>::value; |
| 134 | 134 | |
| 135 | template <class Default, template<class...> class _Op, class... _Args> | |
| 136 | using detected_or = _DETECTOR<Default, void, _Op, _Args...>; | |
| 137 | template <class Default, template<class...> class _Op, class... _Args> | |
| 138 | using detected_or_t = typename detected_or<Default, _Op, _Args...>::type; | |
| 135 | template <class _Default, template<class...> class _Op, class... _Args> | |
| 136 | using detected_or = _DETECTOR<_Default, void, _Op, _Args...>; | |
| 137 | template <class _Default, template<class...> class _Op, class... _Args> | |
| 138 | using detected_or_t = typename detected_or<_Default, _Op, _Args...>::type; | |
| 139 | 139 | |
| 140 | template <class Expected, template<class...> class _Op, class... _Args> | |
| 141 | using is_detected_exact = is_same<Expected, detected_t<_Op, _Args...>>; | |
| 142 | template <class Expected, template<class...> class _Op, class... _Args> | |
| 143 | _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<Expected, _Op, _Args...>::value; | |
| 140 | template <class _Expected, template<class...> class _Op, class... _Args> | |
| 141 | using is_detected_exact = is_same<_Expected, detected_t<_Op, _Args...>>; | |
| 142 | template <class _Expected, template<class...> class _Op, class... _Args> | |
| 143 | _LIBCPP_CONSTEXPR bool is_detected_exact_v = is_detected_exact<_Expected, _Op, _Args...>::value; | |
| 144 | 144 | |
| 145 | template <class To, template<class...> class _Op, class... _Args> | |
| 146 | using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, To>; | |
| 147 | template <class To, template<class...> class _Op, class... _Args> | |
| 148 | _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<To, _Op, _Args...>::value; | |
| 145 | template <class _To, template<class...> class _Op, class... _Args> | |
| 146 | using is_detected_convertible = is_convertible<detected_t<_Op, _Args...>, _To>; | |
| 147 | template <class _To, template<class...> class _Op, class... _Args> | |
| 148 | _LIBCPP_CONSTEXPR bool is_detected_convertible_v = is_detected_convertible<_To, _Op, _Args...>::value; | |
| 149 | 149 | |
| 150 | 150 | |
| 151 | 151 | _LIBCPP_END_NAMESPACE_LFTS |
| 152 | 152 | |
| 153 | #endif /* _LIBCPP_STD_VER > 11 */ | |
| 153 | #endif /* _LIBCPP_STD_VER >= 14 */ | |
| 154 | 154 | |
| 155 | 155 | #endif /* _LIBCPP_EXPERIMENTAL_TYPE_TRAITS */ |
lib/libcxx/include/ext/hash_map+16-16| ... | ... | @@ -208,7 +208,6 @@ template <class Key, class T, class Hash, class Pred, class Alloc> |
| 208 | 208 | #include <ext/__hash> |
| 209 | 209 | #include <functional> |
| 210 | 210 | #include <stdexcept> |
| 211 | #include <type_traits> | |
| 212 | 211 | |
| 213 | 212 | #if defined(__DEPRECATED) && __DEPRECATED |
| 214 | 213 | #if defined(_LIBCPP_WARNING) |
| ... | ... | @@ -324,7 +323,7 @@ public: |
| 324 | 323 | bool __first_constructed; |
| 325 | 324 | bool __second_constructed; |
| 326 | 325 | |
| 327 | __hash_map_node_destructor(__hash_map_node_destructor const&) = default; | |
| 326 | _LIBCPP_HIDE_FROM_ABI __hash_map_node_destructor(__hash_map_node_destructor const&) = default; | |
| 328 | 327 | __hash_map_node_destructor& operator=(const __hash_map_node_destructor&) = delete; |
| 329 | 328 | |
| 330 | 329 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -508,23 +507,23 @@ public: |
| 508 | 507 | typedef __hash_map_const_iterator<typename __table::const_iterator> const_iterator; |
| 509 | 508 | |
| 510 | 509 | _LIBCPP_INLINE_VISIBILITY hash_map() { } |
| 511 | explicit hash_map(size_type __n, const hasher& __hf = hasher(), | |
| 510 | explicit _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf = hasher(), | |
| 512 | 511 | const key_equal& __eql = key_equal()); |
| 513 | hash_map(size_type __n, const hasher& __hf, | |
| 512 | _LIBCPP_HIDE_FROM_ABI hash_map(size_type __n, const hasher& __hf, | |
| 514 | 513 | const key_equal& __eql, |
| 515 | 514 | const allocator_type& __a); |
| 516 | 515 | template <class _InputIterator> |
| 517 | hash_map(_InputIterator __first, _InputIterator __last); | |
| 516 | _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last); | |
| 518 | 517 | template <class _InputIterator> |
| 519 | hash_map(_InputIterator __first, _InputIterator __last, | |
| 518 | _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last, | |
| 520 | 519 | size_type __n, const hasher& __hf = hasher(), |
| 521 | 520 | const key_equal& __eql = key_equal()); |
| 522 | 521 | template <class _InputIterator> |
| 523 | hash_map(_InputIterator __first, _InputIterator __last, | |
| 522 | _LIBCPP_HIDE_FROM_ABI hash_map(_InputIterator __first, _InputIterator __last, | |
| 524 | 523 | size_type __n, const hasher& __hf, |
| 525 | 524 | const key_equal& __eql, |
| 526 | 525 | const allocator_type& __a); |
| 527 | hash_map(const hash_map& __u); | |
| 526 | _LIBCPP_HIDE_FROM_ABI hash_map(const hash_map& __u); | |
| 528 | 527 | |
| 529 | 528 | _LIBCPP_INLINE_VISIBILITY |
| 530 | 529 | allocator_type get_allocator() const |
| ... | ... | @@ -588,7 +587,7 @@ public: |
| 588 | 587 | std::pair<const_iterator, const_iterator> equal_range(const key_type& __k) const |
| 589 | 588 | {return __table_.__equal_range_unique(__k);} |
| 590 | 589 | |
| 591 | mapped_type& operator[](const key_type& __k); | |
| 590 | _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k); | |
| 592 | 591 | |
| 593 | 592 | _LIBCPP_INLINE_VISIBILITY |
| 594 | 593 | size_type bucket_count() const {return __table_.bucket_count();} |
| ... | ... | @@ -603,7 +602,7 @@ public: |
| 603 | 602 | void resize(size_type __n) {__table_.__rehash_unique(__n);} |
| 604 | 603 | |
| 605 | 604 | private: |
| 606 | __node_holder __construct_node(const key_type& __k); | |
| 605 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(const key_type& __k); | |
| 607 | 606 | }; |
| 608 | 607 | |
| 609 | 608 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -780,23 +779,23 @@ public: |
| 780 | 779 | |
| 781 | 780 | _LIBCPP_INLINE_VISIBILITY |
| 782 | 781 | hash_multimap() { } |
| 783 | explicit hash_multimap(size_type __n, const hasher& __hf = hasher(), | |
| 782 | explicit _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf = hasher(), | |
| 784 | 783 | const key_equal& __eql = key_equal()); |
| 785 | hash_multimap(size_type __n, const hasher& __hf, | |
| 784 | _LIBCPP_HIDE_FROM_ABI hash_multimap(size_type __n, const hasher& __hf, | |
| 786 | 785 | const key_equal& __eql, |
| 787 | 786 | const allocator_type& __a); |
| 788 | 787 | template <class _InputIterator> |
| 789 | hash_multimap(_InputIterator __first, _InputIterator __last); | |
| 788 | _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last); | |
| 790 | 789 | template <class _InputIterator> |
| 791 | hash_multimap(_InputIterator __first, _InputIterator __last, | |
| 790 | _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last, | |
| 792 | 791 | size_type __n, const hasher& __hf = hasher(), |
| 793 | 792 | const key_equal& __eql = key_equal()); |
| 794 | 793 | template <class _InputIterator> |
| 795 | hash_multimap(_InputIterator __first, _InputIterator __last, | |
| 794 | _LIBCPP_HIDE_FROM_ABI hash_multimap(_InputIterator __first, _InputIterator __last, | |
| 796 | 795 | size_type __n, const hasher& __hf, |
| 797 | 796 | const key_equal& __eql, |
| 798 | 797 | const allocator_type& __a); |
| 799 | hash_multimap(const hash_multimap& __u); | |
| 798 | _LIBCPP_HIDE_FROM_ABI hash_multimap(const hash_multimap& __u); | |
| 800 | 799 | |
| 801 | 800 | _LIBCPP_INLINE_VISIBILITY |
| 802 | 801 | allocator_type get_allocator() const |
| ... | ... | @@ -985,6 +984,7 @@ operator!=(const hash_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 985 | 984 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 986 | 985 | # include <concepts> |
| 987 | 986 | # include <iterator> |
| 987 | # include <type_traits> | |
| 988 | 988 | #endif |
| 989 | 989 | |
| 990 | 990 | #endif // _LIBCPP_HASH_MAP |
lib/libcxx/include/ext/hash_set+13-12| ... | ... | @@ -244,21 +244,21 @@ public: |
| 244 | 244 | |
| 245 | 245 | _LIBCPP_INLINE_VISIBILITY |
| 246 | 246 | hash_set() { } |
| 247 | explicit hash_set(size_type __n, const hasher& __hf = hasher(), | |
| 247 | _LIBCPP_HIDE_FROM_ABI explicit hash_set(size_type __n, const hasher& __hf = hasher(), | |
| 248 | 248 | const key_equal& __eql = key_equal()); |
| 249 | hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, | |
| 249 | _LIBCPP_HIDE_FROM_ABI hash_set(size_type __n, const hasher& __hf, const key_equal& __eql, | |
| 250 | 250 | const allocator_type& __a); |
| 251 | 251 | template <class _InputIterator> |
| 252 | hash_set(_InputIterator __first, _InputIterator __last); | |
| 252 | _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last); | |
| 253 | 253 | template <class _InputIterator> |
| 254 | hash_set(_InputIterator __first, _InputIterator __last, | |
| 254 | _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last, | |
| 255 | 255 | size_type __n, const hasher& __hf = hasher(), |
| 256 | 256 | const key_equal& __eql = key_equal()); |
| 257 | 257 | template <class _InputIterator> |
| 258 | hash_set(_InputIterator __first, _InputIterator __last, | |
| 258 | _LIBCPP_HIDE_FROM_ABI hash_set(_InputIterator __first, _InputIterator __last, | |
| 259 | 259 | size_type __n, const hasher& __hf, const key_equal& __eql, |
| 260 | 260 | const allocator_type& __a); |
| 261 | hash_set(const hash_set& __u); | |
| 261 | _LIBCPP_HIDE_FROM_ABI hash_set(const hash_set& __u); | |
| 262 | 262 | |
| 263 | 263 | _LIBCPP_INLINE_VISIBILITY |
| 264 | 264 | allocator_type get_allocator() const |
| ... | ... | @@ -465,21 +465,21 @@ public: |
| 465 | 465 | |
| 466 | 466 | _LIBCPP_INLINE_VISIBILITY |
| 467 | 467 | hash_multiset() { } |
| 468 | explicit hash_multiset(size_type __n, const hasher& __hf = hasher(), | |
| 468 | explicit _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf = hasher(), | |
| 469 | 469 | const key_equal& __eql = key_equal()); |
| 470 | hash_multiset(size_type __n, const hasher& __hf, | |
| 470 | _LIBCPP_HIDE_FROM_ABI hash_multiset(size_type __n, const hasher& __hf, | |
| 471 | 471 | const key_equal& __eql, const allocator_type& __a); |
| 472 | 472 | template <class _InputIterator> |
| 473 | hash_multiset(_InputIterator __first, _InputIterator __last); | |
| 473 | _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last); | |
| 474 | 474 | template <class _InputIterator> |
| 475 | hash_multiset(_InputIterator __first, _InputIterator __last, | |
| 475 | _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last, | |
| 476 | 476 | size_type __n, const hasher& __hf = hasher(), |
| 477 | 477 | const key_equal& __eql = key_equal()); |
| 478 | 478 | template <class _InputIterator> |
| 479 | hash_multiset(_InputIterator __first, _InputIterator __last, | |
| 479 | _LIBCPP_HIDE_FROM_ABI hash_multiset(_InputIterator __first, _InputIterator __last, | |
| 480 | 480 | size_type __n , const hasher& __hf, |
| 481 | 481 | const key_equal& __eql, const allocator_type& __a); |
| 482 | hash_multiset(const hash_multiset& __u); | |
| 482 | _LIBCPP_HIDE_FROM_ABI hash_multiset(const hash_multiset& __u); | |
| 483 | 483 | |
| 484 | 484 | _LIBCPP_INLINE_VISIBILITY |
| 485 | 485 | allocator_type get_allocator() const |
| ... | ... | @@ -665,6 +665,7 @@ operator!=(const hash_multiset<_Value, _Hash, _Pred, _Alloc>& __x, |
| 665 | 665 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 666 | 666 | # include <concepts> |
| 667 | 667 | # include <iterator> |
| 668 | # include <type_traits> | |
| 668 | 669 | #endif |
| 669 | 670 | |
| 670 | 671 | #endif // _LIBCPP_HASH_SET |
lib/libcxx/include/filesystem+109-7| ... | ... | @@ -159,6 +159,9 @@ |
| 159 | 159 | void swap(path& lhs, path& rhs) noexcept; |
| 160 | 160 | size_t hash_value(const path& p) noexcept; |
| 161 | 161 | |
| 162 | // [fs.path.hash], hash support | |
| 163 | template<> struct hash<filesystem::path>; | |
| 164 | ||
| 162 | 165 | template <class Source> |
| 163 | 166 | path u8path(const Source& source); |
| 164 | 167 | template <class InputIterator> |
| ... | ... | @@ -233,19 +236,120 @@ |
| 233 | 236 | friend class directory_iterator; // exposition only |
| 234 | 237 | }; |
| 235 | 238 | |
| 236 | class directory_iterator; | |
| 239 | class directory_iterator { | |
| 240 | public: | |
| 241 | using iterator_category = input_iterator_tag; | |
| 242 | using value_type = directory_entry; | |
| 243 | using difference_type = ptrdiff_t; | |
| 244 | using pointer = const directory_entry*; | |
| 245 | using reference = const directory_entry&; | |
| 246 | ||
| 247 | // [fs.dir.itr.members], member functions | |
| 248 | directory_iterator() noexcept; | |
| 249 | explicit directory_iterator(const path& p); | |
| 250 | directory_iterator(const path& p, directory_options options); | |
| 251 | directory_iterator(const path& p, error_code& ec); | |
| 252 | directory_iterator(const path& p, directory_options options, | |
| 253 | error_code& ec); | |
| 254 | directory_iterator(const directory_iterator& rhs); | |
| 255 | directory_iterator(directory_iterator&& rhs) noexcept; | |
| 256 | ~directory_iterator(); | |
| 257 | ||
| 258 | directory_iterator& operator=(const directory_iterator& rhs); | |
| 259 | directory_iterator& operator=(directory_iterator&& rhs) noexcept; | |
| 260 | ||
| 261 | const directory_entry& operator*() const; | |
| 262 | const directory_entry* operator->() const; | |
| 263 | directory_iterator& operator++(); | |
| 264 | directory_iterator& increment(error_code& ec); | |
| 265 | ||
| 266 | bool operator==(default_sentinel_t) const noexcept { // since C++20 | |
| 267 | return *this == directory_iterator(); | |
| 268 | } | |
| 269 | ||
| 270 | // other members as required by [input.iterators], input iterators | |
| 271 | }; | |
| 237 | 272 | |
| 238 | 273 | // enable directory_iterator range-based for statements |
| 239 | 274 | directory_iterator begin(directory_iterator iter) noexcept; |
| 240 | 275 | directory_iterator end(directory_iterator) noexcept; |
| 241 | 276 | |
| 242 | class recursive_directory_iterator; | |
| 277 | class recursive_directory_iterator { | |
| 278 | public: | |
| 279 | using iterator_category = input_iterator_tag; | |
| 280 | using value_type = directory_entry; | |
| 281 | using difference_type = ptrdiff_t; | |
| 282 | using pointer = const directory_entry*; | |
| 283 | using reference = const directory_entry&; | |
| 284 | ||
| 285 | // [fs.rec.dir.itr.members], constructors and destructor | |
| 286 | recursive_directory_iterator() noexcept; | |
| 287 | explicit recursive_directory_iterator(const path& p); | |
| 288 | recursive_directory_iterator(const path& p, directory_options options); | |
| 289 | recursive_directory_iterator(const path& p, directory_options options, | |
| 290 | error_code& ec); | |
| 291 | recursive_directory_iterator(const path& p, error_code& ec); | |
| 292 | recursive_directory_iterator(const recursive_directory_iterator& rhs); | |
| 293 | recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; | |
| 294 | ~recursive_directory_iterator(); | |
| 295 | ||
| 296 | // [fs.rec.dir.itr.members], observers | |
| 297 | directory_options options() const; | |
| 298 | int depth() const; | |
| 299 | bool recursion_pending() const; | |
| 300 | ||
| 301 | const directory_entry& operator*() const; | |
| 302 | const directory_entry* operator->() const; | |
| 303 | ||
| 304 | // [fs.rec.dir.itr.members], modifiers | |
| 305 | recursive_directory_iterator& | |
| 306 | operator=(const recursive_directory_iterator& rhs); | |
| 307 | recursive_directory_iterator& | |
| 308 | operator=(recursive_directory_iterator&& rhs) noexcept; | |
| 309 | ||
| 310 | recursive_directory_iterator& operator++(); | |
| 311 | recursive_directory_iterator& increment(error_code& ec); | |
| 312 | ||
| 313 | void pop(); | |
| 314 | void pop(error_code& ec); | |
| 315 | void disable_recursion_pending(); | |
| 316 | ||
| 317 | bool operator==(default_sentinel_t) const noexcept { // since C++20 | |
| 318 | return *this == recursive_directory_iterator(); | |
| 319 | } | |
| 320 | ||
| 321 | // other members as required by [input.iterators], input iterators | |
| 322 | }; | |
| 243 | 323 | |
| 244 | 324 | // enable recursive_directory_iterator range-based for statements |
| 245 | 325 | recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; |
| 246 | 326 | recursive_directory_iterator end(recursive_directory_iterator) noexcept; |
| 247 | 327 | |
| 248 | class file_status; | |
| 328 | class file_status { | |
| 329 | public: | |
| 330 | // [fs.file.status.cons], constructors and destructor | |
| 331 | file_status() noexcept : file_status(file_type::none) {} | |
| 332 | explicit file_status(file_type ft, | |
| 333 | perms prms = perms::unknown) noexcept; | |
| 334 | file_status(const file_status&) noexcept = default; | |
| 335 | file_status(file_status&&) noexcept = default; | |
| 336 | ~file_status(); | |
| 337 | ||
| 338 | // assignments | |
| 339 | file_status& operator=(const file_status&) noexcept = default; | |
| 340 | file_status& operator=(file_status&&) noexcept = default; | |
| 341 | ||
| 342 | // [fs.file.status.mods], modifiers | |
| 343 | void type(file_type ft) noexcept; | |
| 344 | void permissions(perms prms) noexcept; | |
| 345 | ||
| 346 | // [fs.file.status.obs], observers | |
| 347 | file_type type() const noexcept; | |
| 348 | perms permissions() const noexcept; | |
| 349 | ||
| 350 | friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept | |
| 351 | { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } // C++20 | |
| 352 | }; | |
| 249 | 353 | |
| 250 | 354 | struct space_info |
| 251 | 355 | { |
| ... | ... | @@ -454,16 +558,14 @@ inline constexpr bool std::ranges::enable_view<std::filesystem::recursive_direct |
| 454 | 558 | // [fs.filesystem.syn] |
| 455 | 559 | #include <compare> |
| 456 | 560 | |
| 457 | #if defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 458 | # error "The <filesystem> library is not supported since libc++ has been configured without support for a filesystem." | |
| 459 | #endif | |
| 460 | ||
| 461 | 561 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 462 | 562 | # pragma GCC system_header |
| 463 | 563 | #endif |
| 464 | 564 | |
| 465 | 565 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 466 | 566 | # include <concepts> |
| 567 | # include <cstdlib> | |
| 568 | # include <system_error> | |
| 467 | 569 | #endif |
| 468 | 570 | |
| 469 | 571 | #endif // _LIBCPP_FILESYSTEM |
lib/libcxx/include/format+1-7| ... | ... | @@ -170,11 +170,6 @@ namespace std { |
| 170 | 170 | */ |
| 171 | 171 | |
| 172 | 172 | #include <__assert> // all public C++ headers provide the assertion handler |
| 173 | // Make sure all feature-test macros are available. | |
| 174 | #include <version> | |
| 175 | // Enable the contents of the header only when libc++ was built with experimental features enabled. | |
| 176 | #if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 177 | ||
| 178 | 173 | #include <__config> |
| 179 | 174 | #include <__format/buffer.h> |
| 180 | 175 | #include <__format/concepts.h> |
| ... | ... | @@ -202,11 +197,10 @@ namespace std { |
| 202 | 197 | #include <__format/range_default_formatter.h> |
| 203 | 198 | #include <__format/range_formatter.h> |
| 204 | 199 | #include <__format/unicode.h> |
| 200 | #include <version> | |
| 205 | 201 | |
| 206 | 202 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 207 | 203 | # pragma GCC system_header |
| 208 | 204 | #endif |
| 209 | 205 | |
| 210 | #endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 211 | ||
| 212 | 206 | #endif // _LIBCPP_FORMAT |
lib/libcxx/include/forward_list+243-104| ... | ... | @@ -44,6 +44,8 @@ public: |
| 44 | 44 | forward_list(InputIterator first, InputIterator last); |
| 45 | 45 | template <class InputIterator> |
| 46 | 46 | forward_list(InputIterator first, InputIterator last, const allocator_type& a); |
| 47 | template<container-compatible-range<T> R> | |
| 48 | forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 | |
| 47 | 49 | forward_list(const forward_list& x); |
| 48 | 50 | forward_list(const forward_list& x, const allocator_type& a); |
| 49 | 51 | forward_list(forward_list&& x) |
| ... | ... | @@ -63,6 +65,8 @@ public: |
| 63 | 65 | |
| 64 | 66 | template <class InputIterator> |
| 65 | 67 | void assign(InputIterator first, InputIterator last); |
| 68 | template<container-compatible-range<T> R> | |
| 69 | void assign_range(R&& rg); // C++23 | |
| 66 | 70 | void assign(size_type n, const value_type& v); |
| 67 | 71 | void assign(initializer_list<value_type> il); |
| 68 | 72 | |
| ... | ... | @@ -89,6 +93,8 @@ public: |
| 89 | 93 | template <class... Args> reference emplace_front(Args&&... args); // reference in C++17 |
| 90 | 94 | void push_front(const value_type& v); |
| 91 | 95 | void push_front(value_type&& v); |
| 96 | template<container-compatible-range<T> R> | |
| 97 | void prepend_range(R&& rg); // C++23 | |
| 92 | 98 | |
| 93 | 99 | void pop_front(); |
| 94 | 100 | |
| ... | ... | @@ -100,6 +106,8 @@ public: |
| 100 | 106 | template <class InputIterator> |
| 101 | 107 | iterator insert_after(const_iterator p, |
| 102 | 108 | InputIterator first, InputIterator last); |
| 109 | template<container-compatible-range<T> R> | |
| 110 | iterator insert_range_after(const_iterator position, R&& rg); // C++23 | |
| 103 | 111 | iterator insert_after(const_iterator p, initializer_list<value_type> il); |
| 104 | 112 | |
| 105 | 113 | iterator erase_after(const_iterator p); |
| ... | ... | @@ -140,29 +148,37 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra |
| 140 | 148 | forward_list(InputIterator, InputIterator, Allocator = Allocator()) |
| 141 | 149 | -> forward_list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 |
| 142 | 150 | |
| 151 | template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> | |
| 152 | forward_list(from_range_t, R&&, Allocator = Allocator()) | |
| 153 | -> forward_list<ranges::range_value_t<R>, Allocator>; // C++23 | |
| 154 | ||
| 143 | 155 | template <class T, class Allocator> |
| 144 | 156 | bool operator==(const forward_list<T, Allocator>& x, |
| 145 | 157 | const forward_list<T, Allocator>& y); |
| 146 | 158 | |
| 147 | 159 | template <class T, class Allocator> |
| 148 | 160 | bool operator< (const forward_list<T, Allocator>& x, |
| 149 | const forward_list<T, Allocator>& y); | |
| 161 | const forward_list<T, Allocator>& y); // removed in C++20 | |
| 150 | 162 | |
| 151 | 163 | template <class T, class Allocator> |
| 152 | 164 | bool operator!=(const forward_list<T, Allocator>& x, |
| 153 | const forward_list<T, Allocator>& y); | |
| 165 | const forward_list<T, Allocator>& y); // removed in C++20 | |
| 154 | 166 | |
| 155 | 167 | template <class T, class Allocator> |
| 156 | 168 | bool operator> (const forward_list<T, Allocator>& x, |
| 157 | const forward_list<T, Allocator>& y); | |
| 169 | const forward_list<T, Allocator>& y); // removed in C++20 | |
| 158 | 170 | |
| 159 | 171 | template <class T, class Allocator> |
| 160 | 172 | bool operator>=(const forward_list<T, Allocator>& x, |
| 161 | const forward_list<T, Allocator>& y); | |
| 173 | const forward_list<T, Allocator>& y); // removed in C++20 | |
| 162 | 174 | |
| 163 | 175 | template <class T, class Allocator> |
| 164 | 176 | bool operator<=(const forward_list<T, Allocator>& x, |
| 165 | const forward_list<T, Allocator>& y); | |
| 177 | const forward_list<T, Allocator>& y); // removed in C++20 | |
| 178 | ||
| 179 | template<class T, class Allocator> | |
| 180 | synth-three-way-result<T> operator<=>(const forward_list<T, Allocator>& x, | |
| 181 | const forward_list<T, Allocator>& y); // since C++20 | |
| 166 | 182 | |
| 167 | 183 | template <class T, class Allocator> |
| 168 | 184 | void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) |
| ... | ... | @@ -181,14 +197,17 @@ template <class T, class Allocator, class Predicate> |
| 181 | 197 | |
| 182 | 198 | #include <__algorithm/comp.h> |
| 183 | 199 | #include <__algorithm/lexicographical_compare.h> |
| 200 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 184 | 201 | #include <__algorithm/min.h> |
| 185 | 202 | #include <__assert> // all public C++ headers provide the assertion handler |
| 203 | #include <__availability> | |
| 186 | 204 | #include <__config> |
| 187 | 205 | #include <__iterator/distance.h> |
| 188 | 206 | #include <__iterator/iterator_traits.h> |
| 189 | 207 | #include <__iterator/move_iterator.h> |
| 190 | 208 | #include <__iterator/next.h> |
| 191 | 209 | #include <__memory/addressof.h> |
| 210 | #include <__memory/allocation_guard.h> | |
| 192 | 211 | #include <__memory/allocator.h> |
| 193 | 212 | #include <__memory/allocator_destructor.h> |
| 194 | 213 | #include <__memory/allocator_traits.h> |
| ... | ... | @@ -197,11 +216,22 @@ template <class T, class Allocator, class Predicate> |
| 197 | 216 | #include <__memory/swap_allocator.h> |
| 198 | 217 | #include <__memory/unique_ptr.h> |
| 199 | 218 | #include <__memory_resource/polymorphic_allocator.h> |
| 219 | #include <__ranges/access.h> | |
| 220 | #include <__ranges/concepts.h> | |
| 221 | #include <__ranges/container_compatible_range.h> | |
| 222 | #include <__ranges/from_range.h> | |
| 223 | #include <__type_traits/conditional.h> | |
| 200 | 224 | #include <__type_traits/is_allocator.h> |
| 225 | #include <__type_traits/is_const.h> | |
| 226 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 227 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 228 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 229 | #include <__type_traits/is_pointer.h> | |
| 230 | #include <__type_traits/is_same.h> | |
| 231 | #include <__type_traits/type_identity.h> | |
| 201 | 232 | #include <__utility/forward.h> |
| 202 | 233 | #include <__utility/move.h> |
| 203 | 234 | #include <limits> |
| 204 | #include <type_traits> | |
| 205 | 235 | #include <version> |
| 206 | 236 | |
| 207 | 237 | // standard-mandated includes |
| ... | ... | @@ -279,6 +309,7 @@ struct __forward_begin_node |
| 279 | 309 | pointer __next_; |
| 280 | 310 | |
| 281 | 311 | _LIBCPP_INLINE_VISIBILITY __forward_begin_node() : __next_(nullptr) {} |
| 312 | _LIBCPP_INLINE_VISIBILITY explicit __forward_begin_node(pointer __n) : __next_(__n) {} | |
| 282 | 313 | |
| 283 | 314 | _LIBCPP_INLINE_VISIBILITY |
| 284 | 315 | __begin_node_pointer __next_as_begin() const { |
| ... | ... | @@ -294,8 +325,13 @@ struct _LIBCPP_STANDALONE_DEBUG __forward_list_node |
| 294 | 325 | : public __begin_node_of<_Tp, _VoidPtr> |
| 295 | 326 | { |
| 296 | 327 | typedef _Tp value_type; |
| 328 | typedef __begin_node_of<_Tp, _VoidPtr> _Base; | |
| 329 | typedef typename _Base::pointer _NodePtr; | |
| 297 | 330 | |
| 298 | 331 | value_type __value_; |
| 332 | ||
| 333 | _LIBCPP_HIDE_FROM_ABI __forward_list_node() = default; | |
| 334 | _LIBCPP_HIDE_FROM_ABI __forward_list_node(const value_type& __v, _NodePtr __next) : _Base(__next), __value_(__v) {} | |
| 299 | 335 | }; |
| 300 | 336 | |
| 301 | 337 | |
| ... | ... | @@ -395,11 +431,11 @@ class _LIBCPP_TEMPLATE_VIS __forward_list_const_iterator |
| 395 | 431 | |
| 396 | 432 | __iter_node_pointer __ptr_; |
| 397 | 433 | |
| 398 | __begin_node_pointer __get_begin() const { | |
| 434 | _LIBCPP_HIDE_FROM_ABI __begin_node_pointer __get_begin() const { | |
| 399 | 435 | return static_cast<__begin_node_pointer>( |
| 400 | 436 | static_cast<__void_pointer>(__ptr_)); |
| 401 | 437 | } |
| 402 | __node_pointer __get_unsafe_node_pointer() const { | |
| 438 | _LIBCPP_HIDE_FROM_ABI __node_pointer __get_unsafe_node_pointer() const { | |
| 403 | 439 | return static_cast<__node_pointer>( |
| 404 | 440 | static_cast<__void_pointer>(__ptr_)); |
| 405 | 441 | } |
| ... | ... | @@ -482,14 +518,6 @@ protected: |
| 482 | 518 | typedef typename allocator_traits<__begin_node_allocator>::pointer |
| 483 | 519 | __begin_node_pointer; |
| 484 | 520 | |
| 485 | static_assert((!is_same<allocator_type, __node_allocator>::value), | |
| 486 | "internal allocator type must differ from user-specified " | |
| 487 | "type; otherwise overload resolution breaks"); | |
| 488 | ||
| 489 | static_assert(is_same<allocator_type, __rebind_alloc<__node_traits, value_type> >::value, | |
| 490 | "[allocator.requirements] states that rebinding an allocator to the same type should result in the " | |
| 491 | "original allocator"); | |
| 492 | ||
| 493 | 521 | __compressed_pair<__begin_node, __node_allocator> __before_begin_; |
| 494 | 522 | |
| 495 | 523 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -533,7 +561,7 @@ private: |
| 533 | 561 | __forward_list_base& operator=(const __forward_list_base&); |
| 534 | 562 | |
| 535 | 563 | public: |
| 536 | ~__forward_list_base(); | |
| 564 | _LIBCPP_HIDE_FROM_ABI ~__forward_list_base(); | |
| 537 | 565 | |
| 538 | 566 | protected: |
| 539 | 567 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -558,7 +586,7 @@ public: |
| 558 | 586 | __is_nothrow_swappable<__node_allocator>::value); |
| 559 | 587 | #endif |
| 560 | 588 | protected: |
| 561 | void clear() _NOEXCEPT; | |
| 589 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; | |
| 562 | 590 | |
| 563 | 591 | private: |
| 564 | 592 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -659,9 +687,17 @@ public: |
| 659 | 687 | typedef _Tp value_type; |
| 660 | 688 | typedef _Alloc allocator_type; |
| 661 | 689 | |
| 662 | static_assert((is_same<typename allocator_type::value_type, value_type>::value), | |
| 690 | static_assert(is_same<value_type, typename allocator_type::value_type>::value, | |
| 663 | 691 | "Allocator::value_type must be same type as value_type"); |
| 664 | 692 | |
| 693 | static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value, | |
| 694 | "[allocator.requirements] states that rebinding an allocator to the same type should result in the " | |
| 695 | "original allocator"); | |
| 696 | ||
| 697 | static_assert((!is_same<allocator_type, __node_allocator>::value), | |
| 698 | "internal allocator type must differ from user-specified " | |
| 699 | "type; otherwise overload resolution breaks"); | |
| 700 | ||
| 665 | 701 | typedef value_type& reference; |
| 666 | 702 | typedef const value_type& const_reference; |
| 667 | 703 | typedef typename allocator_traits<allocator_type>::pointer pointer; |
| ... | ... | @@ -671,7 +707,7 @@ public: |
| 671 | 707 | |
| 672 | 708 | typedef typename base::iterator iterator; |
| 673 | 709 | typedef typename base::const_iterator const_iterator; |
| 674 | #if _LIBCPP_STD_VER > 17 | |
| 710 | #if _LIBCPP_STD_VER >= 20 | |
| 675 | 711 | typedef size_type __remove_return_type; |
| 676 | 712 | #else |
| 677 | 713 | typedef void __remove_return_type; |
| ... | ... | @@ -683,39 +719,48 @@ public: |
| 683 | 719 | {} // = default; |
| 684 | 720 | _LIBCPP_INLINE_VISIBILITY |
| 685 | 721 | explicit forward_list(const allocator_type& __a); |
| 686 | explicit forward_list(size_type __n); | |
| 687 | #if _LIBCPP_STD_VER > 11 | |
| 688 | explicit forward_list(size_type __n, const allocator_type& __a); | |
| 722 | _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n); | |
| 723 | #if _LIBCPP_STD_VER >= 14 | |
| 724 | _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a); | |
| 689 | 725 | #endif |
| 690 | forward_list(size_type __n, const value_type& __v); | |
| 726 | _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v); | |
| 691 | 727 | |
| 692 | 728 | template <class = __enable_if_t<__is_allocator<_Alloc>::value> > |
| 693 | forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) | |
| 729 | _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a) | |
| 694 | 730 | { |
| 695 | 731 | insert_after(cbefore_begin(), __n, __v); |
| 696 | 732 | } |
| 697 | 733 | |
| 698 | 734 | template <class _InputIterator> |
| 699 | forward_list(_InputIterator __f, _InputIterator __l, | |
| 700 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr); | |
| 735 | _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, | |
| 736 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr); | |
| 701 | 737 | template <class _InputIterator> |
| 702 | forward_list(_InputIterator __f, _InputIterator __l, | |
| 738 | _LIBCPP_HIDE_FROM_ABI forward_list(_InputIterator __f, _InputIterator __l, | |
| 703 | 739 | const allocator_type& __a, |
| 704 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>* = nullptr); | |
| 705 | forward_list(const forward_list& __x); | |
| 706 | forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a); | |
| 740 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value>* = nullptr); | |
| 707 | 741 | |
| 708 | forward_list& operator=(const forward_list& __x); | |
| 742 | #if _LIBCPP_STD_VER >= 23 | |
| 743 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 744 | _LIBCPP_HIDE_FROM_ABI forward_list(from_range_t, _Range&& __range, | |
| 745 | const allocator_type& __a = allocator_type()) : base(__a) { | |
| 746 | prepend_range(std::forward<_Range>(__range)); | |
| 747 | } | |
| 748 | #endif | |
| 749 | ||
| 750 | _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x); | |
| 751 | _LIBCPP_HIDE_FROM_ABI forward_list(const forward_list& __x, const __type_identity_t<allocator_type>& __a); | |
| 752 | ||
| 753 | _LIBCPP_HIDE_FROM_ABI forward_list& operator=(const forward_list& __x); | |
| 709 | 754 | |
| 710 | 755 | #ifndef _LIBCPP_CXX03_LANG |
| 711 | 756 | _LIBCPP_INLINE_VISIBILITY |
| 712 | 757 | forward_list(forward_list&& __x) |
| 713 | 758 | _NOEXCEPT_(is_nothrow_move_constructible<base>::value) |
| 714 | 759 | : base(_VSTD::move(__x)) {} |
| 715 | forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a); | |
| 760 | _LIBCPP_HIDE_FROM_ABI forward_list(forward_list&& __x, const __type_identity_t<allocator_type>& __a); | |
| 716 | 761 | |
| 717 | forward_list(initializer_list<value_type> __il); | |
| 718 | forward_list(initializer_list<value_type> __il, const allocator_type& __a); | |
| 762 | _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il); | |
| 763 | _LIBCPP_HIDE_FROM_ABI forward_list(initializer_list<value_type> __il, const allocator_type& __a); | |
| 719 | 764 | |
| 720 | 765 | _LIBCPP_INLINE_VISIBILITY |
| 721 | 766 | forward_list& operator=(forward_list&& __x) |
| ... | ... | @@ -733,9 +778,18 @@ public: |
| 733 | 778 | // ~forward_list() = default; |
| 734 | 779 | |
| 735 | 780 | template <class _InputIterator> |
| 736 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void> | |
| 737 | assign(_InputIterator __f, _InputIterator __l); | |
| 738 | void assign(size_type __n, const value_type& __v); | |
| 781 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value, void> | |
| 782 | _LIBCPP_HIDE_FROM_ABI assign(_InputIterator __f, _InputIterator __l); | |
| 783 | ||
| 784 | #if _LIBCPP_STD_VER >= 23 | |
| 785 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 786 | _LIBCPP_HIDE_FROM_ABI | |
| 787 | void assign_range(_Range&& __range) { | |
| 788 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 789 | } | |
| 790 | #endif | |
| 791 | ||
| 792 | _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __v); | |
| 739 | 793 | |
| 740 | 794 | _LIBCPP_INLINE_VISIBILITY |
| 741 | 795 | allocator_type get_allocator() const _NOEXCEPT |
| ... | ... | @@ -787,34 +841,56 @@ public: |
| 787 | 841 | const_reference front() const {return base::__before_begin()->__next_->__value_;} |
| 788 | 842 | |
| 789 | 843 | #ifndef _LIBCPP_CXX03_LANG |
| 790 | #if _LIBCPP_STD_VER > 14 | |
| 791 | template <class... _Args> reference emplace_front(_Args&&... __args); | |
| 844 | #if _LIBCPP_STD_VER >= 17 | |
| 845 | template <class... _Args> | |
| 846 | _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); | |
| 792 | 847 | #else |
| 793 | template <class... _Args> void emplace_front(_Args&&... __args); | |
| 848 | template <class... _Args> | |
| 849 | _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); | |
| 794 | 850 | #endif |
| 795 | void push_front(value_type&& __v); | |
| 851 | _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __v); | |
| 796 | 852 | #endif // _LIBCPP_CXX03_LANG |
| 797 | void push_front(const value_type& __v); | |
| 853 | _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __v); | |
| 798 | 854 | |
| 799 | void pop_front(); | |
| 855 | #if _LIBCPP_STD_VER >= 23 | |
| 856 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 857 | _LIBCPP_HIDE_FROM_ABI | |
| 858 | void prepend_range(_Range&& __range) { | |
| 859 | insert_range_after(cbefore_begin(), std::forward<_Range>(__range)); | |
| 860 | } | |
| 861 | #endif | |
| 862 | ||
| 863 | _LIBCPP_HIDE_FROM_ABI void pop_front(); | |
| 800 | 864 | |
| 801 | 865 | #ifndef _LIBCPP_CXX03_LANG |
| 802 | 866 | template <class... _Args> |
| 803 | iterator emplace_after(const_iterator __p, _Args&&... __args); | |
| 867 | _LIBCPP_HIDE_FROM_ABI iterator emplace_after(const_iterator __p, _Args&&... __args); | |
| 804 | 868 | |
| 805 | iterator insert_after(const_iterator __p, value_type&& __v); | |
| 806 | iterator insert_after(const_iterator __p, initializer_list<value_type> __il) | |
| 869 | _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, value_type&& __v); | |
| 870 | _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, initializer_list<value_type> __il) | |
| 807 | 871 | {return insert_after(__p, __il.begin(), __il.end());} |
| 808 | 872 | #endif // _LIBCPP_CXX03_LANG |
| 809 | iterator insert_after(const_iterator __p, const value_type& __v); | |
| 810 | iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); | |
| 873 | _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, const value_type& __v); | |
| 874 | _LIBCPP_HIDE_FROM_ABI iterator insert_after(const_iterator __p, size_type __n, const value_type& __v); | |
| 811 | 875 | template <class _InputIterator> |
| 812 | 876 | _LIBCPP_INLINE_VISIBILITY |
| 813 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, iterator> | |
| 877 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value, iterator> | |
| 814 | 878 | insert_after(const_iterator __p, _InputIterator __f, _InputIterator __l); |
| 815 | 879 | |
| 816 | iterator erase_after(const_iterator __p); | |
| 817 | iterator erase_after(const_iterator __f, const_iterator __l); | |
| 880 | #if _LIBCPP_STD_VER >= 23 | |
| 881 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 882 | _LIBCPP_HIDE_FROM_ABI | |
| 883 | iterator insert_range_after(const_iterator __position, _Range&& __range) { | |
| 884 | return __insert_after_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); | |
| 885 | } | |
| 886 | #endif | |
| 887 | ||
| 888 | template <class _InputIterator, class _Sentinel> | |
| 889 | _LIBCPP_HIDE_FROM_ABI | |
| 890 | iterator __insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l); | |
| 891 | ||
| 892 | _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __p); | |
| 893 | _LIBCPP_HIDE_FROM_ABI iterator erase_after(const_iterator __f, const_iterator __l); | |
| 818 | 894 | |
| 819 | 895 | _LIBCPP_INLINE_VISIBILITY |
| 820 | 896 | void swap(forward_list& __x) |
| ... | ... | @@ -826,8 +902,8 @@ public: |
| 826 | 902 | #endif |
| 827 | 903 | {base::swap(__x);} |
| 828 | 904 | |
| 829 | void resize(size_type __n); | |
| 830 | void resize(size_type __n, const value_type& __v); | |
| 905 | _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); | |
| 906 | _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __v); | |
| 831 | 907 | _LIBCPP_INLINE_VISIBILITY |
| 832 | 908 | void clear() _NOEXCEPT {base::clear();} |
| 833 | 909 | |
| ... | ... | @@ -838,46 +914,54 @@ public: |
| 838 | 914 | _LIBCPP_INLINE_VISIBILITY |
| 839 | 915 | void splice_after(const_iterator __p, forward_list&& __x, |
| 840 | 916 | const_iterator __f, const_iterator __l); |
| 841 | void splice_after(const_iterator __p, forward_list& __x); | |
| 842 | void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); | |
| 843 | void splice_after(const_iterator __p, forward_list& __x, | |
| 917 | _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x); | |
| 918 | _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, const_iterator __i); | |
| 919 | _LIBCPP_HIDE_FROM_ABI void splice_after(const_iterator __p, forward_list& __x, | |
| 844 | 920 | const_iterator __f, const_iterator __l); |
| 845 | __remove_return_type remove(const value_type& __v); | |
| 846 | template <class _Predicate> __remove_return_type remove_if(_Predicate __pred); | |
| 921 | _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __v); | |
| 922 | template <class _Predicate> | |
| 923 | _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Predicate __pred); | |
| 847 | 924 | _LIBCPP_INLINE_VISIBILITY |
| 848 | 925 | __remove_return_type unique() { return unique(__equal_to()); } |
| 849 | template <class _BinaryPredicate> __remove_return_type unique(_BinaryPredicate __binary_pred); | |
| 926 | template <class _BinaryPredicate> | |
| 927 | _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPredicate __binary_pred); | |
| 850 | 928 | #ifndef _LIBCPP_CXX03_LANG |
| 851 | 929 | _LIBCPP_INLINE_VISIBILITY |
| 852 | void merge(forward_list&& __x) {merge(__x, __less<value_type>());} | |
| 930 | void merge(forward_list&& __x) {merge(__x, __less<>());} | |
| 853 | 931 | template <class _Compare> |
| 854 | 932 | _LIBCPP_INLINE_VISIBILITY |
| 855 | 933 | void merge(forward_list&& __x, _Compare __comp) |
| 856 | 934 | {merge(__x, _VSTD::move(__comp));} |
| 857 | 935 | #endif // _LIBCPP_CXX03_LANG |
| 858 | 936 | _LIBCPP_INLINE_VISIBILITY |
| 859 | void merge(forward_list& __x) {merge(__x, __less<value_type>());} | |
| 860 | template <class _Compare> void merge(forward_list& __x, _Compare __comp); | |
| 937 | void merge(forward_list& __x) {merge(__x, __less<>());} | |
| 938 | template <class _Compare> | |
| 939 | _LIBCPP_HIDE_FROM_ABI void merge(forward_list& __x, _Compare __comp); | |
| 861 | 940 | _LIBCPP_INLINE_VISIBILITY |
| 862 | void sort() {sort(__less<value_type>());} | |
| 941 | void sort() {sort(__less<>());} | |
| 863 | 942 | template <class _Compare> _LIBCPP_INLINE_VISIBILITY void sort(_Compare __comp); |
| 864 | void reverse() _NOEXCEPT; | |
| 943 | _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; | |
| 865 | 944 | |
| 866 | 945 | private: |
| 867 | 946 | |
| 868 | 947 | #ifndef _LIBCPP_CXX03_LANG |
| 869 | void __move_assign(forward_list& __x, true_type) | |
| 948 | _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, true_type) | |
| 870 | 949 | _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); |
| 871 | void __move_assign(forward_list& __x, false_type); | |
| 950 | _LIBCPP_HIDE_FROM_ABI void __move_assign(forward_list& __x, false_type); | |
| 872 | 951 | #endif // _LIBCPP_CXX03_LANG |
| 873 | 952 | |
| 953 | template <class _Iter, class _Sent> | |
| 954 | _LIBCPP_HIDE_FROM_ABI | |
| 955 | void __assign_with_sentinel(_Iter __f, _Sent __l); | |
| 956 | ||
| 874 | 957 | template <class _Compare> |
| 875 | static | |
| 958 | static _LIBCPP_HIDE_FROM_ABI | |
| 876 | 959 | __node_pointer |
| 877 | 960 | __merge(__node_pointer __f1, __node_pointer __f2, _Compare& __comp); |
| 878 | 961 | |
| 962 | // TODO: Make this _LIBCPP_HIDE_FROM_ABI | |
| 879 | 963 | template <class _Compare> |
| 880 | static | |
| 964 | static _LIBCPP_HIDDEN | |
| 881 | 965 | __node_pointer |
| 882 | 966 | __sort(__node_pointer __f, difference_type __sz, _Compare& __comp); |
| 883 | 967 | }; |
| ... | ... | @@ -886,7 +970,7 @@ private: |
| 886 | 970 | #if _LIBCPP_STD_VER >= 17 |
| 887 | 971 | template<class _InputIterator, |
| 888 | 972 | class _Alloc = allocator<__iter_value_type<_InputIterator>>, |
| 889 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 973 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 890 | 974 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 891 | 975 | > |
| 892 | 976 | forward_list(_InputIterator, _InputIterator) |
| ... | ... | @@ -894,13 +978,22 @@ forward_list(_InputIterator, _InputIterator) |
| 894 | 978 | |
| 895 | 979 | template<class _InputIterator, |
| 896 | 980 | class _Alloc, |
| 897 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 981 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 898 | 982 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 899 | 983 | > |
| 900 | 984 | forward_list(_InputIterator, _InputIterator, _Alloc) |
| 901 | 985 | -> forward_list<__iter_value_type<_InputIterator>, _Alloc>; |
| 902 | 986 | #endif |
| 903 | 987 | |
| 988 | #if _LIBCPP_STD_VER >= 23 | |
| 989 | template <ranges::input_range _Range, | |
| 990 | class _Alloc = allocator<ranges::range_value_t<_Range>>, | |
| 991 | class = enable_if_t<__is_allocator<_Alloc>::value> | |
| 992 | > | |
| 993 | forward_list(from_range_t, _Range&&, _Alloc = _Alloc()) | |
| 994 | -> forward_list<ranges::range_value_t<_Range>, _Alloc>; | |
| 995 | #endif | |
| 996 | ||
| 904 | 997 | template <class _Tp, class _Alloc> |
| 905 | 998 | inline |
| 906 | 999 | forward_list<_Tp, _Alloc>::forward_list(const allocator_type& __a) |
| ... | ... | @@ -927,7 +1020,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n) |
| 927 | 1020 | } |
| 928 | 1021 | } |
| 929 | 1022 | |
| 930 | #if _LIBCPP_STD_VER > 11 | |
| 1023 | #if _LIBCPP_STD_VER >= 14 | |
| 931 | 1024 | template <class _Tp, class _Alloc> |
| 932 | 1025 | forward_list<_Tp, _Alloc>::forward_list(size_type __n, |
| 933 | 1026 | const allocator_type& __base_alloc) |
| ... | ... | @@ -959,7 +1052,7 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) |
| 959 | 1052 | template <class _Tp, class _Alloc> |
| 960 | 1053 | template <class _InputIterator> |
| 961 | 1054 | forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, |
| 962 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*) | |
| 1055 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*) | |
| 963 | 1056 | { |
| 964 | 1057 | insert_after(cbefore_begin(), __f, __l); |
| 965 | 1058 | } |
| ... | ... | @@ -968,7 +1061,7 @@ template <class _Tp, class _Alloc> |
| 968 | 1061 | template <class _InputIterator> |
| 969 | 1062 | forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l, |
| 970 | 1063 | const allocator_type& __a, |
| 971 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>*) | |
| 1064 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value>*) | |
| 972 | 1065 | : base(__a) |
| 973 | 1066 | { |
| 974 | 1067 | insert_after(cbefore_begin(), __f, __l); |
| ... | ... | @@ -1078,16 +1171,23 @@ forward_list<_Tp, _Alloc>::operator=(initializer_list<value_type> __il) |
| 1078 | 1171 | |
| 1079 | 1172 | template <class _Tp, class _Alloc> |
| 1080 | 1173 | template <class _InputIterator> |
| 1081 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void> | |
| 1174 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value, void> | |
| 1082 | 1175 | forward_list<_Tp, _Alloc>::assign(_InputIterator __f, _InputIterator __l) |
| 1083 | 1176 | { |
| 1177 | __assign_with_sentinel(__f, __l); | |
| 1178 | } | |
| 1179 | ||
| 1180 | template <class _Tp, class _Alloc> | |
| 1181 | template <class _Iter, class _Sent> | |
| 1182 | _LIBCPP_HIDE_FROM_ABI | |
| 1183 | void forward_list<_Tp, _Alloc>::__assign_with_sentinel(_Iter __f, _Sent __l) { | |
| 1084 | 1184 | iterator __i = before_begin(); |
| 1085 | 1185 | iterator __j = _VSTD::next(__i); |
| 1086 | 1186 | iterator __e = end(); |
| 1087 | 1187 | for (; __j != __e && __f != __l; ++__i, (void) ++__j, ++__f) |
| 1088 | 1188 | *__j = *__f; |
| 1089 | 1189 | if (__j == __e) |
| 1090 | insert_after(__i, __f, __l); | |
| 1190 | __insert_after_with_sentinel(__i, std::move(__f), std::move(__l)); | |
| 1091 | 1191 | else |
| 1092 | 1192 | erase_after(__i, __e); |
| 1093 | 1193 | } |
| ... | ... | @@ -1119,7 +1219,7 @@ forward_list<_Tp, _Alloc>::assign(initializer_list<value_type> __il) |
| 1119 | 1219 | |
| 1120 | 1220 | template <class _Tp, class _Alloc> |
| 1121 | 1221 | template <class... _Args> |
| 1122 | #if _LIBCPP_STD_VER > 14 | |
| 1222 | #if _LIBCPP_STD_VER >= 17 | |
| 1123 | 1223 | typename forward_list<_Tp, _Alloc>::reference |
| 1124 | 1224 | #else |
| 1125 | 1225 | void |
| ... | ... | @@ -1133,7 +1233,7 @@ forward_list<_Tp, _Alloc>::emplace_front(_Args&&... __args) |
| 1133 | 1233 | _VSTD::forward<_Args>(__args)...); |
| 1134 | 1234 | __h->__next_ = base::__before_begin()->__next_; |
| 1135 | 1235 | base::__before_begin()->__next_ = __h.release(); |
| 1136 | #if _LIBCPP_STD_VER > 14 | |
| 1236 | #if _LIBCPP_STD_VER >= 17 | |
| 1137 | 1237 | return base::__before_begin()->__next_->__value_; |
| 1138 | 1238 | #endif |
| 1139 | 1239 | } |
| ... | ... | @@ -1228,26 +1328,33 @@ typename forward_list<_Tp, _Alloc>::iterator |
| 1228 | 1328 | forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, |
| 1229 | 1329 | const value_type& __v) |
| 1230 | 1330 | { |
| 1331 | using _Guard = __allocation_guard<__node_allocator>; | |
| 1332 | ||
| 1231 | 1333 | __begin_node_pointer __r = __p.__get_begin(); |
| 1232 | 1334 | if (__n > 0) |
| 1233 | 1335 | { |
| 1234 | 1336 | __node_allocator& __a = base::__alloc(); |
| 1235 | typedef __allocator_destructor<__node_allocator> _Dp; | |
| 1236 | unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); | |
| 1237 | __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); | |
| 1238 | __node_pointer __first = __h.release(); | |
| 1337 | ||
| 1338 | __node_pointer __first = nullptr; | |
| 1339 | { | |
| 1340 | _Guard __h(__a, 1); | |
| 1341 | __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); | |
| 1342 | __h.__get()->__next_ = nullptr; | |
| 1343 | __first = __h.__release_ptr(); | |
| 1344 | } | |
| 1239 | 1345 | __node_pointer __last = __first; |
| 1240 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1346 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1241 | 1347 | try |
| 1242 | 1348 | { |
| 1243 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1349 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1244 | 1350 | for (--__n; __n != 0; --__n, __last = __last->__next_) |
| 1245 | 1351 | { |
| 1246 | __h.reset(__node_traits::allocate(__a, 1)); | |
| 1247 | __node_traits::construct(__a, _VSTD::addressof(__h->__value_), __v); | |
| 1248 | __last->__next_ = __h.release(); | |
| 1352 | _Guard __h(__a, 1); | |
| 1353 | __node_traits::construct(__a, std::addressof(__h.__get()->__value_), __v); | |
| 1354 | __h.__get()->__next_ = nullptr; | |
| 1355 | __last->__next_ = __h.__release_ptr(); | |
| 1249 | 1356 | } |
| 1250 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1357 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1251 | 1358 | } |
| 1252 | 1359 | catch (...) |
| 1253 | 1360 | { |
| ... | ... | @@ -1260,7 +1367,7 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, |
| 1260 | 1367 | } |
| 1261 | 1368 | throw; |
| 1262 | 1369 | } |
| 1263 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1370 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1264 | 1371 | __last->__next_ = __r->__next_; |
| 1265 | 1372 | __r->__next_ = __first; |
| 1266 | 1373 | __r = static_cast<__begin_node_pointer>(__last); |
| ... | ... | @@ -1270,30 +1377,45 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, size_type __n, |
| 1270 | 1377 | |
| 1271 | 1378 | template <class _Tp, class _Alloc> |
| 1272 | 1379 | template <class _InputIterator> |
| 1273 | __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator> | |
| 1380 | __enable_if_t<__has_input_iterator_category<_InputIterator>::value, typename forward_list<_Tp, _Alloc>::iterator> | |
| 1274 | 1381 | forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, |
| 1275 | 1382 | _InputIterator __f, _InputIterator __l) |
| 1276 | 1383 | { |
| 1384 | return __insert_after_with_sentinel(__p, std::move(__f), std::move(__l)); | |
| 1385 | } | |
| 1386 | ||
| 1387 | template <class _Tp, class _Alloc> | |
| 1388 | template <class _InputIterator, class _Sentinel> | |
| 1389 | _LIBCPP_HIDE_FROM_ABI | |
| 1390 | typename forward_list<_Tp, _Alloc>::iterator | |
| 1391 | forward_list<_Tp, _Alloc>::__insert_after_with_sentinel(const_iterator __p, _InputIterator __f, _Sentinel __l) { | |
| 1392 | using _Guard = __allocation_guard<__node_allocator>; | |
| 1277 | 1393 | __begin_node_pointer __r = __p.__get_begin(); |
| 1394 | ||
| 1278 | 1395 | if (__f != __l) |
| 1279 | 1396 | { |
| 1280 | 1397 | __node_allocator& __a = base::__alloc(); |
| 1281 | typedef __allocator_destructor<__node_allocator> _Dp; | |
| 1282 | unique_ptr<__node, _Dp> __h(__node_traits::allocate(__a, 1), _Dp(__a, 1)); | |
| 1283 | __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); | |
| 1284 | __node_pointer __first = __h.release(); | |
| 1398 | __node_pointer __first = nullptr; | |
| 1399 | { | |
| 1400 | _Guard __h(__a, 1); | |
| 1401 | __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); | |
| 1402 | __h.__get()->__next_ = nullptr; | |
| 1403 | __first = __h.__release_ptr(); | |
| 1404 | } | |
| 1285 | 1405 | __node_pointer __last = __first; |
| 1286 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1406 | ||
| 1407 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1287 | 1408 | try |
| 1288 | 1409 | { |
| 1289 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1410 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1290 | 1411 | for (++__f; __f != __l; ++__f, ((void)(__last = __last->__next_))) |
| 1291 | 1412 | { |
| 1292 | __h.reset(__node_traits::allocate(__a, 1)); | |
| 1293 | __node_traits::construct(__a, _VSTD::addressof(__h->__value_), *__f); | |
| 1294 | __last->__next_ = __h.release(); | |
| 1413 | _Guard __h(__a, 1); | |
| 1414 | __node_traits::construct(__a, std::addressof(__h.__get()->__value_), *__f); | |
| 1415 | __h.__get()->__next_ = nullptr; | |
| 1416 | __last->__next_ = __h.__release_ptr(); | |
| 1295 | 1417 | } |
| 1296 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1418 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1297 | 1419 | } |
| 1298 | 1420 | catch (...) |
| 1299 | 1421 | { |
| ... | ... | @@ -1306,11 +1428,13 @@ forward_list<_Tp, _Alloc>::insert_after(const_iterator __p, |
| 1306 | 1428 | } |
| 1307 | 1429 | throw; |
| 1308 | 1430 | } |
| 1309 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1431 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1432 | ||
| 1310 | 1433 | __last->__next_ = __r->__next_; |
| 1311 | 1434 | __r->__next_ = __first; |
| 1312 | 1435 | __r = static_cast<__begin_node_pointer>(__last); |
| 1313 | 1436 | } |
| 1437 | ||
| 1314 | 1438 | return iterator(__r); |
| 1315 | 1439 | } |
| 1316 | 1440 | |
| ... | ... | @@ -1711,6 +1835,8 @@ bool operator==(const forward_list<_Tp, _Alloc>& __x, |
| 1711 | 1835 | return (__ix == __ex) == (__iy == __ey); |
| 1712 | 1836 | } |
| 1713 | 1837 | |
| 1838 | #if _LIBCPP_STD_VER <= 17 | |
| 1839 | ||
| 1714 | 1840 | template <class _Tp, class _Alloc> |
| 1715 | 1841 | inline _LIBCPP_INLINE_VISIBILITY |
| 1716 | 1842 | bool operator!=(const forward_list<_Tp, _Alloc>& __x, |
| ... | ... | @@ -1752,6 +1878,17 @@ bool operator<=(const forward_list<_Tp, _Alloc>& __x, |
| 1752 | 1878 | return !(__y < __x); |
| 1753 | 1879 | } |
| 1754 | 1880 | |
| 1881 | #else // #if _LIBCPP_STD_VER <= 17 | |
| 1882 | ||
| 1883 | template <class _Tp, class _Allocator> | |
| 1884 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> | |
| 1885 | operator<=>(const forward_list<_Tp, _Allocator>& __x, const forward_list<_Tp, _Allocator>& __y) { | |
| 1886 | return std::lexicographical_compare_three_way( | |
| 1887 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); | |
| 1888 | } | |
| 1889 | ||
| 1890 | #endif // #if _LIBCPP_STD_VER <= 17 | |
| 1891 | ||
| 1755 | 1892 | template <class _Tp, class _Alloc> |
| 1756 | 1893 | inline _LIBCPP_INLINE_VISIBILITY |
| 1757 | 1894 | void |
| ... | ... | @@ -1761,7 +1898,7 @@ swap(forward_list<_Tp, _Alloc>& __x, forward_list<_Tp, _Alloc>& __y) |
| 1761 | 1898 | __x.swap(__y); |
| 1762 | 1899 | } |
| 1763 | 1900 | |
| 1764 | #if _LIBCPP_STD_VER > 17 | |
| 1901 | #if _LIBCPP_STD_VER >= 20 | |
| 1765 | 1902 | template <class _Tp, class _Allocator, class _Predicate> |
| 1766 | 1903 | inline _LIBCPP_INLINE_VISIBILITY |
| 1767 | 1904 | typename forward_list<_Tp, _Allocator>::size_type |
| ... | ... | @@ -1779,11 +1916,11 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 1779 | 1916 | |
| 1780 | 1917 | _LIBCPP_END_NAMESPACE_STD |
| 1781 | 1918 | |
| 1782 | #if _LIBCPP_STD_VER > 14 | |
| 1919 | #if _LIBCPP_STD_VER >= 17 | |
| 1783 | 1920 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 1784 | 1921 | namespace pmr { |
| 1785 | 1922 | template <class _ValueT> |
| 1786 | using forward_list = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 1923 | using forward_list _LIBCPP_AVAILABILITY_PMR = std::forward_list<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 1787 | 1924 | } // namespace pmr |
| 1788 | 1925 | _LIBCPP_END_NAMESPACE_STD |
| 1789 | 1926 | #endif |
| ... | ... | @@ -1794,9 +1931,11 @@ _LIBCPP_POP_MACROS |
| 1794 | 1931 | # include <algorithm> |
| 1795 | 1932 | # include <atomic> |
| 1796 | 1933 | # include <concepts> |
| 1934 | # include <cstdlib> | |
| 1797 | 1935 | # include <functional> |
| 1798 | 1936 | # include <iosfwd> |
| 1799 | 1937 | # include <iterator> |
| 1938 | # include <type_traits> | |
| 1800 | 1939 | # include <typeinfo> |
| 1801 | 1940 | #endif |
| 1802 | 1941 |
lib/libcxx/include/fstream+27-30| ... | ... | @@ -183,22 +183,18 @@ typedef basic_fstream<wchar_t> wfstream; |
| 183 | 183 | #include <__assert> // all public C++ headers provide the assertion handler |
| 184 | 184 | #include <__availability> |
| 185 | 185 | #include <__config> |
| 186 | #include <__fwd/fstream.h> | |
| 186 | 187 | #include <__locale> |
| 187 | 188 | #include <__utility/move.h> |
| 188 | 189 | #include <__utility/swap.h> |
| 189 | 190 | #include <__utility/unreachable.h> |
| 190 | 191 | #include <cstdio> |
| 191 | #include <cstdlib> | |
| 192 | #include <cstring> | |
| 192 | #include <filesystem> | |
| 193 | 193 | #include <istream> |
| 194 | 194 | #include <ostream> |
| 195 | 195 | #include <typeinfo> |
| 196 | 196 | #include <version> |
| 197 | 197 | |
| 198 | #if !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 199 | # include <filesystem> | |
| 200 | #endif | |
| 201 | ||
| 202 | 198 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 203 | 199 | # pragma GCC system_header |
| 204 | 200 | #endif |
| ... | ... | @@ -210,7 +206,7 @@ _LIBCPP_PUSH_MACROS |
| 210 | 206 | # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS |
| 211 | 207 | #endif |
| 212 | 208 | |
| 213 | #if !defined(_LIBCPP_HAS_NO_FSTREAM) | |
| 209 | #if !defined(_LIBCPP_HAS_NO_FILESYSTEM) | |
| 214 | 210 | |
| 215 | 211 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 216 | 212 | |
| ... | ... | @@ -246,8 +242,8 @@ public: |
| 246 | 242 | _LIBCPP_INLINE_VISIBILITY |
| 247 | 243 | basic_filebuf* open(const string& __s, ios_base::openmode __mode); |
| 248 | 244 | |
| 249 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 250 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 245 | #if _LIBCPP_STD_VER >= 17 | |
| 246 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 251 | 247 | basic_filebuf* open(const _VSTD_FS::path& __p, ios_base::openmode __mode) { |
| 252 | 248 | return open(__p.c_str(), __mode); |
| 253 | 249 | } |
| ... | ... | @@ -398,17 +394,17 @@ basic_filebuf<_CharT, _Traits>::operator=(basic_filebuf&& __rhs) |
| 398 | 394 | template <class _CharT, class _Traits> |
| 399 | 395 | basic_filebuf<_CharT, _Traits>::~basic_filebuf() |
| 400 | 396 | { |
| 401 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 397 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 402 | 398 | try |
| 403 | 399 | { |
| 404 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 400 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 405 | 401 | close(); |
| 406 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 402 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 407 | 403 | } |
| 408 | 404 | catch (...) |
| 409 | 405 | { |
| 410 | 406 | } |
| 411 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 407 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 412 | 408 | if (__owns_eb_) |
| 413 | 409 | delete [] __extbuf_; |
| 414 | 410 | if (__owns_ib_) |
| ... | ... | @@ -754,8 +750,8 @@ basic_filebuf<_CharT, _Traits>::underflow() |
| 754 | 750 | else |
| 755 | 751 | { |
| 756 | 752 | if (__extbufend_ != __extbufnext_) { |
| 757 | _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr"); | |
| 758 | _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr"); | |
| 753 | _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr"); | |
| 754 | _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr"); | |
| 759 | 755 | _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); |
| 760 | 756 | } |
| 761 | 757 | __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); |
| ... | ... | @@ -1169,8 +1165,8 @@ public: |
| 1169 | 1165 | #endif |
| 1170 | 1166 | _LIBCPP_INLINE_VISIBILITY |
| 1171 | 1167 | explicit basic_ifstream(const string& __s, ios_base::openmode __mode = ios_base::in); |
| 1172 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1173 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1168 | #if _LIBCPP_STD_VER >= 17 | |
| 1169 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1174 | 1170 | explicit basic_ifstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in) |
| 1175 | 1171 | : basic_ifstream(__p.c_str(), __mode) {} |
| 1176 | 1172 | #endif // _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1190,8 +1186,8 @@ public: |
| 1190 | 1186 | void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in); |
| 1191 | 1187 | #endif |
| 1192 | 1188 | void open(const string& __s, ios_base::openmode __mode = ios_base::in); |
| 1193 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1194 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1189 | #if _LIBCPP_STD_VER >= 17 | |
| 1190 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1195 | 1191 | void open(const filesystem::path& __p, |
| 1196 | 1192 | ios_base::openmode __mode = ios_base::in) { |
| 1197 | 1193 | return open(__p.c_str(), __mode); |
| ... | ... | @@ -1370,8 +1366,8 @@ public: |
| 1370 | 1366 | _LIBCPP_INLINE_VISIBILITY |
| 1371 | 1367 | explicit basic_ofstream(const string& __s, ios_base::openmode __mode = ios_base::out); |
| 1372 | 1368 | |
| 1373 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1374 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1369 | #if _LIBCPP_STD_VER >= 17 | |
| 1370 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1375 | 1371 | explicit basic_ofstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) |
| 1376 | 1372 | : basic_ofstream(__p.c_str(), __mode) {} |
| 1377 | 1373 | #endif // _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1393,8 +1389,8 @@ public: |
| 1393 | 1389 | #endif |
| 1394 | 1390 | void open(const string& __s, ios_base::openmode __mode = ios_base::out); |
| 1395 | 1391 | |
| 1396 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1397 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1392 | #if _LIBCPP_STD_VER >= 17 | |
| 1393 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1398 | 1394 | void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::out) |
| 1399 | 1395 | { return open(__p.c_str(), __mode); } |
| 1400 | 1396 | #endif // _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1571,8 +1567,8 @@ public: |
| 1571 | 1567 | _LIBCPP_INLINE_VISIBILITY |
| 1572 | 1568 | explicit basic_fstream(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); |
| 1573 | 1569 | |
| 1574 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1575 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1570 | #if _LIBCPP_STD_VER >= 17 | |
| 1571 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1576 | 1572 | explicit basic_fstream(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in | ios_base::out) |
| 1577 | 1573 | : basic_fstream(__p.c_str(), __mode) {} |
| 1578 | 1574 | #endif // _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1590,14 +1586,14 @@ public: |
| 1590 | 1586 | basic_filebuf<char_type, traits_type>* rdbuf() const; |
| 1591 | 1587 | _LIBCPP_INLINE_VISIBILITY |
| 1592 | 1588 | bool is_open() const; |
| 1593 | void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); | |
| 1589 | _LIBCPP_HIDE_FROM_ABI void open(const char* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); | |
| 1594 | 1590 | #ifdef _LIBCPP_HAS_OPEN_WITH_WCHAR |
| 1595 | 1591 | void open(const wchar_t* __s, ios_base::openmode __mode = ios_base::in | ios_base::out); |
| 1596 | 1592 | #endif |
| 1597 | void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); | |
| 1593 | _LIBCPP_HIDE_FROM_ABI void open(const string& __s, ios_base::openmode __mode = ios_base::in | ios_base::out); | |
| 1598 | 1594 | |
| 1599 | #if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY) | |
| 1600 | _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_INLINE_VISIBILITY | |
| 1595 | #if _LIBCPP_STD_VER >= 17 | |
| 1596 | _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INLINE_VISIBILITY | |
| 1601 | 1597 | void open(const filesystem::path& __p, ios_base::openmode __mode = ios_base::in|ios_base::out) |
| 1602 | 1598 | { return open(__p.c_str(), __mode); } |
| 1603 | 1599 | #endif // _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1746,13 +1742,14 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf<char>; |
| 1746 | 1742 | |
| 1747 | 1743 | _LIBCPP_END_NAMESPACE_STD |
| 1748 | 1744 | |
| 1749 | #endif // _LIBCPP_HAS_NO_FSTREAM | |
| 1745 | #endif // _LIBCPP_HAS_NO_FILESYSTEM | |
| 1750 | 1746 | |
| 1751 | 1747 | _LIBCPP_POP_MACROS |
| 1752 | 1748 | |
| 1753 | 1749 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1754 | 1750 | # include <atomic> |
| 1755 | 1751 | # include <concepts> |
| 1752 | # include <cstdlib> | |
| 1756 | 1753 | # include <iosfwd> |
| 1757 | 1754 | # include <limits> |
| 1758 | 1755 | # include <new> |
lib/libcxx/include/functional+54-41| ... | ... | @@ -43,20 +43,22 @@ public: |
| 43 | 43 | |
| 44 | 44 | // construct/copy/destroy |
| 45 | 45 | template<class U> |
| 46 | reference_wrapper(U&&); | |
| 47 | reference_wrapper(const reference_wrapper<T>& x) noexcept; | |
| 46 | constexpr reference_wrapper(U&&); // constexpr since C++20 | |
| 47 | constexpr reference_wrapper(const reference_wrapper<T>& x) noexcept; // constexpr since C++20 | |
| 48 | 48 | |
| 49 | 49 | // assignment |
| 50 | reference_wrapper& operator=(const reference_wrapper<T>& x) noexcept; | |
| 50 | constexpr reference_wrapper& | |
| 51 | operator=(const reference_wrapper<T>& x) noexcept; // constexpr since C++20 | |
| 51 | 52 | |
| 52 | 53 | // access |
| 53 | operator T& () const noexcept; | |
| 54 | T& get() const noexcept; | |
| 54 | constexpr operator T& () const noexcept; // constexpr since C++20 | |
| 55 | constexpr T& get() const noexcept; // constexpr since C++20 | |
| 55 | 56 | |
| 56 | 57 | // invoke |
| 57 | 58 | template <class... ArgTypes> |
| 58 | typename result_of<T&(ArgTypes&&...)>::type | |
| 59 | operator() (ArgTypes&&...) const; | |
| 59 | constexpr typename result_of<T&(ArgTypes&&...)>::type // constexpr since C++20 | |
| 60 | operator() (ArgTypes&&...) const | |
| 61 | noexcept(is_nothrow_invocable_v<T&, ArgTypes...>); // noexcept since C++17 | |
| 60 | 62 | }; |
| 61 | 63 | |
| 62 | 64 | template <class T> |
| ... | ... | @@ -220,11 +222,16 @@ template<class Fn, class... BoundArgs> |
| 220 | 222 | template<class R, class Fn, class... BoundArgs> |
| 221 | 223 | constexpr unspecified bind(Fn&&, BoundArgs&&...); // constexpr in C++20 |
| 222 | 224 | |
| 225 | // [func.invoke] | |
| 223 | 226 | template<class F, class... Args> |
| 224 | 227 | constexpr // constexpr in C++20 |
| 225 | 228 | invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) // C++17 |
| 226 | 229 | noexcept(is_nothrow_invocable_v<F, Args...>); |
| 227 | 230 | |
| 231 | template<class R, class F, class... Args> | |
| 232 | constexpr R invoke_r(F&& f, Args&&... args) // C++23 | |
| 233 | noexcept(is_nothrow_invocable_r_v<R, F, Args...>); | |
| 234 | ||
| 228 | 235 | namespace placeholders { |
| 229 | 236 | // M is the implementation-defined number of placeholders |
| 230 | 237 | extern unspecified _1; |
| ... | ... | @@ -250,10 +257,10 @@ public: |
| 250 | 257 | }; |
| 251 | 258 | |
| 252 | 259 | template <class Operation, class T> |
| 253 | binder1st<Operation> bind1st(const Operation& op, const T& x); // deprecated in C++11, removed in C++17 | |
| 260 | binder1st<Operation> bind1st(const Operation& op, const T& x); // deprecated in C++11, removed in C++17 | |
| 254 | 261 | |
| 255 | 262 | template <class Operation> |
| 256 | class binder2nd // deprecated in C++11, removed in C++17 | |
| 263 | class binder2nd // deprecated in C++11, removed in C++17 | |
| 257 | 264 | : public unary_function<typename Operation::first_argument_type, |
| 258 | 265 | typename Operation::result_type> |
| 259 | 266 | { |
| ... | ... | @@ -267,9 +274,9 @@ public: |
| 267 | 274 | }; |
| 268 | 275 | |
| 269 | 276 | template <class Operation, class T> |
| 270 | binder2nd<Operation> bind2nd(const Operation& op, const T& x); // deprecated in C++11, removed in C++17 | |
| 277 | binder2nd<Operation> bind2nd(const Operation& op, const T& x); // deprecated in C++11, removed in C++17 | |
| 271 | 278 | |
| 272 | template <class Arg, class Result> // deprecated in C++11, removed in C++17 | |
| 279 | template <class Arg, class Result> // deprecated in C++11, removed in C++17 | |
| 273 | 280 | class pointer_to_unary_function : public unary_function<Arg, Result> |
| 274 | 281 | { |
| 275 | 282 | public: |
| ... | ... | @@ -278,9 +285,9 @@ public: |
| 278 | 285 | }; |
| 279 | 286 | |
| 280 | 287 | template <class Arg, class Result> |
| 281 | pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)); // deprecated in C++11, removed in C++17 | |
| 288 | pointer_to_unary_function<Arg,Result> ptr_fun(Result (*f)(Arg)); // deprecated in C++11, removed in C++17 | |
| 282 | 289 | |
| 283 | template <class Arg1, class Arg2, class Result> // deprecated in C++11, removed in C++17 | |
| 290 | template <class Arg1, class Arg2, class Result> // deprecated in C++11, removed in C++17 | |
| 284 | 291 | class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> |
| 285 | 292 | { |
| 286 | 293 | public: |
| ... | ... | @@ -289,9 +296,9 @@ public: |
| 289 | 296 | }; |
| 290 | 297 | |
| 291 | 298 | template <class Arg1, class Arg2, class Result> |
| 292 | pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2)); // deprecated in C++11, removed in C++17 | |
| 299 | pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*f)(Arg1,Arg2)); // deprecated in C++11, removed in C++17 | |
| 293 | 300 | |
| 294 | template<class S, class T> // deprecated in C++11, removed in C++17 | |
| 301 | template<class S, class T> // deprecated in C++11, removed in C++17 | |
| 295 | 302 | class mem_fun_t : public unary_function<T*, S> |
| 296 | 303 | { |
| 297 | 304 | public: |
| ... | ... | @@ -300,18 +307,18 @@ public: |
| 300 | 307 | }; |
| 301 | 308 | |
| 302 | 309 | template<class S, class T, class A> |
| 303 | class mem_fun1_t : public binary_function<T*, A, S> // deprecated in C++11, removed in C++17 | |
| 310 | class mem_fun1_t : public binary_function<T*, A, S> // deprecated in C++11, removed in C++17 | |
| 304 | 311 | { |
| 305 | 312 | public: |
| 306 | 313 | explicit mem_fun1_t(S (T::*p)(A)); |
| 307 | 314 | S operator()(T* p, A x) const; |
| 308 | 315 | }; |
| 309 | 316 | |
| 310 | template<class S, class T> mem_fun_t<S,T> mem_fun(S (T::*f)()); // deprecated in C++11, removed in C++17 | |
| 311 | template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)); // deprecated in C++11, removed in C++17 | |
| 317 | template<class S, class T> mem_fun_t<S,T> mem_fun(S (T::*f)()); // deprecated in C++11, removed in C++17 | |
| 318 | template<class S, class T, class A> mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A)); // deprecated in C++11, removed in C++17 | |
| 312 | 319 | |
| 313 | 320 | template<class S, class T> |
| 314 | class mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17 | |
| 321 | class mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17 | |
| 315 | 322 | { |
| 316 | 323 | public: |
| 317 | 324 | explicit mem_fun_ref_t(S (T::*p)()); |
| ... | ... | @@ -319,18 +326,20 @@ public: |
| 319 | 326 | }; |
| 320 | 327 | |
| 321 | 328 | template<class S, class T, class A> |
| 322 | class mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17 | |
| 329 | class mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17 | |
| 323 | 330 | { |
| 324 | 331 | public: |
| 325 | 332 | explicit mem_fun1_ref_t(S (T::*p)(A)); |
| 326 | 333 | S operator()(T& p, A x) const; |
| 327 | 334 | }; |
| 328 | 335 | |
| 329 | template<class S, class T> mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()); // deprecated in C++11, removed in C++17 | |
| 330 | template<class S, class T, class A> mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)); // deprecated in C++11, removed in C++17 | |
| 336 | template<class S, class T> | |
| 337 | mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()); // deprecated in C++11, removed in C++17 | |
| 338 | template<class S, class T, class A> | |
| 339 | mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A)); // deprecated in C++11, removed in C++17 | |
| 331 | 340 | |
| 332 | 341 | template <class S, class T> |
| 333 | class const_mem_fun_t : public unary_function<const T*, S> // deprecated in C++11, removed in C++17 | |
| 342 | class const_mem_fun_t : public unary_function<const T*, S> // deprecated in C++11, removed in C++17 | |
| 334 | 343 | { |
| 335 | 344 | public: |
| 336 | 345 | explicit const_mem_fun_t(S (T::*p)() const); |
| ... | ... | @@ -338,18 +347,20 @@ public: |
| 338 | 347 | }; |
| 339 | 348 | |
| 340 | 349 | template <class S, class T, class A> |
| 341 | class const_mem_fun1_t : public binary_function<const T*, A, S> // deprecated in C++11, removed in C++17 | |
| 350 | class const_mem_fun1_t : public binary_function<const T*, A, S> // deprecated in C++11, removed in C++17 | |
| 342 | 351 | { |
| 343 | 352 | public: |
| 344 | 353 | explicit const_mem_fun1_t(S (T::*p)(A) const); |
| 345 | 354 | S operator()(const T* p, A x) const; |
| 346 | 355 | }; |
| 347 | 356 | |
| 348 | template <class S, class T> const_mem_fun_t<S,T> mem_fun(S (T::*f)() const); // deprecated in C++11, removed in C++17 | |
| 349 | template <class S, class T, class A> const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const); // deprecated in C++11, removed in C++17 | |
| 357 | template <class S, class T> | |
| 358 | const_mem_fun_t<S,T> mem_fun(S (T::*f)() const); // deprecated in C++11, removed in C++17 | |
| 359 | template <class S, class T, class A> | |
| 360 | const_mem_fun1_t<S,T,A> mem_fun(S (T::*f)(A) const); // deprecated in C++11, removed in C++17 | |
| 350 | 361 | |
| 351 | 362 | template <class S, class T> |
| 352 | class const_mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17 | |
| 363 | class const_mem_fun_ref_t : public unary_function<T, S> // deprecated in C++11, removed in C++17 | |
| 353 | 364 | { |
| 354 | 365 | public: |
| 355 | 366 | explicit const_mem_fun_ref_t(S (T::*p)() const); |
| ... | ... | @@ -357,18 +368,19 @@ public: |
| 357 | 368 | }; |
| 358 | 369 | |
| 359 | 370 | template <class S, class T, class A> |
| 360 | class const_mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17 | |
| 371 | class const_mem_fun1_ref_t : public binary_function<T, A, S> // deprecated in C++11, removed in C++17 | |
| 361 | 372 | { |
| 362 | 373 | public: |
| 363 | 374 | explicit const_mem_fun1_ref_t(S (T::*p)(A) const); |
| 364 | 375 | S operator()(const T& p, A x) const; |
| 365 | 376 | }; |
| 366 | 377 | |
| 367 | template <class S, class T> const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const); // deprecated in C++11, removed in C++17 | |
| 368 | template <class S, class T, class A> const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const); // deprecated in C++11, removed in C++17 | |
| 378 | template <class S, class T> | |
| 379 | const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const); // deprecated in C++11, removed in C++17 | |
| 380 | template <class S, class T, class A> | |
| 381 | const_mem_fun1_ref_t<S,T,A> mem_fun_ref(S (T::*f)(A) const); // deprecated in C++11, removed in C++17 | |
| 369 | 382 | |
| 370 | template<class R, class T> | |
| 371 | constexpr unspecified mem_fn(R T::*); // constexpr in C++20 | |
| 383 | template<class R, class T> constexpr unspecified mem_fn(R T::*); // constexpr in C++20 | |
| 372 | 384 | |
| 373 | 385 | class bad_function_call |
| 374 | 386 | : public exception |
| ... | ... | @@ -444,13 +456,13 @@ template <class R, class ... ArgTypes> |
| 444 | 456 | bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept; |
| 445 | 457 | |
| 446 | 458 | template <class R, class ... ArgTypes> |
| 447 | bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept; | |
| 459 | bool operator==(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20 | |
| 448 | 460 | |
| 449 | 461 | template <class R, class ... ArgTypes> |
| 450 | bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept; | |
| 462 | bool operator!=(const function<R(ArgTypes...)>&, nullptr_t) noexcept; // removed in C++20 | |
| 451 | 463 | |
| 452 | 464 | template <class R, class ... ArgTypes> |
| 453 | bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept; | |
| 465 | bool operator!=(nullptr_t, const function<R(ArgTypes...)>&) noexcept; // removed in C++20 | |
| 454 | 466 | |
| 455 | 467 | // specialized algorithms: |
| 456 | 468 | template <class R, class ... ArgTypes> |
| ... | ... | @@ -504,8 +516,7 @@ POLICY: For non-variadic implementations, the number of arguments is limited |
| 504 | 516 | #include <__assert> // all public C++ headers provide the assertion handler |
| 505 | 517 | #include <__compare/compare_three_way.h> |
| 506 | 518 | #include <__config> |
| 507 | #include <__debug> | |
| 508 | #include <__functional/binary_function.h> // TODO: deprecate | |
| 519 | #include <__functional/binary_function.h> | |
| 509 | 520 | #include <__functional/binary_negate.h> |
| 510 | 521 | #include <__functional/bind.h> |
| 511 | 522 | #include <__functional/bind_back.h> |
| ... | ... | @@ -527,13 +538,11 @@ POLICY: For non-variadic implementations, the number of arguments is limited |
| 527 | 538 | #include <__functional/pointer_to_unary_function.h> |
| 528 | 539 | #include <__functional/ranges_operations.h> |
| 529 | 540 | #include <__functional/reference_wrapper.h> |
| 530 | #include <__functional/unary_function.h> // TODO: deprecate | |
| 541 | #include <__functional/unary_function.h> | |
| 531 | 542 | #include <__functional/unary_negate.h> |
| 532 | #include <__functional/unwrap_ref.h> | |
| 543 | #include <__type_traits/unwrap_ref.h> | |
| 533 | 544 | #include <__utility/forward.h> |
| 534 | #include <exception> | |
| 535 | 545 | #include <memory> // TODO: find out why removing this breaks the modules build |
| 536 | #include <type_traits> | |
| 537 | 546 | #include <typeinfo> |
| 538 | 547 | #include <version> |
| 539 | 548 | |
| ... | ... | @@ -542,8 +551,12 @@ POLICY: For non-variadic implementations, the number of arguments is limited |
| 542 | 551 | #endif |
| 543 | 552 | |
| 544 | 553 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 554 | # include <atomic> | |
| 545 | 555 | # include <concepts> |
| 556 | # include <cstdlib> | |
| 557 | # include <exception> | |
| 546 | 558 | # include <tuple> |
| 559 | # include <type_traits> | |
| 547 | 560 | # include <utility> |
| 548 | 561 | #endif |
| 549 | 562 |
lib/libcxx/include/future+147-129| ... | ... | @@ -366,17 +366,29 @@ template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; |
| 366 | 366 | #include <__chrono/duration.h> |
| 367 | 367 | #include <__chrono/time_point.h> |
| 368 | 368 | #include <__config> |
| 369 | #include <__exception/exception_ptr.h> | |
| 370 | #include <__memory/addressof.h> | |
| 371 | #include <__memory/allocator.h> | |
| 369 | 372 | #include <__memory/allocator_arg_t.h> |
| 370 | 373 | #include <__memory/allocator_destructor.h> |
| 374 | #include <__memory/allocator_traits.h> | |
| 375 | #include <__memory/compressed_pair.h> | |
| 376 | #include <__memory/pointer_traits.h> | |
| 377 | #include <__memory/shared_ptr.h> | |
| 378 | #include <__memory/unique_ptr.h> | |
| 371 | 379 | #include <__memory/uses_allocator.h> |
| 380 | #include <__system_error/error_category.h> | |
| 381 | #include <__system_error/error_code.h> | |
| 382 | #include <__system_error/error_condition.h> | |
| 383 | #include <__type_traits/aligned_storage.h> | |
| 384 | #include <__type_traits/alignment_of.h> | |
| 372 | 385 | #include <__type_traits/strip_signature.h> |
| 373 | 386 | #include <__utility/auto_cast.h> |
| 374 | 387 | #include <__utility/forward.h> |
| 375 | 388 | #include <__utility/move.h> |
| 376 | #include <exception> | |
| 377 | 389 | #include <mutex> |
| 378 | 390 | #include <new> |
| 379 | #include <system_error> | |
| 391 | #include <stdexcept> | |
| 380 | 392 | #include <thread> |
| 381 | 393 | #include <version> |
| 382 | 394 | |
| ... | ... | @@ -488,8 +500,7 @@ _LIBCPP_DECLARE_STRONG_ENUM(future_status) |
| 488 | 500 | }; |
| 489 | 501 | _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(future_status) |
| 490 | 502 | |
| 491 | _LIBCPP_FUNC_VIS | |
| 492 | const error_category& future_category() _NOEXCEPT; | |
| 503 | _LIBCPP_EXPORTED_FROM_ABI const error_category& future_category() _NOEXCEPT; | |
| 493 | 504 | |
| 494 | 505 | inline _LIBCPP_INLINE_VISIBILITY |
| 495 | 506 | error_code |
| ... | ... | @@ -505,7 +516,7 @@ make_error_condition(future_errc __e) _NOEXCEPT |
| 505 | 516 | return error_condition(static_cast<int>(__e), future_category()); |
| 506 | 517 | } |
| 507 | 518 | |
| 508 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error | |
| 519 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error | |
| 509 | 520 | : public logic_error |
| 510 | 521 | { |
| 511 | 522 | error_code __ec_; |
| ... | ... | @@ -515,25 +526,25 @@ public: |
| 515 | 526 | _LIBCPP_INLINE_VISIBILITY |
| 516 | 527 | const error_code& code() const _NOEXCEPT {return __ec_;} |
| 517 | 528 | |
| 518 | future_error(const future_error&) _NOEXCEPT = default; | |
| 529 | _LIBCPP_HIDE_FROM_ABI future_error(const future_error&) _NOEXCEPT = default; | |
| 519 | 530 | ~future_error() _NOEXCEPT override; |
| 520 | 531 | }; |
| 521 | 532 | |
| 522 | 533 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 523 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 534 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 524 | 535 | _LIBCPP_AVAILABILITY_FUTURE_ERROR |
| 525 | 536 | #endif |
| 526 | 537 | void __throw_future_error(future_errc __ev) |
| 527 | 538 | { |
| 528 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 539 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 529 | 540 | throw future_error(make_error_code(__ev)); |
| 530 | 541 | #else |
| 531 | ((void)__ev); | |
| 532 | _VSTD::abort(); | |
| 542 | (void)__ev; | |
| 543 | _LIBCPP_VERBOSE_ABORT("future_error was thrown in -fno-exceptions mode"); | |
| 533 | 544 | #endif |
| 534 | 545 | } |
| 535 | 546 | |
| 536 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state | |
| 547 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state | |
| 537 | 548 | : public __shared_count |
| 538 | 549 | { |
| 539 | 550 | protected: |
| ... | ... | @@ -631,17 +642,17 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 631 | 642 | protected: |
| 632 | 643 | _Up __value_; |
| 633 | 644 | |
| 634 | void __on_zero_shared() _NOEXCEPT override; | |
| 645 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; | |
| 635 | 646 | public: |
| 636 | 647 | |
| 637 | 648 | template <class _Arg> |
| 638 | void set_value(_Arg&& __arg); | |
| 649 | _LIBCPP_HIDE_FROM_ABI void set_value(_Arg&& __arg); | |
| 639 | 650 | |
| 640 | 651 | template <class _Arg> |
| 641 | void set_value_at_thread_exit(_Arg&& __arg); | |
| 652 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Arg&& __arg); | |
| 642 | 653 | |
| 643 | _Rp move(); | |
| 644 | __add_lvalue_reference_t<_Rp> copy(); | |
| 654 | _LIBCPP_HIDE_FROM_ABI _Rp move(); | |
| 655 | _LIBCPP_HIDE_FROM_ABI __add_lvalue_reference_t<_Rp> copy(); | |
| 645 | 656 | }; |
| 646 | 657 | |
| 647 | 658 | template <class _Rp> |
| ... | ... | @@ -711,13 +722,13 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&> |
| 711 | 722 | protected: |
| 712 | 723 | _Up __value_; |
| 713 | 724 | |
| 714 | void __on_zero_shared() _NOEXCEPT override; | |
| 725 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; | |
| 715 | 726 | public: |
| 716 | 727 | |
| 717 | void set_value(_Rp& __arg); | |
| 718 | void set_value_at_thread_exit(_Rp& __arg); | |
| 728 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __arg); | |
| 729 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp& __arg); | |
| 719 | 730 | |
| 720 | _Rp& copy(); | |
| 731 | _LIBCPP_HIDE_FROM_ABI _Rp& copy(); | |
| 721 | 732 | }; |
| 722 | 733 | |
| 723 | 734 | template <class _Rp> |
| ... | ... | @@ -769,7 +780,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc |
| 769 | 780 | typedef __assoc_state<_Rp> base; |
| 770 | 781 | _Alloc __alloc_; |
| 771 | 782 | |
| 772 | virtual void __on_zero_shared() _NOEXCEPT; | |
| 783 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; | |
| 773 | 784 | public: |
| 774 | 785 | _LIBCPP_INLINE_VISIBILITY |
| 775 | 786 | explicit __assoc_state_alloc(const _Alloc& __a) |
| ... | ... | @@ -797,7 +808,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc> |
| 797 | 808 | typedef __assoc_state<_Rp&> base; |
| 798 | 809 | _Alloc __alloc_; |
| 799 | 810 | |
| 800 | virtual void __on_zero_shared() _NOEXCEPT; | |
| 811 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; | |
| 801 | 812 | public: |
| 802 | 813 | _LIBCPP_INLINE_VISIBILITY |
| 803 | 814 | explicit __assoc_state_alloc(const _Alloc& __a) |
| ... | ... | @@ -823,7 +834,7 @@ class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc |
| 823 | 834 | typedef __assoc_sub_state base; |
| 824 | 835 | _Alloc __alloc_; |
| 825 | 836 | |
| 826 | void __on_zero_shared() _NOEXCEPT override; | |
| 837 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; | |
| 827 | 838 | public: |
| 828 | 839 | _LIBCPP_INLINE_VISIBILITY |
| 829 | 840 | explicit __assoc_sub_state_alloc(const _Alloc& __a) |
| ... | ... | @@ -854,7 +865,7 @@ public: |
| 854 | 865 | _LIBCPP_INLINE_VISIBILITY |
| 855 | 866 | explicit __deferred_assoc_state(_Fp&& __f); |
| 856 | 867 | |
| 857 | virtual void __execute(); | |
| 868 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); | |
| 858 | 869 | }; |
| 859 | 870 | |
| 860 | 871 | template <class _Rp, class _Fp> |
| ... | ... | @@ -869,18 +880,18 @@ template <class _Rp, class _Fp> |
| 869 | 880 | void |
| 870 | 881 | __deferred_assoc_state<_Rp, _Fp>::__execute() |
| 871 | 882 | { |
| 872 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 883 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 873 | 884 | try |
| 874 | 885 | { |
| 875 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 886 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 876 | 887 | this->set_value(__func_()); |
| 877 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 888 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 878 | 889 | } |
| 879 | 890 | catch (...) |
| 880 | 891 | { |
| 881 | 892 | this->set_exception(current_exception()); |
| 882 | 893 | } |
| 883 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 894 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 884 | 895 | } |
| 885 | 896 | |
| 886 | 897 | template <class _Fp> |
| ... | ... | @@ -895,7 +906,7 @@ public: |
| 895 | 906 | _LIBCPP_INLINE_VISIBILITY |
| 896 | 907 | explicit __deferred_assoc_state(_Fp&& __f); |
| 897 | 908 | |
| 898 | void __execute() override; | |
| 909 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; | |
| 899 | 910 | }; |
| 900 | 911 | |
| 901 | 912 | template <class _Fp> |
| ... | ... | @@ -910,19 +921,19 @@ template <class _Fp> |
| 910 | 921 | void |
| 911 | 922 | __deferred_assoc_state<void, _Fp>::__execute() |
| 912 | 923 | { |
| 913 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 924 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 914 | 925 | try |
| 915 | 926 | { |
| 916 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 927 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 917 | 928 | __func_(); |
| 918 | 929 | this->set_value(); |
| 919 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 930 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 920 | 931 | } |
| 921 | 932 | catch (...) |
| 922 | 933 | { |
| 923 | 934 | this->set_exception(current_exception()); |
| 924 | 935 | } |
| 925 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 936 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 926 | 937 | } |
| 927 | 938 | |
| 928 | 939 | template <class _Rp, class _Fp> |
| ... | ... | @@ -933,12 +944,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state |
| 933 | 944 | |
| 934 | 945 | _Fp __func_; |
| 935 | 946 | |
| 936 | virtual void __on_zero_shared() _NOEXCEPT; | |
| 947 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __on_zero_shared() _NOEXCEPT; | |
| 937 | 948 | public: |
| 938 | 949 | _LIBCPP_INLINE_VISIBILITY |
| 939 | 950 | explicit __async_assoc_state(_Fp&& __f); |
| 940 | 951 | |
| 941 | virtual void __execute(); | |
| 952 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __execute(); | |
| 942 | 953 | }; |
| 943 | 954 | |
| 944 | 955 | template <class _Rp, class _Fp> |
| ... | ... | @@ -952,18 +963,18 @@ template <class _Rp, class _Fp> |
| 952 | 963 | void |
| 953 | 964 | __async_assoc_state<_Rp, _Fp>::__execute() |
| 954 | 965 | { |
| 955 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 966 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 956 | 967 | try |
| 957 | 968 | { |
| 958 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 969 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 959 | 970 | this->set_value(__func_()); |
| 960 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 971 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 961 | 972 | } |
| 962 | 973 | catch (...) |
| 963 | 974 | { |
| 964 | 975 | this->set_exception(current_exception()); |
| 965 | 976 | } |
| 966 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 977 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 967 | 978 | } |
| 968 | 979 | |
| 969 | 980 | template <class _Rp, class _Fp> |
| ... | ... | @@ -982,12 +993,12 @@ class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp> |
| 982 | 993 | |
| 983 | 994 | _Fp __func_; |
| 984 | 995 | |
| 985 | void __on_zero_shared() _NOEXCEPT override; | |
| 996 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __on_zero_shared() _NOEXCEPT override; | |
| 986 | 997 | public: |
| 987 | 998 | _LIBCPP_INLINE_VISIBILITY |
| 988 | 999 | explicit __async_assoc_state(_Fp&& __f); |
| 989 | 1000 | |
| 990 | void __execute() override; | |
| 1001 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __execute() override; | |
| 991 | 1002 | }; |
| 992 | 1003 | |
| 993 | 1004 | template <class _Fp> |
| ... | ... | @@ -1001,19 +1012,19 @@ template <class _Fp> |
| 1001 | 1012 | void |
| 1002 | 1013 | __async_assoc_state<void, _Fp>::__execute() |
| 1003 | 1014 | { |
| 1004 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1015 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1005 | 1016 | try |
| 1006 | 1017 | { |
| 1007 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1018 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1008 | 1019 | __func_(); |
| 1009 | 1020 | this->set_value(); |
| 1010 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1021 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1011 | 1022 | } |
| 1012 | 1023 | catch (...) |
| 1013 | 1024 | { |
| 1014 | 1025 | this->set_exception(current_exception()); |
| 1015 | 1026 | } |
| 1016 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1027 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1017 | 1028 | } |
| 1018 | 1029 | |
| 1019 | 1030 | template <class _Fp> |
| ... | ... | @@ -1044,7 +1055,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future |
| 1044 | 1055 | { |
| 1045 | 1056 | __assoc_state<_Rp>* __state_; |
| 1046 | 1057 | |
| 1047 | explicit future(__assoc_state<_Rp>* __state); | |
| 1058 | explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp>* __state); | |
| 1048 | 1059 | |
| 1049 | 1060 | template <class> friend class promise; |
| 1050 | 1061 | template <class> friend class shared_future; |
| ... | ... | @@ -1069,12 +1080,12 @@ public: |
| 1069 | 1080 | return *this; |
| 1070 | 1081 | } |
| 1071 | 1082 | |
| 1072 | ~future(); | |
| 1083 | _LIBCPP_HIDE_FROM_ABI ~future(); | |
| 1073 | 1084 | _LIBCPP_INLINE_VISIBILITY |
| 1074 | 1085 | shared_future<_Rp> share() _NOEXCEPT; |
| 1075 | 1086 | |
| 1076 | 1087 | // retrieving the value |
| 1077 | _Rp get(); | |
| 1088 | _LIBCPP_HIDE_FROM_ABI _Rp get(); | |
| 1078 | 1089 | |
| 1079 | 1090 | _LIBCPP_INLINE_VISIBILITY |
| 1080 | 1091 | void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
| ... | ... | @@ -1106,7 +1117,7 @@ future<_Rp>::future(__assoc_state<_Rp>* __state) |
| 1106 | 1117 | |
| 1107 | 1118 | struct __release_shared_count |
| 1108 | 1119 | { |
| 1109 | void operator()(__shared_count* __p) {__p->__release_shared();} | |
| 1120 | _LIBCPP_HIDE_FROM_ABI void operator()(__shared_count* __p) {__p->__release_shared();} | |
| 1110 | 1121 | }; |
| 1111 | 1122 | |
| 1112 | 1123 | template <class _Rp> |
| ... | ... | @@ -1120,7 +1131,7 @@ template <class _Rp> |
| 1120 | 1131 | _Rp |
| 1121 | 1132 | future<_Rp>::get() |
| 1122 | 1133 | { |
| 1123 | unique_ptr<__shared_count, __release_shared_count> __(__state_); | |
| 1134 | unique_ptr<__shared_count, __release_shared_count> __guard(__state_); | |
| 1124 | 1135 | __assoc_state<_Rp>* __s = __state_; |
| 1125 | 1136 | __state_ = nullptr; |
| 1126 | 1137 | return __s->move(); |
| ... | ... | @@ -1131,7 +1142,7 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&> |
| 1131 | 1142 | { |
| 1132 | 1143 | __assoc_state<_Rp&>* __state_; |
| 1133 | 1144 | |
| 1134 | explicit future(__assoc_state<_Rp&>* __state); | |
| 1145 | explicit _LIBCPP_HIDE_FROM_ABI future(__assoc_state<_Rp&>* __state); | |
| 1135 | 1146 | |
| 1136 | 1147 | template <class> friend class promise; |
| 1137 | 1148 | template <class> friend class shared_future; |
| ... | ... | @@ -1156,12 +1167,12 @@ public: |
| 1156 | 1167 | return *this; |
| 1157 | 1168 | } |
| 1158 | 1169 | |
| 1159 | ~future(); | |
| 1170 | _LIBCPP_HIDE_FROM_ABI ~future(); | |
| 1160 | 1171 | _LIBCPP_INLINE_VISIBILITY |
| 1161 | 1172 | shared_future<_Rp&> share() _NOEXCEPT; |
| 1162 | 1173 | |
| 1163 | 1174 | // retrieving the value |
| 1164 | _Rp& get(); | |
| 1175 | _LIBCPP_HIDE_FROM_ABI _Rp& get(); | |
| 1165 | 1176 | |
| 1166 | 1177 | _LIBCPP_INLINE_VISIBILITY |
| 1167 | 1178 | void swap(future& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
| ... | ... | @@ -1202,14 +1213,14 @@ template <class _Rp> |
| 1202 | 1213 | _Rp& |
| 1203 | 1214 | future<_Rp&>::get() |
| 1204 | 1215 | { |
| 1205 | unique_ptr<__shared_count, __release_shared_count> __(__state_); | |
| 1216 | unique_ptr<__shared_count, __release_shared_count> __guard(__state_); | |
| 1206 | 1217 | __assoc_state<_Rp&>* __s = __state_; |
| 1207 | 1218 | __state_ = nullptr; |
| 1208 | 1219 | return __s->copy(); |
| 1209 | 1220 | } |
| 1210 | 1221 | |
| 1211 | 1222 | template <> |
| 1212 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void> | |
| 1223 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE future<void> | |
| 1213 | 1224 | { |
| 1214 | 1225 | __assoc_sub_state* __state_; |
| 1215 | 1226 | |
| ... | ... | @@ -1288,14 +1299,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise |
| 1288 | 1299 | |
| 1289 | 1300 | template <class> friend class packaged_task; |
| 1290 | 1301 | public: |
| 1291 | promise(); | |
| 1302 | _LIBCPP_HIDE_FROM_ABI promise(); | |
| 1292 | 1303 | template <class _Alloc> |
| 1293 | promise(allocator_arg_t, const _Alloc& __a); | |
| 1304 | _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Alloc& __a); | |
| 1294 | 1305 | _LIBCPP_INLINE_VISIBILITY |
| 1295 | 1306 | promise(promise&& __rhs) _NOEXCEPT |
| 1296 | 1307 | : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
| 1297 | 1308 | promise(const promise& __rhs) = delete; |
| 1298 | ~promise(); | |
| 1309 | _LIBCPP_HIDE_FROM_ABI ~promise(); | |
| 1299 | 1310 | |
| 1300 | 1311 | // assignment |
| 1301 | 1312 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1310,17 +1321,17 @@ public: |
| 1310 | 1321 | void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
| 1311 | 1322 | |
| 1312 | 1323 | // retrieving the result |
| 1313 | future<_Rp> get_future(); | |
| 1324 | _LIBCPP_HIDE_FROM_ABI future<_Rp> get_future(); | |
| 1314 | 1325 | |
| 1315 | 1326 | // setting the result |
| 1316 | void set_value(const _Rp& __r); | |
| 1317 | void set_value(_Rp&& __r); | |
| 1318 | void set_exception(exception_ptr __p); | |
| 1327 | _LIBCPP_HIDE_FROM_ABI void set_value(const _Rp& __r); | |
| 1328 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp&& __r); | |
| 1329 | _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); | |
| 1319 | 1330 | |
| 1320 | 1331 | // setting the result with deferred notification |
| 1321 | void set_value_at_thread_exit(const _Rp& __r); | |
| 1322 | void set_value_at_thread_exit(_Rp&& __r); | |
| 1323 | void set_exception_at_thread_exit(exception_ptr __p); | |
| 1332 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(const _Rp& __r); | |
| 1333 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&& __r); | |
| 1334 | _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); | |
| 1324 | 1335 | }; |
| 1325 | 1336 | |
| 1326 | 1337 | template <class _Rp> |
| ... | ... | @@ -1386,7 +1397,7 @@ template <class _Rp> |
| 1386 | 1397 | void |
| 1387 | 1398 | promise<_Rp>::set_exception(exception_ptr __p) |
| 1388 | 1399 | { |
| 1389 | _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); | |
| 1400 | _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" ); | |
| 1390 | 1401 | if (__state_ == nullptr) |
| 1391 | 1402 | __throw_future_error(future_errc::no_state); |
| 1392 | 1403 | __state_->set_exception(__p); |
| ... | ... | @@ -1414,7 +1425,7 @@ template <class _Rp> |
| 1414 | 1425 | void |
| 1415 | 1426 | promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p) |
| 1416 | 1427 | { |
| 1417 | _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); | |
| 1428 | _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); | |
| 1418 | 1429 | if (__state_ == nullptr) |
| 1419 | 1430 | __throw_future_error(future_errc::no_state); |
| 1420 | 1431 | __state_->set_exception_at_thread_exit(__p); |
| ... | ... | @@ -1433,14 +1444,14 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&> |
| 1433 | 1444 | template <class> friend class packaged_task; |
| 1434 | 1445 | |
| 1435 | 1446 | public: |
| 1436 | promise(); | |
| 1447 | _LIBCPP_HIDE_FROM_ABI promise(); | |
| 1437 | 1448 | template <class _Allocator> |
| 1438 | promise(allocator_arg_t, const _Allocator& __a); | |
| 1449 | _LIBCPP_HIDE_FROM_ABI promise(allocator_arg_t, const _Allocator& __a); | |
| 1439 | 1450 | _LIBCPP_INLINE_VISIBILITY |
| 1440 | 1451 | promise(promise&& __rhs) _NOEXCEPT |
| 1441 | 1452 | : __state_(__rhs.__state_) {__rhs.__state_ = nullptr;} |
| 1442 | 1453 | promise(const promise& __rhs) = delete; |
| 1443 | ~promise(); | |
| 1454 | _LIBCPP_HIDE_FROM_ABI ~promise(); | |
| 1444 | 1455 | |
| 1445 | 1456 | // assignment |
| 1446 | 1457 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1455,15 +1466,15 @@ public: |
| 1455 | 1466 | void swap(promise& __rhs) _NOEXCEPT {_VSTD::swap(__state_, __rhs.__state_);} |
| 1456 | 1467 | |
| 1457 | 1468 | // retrieving the result |
| 1458 | future<_Rp&> get_future(); | |
| 1469 | _LIBCPP_HIDE_FROM_ABI future<_Rp&> get_future(); | |
| 1459 | 1470 | |
| 1460 | 1471 | // setting the result |
| 1461 | void set_value(_Rp& __r); | |
| 1462 | void set_exception(exception_ptr __p); | |
| 1472 | _LIBCPP_HIDE_FROM_ABI void set_value(_Rp& __r); | |
| 1473 | _LIBCPP_HIDE_FROM_ABI void set_exception(exception_ptr __p); | |
| 1463 | 1474 | |
| 1464 | 1475 | // setting the result with deferred notification |
| 1465 | void set_value_at_thread_exit(_Rp&); | |
| 1466 | void set_exception_at_thread_exit(exception_ptr __p); | |
| 1476 | _LIBCPP_HIDE_FROM_ABI void set_value_at_thread_exit(_Rp&); | |
| 1477 | _LIBCPP_HIDE_FROM_ABI void set_exception_at_thread_exit(exception_ptr __p); | |
| 1467 | 1478 | }; |
| 1468 | 1479 | |
| 1469 | 1480 | template <class _Rp> |
| ... | ... | @@ -1520,7 +1531,7 @@ template <class _Rp> |
| 1520 | 1531 | void |
| 1521 | 1532 | promise<_Rp&>::set_exception(exception_ptr __p) |
| 1522 | 1533 | { |
| 1523 | _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception: received nullptr" ); | |
| 1534 | _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception: received nullptr" ); | |
| 1524 | 1535 | if (__state_ == nullptr) |
| 1525 | 1536 | __throw_future_error(future_errc::no_state); |
| 1526 | 1537 | __state_->set_exception(__p); |
| ... | ... | @@ -1539,7 +1550,7 @@ template <class _Rp> |
| 1539 | 1550 | void |
| 1540 | 1551 | promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) |
| 1541 | 1552 | { |
| 1542 | _LIBCPP_ASSERT( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); | |
| 1553 | _LIBCPP_ASSERT_UNCATEGORIZED( __p != nullptr, "promise::set_exception_at_thread_exit: received nullptr" ); | |
| 1543 | 1554 | if (__state_ == nullptr) |
| 1544 | 1555 | __throw_future_error(future_errc::no_state); |
| 1545 | 1556 | __state_->set_exception_at_thread_exit(__p); |
| ... | ... | @@ -1548,7 +1559,7 @@ promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p) |
| 1548 | 1559 | // promise<void> |
| 1549 | 1560 | |
| 1550 | 1561 | template <> |
| 1551 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void> | |
| 1562 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE promise<void> | |
| 1552 | 1563 | { |
| 1553 | 1564 | __assoc_sub_state* __state_; |
| 1554 | 1565 | |
| ... | ... | @@ -1654,10 +1665,10 @@ public: |
| 1654 | 1665 | _LIBCPP_INLINE_VISIBILITY |
| 1655 | 1666 | __packaged_task_func(_Fp&& __f, const _Alloc& __a) |
| 1656 | 1667 | : __f_(_VSTD::move(__f), __a) {} |
| 1657 | virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; | |
| 1658 | virtual void destroy(); | |
| 1659 | virtual void destroy_deallocate(); | |
| 1660 | virtual _Rp operator()(_ArgTypes&& ... __args); | |
| 1668 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __move_to(__packaged_task_base<_Rp(_ArgTypes...)>*) _NOEXCEPT; | |
| 1669 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy(); | |
| 1670 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate(); | |
| 1671 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&& ... __args); | |
| 1661 | 1672 | }; |
| 1662 | 1673 | |
| 1663 | 1674 | template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes> |
| ... | ... | @@ -1716,22 +1727,22 @@ public: |
| 1716 | 1727 | _LIBCPP_INLINE_VISIBILITY |
| 1717 | 1728 | __packaged_task_function() _NOEXCEPT : __f_(nullptr) {} |
| 1718 | 1729 | template<class _Fp> |
| 1719 | __packaged_task_function(_Fp&& __f); | |
| 1730 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f); | |
| 1720 | 1731 | template<class _Fp, class _Alloc> |
| 1721 | __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); | |
| 1732 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f); | |
| 1722 | 1733 | |
| 1723 | __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; | |
| 1724 | __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; | |
| 1734 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT; | |
| 1735 | _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT; | |
| 1725 | 1736 | |
| 1726 | 1737 | __packaged_task_function(const __packaged_task_function&) = delete; |
| 1727 | 1738 | __packaged_task_function& operator=(const __packaged_task_function&) = delete; |
| 1728 | 1739 | |
| 1729 | ~__packaged_task_function(); | |
| 1740 | _LIBCPP_HIDE_FROM_ABI ~__packaged_task_function(); | |
| 1730 | 1741 | |
| 1731 | void swap(__packaged_task_function&) _NOEXCEPT; | |
| 1742 | _LIBCPP_HIDE_FROM_ABI void swap(__packaged_task_function&) _NOEXCEPT; | |
| 1732 | 1743 | |
| 1733 | 1744 | _LIBCPP_INLINE_VISIBILITY |
| 1734 | _Rp operator()(_ArgTypes...) const; | |
| 1745 | _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; | |
| 1735 | 1746 | }; |
| 1736 | 1747 | |
| 1737 | 1748 | template<class _Rp, class ..._ArgTypes> |
| ... | ... | @@ -1756,7 +1767,7 @@ template <class _Fp> |
| 1756 | 1767 | __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f) |
| 1757 | 1768 | : __f_(nullptr) |
| 1758 | 1769 | { |
| 1759 | typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR; | |
| 1770 | typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; | |
| 1760 | 1771 | typedef __packaged_task_func<_FR, allocator<_FR>, _Rp(_ArgTypes...)> _FF; |
| 1761 | 1772 | if (sizeof(_FF) <= sizeof(__buf_)) |
| 1762 | 1773 | { |
| ... | ... | @@ -1780,7 +1791,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function( |
| 1780 | 1791 | allocator_arg_t, const _Alloc& __a0, _Fp&& __f) |
| 1781 | 1792 | : __f_(nullptr) |
| 1782 | 1793 | { |
| 1783 | typedef __libcpp_remove_reference_t<typename decay<_Fp>::type> _FR; | |
| 1794 | typedef __libcpp_remove_reference_t<__decay_t<_Fp> > _FR; | |
| 1784 | 1795 | typedef __packaged_task_func<_FR, _Alloc, _Rp(_ArgTypes...)> _FF; |
| 1785 | 1796 | if (sizeof(_FF) <= sizeof(__buf_)) |
| 1786 | 1797 | { |
| ... | ... | @@ -1902,8 +1913,8 @@ public: |
| 1902 | 1913 | class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> > |
| 1903 | 1914 | _LIBCPP_INLINE_VISIBILITY |
| 1904 | 1915 | packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
| 1905 | : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), | |
| 1906 | __p_(allocator_arg, __a) {} | |
| 1916 | : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)), | |
| 1917 | __p_(allocator_arg_t(), __a) {} | |
| 1907 | 1918 | // ~packaged_task() = default; |
| 1908 | 1919 | |
| 1909 | 1920 | // no copy |
| ... | ... | @@ -1936,10 +1947,10 @@ public: |
| 1936 | 1947 | future<result_type> get_future() {return __p_.get_future();} |
| 1937 | 1948 | |
| 1938 | 1949 | // execution |
| 1939 | void operator()(_ArgTypes... __args); | |
| 1940 | void make_ready_at_thread_exit(_ArgTypes... __args); | |
| 1950 | _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); | |
| 1951 | _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); | |
| 1941 | 1952 | |
| 1942 | void reset(); | |
| 1953 | _LIBCPP_HIDE_FROM_ABI void reset(); | |
| 1943 | 1954 | }; |
| 1944 | 1955 | |
| 1945 | 1956 | template<class _Rp, class ..._ArgTypes> |
| ... | ... | @@ -1950,18 +1961,18 @@ packaged_task<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __args) |
| 1950 | 1961 | __throw_future_error(future_errc::no_state); |
| 1951 | 1962 | if (__p_.__state_->__has_value()) |
| 1952 | 1963 | __throw_future_error(future_errc::promise_already_satisfied); |
| 1953 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1964 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1954 | 1965 | try |
| 1955 | 1966 | { |
| 1956 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1967 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1957 | 1968 | __p_.set_value(__f_(_VSTD::forward<_ArgTypes>(__args)...)); |
| 1958 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1969 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1959 | 1970 | } |
| 1960 | 1971 | catch (...) |
| 1961 | 1972 | { |
| 1962 | 1973 | __p_.set_exception(current_exception()); |
| 1963 | 1974 | } |
| 1964 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1975 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1965 | 1976 | } |
| 1966 | 1977 | |
| 1967 | 1978 | template<class _Rp, class ..._ArgTypes> |
| ... | ... | @@ -1972,18 +1983,18 @@ packaged_task<_Rp(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args) |
| 1972 | 1983 | __throw_future_error(future_errc::no_state); |
| 1973 | 1984 | if (__p_.__state_->__has_value()) |
| 1974 | 1985 | __throw_future_error(future_errc::promise_already_satisfied); |
| 1975 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1986 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1976 | 1987 | try |
| 1977 | 1988 | { |
| 1978 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1989 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1979 | 1990 | __p_.set_value_at_thread_exit(__f_(_VSTD::forward<_ArgTypes>(__args)...)); |
| 1980 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1991 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1981 | 1992 | } |
| 1982 | 1993 | catch (...) |
| 1983 | 1994 | { |
| 1984 | 1995 | __p_.set_exception_at_thread_exit(current_exception()); |
| 1985 | 1996 | } |
| 1986 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1997 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1987 | 1998 | } |
| 1988 | 1999 | |
| 1989 | 2000 | template<class _Rp, class ..._ArgTypes> |
| ... | ... | @@ -2017,8 +2028,8 @@ public: |
| 2017 | 2028 | class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value> > |
| 2018 | 2029 | _LIBCPP_INLINE_VISIBILITY |
| 2019 | 2030 | packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f) |
| 2020 | : __f_(allocator_arg, __a, _VSTD::forward<_Fp>(__f)), | |
| 2021 | __p_(allocator_arg, __a) {} | |
| 2031 | : __f_(allocator_arg_t(), __a, _VSTD::forward<_Fp>(__f)), | |
| 2032 | __p_(allocator_arg_t(), __a) {} | |
| 2022 | 2033 | // ~packaged_task() = default; |
| 2023 | 2034 | |
| 2024 | 2035 | // no copy |
| ... | ... | @@ -2051,10 +2062,10 @@ public: |
| 2051 | 2062 | future<result_type> get_future() {return __p_.get_future();} |
| 2052 | 2063 | |
| 2053 | 2064 | // execution |
| 2054 | void operator()(_ArgTypes... __args); | |
| 2055 | void make_ready_at_thread_exit(_ArgTypes... __args); | |
| 2065 | _LIBCPP_HIDE_FROM_ABI void operator()(_ArgTypes... __args); | |
| 2066 | _LIBCPP_HIDE_FROM_ABI void make_ready_at_thread_exit(_ArgTypes... __args); | |
| 2056 | 2067 | |
| 2057 | void reset(); | |
| 2068 | _LIBCPP_HIDE_FROM_ABI void reset(); | |
| 2058 | 2069 | }; |
| 2059 | 2070 | |
| 2060 | 2071 | #if _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -2075,19 +2086,19 @@ packaged_task<void(_ArgTypes...)>::operator()(_ArgTypes... __args) |
| 2075 | 2086 | __throw_future_error(future_errc::no_state); |
| 2076 | 2087 | if (__p_.__state_->__has_value()) |
| 2077 | 2088 | __throw_future_error(future_errc::promise_already_satisfied); |
| 2078 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2089 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2079 | 2090 | try |
| 2080 | 2091 | { |
| 2081 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2092 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2082 | 2093 | __f_(_VSTD::forward<_ArgTypes>(__args)...); |
| 2083 | 2094 | __p_.set_value(); |
| 2084 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2095 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2085 | 2096 | } |
| 2086 | 2097 | catch (...) |
| 2087 | 2098 | { |
| 2088 | 2099 | __p_.set_exception(current_exception()); |
| 2089 | 2100 | } |
| 2090 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2101 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2091 | 2102 | } |
| 2092 | 2103 | |
| 2093 | 2104 | template<class ..._ArgTypes> |
| ... | ... | @@ -2098,19 +2109,19 @@ packaged_task<void(_ArgTypes...)>::make_ready_at_thread_exit(_ArgTypes... __args |
| 2098 | 2109 | __throw_future_error(future_errc::no_state); |
| 2099 | 2110 | if (__p_.__state_->__has_value()) |
| 2100 | 2111 | __throw_future_error(future_errc::promise_already_satisfied); |
| 2101 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2112 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2102 | 2113 | try |
| 2103 | 2114 | { |
| 2104 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2115 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2105 | 2116 | __f_(_VSTD::forward<_ArgTypes>(__args)...); |
| 2106 | 2117 | __p_.set_value_at_thread_exit(); |
| 2107 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2118 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2108 | 2119 | } |
| 2109 | 2120 | catch (...) |
| 2110 | 2121 | { |
| 2111 | 2122 | __p_.set_exception_at_thread_exit(current_exception()); |
| 2112 | 2123 | } |
| 2113 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2124 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2114 | 2125 | } |
| 2115 | 2126 | |
| 2116 | 2127 | template<class ..._ArgTypes> |
| ... | ... | @@ -2170,14 +2181,14 @@ public: |
| 2170 | 2181 | _LIBCPP_INLINE_VISIBILITY |
| 2171 | 2182 | __async_func(__async_func&& __f) : __f_(_VSTD::move(__f.__f_)) {} |
| 2172 | 2183 | |
| 2173 | _Rp operator()() | |
| 2184 | _LIBCPP_HIDE_FROM_ABI _Rp operator()() | |
| 2174 | 2185 | { |
| 2175 | 2186 | typedef typename __make_tuple_indices<1+sizeof...(_Args), 1>::type _Index; |
| 2176 | 2187 | return __execute(_Index()); |
| 2177 | 2188 | } |
| 2178 | 2189 | private: |
| 2179 | 2190 | template <size_t ..._Indices> |
| 2180 | _Rp | |
| 2191 | _LIBCPP_HIDE_FROM_ABI _Rp | |
| 2181 | 2192 | __execute(__tuple_indices<_Indices...>) |
| 2182 | 2193 | { |
| 2183 | 2194 | return _VSTD::__invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); |
| ... | ... | @@ -2189,20 +2200,20 @@ inline _LIBCPP_INLINE_VISIBILITY bool __does_policy_contain(launch __policy, lau |
| 2189 | 2200 | |
| 2190 | 2201 | template <class _Fp, class... _Args> |
| 2191 | 2202 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI |
| 2192 | future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> | |
| 2203 | future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type> | |
| 2193 | 2204 | async(launch __policy, _Fp&& __f, _Args&&... __args) |
| 2194 | 2205 | { |
| 2195 | typedef __async_func<typename decay<_Fp>::type, typename decay<_Args>::type...> _BF; | |
| 2206 | typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF; | |
| 2196 | 2207 | typedef typename _BF::_Rp _Rp; |
| 2197 | 2208 | |
| 2198 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2209 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2199 | 2210 | try |
| 2200 | 2211 | { |
| 2201 | 2212 | #endif |
| 2202 | 2213 | if (__does_policy_contain(__policy, launch::async)) |
| 2203 | 2214 | return _VSTD::__make_async_assoc_state<_Rp>(_BF(_LIBCPP_AUTO_CAST(_VSTD::forward<_Fp>(__f)), |
| 2204 | 2215 | _LIBCPP_AUTO_CAST(_VSTD::forward<_Args>(__args))...)); |
| 2205 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2216 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2206 | 2217 | } |
| 2207 | 2218 | catch ( ... ) { if (__policy == launch::async) throw ; } |
| 2208 | 2219 | #endif |
| ... | ... | @@ -2215,7 +2226,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args) |
| 2215 | 2226 | |
| 2216 | 2227 | template <class _Fp, class... _Args> |
| 2217 | 2228 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY |
| 2218 | future<typename __invoke_of<typename decay<_Fp>::type, typename decay<_Args>::type...>::type> | |
| 2229 | future<typename __invoke_of<__decay_t<_Fp>, __decay_t<_Args>...>::type> | |
| 2219 | 2230 | async(_Fp&& __f, _Args&&... __args) |
| 2220 | 2231 | { |
| 2221 | 2232 | return _VSTD::async(launch::any, _VSTD::forward<_Fp>(__f), |
| ... | ... | @@ -2243,8 +2254,8 @@ public: |
| 2243 | 2254 | _LIBCPP_INLINE_VISIBILITY |
| 2244 | 2255 | shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) |
| 2245 | 2256 | {__rhs.__state_ = nullptr;} |
| 2246 | ~shared_future(); | |
| 2247 | shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; | |
| 2257 | _LIBCPP_HIDE_FROM_ABI ~shared_future(); | |
| 2258 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs) _NOEXCEPT; | |
| 2248 | 2259 | _LIBCPP_INLINE_VISIBILITY |
| 2249 | 2260 | shared_future& operator=(shared_future&& __rhs) _NOEXCEPT |
| 2250 | 2261 | { |
| ... | ... | @@ -2313,8 +2324,8 @@ public: |
| 2313 | 2324 | _LIBCPP_INLINE_VISIBILITY |
| 2314 | 2325 | shared_future(shared_future&& __rhs) _NOEXCEPT : __state_(__rhs.__state_) |
| 2315 | 2326 | {__rhs.__state_ = nullptr;} |
| 2316 | ~shared_future(); | |
| 2317 | shared_future& operator=(const shared_future& __rhs); | |
| 2327 | _LIBCPP_HIDE_FROM_ABI ~shared_future(); | |
| 2328 | _LIBCPP_HIDE_FROM_ABI shared_future& operator=(const shared_future& __rhs); | |
| 2318 | 2329 | _LIBCPP_INLINE_VISIBILITY |
| 2319 | 2330 | shared_future& operator=(shared_future&& __rhs) _NOEXCEPT |
| 2320 | 2331 | { |
| ... | ... | @@ -2367,7 +2378,7 @@ shared_future<_Rp&>::operator=(const shared_future& __rhs) |
| 2367 | 2378 | } |
| 2368 | 2379 | |
| 2369 | 2380 | template <> |
| 2370 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void> | |
| 2381 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_FUTURE shared_future<void> | |
| 2371 | 2382 | { |
| 2372 | 2383 | __assoc_sub_state* __state_; |
| 2373 | 2384 | |
| ... | ... | @@ -2454,4 +2465,11 @@ _LIBCPP_END_NAMESPACE_STD |
| 2454 | 2465 | # include <chrono> |
| 2455 | 2466 | #endif |
| 2456 | 2467 | |
| 2468 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 2469 | # include <atomic> | |
| 2470 | # include <cstdlib> | |
| 2471 | # include <exception> | |
| 2472 | # include <system_error> | |
| 2473 | #endif | |
| 2474 | ||
| 2457 | 2475 | #endif // _LIBCPP_FUTURE |
lib/libcxx/include/iomanip+18-22| ... | ... | @@ -301,10 +301,10 @@ template <class _CharT, class _Traits, class _MoneyT> |
| 301 | 301 | _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& |
| 302 | 302 | operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) |
| 303 | 303 | { |
| 304 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 304 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 305 | 305 | try |
| 306 | 306 | { |
| 307 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 307 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 308 | 308 | typename basic_istream<_CharT, _Traits>::sentry __s(__is); |
| 309 | 309 | if (__s) |
| 310 | 310 | { |
| ... | ... | @@ -315,13 +315,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x) |
| 315 | 315 | __mf.get(_Ip(__is), _Ip(), __x.__intl_, __is, __err, __x.__mon_); |
| 316 | 316 | __is.setstate(__err); |
| 317 | 317 | } |
| 318 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 318 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 319 | 319 | } |
| 320 | 320 | catch (...) |
| 321 | 321 | { |
| 322 | 322 | __is.__set_badbit_and_consider_rethrow(); |
| 323 | 323 | } |
| 324 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 324 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 325 | 325 | return __is; |
| 326 | 326 | } |
| 327 | 327 | |
| ... | ... | @@ -361,10 +361,10 @@ template <class _CharT, class _Traits, class _MoneyT> |
| 361 | 361 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 362 | 362 | operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) |
| 363 | 363 | { |
| 364 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 364 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 365 | 365 | try |
| 366 | 366 | { |
| 367 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 367 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 368 | 368 | typename basic_ostream<_CharT, _Traits>::sentry __s(__os); |
| 369 | 369 | if (__s) |
| 370 | 370 | { |
| ... | ... | @@ -374,13 +374,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t8<_MoneyT>& __x) |
| 374 | 374 | if (__mf.put(_Op(__os), __x.__intl_, __os, __os.fill(), __x.__mon_).failed()) |
| 375 | 375 | __os.setstate(ios_base::badbit); |
| 376 | 376 | } |
| 377 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 377 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 378 | 378 | } |
| 379 | 379 | catch (...) |
| 380 | 380 | { |
| 381 | 381 | __os.__set_badbit_and_consider_rethrow(); |
| 382 | 382 | } |
| 383 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 383 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 384 | 384 | return __os; |
| 385 | 385 | } |
| 386 | 386 | |
| ... | ... | @@ -420,10 +420,10 @@ template <class _CharT, class _Traits> |
| 420 | 420 | _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& |
| 421 | 421 | operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) |
| 422 | 422 | { |
| 423 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 423 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 424 | 424 | try |
| 425 | 425 | { |
| 426 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 426 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 427 | 427 | typename basic_istream<_CharT, _Traits>::sentry __s(__is); |
| 428 | 428 | if (__s) |
| 429 | 429 | { |
| ... | ... | @@ -435,13 +435,13 @@ operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t9<_CharT>& __x) |
| 435 | 435 | __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)); |
| 436 | 436 | __is.setstate(__err); |
| 437 | 437 | } |
| 438 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 438 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 439 | 439 | } |
| 440 | 440 | catch (...) |
| 441 | 441 | { |
| 442 | 442 | __is.__set_badbit_and_consider_rethrow(); |
| 443 | 443 | } |
| 444 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 444 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 445 | 445 | return __is; |
| 446 | 446 | } |
| 447 | 447 | |
| ... | ... | @@ -481,10 +481,10 @@ template <class _CharT, class _Traits> |
| 481 | 481 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 482 | 482 | operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) |
| 483 | 483 | { |
| 484 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 484 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 485 | 485 | try |
| 486 | 486 | { |
| 487 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 487 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 488 | 488 | typename basic_ostream<_CharT, _Traits>::sentry __s(__os); |
| 489 | 489 | if (__s) |
| 490 | 490 | { |
| ... | ... | @@ -495,13 +495,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const __iom_t10<_CharT>& __x) |
| 495 | 495 | __x.__fmt_, __x.__fmt_ + _Traits::length(__x.__fmt_)).failed()) |
| 496 | 496 | __os.setstate(ios_base::badbit); |
| 497 | 497 | } |
| 498 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 498 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 499 | 499 | } |
| 500 | 500 | catch (...) |
| 501 | 501 | { |
| 502 | 502 | __os.__set_badbit_and_consider_rethrow(); |
| 503 | 503 | } |
| 504 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 504 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 505 | 505 | return __os; |
| 506 | 506 | } |
| 507 | 507 | |
| ... | ... | @@ -513,8 +513,6 @@ put_time(const tm* __tm, const _CharT* __fmt) |
| 513 | 513 | return __iom_t10<_CharT>(__tm, __fmt); |
| 514 | 514 | } |
| 515 | 515 | |
| 516 | #if _LIBCPP_STD_VER >= 11 | |
| 517 | ||
| 518 | 516 | template <class _CharT, class _Traits> |
| 519 | 517 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 520 | 518 | __quoted_output(basic_ostream<_CharT, _Traits>& __os, |
| ... | ... | @@ -622,9 +620,7 @@ __quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT |
| 622 | 620 | return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape); |
| 623 | 621 | } |
| 624 | 622 | |
| 625 | #endif // _LIBCPP_STD_VER >= 11 | |
| 626 | ||
| 627 | #if _LIBCPP_STD_VER > 11 | |
| 623 | #if _LIBCPP_STD_VER >= 14 | |
| 628 | 624 | |
| 629 | 625 | template <class _CharT> |
| 630 | 626 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -656,7 +652,7 @@ auto quoted(basic_string_view<_CharT, _Traits> __sv, _CharT __delim = _CharT('"' |
| 656 | 652 | return __quoted_output_proxy<_CharT, _Traits>(__sv.data(), __sv.data() + __sv.size(), __delim, __escape); |
| 657 | 653 | } |
| 658 | 654 | |
| 659 | #endif // _LIBCPP_STD_VER > 11 | |
| 655 | #endif // _LIBCPP_STD_VER >= 14 | |
| 660 | 656 | |
| 661 | 657 | _LIBCPP_END_NAMESPACE_STD |
| 662 | 658 |
lib/libcxx/include/ios+24-13| ... | ... | @@ -217,10 +217,15 @@ storage-class-specifier const error_category& iostream_category() noexcept; |
| 217 | 217 | #endif |
| 218 | 218 | |
| 219 | 219 | #include <__assert> // all public C++ headers provide the assertion handler |
| 220 | #include <__fwd/ios.h> | |
| 220 | 221 | #include <__ios/fpos.h> |
| 221 | 222 | #include <__locale> |
| 223 | #include <__system_error/error_category.h> | |
| 224 | #include <__system_error/error_code.h> | |
| 225 | #include <__system_error/error_condition.h> | |
| 226 | #include <__system_error/system_error.h> | |
| 222 | 227 | #include <__utility/swap.h> |
| 223 | #include <system_error> | |
| 228 | #include <__verbose_abort> | |
| 224 | 229 | #include <version> |
| 225 | 230 | |
| 226 | 231 | // standard-mandated includes |
| ... | ... | @@ -229,7 +234,7 @@ storage-class-specifier const error_category& iostream_category() noexcept; |
| 229 | 234 | #include <iosfwd> |
| 230 | 235 | |
| 231 | 236 | #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
| 232 | #include <atomic> // for __xindex_ | |
| 237 | # include <__atomic/atomic.h> // for __xindex_ | |
| 233 | 238 | #endif |
| 234 | 239 | |
| 235 | 240 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -240,10 +245,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 240 | 245 | |
| 241 | 246 | typedef ptrdiff_t streamsize; |
| 242 | 247 | |
| 243 | class _LIBCPP_TYPE_VIS ios_base | |
| 248 | class _LIBCPP_EXPORTED_FROM_ABI ios_base | |
| 244 | 249 | { |
| 245 | 250 | public: |
| 246 | class _LIBCPP_EXCEPTION_ABI failure; | |
| 251 | class _LIBCPP_EXPORTED_FROM_ABI failure; | |
| 247 | 252 | |
| 248 | 253 | typedef unsigned int fmtflags; |
| 249 | 254 | static const fmtflags boolalpha = 0x0001; |
| ... | ... | @@ -290,7 +295,7 @@ public: |
| 290 | 295 | typedef _VSTD::streampos streampos; |
| 291 | 296 | #endif |
| 292 | 297 | |
| 293 | class _LIBCPP_TYPE_VIS Init; | |
| 298 | class _LIBCPP_EXPORTED_FROM_ABI Init; | |
| 294 | 299 | |
| 295 | 300 | // 27.5.2.2 fmtflags state: |
| 296 | 301 | _LIBCPP_INLINE_VISIBILITY fmtflags flags() const; |
| ... | ... | @@ -419,8 +424,7 @@ template <> |
| 419 | 424 | struct _LIBCPP_TEMPLATE_VIS is_error_code_enum<io_errc::__lx> : public true_type { }; |
| 420 | 425 | #endif |
| 421 | 426 | |
| 422 | _LIBCPP_FUNC_VIS | |
| 423 | const error_category& iostream_category() _NOEXCEPT; | |
| 427 | _LIBCPP_EXPORTED_FROM_ABI const error_category& iostream_category() _NOEXCEPT; | |
| 424 | 428 | |
| 425 | 429 | inline _LIBCPP_INLINE_VISIBILITY |
| 426 | 430 | error_code |
| ... | ... | @@ -436,27 +440,26 @@ make_error_condition(io_errc __e) _NOEXCEPT |
| 436 | 440 | return error_condition(static_cast<int>(__e), iostream_category()); |
| 437 | 441 | } |
| 438 | 442 | |
| 439 | class _LIBCPP_EXCEPTION_ABI ios_base::failure | |
| 443 | class _LIBCPP_EXPORTED_FROM_ABI ios_base::failure | |
| 440 | 444 | : public system_error |
| 441 | 445 | { |
| 442 | 446 | public: |
| 443 | 447 | explicit failure(const string& __msg, const error_code& __ec = io_errc::stream); |
| 444 | 448 | explicit failure(const char* __msg, const error_code& __ec = io_errc::stream); |
| 445 | failure(const failure&) _NOEXCEPT = default; | |
| 449 | _LIBCPP_HIDE_FROM_ABI failure(const failure&) _NOEXCEPT = default; | |
| 446 | 450 | ~failure() _NOEXCEPT override; |
| 447 | 451 | }; |
| 448 | 452 | |
| 449 | 453 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 450 | 454 | void __throw_failure(char const* __msg) { |
| 451 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 455 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 452 | 456 | throw ios_base::failure(__msg); |
| 453 | 457 | #else |
| 454 | ((void)__msg); | |
| 455 | _VSTD::abort(); | |
| 458 | _LIBCPP_VERBOSE_ABORT("ios_base::failure was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 456 | 459 | #endif |
| 457 | 460 | } |
| 458 | 461 | |
| 459 | class _LIBCPP_TYPE_VIS ios_base::Init | |
| 462 | class _LIBCPP_EXPORTED_FROM_ABI ios_base::Init | |
| 460 | 463 | { |
| 461 | 464 | public: |
| 462 | 465 | Init(); |
| ... | ... | @@ -844,6 +847,12 @@ basic_ios<_CharT, _Traits>::set_rdbuf(basic_streambuf<char_type, traits_type>* _ |
| 844 | 847 | ios_base::set_rdbuf(__sb); |
| 845 | 848 | } |
| 846 | 849 | |
| 850 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>; | |
| 851 | ||
| 852 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 853 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>; | |
| 854 | #endif | |
| 855 | ||
| 847 | 856 | _LIBCPP_HIDE_FROM_ABI inline |
| 848 | 857 | ios_base& |
| 849 | 858 | boolalpha(ios_base& __str) |
| ... | ... | @@ -1039,6 +1048,7 @@ defaultfloat(ios_base& __str) |
| 1039 | 1048 | _LIBCPP_END_NAMESPACE_STD |
| 1040 | 1049 | |
| 1041 | 1050 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1051 | # include <atomic> | |
| 1042 | 1052 | # include <concepts> |
| 1043 | 1053 | # include <cstddef> |
| 1044 | 1054 | # include <cstdlib> |
| ... | ... | @@ -1047,6 +1057,7 @@ _LIBCPP_END_NAMESPACE_STD |
| 1047 | 1057 | # include <limits> |
| 1048 | 1058 | # include <new> |
| 1049 | 1059 | # include <stdexcept> |
| 1060 | # include <system_error> | |
| 1050 | 1061 | # include <type_traits> |
| 1051 | 1062 | # include <typeinfo> |
| 1052 | 1063 | #endif |
lib/libcxx/include/iosfwd+8-110| ... | ... | @@ -96,8 +96,14 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>; |
| 96 | 96 | |
| 97 | 97 | #include <__assert> // all public C++ headers provide the assertion handler |
| 98 | 98 | #include <__config> |
| 99 | #include <__fwd/fstream.h> | |
| 100 | #include <__fwd/ios.h> | |
| 101 | #include <__fwd/istream.h> | |
| 102 | #include <__fwd/ostream.h> | |
| 103 | #include <__fwd/sstream.h> | |
| 104 | #include <__fwd/streambuf.h> | |
| 99 | 105 | #include <__fwd/string.h> |
| 100 | #include <__mbstate_t.h> | |
| 106 | #include <__std_mbstate_t.h> | |
| 101 | 107 | #include <version> |
| 102 | 108 | |
| 103 | 109 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -106,114 +112,13 @@ using u32streampos = fpos<char_traits<char32_t>::state_type>; |
| 106 | 112 | |
| 107 | 113 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 108 | 114 | |
| 109 | class _LIBCPP_TYPE_VIS ios_base; | |
| 110 | ||
| 111 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 112 | class _LIBCPP_TEMPLATE_VIS basic_ios; | |
| 113 | ||
| 114 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 115 | class _LIBCPP_TEMPLATE_VIS basic_streambuf; | |
| 116 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 117 | class _LIBCPP_TEMPLATE_VIS basic_istream; | |
| 118 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 119 | class _LIBCPP_TEMPLATE_VIS basic_ostream; | |
| 120 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 121 | class _LIBCPP_TEMPLATE_VIS basic_iostream; | |
| 122 | ||
| 123 | template <class _CharT, class _Traits = char_traits<_CharT>, | |
| 124 | class _Allocator = allocator<_CharT> > | |
| 125 | class _LIBCPP_TEMPLATE_VIS basic_stringbuf; | |
| 126 | template <class _CharT, class _Traits = char_traits<_CharT>, | |
| 127 | class _Allocator = allocator<_CharT> > | |
| 128 | class _LIBCPP_TEMPLATE_VIS basic_istringstream; | |
| 129 | template <class _CharT, class _Traits = char_traits<_CharT>, | |
| 130 | class _Allocator = allocator<_CharT> > | |
| 131 | class _LIBCPP_TEMPLATE_VIS basic_ostringstream; | |
| 132 | template <class _CharT, class _Traits = char_traits<_CharT>, | |
| 133 | class _Allocator = allocator<_CharT> > | |
| 134 | class _LIBCPP_TEMPLATE_VIS basic_stringstream; | |
| 135 | ||
| 136 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 137 | class _LIBCPP_TEMPLATE_VIS basic_filebuf; | |
| 138 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 139 | class _LIBCPP_TEMPLATE_VIS basic_ifstream; | |
| 140 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 141 | class _LIBCPP_TEMPLATE_VIS basic_ofstream; | |
| 142 | template <class _CharT, class _Traits = char_traits<_CharT> > | |
| 143 | class _LIBCPP_TEMPLATE_VIS basic_fstream; | |
| 115 | class _LIBCPP_EXPORTED_FROM_ABI ios_base; | |
| 144 | 116 | |
| 145 | 117 | template <class _CharT, class _Traits = char_traits<_CharT> > |
| 146 | 118 | class _LIBCPP_TEMPLATE_VIS istreambuf_iterator; |
| 147 | 119 | template <class _CharT, class _Traits = char_traits<_CharT> > |
| 148 | 120 | class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator; |
| 149 | 121 | |
| 150 | typedef basic_ios<char> ios; | |
| 151 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 152 | typedef basic_ios<wchar_t> wios; | |
| 153 | #endif | |
| 154 | ||
| 155 | typedef basic_streambuf<char> streambuf; | |
| 156 | typedef basic_istream<char> istream; | |
| 157 | typedef basic_ostream<char> ostream; | |
| 158 | typedef basic_iostream<char> iostream; | |
| 159 | ||
| 160 | typedef basic_stringbuf<char> stringbuf; | |
| 161 | typedef basic_istringstream<char> istringstream; | |
| 162 | typedef basic_ostringstream<char> ostringstream; | |
| 163 | typedef basic_stringstream<char> stringstream; | |
| 164 | ||
| 165 | typedef basic_filebuf<char> filebuf; | |
| 166 | typedef basic_ifstream<char> ifstream; | |
| 167 | typedef basic_ofstream<char> ofstream; | |
| 168 | typedef basic_fstream<char> fstream; | |
| 169 | ||
| 170 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 171 | typedef basic_streambuf<wchar_t> wstreambuf; | |
| 172 | typedef basic_istream<wchar_t> wistream; | |
| 173 | typedef basic_ostream<wchar_t> wostream; | |
| 174 | typedef basic_iostream<wchar_t> wiostream; | |
| 175 | ||
| 176 | typedef basic_stringbuf<wchar_t> wstringbuf; | |
| 177 | typedef basic_istringstream<wchar_t> wistringstream; | |
| 178 | typedef basic_ostringstream<wchar_t> wostringstream; | |
| 179 | typedef basic_stringstream<wchar_t> wstringstream; | |
| 180 | ||
| 181 | typedef basic_filebuf<wchar_t> wfilebuf; | |
| 182 | typedef basic_ifstream<wchar_t> wifstream; | |
| 183 | typedef basic_ofstream<wchar_t> wofstream; | |
| 184 | typedef basic_fstream<wchar_t> wfstream; | |
| 185 | #endif | |
| 186 | ||
| 187 | template <class _CharT, class _Traits> | |
| 188 | class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wios)) basic_ios; | |
| 189 | ||
| 190 | template <class _CharT, class _Traits> | |
| 191 | class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstreambuf)) basic_streambuf; | |
| 192 | template <class _CharT, class _Traits> | |
| 193 | class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistream)) basic_istream; | |
| 194 | template <class _CharT, class _Traits> | |
| 195 | class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostream)) basic_ostream; | |
| 196 | template <class _CharT, class _Traits> | |
| 197 | class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wiostream)) basic_iostream; | |
| 198 | ||
| 199 | template <class _CharT, class _Traits, class _Allocator> | |
| 200 | class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringbuf)) basic_stringbuf; | |
| 201 | template <class _CharT, class _Traits, class _Allocator> | |
| 202 | class _LIBCPP_PREFERRED_NAME(istringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wistringstream)) basic_istringstream; | |
| 203 | template <class _CharT, class _Traits, class _Allocator> | |
| 204 | class _LIBCPP_PREFERRED_NAME(ostringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wostringstream)) basic_ostringstream; | |
| 205 | template <class _CharT, class _Traits, class _Allocator> | |
| 206 | class _LIBCPP_PREFERRED_NAME(stringstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wstringstream)) basic_stringstream; | |
| 207 | ||
| 208 | template <class _CharT, class _Traits> | |
| 209 | class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfilebuf)) basic_filebuf; | |
| 210 | template <class _CharT, class _Traits> | |
| 211 | class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wifstream)) basic_ifstream; | |
| 212 | template <class _CharT, class _Traits> | |
| 213 | class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wofstream)) basic_ofstream; | |
| 214 | template <class _CharT, class _Traits> | |
| 215 | class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wfstream)) basic_fstream; | |
| 216 | ||
| 217 | 122 | template <class _State> class _LIBCPP_TEMPLATE_VIS fpos; |
| 218 | 123 | typedef fpos<mbstate_t> streampos; |
| 219 | 124 | typedef fpos<mbstate_t> wstreampos; |
| ... | ... | @@ -223,13 +128,6 @@ typedef fpos<mbstate_t> u8streampos; |
| 223 | 128 | typedef fpos<mbstate_t> u16streampos; |
| 224 | 129 | typedef fpos<mbstate_t> u32streampos; |
| 225 | 130 | |
| 226 | #if defined(_NEWLIB_VERSION) | |
| 227 | // On newlib, off_t is 'long int' | |
| 228 | typedef long int streamoff; // for char_traits in <string> | |
| 229 | #else | |
| 230 | typedef long long streamoff; // for char_traits in <string> | |
| 231 | #endif | |
| 232 | ||
| 233 | 131 | // Include other forward declarations here |
| 234 | 132 | template <class _Tp, class _Alloc = allocator<_Tp> > |
| 235 | 133 | class _LIBCPP_TEMPLATE_VIS vector; |
lib/libcxx/include/iostream+8-8| ... | ... | @@ -51,16 +51,16 @@ extern wostream wclog; |
| 51 | 51 | |
| 52 | 52 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 53 | 53 | |
| 54 | extern _LIBCPP_FUNC_VIS istream cin; | |
| 55 | extern _LIBCPP_FUNC_VIS ostream cout; | |
| 56 | extern _LIBCPP_FUNC_VIS ostream cerr; | |
| 57 | extern _LIBCPP_FUNC_VIS ostream clog; | |
| 54 | extern _LIBCPP_EXPORTED_FROM_ABI istream cin; | |
| 55 | extern _LIBCPP_EXPORTED_FROM_ABI ostream cout; | |
| 56 | extern _LIBCPP_EXPORTED_FROM_ABI ostream cerr; | |
| 57 | extern _LIBCPP_EXPORTED_FROM_ABI ostream clog; | |
| 58 | 58 | |
| 59 | 59 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 60 | extern _LIBCPP_FUNC_VIS wistream wcin; | |
| 61 | extern _LIBCPP_FUNC_VIS wostream wcout; | |
| 62 | extern _LIBCPP_FUNC_VIS wostream wcerr; | |
| 63 | extern _LIBCPP_FUNC_VIS wostream wclog; | |
| 60 | extern _LIBCPP_EXPORTED_FROM_ABI wistream wcin; | |
| 61 | extern _LIBCPP_EXPORTED_FROM_ABI wostream wcout; | |
| 62 | extern _LIBCPP_EXPORTED_FROM_ABI wostream wcerr; | |
| 63 | extern _LIBCPP_EXPORTED_FROM_ABI wostream wclog; | |
| 64 | 64 | #endif |
| 65 | 65 | |
| 66 | 66 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/istream+84-79| ... | ... | @@ -160,7 +160,12 @@ template <class Stream, class T> |
| 160 | 160 | |
| 161 | 161 | #include <__assert> // all public C++ headers provide the assertion handler |
| 162 | 162 | #include <__config> |
| 163 | #include <__fwd/istream.h> | |
| 163 | 164 | #include <__iterator/istreambuf_iterator.h> |
| 165 | #include <__type_traits/conjunction.h> | |
| 166 | #include <__type_traits/enable_if.h> | |
| 167 | #include <__type_traits/is_base_of.h> | |
| 168 | #include <__utility/declval.h> | |
| 164 | 169 | #include <__utility/forward.h> |
| 165 | 170 | #include <ostream> |
| 166 | 171 | #include <version> |
| ... | ... | @@ -360,14 +365,14 @@ __input_arithmetic(basic_istream<_CharT, _Traits>& __is, _Tp& __n) { |
| 360 | 365 | typename basic_istream<_CharT, _Traits>::sentry __s(__is); |
| 361 | 366 | if (__s) |
| 362 | 367 | { |
| 363 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 368 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 364 | 369 | try |
| 365 | 370 | { |
| 366 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 371 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 367 | 372 | typedef istreambuf_iterator<_CharT, _Traits> _Ip; |
| 368 | 373 | typedef num_get<_CharT, _Ip> _Fp; |
| 369 | 374 | std::use_facet<_Fp>(__is.getloc()).get(_Ip(__is), _Ip(), __is, __state, __n); |
| 370 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 375 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 371 | 376 | } |
| 372 | 377 | catch (...) |
| 373 | 378 | { |
| ... | ... | @@ -469,10 +474,10 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp |
| 469 | 474 | typename basic_istream<_CharT, _Traits>::sentry __s(__is); |
| 470 | 475 | if (__s) |
| 471 | 476 | { |
| 472 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 477 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 473 | 478 | try |
| 474 | 479 | { |
| 475 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 480 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 476 | 481 | typedef istreambuf_iterator<_CharT, _Traits> _Ip; |
| 477 | 482 | typedef num_get<_CharT, _Ip> _Fp; |
| 478 | 483 | long __temp; |
| ... | ... | @@ -491,7 +496,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp |
| 491 | 496 | { |
| 492 | 497 | __n = static_cast<_Tp>(__temp); |
| 493 | 498 | } |
| 494 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 499 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 495 | 500 | } |
| 496 | 501 | catch (...) |
| 497 | 502 | { |
| ... | ... | @@ -502,7 +507,7 @@ __input_arithmetic_with_numeric_limits(basic_istream<_CharT, _Traits>& __is, _Tp |
| 502 | 507 | throw; |
| 503 | 508 | } |
| 504 | 509 | } |
| 505 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 510 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 506 | 511 | __is.setstate(__state); |
| 507 | 512 | } |
| 508 | 513 | return __is; |
| ... | ... | @@ -531,7 +536,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) |
| 531 | 536 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is); |
| 532 | 537 | if (__sen) |
| 533 | 538 | { |
| 534 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 539 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 535 | 540 | try |
| 536 | 541 | { |
| 537 | 542 | #endif |
| ... | ... | @@ -555,7 +560,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) |
| 555 | 560 | __is.width(0); |
| 556 | 561 | if (__s == __p) |
| 557 | 562 | __state |= ios_base::failbit; |
| 558 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 563 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 559 | 564 | } |
| 560 | 565 | catch (...) |
| 561 | 566 | { |
| ... | ... | @@ -572,7 +577,7 @@ __input_c_string(basic_istream<_CharT, _Traits>& __is, _CharT* __p, size_t __n) |
| 572 | 577 | return __is; |
| 573 | 578 | } |
| 574 | 579 | |
| 575 | #if _LIBCPP_STD_VER > 17 | |
| 580 | #if _LIBCPP_STD_VER >= 20 | |
| 576 | 581 | |
| 577 | 582 | template<class _CharT, class _Traits, size_t _Np> |
| 578 | 583 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -630,7 +635,7 @@ operator>>(basic_istream<char, _Traits>& __is, signed char* __s) |
| 630 | 635 | return __is >> (char*)__s; |
| 631 | 636 | } |
| 632 | 637 | |
| 633 | #endif // _LIBCPP_STD_VER > 17 | |
| 638 | #endif // _LIBCPP_STD_VER >= 20 | |
| 634 | 639 | |
| 635 | 640 | template<class _CharT, class _Traits> |
| 636 | 641 | _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>& |
| ... | ... | @@ -640,7 +645,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) |
| 640 | 645 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is); |
| 641 | 646 | if (__sen) |
| 642 | 647 | { |
| 643 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 648 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 644 | 649 | try |
| 645 | 650 | { |
| 646 | 651 | #endif |
| ... | ... | @@ -649,7 +654,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c) |
| 649 | 654 | __state |= ios_base::eofbit | ios_base::failbit; |
| 650 | 655 | else |
| 651 | 656 | __c = _Traits::to_char_type(__i); |
| 652 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 657 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 653 | 658 | } |
| 654 | 659 | catch (...) |
| 655 | 660 | { |
| ... | ... | @@ -693,10 +698,10 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ |
| 693 | 698 | { |
| 694 | 699 | if (__sb) |
| 695 | 700 | { |
| 696 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 701 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 697 | 702 | try |
| 698 | 703 | { |
| 699 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 704 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 700 | 705 | while (true) |
| 701 | 706 | { |
| 702 | 707 | typename traits_type::int_type __i = this->rdbuf()->sgetc(); |
| ... | ... | @@ -714,7 +719,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ |
| 714 | 719 | } |
| 715 | 720 | if (__gc_ == 0) |
| 716 | 721 | __state |= ios_base::failbit; |
| 717 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 722 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 718 | 723 | } |
| 719 | 724 | catch (...) |
| 720 | 725 | { |
| ... | ... | @@ -728,7 +733,7 @@ basic_istream<_CharT, _Traits>::operator>>(basic_streambuf<char_type, traits_typ |
| 728 | 733 | throw; |
| 729 | 734 | } |
| 730 | 735 | } |
| 731 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 736 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 732 | 737 | } |
| 733 | 738 | else |
| 734 | 739 | { |
| ... | ... | @@ -749,7 +754,7 @@ basic_istream<_CharT, _Traits>::get() |
| 749 | 754 | sentry __s(*this, true); |
| 750 | 755 | if (__s) |
| 751 | 756 | { |
| 752 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 757 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 753 | 758 | try |
| 754 | 759 | { |
| 755 | 760 | #endif |
| ... | ... | @@ -758,7 +763,7 @@ basic_istream<_CharT, _Traits>::get() |
| 758 | 763 | __state |= ios_base::failbit | ios_base::eofbit; |
| 759 | 764 | else |
| 760 | 765 | __gc_ = 1; |
| 761 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 766 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 762 | 767 | } |
| 763 | 768 | catch (...) |
| 764 | 769 | { |
| ... | ... | @@ -785,7 +790,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ |
| 785 | 790 | { |
| 786 | 791 | if (__n > 0) |
| 787 | 792 | { |
| 788 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 793 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 789 | 794 | try |
| 790 | 795 | { |
| 791 | 796 | #endif |
| ... | ... | @@ -806,7 +811,7 @@ basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __ |
| 806 | 811 | } |
| 807 | 812 | if (__gc_ == 0) |
| 808 | 813 | __state |= ios_base::failbit; |
| 809 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 814 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 810 | 815 | } |
| 811 | 816 | catch (...) |
| 812 | 817 | { |
| ... | ... | @@ -845,10 +850,10 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s |
| 845 | 850 | sentry __sen(*this, true); |
| 846 | 851 | if (__sen) |
| 847 | 852 | { |
| 848 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 853 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 849 | 854 | try |
| 850 | 855 | { |
| 851 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 856 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 852 | 857 | while (true) |
| 853 | 858 | { |
| 854 | 859 | typename traits_type::int_type __i = this->rdbuf()->sgetc(); |
| ... | ... | @@ -865,14 +870,14 @@ basic_istream<_CharT, _Traits>::get(basic_streambuf<char_type, traits_type>& __s |
| 865 | 870 | ++__gc_; |
| 866 | 871 | this->rdbuf()->sbumpc(); |
| 867 | 872 | } |
| 868 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 873 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 869 | 874 | } |
| 870 | 875 | catch (...) |
| 871 | 876 | { |
| 872 | 877 | __state |= ios_base::badbit; |
| 873 | 878 | // according to the spec, exceptions here are caught but not rethrown |
| 874 | 879 | } |
| 875 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 880 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 876 | 881 | if (__gc_ == 0) |
| 877 | 882 | __state |= ios_base::failbit; |
| 878 | 883 | this->setstate(__state); |
| ... | ... | @@ -889,10 +894,10 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ |
| 889 | 894 | sentry __sen(*this, true); |
| 890 | 895 | if (__sen) |
| 891 | 896 | { |
| 892 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 897 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 893 | 898 | try |
| 894 | 899 | { |
| 895 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 900 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 896 | 901 | while (true) |
| 897 | 902 | { |
| 898 | 903 | typename traits_type::int_type __i = this->rdbuf()->sgetc(); |
| ... | ... | @@ -917,7 +922,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ |
| 917 | 922 | this->rdbuf()->sbumpc(); |
| 918 | 923 | ++__gc_; |
| 919 | 924 | } |
| 920 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 925 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 921 | 926 | } |
| 922 | 927 | catch (...) |
| 923 | 928 | { |
| ... | ... | @@ -932,7 +937,7 @@ basic_istream<_CharT, _Traits>::getline(char_type* __s, streamsize __n, char_typ |
| 932 | 937 | throw; |
| 933 | 938 | } |
| 934 | 939 | } |
| 935 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 940 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 936 | 941 | } |
| 937 | 942 | if (__n > 0) |
| 938 | 943 | *__s = char_type(); |
| ... | ... | @@ -951,10 +956,10 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) |
| 951 | 956 | sentry __sen(*this, true); |
| 952 | 957 | if (__sen) |
| 953 | 958 | { |
| 954 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 959 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 955 | 960 | try |
| 956 | 961 | { |
| 957 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 962 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 958 | 963 | if (__n == numeric_limits<streamsize>::max()) |
| 959 | 964 | { |
| 960 | 965 | while (true) |
| ... | ... | @@ -985,7 +990,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) |
| 985 | 990 | break; |
| 986 | 991 | } |
| 987 | 992 | } |
| 988 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 993 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 989 | 994 | } |
| 990 | 995 | catch (...) |
| 991 | 996 | { |
| ... | ... | @@ -996,7 +1001,7 @@ basic_istream<_CharT, _Traits>::ignore(streamsize __n, int_type __dlm) |
| 996 | 1001 | throw; |
| 997 | 1002 | } |
| 998 | 1003 | } |
| 999 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1004 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1000 | 1005 | this->setstate(__state); |
| 1001 | 1006 | } |
| 1002 | 1007 | return *this; |
| ... | ... | @@ -1012,14 +1017,14 @@ basic_istream<_CharT, _Traits>::peek() |
| 1012 | 1017 | sentry __sen(*this, true); |
| 1013 | 1018 | if (__sen) |
| 1014 | 1019 | { |
| 1015 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1020 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1016 | 1021 | try |
| 1017 | 1022 | { |
| 1018 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1023 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1019 | 1024 | __r = this->rdbuf()->sgetc(); |
| 1020 | 1025 | if (traits_type::eq_int_type(__r, traits_type::eof())) |
| 1021 | 1026 | __state |= ios_base::eofbit; |
| 1022 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1027 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1023 | 1028 | } |
| 1024 | 1029 | catch (...) |
| 1025 | 1030 | { |
| ... | ... | @@ -1030,7 +1035,7 @@ basic_istream<_CharT, _Traits>::peek() |
| 1030 | 1035 | throw; |
| 1031 | 1036 | } |
| 1032 | 1037 | } |
| 1033 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1038 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1034 | 1039 | this->setstate(__state); |
| 1035 | 1040 | } |
| 1036 | 1041 | return __r; |
| ... | ... | @@ -1045,14 +1050,14 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) |
| 1045 | 1050 | sentry __sen(*this, true); |
| 1046 | 1051 | if (__sen) |
| 1047 | 1052 | { |
| 1048 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1053 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1049 | 1054 | try |
| 1050 | 1055 | { |
| 1051 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1056 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1052 | 1057 | __gc_ = this->rdbuf()->sgetn(__s, __n); |
| 1053 | 1058 | if (__gc_ != __n) |
| 1054 | 1059 | __state |= ios_base::failbit | ios_base::eofbit; |
| 1055 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1060 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1056 | 1061 | } |
| 1057 | 1062 | catch (...) |
| 1058 | 1063 | { |
| ... | ... | @@ -1063,7 +1068,7 @@ basic_istream<_CharT, _Traits>::read(char_type* __s, streamsize __n) |
| 1063 | 1068 | throw; |
| 1064 | 1069 | } |
| 1065 | 1070 | } |
| 1066 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1071 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1067 | 1072 | } |
| 1068 | 1073 | else |
| 1069 | 1074 | { |
| ... | ... | @@ -1082,10 +1087,10 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) |
| 1082 | 1087 | sentry __sen(*this, true); |
| 1083 | 1088 | if (__sen) |
| 1084 | 1089 | { |
| 1085 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1090 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1086 | 1091 | try |
| 1087 | 1092 | { |
| 1088 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1093 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1089 | 1094 | streamsize __c = this->rdbuf()->in_avail(); |
| 1090 | 1095 | switch (__c) |
| 1091 | 1096 | { |
| ... | ... | @@ -1101,7 +1106,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) |
| 1101 | 1106 | __state |= ios_base::failbit | ios_base::eofbit; |
| 1102 | 1107 | break; |
| 1103 | 1108 | } |
| 1104 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1109 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1105 | 1110 | } |
| 1106 | 1111 | catch (...) |
| 1107 | 1112 | { |
| ... | ... | @@ -1112,7 +1117,7 @@ basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) |
| 1112 | 1117 | throw; |
| 1113 | 1118 | } |
| 1114 | 1119 | } |
| 1115 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1120 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1116 | 1121 | } |
| 1117 | 1122 | else |
| 1118 | 1123 | { |
| ... | ... | @@ -1132,13 +1137,13 @@ basic_istream<_CharT, _Traits>::putback(char_type __c) |
| 1132 | 1137 | sentry __sen(*this, true); |
| 1133 | 1138 | if (__sen) |
| 1134 | 1139 | { |
| 1135 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1140 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1136 | 1141 | try |
| 1137 | 1142 | { |
| 1138 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1143 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1139 | 1144 | if (this->rdbuf() == nullptr || this->rdbuf()->sputbackc(__c) == traits_type::eof()) |
| 1140 | 1145 | __state |= ios_base::badbit; |
| 1141 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1146 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1142 | 1147 | } |
| 1143 | 1148 | catch (...) |
| 1144 | 1149 | { |
| ... | ... | @@ -1149,7 +1154,7 @@ basic_istream<_CharT, _Traits>::putback(char_type __c) |
| 1149 | 1154 | throw; |
| 1150 | 1155 | } |
| 1151 | 1156 | } |
| 1152 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1157 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1153 | 1158 | } |
| 1154 | 1159 | else |
| 1155 | 1160 | { |
| ... | ... | @@ -1169,13 +1174,13 @@ basic_istream<_CharT, _Traits>::unget() |
| 1169 | 1174 | sentry __sen(*this, true); |
| 1170 | 1175 | if (__sen) |
| 1171 | 1176 | { |
| 1172 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1177 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1173 | 1178 | try |
| 1174 | 1179 | { |
| 1175 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1180 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1176 | 1181 | if (this->rdbuf() == nullptr || this->rdbuf()->sungetc() == traits_type::eof()) |
| 1177 | 1182 | __state |= ios_base::badbit; |
| 1178 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1183 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1179 | 1184 | } |
| 1180 | 1185 | catch (...) |
| 1181 | 1186 | { |
| ... | ... | @@ -1186,7 +1191,7 @@ basic_istream<_CharT, _Traits>::unget() |
| 1186 | 1191 | throw; |
| 1187 | 1192 | } |
| 1188 | 1193 | } |
| 1189 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1194 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1190 | 1195 | } |
| 1191 | 1196 | else |
| 1192 | 1197 | { |
| ... | ... | @@ -1205,10 +1210,10 @@ basic_istream<_CharT, _Traits>::sync() |
| 1205 | 1210 | sentry __sen(*this, true); |
| 1206 | 1211 | if (__sen) |
| 1207 | 1212 | { |
| 1208 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1213 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1209 | 1214 | try |
| 1210 | 1215 | { |
| 1211 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1216 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1212 | 1217 | if (this->rdbuf() == nullptr) |
| 1213 | 1218 | return -1; |
| 1214 | 1219 | if (this->rdbuf()->pubsync() == -1) |
| ... | ... | @@ -1216,7 +1221,7 @@ basic_istream<_CharT, _Traits>::sync() |
| 1216 | 1221 | __state |= ios_base::badbit; |
| 1217 | 1222 | return -1; |
| 1218 | 1223 | } |
| 1219 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1224 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1220 | 1225 | } |
| 1221 | 1226 | catch (...) |
| 1222 | 1227 | { |
| ... | ... | @@ -1227,7 +1232,7 @@ basic_istream<_CharT, _Traits>::sync() |
| 1227 | 1232 | throw; |
| 1228 | 1233 | } |
| 1229 | 1234 | } |
| 1230 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1235 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1231 | 1236 | this->setstate(__state); |
| 1232 | 1237 | } |
| 1233 | 1238 | return __r; |
| ... | ... | @@ -1242,12 +1247,12 @@ basic_istream<_CharT, _Traits>::tellg() |
| 1242 | 1247 | sentry __sen(*this, true); |
| 1243 | 1248 | if (__sen) |
| 1244 | 1249 | { |
| 1245 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1250 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1246 | 1251 | try |
| 1247 | 1252 | { |
| 1248 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1253 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1249 | 1254 | __r = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); |
| 1250 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1255 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1251 | 1256 | } |
| 1252 | 1257 | catch (...) |
| 1253 | 1258 | { |
| ... | ... | @@ -1258,7 +1263,7 @@ basic_istream<_CharT, _Traits>::tellg() |
| 1258 | 1263 | throw; |
| 1259 | 1264 | } |
| 1260 | 1265 | } |
| 1261 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1266 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1262 | 1267 | this->setstate(__state); |
| 1263 | 1268 | } |
| 1264 | 1269 | return __r; |
| ... | ... | @@ -1273,13 +1278,13 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos) |
| 1273 | 1278 | sentry __sen(*this, true); |
| 1274 | 1279 | if (__sen) |
| 1275 | 1280 | { |
| 1276 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1281 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1277 | 1282 | try |
| 1278 | 1283 | { |
| 1279 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1284 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1280 | 1285 | if (this->rdbuf()->pubseekpos(__pos, ios_base::in) == pos_type(-1)) |
| 1281 | 1286 | __state |= ios_base::failbit; |
| 1282 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1287 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1283 | 1288 | } |
| 1284 | 1289 | catch (...) |
| 1285 | 1290 | { |
| ... | ... | @@ -1290,7 +1295,7 @@ basic_istream<_CharT, _Traits>::seekg(pos_type __pos) |
| 1290 | 1295 | throw; |
| 1291 | 1296 | } |
| 1292 | 1297 | } |
| 1293 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1298 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1294 | 1299 | this->setstate(__state); |
| 1295 | 1300 | } |
| 1296 | 1301 | return *this; |
| ... | ... | @@ -1305,13 +1310,13 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) |
| 1305 | 1310 | sentry __sen(*this, true); |
| 1306 | 1311 | if (__sen) |
| 1307 | 1312 | { |
| 1308 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1313 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1309 | 1314 | try |
| 1310 | 1315 | { |
| 1311 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1316 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1312 | 1317 | if (this->rdbuf()->pubseekoff(__off, __dir, ios_base::in) == pos_type(-1)) |
| 1313 | 1318 | __state |= ios_base::failbit; |
| 1314 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1319 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1315 | 1320 | } |
| 1316 | 1321 | catch (...) |
| 1317 | 1322 | { |
| ... | ... | @@ -1322,7 +1327,7 @@ basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) |
| 1322 | 1327 | throw; |
| 1323 | 1328 | } |
| 1324 | 1329 | } |
| 1325 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1330 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1326 | 1331 | this->setstate(__state); |
| 1327 | 1332 | } |
| 1328 | 1333 | return *this; |
| ... | ... | @@ -1336,10 +1341,10 @@ ws(basic_istream<_CharT, _Traits>& __is) |
| 1336 | 1341 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true); |
| 1337 | 1342 | if (__sen) |
| 1338 | 1343 | { |
| 1339 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1344 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1340 | 1345 | try |
| 1341 | 1346 | { |
| 1342 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1347 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1343 | 1348 | const ctype<_CharT>& __ct = std::use_facet<ctype<_CharT> >(__is.getloc()); |
| 1344 | 1349 | while (true) |
| 1345 | 1350 | { |
| ... | ... | @@ -1353,7 +1358,7 @@ ws(basic_istream<_CharT, _Traits>& __is) |
| 1353 | 1358 | break; |
| 1354 | 1359 | __is.rdbuf()->sbumpc(); |
| 1355 | 1360 | } |
| 1356 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1361 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1357 | 1362 | } |
| 1358 | 1363 | catch (...) |
| 1359 | 1364 | { |
| ... | ... | @@ -1364,7 +1369,7 @@ ws(basic_istream<_CharT, _Traits>& __is) |
| 1364 | 1369 | throw; |
| 1365 | 1370 | } |
| 1366 | 1371 | } |
| 1367 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1372 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1368 | 1373 | __is.setstate(__state); |
| 1369 | 1374 | } |
| 1370 | 1375 | return __is; |
| ... | ... | @@ -1450,7 +1455,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, |
| 1450 | 1455 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is); |
| 1451 | 1456 | if (__sen) |
| 1452 | 1457 | { |
| 1453 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1458 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1454 | 1459 | try |
| 1455 | 1460 | { |
| 1456 | 1461 | #endif |
| ... | ... | @@ -1480,7 +1485,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, |
| 1480 | 1485 | __is.width(0); |
| 1481 | 1486 | if (__c == 0) |
| 1482 | 1487 | __state |= ios_base::failbit; |
| 1483 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1488 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1484 | 1489 | } |
| 1485 | 1490 | catch (...) |
| 1486 | 1491 | { |
| ... | ... | @@ -1506,7 +1511,7 @@ getline(basic_istream<_CharT, _Traits>& __is, |
| 1506 | 1511 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is, true); |
| 1507 | 1512 | if (__sen) |
| 1508 | 1513 | { |
| 1509 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1514 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1510 | 1515 | try |
| 1511 | 1516 | { |
| 1512 | 1517 | #endif |
| ... | ... | @@ -1533,7 +1538,7 @@ getline(basic_istream<_CharT, _Traits>& __is, |
| 1533 | 1538 | } |
| 1534 | 1539 | if (__extr == 0) |
| 1535 | 1540 | __state |= ios_base::failbit; |
| 1536 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1541 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1537 | 1542 | } |
| 1538 | 1543 | catch (...) |
| 1539 | 1544 | { |
| ... | ... | @@ -1585,7 +1590,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) |
| 1585 | 1590 | typename basic_istream<_CharT, _Traits>::sentry __sen(__is); |
| 1586 | 1591 | if (__sen) |
| 1587 | 1592 | { |
| 1588 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1593 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1589 | 1594 | try |
| 1590 | 1595 | { |
| 1591 | 1596 | #endif |
| ... | ... | @@ -1612,7 +1617,7 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x) |
| 1612 | 1617 | __x = bitset<_Size>(__str); |
| 1613 | 1618 | if (_Size > 0 && __c == 0) |
| 1614 | 1619 | __state |= ios_base::failbit; |
| 1615 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1620 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1616 | 1621 | } |
| 1617 | 1622 | catch (...) |
| 1618 | 1623 | { |
lib/libcxx/include/iterator+2-2| ... | ... | @@ -387,7 +387,7 @@ template <class Iterator> |
| 387 | 387 | class move_iterator { |
| 388 | 388 | public: |
| 389 | 389 | using iterator_type = Iterator; |
| 390 | using iterator_concept = input_iterator_tag; // From C++20 | |
| 390 | using iterator_concept = see below; // From C++20 | |
| 391 | 391 | using iterator_category = see below; // not always present starting from C++20 |
| 392 | 392 | using value_type = iter_value_t<Iterator>; // Until C++20, iterator_traits<Iterator>::value_type |
| 393 | 393 | using difference_type = iter_difference_t<Iterator>; // Until C++20, iterator_traits<Iterator>::difference_type; |
| ... | ... | @@ -676,7 +676,6 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; |
| 676 | 676 | |
| 677 | 677 | #include <__assert> // all public C++ headers provide the assertion handler |
| 678 | 678 | #include <__config> |
| 679 | #include <__debug> | |
| 680 | 679 | #include <__iterator/access.h> |
| 681 | 680 | #include <__iterator/advance.h> |
| 682 | 681 | #include <__iterator/back_insert_iterator.h> |
| ... | ... | @@ -732,6 +731,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept; |
| 732 | 731 | #endif |
| 733 | 732 | |
| 734 | 733 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 734 | # include <cstdlib> | |
| 735 | 735 | # include <exception> |
| 736 | 736 | # include <new> |
| 737 | 737 | # include <type_traits> |
lib/libcxx/include/latch+30-6| ... | ... | @@ -41,9 +41,12 @@ namespace std |
| 41 | 41 | */ |
| 42 | 42 | |
| 43 | 43 | #include <__assert> // all public C++ headers provide the assertion handler |
| 44 | #include <__atomic/atomic_base.h> | |
| 45 | #include <__atomic/atomic_sync.h> | |
| 46 | #include <__atomic/memory_order.h> | |
| 44 | 47 | #include <__availability> |
| 45 | 48 | #include <__config> |
| 46 | #include <atomic> | |
| 49 | #include <cstddef> | |
| 47 | 50 | #include <limits> |
| 48 | 51 | #include <version> |
| 49 | 52 | |
| ... | ... | @@ -67,22 +70,35 @@ class latch |
| 67 | 70 | __atomic_base<ptrdiff_t> __a_; |
| 68 | 71 | |
| 69 | 72 | public: |
| 70 | static constexpr ptrdiff_t max() noexcept { | |
| 73 | static _LIBCPP_HIDE_FROM_ABI constexpr ptrdiff_t max() noexcept { | |
| 71 | 74 | return numeric_limits<ptrdiff_t>::max(); |
| 72 | 75 | } |
| 73 | 76 | |
| 74 | 77 | inline _LIBCPP_INLINE_VISIBILITY |
| 75 | constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) { } | |
| 78 | constexpr explicit latch(ptrdiff_t __expected) : __a_(__expected) | |
| 79 | { | |
| 80 | _LIBCPP_ASSERT_UNCATEGORIZED(__expected >= 0, | |
| 81 | "latch::latch(ptrdiff_t): latch cannot be " | |
| 82 | "initialized with a negative value"); | |
| 83 | _LIBCPP_ASSERT_UNCATEGORIZED(__expected <= max(), | |
| 84 | "latch::latch(ptrdiff_t): latch cannot be " | |
| 85 | "initialized with a value greater than max()"); | |
| 86 | } | |
| 76 | 87 | |
| 77 | ~latch() = default; | |
| 88 | _LIBCPP_HIDE_FROM_ABI ~latch() = default; | |
| 78 | 89 | latch(const latch&) = delete; |
| 79 | 90 | latch& operator=(const latch&) = delete; |
| 80 | 91 | |
| 81 | 92 | inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 82 | 93 | void count_down(ptrdiff_t __update = 1) |
| 83 | 94 | { |
| 95 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 96 | __update >= 0, "latch::count_down called with a negative value"); | |
| 84 | 97 | auto const __old = __a_.fetch_sub(__update, memory_order_release); |
| 85 | if(__old == __update) | |
| 98 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 99 | __update <= __old, "latch::count_down called with a value greater " | |
| 100 | "than the internal counter"); | |
| 101 | if (__old == __update) | |
| 86 | 102 | __a_.notify_all(); |
| 87 | 103 | } |
| 88 | 104 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -93,13 +109,17 @@ public: |
| 93 | 109 | inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 94 | 110 | void wait() const |
| 95 | 111 | { |
| 96 | __cxx_atomic_wait(&__a_.__a_, [&]() -> bool { | |
| 112 | __cxx_atomic_wait(&__a_.__a_, [this]() -> bool { | |
| 97 | 113 | return try_wait(); |
| 98 | 114 | }); |
| 99 | 115 | } |
| 100 | 116 | inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 101 | 117 | void arrive_and_wait(ptrdiff_t __update = 1) |
| 102 | 118 | { |
| 119 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 120 | __update >= 0, "latch::arrive_and_wait called with a negative value"); | |
| 121 | // other preconditions on __update are checked in count_down() | |
| 122 | ||
| 103 | 123 | count_down(__update); |
| 104 | 124 | wait(); |
| 105 | 125 | } |
| ... | ... | @@ -111,4 +131,8 @@ _LIBCPP_END_NAMESPACE_STD |
| 111 | 131 | |
| 112 | 132 | _LIBCPP_POP_MACROS |
| 113 | 133 | |
| 134 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 135 | # include <atomic> | |
| 136 | #endif | |
| 137 | ||
| 114 | 138 | #endif //_LIBCPP_LATCH |
lib/libcxx/include/list+249-489| ... | ... | @@ -46,6 +46,8 @@ public: |
| 46 | 46 | list(Iter first, Iter last); |
| 47 | 47 | template <class Iter> |
| 48 | 48 | list(Iter first, Iter last, const allocator_type& a); |
| 49 | template<container-compatible-range<T> R> | |
| 50 | list(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 | |
| 49 | 51 | list(const list& x); |
| 50 | 52 | list(const list&, const allocator_type& a); |
| 51 | 53 | list(list&& x) |
| ... | ... | @@ -64,6 +66,8 @@ public: |
| 64 | 66 | list& operator=(initializer_list<value_type>); |
| 65 | 67 | template <class Iter> |
| 66 | 68 | void assign(Iter first, Iter last); |
| 69 | template<container-compatible-range<T> R> | |
| 70 | void assign_range(R&& rg); // C++23 | |
| 67 | 71 | void assign(size_type n, const value_type& t); |
| 68 | 72 | void assign(initializer_list<value_type>); |
| 69 | 73 | |
| ... | ... | @@ -99,8 +103,12 @@ public: |
| 99 | 103 | void pop_back(); |
| 100 | 104 | void push_front(const value_type& x); |
| 101 | 105 | void push_front(value_type&& x); |
| 106 | template<container-compatible-range<T> R> | |
| 107 | void prepend_range(R&& rg); // C++23 | |
| 102 | 108 | void push_back(const value_type& x); |
| 103 | 109 | void push_back(value_type&& x); |
| 110 | template<container-compatible-range<T> R> | |
| 111 | void append_range(R&& rg); // C++23 | |
| 104 | 112 | template <class... Args> |
| 105 | 113 | iterator emplace(const_iterator position, Args&&... args); |
| 106 | 114 | iterator insert(const_iterator position, const value_type& x); |
| ... | ... | @@ -108,6 +116,8 @@ public: |
| 108 | 116 | iterator insert(const_iterator position, size_type n, const value_type& x); |
| 109 | 117 | template <class Iter> |
| 110 | 118 | iterator insert(const_iterator position, Iter first, Iter last); |
| 119 | template<container-compatible-range<T> R> | |
| 120 | iterator insert_range(const_iterator position, R&& rg); // C++23 | |
| 111 | 121 | iterator insert(const_iterator position, initializer_list<value_type> il); |
| 112 | 122 | |
| 113 | 123 | iterator erase(const_iterator position); |
| ... | ... | @@ -152,18 +162,25 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra |
| 152 | 162 | list(InputIterator, InputIterator, Allocator = Allocator()) |
| 153 | 163 | -> list<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 |
| 154 | 164 | |
| 165 | template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> | |
| 166 | list(from_range_t, R&&, Allocator = Allocator()) | |
| 167 | -> list<ranges::range_value_t<R>, Allocator>; // C++23 | |
| 168 | ||
| 155 | 169 | template <class T, class Alloc> |
| 156 | 170 | bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y); |
| 157 | 171 | template <class T, class Alloc> |
| 158 | bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y); | |
| 172 | bool operator< (const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20 | |
| 159 | 173 | template <class T, class Alloc> |
| 160 | bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y); | |
| 174 | bool operator!=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20 | |
| 161 | 175 | template <class T, class Alloc> |
| 162 | bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y); | |
| 176 | bool operator> (const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20 | |
| 163 | 177 | template <class T, class Alloc> |
| 164 | bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y); | |
| 178 | bool operator>=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20 | |
| 165 | 179 | template <class T, class Alloc> |
| 166 | bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y); | |
| 180 | bool operator<=(const list<T,Alloc>& x, const list<T,Alloc>& y); // removed in C++20 | |
| 181 | template<class T, class Allocator> | |
| 182 | synth-three-way-result<T> operator<=>(const list<T, Allocator>& x, | |
| 183 | const list<T, Allocator>& y); // since C++20 | |
| 167 | 184 | |
| 168 | 185 | template <class T, class Alloc> |
| 169 | 186 | void swap(list<T,Alloc>& x, list<T,Alloc>& y) |
| ... | ... | @@ -171,10 +188,10 @@ template <class T, class Alloc> |
| 171 | 188 | |
| 172 | 189 | template <class T, class Allocator, class U> |
| 173 | 190 | typename list<T, Allocator>::size_type |
| 174 | erase(list<T, Allocator>& c, const U& value); // C++20 | |
| 191 | erase(list<T, Allocator>& c, const U& value); // since C++20 | |
| 175 | 192 | template <class T, class Allocator, class Predicate> |
| 176 | 193 | typename list<T, Allocator>::size_type |
| 177 | erase_if(list<T, Allocator>& c, Predicate pred); // C++20 | |
| 194 | erase_if(list<T, Allocator>& c, Predicate pred); // since C++20 | |
| 178 | 195 | |
| 179 | 196 | } // std |
| 180 | 197 | |
| ... | ... | @@ -183,10 +200,11 @@ template <class T, class Allocator, class Predicate> |
| 183 | 200 | #include <__algorithm/comp.h> |
| 184 | 201 | #include <__algorithm/equal.h> |
| 185 | 202 | #include <__algorithm/lexicographical_compare.h> |
| 203 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 186 | 204 | #include <__algorithm/min.h> |
| 187 | 205 | #include <__assert> // all public C++ headers provide the assertion handler |
| 206 | #include <__availability> | |
| 188 | 207 | #include <__config> |
| 189 | #include <__debug> | |
| 190 | 208 | #include <__format/enable_insertable.h> |
| 191 | 209 | #include <__iterator/distance.h> |
| 192 | 210 | #include <__iterator/iterator_traits.h> |
| ... | ... | @@ -203,13 +221,23 @@ template <class T, class Allocator, class Predicate> |
| 203 | 221 | #include <__memory/swap_allocator.h> |
| 204 | 222 | #include <__memory/unique_ptr.h> |
| 205 | 223 | #include <__memory_resource/polymorphic_allocator.h> |
| 224 | #include <__ranges/access.h> | |
| 225 | #include <__ranges/concepts.h> | |
| 226 | #include <__ranges/container_compatible_range.h> | |
| 227 | #include <__ranges/from_range.h> | |
| 228 | #include <__type_traits/conditional.h> | |
| 206 | 229 | #include <__type_traits/is_allocator.h> |
| 230 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 231 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 232 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 233 | #include <__type_traits/is_pointer.h> | |
| 234 | #include <__type_traits/is_same.h> | |
| 235 | #include <__type_traits/type_identity.h> | |
| 207 | 236 | #include <__utility/forward.h> |
| 208 | 237 | #include <__utility/move.h> |
| 209 | 238 | #include <__utility/swap.h> |
| 210 | 239 | #include <cstring> |
| 211 | 240 | #include <limits> |
| 212 | #include <type_traits> | |
| 213 | 241 | #include <version> |
| 214 | 242 | |
| 215 | 243 | // standard-mandated includes |
| ... | ... | @@ -320,13 +348,9 @@ class _LIBCPP_TEMPLATE_VIS __list_iterator |
| 320 | 348 | __link_pointer __ptr_; |
| 321 | 349 | |
| 322 | 350 | _LIBCPP_INLINE_VISIBILITY |
| 323 | explicit __list_iterator(__link_pointer __p, const void* __c) _NOEXCEPT | |
| 351 | explicit __list_iterator(__link_pointer __p) _NOEXCEPT | |
| 324 | 352 | : __ptr_(__p) |
| 325 | 353 | { |
| 326 | (void)__c; | |
| 327 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 328 | __get_db()->__insert_ic(this, __c); | |
| 329 | #endif | |
| 330 | 354 | } |
| 331 | 355 | |
| 332 | 356 | template<class, class> friend class list; |
| ... | ... | @@ -342,57 +366,22 @@ public: |
| 342 | 366 | _LIBCPP_INLINE_VISIBILITY |
| 343 | 367 | __list_iterator() _NOEXCEPT : __ptr_(nullptr) |
| 344 | 368 | { |
| 345 | _VSTD::__debug_db_insert_i(this); | |
| 346 | } | |
| 347 | ||
| 348 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 349 | ||
| 350 | _LIBCPP_INLINE_VISIBILITY | |
| 351 | __list_iterator(const __list_iterator& __p) | |
| 352 | : __ptr_(__p.__ptr_) | |
| 353 | { | |
| 354 | __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); | |
| 355 | } | |
| 356 | ||
| 357 | _LIBCPP_INLINE_VISIBILITY | |
| 358 | ~__list_iterator() | |
| 359 | { | |
| 360 | __get_db()->__erase_i(this); | |
| 361 | } | |
| 362 | ||
| 363 | _LIBCPP_INLINE_VISIBILITY | |
| 364 | __list_iterator& operator=(const __list_iterator& __p) | |
| 365 | { | |
| 366 | if (this != _VSTD::addressof(__p)) | |
| 367 | { | |
| 368 | __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); | |
| 369 | __ptr_ = __p.__ptr_; | |
| 370 | } | |
| 371 | return *this; | |
| 372 | 369 | } |
| 373 | 370 | |
| 374 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 375 | ||
| 376 | 371 | _LIBCPP_INLINE_VISIBILITY |
| 377 | 372 | reference operator*() const |
| 378 | 373 | { |
| 379 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 380 | "Attempted to dereference a non-dereferenceable list::iterator"); | |
| 381 | 374 | return __ptr_->__as_node()->__value_; |
| 382 | 375 | } |
| 383 | 376 | _LIBCPP_INLINE_VISIBILITY |
| 384 | 377 | pointer operator->() const |
| 385 | 378 | { |
| 386 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 387 | "Attempted to dereference a non-dereferenceable list::iterator"); | |
| 388 | 379 | return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); |
| 389 | 380 | } |
| 390 | 381 | |
| 391 | 382 | _LIBCPP_INLINE_VISIBILITY |
| 392 | 383 | __list_iterator& operator++() |
| 393 | 384 | { |
| 394 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 395 | "Attempted to increment a non-incrementable list::iterator"); | |
| 396 | 385 | __ptr_ = __ptr_->__next_; |
| 397 | 386 | return *this; |
| 398 | 387 | } |
| ... | ... | @@ -402,8 +391,6 @@ public: |
| 402 | 391 | _LIBCPP_INLINE_VISIBILITY |
| 403 | 392 | __list_iterator& operator--() |
| 404 | 393 | { |
| 405 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), | |
| 406 | "Attempted to decrement a non-decrementable list::iterator"); | |
| 407 | 394 | __ptr_ = __ptr_->__prev_; |
| 408 | 395 | return *this; |
| 409 | 396 | } |
| ... | ... | @@ -429,13 +416,9 @@ class _LIBCPP_TEMPLATE_VIS __list_const_iterator |
| 429 | 416 | __link_pointer __ptr_; |
| 430 | 417 | |
| 431 | 418 | _LIBCPP_INLINE_VISIBILITY |
| 432 | explicit __list_const_iterator(__link_pointer __p, const void* __c) _NOEXCEPT | |
| 419 | explicit __list_const_iterator(__link_pointer __p) _NOEXCEPT | |
| 433 | 420 | : __ptr_(__p) |
| 434 | 421 | { |
| 435 | (void)__c; | |
| 436 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 437 | __get_db()->__insert_ic(this, __c); | |
| 438 | #endif | |
| 439 | 422 | } |
| 440 | 423 | |
| 441 | 424 | template<class, class> friend class list; |
| ... | ... | @@ -450,64 +433,27 @@ public: |
| 450 | 433 | _LIBCPP_INLINE_VISIBILITY |
| 451 | 434 | __list_const_iterator() _NOEXCEPT : __ptr_(nullptr) |
| 452 | 435 | { |
| 453 | _VSTD::__debug_db_insert_i(this); | |
| 454 | 436 | } |
| 455 | 437 | _LIBCPP_INLINE_VISIBILITY |
| 456 | 438 | __list_const_iterator(const __list_iterator<_Tp, _VoidPtr>& __p) _NOEXCEPT |
| 457 | 439 | : __ptr_(__p.__ptr_) |
| 458 | 440 | { |
| 459 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 460 | __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); | |
| 461 | #endif | |
| 462 | } | |
| 463 | ||
| 464 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 465 | ||
| 466 | _LIBCPP_INLINE_VISIBILITY | |
| 467 | __list_const_iterator(const __list_const_iterator& __p) | |
| 468 | : __ptr_(__p.__ptr_) | |
| 469 | { | |
| 470 | __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); | |
| 471 | } | |
| 472 | ||
| 473 | _LIBCPP_INLINE_VISIBILITY | |
| 474 | ~__list_const_iterator() | |
| 475 | { | |
| 476 | __get_db()->__erase_i(this); | |
| 477 | } | |
| 478 | ||
| 479 | _LIBCPP_INLINE_VISIBILITY | |
| 480 | __list_const_iterator& operator=(const __list_const_iterator& __p) | |
| 481 | { | |
| 482 | if (this != _VSTD::addressof(__p)) | |
| 483 | { | |
| 484 | __get_db()->__iterator_copy(this, _VSTD::addressof(__p)); | |
| 485 | __ptr_ = __p.__ptr_; | |
| 486 | } | |
| 487 | return *this; | |
| 488 | 441 | } |
| 489 | 442 | |
| 490 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 491 | 443 | _LIBCPP_INLINE_VISIBILITY |
| 492 | 444 | reference operator*() const |
| 493 | 445 | { |
| 494 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 495 | "Attempted to dereference a non-dereferenceable list::const_iterator"); | |
| 496 | 446 | return __ptr_->__as_node()->__value_; |
| 497 | 447 | } |
| 498 | 448 | _LIBCPP_INLINE_VISIBILITY |
| 499 | 449 | pointer operator->() const |
| 500 | 450 | { |
| 501 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 502 | "Attempted to dereference a non-dereferenceable list::const_iterator"); | |
| 503 | 451 | return pointer_traits<pointer>::pointer_to(__ptr_->__as_node()->__value_); |
| 504 | 452 | } |
| 505 | 453 | |
| 506 | 454 | _LIBCPP_INLINE_VISIBILITY |
| 507 | 455 | __list_const_iterator& operator++() |
| 508 | 456 | { |
| 509 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), | |
| 510 | "Attempted to increment a non-incrementable list::const_iterator"); | |
| 511 | 457 | __ptr_ = __ptr_->__next_; |
| 512 | 458 | return *this; |
| 513 | 459 | } |
| ... | ... | @@ -517,8 +463,6 @@ public: |
| 517 | 463 | _LIBCPP_INLINE_VISIBILITY |
| 518 | 464 | __list_const_iterator& operator--() |
| 519 | 465 | { |
| 520 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__decrementable(this), | |
| 521 | "Attempted to decrement a non-decrementable list::const_iterator"); | |
| 522 | 466 | __ptr_ = __ptr_->__prev_; |
| 523 | 467 | return *this; |
| 524 | 468 | } |
| ... | ... | @@ -604,35 +548,35 @@ protected: |
| 604 | 548 | _LIBCPP_INLINE_VISIBILITY |
| 605 | 549 | __list_imp(const __node_allocator& __a); |
| 606 | 550 | #ifndef _LIBCPP_CXX03_LANG |
| 607 | __list_imp(__node_allocator&& __a) _NOEXCEPT; | |
| 551 | _LIBCPP_HIDE_FROM_ABI __list_imp(__node_allocator&& __a) _NOEXCEPT; | |
| 608 | 552 | #endif |
| 609 | ~__list_imp(); | |
| 610 | void clear() _NOEXCEPT; | |
| 553 | _LIBCPP_HIDE_FROM_ABI ~__list_imp(); | |
| 554 | _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; | |
| 611 | 555 | _LIBCPP_INLINE_VISIBILITY |
| 612 | 556 | bool empty() const _NOEXCEPT {return __sz() == 0;} |
| 613 | 557 | |
| 614 | 558 | _LIBCPP_INLINE_VISIBILITY |
| 615 | 559 | iterator begin() _NOEXCEPT |
| 616 | 560 | { |
| 617 | return iterator(__end_.__next_, this); | |
| 561 | return iterator(__end_.__next_); | |
| 618 | 562 | } |
| 619 | 563 | _LIBCPP_INLINE_VISIBILITY |
| 620 | 564 | const_iterator begin() const _NOEXCEPT |
| 621 | 565 | { |
| 622 | return const_iterator(__end_.__next_, this); | |
| 566 | return const_iterator(__end_.__next_); | |
| 623 | 567 | } |
| 624 | 568 | _LIBCPP_INLINE_VISIBILITY |
| 625 | 569 | iterator end() _NOEXCEPT |
| 626 | 570 | { |
| 627 | return iterator(__end_as_link(), this); | |
| 571 | return iterator(__end_as_link()); | |
| 628 | 572 | } |
| 629 | 573 | _LIBCPP_INLINE_VISIBILITY |
| 630 | 574 | const_iterator end() const _NOEXCEPT |
| 631 | 575 | { |
| 632 | return const_iterator(__end_as_link(), this); | |
| 576 | return const_iterator(__end_as_link()); | |
| 633 | 577 | } |
| 634 | 578 | |
| 635 | void swap(__list_imp& __c) | |
| 579 | _LIBCPP_HIDE_FROM_ABI void swap(__list_imp& __c) | |
| 636 | 580 | #if _LIBCPP_STD_VER >= 14 |
| 637 | 581 | _NOEXCEPT; |
| 638 | 582 | #else |
| ... | ... | @@ -718,7 +662,6 @@ inline __list_imp<_Tp, _Alloc>::__list_imp(__node_allocator&& __a) _NOEXCEPT |
| 718 | 662 | template <class _Tp, class _Alloc> |
| 719 | 663 | __list_imp<_Tp, _Alloc>::~__list_imp() { |
| 720 | 664 | clear(); |
| 721 | std::__debug_db_erase_c(this); | |
| 722 | 665 | } |
| 723 | 666 | |
| 724 | 667 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -739,7 +682,6 @@ __list_imp<_Tp, _Alloc>::clear() _NOEXCEPT |
| 739 | 682 | __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); |
| 740 | 683 | __node_alloc_traits::deallocate(__na, __np, 1); |
| 741 | 684 | } |
| 742 | std::__debug_db_invalidate_all(this); | |
| 743 | 685 | } |
| 744 | 686 | } |
| 745 | 687 | |
| ... | ... | @@ -753,10 +695,10 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) |
| 753 | 695 | __is_nothrow_swappable<allocator_type>::value) |
| 754 | 696 | #endif |
| 755 | 697 | { |
| 756 | _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || | |
| 757 | this->__node_alloc() == __c.__node_alloc(), | |
| 758 | "list::swap: Either propagate_on_container_swap must be true" | |
| 759 | " or the allocators must compare equal"); | |
| 698 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value || | |
| 699 | this->__node_alloc() == __c.__node_alloc(), | |
| 700 | "list::swap: Either propagate_on_container_swap must be true" | |
| 701 | " or the allocators must compare equal"); | |
| 760 | 702 | using _VSTD::swap; |
| 761 | 703 | _VSTD::__swap_allocator(__node_alloc(), __c.__node_alloc()); |
| 762 | 704 | swap(__sz(), __c.__sz()); |
| ... | ... | @@ -769,42 +711,6 @@ __list_imp<_Tp, _Alloc>::swap(__list_imp& __c) |
| 769 | 711 | __c.__end_.__next_ = __c.__end_.__prev_ = __c.__end_as_link(); |
| 770 | 712 | else |
| 771 | 713 | __c.__end_.__prev_->__next_ = __c.__end_.__next_->__prev_ = __c.__end_as_link(); |
| 772 | ||
| 773 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 774 | __libcpp_db* __db = __get_db(); | |
| 775 | __c_node* __cn1 = __db->__find_c_and_lock(this); | |
| 776 | __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); | |
| 777 | _VSTD::swap(__cn1->beg_, __cn2->beg_); | |
| 778 | _VSTD::swap(__cn1->end_, __cn2->end_); | |
| 779 | _VSTD::swap(__cn1->cap_, __cn2->cap_); | |
| 780 | for (__i_node** __p = __cn1->end_; __p != __cn1->beg_;) | |
| 781 | { | |
| 782 | --__p; | |
| 783 | const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); | |
| 784 | if (__i->__ptr_ == __c.__end_as_link()) | |
| 785 | { | |
| 786 | __cn2->__add(*__p); | |
| 787 | if (--__cn1->end_ != __p) | |
| 788 | _VSTD::memmove(__p, __p+1, (__cn1->end_ - __p)*sizeof(__i_node*)); | |
| 789 | } | |
| 790 | else | |
| 791 | (*__p)->__c_ = __cn1; | |
| 792 | } | |
| 793 | for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) | |
| 794 | { | |
| 795 | --__p; | |
| 796 | const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); | |
| 797 | if (__i->__ptr_ == __end_as_link()) | |
| 798 | { | |
| 799 | __cn1->__add(*__p); | |
| 800 | if (--__cn2->end_ != __p) | |
| 801 | _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); | |
| 802 | } | |
| 803 | else | |
| 804 | (*__p)->__c_ = __cn2; | |
| 805 | } | |
| 806 | __db->unlock(); | |
| 807 | #endif | |
| 808 | 714 | } |
| 809 | 715 | |
| 810 | 716 | template <class _Tp, class _Alloc /*= allocator<_Tp>*/> |
| ... | ... | @@ -824,7 +730,7 @@ public: |
| 824 | 730 | typedef _Tp value_type; |
| 825 | 731 | typedef _Alloc allocator_type; |
| 826 | 732 | static_assert((is_same<value_type, typename allocator_type::value_type>::value), |
| 827 | "Invalid allocator::value_type"); | |
| 733 | "Allocator::value_type must be same type as value_type"); | |
| 828 | 734 | typedef value_type& reference; |
| 829 | 735 | typedef const value_type& const_reference; |
| 830 | 736 | typedef typename base::pointer pointer; |
| ... | ... | @@ -835,7 +741,7 @@ public: |
| 835 | 741 | typedef typename base::const_iterator const_iterator; |
| 836 | 742 | typedef _VSTD::reverse_iterator<iterator> reverse_iterator; |
| 837 | 743 | typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; |
| 838 | #if _LIBCPP_STD_VER > 17 | |
| 744 | #if _LIBCPP_STD_VER >= 20 | |
| 839 | 745 | typedef size_type __remove_return_type; |
| 840 | 746 | #else |
| 841 | 747 | typedef void __remove_return_type; |
| ... | ... | @@ -849,40 +755,45 @@ public: |
| 849 | 755 | list() |
| 850 | 756 | _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) |
| 851 | 757 | { |
| 852 | _VSTD::__debug_db_insert_c(this); | |
| 853 | 758 | } |
| 854 | 759 | _LIBCPP_INLINE_VISIBILITY |
| 855 | 760 | explicit list(const allocator_type& __a) : base(__a) |
| 856 | 761 | { |
| 857 | _VSTD::__debug_db_insert_c(this); | |
| 858 | 762 | } |
| 859 | explicit list(size_type __n); | |
| 860 | #if _LIBCPP_STD_VER > 11 | |
| 861 | explicit list(size_type __n, const allocator_type& __a); | |
| 763 | _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n); | |
| 764 | #if _LIBCPP_STD_VER >= 14 | |
| 765 | _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a); | |
| 862 | 766 | #endif |
| 863 | list(size_type __n, const value_type& __x); | |
| 767 | _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x); | |
| 864 | 768 | template <class = __enable_if_t<__is_allocator<_Alloc>::value> > |
| 865 | list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) | |
| 769 | _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a) | |
| 866 | 770 | { |
| 867 | _VSTD::__debug_db_insert_c(this); | |
| 868 | 771 | for (; __n > 0; --__n) |
| 869 | 772 | push_back(__x); |
| 870 | 773 | } |
| 871 | 774 | |
| 872 | 775 | template <class _InpIter> |
| 873 | list(_InpIter __f, _InpIter __l, | |
| 874 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0); | |
| 776 | _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, | |
| 777 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0); | |
| 875 | 778 | template <class _InpIter> |
| 876 | list(_InpIter __f, _InpIter __l, const allocator_type& __a, | |
| 877 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0); | |
| 779 | _LIBCPP_HIDE_FROM_ABI list(_InpIter __f, _InpIter __l, const allocator_type& __a, | |
| 780 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0); | |
| 781 | ||
| 782 | #if _LIBCPP_STD_VER >= 23 | |
| 783 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 784 | _LIBCPP_HIDE_FROM_ABI list(from_range_t, _Range&& __range, | |
| 785 | const allocator_type& __a = allocator_type()) : base(__a) { | |
| 786 | prepend_range(std::forward<_Range>(__range)); | |
| 787 | } | |
| 788 | #endif | |
| 878 | 789 | |
| 879 | list(const list& __c); | |
| 880 | list(const list& __c, const __type_identity_t<allocator_type>& __a); | |
| 790 | _LIBCPP_HIDE_FROM_ABI list(const list& __c); | |
| 791 | _LIBCPP_HIDE_FROM_ABI list(const list& __c, const __type_identity_t<allocator_type>& __a); | |
| 881 | 792 | _LIBCPP_INLINE_VISIBILITY |
| 882 | 793 | list& operator=(const list& __c); |
| 883 | 794 | #ifndef _LIBCPP_CXX03_LANG |
| 884 | list(initializer_list<value_type> __il); | |
| 885 | list(initializer_list<value_type> __il, const allocator_type& __a); | |
| 795 | _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il); | |
| 796 | _LIBCPP_HIDE_FROM_ABI list(initializer_list<value_type> __il, const allocator_type& __a); | |
| 886 | 797 | |
| 887 | 798 | _LIBCPP_INLINE_VISIBILITY |
| 888 | 799 | list(list&& __c) |
| ... | ... | @@ -905,9 +816,18 @@ public: |
| 905 | 816 | #endif // _LIBCPP_CXX03_LANG |
| 906 | 817 | |
| 907 | 818 | template <class _InpIter> |
| 908 | void assign(_InpIter __f, _InpIter __l, | |
| 909 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0); | |
| 910 | void assign(size_type __n, const value_type& __x); | |
| 819 | _LIBCPP_HIDE_FROM_ABI void assign(_InpIter __f, _InpIter __l, | |
| 820 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0); | |
| 821 | ||
| 822 | #if _LIBCPP_STD_VER >= 23 | |
| 823 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 824 | _LIBCPP_HIDE_FROM_ABI | |
| 825 | void assign_range(_Range&& __range) { | |
| 826 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 827 | } | |
| 828 | #endif | |
| 829 | ||
| 830 | _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const value_type& __x); | |
| 911 | 831 | |
| 912 | 832 | _LIBCPP_INLINE_VISIBILITY |
| 913 | 833 | allocator_type get_allocator() const _NOEXCEPT; |
| ... | ... | @@ -959,56 +879,70 @@ public: |
| 959 | 879 | _LIBCPP_INLINE_VISIBILITY |
| 960 | 880 | reference front() |
| 961 | 881 | { |
| 962 | _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); | |
| 882 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); | |
| 963 | 883 | return base::__end_.__next_->__as_node()->__value_; |
| 964 | 884 | } |
| 965 | 885 | _LIBCPP_INLINE_VISIBILITY |
| 966 | 886 | const_reference front() const |
| 967 | 887 | { |
| 968 | _LIBCPP_ASSERT(!empty(), "list::front called on empty list"); | |
| 888 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::front called on empty list"); | |
| 969 | 889 | return base::__end_.__next_->__as_node()->__value_; |
| 970 | 890 | } |
| 971 | 891 | _LIBCPP_INLINE_VISIBILITY |
| 972 | 892 | reference back() |
| 973 | 893 | { |
| 974 | _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); | |
| 894 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); | |
| 975 | 895 | return base::__end_.__prev_->__as_node()->__value_; |
| 976 | 896 | } |
| 977 | 897 | _LIBCPP_INLINE_VISIBILITY |
| 978 | 898 | const_reference back() const |
| 979 | 899 | { |
| 980 | _LIBCPP_ASSERT(!empty(), "list::back called on empty list"); | |
| 900 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::back called on empty list"); | |
| 981 | 901 | return base::__end_.__prev_->__as_node()->__value_; |
| 982 | 902 | } |
| 983 | 903 | |
| 984 | 904 | #ifndef _LIBCPP_CXX03_LANG |
| 985 | void push_front(value_type&& __x); | |
| 986 | void push_back(value_type&& __x); | |
| 905 | _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x); | |
| 906 | _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x); | |
| 907 | ||
| 908 | #if _LIBCPP_STD_VER >= 23 | |
| 909 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 910 | _LIBCPP_HIDE_FROM_ABI | |
| 911 | void prepend_range(_Range&& __range) { | |
| 912 | insert_range(begin(), std::forward<_Range>(__range)); | |
| 913 | } | |
| 914 | ||
| 915 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 916 | _LIBCPP_HIDE_FROM_ABI | |
| 917 | void append_range(_Range&& __range) { | |
| 918 | insert_range(end(), std::forward<_Range>(__range)); | |
| 919 | } | |
| 920 | #endif | |
| 987 | 921 | |
| 988 | 922 | template <class... _Args> |
| 989 | #if _LIBCPP_STD_VER > 14 | |
| 990 | reference emplace_front(_Args&&... __args); | |
| 923 | #if _LIBCPP_STD_VER >= 17 | |
| 924 | _LIBCPP_HIDE_FROM_ABI reference emplace_front(_Args&&... __args); | |
| 991 | 925 | #else |
| 992 | void emplace_front(_Args&&... __args); | |
| 926 | _LIBCPP_HIDE_FROM_ABI void emplace_front(_Args&&... __args); | |
| 993 | 927 | #endif |
| 994 | 928 | template <class... _Args> |
| 995 | #if _LIBCPP_STD_VER > 14 | |
| 996 | reference emplace_back(_Args&&... __args); | |
| 929 | #if _LIBCPP_STD_VER >= 17 | |
| 930 | _LIBCPP_HIDE_FROM_ABI reference emplace_back(_Args&&... __args); | |
| 997 | 931 | #else |
| 998 | void emplace_back(_Args&&... __args); | |
| 932 | _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args); | |
| 999 | 933 | #endif |
| 1000 | 934 | template <class... _Args> |
| 1001 | iterator emplace(const_iterator __p, _Args&&... __args); | |
| 935 | _LIBCPP_HIDE_FROM_ABI iterator emplace(const_iterator __p, _Args&&... __args); | |
| 1002 | 936 | |
| 1003 | iterator insert(const_iterator __p, value_type&& __x); | |
| 937 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __x); | |
| 1004 | 938 | |
| 1005 | 939 | _LIBCPP_INLINE_VISIBILITY |
| 1006 | 940 | iterator insert(const_iterator __p, initializer_list<value_type> __il) |
| 1007 | 941 | {return insert(__p, __il.begin(), __il.end());} |
| 1008 | 942 | #endif // _LIBCPP_CXX03_LANG |
| 1009 | 943 | |
| 1010 | void push_front(const value_type& __x); | |
| 1011 | void push_back(const value_type& __x); | |
| 944 | _LIBCPP_HIDE_FROM_ABI void push_front(const value_type& __x); | |
| 945 | _LIBCPP_HIDE_FROM_ABI void push_back(const value_type& __x); | |
| 1012 | 946 | |
| 1013 | 947 | #ifndef _LIBCPP_CXX03_LANG |
| 1014 | 948 | template <class _Arg> |
| ... | ... | @@ -1019,11 +953,19 @@ public: |
| 1019 | 953 | void __emplace_back(value_type const& __arg) { push_back(__arg); } |
| 1020 | 954 | #endif |
| 1021 | 955 | |
| 1022 | iterator insert(const_iterator __p, const value_type& __x); | |
| 1023 | iterator insert(const_iterator __p, size_type __n, const value_type& __x); | |
| 956 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __x); | |
| 957 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, size_type __n, const value_type& __x); | |
| 1024 | 958 | template <class _InpIter> |
| 1025 | iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, | |
| 1026 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>* = 0); | |
| 959 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, _InpIter __f, _InpIter __l, | |
| 960 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>* = 0); | |
| 961 | ||
| 962 | #if _LIBCPP_STD_VER >= 23 | |
| 963 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 964 | _LIBCPP_HIDE_FROM_ABI | |
| 965 | iterator insert_range(const_iterator __position, _Range&& __range) { | |
| 966 | return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); | |
| 967 | } | |
| 968 | #endif | |
| 1027 | 969 | |
| 1028 | 970 | _LIBCPP_INLINE_VISIBILITY |
| 1029 | 971 | void swap(list& __c) |
| ... | ... | @@ -1037,16 +979,16 @@ public: |
| 1037 | 979 | _LIBCPP_INLINE_VISIBILITY |
| 1038 | 980 | void clear() _NOEXCEPT {base::clear();} |
| 1039 | 981 | |
| 1040 | void pop_front(); | |
| 1041 | void pop_back(); | |
| 982 | _LIBCPP_HIDE_FROM_ABI void pop_front(); | |
| 983 | _LIBCPP_HIDE_FROM_ABI void pop_back(); | |
| 1042 | 984 | |
| 1043 | iterator erase(const_iterator __p); | |
| 1044 | iterator erase(const_iterator __f, const_iterator __l); | |
| 985 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); | |
| 986 | _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l); | |
| 1045 | 987 | |
| 1046 | void resize(size_type __n); | |
| 1047 | void resize(size_type __n, const value_type& __x); | |
| 988 | _LIBCPP_HIDE_FROM_ABI void resize(size_type __n); | |
| 989 | _LIBCPP_HIDE_FROM_ABI void resize(size_type __n, const value_type& __x); | |
| 1048 | 990 | |
| 1049 | void splice(const_iterator __p, list& __c); | |
| 991 | _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c); | |
| 1050 | 992 | #ifndef _LIBCPP_CXX03_LANG |
| 1051 | 993 | _LIBCPP_INLINE_VISIBILITY |
| 1052 | 994 | void splice(const_iterator __p, list&& __c) {splice(__p, __c);} |
| ... | ... | @@ -1057,15 +999,16 @@ public: |
| 1057 | 999 | void splice(const_iterator __p, list&& __c, const_iterator __f, const_iterator __l) |
| 1058 | 1000 | {splice(__p, __c, __f, __l);} |
| 1059 | 1001 | #endif |
| 1060 | void splice(const_iterator __p, list& __c, const_iterator __i); | |
| 1061 | void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); | |
| 1002 | _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __i); | |
| 1003 | _LIBCPP_HIDE_FROM_ABI void splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l); | |
| 1062 | 1004 | |
| 1063 | __remove_return_type remove(const value_type& __x); | |
| 1064 | template <class _Pred> __remove_return_type remove_if(_Pred __pred); | |
| 1005 | _LIBCPP_HIDE_FROM_ABI __remove_return_type remove(const value_type& __x); | |
| 1006 | template <class _Pred> | |
| 1007 | _LIBCPP_HIDE_FROM_ABI __remove_return_type remove_if(_Pred __pred); | |
| 1065 | 1008 | _LIBCPP_INLINE_VISIBILITY |
| 1066 | 1009 | __remove_return_type unique() { return unique(__equal_to()); } |
| 1067 | 1010 | template <class _BinaryPred> |
| 1068 | __remove_return_type unique(_BinaryPred __binary_pred); | |
| 1011 | _LIBCPP_HIDE_FROM_ABI __remove_return_type unique(_BinaryPred __binary_pred); | |
| 1069 | 1012 | _LIBCPP_INLINE_VISIBILITY |
| 1070 | 1013 | void merge(list& __c); |
| 1071 | 1014 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -1077,7 +1020,7 @@ public: |
| 1077 | 1020 | void merge(list&& __c, _Comp __comp) {merge(__c, __comp);} |
| 1078 | 1021 | #endif |
| 1079 | 1022 | template <class _Comp> |
| 1080 | void merge(list& __c, _Comp __comp); | |
| 1023 | _LIBCPP_HIDE_FROM_ABI void merge(list& __c, _Comp __comp); | |
| 1081 | 1024 | |
| 1082 | 1025 | _LIBCPP_INLINE_VISIBILITY |
| 1083 | 1026 | void sort(); |
| ... | ... | @@ -1085,9 +1028,9 @@ public: |
| 1085 | 1028 | _LIBCPP_INLINE_VISIBILITY |
| 1086 | 1029 | void sort(_Comp __comp); |
| 1087 | 1030 | |
| 1088 | void reverse() _NOEXCEPT; | |
| 1031 | _LIBCPP_HIDE_FROM_ABI void reverse() _NOEXCEPT; | |
| 1089 | 1032 | |
| 1090 | bool __invariants() const; | |
| 1033 | _LIBCPP_HIDE_FROM_ABI bool __invariants() const; | |
| 1091 | 1034 | |
| 1092 | 1035 | typedef __allocator_destructor<__node_allocator> __node_destructor; |
| 1093 | 1036 | typedef unique_ptr<__node, __node_destructor> __hold_pointer; |
| ... | ... | @@ -1099,35 +1042,35 @@ public: |
| 1099 | 1042 | return __hold_pointer(__p, __node_destructor(__na, 1)); |
| 1100 | 1043 | } |
| 1101 | 1044 | |
| 1102 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1103 | ||
| 1104 | bool __dereferenceable(const const_iterator* __i) const; | |
| 1105 | bool __decrementable(const const_iterator* __i) const; | |
| 1106 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1107 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1045 | private: | |
| 1046 | template <class _Iterator, class _Sentinel> | |
| 1047 | _LIBCPP_HIDE_FROM_ABI | |
| 1048 | void __assign_with_sentinel(_Iterator __f, _Sentinel __l); | |
| 1108 | 1049 | |
| 1109 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 1050 | template <class _Iterator, class _Sentinel> | |
| 1051 | _LIBCPP_HIDE_FROM_ABI | |
| 1052 | iterator __insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l); | |
| 1110 | 1053 | |
| 1111 | private: | |
| 1112 | 1054 | _LIBCPP_INLINE_VISIBILITY |
| 1113 | 1055 | static void __link_nodes (__link_pointer __p, __link_pointer __f, __link_pointer __l); |
| 1114 | 1056 | _LIBCPP_INLINE_VISIBILITY |
| 1115 | 1057 | void __link_nodes_at_front(__link_pointer __f, __link_pointer __l); |
| 1116 | 1058 | _LIBCPP_INLINE_VISIBILITY |
| 1117 | 1059 | void __link_nodes_at_back (__link_pointer __f, __link_pointer __l); |
| 1118 | iterator __iterator(size_type __n); | |
| 1060 | _LIBCPP_HIDE_FROM_ABI iterator __iterator(size_type __n); | |
| 1061 | // TODO: Make this _LIBCPP_HIDE_FROM_ABI | |
| 1119 | 1062 | template <class _Comp> |
| 1120 | static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); | |
| 1063 | _LIBCPP_HIDDEN static iterator __sort(iterator __f1, iterator __e2, size_type __n, _Comp& __comp); | |
| 1121 | 1064 | |
| 1122 | void __move_assign(list& __c, true_type) | |
| 1065 | _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, true_type) | |
| 1123 | 1066 | _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value); |
| 1124 | void __move_assign(list& __c, false_type); | |
| 1067 | _LIBCPP_HIDE_FROM_ABI void __move_assign(list& __c, false_type); | |
| 1125 | 1068 | }; |
| 1126 | 1069 | |
| 1127 | 1070 | #if _LIBCPP_STD_VER >= 17 |
| 1128 | 1071 | template<class _InputIterator, |
| 1129 | 1072 | class _Alloc = allocator<__iter_value_type<_InputIterator>>, |
| 1130 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1073 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1131 | 1074 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 1132 | 1075 | > |
| 1133 | 1076 | list(_InputIterator, _InputIterator) |
| ... | ... | @@ -1135,13 +1078,22 @@ list(_InputIterator, _InputIterator) |
| 1135 | 1078 | |
| 1136 | 1079 | template<class _InputIterator, |
| 1137 | 1080 | class _Alloc, |
| 1138 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1081 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1139 | 1082 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 1140 | 1083 | > |
| 1141 | 1084 | list(_InputIterator, _InputIterator, _Alloc) |
| 1142 | 1085 | -> list<__iter_value_type<_InputIterator>, _Alloc>; |
| 1143 | 1086 | #endif |
| 1144 | 1087 | |
| 1088 | #if _LIBCPP_STD_VER >= 23 | |
| 1089 | template <ranges::input_range _Range, | |
| 1090 | class _Alloc = allocator<ranges::range_value_t<_Range>>, | |
| 1091 | class = enable_if_t<__is_allocator<_Alloc>::value> | |
| 1092 | > | |
| 1093 | list(from_range_t, _Range&&, _Alloc = _Alloc()) | |
| 1094 | -> list<ranges::range_value_t<_Range>, _Alloc>; | |
| 1095 | #endif | |
| 1096 | ||
| 1145 | 1097 | // Link in nodes [__f, __l] just prior to __p |
| 1146 | 1098 | template <class _Tp, class _Alloc> |
| 1147 | 1099 | inline |
| ... | ... | @@ -1191,7 +1143,6 @@ list<_Tp, _Alloc>::__iterator(size_type __n) |
| 1191 | 1143 | template <class _Tp, class _Alloc> |
| 1192 | 1144 | list<_Tp, _Alloc>::list(size_type __n) |
| 1193 | 1145 | { |
| 1194 | _VSTD::__debug_db_insert_c(this); | |
| 1195 | 1146 | for (; __n > 0; --__n) |
| 1196 | 1147 | #ifndef _LIBCPP_CXX03_LANG |
| 1197 | 1148 | emplace_back(); |
| ... | ... | @@ -1200,11 +1151,10 @@ list<_Tp, _Alloc>::list(size_type __n) |
| 1200 | 1151 | #endif |
| 1201 | 1152 | } |
| 1202 | 1153 | |
| 1203 | #if _LIBCPP_STD_VER > 11 | |
| 1154 | #if _LIBCPP_STD_VER >= 14 | |
| 1204 | 1155 | template <class _Tp, class _Alloc> |
| 1205 | 1156 | list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) |
| 1206 | 1157 | { |
| 1207 | _VSTD::__debug_db_insert_c(this); | |
| 1208 | 1158 | for (; __n > 0; --__n) |
| 1209 | 1159 | emplace_back(); |
| 1210 | 1160 | } |
| ... | ... | @@ -1213,7 +1163,6 @@ list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : base(__a) |
| 1213 | 1163 | template <class _Tp, class _Alloc> |
| 1214 | 1164 | list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) |
| 1215 | 1165 | { |
| 1216 | _VSTD::__debug_db_insert_c(this); | |
| 1217 | 1166 | for (; __n > 0; --__n) |
| 1218 | 1167 | push_back(__x); |
| 1219 | 1168 | } |
| ... | ... | @@ -1221,9 +1170,8 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) |
| 1221 | 1170 | template <class _Tp, class _Alloc> |
| 1222 | 1171 | template <class _InpIter> |
| 1223 | 1172 | list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, |
| 1224 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*) | |
| 1173 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>*) | |
| 1225 | 1174 | { |
| 1226 | _VSTD::__debug_db_insert_c(this); | |
| 1227 | 1175 | for (; __f != __l; ++__f) |
| 1228 | 1176 | __emplace_back(*__f); |
| 1229 | 1177 | } |
| ... | ... | @@ -1231,10 +1179,9 @@ list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, |
| 1231 | 1179 | template <class _Tp, class _Alloc> |
| 1232 | 1180 | template <class _InpIter> |
| 1233 | 1181 | list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l, const allocator_type& __a, |
| 1234 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*) | |
| 1182 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>*) | |
| 1235 | 1183 | : base(__a) |
| 1236 | 1184 | { |
| 1237 | _VSTD::__debug_db_insert_c(this); | |
| 1238 | 1185 | for (; __f != __l; ++__f) |
| 1239 | 1186 | __emplace_back(*__f); |
| 1240 | 1187 | } |
| ... | ... | @@ -1243,7 +1190,6 @@ template <class _Tp, class _Alloc> |
| 1243 | 1190 | list<_Tp, _Alloc>::list(const list& __c) |
| 1244 | 1191 | : base(__node_alloc_traits::select_on_container_copy_construction( |
| 1245 | 1192 | __c.__node_alloc())) { |
| 1246 | _VSTD::__debug_db_insert_c(this); | |
| 1247 | 1193 | for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) |
| 1248 | 1194 | push_back(*__i); |
| 1249 | 1195 | } |
| ... | ... | @@ -1252,7 +1198,6 @@ template <class _Tp, class _Alloc> |
| 1252 | 1198 | list<_Tp, _Alloc>::list(const list& __c, const __type_identity_t<allocator_type>& __a) |
| 1253 | 1199 | : base(__a) |
| 1254 | 1200 | { |
| 1255 | _VSTD::__debug_db_insert_c(this); | |
| 1256 | 1201 | for (const_iterator __i = __c.begin(), __e = __c.end(); __i != __e; ++__i) |
| 1257 | 1202 | push_back(*__i); |
| 1258 | 1203 | } |
| ... | ... | @@ -1263,7 +1208,6 @@ template <class _Tp, class _Alloc> |
| 1263 | 1208 | list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& __a) |
| 1264 | 1209 | : base(__a) |
| 1265 | 1210 | { |
| 1266 | _VSTD::__debug_db_insert_c(this); | |
| 1267 | 1211 | for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), |
| 1268 | 1212 | __e = __il.end(); __i != __e; ++__i) |
| 1269 | 1213 | push_back(*__i); |
| ... | ... | @@ -1272,7 +1216,6 @@ list<_Tp, _Alloc>::list(initializer_list<value_type> __il, const allocator_type& |
| 1272 | 1216 | template <class _Tp, class _Alloc> |
| 1273 | 1217 | list<_Tp, _Alloc>::list(initializer_list<value_type> __il) |
| 1274 | 1218 | { |
| 1275 | _VSTD::__debug_db_insert_c(this); | |
| 1276 | 1219 | for (typename initializer_list<value_type>::const_iterator __i = __il.begin(), |
| 1277 | 1220 | __e = __il.end(); __i != __e; ++__i) |
| 1278 | 1221 | push_back(*__i); |
| ... | ... | @@ -1282,7 +1225,6 @@ template <class _Tp, class _Alloc> |
| 1282 | 1225 | inline list<_Tp, _Alloc>::list(list&& __c) |
| 1283 | 1226 | _NOEXCEPT_(is_nothrow_move_constructible<__node_allocator>::value) |
| 1284 | 1227 | : base(_VSTD::move(__c.__node_alloc())) { |
| 1285 | _VSTD::__debug_db_insert_c(this); | |
| 1286 | 1228 | splice(end(), __c); |
| 1287 | 1229 | } |
| 1288 | 1230 | |
| ... | ... | @@ -1291,7 +1233,6 @@ inline |
| 1291 | 1233 | list<_Tp, _Alloc>::list(list&& __c, const __type_identity_t<allocator_type>& __a) |
| 1292 | 1234 | : base(__a) |
| 1293 | 1235 | { |
| 1294 | _VSTD::__debug_db_insert_c(this); | |
| 1295 | 1236 | if (__a == __c.get_allocator()) |
| 1296 | 1237 | splice(end(), __c); |
| 1297 | 1238 | else |
| ... | ... | @@ -1356,17 +1297,23 @@ template <class _Tp, class _Alloc> |
| 1356 | 1297 | template <class _InpIter> |
| 1357 | 1298 | void |
| 1358 | 1299 | list<_Tp, _Alloc>::assign(_InpIter __f, _InpIter __l, |
| 1359 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*) | |
| 1300 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>*) | |
| 1360 | 1301 | { |
| 1302 | __assign_with_sentinel(__f, __l); | |
| 1303 | } | |
| 1304 | ||
| 1305 | template <class _Tp, class _Alloc> | |
| 1306 | template <class _Iterator, class _Sentinel> | |
| 1307 | _LIBCPP_HIDE_FROM_ABI | |
| 1308 | void list<_Tp, _Alloc>::__assign_with_sentinel(_Iterator __f, _Sentinel __l) { | |
| 1361 | 1309 | iterator __i = begin(); |
| 1362 | 1310 | iterator __e = end(); |
| 1363 | 1311 | for (; __f != __l && __i != __e; ++__f, (void) ++__i) |
| 1364 | 1312 | *__i = *__f; |
| 1365 | 1313 | if (__i == __e) |
| 1366 | insert(__e, __f, __l); | |
| 1314 | __insert_with_sentinel(__e, std::move(__f), std::move(__l)); | |
| 1367 | 1315 | else |
| 1368 | 1316 | erase(__i, __e); |
| 1369 | std::__debug_db_invalidate_all(this); | |
| 1370 | 1317 | } |
| 1371 | 1318 | |
| 1372 | 1319 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -1381,7 +1328,6 @@ list<_Tp, _Alloc>::assign(size_type __n, const value_type& __x) |
| 1381 | 1328 | insert(__e, __n, __x); |
| 1382 | 1329 | else |
| 1383 | 1330 | erase(__i, __e); |
| 1384 | std::__debug_db_invalidate_all(this); | |
| 1385 | 1331 | } |
| 1386 | 1332 | |
| 1387 | 1333 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -1396,23 +1342,19 @@ template <class _Tp, class _Alloc> |
| 1396 | 1342 | typename list<_Tp, _Alloc>::iterator |
| 1397 | 1343 | list<_Tp, _Alloc>::insert(const_iterator __p, const value_type& __x) |
| 1398 | 1344 | { |
| 1399 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1400 | "list::insert(iterator, x) called with an iterator not referring to this list"); | |
| 1401 | 1345 | __node_allocator& __na = base::__node_alloc(); |
| 1402 | 1346 | __hold_pointer __hold = __allocate_node(__na); |
| 1403 | 1347 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); |
| 1404 | 1348 | __link_nodes(__p.__ptr_, __hold->__as_link(), __hold->__as_link()); |
| 1405 | 1349 | ++base::__sz(); |
| 1406 | return iterator(__hold.release()->__as_link(), this); | |
| 1350 | return iterator(__hold.release()->__as_link()); | |
| 1407 | 1351 | } |
| 1408 | 1352 | |
| 1409 | 1353 | template <class _Tp, class _Alloc> |
| 1410 | 1354 | typename list<_Tp, _Alloc>::iterator |
| 1411 | 1355 | list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& __x) |
| 1412 | 1356 | { |
| 1413 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1414 | "list::insert(iterator, n, x) called with an iterator not referring to this list"); | |
| 1415 | iterator __r(__p.__ptr_, this); | |
| 1357 | iterator __r(__p.__ptr_); | |
| 1416 | 1358 | if (__n > 0) |
| 1417 | 1359 | { |
| 1418 | 1360 | size_type __ds = 0; |
| ... | ... | @@ -1420,13 +1362,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _ |
| 1420 | 1362 | __hold_pointer __hold = __allocate_node(__na); |
| 1421 | 1363 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); |
| 1422 | 1364 | ++__ds; |
| 1423 | __r = iterator(__hold->__as_link(), this); | |
| 1365 | __r = iterator(__hold->__as_link()); | |
| 1424 | 1366 | __hold.release(); |
| 1425 | 1367 | iterator __e = __r; |
| 1426 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1368 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1427 | 1369 | try |
| 1428 | 1370 | { |
| 1429 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1371 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1430 | 1372 | for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) |
| 1431 | 1373 | { |
| 1432 | 1374 | __hold.reset(__node_alloc_traits::allocate(__na, 1)); |
| ... | ... | @@ -1435,7 +1377,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _ |
| 1435 | 1377 | __hold->__prev_ = __e.__ptr_; |
| 1436 | 1378 | __hold.release(); |
| 1437 | 1379 | } |
| 1438 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1380 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1439 | 1381 | } |
| 1440 | 1382 | catch (...) |
| 1441 | 1383 | { |
| ... | ... | @@ -1446,11 +1388,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, size_type __n, const value_type& _ |
| 1446 | 1388 | __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); |
| 1447 | 1389 | if (__prev == 0) |
| 1448 | 1390 | break; |
| 1449 | __e = iterator(__prev, this); | |
| 1391 | __e = iterator(__prev); | |
| 1450 | 1392 | } |
| 1451 | 1393 | throw; |
| 1452 | 1394 | } |
| 1453 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1395 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1454 | 1396 | __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); |
| 1455 | 1397 | base::__sz() += __ds; |
| 1456 | 1398 | } |
| ... | ... | @@ -1461,11 +1403,17 @@ template <class _Tp, class _Alloc> |
| 1461 | 1403 | template <class _InpIter> |
| 1462 | 1404 | typename list<_Tp, _Alloc>::iterator |
| 1463 | 1405 | list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, |
| 1464 | __enable_if_t<__is_cpp17_input_iterator<_InpIter>::value>*) | |
| 1406 | __enable_if_t<__has_input_iterator_category<_InpIter>::value>*) | |
| 1465 | 1407 | { |
| 1466 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1467 | "list::insert(iterator, range) called with an iterator not referring to this list"); | |
| 1468 | iterator __r(__p.__ptr_, this); | |
| 1408 | return __insert_with_sentinel(__p, __f, __l); | |
| 1409 | } | |
| 1410 | ||
| 1411 | template <class _Tp, class _Alloc> | |
| 1412 | template <class _Iterator, class _Sentinel> | |
| 1413 | _LIBCPP_HIDE_FROM_ABI | |
| 1414 | typename list<_Tp, _Alloc>::iterator | |
| 1415 | list<_Tp, _Alloc>::__insert_with_sentinel(const_iterator __p, _Iterator __f, _Sentinel __l) { | |
| 1416 | iterator __r(__p.__ptr_); | |
| 1469 | 1417 | if (__f != __l) |
| 1470 | 1418 | { |
| 1471 | 1419 | size_type __ds = 0; |
| ... | ... | @@ -1473,13 +1421,13 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, |
| 1473 | 1421 | __hold_pointer __hold = __allocate_node(__na); |
| 1474 | 1422 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), *__f); |
| 1475 | 1423 | ++__ds; |
| 1476 | __r = iterator(__hold.get()->__as_link(), this); | |
| 1424 | __r = iterator(__hold.get()->__as_link()); | |
| 1477 | 1425 | __hold.release(); |
| 1478 | 1426 | iterator __e = __r; |
| 1479 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1427 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1480 | 1428 | try |
| 1481 | 1429 | { |
| 1482 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1430 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1483 | 1431 | for (++__f; __f != __l; ++__f, (void) ++__e, ++__ds) |
| 1484 | 1432 | { |
| 1485 | 1433 | __hold.reset(__node_alloc_traits::allocate(__na, 1)); |
| ... | ... | @@ -1488,7 +1436,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, |
| 1488 | 1436 | __hold->__prev_ = __e.__ptr_; |
| 1489 | 1437 | __hold.release(); |
| 1490 | 1438 | } |
| 1491 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1439 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1492 | 1440 | } |
| 1493 | 1441 | catch (...) |
| 1494 | 1442 | { |
| ... | ... | @@ -1499,11 +1447,11 @@ list<_Tp, _Alloc>::insert(const_iterator __p, _InpIter __f, _InpIter __l, |
| 1499 | 1447 | __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); |
| 1500 | 1448 | if (__prev == 0) |
| 1501 | 1449 | break; |
| 1502 | __e = iterator(__prev, this); | |
| 1450 | __e = iterator(__prev); | |
| 1503 | 1451 | } |
| 1504 | 1452 | throw; |
| 1505 | 1453 | } |
| 1506 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1454 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1507 | 1455 | __link_nodes(__p.__ptr_, __r.__ptr_, __e.__ptr_); |
| 1508 | 1456 | base::__sz() += __ds; |
| 1509 | 1457 | } |
| ... | ... | @@ -1563,7 +1511,7 @@ list<_Tp, _Alloc>::push_back(value_type&& __x) |
| 1563 | 1511 | |
| 1564 | 1512 | template <class _Tp, class _Alloc> |
| 1565 | 1513 | template <class... _Args> |
| 1566 | #if _LIBCPP_STD_VER > 14 | |
| 1514 | #if _LIBCPP_STD_VER >= 17 | |
| 1567 | 1515 | typename list<_Tp, _Alloc>::reference |
| 1568 | 1516 | #else |
| 1569 | 1517 | void |
| ... | ... | @@ -1575,7 +1523,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args) |
| 1575 | 1523 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); |
| 1576 | 1524 | __link_nodes_at_front(__hold.get()->__as_link(), __hold.get()->__as_link()); |
| 1577 | 1525 | ++base::__sz(); |
| 1578 | #if _LIBCPP_STD_VER > 14 | |
| 1526 | #if _LIBCPP_STD_VER >= 17 | |
| 1579 | 1527 | return __hold.release()->__value_; |
| 1580 | 1528 | #else |
| 1581 | 1529 | __hold.release(); |
| ... | ... | @@ -1584,7 +1532,7 @@ list<_Tp, _Alloc>::emplace_front(_Args&&... __args) |
| 1584 | 1532 | |
| 1585 | 1533 | template <class _Tp, class _Alloc> |
| 1586 | 1534 | template <class... _Args> |
| 1587 | #if _LIBCPP_STD_VER > 14 | |
| 1535 | #if _LIBCPP_STD_VER >= 17 | |
| 1588 | 1536 | typename list<_Tp, _Alloc>::reference |
| 1589 | 1537 | #else |
| 1590 | 1538 | void |
| ... | ... | @@ -1597,7 +1545,7 @@ list<_Tp, _Alloc>::emplace_back(_Args&&... __args) |
| 1597 | 1545 | __link_pointer __nl = __hold->__as_link(); |
| 1598 | 1546 | __link_nodes_at_back(__nl, __nl); |
| 1599 | 1547 | ++base::__sz(); |
| 1600 | #if _LIBCPP_STD_VER > 14 | |
| 1548 | #if _LIBCPP_STD_VER >= 17 | |
| 1601 | 1549 | return __hold.release()->__value_; |
| 1602 | 1550 | #else |
| 1603 | 1551 | __hold.release(); |
| ... | ... | @@ -1609,8 +1557,6 @@ template <class... _Args> |
| 1609 | 1557 | typename list<_Tp, _Alloc>::iterator |
| 1610 | 1558 | list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) |
| 1611 | 1559 | { |
| 1612 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1613 | "list::emplace(iterator, args...) called with an iterator not referring to this list"); | |
| 1614 | 1560 | __node_allocator& __na = base::__node_alloc(); |
| 1615 | 1561 | __hold_pointer __hold = __allocate_node(__na); |
| 1616 | 1562 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::forward<_Args>(__args)...); |
| ... | ... | @@ -1618,15 +1564,13 @@ list<_Tp, _Alloc>::emplace(const_iterator __p, _Args&&... __args) |
| 1618 | 1564 | __link_nodes(__p.__ptr_, __nl, __nl); |
| 1619 | 1565 | ++base::__sz(); |
| 1620 | 1566 | __hold.release(); |
| 1621 | return iterator(__nl, this); | |
| 1567 | return iterator(__nl); | |
| 1622 | 1568 | } |
| 1623 | 1569 | |
| 1624 | 1570 | template <class _Tp, class _Alloc> |
| 1625 | 1571 | typename list<_Tp, _Alloc>::iterator |
| 1626 | 1572 | list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) |
| 1627 | 1573 | { |
| 1628 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1629 | "list::insert(iterator, x) called with an iterator not referring to this list"); | |
| 1630 | 1574 | __node_allocator& __na = base::__node_alloc(); |
| 1631 | 1575 | __hold_pointer __hold = __allocate_node(__na); |
| 1632 | 1576 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), _VSTD::move(__x)); |
| ... | ... | @@ -1634,7 +1578,7 @@ list<_Tp, _Alloc>::insert(const_iterator __p, value_type&& __x) |
| 1634 | 1578 | __link_nodes(__p.__ptr_, __nl, __nl); |
| 1635 | 1579 | ++base::__sz(); |
| 1636 | 1580 | __hold.release(); |
| 1637 | return iterator(__nl, this); | |
| 1581 | return iterator(__nl); | |
| 1638 | 1582 | } |
| 1639 | 1583 | |
| 1640 | 1584 | #endif // _LIBCPP_CXX03_LANG |
| ... | ... | @@ -1643,26 +1587,11 @@ template <class _Tp, class _Alloc> |
| 1643 | 1587 | void |
| 1644 | 1588 | list<_Tp, _Alloc>::pop_front() |
| 1645 | 1589 | { |
| 1646 | _LIBCPP_ASSERT(!empty(), "list::pop_front() called with empty list"); | |
| 1590 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_front() called with empty list"); | |
| 1647 | 1591 | __node_allocator& __na = base::__node_alloc(); |
| 1648 | 1592 | __link_pointer __n = base::__end_.__next_; |
| 1649 | 1593 | base::__unlink_nodes(__n, __n); |
| 1650 | 1594 | --base::__sz(); |
| 1651 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1652 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 1653 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) | |
| 1654 | { | |
| 1655 | --__p; | |
| 1656 | iterator* __i = static_cast<iterator*>((*__p)->__i_); | |
| 1657 | if (__i->__ptr_ == __n) | |
| 1658 | { | |
| 1659 | (*__p)->__c_ = nullptr; | |
| 1660 | if (--__c->end_ != __p) | |
| 1661 | _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 1662 | } | |
| 1663 | } | |
| 1664 | __get_db()->unlock(); | |
| 1665 | #endif | |
| 1666 | 1595 | __node_pointer __np = __n->__as_node(); |
| 1667 | 1596 | __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); |
| 1668 | 1597 | __node_alloc_traits::deallocate(__na, __np, 1); |
| ... | ... | @@ -1672,26 +1601,11 @@ template <class _Tp, class _Alloc> |
| 1672 | 1601 | void |
| 1673 | 1602 | list<_Tp, _Alloc>::pop_back() |
| 1674 | 1603 | { |
| 1675 | _LIBCPP_ASSERT(!empty(), "list::pop_back() called on an empty list"); | |
| 1604 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "list::pop_back() called on an empty list"); | |
| 1676 | 1605 | __node_allocator& __na = base::__node_alloc(); |
| 1677 | 1606 | __link_pointer __n = base::__end_.__prev_; |
| 1678 | 1607 | base::__unlink_nodes(__n, __n); |
| 1679 | 1608 | --base::__sz(); |
| 1680 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1681 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 1682 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) | |
| 1683 | { | |
| 1684 | --__p; | |
| 1685 | iterator* __i = static_cast<iterator*>((*__p)->__i_); | |
| 1686 | if (__i->__ptr_ == __n) | |
| 1687 | { | |
| 1688 | (*__p)->__c_ = nullptr; | |
| 1689 | if (--__c->end_ != __p) | |
| 1690 | _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 1691 | } | |
| 1692 | } | |
| 1693 | __get_db()->unlock(); | |
| 1694 | #endif | |
| 1695 | 1609 | __node_pointer __np = __n->__as_node(); |
| 1696 | 1610 | __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); |
| 1697 | 1611 | __node_alloc_traits::deallocate(__na, __np, 1); |
| ... | ... | @@ -1701,44 +1615,23 @@ template <class _Tp, class _Alloc> |
| 1701 | 1615 | typename list<_Tp, _Alloc>::iterator |
| 1702 | 1616 | list<_Tp, _Alloc>::erase(const_iterator __p) |
| 1703 | 1617 | { |
| 1704 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1705 | "list::erase(iterator) called with an iterator not referring to this list"); | |
| 1706 | _LIBCPP_ASSERT(__p != end(), | |
| 1618 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p != end(), | |
| 1707 | 1619 | "list::erase(iterator) called with a non-dereferenceable iterator"); |
| 1708 | 1620 | __node_allocator& __na = base::__node_alloc(); |
| 1709 | 1621 | __link_pointer __n = __p.__ptr_; |
| 1710 | 1622 | __link_pointer __r = __n->__next_; |
| 1711 | 1623 | base::__unlink_nodes(__n, __n); |
| 1712 | 1624 | --base::__sz(); |
| 1713 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1714 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 1715 | for (__i_node** __ip = __c->end_; __ip != __c->beg_; ) | |
| 1716 | { | |
| 1717 | --__ip; | |
| 1718 | iterator* __i = static_cast<iterator*>((*__ip)->__i_); | |
| 1719 | if (__i->__ptr_ == __n) | |
| 1720 | { | |
| 1721 | (*__ip)->__c_ = nullptr; | |
| 1722 | if (--__c->end_ != __ip) | |
| 1723 | _VSTD::memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*)); | |
| 1724 | } | |
| 1725 | } | |
| 1726 | __get_db()->unlock(); | |
| 1727 | #endif | |
| 1728 | 1625 | __node_pointer __np = __n->__as_node(); |
| 1729 | 1626 | __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); |
| 1730 | 1627 | __node_alloc_traits::deallocate(__na, __np, 1); |
| 1731 | return iterator(__r, this); | |
| 1628 | return iterator(__r); | |
| 1732 | 1629 | } |
| 1733 | 1630 | |
| 1734 | 1631 | template <class _Tp, class _Alloc> |
| 1735 | 1632 | typename list<_Tp, _Alloc>::iterator |
| 1736 | 1633 | list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) |
| 1737 | 1634 | { |
| 1738 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == this, | |
| 1739 | "list::erase(iterator, iterator) called with an iterator not referring to this list"); | |
| 1740 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == this, | |
| 1741 | "list::erase(iterator, iterator) called with an iterator not referring to this list"); | |
| 1742 | 1635 | if (__f != __l) |
| 1743 | 1636 | { |
| 1744 | 1637 | __node_allocator& __na = base::__node_alloc(); |
| ... | ... | @@ -1748,27 +1641,12 @@ list<_Tp, _Alloc>::erase(const_iterator __f, const_iterator __l) |
| 1748 | 1641 | __link_pointer __n = __f.__ptr_; |
| 1749 | 1642 | ++__f; |
| 1750 | 1643 | --base::__sz(); |
| 1751 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1752 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 1753 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) | |
| 1754 | { | |
| 1755 | --__p; | |
| 1756 | iterator* __i = static_cast<iterator*>((*__p)->__i_); | |
| 1757 | if (__i->__ptr_ == __n) | |
| 1758 | { | |
| 1759 | (*__p)->__c_ = nullptr; | |
| 1760 | if (--__c->end_ != __p) | |
| 1761 | _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 1762 | } | |
| 1763 | } | |
| 1764 | __get_db()->unlock(); | |
| 1765 | #endif | |
| 1766 | 1644 | __node_pointer __np = __n->__as_node(); |
| 1767 | 1645 | __node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_)); |
| 1768 | 1646 | __node_alloc_traits::deallocate(__na, __np, 1); |
| 1769 | 1647 | } |
| 1770 | 1648 | } |
| 1771 | return iterator(__l.__ptr_, this); | |
| 1649 | return iterator(__l.__ptr_); | |
| 1772 | 1650 | } |
| 1773 | 1651 | |
| 1774 | 1652 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -1785,12 +1663,12 @@ list<_Tp, _Alloc>::resize(size_type __n) |
| 1785 | 1663 | __hold_pointer __hold = __allocate_node(__na); |
| 1786 | 1664 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_)); |
| 1787 | 1665 | ++__ds; |
| 1788 | iterator __r = iterator(__hold.release()->__as_link(), this); | |
| 1666 | iterator __r = iterator(__hold.release()->__as_link()); | |
| 1789 | 1667 | iterator __e = __r; |
| 1790 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1668 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1791 | 1669 | try |
| 1792 | 1670 | { |
| 1793 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1671 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1794 | 1672 | for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) |
| 1795 | 1673 | { |
| 1796 | 1674 | __hold.reset(__node_alloc_traits::allocate(__na, 1)); |
| ... | ... | @@ -1799,7 +1677,7 @@ list<_Tp, _Alloc>::resize(size_type __n) |
| 1799 | 1677 | __hold->__prev_ = __e.__ptr_; |
| 1800 | 1678 | __hold.release(); |
| 1801 | 1679 | } |
| 1802 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1680 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1803 | 1681 | } |
| 1804 | 1682 | catch (...) |
| 1805 | 1683 | { |
| ... | ... | @@ -1810,11 +1688,11 @@ list<_Tp, _Alloc>::resize(size_type __n) |
| 1810 | 1688 | __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); |
| 1811 | 1689 | if (__prev == 0) |
| 1812 | 1690 | break; |
| 1813 | __e = iterator(__prev, this); | |
| 1691 | __e = iterator(__prev); | |
| 1814 | 1692 | } |
| 1815 | 1693 | throw; |
| 1816 | 1694 | } |
| 1817 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1695 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1818 | 1696 | __link_nodes_at_back(__r.__ptr_, __e.__ptr_); |
| 1819 | 1697 | base::__sz() += __ds; |
| 1820 | 1698 | } |
| ... | ... | @@ -1835,12 +1713,12 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) |
| 1835 | 1713 | __node_alloc_traits::construct(__na, _VSTD::addressof(__hold->__value_), __x); |
| 1836 | 1714 | ++__ds; |
| 1837 | 1715 | __link_pointer __nl = __hold.release()->__as_link(); |
| 1838 | iterator __r = iterator(__nl, this); | |
| 1716 | iterator __r = iterator(__nl); | |
| 1839 | 1717 | iterator __e = __r; |
| 1840 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1718 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1841 | 1719 | try |
| 1842 | 1720 | { |
| 1843 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1721 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1844 | 1722 | for (--__n; __n != 0; --__n, (void) ++__e, ++__ds) |
| 1845 | 1723 | { |
| 1846 | 1724 | __hold.reset(__node_alloc_traits::allocate(__na, 1)); |
| ... | ... | @@ -1849,7 +1727,7 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) |
| 1849 | 1727 | __hold->__prev_ = __e.__ptr_; |
| 1850 | 1728 | __hold.release(); |
| 1851 | 1729 | } |
| 1852 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1730 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1853 | 1731 | } |
| 1854 | 1732 | catch (...) |
| 1855 | 1733 | { |
| ... | ... | @@ -1860,11 +1738,11 @@ list<_Tp, _Alloc>::resize(size_type __n, const value_type& __x) |
| 1860 | 1738 | __node_alloc_traits::deallocate(__na, __e.__ptr_->__as_node(), 1); |
| 1861 | 1739 | if (__prev == 0) |
| 1862 | 1740 | break; |
| 1863 | __e = iterator(__prev, this); | |
| 1741 | __e = iterator(__prev); | |
| 1864 | 1742 | } |
| 1865 | 1743 | throw; |
| 1866 | 1744 | } |
| 1867 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1745 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1868 | 1746 | __link_nodes(base::__end_as_link(), __r.__ptr_, __e.__ptr_); |
| 1869 | 1747 | base::__sz() += __ds; |
| 1870 | 1748 | } |
| ... | ... | @@ -1874,10 +1752,8 @@ template <class _Tp, class _Alloc> |
| 1874 | 1752 | void |
| 1875 | 1753 | list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) |
| 1876 | 1754 | { |
| 1877 | _LIBCPP_ASSERT(this != _VSTD::addressof(__c), | |
| 1878 | "list::splice(iterator, list) called with this == &list"); | |
| 1879 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1880 | "list::splice(iterator, list) called with an iterator not referring to this list"); | |
| 1755 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(this != _VSTD::addressof(__c), | |
| 1756 | "list::splice(iterator, list) called with this == &list"); | |
| 1881 | 1757 | if (!__c.empty()) |
| 1882 | 1758 | { |
| 1883 | 1759 | __link_pointer __f = __c.__end_.__next_; |
| ... | ... | @@ -1886,26 +1762,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c) |
| 1886 | 1762 | __link_nodes(__p.__ptr_, __f, __l); |
| 1887 | 1763 | base::__sz() += __c.__sz(); |
| 1888 | 1764 | __c.__sz() = 0; |
| 1889 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1890 | if (_VSTD::addressof(__c) != this) { | |
| 1891 | __libcpp_db* __db = __get_db(); | |
| 1892 | __c_node* __cn1 = __db->__find_c_and_lock(this); | |
| 1893 | __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); | |
| 1894 | for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) | |
| 1895 | { | |
| 1896 | --__ip; | |
| 1897 | iterator* __i = static_cast<iterator*>((*__ip)->__i_); | |
| 1898 | if (__i->__ptr_ != __c.__end_as_link()) | |
| 1899 | { | |
| 1900 | __cn1->__add(*__ip); | |
| 1901 | (*__ip)->__c_ = __cn1; | |
| 1902 | if (--__cn2->end_ != __ip) | |
| 1903 | _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); | |
| 1904 | } | |
| 1905 | } | |
| 1906 | __db->unlock(); | |
| 1907 | } | |
| 1908 | #endif | |
| 1909 | 1765 | } |
| 1910 | 1766 | } |
| 1911 | 1767 | |
| ... | ... | @@ -1913,13 +1769,6 @@ template <class _Tp, class _Alloc> |
| 1913 | 1769 | void |
| 1914 | 1770 | list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) |
| 1915 | 1771 | { |
| 1916 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1917 | "list::splice(iterator, list, iterator) called with the first iterator not referring to this list"); | |
| 1918 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__i)) == _VSTD::addressof(__c), | |
| 1919 | "list::splice(iterator, list, iterator) called with the second iterator not referring to the list argument"); | |
| 1920 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(_VSTD::addressof(__i)), | |
| 1921 | "list::splice(iterator, list, iterator) called with the second iterator not dereferenceable"); | |
| 1922 | ||
| 1923 | 1772 | if (__p.__ptr_ != __i.__ptr_ && __p.__ptr_ != __i.__ptr_->__next_) |
| 1924 | 1773 | { |
| 1925 | 1774 | __link_pointer __f = __i.__ptr_; |
| ... | ... | @@ -1927,26 +1776,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i) |
| 1927 | 1776 | __link_nodes(__p.__ptr_, __f, __f); |
| 1928 | 1777 | --__c.__sz(); |
| 1929 | 1778 | ++base::__sz(); |
| 1930 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1931 | if (_VSTD::addressof(__c) != this) { | |
| 1932 | __libcpp_db* __db = __get_db(); | |
| 1933 | __c_node* __cn1 = __db->__find_c_and_lock(this); | |
| 1934 | __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); | |
| 1935 | for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) | |
| 1936 | { | |
| 1937 | --__ip; | |
| 1938 | iterator* __j = static_cast<iterator*>((*__ip)->__i_); | |
| 1939 | if (__j->__ptr_ == __f) | |
| 1940 | { | |
| 1941 | __cn1->__add(*__ip); | |
| 1942 | (*__ip)->__c_ = __cn1; | |
| 1943 | if (--__cn2->end_ != __ip) | |
| 1944 | _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); | |
| 1945 | } | |
| 1946 | } | |
| 1947 | __db->unlock(); | |
| 1948 | } | |
| 1949 | #endif | |
| 1950 | 1779 | } |
| 1951 | 1780 | } |
| 1952 | 1781 | |
| ... | ... | @@ -1965,16 +1794,6 @@ template <class _Tp, class _Alloc> |
| 1965 | 1794 | void |
| 1966 | 1795 | list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l) |
| 1967 | 1796 | { |
| 1968 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1969 | "list::splice(iterator, list, iterator, iterator) called with first iterator not referring to this list"); | |
| 1970 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__f)) == _VSTD::addressof(__c), | |
| 1971 | "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument"); | |
| 1972 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c), | |
| 1973 | "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument"); | |
| 1974 | _LIBCPP_DEBUG_ASSERT(this != std::addressof(__c) || !std::__iterator_in_range(__f, __l, __p), | |
| 1975 | "list::splice(iterator, list, iterator, iterator)" | |
| 1976 | " called with the first iterator within the range of the second and third iterators"); | |
| 1977 | ||
| 1978 | 1797 | if (__f != __l) |
| 1979 | 1798 | { |
| 1980 | 1799 | __link_pointer __first = __f.__ptr_; |
| ... | ... | @@ -1988,30 +1807,6 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con |
| 1988 | 1807 | } |
| 1989 | 1808 | base::__unlink_nodes(__first, __last); |
| 1990 | 1809 | __link_nodes(__p.__ptr_, __first, __last); |
| 1991 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1992 | if (_VSTD::addressof(__c) != this) { | |
| 1993 | __libcpp_db* __db = __get_db(); | |
| 1994 | __c_node* __cn1 = __db->__find_c_and_lock(this); | |
| 1995 | __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); | |
| 1996 | for (__i_node** __ip = __cn2->end_; __ip != __cn2->beg_;) | |
| 1997 | { | |
| 1998 | --__ip; | |
| 1999 | iterator* __j = static_cast<iterator*>((*__ip)->__i_); | |
| 2000 | for (__link_pointer __k = __f.__ptr_; | |
| 2001 | __k != __l.__ptr_; __k = __k->__next_) | |
| 2002 | { | |
| 2003 | if (__j->__ptr_ == __k) | |
| 2004 | { | |
| 2005 | __cn1->__add(*__ip); | |
| 2006 | (*__ip)->__c_ = __cn1; | |
| 2007 | if (--__cn2->end_ != __ip) | |
| 2008 | _VSTD::memmove(__ip, __ip+1, (__cn2->end_ - __ip)*sizeof(__i_node*)); | |
| 2009 | } | |
| 2010 | } | |
| 2011 | } | |
| 2012 | __db->unlock(); | |
| 2013 | } | |
| 2014 | #endif | |
| 2015 | 1810 | } |
| 2016 | 1811 | } |
| 2017 | 1812 | |
| ... | ... | @@ -2089,7 +1884,7 @@ inline |
| 2089 | 1884 | void |
| 2090 | 1885 | list<_Tp, _Alloc>::merge(list& __c) |
| 2091 | 1886 | { |
| 2092 | merge(__c, __less<value_type>()); | |
| 1887 | merge(__c, __less<>()); | |
| 2093 | 1888 | } |
| 2094 | 1889 | |
| 2095 | 1890 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -2125,24 +1920,6 @@ list<_Tp, _Alloc>::merge(list& __c, _Comp __comp) |
| 2125 | 1920 | ++__f1; |
| 2126 | 1921 | } |
| 2127 | 1922 | splice(__e1, __c); |
| 2128 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2129 | __libcpp_db* __db = __get_db(); | |
| 2130 | __c_node* __cn1 = __db->__find_c_and_lock(this); | |
| 2131 | __c_node* __cn2 = __db->__find_c(_VSTD::addressof(__c)); | |
| 2132 | for (__i_node** __p = __cn2->end_; __p != __cn2->beg_;) | |
| 2133 | { | |
| 2134 | --__p; | |
| 2135 | iterator* __i = static_cast<iterator*>((*__p)->__i_); | |
| 2136 | if (__i->__ptr_ != __c.__end_as_link()) | |
| 2137 | { | |
| 2138 | __cn1->__add(*__p); | |
| 2139 | (*__p)->__c_ = __cn1; | |
| 2140 | if (--__cn2->end_ != __p) | |
| 2141 | _VSTD::memmove(__p, __p+1, (__cn2->end_ - __p)*sizeof(__i_node*)); | |
| 2142 | } | |
| 2143 | } | |
| 2144 | __db->unlock(); | |
| 2145 | #endif | |
| 2146 | 1923 | } |
| 2147 | 1924 | } |
| 2148 | 1925 | |
| ... | ... | @@ -2151,7 +1928,7 @@ inline |
| 2151 | 1928 | void |
| 2152 | 1929 | list<_Tp, _Alloc>::sort() |
| 2153 | 1930 | { |
| 2154 | sort(__less<value_type>()); | |
| 1931 | sort(__less<>()); | |
| 2155 | 1932 | } |
| 2156 | 1933 | |
| 2157 | 1934 | template <class _Tp, class _Alloc> |
| ... | ... | @@ -2249,38 +2026,6 @@ list<_Tp, _Alloc>::__invariants() const |
| 2249 | 2026 | return size() == _VSTD::distance(begin(), end()); |
| 2250 | 2027 | } |
| 2251 | 2028 | |
| 2252 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2253 | ||
| 2254 | template <class _Tp, class _Alloc> | |
| 2255 | bool | |
| 2256 | list<_Tp, _Alloc>::__dereferenceable(const const_iterator* __i) const | |
| 2257 | { | |
| 2258 | return __i->__ptr_ != this->__end_as_link(); | |
| 2259 | } | |
| 2260 | ||
| 2261 | template <class _Tp, class _Alloc> | |
| 2262 | bool | |
| 2263 | list<_Tp, _Alloc>::__decrementable(const const_iterator* __i) const | |
| 2264 | { | |
| 2265 | return !empty() && __i->__ptr_ != base::__end_.__next_; | |
| 2266 | } | |
| 2267 | ||
| 2268 | template <class _Tp, class _Alloc> | |
| 2269 | bool | |
| 2270 | list<_Tp, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const | |
| 2271 | { | |
| 2272 | return false; | |
| 2273 | } | |
| 2274 | ||
| 2275 | template <class _Tp, class _Alloc> | |
| 2276 | bool | |
| 2277 | list<_Tp, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const | |
| 2278 | { | |
| 2279 | return false; | |
| 2280 | } | |
| 2281 | ||
| 2282 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 2283 | ||
| 2284 | 2029 | template <class _Tp, class _Alloc> |
| 2285 | 2030 | inline _LIBCPP_INLINE_VISIBILITY |
| 2286 | 2031 | bool |
| ... | ... | @@ -2289,6 +2034,8 @@ operator==(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
| 2289 | 2034 | return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 2290 | 2035 | } |
| 2291 | 2036 | |
| 2037 | #if _LIBCPP_STD_VER <= 17 | |
| 2038 | ||
| 2292 | 2039 | template <class _Tp, class _Alloc> |
| 2293 | 2040 | inline _LIBCPP_INLINE_VISIBILITY |
| 2294 | 2041 | bool |
| ... | ... | @@ -2329,6 +2076,17 @@ operator<=(const list<_Tp, _Alloc>& __x, const list<_Tp, _Alloc>& __y) |
| 2329 | 2076 | return !(__y < __x); |
| 2330 | 2077 | } |
| 2331 | 2078 | |
| 2079 | #else // _LIBCPP_STD_VER <= 17 | |
| 2080 | ||
| 2081 | template <class _Tp, class _Allocator> | |
| 2082 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Tp> | |
| 2083 | operator<=>(const list<_Tp, _Allocator>& __x, const list<_Tp, _Allocator>& __y) { | |
| 2084 | return std::lexicographical_compare_three_way( | |
| 2085 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); | |
| 2086 | } | |
| 2087 | ||
| 2088 | #endif // _LIBCPP_STD_VER <= 17 | |
| 2089 | ||
| 2332 | 2090 | template <class _Tp, class _Alloc> |
| 2333 | 2091 | inline _LIBCPP_INLINE_VISIBILITY |
| 2334 | 2092 | void |
| ... | ... | @@ -2338,7 +2096,7 @@ swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) |
| 2338 | 2096 | __x.swap(__y); |
| 2339 | 2097 | } |
| 2340 | 2098 | |
| 2341 | #if _LIBCPP_STD_VER > 17 | |
| 2099 | #if _LIBCPP_STD_VER >= 20 | |
| 2342 | 2100 | template <class _Tp, class _Allocator, class _Predicate> |
| 2343 | 2101 | inline _LIBCPP_INLINE_VISIBILITY typename list<_Tp, _Allocator>::size_type |
| 2344 | 2102 | erase_if(list<_Tp, _Allocator>& __c, _Predicate __pred) { |
| ... | ... | @@ -2358,15 +2116,15 @@ template <> |
| 2358 | 2116 | inline constexpr bool __format::__enable_insertable<std::list<wchar_t>> = true; |
| 2359 | 2117 | #endif |
| 2360 | 2118 | |
| 2361 | #endif // _LIBCPP_STD_VER > 17 | |
| 2119 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2362 | 2120 | |
| 2363 | 2121 | _LIBCPP_END_NAMESPACE_STD |
| 2364 | 2122 | |
| 2365 | #if _LIBCPP_STD_VER > 14 | |
| 2123 | #if _LIBCPP_STD_VER >= 17 | |
| 2366 | 2124 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 2367 | 2125 | namespace pmr { |
| 2368 | 2126 | template <class _ValueT> |
| 2369 | using list = std::list<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 2127 | using list _LIBCPP_AVAILABILITY_PMR = std::list<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 2370 | 2128 | } // namespace pmr |
| 2371 | 2129 | _LIBCPP_END_NAMESPACE_STD |
| 2372 | 2130 | #endif |
| ... | ... | @@ -2377,9 +2135,11 @@ _LIBCPP_POP_MACROS |
| 2377 | 2135 | # include <algorithm> |
| 2378 | 2136 | # include <atomic> |
| 2379 | 2137 | # include <concepts> |
| 2138 | # include <cstdlib> | |
| 2380 | 2139 | # include <functional> |
| 2381 | 2140 | # include <iosfwd> |
| 2382 | 2141 | # include <iterator> |
| 2142 | # include <type_traits> | |
| 2383 | 2143 | # include <typeinfo> |
| 2384 | 2144 | #endif |
| 2385 | 2145 |
lib/libcxx/include/locale+86-91| ... | ... | @@ -53,7 +53,7 @@ public: |
| 53 | 53 | // locale operations: |
| 54 | 54 | basic_string<char> name() const; |
| 55 | 55 | bool operator==(const locale& other) const; |
| 56 | bool operator!=(const locale& other) const; | |
| 56 | bool operator!=(const locale& other) const; // removed C++20 | |
| 57 | 57 | template <class charT, class Traits, class Allocator> |
| 58 | 58 | bool operator()(const basic_string<charT,Traits,Allocator>& s1, |
| 59 | 59 | const basic_string<charT,Traits,Allocator>& s2) const; |
| ... | ... | @@ -195,13 +195,14 @@ template <class charT> class messages_byname; |
| 195 | 195 | #include <__algorithm/unwrap_iter.h> |
| 196 | 196 | #include <__assert> // all public C++ headers provide the assertion handler |
| 197 | 197 | #include <__config> |
| 198 | #include <__debug> | |
| 199 | 198 | #include <__iterator/access.h> |
| 200 | 199 | #include <__iterator/back_insert_iterator.h> |
| 201 | 200 | #include <__iterator/istreambuf_iterator.h> |
| 202 | 201 | #include <__iterator/ostreambuf_iterator.h> |
| 203 | 202 | #include <__locale> |
| 204 | 203 | #include <__memory/unique_ptr.h> |
| 204 | #include <__type_traits/make_unsigned.h> | |
| 205 | #include <cerrno> | |
| 205 | 206 | #include <cstdio> |
| 206 | 207 | #include <cstdlib> |
| 207 | 208 | #include <ctime> |
| ... | ... | @@ -223,9 +224,9 @@ template <class charT> class messages_byname; |
| 223 | 224 | #endif |
| 224 | 225 | |
| 225 | 226 | #ifdef _LIBCPP_LOCALE__L_EXTENSIONS |
| 226 | #include <__bsd_locale_defaults.h> | |
| 227 | # include <__locale_dir/locale_base_api/bsd_locale_defaults.h> | |
| 227 | 228 | #else |
| 228 | #include <__bsd_locale_fallbacks.h> | |
| 229 | # include <__locale_dir/locale_base_api/bsd_locale_fallbacks.h> | |
| 229 | 230 | #endif |
| 230 | 231 | |
| 231 | 232 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -245,7 +246,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 245 | 246 | #else |
| 246 | 247 | # define _LIBCPP_GET_C_LOCALE __cloc() |
| 247 | 248 | // Get the C locale object |
| 248 | _LIBCPP_FUNC_VIS locale_t __cloc(); | |
| 249 | _LIBCPP_EXPORTED_FROM_ABI locale_t __cloc(); | |
| 249 | 250 | #define __cloc_defined |
| 250 | 251 | #endif |
| 251 | 252 | |
| ... | ... | @@ -377,7 +378,7 @@ __scan_keyword(_InputIterator& __b, _InputIterator __e, |
| 377 | 378 | return __kb; |
| 378 | 379 | } |
| 379 | 380 | |
| 380 | struct _LIBCPP_TYPE_VIS __num_get_base | |
| 381 | struct _LIBCPP_EXPORTED_FROM_ABI __num_get_base | |
| 381 | 382 | { |
| 382 | 383 | static const int __num_get_buf_sz = 40; |
| 383 | 384 | |
| ... | ... | @@ -385,8 +386,7 @@ struct _LIBCPP_TYPE_VIS __num_get_base |
| 385 | 386 | static const char __src[33]; |
| 386 | 387 | }; |
| 387 | 388 | |
| 388 | _LIBCPP_FUNC_VIS | |
| 389 | void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, | |
| 389 | _LIBCPP_EXPORTED_FROM_ABI void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, | |
| 390 | 390 | ios_base::iostate& __err); |
| 391 | 391 | |
| 392 | 392 | template <class _CharT> |
| ... | ... | @@ -1126,7 +1126,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<char>; |
| 1126 | 1126 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS num_get<wchar_t>; |
| 1127 | 1127 | #endif |
| 1128 | 1128 | |
| 1129 | struct _LIBCPP_TYPE_VIS __num_put_base | |
| 1129 | struct _LIBCPP_EXPORTED_FROM_ABI __num_put_base | |
| 1130 | 1130 | { |
| 1131 | 1131 | protected: |
| 1132 | 1132 | static void __format_int(char* __fmt, const char* __len, bool __signd, |
| ... | ... | @@ -1464,12 +1464,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, |
| 1464 | 1464 | return do_put(__s, __iob, __fl, (unsigned long)__v); |
| 1465 | 1465 | const numpunct<char_type>& __np = std::use_facet<numpunct<char_type> >(__iob.getloc()); |
| 1466 | 1466 | typedef typename numpunct<char_type>::string_type string_type; |
| 1467 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1468 | string_type __tmp(__v ? __np.truename() : __np.falsename()); | |
| 1469 | string_type __nm = _VSTD::move(__tmp); | |
| 1470 | #else | |
| 1471 | 1467 | string_type __nm = __v ? __np.truename() : __np.falsename(); |
| 1472 | #endif | |
| 1473 | 1468 | for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) |
| 1474 | 1469 | *__s = *__i; |
| 1475 | 1470 | return __s; |
| ... | ... | @@ -1681,7 +1676,7 @@ __get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, |
| 1681 | 1676 | return __r; |
| 1682 | 1677 | } |
| 1683 | 1678 | |
| 1684 | class _LIBCPP_TYPE_VIS time_base | |
| 1679 | class _LIBCPP_EXPORTED_FROM_ABI time_base | |
| 1685 | 1680 | { |
| 1686 | 1681 | public: |
| 1687 | 1682 | enum dateorder {no_order, dmy, mdy, ymd, ydm}; |
| ... | ... | @@ -1705,22 +1700,22 @@ protected: |
| 1705 | 1700 | ~__time_get_c_storage() {} |
| 1706 | 1701 | }; |
| 1707 | 1702 | |
| 1708 | template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const; | |
| 1709 | template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const; | |
| 1710 | template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const; | |
| 1711 | template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const; | |
| 1712 | template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const; | |
| 1713 | template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const; | |
| 1714 | template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const; | |
| 1703 | template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__weeks() const; | |
| 1704 | template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__months() const; | |
| 1705 | template <> _LIBCPP_EXPORTED_FROM_ABI const string* __time_get_c_storage<char>::__am_pm() const; | |
| 1706 | template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__c() const; | |
| 1707 | template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__r() const; | |
| 1708 | template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__x() const; | |
| 1709 | template <> _LIBCPP_EXPORTED_FROM_ABI const string& __time_get_c_storage<char>::__X() const; | |
| 1715 | 1710 | |
| 1716 | 1711 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 1717 | template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const; | |
| 1718 | template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const; | |
| 1719 | template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; | |
| 1720 | template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const; | |
| 1721 | template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const; | |
| 1722 | template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const; | |
| 1723 | template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const; | |
| 1712 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__weeks() const; | |
| 1713 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__months() const; | |
| 1714 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring* __time_get_c_storage<wchar_t>::__am_pm() const; | |
| 1715 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__c() const; | |
| 1716 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__r() const; | |
| 1717 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__x() const; | |
| 1718 | template <> _LIBCPP_EXPORTED_FROM_ABI const wstring& __time_get_c_storage<wchar_t>::__X() const; | |
| 1724 | 1719 | #endif |
| 1725 | 1720 | |
| 1726 | 1721 | template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > |
| ... | ... | @@ -2337,7 +2332,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<char>; |
| 2337 | 2332 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get<wchar_t>; |
| 2338 | 2333 | #endif |
| 2339 | 2334 | |
| 2340 | class _LIBCPP_TYPE_VIS __time_get | |
| 2335 | class _LIBCPP_EXPORTED_FROM_ABI __time_get | |
| 2341 | 2336 | { |
| 2342 | 2337 | protected: |
| 2343 | 2338 | locale_t __loc_; |
| ... | ... | @@ -2375,16 +2370,16 @@ private: |
| 2375 | 2370 | }; |
| 2376 | 2371 | |
| 2377 | 2372 | #define _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(_CharT) \ |
| 2378 | template <> _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ | |
| 2379 | template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ | |
| 2380 | template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ | |
| 2381 | template <> _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ | |
| 2382 | template <> _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ | |
| 2383 | extern template _LIBCPP_FUNC_VIS time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ | |
| 2384 | extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const char*); \ | |
| 2385 | extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::__time_get_storage(const string&); \ | |
| 2386 | extern template _LIBCPP_FUNC_VIS void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ | |
| 2387 | extern template _LIBCPP_FUNC_VIS __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ | |
| 2373 | template <> _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ | |
| 2374 | template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ | |
| 2375 | template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ | |
| 2376 | template <> _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ | |
| 2377 | template <> _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ | |
| 2378 | extern template _LIBCPP_EXPORTED_FROM_ABI time_base::dateorder __time_get_storage<_CharT>::__do_date_order() const; \ | |
| 2379 | extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const char*); \ | |
| 2380 | extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::__time_get_storage(const string&); \ | |
| 2381 | extern template _LIBCPP_EXPORTED_FROM_ABI void __time_get_storage<_CharT>::init(const ctype<_CharT>&); \ | |
| 2382 | extern template _LIBCPP_EXPORTED_FROM_ABI __time_get_storage<_CharT>::string_type __time_get_storage<_CharT>::__analyze(char, const ctype<_CharT>&); \ | |
| 2388 | 2383 | /**/ |
| 2389 | 2384 | |
| 2390 | 2385 | _LIBCPP_TIME_GET_STORAGE_EXPLICIT_INSTANTIATION(char) |
| ... | ... | @@ -2432,7 +2427,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<char>; |
| 2432 | 2427 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_get_byname<wchar_t>; |
| 2433 | 2428 | #endif |
| 2434 | 2429 | |
| 2435 | class _LIBCPP_TYPE_VIS __time_put | |
| 2430 | class _LIBCPP_EXPORTED_FROM_ABI __time_put | |
| 2436 | 2431 | { |
| 2437 | 2432 | locale_t __loc_; |
| 2438 | 2433 | protected: |
| ... | ... | @@ -2572,7 +2567,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS time_put_byname<wchar_t>; |
| 2572 | 2567 | |
| 2573 | 2568 | // money_base |
| 2574 | 2569 | |
| 2575 | class _LIBCPP_TYPE_VIS money_base | |
| 2570 | class _LIBCPP_EXPORTED_FROM_ABI money_base | |
| 2576 | 2571 | { |
| 2577 | 2572 | public: |
| 2578 | 2573 | enum part {none, space, symbol, sign, value}; |
| ... | ... | @@ -2686,14 +2681,14 @@ private: |
| 2686 | 2681 | void init(const char*); |
| 2687 | 2682 | }; |
| 2688 | 2683 | |
| 2689 | template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, false>::init(const char*); | |
| 2690 | template<> _LIBCPP_FUNC_VIS void moneypunct_byname<char, true>::init(const char*); | |
| 2684 | template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, false>::init(const char*); | |
| 2685 | template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<char, true>::init(const char*); | |
| 2691 | 2686 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, false>; |
| 2692 | 2687 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<char, true>; |
| 2693 | 2688 | |
| 2694 | 2689 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 2695 | template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, false>::init(const char*); | |
| 2696 | template<> _LIBCPP_FUNC_VIS void moneypunct_byname<wchar_t, true>::init(const char*); | |
| 2690 | template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, false>::init(const char*); | |
| 2691 | template<> _LIBCPP_EXPORTED_FROM_ABI void moneypunct_byname<wchar_t, true>::init(const char*); | |
| 2697 | 2692 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, false>; |
| 2698 | 2693 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS moneypunct_byname<wchar_t, true>; |
| 2699 | 2694 | #endif |
| ... | ... | @@ -2810,7 +2805,7 @@ template <class _CharT, class _InputIterator> |
| 2810 | 2805 | locale::id |
| 2811 | 2806 | money_get<_CharT, _InputIterator>::id; |
| 2812 | 2807 | |
| 2813 | _LIBCPP_FUNC_VIS void __do_nothing(void*); | |
| 2808 | _LIBCPP_EXPORTED_FROM_ABI void __do_nothing(void*); | |
| 2814 | 2809 | |
| 2815 | 2810 | template <class _Tp> |
| 2816 | 2811 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -3457,7 +3452,7 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS money_put<wchar_t>; |
| 3457 | 3452 | |
| 3458 | 3453 | // messages |
| 3459 | 3454 | |
| 3460 | class _LIBCPP_TYPE_VIS messages_base | |
| 3455 | class _LIBCPP_EXPORTED_FROM_ABI messages_base | |
| 3461 | 3456 | { |
| 3462 | 3457 | public: |
| 3463 | 3458 | typedef ptrdiff_t catalog; |
| ... | ... | @@ -3598,15 +3593,15 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS messages_byname<wchar_t>; |
| 3598 | 3593 | #endif |
| 3599 | 3594 | |
| 3600 | 3595 | template<class _Codecvt, class _Elem = wchar_t, |
| 3601 | class _Wide_alloc = allocator<_Elem>, | |
| 3602 | class _Byte_alloc = allocator<char> > | |
| 3596 | class _WideAlloc = allocator<_Elem>, | |
| 3597 | class _ByteAlloc = allocator<char> > | |
| 3603 | 3598 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 wstring_convert |
| 3604 | 3599 | { |
| 3605 | 3600 | public: |
| 3606 | typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; | |
| 3607 | typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; | |
| 3608 | typedef typename _Codecvt::state_type state_type; | |
| 3609 | typedef typename wide_string::traits_type::int_type int_type; | |
| 3601 | typedef basic_string<char, char_traits<char>, _ByteAlloc> byte_string; | |
| 3602 | typedef basic_string<_Elem, char_traits<_Elem>, _WideAlloc> wide_string; | |
| 3603 | typedef typename _Codecvt::state_type state_type; | |
| 3604 | typedef typename wide_string::traits_type::int_type int_type; | |
| 3610 | 3605 | |
| 3611 | 3606 | private: |
| 3612 | 3607 | byte_string __byte_err_string_; |
| ... | ... | @@ -3625,19 +3620,19 @@ public: |
| 3625 | 3620 | explicit wstring_convert(_Codecvt* __pcvt); |
| 3626 | 3621 | #else |
| 3627 | 3622 | _LIBCPP_INLINE_VISIBILITY |
| 3628 | _LIBCPP_EXPLICIT_AFTER_CXX11 | |
| 3623 | _LIBCPP_EXPLICIT_SINCE_CXX14 | |
| 3629 | 3624 | wstring_convert(_Codecvt* __pcvt = new _Codecvt); |
| 3630 | 3625 | #endif |
| 3631 | 3626 | |
| 3632 | 3627 | _LIBCPP_INLINE_VISIBILITY |
| 3633 | 3628 | wstring_convert(_Codecvt* __pcvt, state_type __state); |
| 3634 | _LIBCPP_EXPLICIT_AFTER_CXX11 wstring_convert(const byte_string& __byte_err, | |
| 3629 | _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI wstring_convert(const byte_string& __byte_err, | |
| 3635 | 3630 | const wide_string& __wide_err = wide_string()); |
| 3636 | 3631 | #ifndef _LIBCPP_CXX03_LANG |
| 3637 | 3632 | _LIBCPP_INLINE_VISIBILITY |
| 3638 | 3633 | wstring_convert(wstring_convert&& __wc); |
| 3639 | 3634 | #endif |
| 3640 | ~wstring_convert(); | |
| 3635 | _LIBCPP_HIDE_FROM_ABI ~wstring_convert(); | |
| 3641 | 3636 | |
| 3642 | 3637 | _LIBCPP_INLINE_VISIBILITY |
| 3643 | 3638 | wide_string from_bytes(char __byte) |
| ... | ... | @@ -3648,7 +3643,7 @@ public: |
| 3648 | 3643 | _LIBCPP_INLINE_VISIBILITY |
| 3649 | 3644 | wide_string from_bytes(const byte_string& __str) |
| 3650 | 3645 | {return from_bytes(__str.data(), __str.data() + __str.size());} |
| 3651 | wide_string from_bytes(const char* __first, const char* __last); | |
| 3646 | _LIBCPP_HIDE_FROM_ABI wide_string from_bytes(const char* __first, const char* __last); | |
| 3652 | 3647 | |
| 3653 | 3648 | _LIBCPP_INLINE_VISIBILITY |
| 3654 | 3649 | byte_string to_bytes(_Elem __wchar) |
| ... | ... | @@ -3659,7 +3654,7 @@ public: |
| 3659 | 3654 | _LIBCPP_INLINE_VISIBILITY |
| 3660 | 3655 | byte_string to_bytes(const wide_string& __wstr) |
| 3661 | 3656 | {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} |
| 3662 | byte_string to_bytes(const _Elem* __first, const _Elem* __last); | |
| 3657 | _LIBCPP_HIDE_FROM_ABI byte_string to_bytes(const _Elem* __first, const _Elem* __last); | |
| 3663 | 3658 | |
| 3664 | 3659 | _LIBCPP_INLINE_VISIBILITY |
| 3665 | 3660 | size_t converted() const _NOEXCEPT {return __cvtcount_;} |
| ... | ... | @@ -3668,25 +3663,25 @@ public: |
| 3668 | 3663 | }; |
| 3669 | 3664 | |
| 3670 | 3665 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 3671 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3666 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3672 | 3667 | inline |
| 3673 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3668 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3674 | 3669 | wstring_convert(_Codecvt* __pcvt) |
| 3675 | 3670 | : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) |
| 3676 | 3671 | { |
| 3677 | 3672 | } |
| 3678 | 3673 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 3679 | 3674 | |
| 3680 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3675 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3681 | 3676 | inline |
| 3682 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3677 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3683 | 3678 | wstring_convert(_Codecvt* __pcvt, state_type __state) |
| 3684 | 3679 | : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) |
| 3685 | 3680 | { |
| 3686 | 3681 | } |
| 3687 | 3682 | |
| 3688 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3689 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3683 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3684 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3690 | 3685 | wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) |
| 3691 | 3686 | : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), |
| 3692 | 3687 | __cvtstate_(), __cvtcount_(0) |
| ... | ... | @@ -3696,9 +3691,9 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: |
| 3696 | 3691 | |
| 3697 | 3692 | #ifndef _LIBCPP_CXX03_LANG |
| 3698 | 3693 | |
| 3699 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3694 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3700 | 3695 | inline |
| 3701 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3696 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3702 | 3697 | wstring_convert(wstring_convert&& __wc) |
| 3703 | 3698 | : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), |
| 3704 | 3699 | __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), |
| ... | ... | @@ -3711,15 +3706,15 @@ wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: |
| 3711 | 3706 | #endif // _LIBCPP_CXX03_LANG |
| 3712 | 3707 | |
| 3713 | 3708 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| 3714 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3715 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() | |
| 3709 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3710 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::~wstring_convert() | |
| 3716 | 3711 | { |
| 3717 | 3712 | delete __cvtptr_; |
| 3718 | 3713 | } |
| 3719 | 3714 | |
| 3720 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3721 | typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string | |
| 3722 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3715 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3716 | typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::wide_string | |
| 3717 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3723 | 3718 | from_bytes(const char* __frm, const char* __frm_end) |
| 3724 | 3719 | { |
| 3725 | 3720 | _LIBCPP_SUPPRESS_DEPRECATED_POP |
| ... | ... | @@ -3779,9 +3774,9 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 3779 | 3774 | return __wide_err_string_; |
| 3780 | 3775 | } |
| 3781 | 3776 | |
| 3782 | template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> | |
| 3783 | typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string | |
| 3784 | wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: | |
| 3777 | template<class _Codecvt, class _Elem, class _WideAlloc, class _ByteAlloc> | |
| 3778 | typename wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>::byte_string | |
| 3779 | wstring_convert<_Codecvt, _Elem, _WideAlloc, _ByteAlloc>:: | |
| 3785 | 3780 | to_bytes(const _Elem* __frm, const _Elem* __frm_end) |
| 3786 | 3781 | { |
| 3787 | 3782 | __cvtcount_ = 0; |
| ... | ... | @@ -3902,18 +3897,18 @@ private: |
| 3902 | 3897 | |
| 3903 | 3898 | public: |
| 3904 | 3899 | #ifndef _LIBCPP_CXX03_LANG |
| 3905 | wbuffer_convert() : wbuffer_convert(nullptr) {} | |
| 3906 | explicit wbuffer_convert(streambuf* __bytebuf, | |
| 3900 | _LIBCPP_HIDE_FROM_ABI wbuffer_convert() : wbuffer_convert(nullptr) {} | |
| 3901 | explicit _LIBCPP_HIDE_FROM_ABI wbuffer_convert(streambuf* __bytebuf, | |
| 3907 | 3902 | _Codecvt* __pcvt = new _Codecvt, |
| 3908 | 3903 | state_type __state = state_type()); |
| 3909 | 3904 | #else |
| 3910 | _LIBCPP_EXPLICIT_AFTER_CXX11 | |
| 3905 | _LIBCPP_EXPLICIT_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI | |
| 3911 | 3906 | wbuffer_convert(streambuf* __bytebuf = nullptr, |
| 3912 | 3907 | _Codecvt* __pcvt = new _Codecvt, |
| 3913 | 3908 | state_type __state = state_type()); |
| 3914 | 3909 | #endif |
| 3915 | 3910 | |
| 3916 | ~wbuffer_convert(); | |
| 3911 | _LIBCPP_HIDE_FROM_ABI ~wbuffer_convert(); | |
| 3917 | 3912 | |
| 3918 | 3913 | _LIBCPP_INLINE_VISIBILITY |
| 3919 | 3914 | streambuf* rdbuf() const {return __bufptr_;} |
| ... | ... | @@ -3929,21 +3924,21 @@ public: |
| 3929 | 3924 | state_type state() const {return __st_;} |
| 3930 | 3925 | |
| 3931 | 3926 | protected: |
| 3932 | virtual int_type underflow(); | |
| 3933 | virtual int_type pbackfail(int_type __c = traits_type::eof()); | |
| 3934 | virtual int_type overflow (int_type __c = traits_type::eof()); | |
| 3935 | virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, | |
| 3927 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type underflow(); | |
| 3928 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type pbackfail(int_type __c = traits_type::eof()); | |
| 3929 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int_type overflow (int_type __c = traits_type::eof()); | |
| 3930 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, | |
| 3936 | 3931 | streamsize __n); |
| 3937 | virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, | |
| 3932 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, | |
| 3938 | 3933 | ios_base::openmode __wch = ios_base::in | ios_base::out); |
| 3939 | virtual pos_type seekpos(pos_type __sp, | |
| 3934 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual pos_type seekpos(pos_type __sp, | |
| 3940 | 3935 | ios_base::openmode __wch = ios_base::in | ios_base::out); |
| 3941 | virtual int sync(); | |
| 3936 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual int sync(); | |
| 3942 | 3937 | |
| 3943 | 3938 | private: |
| 3944 | bool __read_mode(); | |
| 3945 | void __write_mode(); | |
| 3946 | wbuffer_convert* __close(); | |
| 3939 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL bool __read_mode(); | |
| 3940 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL void __write_mode(); | |
| 3941 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL wbuffer_convert* __close(); | |
| 3947 | 3942 | }; |
| 3948 | 3943 | |
| 3949 | 3944 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH |
| ... | ... | @@ -4009,8 +4004,8 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 4009 | 4004 | else |
| 4010 | 4005 | { |
| 4011 | 4006 | if (__extbufend_ != __extbufnext_) { |
| 4012 | _LIBCPP_ASSERT(__extbufnext_ != nullptr, "underflow moving from nullptr"); | |
| 4013 | _LIBCPP_ASSERT(__extbuf_ != nullptr, "underflow moving into nullptr"); | |
| 4007 | _LIBCPP_ASSERT_UNCATEGORIZED(__extbufnext_ != nullptr, "underflow moving from nullptr"); | |
| 4008 | _LIBCPP_ASSERT_UNCATEGORIZED(__extbuf_ != nullptr, "underflow moving into nullptr"); | |
| 4014 | 4009 | _VSTD::memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); |
| 4015 | 4010 | } |
| 4016 | 4011 | __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); |
lib/libcxx/include/map+250-76| ... | ... | @@ -70,6 +70,8 @@ public: |
| 70 | 70 | template <class InputIterator> |
| 71 | 71 | map(InputIterator first, InputIterator last, |
| 72 | 72 | const key_compare& comp, const allocator_type& a); |
| 73 | template<container-compatible-range<value_type> R> | |
| 74 | map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23 | |
| 73 | 75 | map(const map& m); |
| 74 | 76 | map(map&& m) |
| 75 | 77 | noexcept( |
| ... | ... | @@ -83,6 +85,9 @@ public: |
| 83 | 85 | template <class InputIterator> |
| 84 | 86 | map(InputIterator first, InputIterator last, const allocator_type& a) |
| 85 | 87 | : map(first, last, Compare(), a) {} // C++14 |
| 88 | template<container-compatible-range<value_type> R> | |
| 89 | map(from_range_t, R&& rg, const Allocator& a)) | |
| 90 | : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++23 | |
| 86 | 91 | map(initializer_list<value_type> il, const allocator_type& a) |
| 87 | 92 | : map(il, Compare(), a) {} // C++14 |
| 88 | 93 | ~map(); |
| ... | ... | @@ -138,6 +143,8 @@ public: |
| 138 | 143 | iterator insert(const_iterator position, P&& p); |
| 139 | 144 | template <class InputIterator> |
| 140 | 145 | void insert(InputIterator first, InputIterator last); |
| 146 | template<container-compatible-range<value_type> R> | |
| 147 | void insert_range(R&& rg); // C++23 | |
| 141 | 148 | void insert(initializer_list<value_type> il); |
| 142 | 149 | |
| 143 | 150 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -229,6 +236,11 @@ template <class InputIterator, |
| 229 | 236 | map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) |
| 230 | 237 | -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17 |
| 231 | 238 | |
| 239 | template<ranges::input_range R, class Compare = less<range-key-type<R>, | |
| 240 | class Allocator = allocator<range-to-alloc-type<R>>> | |
| 241 | map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) | |
| 242 | -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23 | |
| 243 | ||
| 232 | 244 | template<class Key, class T, class Compare = less<Key>, |
| 233 | 245 | class Allocator = allocator<pair<const Key, T>>> |
| 234 | 246 | map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator()) |
| ... | ... | @@ -239,6 +251,10 @@ map(InputIterator, InputIterator, Allocator) |
| 239 | 251 | -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>, |
| 240 | 252 | Allocator>; // C++17 |
| 241 | 253 | |
| 254 | template<ranges::input_range R, class Allocator> | |
| 255 | map(from_range_t, R&&, Allocator) | |
| 256 | -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23 | |
| 257 | ||
| 242 | 258 | template<class Key, class T, class Allocator> |
| 243 | 259 | map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17 |
| 244 | 260 | |
| ... | ... | @@ -250,27 +266,32 @@ operator==(const map<Key, T, Compare, Allocator>& x, |
| 250 | 266 | template <class Key, class T, class Compare, class Allocator> |
| 251 | 267 | bool |
| 252 | 268 | operator< (const map<Key, T, Compare, Allocator>& x, |
| 253 | const map<Key, T, Compare, Allocator>& y); | |
| 269 | const map<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 254 | 270 | |
| 255 | 271 | template <class Key, class T, class Compare, class Allocator> |
| 256 | 272 | bool |
| 257 | 273 | operator!=(const map<Key, T, Compare, Allocator>& x, |
| 258 | const map<Key, T, Compare, Allocator>& y); | |
| 274 | const map<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 259 | 275 | |
| 260 | 276 | template <class Key, class T, class Compare, class Allocator> |
| 261 | 277 | bool |
| 262 | 278 | operator> (const map<Key, T, Compare, Allocator>& x, |
| 263 | const map<Key, T, Compare, Allocator>& y); | |
| 279 | const map<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 264 | 280 | |
| 265 | 281 | template <class Key, class T, class Compare, class Allocator> |
| 266 | 282 | bool |
| 267 | 283 | operator>=(const map<Key, T, Compare, Allocator>& x, |
| 268 | const map<Key, T, Compare, Allocator>& y); | |
| 284 | const map<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 269 | 285 | |
| 270 | 286 | template <class Key, class T, class Compare, class Allocator> |
| 271 | 287 | bool |
| 272 | 288 | operator<=(const map<Key, T, Compare, Allocator>& x, |
| 273 | const map<Key, T, Compare, Allocator>& y); | |
| 289 | const map<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 290 | ||
| 291 | template<class Key, class T, class Compare, class Allocator> | |
| 292 | synth-three-way-result<pair<const Key, T>> | |
| 293 | operator<=>(const map<Key, T, Compare, Allocator>& x, | |
| 294 | const map<Key, T, Compare, Allocator>& y); // since C++20 | |
| 274 | 295 | |
| 275 | 296 | // specialized algorithms: |
| 276 | 297 | template <class Key, class T, class Compare, class Allocator> |
| ... | ... | @@ -333,6 +354,9 @@ public: |
| 333 | 354 | template <class InputIterator> |
| 334 | 355 | multimap(InputIterator first, InputIterator last, const key_compare& comp, |
| 335 | 356 | const allocator_type& a); |
| 357 | template<container-compatible-range<value_type> R> | |
| 358 | multimap(from_range_t, R&& rg, | |
| 359 | const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23 | |
| 336 | 360 | multimap(const multimap& m); |
| 337 | 361 | multimap(multimap&& m) |
| 338 | 362 | noexcept( |
| ... | ... | @@ -347,6 +371,9 @@ public: |
| 347 | 371 | template <class InputIterator> |
| 348 | 372 | multimap(InputIterator first, InputIterator last, const allocator_type& a) |
| 349 | 373 | : multimap(first, last, Compare(), a) {} // C++14 |
| 374 | template<container-compatible-range<value_type> R> | |
| 375 | multimap(from_range_t, R&& rg, const Allocator& a)) | |
| 376 | : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23 | |
| 350 | 377 | multimap(initializer_list<value_type> il, const allocator_type& a) |
| 351 | 378 | : multimap(il, Compare(), a) {} // C++14 |
| 352 | 379 | ~multimap(); |
| ... | ... | @@ -395,6 +422,8 @@ public: |
| 395 | 422 | iterator insert(const_iterator position, P&& p); |
| 396 | 423 | template <class InputIterator> |
| 397 | 424 | void insert(InputIterator first, InputIterator last); |
| 425 | template<container-compatible-range<value_type> R> | |
| 426 | void insert_range(R&& rg); // C++23 | |
| 398 | 427 | void insert(initializer_list<value_type> il); |
| 399 | 428 | |
| 400 | 429 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -469,6 +498,11 @@ template <class InputIterator, |
| 469 | 498 | multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator()) |
| 470 | 499 | -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17 |
| 471 | 500 | |
| 501 | template<ranges::input_range R, class Compare = less<range-key-type<R>>, | |
| 502 | class Allocator = allocator<range-to-alloc-type<R>>> | |
| 503 | multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) | |
| 504 | -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23 | |
| 505 | ||
| 472 | 506 | template<class Key, class T, class Compare = less<Key>, |
| 473 | 507 | class Allocator = allocator<pair<const Key, T>>> |
| 474 | 508 | multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator()) |
| ... | ... | @@ -479,6 +513,10 @@ multimap(InputIterator, InputIterator, Allocator) |
| 479 | 513 | -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, |
| 480 | 514 | less<iter_key_t<InputIterator>>, Allocator>; // C++17 |
| 481 | 515 | |
| 516 | template<ranges::input_range R, class Allocator> | |
| 517 | multimap(from_range_t, R&&, Allocator) | |
| 518 | -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23 | |
| 519 | ||
| 482 | 520 | template<class Key, class T, class Allocator> |
| 483 | 521 | multimap(initializer_list<pair<const Key, T>>, Allocator) |
| 484 | 522 | -> multimap<Key, T, less<Key>, Allocator>; // C++17 |
| ... | ... | @@ -491,27 +529,32 @@ operator==(const multimap<Key, T, Compare, Allocator>& x, |
| 491 | 529 | template <class Key, class T, class Compare, class Allocator> |
| 492 | 530 | bool |
| 493 | 531 | operator< (const multimap<Key, T, Compare, Allocator>& x, |
| 494 | const multimap<Key, T, Compare, Allocator>& y); | |
| 532 | const multimap<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 495 | 533 | |
| 496 | 534 | template <class Key, class T, class Compare, class Allocator> |
| 497 | 535 | bool |
| 498 | 536 | operator!=(const multimap<Key, T, Compare, Allocator>& x, |
| 499 | const multimap<Key, T, Compare, Allocator>& y); | |
| 537 | const multimap<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 500 | 538 | |
| 501 | 539 | template <class Key, class T, class Compare, class Allocator> |
| 502 | 540 | bool |
| 503 | 541 | operator> (const multimap<Key, T, Compare, Allocator>& x, |
| 504 | const multimap<Key, T, Compare, Allocator>& y); | |
| 542 | const multimap<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 505 | 543 | |
| 506 | 544 | template <class Key, class T, class Compare, class Allocator> |
| 507 | 545 | bool |
| 508 | 546 | operator>=(const multimap<Key, T, Compare, Allocator>& x, |
| 509 | const multimap<Key, T, Compare, Allocator>& y); | |
| 547 | const multimap<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 510 | 548 | |
| 511 | 549 | template <class Key, class T, class Compare, class Allocator> |
| 512 | 550 | bool |
| 513 | 551 | operator<=(const multimap<Key, T, Compare, Allocator>& x, |
| 514 | const multimap<Key, T, Compare, Allocator>& y); | |
| 552 | const multimap<Key, T, Compare, Allocator>& y); // removed in C++20 | |
| 553 | ||
| 554 | template<class Key, class T, class Compare, class Allocator> | |
| 555 | synth-three-way-result<pair<const Key, T>> | |
| 556 | operator<=>(const multimap<Key, T, Compare, Allocator>& x, | |
| 557 | const multimap<Key, T, Compare, Allocator>& y); // since c++20 | |
| 515 | 558 | |
| 516 | 559 | // specialized algorithms: |
| 517 | 560 | template <class Key, class T, class Compare, class Allocator> |
| ... | ... | @@ -530,24 +573,30 @@ erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 |
| 530 | 573 | |
| 531 | 574 | #include <__algorithm/equal.h> |
| 532 | 575 | #include <__algorithm/lexicographical_compare.h> |
| 576 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 533 | 577 | #include <__assert> // all public C++ headers provide the assertion handler |
| 578 | #include <__availability> | |
| 534 | 579 | #include <__config> |
| 535 | 580 | #include <__functional/binary_function.h> |
| 536 | 581 | #include <__functional/is_transparent.h> |
| 537 | 582 | #include <__functional/operations.h> |
| 538 | 583 | #include <__iterator/erase_if_container.h> |
| 539 | 584 | #include <__iterator/iterator_traits.h> |
| 585 | #include <__iterator/ranges_iterator_traits.h> | |
| 540 | 586 | #include <__iterator/reverse_iterator.h> |
| 587 | #include <__memory/addressof.h> | |
| 541 | 588 | #include <__memory/allocator.h> |
| 542 | 589 | #include <__memory_resource/polymorphic_allocator.h> |
| 543 | 590 | #include <__node_handle> |
| 591 | #include <__ranges/concepts.h> | |
| 592 | #include <__ranges/container_compatible_range.h> | |
| 593 | #include <__ranges/from_range.h> | |
| 544 | 594 | #include <__tree> |
| 545 | 595 | #include <__type_traits/is_allocator.h> |
| 546 | 596 | #include <__utility/forward.h> |
| 547 | 597 | #include <__utility/piecewise_construct.h> |
| 548 | 598 | #include <__utility/swap.h> |
| 549 | 599 | #include <tuple> |
| 550 | #include <type_traits> | |
| 551 | 600 | #include <version> |
| 552 | 601 | |
| 553 | 602 | // standard-mandated includes |
| ... | ... | @@ -594,14 +643,14 @@ public: |
| 594 | 643 | _LIBCPP_INLINE_VISIBILITY |
| 595 | 644 | bool operator()(const _Key& __x, const _CP& __y) const |
| 596 | 645 | {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);} |
| 597 | void swap(__map_value_compare& __y) | |
| 646 | _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) | |
| 598 | 647 | _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) |
| 599 | 648 | { |
| 600 | 649 | using _VSTD::swap; |
| 601 | 650 | swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y)); |
| 602 | 651 | } |
| 603 | 652 | |
| 604 | #if _LIBCPP_STD_VER > 11 | |
| 653 | #if _LIBCPP_STD_VER >= 14 | |
| 605 | 654 | template <typename _K2> |
| 606 | 655 | _LIBCPP_INLINE_VISIBILITY |
| 607 | 656 | bool operator()(const _K2& __x, const _CP& __y) const |
| ... | ... | @@ -647,7 +696,7 @@ public: |
| 647 | 696 | swap(__comp_, __y.__comp_); |
| 648 | 697 | } |
| 649 | 698 | |
| 650 | #if _LIBCPP_STD_VER > 11 | |
| 699 | #if _LIBCPP_STD_VER >= 14 | |
| 651 | 700 | template <typename _K2> |
| 652 | 701 | _LIBCPP_INLINE_VISIBILITY |
| 653 | 702 | bool operator()(const _K2& __x, const _CP& __y) const |
| ... | ... | @@ -742,7 +791,7 @@ public: |
| 742 | 791 | _LIBCPP_INLINE_VISIBILITY |
| 743 | 792 | value_type& __get_value() |
| 744 | 793 | { |
| 745 | #if _LIBCPP_STD_VER > 14 | |
| 794 | #if _LIBCPP_STD_VER >= 17 | |
| 746 | 795 | return *_VSTD::launder(_VSTD::addressof(__cc_)); |
| 747 | 796 | #else |
| 748 | 797 | return __cc_; |
| ... | ... | @@ -752,7 +801,7 @@ public: |
| 752 | 801 | _LIBCPP_INLINE_VISIBILITY |
| 753 | 802 | const value_type& __get_value() const |
| 754 | 803 | { |
| 755 | #if _LIBCPP_STD_VER > 14 | |
| 804 | #if _LIBCPP_STD_VER >= 17 | |
| 756 | 805 | return *_VSTD::launder(_VSTD::addressof(__cc_)); |
| 757 | 806 | #else |
| 758 | 807 | return __cc_; |
| ... | ... | @@ -1020,7 +1069,7 @@ public: |
| 1020 | 1069 | typedef _VSTD::reverse_iterator<iterator> reverse_iterator; |
| 1021 | 1070 | typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; |
| 1022 | 1071 | |
| 1023 | #if _LIBCPP_STD_VER > 14 | |
| 1072 | #if _LIBCPP_STD_VER >= 17 | |
| 1024 | 1073 | typedef __map_node_handle<typename __base::__node, allocator_type> node_type; |
| 1025 | 1074 | typedef __insert_return_type<iterator, node_type> insert_return_type; |
| 1026 | 1075 | #endif |
| ... | ... | @@ -1067,13 +1116,30 @@ public: |
| 1067 | 1116 | insert(__f, __l); |
| 1068 | 1117 | } |
| 1069 | 1118 | |
| 1070 | #if _LIBCPP_STD_VER > 11 | |
| 1119 | #if _LIBCPP_STD_VER >= 23 | |
| 1120 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1121 | _LIBCPP_HIDE_FROM_ABI | |
| 1122 | map(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(), | |
| 1123 | const allocator_type& __a = allocator_type()) | |
| 1124 | : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { | |
| 1125 | insert_range(std::forward<_Range>(__range)); | |
| 1126 | } | |
| 1127 | #endif | |
| 1128 | ||
| 1129 | #if _LIBCPP_STD_VER >= 14 | |
| 1071 | 1130 | template <class _InputIterator> |
| 1072 | 1131 | _LIBCPP_INLINE_VISIBILITY |
| 1073 | 1132 | map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) |
| 1074 | 1133 | : map(__f, __l, key_compare(), __a) {} |
| 1075 | 1134 | #endif |
| 1076 | 1135 | |
| 1136 | #if _LIBCPP_STD_VER >= 23 | |
| 1137 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1138 | _LIBCPP_HIDE_FROM_ABI | |
| 1139 | map(from_range_t, _Range&& __range, const allocator_type& __a) | |
| 1140 | : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {} | |
| 1141 | #endif | |
| 1142 | ||
| 1077 | 1143 | _LIBCPP_INLINE_VISIBILITY |
| 1078 | 1144 | map(const map& __m) |
| 1079 | 1145 | : __tree_(__m.__tree_) |
| ... | ... | @@ -1106,7 +1172,7 @@ public: |
| 1106 | 1172 | { |
| 1107 | 1173 | } |
| 1108 | 1174 | |
| 1109 | map(map&& __m, const allocator_type& __a); | |
| 1175 | _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a); | |
| 1110 | 1176 | |
| 1111 | 1177 | _LIBCPP_INLINE_VISIBILITY |
| 1112 | 1178 | map& operator=(map&& __m) |
| ... | ... | @@ -1130,7 +1196,7 @@ public: |
| 1130 | 1196 | insert(__il.begin(), __il.end()); |
| 1131 | 1197 | } |
| 1132 | 1198 | |
| 1133 | #if _LIBCPP_STD_VER > 11 | |
| 1199 | #if _LIBCPP_STD_VER >= 14 | |
| 1134 | 1200 | _LIBCPP_INLINE_VISIBILITY |
| 1135 | 1201 | map(initializer_list<value_type> __il, const allocator_type& __a) |
| 1136 | 1202 | : map(__il, key_compare(), __a) {} |
| ... | ... | @@ -1200,13 +1266,13 @@ public: |
| 1200 | 1266 | _LIBCPP_INLINE_VISIBILITY |
| 1201 | 1267 | size_type max_size() const _NOEXCEPT {return __tree_.max_size();} |
| 1202 | 1268 | |
| 1203 | mapped_type& operator[](const key_type& __k); | |
| 1269 | _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k); | |
| 1204 | 1270 | #ifndef _LIBCPP_CXX03_LANG |
| 1205 | mapped_type& operator[](key_type&& __k); | |
| 1271 | _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k); | |
| 1206 | 1272 | #endif |
| 1207 | 1273 | |
| 1208 | mapped_type& at(const key_type& __k); | |
| 1209 | const mapped_type& at(const key_type& __k) const; | |
| 1274 | _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k); | |
| 1275 | _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const; | |
| 1210 | 1276 | |
| 1211 | 1277 | _LIBCPP_INLINE_VISIBILITY |
| 1212 | 1278 | allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} |
| ... | ... | @@ -1273,7 +1339,18 @@ public: |
| 1273 | 1339 | insert(__e.__i_, *__f); |
| 1274 | 1340 | } |
| 1275 | 1341 | |
| 1276 | #if _LIBCPP_STD_VER > 14 | |
| 1342 | #if _LIBCPP_STD_VER >= 23 | |
| 1343 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1344 | _LIBCPP_HIDE_FROM_ABI | |
| 1345 | void insert_range(_Range&& __range) { | |
| 1346 | const_iterator __end = cend(); | |
| 1347 | for (auto&& __element : __range) { | |
| 1348 | insert(__end.__i_, std::forward<decltype(__element)>(__element)); | |
| 1349 | } | |
| 1350 | } | |
| 1351 | #endif | |
| 1352 | ||
| 1353 | #if _LIBCPP_STD_VER >= 17 | |
| 1277 | 1354 | |
| 1278 | 1355 | template <class... _Args> |
| 1279 | 1356 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1367,7 +1444,7 @@ public: |
| 1367 | 1444 | return __r; |
| 1368 | 1445 | } |
| 1369 | 1446 | |
| 1370 | #endif // _LIBCPP_STD_VER > 14 | |
| 1447 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1371 | 1448 | |
| 1372 | 1449 | _LIBCPP_INLINE_VISIBILITY |
| 1373 | 1450 | iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} |
| ... | ... | @@ -1382,11 +1459,11 @@ public: |
| 1382 | 1459 | _LIBCPP_INLINE_VISIBILITY |
| 1383 | 1460 | void clear() _NOEXCEPT {__tree_.clear();} |
| 1384 | 1461 | |
| 1385 | #if _LIBCPP_STD_VER > 14 | |
| 1462 | #if _LIBCPP_STD_VER >= 17 | |
| 1386 | 1463 | _LIBCPP_INLINE_VISIBILITY |
| 1387 | 1464 | insert_return_type insert(node_type&& __nh) |
| 1388 | 1465 | { |
| 1389 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1466 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1390 | 1467 | "node_type with incompatible allocator passed to map::insert()"); |
| 1391 | 1468 | return __tree_.template __node_handle_insert_unique< |
| 1392 | 1469 | node_type, insert_return_type>(_VSTD::move(__nh)); |
| ... | ... | @@ -1394,7 +1471,7 @@ public: |
| 1394 | 1471 | _LIBCPP_INLINE_VISIBILITY |
| 1395 | 1472 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 1396 | 1473 | { |
| 1397 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1474 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1398 | 1475 | "node_type with incompatible allocator passed to map::insert()"); |
| 1399 | 1476 | return __tree_.template __node_handle_insert_unique<node_type>( |
| 1400 | 1477 | __hint.__i_, _VSTD::move(__nh)); |
| ... | ... | @@ -1413,32 +1490,32 @@ public: |
| 1413 | 1490 | _LIBCPP_INLINE_VISIBILITY |
| 1414 | 1491 | void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) |
| 1415 | 1492 | { |
| 1416 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1417 | "merging container with incompatible allocator"); | |
| 1493 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1494 | "merging container with incompatible allocator"); | |
| 1418 | 1495 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 1419 | 1496 | } |
| 1420 | 1497 | template <class _Compare2> |
| 1421 | 1498 | _LIBCPP_INLINE_VISIBILITY |
| 1422 | 1499 | void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) |
| 1423 | 1500 | { |
| 1424 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1425 | "merging container with incompatible allocator"); | |
| 1501 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1502 | "merging container with incompatible allocator"); | |
| 1426 | 1503 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 1427 | 1504 | } |
| 1428 | 1505 | template <class _Compare2> |
| 1429 | 1506 | _LIBCPP_INLINE_VISIBILITY |
| 1430 | 1507 | void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) |
| 1431 | 1508 | { |
| 1432 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1433 | "merging container with incompatible allocator"); | |
| 1509 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1510 | "merging container with incompatible allocator"); | |
| 1434 | 1511 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 1435 | 1512 | } |
| 1436 | 1513 | template <class _Compare2> |
| 1437 | 1514 | _LIBCPP_INLINE_VISIBILITY |
| 1438 | 1515 | void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) |
| 1439 | 1516 | { |
| 1440 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1441 | "merging container with incompatible allocator"); | |
| 1517 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1518 | "merging container with incompatible allocator"); | |
| 1442 | 1519 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 1443 | 1520 | } |
| 1444 | 1521 | #endif |
| ... | ... | @@ -1452,7 +1529,7 @@ public: |
| 1452 | 1529 | iterator find(const key_type& __k) {return __tree_.find(__k);} |
| 1453 | 1530 | _LIBCPP_INLINE_VISIBILITY |
| 1454 | 1531 | const_iterator find(const key_type& __k) const {return __tree_.find(__k);} |
| 1455 | #if _LIBCPP_STD_VER > 11 | |
| 1532 | #if _LIBCPP_STD_VER >= 14 | |
| 1456 | 1533 | template <typename _K2> |
| 1457 | 1534 | _LIBCPP_INLINE_VISIBILITY |
| 1458 | 1535 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -1466,21 +1543,21 @@ public: |
| 1466 | 1543 | _LIBCPP_INLINE_VISIBILITY |
| 1467 | 1544 | size_type count(const key_type& __k) const |
| 1468 | 1545 | {return __tree_.__count_unique(__k);} |
| 1469 | #if _LIBCPP_STD_VER > 11 | |
| 1546 | #if _LIBCPP_STD_VER >= 14 | |
| 1470 | 1547 | template <typename _K2> |
| 1471 | 1548 | _LIBCPP_INLINE_VISIBILITY |
| 1472 | 1549 | __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type> |
| 1473 | 1550 | count(const _K2& __k) const {return __tree_.__count_multi(__k);} |
| 1474 | 1551 | #endif |
| 1475 | 1552 | |
| 1476 | #if _LIBCPP_STD_VER > 17 | |
| 1553 | #if _LIBCPP_STD_VER >= 20 | |
| 1477 | 1554 | _LIBCPP_INLINE_VISIBILITY |
| 1478 | 1555 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 1479 | 1556 | template <typename _K2> |
| 1480 | 1557 | _LIBCPP_INLINE_VISIBILITY |
| 1481 | 1558 | __enable_if_t<__is_transparent<_Compare, _K2>::value, bool> |
| 1482 | 1559 | contains(const _K2& __k) const { return find(__k) != end(); } |
| 1483 | #endif // _LIBCPP_STD_VER > 17 | |
| 1560 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1484 | 1561 | |
| 1485 | 1562 | _LIBCPP_INLINE_VISIBILITY |
| 1486 | 1563 | iterator lower_bound(const key_type& __k) |
| ... | ... | @@ -1488,7 +1565,7 @@ public: |
| 1488 | 1565 | _LIBCPP_INLINE_VISIBILITY |
| 1489 | 1566 | const_iterator lower_bound(const key_type& __k) const |
| 1490 | 1567 | {return __tree_.lower_bound(__k);} |
| 1491 | #if _LIBCPP_STD_VER > 11 | |
| 1568 | #if _LIBCPP_STD_VER >= 14 | |
| 1492 | 1569 | template <typename _K2> |
| 1493 | 1570 | _LIBCPP_INLINE_VISIBILITY |
| 1494 | 1571 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -1506,7 +1583,7 @@ public: |
| 1506 | 1583 | _LIBCPP_INLINE_VISIBILITY |
| 1507 | 1584 | const_iterator upper_bound(const key_type& __k) const |
| 1508 | 1585 | {return __tree_.upper_bound(__k);} |
| 1509 | #if _LIBCPP_STD_VER > 11 | |
| 1586 | #if _LIBCPP_STD_VER >= 14 | |
| 1510 | 1587 | template <typename _K2> |
| 1511 | 1588 | _LIBCPP_INLINE_VISIBILITY |
| 1512 | 1589 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -1523,7 +1600,7 @@ public: |
| 1523 | 1600 | _LIBCPP_INLINE_VISIBILITY |
| 1524 | 1601 | pair<const_iterator,const_iterator> equal_range(const key_type& __k) const |
| 1525 | 1602 | {return __tree_.__equal_range_unique(__k);} |
| 1526 | #if _LIBCPP_STD_VER > 11 | |
| 1603 | #if _LIBCPP_STD_VER >= 14 | |
| 1527 | 1604 | template <typename _K2> |
| 1528 | 1605 | _LIBCPP_INLINE_VISIBILITY |
| 1529 | 1606 | __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>> |
| ... | ... | @@ -1545,19 +1622,28 @@ private: |
| 1545 | 1622 | typedef unique_ptr<__node, _Dp> __node_holder; |
| 1546 | 1623 | |
| 1547 | 1624 | #ifdef _LIBCPP_CXX03_LANG |
| 1548 | __node_holder __construct_node_with_key(const key_type& __k); | |
| 1625 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k); | |
| 1549 | 1626 | #endif |
| 1550 | 1627 | }; |
| 1551 | 1628 | |
| 1552 | 1629 | #if _LIBCPP_STD_VER >= 17 |
| 1553 | 1630 | template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, |
| 1554 | 1631 | class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, |
| 1555 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1632 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 1556 | 1633 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, |
| 1557 | 1634 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 1558 | 1635 | map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) |
| 1559 | 1636 | -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; |
| 1560 | 1637 | |
| 1638 | #if _LIBCPP_STD_VER >= 23 | |
| 1639 | template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>, | |
| 1640 | class _Allocator = allocator<__range_to_alloc_type<_Range>>, | |
| 1641 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, | |
| 1642 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 1643 | map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) | |
| 1644 | -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>; | |
| 1645 | #endif | |
| 1646 | ||
| 1561 | 1647 | template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, |
| 1562 | 1648 | class _Allocator = allocator<pair<const _Key, _Tp>>, |
| 1563 | 1649 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, |
| ... | ... | @@ -1566,12 +1652,19 @@ map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allo |
| 1566 | 1652 | -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; |
| 1567 | 1653 | |
| 1568 | 1654 | template<class _InputIterator, class _Allocator, |
| 1569 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1655 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 1570 | 1656 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 1571 | 1657 | map(_InputIterator, _InputIterator, _Allocator) |
| 1572 | 1658 | -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 1573 | 1659 | less<__iter_key_type<_InputIterator>>, _Allocator>; |
| 1574 | 1660 | |
| 1661 | #if _LIBCPP_STD_VER >= 23 | |
| 1662 | template <ranges::input_range _Range, class _Allocator, | |
| 1663 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 1664 | map(from_range_t, _Range&&, _Allocator) | |
| 1665 | -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>; | |
| 1666 | #endif | |
| 1667 | ||
| 1575 | 1668 | template<class _Key, class _Tp, class _Allocator, |
| 1576 | 1669 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 1577 | 1670 | map(initializer_list<pair<_Key, _Tp>>, _Allocator) |
| ... | ... | @@ -1677,6 +1770,8 @@ operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, |
| 1677 | 1770 | return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 1678 | 1771 | } |
| 1679 | 1772 | |
| 1773 | #if _LIBCPP_STD_VER <= 17 | |
| 1774 | ||
| 1680 | 1775 | template <class _Key, class _Tp, class _Compare, class _Allocator> |
| 1681 | 1776 | inline _LIBCPP_INLINE_VISIBILITY |
| 1682 | 1777 | bool |
| ... | ... | @@ -1722,6 +1817,21 @@ operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, |
| 1722 | 1817 | return !(__y < __x); |
| 1723 | 1818 | } |
| 1724 | 1819 | |
| 1820 | #else // #if _LIBCPP_STD_VER <= 17 | |
| 1821 | ||
| 1822 | template <class _Key, class _Tp, class _Compare, class _Allocator> | |
| 1823 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>> | |
| 1824 | operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) { | |
| 1825 | return std::lexicographical_compare_three_way( | |
| 1826 | __x.begin(), | |
| 1827 | __x.end(), | |
| 1828 | __y.begin(), | |
| 1829 | __y.end(), | |
| 1830 | std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>); | |
| 1831 | } | |
| 1832 | ||
| 1833 | #endif // #if _LIBCPP_STD_VER <= 17 | |
| 1834 | ||
| 1725 | 1835 | template <class _Key, class _Tp, class _Compare, class _Allocator> |
| 1726 | 1836 | inline _LIBCPP_INLINE_VISIBILITY |
| 1727 | 1837 | void |
| ... | ... | @@ -1732,7 +1842,7 @@ swap(map<_Key, _Tp, _Compare, _Allocator>& __x, |
| 1732 | 1842 | __x.swap(__y); |
| 1733 | 1843 | } |
| 1734 | 1844 | |
| 1735 | #if _LIBCPP_STD_VER > 17 | |
| 1845 | #if _LIBCPP_STD_VER >= 20 | |
| 1736 | 1846 | template <class _Key, class _Tp, class _Compare, class _Allocator, |
| 1737 | 1847 | class _Predicate> |
| 1738 | 1848 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1800,7 +1910,7 @@ public: |
| 1800 | 1910 | typedef _VSTD::reverse_iterator<iterator> reverse_iterator; |
| 1801 | 1911 | typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; |
| 1802 | 1912 | |
| 1803 | #if _LIBCPP_STD_VER > 14 | |
| 1913 | #if _LIBCPP_STD_VER >= 17 | |
| 1804 | 1914 | typedef __map_node_handle<typename __base::__node, allocator_type> node_type; |
| 1805 | 1915 | #endif |
| 1806 | 1916 | |
| ... | ... | @@ -1846,13 +1956,30 @@ public: |
| 1846 | 1956 | insert(__f, __l); |
| 1847 | 1957 | } |
| 1848 | 1958 | |
| 1849 | #if _LIBCPP_STD_VER > 11 | |
| 1959 | #if _LIBCPP_STD_VER >= 23 | |
| 1960 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1961 | _LIBCPP_HIDE_FROM_ABI | |
| 1962 | multimap(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(), | |
| 1963 | const allocator_type& __a = allocator_type()) | |
| 1964 | : __tree_(__vc(__comp), typename __base::allocator_type(__a)) { | |
| 1965 | insert_range(std::forward<_Range>(__range)); | |
| 1966 | } | |
| 1967 | #endif | |
| 1968 | ||
| 1969 | #if _LIBCPP_STD_VER >= 14 | |
| 1850 | 1970 | template <class _InputIterator> |
| 1851 | 1971 | _LIBCPP_INLINE_VISIBILITY |
| 1852 | 1972 | multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) |
| 1853 | 1973 | : multimap(__f, __l, key_compare(), __a) {} |
| 1854 | 1974 | #endif |
| 1855 | 1975 | |
| 1976 | #if _LIBCPP_STD_VER >= 23 | |
| 1977 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1978 | _LIBCPP_HIDE_FROM_ABI | |
| 1979 | multimap(from_range_t, _Range&& __range, const allocator_type& __a) | |
| 1980 | : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {} | |
| 1981 | #endif | |
| 1982 | ||
| 1856 | 1983 | _LIBCPP_INLINE_VISIBILITY |
| 1857 | 1984 | multimap(const multimap& __m) |
| 1858 | 1985 | : __tree_(__m.__tree_.value_comp(), |
| ... | ... | @@ -1886,7 +2013,7 @@ public: |
| 1886 | 2013 | { |
| 1887 | 2014 | } |
| 1888 | 2015 | |
| 1889 | multimap(multimap&& __m, const allocator_type& __a); | |
| 2016 | _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a); | |
| 1890 | 2017 | |
| 1891 | 2018 | _LIBCPP_INLINE_VISIBILITY |
| 1892 | 2019 | multimap& operator=(multimap&& __m) |
| ... | ... | @@ -1910,7 +2037,7 @@ public: |
| 1910 | 2037 | insert(__il.begin(), __il.end()); |
| 1911 | 2038 | } |
| 1912 | 2039 | |
| 1913 | #if _LIBCPP_STD_VER > 11 | |
| 2040 | #if _LIBCPP_STD_VER >= 14 | |
| 1914 | 2041 | _LIBCPP_INLINE_VISIBILITY |
| 1915 | 2042 | multimap(initializer_list<value_type> __il, const allocator_type& __a) |
| 1916 | 2043 | : multimap(__il, key_compare(), __a) {} |
| ... | ... | @@ -2043,6 +2170,17 @@ public: |
| 2043 | 2170 | __tree_.__insert_multi(__e.__i_, *__f); |
| 2044 | 2171 | } |
| 2045 | 2172 | |
| 2173 | #if _LIBCPP_STD_VER >= 23 | |
| 2174 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 2175 | _LIBCPP_HIDE_FROM_ABI | |
| 2176 | void insert_range(_Range&& __range) { | |
| 2177 | const_iterator __end = cend(); | |
| 2178 | for (auto&& __element : __range) { | |
| 2179 | __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element)); | |
| 2180 | } | |
| 2181 | } | |
| 2182 | #endif | |
| 2183 | ||
| 2046 | 2184 | _LIBCPP_INLINE_VISIBILITY |
| 2047 | 2185 | iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} |
| 2048 | 2186 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -2053,11 +2191,11 @@ public: |
| 2053 | 2191 | iterator erase(const_iterator __f, const_iterator __l) |
| 2054 | 2192 | {return __tree_.erase(__f.__i_, __l.__i_);} |
| 2055 | 2193 | |
| 2056 | #if _LIBCPP_STD_VER > 14 | |
| 2194 | #if _LIBCPP_STD_VER >= 17 | |
| 2057 | 2195 | _LIBCPP_INLINE_VISIBILITY |
| 2058 | 2196 | iterator insert(node_type&& __nh) |
| 2059 | 2197 | { |
| 2060 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2198 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2061 | 2199 | "node_type with incompatible allocator passed to multimap::insert()"); |
| 2062 | 2200 | return __tree_.template __node_handle_insert_multi<node_type>( |
| 2063 | 2201 | _VSTD::move(__nh)); |
| ... | ... | @@ -2065,7 +2203,7 @@ public: |
| 2065 | 2203 | _LIBCPP_INLINE_VISIBILITY |
| 2066 | 2204 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 2067 | 2205 | { |
| 2068 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2206 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2069 | 2207 | "node_type with incompatible allocator passed to multimap::insert()"); |
| 2070 | 2208 | return __tree_.template __node_handle_insert_multi<node_type>( |
| 2071 | 2209 | __hint.__i_, _VSTD::move(__nh)); |
| ... | ... | @@ -2085,32 +2223,32 @@ public: |
| 2085 | 2223 | _LIBCPP_INLINE_VISIBILITY |
| 2086 | 2224 | void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) |
| 2087 | 2225 | { |
| 2088 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2089 | "merging container with incompatible allocator"); | |
| 2226 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2227 | "merging container with incompatible allocator"); | |
| 2090 | 2228 | return __tree_.__node_handle_merge_multi(__source.__tree_); |
| 2091 | 2229 | } |
| 2092 | 2230 | template <class _Compare2> |
| 2093 | 2231 | _LIBCPP_INLINE_VISIBILITY |
| 2094 | 2232 | void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) |
| 2095 | 2233 | { |
| 2096 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2097 | "merging container with incompatible allocator"); | |
| 2234 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2235 | "merging container with incompatible allocator"); | |
| 2098 | 2236 | return __tree_.__node_handle_merge_multi(__source.__tree_); |
| 2099 | 2237 | } |
| 2100 | 2238 | template <class _Compare2> |
| 2101 | 2239 | _LIBCPP_INLINE_VISIBILITY |
| 2102 | 2240 | void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) |
| 2103 | 2241 | { |
| 2104 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2105 | "merging container with incompatible allocator"); | |
| 2242 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2243 | "merging container with incompatible allocator"); | |
| 2106 | 2244 | return __tree_.__node_handle_merge_multi(__source.__tree_); |
| 2107 | 2245 | } |
| 2108 | 2246 | template <class _Compare2> |
| 2109 | 2247 | _LIBCPP_INLINE_VISIBILITY |
| 2110 | 2248 | void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) |
| 2111 | 2249 | { |
| 2112 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2113 | "merging container with incompatible allocator"); | |
| 2250 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2251 | "merging container with incompatible allocator"); | |
| 2114 | 2252 | return __tree_.__node_handle_merge_multi(__source.__tree_); |
| 2115 | 2253 | } |
| 2116 | 2254 | #endif |
| ... | ... | @@ -2127,7 +2265,7 @@ public: |
| 2127 | 2265 | iterator find(const key_type& __k) {return __tree_.find(__k);} |
| 2128 | 2266 | _LIBCPP_INLINE_VISIBILITY |
| 2129 | 2267 | const_iterator find(const key_type& __k) const {return __tree_.find(__k);} |
| 2130 | #if _LIBCPP_STD_VER > 11 | |
| 2268 | #if _LIBCPP_STD_VER >= 14 | |
| 2131 | 2269 | template <typename _K2> |
| 2132 | 2270 | _LIBCPP_INLINE_VISIBILITY |
| 2133 | 2271 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -2141,21 +2279,21 @@ public: |
| 2141 | 2279 | _LIBCPP_INLINE_VISIBILITY |
| 2142 | 2280 | size_type count(const key_type& __k) const |
| 2143 | 2281 | {return __tree_.__count_multi(__k);} |
| 2144 | #if _LIBCPP_STD_VER > 11 | |
| 2282 | #if _LIBCPP_STD_VER >= 14 | |
| 2145 | 2283 | template <typename _K2> |
| 2146 | 2284 | _LIBCPP_INLINE_VISIBILITY |
| 2147 | 2285 | __enable_if_t<__is_transparent<_Compare, _K2>::value, size_type> |
| 2148 | 2286 | count(const _K2& __k) const {return __tree_.__count_multi(__k);} |
| 2149 | 2287 | #endif |
| 2150 | 2288 | |
| 2151 | #if _LIBCPP_STD_VER > 17 | |
| 2289 | #if _LIBCPP_STD_VER >= 20 | |
| 2152 | 2290 | _LIBCPP_INLINE_VISIBILITY |
| 2153 | 2291 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 2154 | 2292 | template <typename _K2> |
| 2155 | 2293 | _LIBCPP_INLINE_VISIBILITY |
| 2156 | 2294 | __enable_if_t<__is_transparent<_Compare, _K2>::value, bool> |
| 2157 | 2295 | contains(const _K2& __k) const { return find(__k) != end(); } |
| 2158 | #endif // _LIBCPP_STD_VER > 17 | |
| 2296 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2159 | 2297 | |
| 2160 | 2298 | _LIBCPP_INLINE_VISIBILITY |
| 2161 | 2299 | iterator lower_bound(const key_type& __k) |
| ... | ... | @@ -2163,7 +2301,7 @@ public: |
| 2163 | 2301 | _LIBCPP_INLINE_VISIBILITY |
| 2164 | 2302 | const_iterator lower_bound(const key_type& __k) const |
| 2165 | 2303 | {return __tree_.lower_bound(__k);} |
| 2166 | #if _LIBCPP_STD_VER > 11 | |
| 2304 | #if _LIBCPP_STD_VER >= 14 | |
| 2167 | 2305 | template <typename _K2> |
| 2168 | 2306 | _LIBCPP_INLINE_VISIBILITY |
| 2169 | 2307 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -2181,7 +2319,7 @@ public: |
| 2181 | 2319 | _LIBCPP_INLINE_VISIBILITY |
| 2182 | 2320 | const_iterator upper_bound(const key_type& __k) const |
| 2183 | 2321 | {return __tree_.upper_bound(__k);} |
| 2184 | #if _LIBCPP_STD_VER > 11 | |
| 2322 | #if _LIBCPP_STD_VER >= 14 | |
| 2185 | 2323 | template <typename _K2> |
| 2186 | 2324 | _LIBCPP_INLINE_VISIBILITY |
| 2187 | 2325 | __enable_if_t<__is_transparent<_Compare, _K2>::value, iterator> |
| ... | ... | @@ -2198,7 +2336,7 @@ public: |
| 2198 | 2336 | _LIBCPP_INLINE_VISIBILITY |
| 2199 | 2337 | pair<const_iterator,const_iterator> equal_range(const key_type& __k) const |
| 2200 | 2338 | {return __tree_.__equal_range_multi(__k);} |
| 2201 | #if _LIBCPP_STD_VER > 11 | |
| 2339 | #if _LIBCPP_STD_VER >= 14 | |
| 2202 | 2340 | template <typename _K2> |
| 2203 | 2341 | _LIBCPP_INLINE_VISIBILITY |
| 2204 | 2342 | __enable_if_t<__is_transparent<_Compare, _K2>::value, pair<iterator,iterator>> |
| ... | ... | @@ -2221,12 +2359,21 @@ private: |
| 2221 | 2359 | #if _LIBCPP_STD_VER >= 17 |
| 2222 | 2360 | template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, |
| 2223 | 2361 | class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, |
| 2224 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 2362 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 2225 | 2363 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, |
| 2226 | 2364 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 2227 | 2365 | multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) |
| 2228 | 2366 | -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; |
| 2229 | 2367 | |
| 2368 | #if _LIBCPP_STD_VER >= 23 | |
| 2369 | template <ranges::input_range _Range, class _Compare = less<__range_key_type<_Range>>, | |
| 2370 | class _Allocator = allocator<__range_to_alloc_type<_Range>>, | |
| 2371 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, | |
| 2372 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 2373 | multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) | |
| 2374 | -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>; | |
| 2375 | #endif | |
| 2376 | ||
| 2230 | 2377 | template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, |
| 2231 | 2378 | class _Allocator = allocator<pair<const _Key, _Tp>>, |
| 2232 | 2379 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, |
| ... | ... | @@ -2235,12 +2382,19 @@ multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = |
| 2235 | 2382 | -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; |
| 2236 | 2383 | |
| 2237 | 2384 | template<class _InputIterator, class _Allocator, |
| 2238 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 2385 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 2239 | 2386 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 2240 | 2387 | multimap(_InputIterator, _InputIterator, _Allocator) |
| 2241 | 2388 | -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 2242 | 2389 | less<__iter_key_type<_InputIterator>>, _Allocator>; |
| 2243 | 2390 | |
| 2391 | #if _LIBCPP_STD_VER >= 23 | |
| 2392 | template <ranges::input_range _Range, class _Allocator, | |
| 2393 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 2394 | multimap(from_range_t, _Range&&, _Allocator) | |
| 2395 | -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>; | |
| 2396 | #endif | |
| 2397 | ||
| 2244 | 2398 | template<class _Key, class _Tp, class _Allocator, |
| 2245 | 2399 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 2246 | 2400 | multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) |
| ... | ... | @@ -2271,6 +2425,8 @@ operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, |
| 2271 | 2425 | return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 2272 | 2426 | } |
| 2273 | 2427 | |
| 2428 | #if _LIBCPP_STD_VER <= 17 | |
| 2429 | ||
| 2274 | 2430 | template <class _Key, class _Tp, class _Compare, class _Allocator> |
| 2275 | 2431 | inline _LIBCPP_INLINE_VISIBILITY |
| 2276 | 2432 | bool |
| ... | ... | @@ -2316,6 +2472,22 @@ operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, |
| 2316 | 2472 | return !(__y < __x); |
| 2317 | 2473 | } |
| 2318 | 2474 | |
| 2475 | #else // #if _LIBCPP_STD_VER <= 17 | |
| 2476 | ||
| 2477 | template <class _Key, class _Tp, class _Compare, class _Allocator> | |
| 2478 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>> | |
| 2479 | operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, | |
| 2480 | const multimap<_Key, _Tp, _Compare, _Allocator>& __y) { | |
| 2481 | return std::lexicographical_compare_three_way( | |
| 2482 | __x.begin(), | |
| 2483 | __x.end(), | |
| 2484 | __y.begin(), | |
| 2485 | __y.end(), | |
| 2486 | std::__synth_three_way<pair<const _Key, _Tp>, pair<const _Key, _Tp>>); | |
| 2487 | } | |
| 2488 | ||
| 2489 | #endif // #if _LIBCPP_STD_VER <= 17 | |
| 2490 | ||
| 2319 | 2491 | template <class _Key, class _Tp, class _Compare, class _Allocator> |
| 2320 | 2492 | inline _LIBCPP_INLINE_VISIBILITY |
| 2321 | 2493 | void |
| ... | ... | @@ -2326,7 +2498,7 @@ swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, |
| 2326 | 2498 | __x.swap(__y); |
| 2327 | 2499 | } |
| 2328 | 2500 | |
| 2329 | #if _LIBCPP_STD_VER > 17 | |
| 2501 | #if _LIBCPP_STD_VER >= 20 | |
| 2330 | 2502 | template <class _Key, class _Tp, class _Compare, class _Allocator, |
| 2331 | 2503 | class _Predicate> |
| 2332 | 2504 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -2339,22 +2511,24 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 2339 | 2511 | |
| 2340 | 2512 | _LIBCPP_END_NAMESPACE_STD |
| 2341 | 2513 | |
| 2342 | #if _LIBCPP_STD_VER > 14 | |
| 2514 | #if _LIBCPP_STD_VER >= 17 | |
| 2343 | 2515 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 2344 | 2516 | namespace pmr { |
| 2345 | 2517 | template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>> |
| 2346 | using map = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; | |
| 2518 | using map _LIBCPP_AVAILABILITY_PMR = std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; | |
| 2347 | 2519 | |
| 2348 | 2520 | template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>> |
| 2349 | using multimap = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; | |
| 2521 | using multimap _LIBCPP_AVAILABILITY_PMR = std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; | |
| 2350 | 2522 | } // namespace pmr |
| 2351 | 2523 | _LIBCPP_END_NAMESPACE_STD |
| 2352 | 2524 | #endif |
| 2353 | 2525 | |
| 2354 | 2526 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 2355 | 2527 | # include <concepts> |
| 2528 | # include <cstdlib> | |
| 2356 | 2529 | # include <functional> |
| 2357 | 2530 | # include <iterator> |
| 2531 | # include <type_traits> | |
| 2358 | 2532 | # include <utility> |
| 2359 | 2533 | #endif |
| 2360 | 2534 |
lib/libcxx/include/math.h-44| ... | ... | @@ -554,7 +554,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 |
| 554 | 554 | |
| 555 | 555 | // acos |
| 556 | 556 | |
| 557 | # if !defined(__sun__) | |
| 558 | 557 | inline _LIBCPP_HIDE_FROM_ABI float acos(float __x) _NOEXCEPT {return __builtin_acosf(__x);} |
| 559 | 558 | |
| 560 | 559 | template <class = int> |
| ... | ... | @@ -563,7 +562,6 @@ _LIBCPP_HIDE_FROM_ABI double acos(double __x) _NOEXCEPT { |
| 563 | 562 | } |
| 564 | 563 | |
| 565 | 564 | inline _LIBCPP_HIDE_FROM_ABI long double acos(long double __x) _NOEXCEPT {return __builtin_acosl(__x);} |
| 566 | # endif | |
| 567 | 565 | |
| 568 | 566 | template <class _A1> |
| 569 | 567 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -572,7 +570,6 @@ acos(_A1 __x) _NOEXCEPT {return __builtin_acos((double)__x);} |
| 572 | 570 | |
| 573 | 571 | // asin |
| 574 | 572 | |
| 575 | # if !defined(__sun__) | |
| 576 | 573 | inline _LIBCPP_HIDE_FROM_ABI float asin(float __x) _NOEXCEPT {return __builtin_asinf(__x);} |
| 577 | 574 | |
| 578 | 575 | template <class = int> |
| ... | ... | @@ -581,7 +578,6 @@ _LIBCPP_HIDE_FROM_ABI double asin(double __x) _NOEXCEPT { |
| 581 | 578 | } |
| 582 | 579 | |
| 583 | 580 | inline _LIBCPP_HIDE_FROM_ABI long double asin(long double __x) _NOEXCEPT {return __builtin_asinl(__x);} |
| 584 | # endif | |
| 585 | 581 | |
| 586 | 582 | template <class _A1> |
| 587 | 583 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -590,7 +586,6 @@ asin(_A1 __x) _NOEXCEPT {return __builtin_asin((double)__x);} |
| 590 | 586 | |
| 591 | 587 | // atan |
| 592 | 588 | |
| 593 | # if !defined(__sun__) | |
| 594 | 589 | inline _LIBCPP_HIDE_FROM_ABI float atan(float __x) _NOEXCEPT {return __builtin_atanf(__x);} |
| 595 | 590 | |
| 596 | 591 | template <class = int> |
| ... | ... | @@ -599,7 +594,6 @@ _LIBCPP_HIDE_FROM_ABI double atan(double __x) _NOEXCEPT { |
| 599 | 594 | } |
| 600 | 595 | |
| 601 | 596 | inline _LIBCPP_HIDE_FROM_ABI long double atan(long double __x) _NOEXCEPT {return __builtin_atanl(__x);} |
| 602 | # endif | |
| 603 | 597 | |
| 604 | 598 | template <class _A1> |
| 605 | 599 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -608,7 +602,6 @@ atan(_A1 __x) _NOEXCEPT {return __builtin_atan((double)__x);} |
| 608 | 602 | |
| 609 | 603 | // atan2 |
| 610 | 604 | |
| 611 | # if !defined(__sun__) | |
| 612 | 605 | inline _LIBCPP_HIDE_FROM_ABI float atan2(float __y, float __x) _NOEXCEPT {return __builtin_atan2f(__y, __x);} |
| 613 | 606 | |
| 614 | 607 | template <class = int> |
| ... | ... | @@ -617,7 +610,6 @@ _LIBCPP_HIDE_FROM_ABI double atan2(double __x, double __y) _NOEXCEPT { |
| 617 | 610 | } |
| 618 | 611 | |
| 619 | 612 | inline _LIBCPP_HIDE_FROM_ABI long double atan2(long double __y, long double __x) _NOEXCEPT {return __builtin_atan2l(__y, __x);} |
| 620 | # endif | |
| 621 | 613 | |
| 622 | 614 | template <class _A1, class _A2> |
| 623 | 615 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -637,7 +629,6 @@ atan2(_A1 __y, _A2 __x) _NOEXCEPT |
| 637 | 629 | |
| 638 | 630 | // ceil |
| 639 | 631 | |
| 640 | # if !defined(__sun__) | |
| 641 | 632 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float ceil(float __x) _NOEXCEPT {return __builtin_ceilf(__x);} |
| 642 | 633 | |
| 643 | 634 | template <class = int> |
| ... | ... | @@ -646,7 +637,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double ceil(double __x) _NOEXCEPT { |
| 646 | 637 | } |
| 647 | 638 | |
| 648 | 639 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double ceil(long double __x) _NOEXCEPT {return __builtin_ceill(__x);} |
| 649 | # endif | |
| 650 | 640 | |
| 651 | 641 | template <class _A1> |
| 652 | 642 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -655,7 +645,6 @@ ceil(_A1 __x) _NOEXCEPT {return __builtin_ceil((double)__x);} |
| 655 | 645 | |
| 656 | 646 | // cos |
| 657 | 647 | |
| 658 | # if !defined(__sun__) | |
| 659 | 648 | inline _LIBCPP_HIDE_FROM_ABI float cos(float __x) _NOEXCEPT {return __builtin_cosf(__x);} |
| 660 | 649 | |
| 661 | 650 | template <class = int> |
| ... | ... | @@ -664,7 +653,6 @@ _LIBCPP_HIDE_FROM_ABI double cos(double __x) _NOEXCEPT { |
| 664 | 653 | } |
| 665 | 654 | |
| 666 | 655 | inline _LIBCPP_HIDE_FROM_ABI long double cos(long double __x) _NOEXCEPT {return __builtin_cosl(__x);} |
| 667 | # endif | |
| 668 | 656 | |
| 669 | 657 | template <class _A1> |
| 670 | 658 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -673,7 +661,6 @@ cos(_A1 __x) _NOEXCEPT {return __builtin_cos((double)__x);} |
| 673 | 661 | |
| 674 | 662 | // cosh |
| 675 | 663 | |
| 676 | # if !defined(__sun__) | |
| 677 | 664 | inline _LIBCPP_HIDE_FROM_ABI float cosh(float __x) _NOEXCEPT {return __builtin_coshf(__x);} |
| 678 | 665 | |
| 679 | 666 | template <class = int> |
| ... | ... | @@ -682,7 +669,6 @@ _LIBCPP_HIDE_FROM_ABI double cosh(double __x) _NOEXCEPT { |
| 682 | 669 | } |
| 683 | 670 | |
| 684 | 671 | inline _LIBCPP_HIDE_FROM_ABI long double cosh(long double __x) _NOEXCEPT {return __builtin_coshl(__x);} |
| 685 | # endif | |
| 686 | 672 | |
| 687 | 673 | template <class _A1> |
| 688 | 674 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -691,7 +677,6 @@ cosh(_A1 __x) _NOEXCEPT {return __builtin_cosh((double)__x);} |
| 691 | 677 | |
| 692 | 678 | // exp |
| 693 | 679 | |
| 694 | # if !defined(__sun__) | |
| 695 | 680 | inline _LIBCPP_HIDE_FROM_ABI float exp(float __x) _NOEXCEPT {return __builtin_expf(__x);} |
| 696 | 681 | |
| 697 | 682 | template <class = int> |
| ... | ... | @@ -700,7 +685,6 @@ _LIBCPP_HIDE_FROM_ABI double exp(double __x) _NOEXCEPT { |
| 700 | 685 | } |
| 701 | 686 | |
| 702 | 687 | inline _LIBCPP_HIDE_FROM_ABI long double exp(long double __x) _NOEXCEPT {return __builtin_expl(__x);} |
| 703 | # endif | |
| 704 | 688 | |
| 705 | 689 | template <class _A1> |
| 706 | 690 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -709,7 +693,6 @@ exp(_A1 __x) _NOEXCEPT {return __builtin_exp((double)__x);} |
| 709 | 693 | |
| 710 | 694 | // fabs |
| 711 | 695 | |
| 712 | # if !defined(__sun__) | |
| 713 | 696 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float fabs(float __x) _NOEXCEPT {return __builtin_fabsf(__x);} |
| 714 | 697 | |
| 715 | 698 | template <class = int> |
| ... | ... | @@ -718,7 +701,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double fabs(double __x) _NOEXCEPT { |
| 718 | 701 | } |
| 719 | 702 | |
| 720 | 703 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double fabs(long double __x) _NOEXCEPT {return __builtin_fabsl(__x);} |
| 721 | # endif | |
| 722 | 704 | |
| 723 | 705 | template <class _A1> |
| 724 | 706 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -727,7 +709,6 @@ fabs(_A1 __x) _NOEXCEPT {return __builtin_fabs((double)__x);} |
| 727 | 709 | |
| 728 | 710 | // floor |
| 729 | 711 | |
| 730 | # if !defined(__sun__) | |
| 731 | 712 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI float floor(float __x) _NOEXCEPT {return __builtin_floorf(__x);} |
| 732 | 713 | |
| 733 | 714 | template <class = int> |
| ... | ... | @@ -736,7 +717,6 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI double floor(double __x) _NOEXCEPT { |
| 736 | 717 | } |
| 737 | 718 | |
| 738 | 719 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI long double floor(long double __x) _NOEXCEPT {return __builtin_floorl(__x);} |
| 739 | # endif | |
| 740 | 720 | |
| 741 | 721 | template <class _A1> |
| 742 | 722 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -745,7 +725,6 @@ floor(_A1 __x) _NOEXCEPT {return __builtin_floor((double)__x);} |
| 745 | 725 | |
| 746 | 726 | // fmod |
| 747 | 727 | |
| 748 | # if !defined(__sun__) | |
| 749 | 728 | inline _LIBCPP_HIDE_FROM_ABI float fmod(float __x, float __y) _NOEXCEPT {return __builtin_fmodf(__x, __y);} |
| 750 | 729 | |
| 751 | 730 | template <class = int> |
| ... | ... | @@ -754,7 +733,6 @@ _LIBCPP_HIDE_FROM_ABI double fmod(double __x, double __y) _NOEXCEPT { |
| 754 | 733 | } |
| 755 | 734 | |
| 756 | 735 | inline _LIBCPP_HIDE_FROM_ABI long double fmod(long double __x, long double __y) _NOEXCEPT {return __builtin_fmodl(__x, __y);} |
| 757 | # endif | |
| 758 | 736 | |
| 759 | 737 | template <class _A1, class _A2> |
| 760 | 738 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -774,7 +752,6 @@ fmod(_A1 __x, _A2 __y) _NOEXCEPT |
| 774 | 752 | |
| 775 | 753 | // frexp |
| 776 | 754 | |
| 777 | # if !defined(__sun__) | |
| 778 | 755 | inline _LIBCPP_HIDE_FROM_ABI float frexp(float __x, int* __e) _NOEXCEPT {return __builtin_frexpf(__x, __e);} |
| 779 | 756 | |
| 780 | 757 | template <class = int> |
| ... | ... | @@ -783,7 +760,6 @@ _LIBCPP_HIDE_FROM_ABI double frexp(double __x, int* __e) _NOEXCEPT { |
| 783 | 760 | } |
| 784 | 761 | |
| 785 | 762 | inline _LIBCPP_HIDE_FROM_ABI long double frexp(long double __x, int* __e) _NOEXCEPT {return __builtin_frexpl(__x, __e);} |
| 786 | # endif | |
| 787 | 763 | |
| 788 | 764 | template <class _A1> |
| 789 | 765 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -792,7 +768,6 @@ frexp(_A1 __x, int* __e) _NOEXCEPT {return __builtin_frexp((double)__x, __e);} |
| 792 | 768 | |
| 793 | 769 | // ldexp |
| 794 | 770 | |
| 795 | # if !defined(__sun__) | |
| 796 | 771 | inline _LIBCPP_HIDE_FROM_ABI float ldexp(float __x, int __e) _NOEXCEPT {return __builtin_ldexpf(__x, __e);} |
| 797 | 772 | |
| 798 | 773 | template <class = int> |
| ... | ... | @@ -801,7 +776,6 @@ _LIBCPP_HIDE_FROM_ABI double ldexp(double __x, int __e) _NOEXCEPT { |
| 801 | 776 | } |
| 802 | 777 | |
| 803 | 778 | inline _LIBCPP_HIDE_FROM_ABI long double ldexp(long double __x, int __e) _NOEXCEPT {return __builtin_ldexpl(__x, __e);} |
| 804 | # endif | |
| 805 | 779 | |
| 806 | 780 | template <class _A1> |
| 807 | 781 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -810,7 +784,6 @@ ldexp(_A1 __x, int __e) _NOEXCEPT {return __builtin_ldexp((double)__x, __e);} |
| 810 | 784 | |
| 811 | 785 | // log |
| 812 | 786 | |
| 813 | # if !defined(__sun__) | |
| 814 | 787 | inline _LIBCPP_HIDE_FROM_ABI float log(float __x) _NOEXCEPT {return __builtin_logf(__x);} |
| 815 | 788 | |
| 816 | 789 | template <class = int> |
| ... | ... | @@ -819,7 +792,6 @@ _LIBCPP_HIDE_FROM_ABI double log(double __x) _NOEXCEPT { |
| 819 | 792 | } |
| 820 | 793 | |
| 821 | 794 | inline _LIBCPP_HIDE_FROM_ABI long double log(long double __x) _NOEXCEPT {return __builtin_logl(__x);} |
| 822 | # endif | |
| 823 | 795 | |
| 824 | 796 | template <class _A1> |
| 825 | 797 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -828,7 +800,6 @@ log(_A1 __x) _NOEXCEPT {return __builtin_log((double)__x);} |
| 828 | 800 | |
| 829 | 801 | // log10 |
| 830 | 802 | |
| 831 | # if !defined(__sun__) | |
| 832 | 803 | inline _LIBCPP_HIDE_FROM_ABI float log10(float __x) _NOEXCEPT {return __builtin_log10f(__x);} |
| 833 | 804 | |
| 834 | 805 | |
| ... | ... | @@ -838,7 +809,6 @@ _LIBCPP_HIDE_FROM_ABI double log10(double __x) _NOEXCEPT { |
| 838 | 809 | } |
| 839 | 810 | |
| 840 | 811 | inline _LIBCPP_HIDE_FROM_ABI long double log10(long double __x) _NOEXCEPT {return __builtin_log10l(__x);} |
| 841 | # endif | |
| 842 | 812 | |
| 843 | 813 | template <class _A1> |
| 844 | 814 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -847,7 +817,6 @@ log10(_A1 __x) _NOEXCEPT {return __builtin_log10((double)__x);} |
| 847 | 817 | |
| 848 | 818 | // modf |
| 849 | 819 | |
| 850 | # if !defined(__sun__) | |
| 851 | 820 | inline _LIBCPP_HIDE_FROM_ABI float modf(float __x, float* __y) _NOEXCEPT {return __builtin_modff(__x, __y);} |
| 852 | 821 | |
| 853 | 822 | template <class = int> |
| ... | ... | @@ -856,11 +825,9 @@ _LIBCPP_HIDE_FROM_ABI double modf(double __x, double* __y) _NOEXCEPT { |
| 856 | 825 | } |
| 857 | 826 | |
| 858 | 827 | inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y) _NOEXCEPT {return __builtin_modfl(__x, __y);} |
| 859 | # endif | |
| 860 | 828 | |
| 861 | 829 | // pow |
| 862 | 830 | |
| 863 | # if !defined(__sun__) | |
| 864 | 831 | inline _LIBCPP_HIDE_FROM_ABI float pow(float __x, float __y) _NOEXCEPT {return __builtin_powf(__x, __y);} |
| 865 | 832 | |
| 866 | 833 | template <class = int> |
| ... | ... | @@ -869,7 +836,6 @@ _LIBCPP_HIDE_FROM_ABI double pow(double __x, double __y) _NOEXCEPT { |
| 869 | 836 | } |
| 870 | 837 | |
| 871 | 838 | inline _LIBCPP_HIDE_FROM_ABI long double pow(long double __x, long double __y) _NOEXCEPT {return __builtin_powl(__x, __y);} |
| 872 | # endif | |
| 873 | 839 | |
| 874 | 840 | template <class _A1, class _A2> |
| 875 | 841 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -889,7 +855,6 @@ pow(_A1 __x, _A2 __y) _NOEXCEPT |
| 889 | 855 | |
| 890 | 856 | // sin |
| 891 | 857 | |
| 892 | # if !defined(__sun__) | |
| 893 | 858 | inline _LIBCPP_HIDE_FROM_ABI float sin(float __x) _NOEXCEPT {return __builtin_sinf(__x);} |
| 894 | 859 | |
| 895 | 860 | template <class = int> |
| ... | ... | @@ -898,7 +863,6 @@ _LIBCPP_HIDE_FROM_ABI double sin(double __x) _NOEXCEPT { |
| 898 | 863 | } |
| 899 | 864 | |
| 900 | 865 | inline _LIBCPP_HIDE_FROM_ABI long double sin(long double __x) _NOEXCEPT {return __builtin_sinl(__x);} |
| 901 | #endif | |
| 902 | 866 | |
| 903 | 867 | template <class _A1> |
| 904 | 868 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -907,7 +871,6 @@ sin(_A1 __x) _NOEXCEPT {return __builtin_sin((double)__x);} |
| 907 | 871 | |
| 908 | 872 | // sinh |
| 909 | 873 | |
| 910 | # if !defined(__sun__) | |
| 911 | 874 | inline _LIBCPP_HIDE_FROM_ABI float sinh(float __x) _NOEXCEPT {return __builtin_sinhf(__x);} |
| 912 | 875 | |
| 913 | 876 | template <class = int> |
| ... | ... | @@ -916,7 +879,6 @@ _LIBCPP_HIDE_FROM_ABI double sinh(double __x) _NOEXCEPT { |
| 916 | 879 | } |
| 917 | 880 | |
| 918 | 881 | inline _LIBCPP_HIDE_FROM_ABI long double sinh(long double __x) _NOEXCEPT {return __builtin_sinhl(__x);} |
| 919 | # endif | |
| 920 | 882 | |
| 921 | 883 | template <class _A1> |
| 922 | 884 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -925,7 +887,6 @@ sinh(_A1 __x) _NOEXCEPT {return __builtin_sinh((double)__x);} |
| 925 | 887 | |
| 926 | 888 | // sqrt |
| 927 | 889 | |
| 928 | # if !defined(__sun__) | |
| 929 | 890 | inline _LIBCPP_HIDE_FROM_ABI float sqrt(float __x) _NOEXCEPT {return __builtin_sqrtf(__x);} |
| 930 | 891 | |
| 931 | 892 | template <class = int> |
| ... | ... | @@ -934,7 +895,6 @@ _LIBCPP_HIDE_FROM_ABI double sqrt(double __x) _NOEXCEPT { |
| 934 | 895 | } |
| 935 | 896 | |
| 936 | 897 | inline _LIBCPP_HIDE_FROM_ABI long double sqrt(long double __x) _NOEXCEPT {return __builtin_sqrtl(__x);} |
| 937 | # endif | |
| 938 | 898 | |
| 939 | 899 | template <class _A1> |
| 940 | 900 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -943,7 +903,6 @@ sqrt(_A1 __x) _NOEXCEPT {return __builtin_sqrt((double)__x);} |
| 943 | 903 | |
| 944 | 904 | // tan |
| 945 | 905 | |
| 946 | # if !defined(__sun__) | |
| 947 | 906 | inline _LIBCPP_HIDE_FROM_ABI float tan(float __x) _NOEXCEPT {return __builtin_tanf(__x);} |
| 948 | 907 | |
| 949 | 908 | template <class = int> |
| ... | ... | @@ -952,7 +911,6 @@ _LIBCPP_HIDE_FROM_ABI double tan(double __x) _NOEXCEPT { |
| 952 | 911 | } |
| 953 | 912 | |
| 954 | 913 | inline _LIBCPP_HIDE_FROM_ABI long double tan(long double __x) _NOEXCEPT {return __builtin_tanl(__x);} |
| 955 | # endif | |
| 956 | 914 | |
| 957 | 915 | template <class _A1> |
| 958 | 916 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -961,7 +919,6 @@ tan(_A1 __x) _NOEXCEPT {return __builtin_tan((double)__x);} |
| 961 | 919 | |
| 962 | 920 | // tanh |
| 963 | 921 | |
| 964 | # if !defined(__sun__) | |
| 965 | 922 | inline _LIBCPP_HIDE_FROM_ABI float tanh(float __x) _NOEXCEPT {return __builtin_tanhf(__x);} |
| 966 | 923 | |
| 967 | 924 | template <class = int> |
| ... | ... | @@ -970,7 +927,6 @@ _LIBCPP_HIDE_FROM_ABI double tanh(double __x) _NOEXCEPT { |
| 970 | 927 | } |
| 971 | 928 | |
| 972 | 929 | inline _LIBCPP_HIDE_FROM_ABI long double tanh(long double __x) _NOEXCEPT {return __builtin_tanhl(__x);} |
| 973 | # endif | |
| 974 | 930 | |
| 975 | 931 | template <class _A1> |
| 976 | 932 | inline _LIBCPP_HIDE_FROM_ABI |
lib/libcxx/include/mdspan created+357| ... | ... | @@ -0,0 +1,357 @@ |
| 1 | // -*-C++ - *- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===---------------------------------------------------------------------===// | |
| 9 | ||
| 10 | /* | |
| 11 | ||
| 12 | // Overall mdspan synopsis | |
| 13 | ||
| 14 | namespace std { | |
| 15 | // [mdspan.extents], class template extents | |
| 16 | template<class IndexType, size_t... Extents> | |
| 17 | class extents; | |
| 18 | ||
| 19 | // [mdspan.extents.dextents], alias template dextents | |
| 20 | template<class IndexType, size_t Rank> | |
| 21 | using dextents = see below; | |
| 22 | ||
| 23 | // [mdspan.layout], layout mapping | |
| 24 | struct layout_left; | |
| 25 | struct layout_right; | |
| 26 | struct layout_stride; // not implemented yet | |
| 27 | ||
| 28 | // [mdspan.accessor.default], class template default_accessor | |
| 29 | template<class ElementType> | |
| 30 | class default_accessor; | |
| 31 | ||
| 32 | // [mdspan.mdspan], class template mdspan | |
| 33 | template<class ElementType, class Extents, class LayoutPolicy = layout_right, | |
| 34 | class AccessorPolicy = default_accessor<ElementType>> | |
| 35 | class mdspan; // not implemented yet | |
| 36 | } | |
| 37 | ||
| 38 | // extents synopsis | |
| 39 | ||
| 40 | namespace std { | |
| 41 | template<class _IndexType, size_t... _Extents> | |
| 42 | class extents { | |
| 43 | public: | |
| 44 | using index_type = _IndexType; | |
| 45 | using size_type = make_unsigned_t<index_type>; | |
| 46 | using rank_type = size_t; | |
| 47 | ||
| 48 | // [mdspan.extents.obs], observers of the multidimensional index space | |
| 49 | static constexpr rank_type rank() noexcept { return sizeof...(_Extents); } | |
| 50 | static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); } | |
| 51 | static constexpr size_t static_extent(rank_type) noexcept; | |
| 52 | constexpr index_type extent(rank_type) const noexcept; | |
| 53 | ||
| 54 | // [mdspan.extents.cons], constructors | |
| 55 | constexpr extents() noexcept = default; | |
| 56 | ||
| 57 | template<class _OtherIndexType, size_t... _OtherExtents> | |
| 58 | constexpr explicit(see below) | |
| 59 | extents(const extents<_OtherIndexType, _OtherExtents...>&) noexcept; | |
| 60 | template<class... _OtherIndexTypes> | |
| 61 | constexpr explicit extents(_OtherIndexTypes...) noexcept; | |
| 62 | template<class _OtherIndexType, size_t N> | |
| 63 | constexpr explicit(N != rank_dynamic()) | |
| 64 | extents(span<_OtherIndexType, N>) noexcept; | |
| 65 | template<class _OtherIndexType, size_t N> | |
| 66 | constexpr explicit(N != rank_dynamic()) | |
| 67 | extents(const array<_OtherIndexType, N>&) noexcept; | |
| 68 | ||
| 69 | // [mdspan.extents.cmp], comparison operators | |
| 70 | template<class _OtherIndexType, size_t... _OtherExtents> | |
| 71 | friend constexpr bool operator==(const extents&, | |
| 72 | const extents<_OtherIndexType, _OtherExtents...>&) noexcept; | |
| 73 | ||
| 74 | private: | |
| 75 | // libcxx note: we do not use an array here, but we need to preserve the as-if behavior | |
| 76 | // for example the default constructor must zero initialize dynamic extents | |
| 77 | array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only | |
| 78 | }; | |
| 79 | ||
| 80 | template<class... Integrals> | |
| 81 | explicit extents(Integrals...) | |
| 82 | -> see below; | |
| 83 | } | |
| 84 | ||
| 85 | // layout_left synopsis | |
| 86 | ||
| 87 | namespace std { | |
| 88 | template<class Extents> | |
| 89 | class layout_left::mapping { | |
| 90 | public: | |
| 91 | using extents_type = Extents; | |
| 92 | using index_type = typename extents_type::index_type; | |
| 93 | using size_type = typename extents_type::size_type; | |
| 94 | using rank_type = typename extents_type::rank_type; | |
| 95 | using layout_type = layout_left; | |
| 96 | ||
| 97 | // [mdspan.layout.right.cons], constructors | |
| 98 | constexpr mapping() noexcept = default; | |
| 99 | constexpr mapping(const mapping&) noexcept = default; | |
| 100 | constexpr mapping(const extents_type&) noexcept; | |
| 101 | template<class OtherExtents> | |
| 102 | constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) | |
| 103 | mapping(const mapping<OtherExtents>&) noexcept; | |
| 104 | template<class OtherExtents> | |
| 105 | constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) | |
| 106 | mapping(const layout_right::mapping<OtherExtents>&) noexcept; | |
| 107 | template<class OtherExtents> | |
| 108 | constexpr explicit(extents_type::rank() > 0) | |
| 109 | mapping(const layout_stride::mapping<OtherExtents>&) noexcept; | |
| 110 | ||
| 111 | constexpr mapping& operator=(const mapping&) noexcept = default; | |
| 112 | ||
| 113 | // [mdspan.layout.right.obs], observers | |
| 114 | constexpr const extents_type& extents() const noexcept { return extents_; } | |
| 115 | ||
| 116 | constexpr index_type required_span_size() const noexcept; | |
| 117 | ||
| 118 | template<class... Indices> | |
| 119 | constexpr index_type operator()(Indices...) const noexcept; | |
| 120 | ||
| 121 | static constexpr bool is_always_unique() noexcept { return true; } | |
| 122 | static constexpr bool is_always_exhaustive() noexcept { return true; } | |
| 123 | static constexpr bool is_always_strided() noexcept { return true; } | |
| 124 | ||
| 125 | static constexpr bool is_unique() noexcept { return true; } | |
| 126 | static constexpr bool is_exhaustive() noexcept { return true; } | |
| 127 | static constexpr bool is_strided() noexcept { return true; } | |
| 128 | ||
| 129 | constexpr index_type stride(rank_type) const noexcept; | |
| 130 | ||
| 131 | template<class OtherExtents> | |
| 132 | friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; | |
| 133 | ||
| 134 | private: | |
| 135 | extents_type extents_{}; // exposition only | |
| 136 | }; | |
| 137 | } | |
| 138 | ||
| 139 | // layout_right synopsis | |
| 140 | ||
| 141 | namespace std { | |
| 142 | template<class Extents> | |
| 143 | class layout_right::mapping { | |
| 144 | public: | |
| 145 | using extents_type = Extents; | |
| 146 | using index_type = typename extents_type::index_type; | |
| 147 | using size_type = typename extents_type::size_type; | |
| 148 | using rank_type = typename extents_type::rank_type; | |
| 149 | using layout_type = layout_right; | |
| 150 | ||
| 151 | // [mdspan.layout.right.cons], constructors | |
| 152 | constexpr mapping() noexcept = default; | |
| 153 | constexpr mapping(const mapping&) noexcept = default; | |
| 154 | constexpr mapping(const extents_type&) noexcept; | |
| 155 | template<class OtherExtents> | |
| 156 | constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) | |
| 157 | mapping(const mapping<OtherExtents>&) noexcept; | |
| 158 | template<class OtherExtents> | |
| 159 | constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) | |
| 160 | mapping(const layout_left::mapping<OtherExtents>&) noexcept; | |
| 161 | template<class OtherExtents> | |
| 162 | constexpr explicit(extents_type::rank() > 0) | |
| 163 | mapping(const layout_stride::mapping<OtherExtents>&) noexcept; | |
| 164 | ||
| 165 | constexpr mapping& operator=(const mapping&) noexcept = default; | |
| 166 | ||
| 167 | // [mdspan.layout.right.obs], observers | |
| 168 | constexpr const extents_type& extents() const noexcept { return extents_; } | |
| 169 | ||
| 170 | constexpr index_type required_span_size() const noexcept; | |
| 171 | ||
| 172 | template<class... Indices> | |
| 173 | constexpr index_type operator()(Indices...) const noexcept; | |
| 174 | ||
| 175 | static constexpr bool is_always_unique() noexcept { return true; } | |
| 176 | static constexpr bool is_always_exhaustive() noexcept { return true; } | |
| 177 | static constexpr bool is_always_strided() noexcept { return true; } | |
| 178 | ||
| 179 | static constexpr bool is_unique() noexcept { return true; } | |
| 180 | static constexpr bool is_exhaustive() noexcept { return true; } | |
| 181 | static constexpr bool is_strided() noexcept { return true; } | |
| 182 | ||
| 183 | constexpr index_type stride(rank_type) const noexcept; | |
| 184 | ||
| 185 | template<class OtherExtents> | |
| 186 | friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; | |
| 187 | ||
| 188 | private: | |
| 189 | extents_type extents_{}; // exposition only | |
| 190 | }; | |
| 191 | } | |
| 192 | ||
| 193 | // default_accessor synopsis | |
| 194 | ||
| 195 | namespace std { | |
| 196 | template<class ElementType> | |
| 197 | struct default_accessor { | |
| 198 | using offset_policy = default_accessor; | |
| 199 | using element_type = ElementType; | |
| 200 | using reference = ElementType&; | |
| 201 | using data_handle_type = ElementType*; | |
| 202 | ||
| 203 | constexpr default_accessor() noexcept = default; | |
| 204 | template<class OtherElementType> | |
| 205 | constexpr default_accessor(default_accessor<OtherElementType>) noexcept; | |
| 206 | constexpr reference access(data_handle_type p, size_t i) const noexcept; | |
| 207 | constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; | |
| 208 | }; | |
| 209 | } | |
| 210 | ||
| 211 | // mdspan synopsis | |
| 212 | ||
| 213 | namespace std { | |
| 214 | template<class ElementType, class Extents, class LayoutPolicy = layout_right, | |
| 215 | class AccessorPolicy = default_accessor<ElementType>> | |
| 216 | class mdspan { | |
| 217 | public: | |
| 218 | using extents_type = Extents; | |
| 219 | using layout_type = LayoutPolicy; | |
| 220 | using accessor_type = AccessorPolicy; | |
| 221 | using mapping_type = typename layout_type::template mapping<extents_type>; | |
| 222 | using element_type = ElementType; | |
| 223 | using value_type = remove_cv_t<element_type>; | |
| 224 | using index_type = typename extents_type::index_type; | |
| 225 | using size_type = typename extents_type::size_type; | |
| 226 | using rank_type = typename extents_type::rank_type; | |
| 227 | using data_handle_type = typename accessor_type::data_handle_type; | |
| 228 | using reference = typename accessor_type::reference; | |
| 229 | ||
| 230 | static constexpr rank_type rank() noexcept { return extents_type::rank(); } | |
| 231 | static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } | |
| 232 | static constexpr size_t static_extent(rank_type r) noexcept | |
| 233 | { return extents_type::static_extent(r); } | |
| 234 | constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); } | |
| 235 | ||
| 236 | // [mdspan.mdspan.cons], constructors | |
| 237 | constexpr mdspan(); | |
| 238 | constexpr mdspan(const mdspan& rhs) = default; | |
| 239 | constexpr mdspan(mdspan&& rhs) = default; | |
| 240 | ||
| 241 | template<class... OtherIndexTypes> | |
| 242 | constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts); | |
| 243 | template<class OtherIndexType, size_t N> | |
| 244 | constexpr explicit(N != rank_dynamic()) | |
| 245 | mdspan(data_handle_type p, span<OtherIndexType, N> exts); | |
| 246 | template<class OtherIndexType, size_t N> | |
| 247 | constexpr explicit(N != rank_dynamic()) | |
| 248 | mdspan(data_handle_type p, const array<OtherIndexType, N>& exts); | |
| 249 | constexpr mdspan(data_handle_type p, const extents_type& ext); | |
| 250 | constexpr mdspan(data_handle_type p, const mapping_type& m); | |
| 251 | constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); | |
| 252 | ||
| 253 | template<class OtherElementType, class OtherExtents, | |
| 254 | class OtherLayoutPolicy, class OtherAccessorPolicy> | |
| 255 | constexpr explicit(see below) | |
| 256 | mdspan(const mdspan<OtherElementType, OtherExtents, | |
| 257 | OtherLayoutPolicy, OtherAccessorPolicy>& other); | |
| 258 | ||
| 259 | constexpr mdspan& operator=(const mdspan& rhs) = default; | |
| 260 | constexpr mdspan& operator=(mdspan&& rhs) = default; | |
| 261 | ||
| 262 | // [mdspan.mdspan.members], members | |
| 263 | template<class... OtherIndexTypes> | |
| 264 | constexpr reference operator[](OtherIndexTypes... indices) const; | |
| 265 | template<class OtherIndexType> | |
| 266 | constexpr reference operator[](span<OtherIndexType, rank()> indices) const; | |
| 267 | template<class OtherIndexType> | |
| 268 | constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const; | |
| 269 | ||
| 270 | constexpr size_type size() const noexcept; | |
| 271 | [[nodiscard]] constexpr bool empty() const noexcept; | |
| 272 | ||
| 273 | friend constexpr void swap(mdspan& x, mdspan& y) noexcept; | |
| 274 | ||
| 275 | constexpr const extents_type& extents() const noexcept { return map_.extents(); } | |
| 276 | constexpr const data_handle_type& data_handle() const noexcept { return ptr_; } | |
| 277 | constexpr const mapping_type& mapping() const noexcept { return map_; } | |
| 278 | constexpr const accessor_type& accessor() const noexcept { return acc_; } | |
| 279 | ||
| 280 | static constexpr bool is_always_unique() | |
| 281 | { return mapping_type::is_always_unique(); } | |
| 282 | static constexpr bool is_always_exhaustive() | |
| 283 | { return mapping_type::is_always_exhaustive(); } | |
| 284 | static constexpr bool is_always_strided() | |
| 285 | { return mapping_type::is_always_strided(); } | |
| 286 | ||
| 287 | constexpr bool is_unique() const | |
| 288 | { return map_.is_unique(); } | |
| 289 | constexpr bool is_exhaustive() const | |
| 290 | { return map_.is_exhaustive(); } | |
| 291 | constexpr bool is_strided() const | |
| 292 | { return map_.is_strided(); } | |
| 293 | constexpr index_type stride(rank_type r) const | |
| 294 | { return map_.stride(r); } | |
| 295 | ||
| 296 | private: | |
| 297 | accessor_type acc_; // exposition only | |
| 298 | mapping_type map_; // exposition only | |
| 299 | data_handle_type ptr_; // exposition only | |
| 300 | }; | |
| 301 | ||
| 302 | template<class CArray> | |
| 303 | requires(is_array_v<CArray> && rank_v<CArray> == 1) | |
| 304 | mdspan(CArray&) | |
| 305 | -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>; | |
| 306 | ||
| 307 | template<class Pointer> | |
| 308 | requires(is_pointer_v<remove_reference_t<Pointer>>) | |
| 309 | mdspan(Pointer&&) | |
| 310 | -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>; | |
| 311 | ||
| 312 | template<class ElementType, class... Integrals> | |
| 313 | requires((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0) | |
| 314 | explicit mdspan(ElementType*, Integrals...) | |
| 315 | -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>; | |
| 316 | ||
| 317 | template<class ElementType, class OtherIndexType, size_t N> | |
| 318 | mdspan(ElementType*, span<OtherIndexType, N>) | |
| 319 | -> mdspan<ElementType, dextents<size_t, N>>; | |
| 320 | ||
| 321 | template<class ElementType, class OtherIndexType, size_t N> | |
| 322 | mdspan(ElementType*, const array<OtherIndexType, N>&) | |
| 323 | -> mdspan<ElementType, dextents<size_t, N>>; | |
| 324 | ||
| 325 | template<class ElementType, class IndexType, size_t... ExtentsPack> | |
| 326 | mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&) | |
| 327 | -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>; | |
| 328 | ||
| 329 | template<class ElementType, class MappingType> | |
| 330 | mdspan(ElementType*, const MappingType&) | |
| 331 | -> mdspan<ElementType, typename MappingType::extents_type, | |
| 332 | typename MappingType::layout_type>; | |
| 333 | ||
| 334 | template<class MappingType, class AccessorType> | |
| 335 | mdspan(const typename AccessorType::data_handle_type&, const MappingType&, | |
| 336 | const AccessorType&) | |
| 337 | -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type, | |
| 338 | typename MappingType::layout_type, AccessorType>; | |
| 339 | } | |
| 340 | */ | |
| 341 | ||
| 342 | #ifndef _LIBCPP_MDSPAN | |
| 343 | #define _LIBCPP_MDSPAN | |
| 344 | ||
| 345 | #include <__config> | |
| 346 | #include <__fwd/mdspan.h> | |
| 347 | #include <__mdspan/default_accessor.h> | |
| 348 | #include <__mdspan/extents.h> | |
| 349 | #include <__mdspan/layout_left.h> | |
| 350 | #include <__mdspan/layout_right.h> | |
| 351 | #include <__mdspan/mdspan.h> | |
| 352 | ||
| 353 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 354 | # pragma GCC system_header | |
| 355 | #endif | |
| 356 | ||
| 357 | #endif // _LIBCPP_MDSPAN |
lib/libcxx/include/memory+3-5| ... | ... | @@ -160,7 +160,7 @@ template <class T, class U> |
| 160 | 160 | bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 |
| 161 | 161 | |
| 162 | 162 | template <class T, class U> |
| 163 | bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20 | |
| 163 | bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // removed in C++20 | |
| 164 | 164 | |
| 165 | 165 | template <class OutputIterator, class T> |
| 166 | 166 | class raw_storage_iterator // deprecated in C++17, removed in C++20 |
| ... | ... | @@ -912,14 +912,12 @@ template<size_t N, class T> |
| 912 | 912 | # pragma GCC system_header |
| 913 | 913 | #endif |
| 914 | 914 | |
| 915 | #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 | |
| 916 | # include <__pstl_memory> | |
| 917 | #endif | |
| 918 | ||
| 919 | 915 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 916 | # include <atomic> | |
| 920 | 917 | # include <concepts> |
| 921 | 918 | # include <cstddef> |
| 922 | 919 | # include <cstdint> |
| 920 | # include <cstdlib> | |
| 923 | 921 | # include <cstring> |
| 924 | 922 | # include <iosfwd> |
| 925 | 923 | # include <iterator> |
lib/libcxx/include/memory_resource+2-2| ... | ... | @@ -22,7 +22,7 @@ namespace std::pmr { |
| 22 | 22 | bool operator==(const memory_resource& a, |
| 23 | 23 | const memory_resource& b) noexcept; |
| 24 | 24 | bool operator!=(const memory_resource& a, |
| 25 | const memory_resource& b) noexcept; | |
| 25 | const memory_resource& b) noexcept; // removed in C++20 | |
| 26 | 26 | |
| 27 | 27 | template <class Tp> class polymorphic_allocator; |
| 28 | 28 | |
| ... | ... | @@ -31,7 +31,7 @@ namespace std::pmr { |
| 31 | 31 | const polymorphic_allocator<T2>& b) noexcept; |
| 32 | 32 | template <class T1, class T2> |
| 33 | 33 | bool operator!=(const polymorphic_allocator<T1>& a, |
| 34 | const polymorphic_allocator<T2>& b) noexcept; | |
| 34 | const polymorphic_allocator<T2>& b) noexcept; // removed in C++20 | |
| 35 | 35 | |
| 36 | 36 | // Global memory resources |
| 37 | 37 | memory_resource* set_default_resource(memory_resource* r) noexcept; |
lib/libcxx/include/mutex+32-17| ... | ... | @@ -187,12 +187,20 @@ template<class Callable, class ...Args> |
| 187 | 187 | */ |
| 188 | 188 | |
| 189 | 189 | #include <__assert> // all public C++ headers provide the assertion handler |
| 190 | #include <__chrono/steady_clock.h> | |
| 191 | #include <__chrono/time_point.h> | |
| 192 | #include <__condition_variable/condition_variable.h> | |
| 190 | 193 | #include <__config> |
| 191 | 194 | #include <__memory/shared_ptr.h> |
| 192 | #include <__mutex_base> | |
| 195 | #include <__mutex/lock_guard.h> | |
| 196 | #include <__mutex/mutex.h> | |
| 197 | #include <__mutex/tag_types.h> | |
| 198 | #include <__mutex/unique_lock.h> | |
| 199 | #include <__thread/id.h> | |
| 193 | 200 | #include <__threading_support> |
| 194 | 201 | #include <__utility/forward.h> |
| 195 | 202 | #include <cstdint> |
| 203 | #include <limits> | |
| 196 | 204 | #ifndef _LIBCPP_CXX03_LANG |
| 197 | 205 | # include <tuple> |
| 198 | 206 | #endif |
| ... | ... | @@ -210,7 +218,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 210 | 218 | |
| 211 | 219 | #ifndef _LIBCPP_HAS_NO_THREADS |
| 212 | 220 | |
| 213 | class _LIBCPP_TYPE_VIS recursive_mutex | |
| 221 | class _LIBCPP_EXPORTED_FROM_ABI recursive_mutex | |
| 214 | 222 | { |
| 215 | 223 | __libcpp_recursive_mutex_t __m_; |
| 216 | 224 | |
| ... | ... | @@ -231,7 +239,7 @@ public: |
| 231 | 239 | native_handle_type native_handle() {return &__m_;} |
| 232 | 240 | }; |
| 233 | 241 | |
| 234 | class _LIBCPP_TYPE_VIS timed_mutex | |
| 242 | class _LIBCPP_EXPORTED_FROM_ABI timed_mutex | |
| 235 | 243 | { |
| 236 | 244 | mutex __m_; |
| 237 | 245 | condition_variable __cv_; |
| ... | ... | @@ -262,9 +270,9 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) |
| 262 | 270 | { |
| 263 | 271 | using namespace chrono; |
| 264 | 272 | unique_lock<mutex> __lk(__m_); |
| 265 | bool no_timeout = _Clock::now() < __t; | |
| 266 | while (no_timeout && __locked_) | |
| 267 | no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; | |
| 273 | bool __no_timeout = _Clock::now() < __t; | |
| 274 | while (__no_timeout && __locked_) | |
| 275 | __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; | |
| 268 | 276 | if (!__locked_) |
| 269 | 277 | { |
| 270 | 278 | __locked_ = true; |
| ... | ... | @@ -273,7 +281,7 @@ timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) |
| 273 | 281 | return false; |
| 274 | 282 | } |
| 275 | 283 | |
| 276 | class _LIBCPP_TYPE_VIS recursive_timed_mutex | |
| 284 | class _LIBCPP_EXPORTED_FROM_ABI recursive_timed_mutex | |
| 277 | 285 | { |
| 278 | 286 | mutex __m_; |
| 279 | 287 | condition_variable __cv_; |
| ... | ... | @@ -304,7 +312,7 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration |
| 304 | 312 | { |
| 305 | 313 | using namespace chrono; |
| 306 | 314 | __thread_id __id = this_thread::get_id(); |
| 307 | unique_lock<mutex> lk(__m_); | |
| 315 | unique_lock<mutex> __lk(__m_); | |
| 308 | 316 | if (__id == __id_) |
| 309 | 317 | { |
| 310 | 318 | if (__count_ == numeric_limits<size_t>::max()) |
| ... | ... | @@ -312,9 +320,9 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration |
| 312 | 320 | ++__count_; |
| 313 | 321 | return true; |
| 314 | 322 | } |
| 315 | bool no_timeout = _Clock::now() < __t; | |
| 316 | while (no_timeout && __count_ != 0) | |
| 317 | no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; | |
| 323 | bool __no_timeout = _Clock::now() < __t; | |
| 324 | while (__no_timeout && __count_ != 0) | |
| 325 | __no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; | |
| 318 | 326 | if (__count_ == 0) |
| 319 | 327 | { |
| 320 | 328 | __count_ = 1; |
| ... | ... | @@ -328,7 +336,7 @@ template <class _L0, class _L1> |
| 328 | 336 | _LIBCPP_HIDE_FROM_ABI int |
| 329 | 337 | try_lock(_L0& __l0, _L1& __l1) |
| 330 | 338 | { |
| 331 | unique_lock<_L0> __u0(__l0, try_to_lock); | |
| 339 | unique_lock<_L0> __u0(__l0, try_to_lock_t()); | |
| 332 | 340 | if (__u0.owns_lock()) |
| 333 | 341 | { |
| 334 | 342 | if (__l1.try_lock()) |
| ... | ... | @@ -467,7 +475,7 @@ void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) { |
| 467 | 475 | |
| 468 | 476 | #endif // _LIBCPP_CXX03_LANG |
| 469 | 477 | |
| 470 | #if _LIBCPP_STD_VER > 14 | |
| 478 | #if _LIBCPP_STD_VER >= 17 | |
| 471 | 479 | template <class ..._Mutexes> |
| 472 | 480 | class _LIBCPP_TEMPLATE_VIS scoped_lock; |
| 473 | 481 | |
| ... | ... | @@ -544,7 +552,7 @@ private: |
| 544 | 552 | }; |
| 545 | 553 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(scoped_lock); |
| 546 | 554 | |
| 547 | #endif // _LIBCPP_STD_VER > 14 | |
| 555 | #endif // _LIBCPP_STD_VER >= 17 | |
| 548 | 556 | #endif // !_LIBCPP_HAS_NO_THREADS |
| 549 | 557 | |
| 550 | 558 | struct _LIBCPP_TEMPLATE_VIS once_flag; |
| ... | ... | @@ -652,8 +660,7 @@ __call_once_proxy(void* __vp) |
| 652 | 660 | (*__p)(); |
| 653 | 661 | } |
| 654 | 662 | |
| 655 | _LIBCPP_FUNC_VIS void __call_once(volatile once_flag::_State_type&, void*, | |
| 656 | void (*)(void*)); | |
| 663 | _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*)); | |
| 657 | 664 | |
| 658 | 665 | #ifndef _LIBCPP_CXX03_LANG |
| 659 | 666 | |
| ... | ... | @@ -704,9 +711,17 @@ _LIBCPP_END_NAMESPACE_STD |
| 704 | 711 | _LIBCPP_POP_MACROS |
| 705 | 712 | |
| 706 | 713 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 714 | # include <atomic> | |
| 707 | 715 | # include <concepts> |
| 708 | # include <functional> | |
| 716 | # include <cstdlib> | |
| 717 | # include <cstring> | |
| 718 | # include <ctime> | |
| 719 | # include <initializer_list> | |
| 720 | # include <new> | |
| 721 | # include <stdexcept> | |
| 722 | # include <system_error> | |
| 709 | 723 | # include <type_traits> |
| 724 | # include <typeinfo> | |
| 710 | 725 | #endif |
| 711 | 726 | |
| 712 | 727 | #endif // _LIBCPP_MUTEX |
lib/libcxx/include/new+18-55| ... | ... | @@ -89,12 +89,14 @@ void operator delete[](void* ptr, void*) noexcept; |
| 89 | 89 | #include <__assert> // all public C++ headers provide the assertion handler |
| 90 | 90 | #include <__availability> |
| 91 | 91 | #include <__config> |
| 92 | #include <__exception/exception.h> | |
| 93 | #include <__type_traits/alignment_of.h> | |
| 92 | 94 | #include <__type_traits/is_function.h> |
| 93 | 95 | #include <__type_traits/is_same.h> |
| 94 | 96 | #include <__type_traits/remove_cv.h> |
| 97 | #include <__verbose_abort> | |
| 95 | 98 | #include <cstddef> |
| 96 | 99 | #include <cstdlib> |
| 97 | #include <exception> | |
| 98 | 100 | #include <version> |
| 99 | 101 | |
| 100 | 102 | #if defined(_LIBCPP_ABI_VCRUNTIME) |
| ... | ... | @@ -123,10 +125,10 @@ namespace std // purposefully not using versioning namespace |
| 123 | 125 | { |
| 124 | 126 | |
| 125 | 127 | #if !defined(_LIBCPP_ABI_VCRUNTIME) |
| 126 | struct _LIBCPP_TYPE_VIS nothrow_t { explicit nothrow_t() = default; }; | |
| 127 | extern _LIBCPP_FUNC_VIS const nothrow_t nothrow; | |
| 128 | struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t { explicit nothrow_t() = default; }; | |
| 129 | extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow; | |
| 128 | 130 | |
| 129 | class _LIBCPP_EXCEPTION_ABI bad_alloc | |
| 131 | class _LIBCPP_EXPORTED_FROM_ABI bad_alloc | |
| 130 | 132 | : public exception |
| 131 | 133 | { |
| 132 | 134 | public: |
| ... | ... | @@ -135,7 +137,7 @@ public: |
| 135 | 137 | const char* what() const _NOEXCEPT override; |
| 136 | 138 | }; |
| 137 | 139 | |
| 138 | class _LIBCPP_EXCEPTION_ABI bad_array_new_length | |
| 140 | class _LIBCPP_EXPORTED_FROM_ABI bad_array_new_length | |
| 139 | 141 | : public bad_alloc |
| 140 | 142 | { |
| 141 | 143 | public: |
| ... | ... | @@ -145,8 +147,8 @@ public: |
| 145 | 147 | }; |
| 146 | 148 | |
| 147 | 149 | typedef void (*new_handler)(); |
| 148 | _LIBCPP_FUNC_VIS new_handler set_new_handler(new_handler) _NOEXCEPT; | |
| 149 | _LIBCPP_FUNC_VIS new_handler get_new_handler() _NOEXCEPT; | |
| 150 | _LIBCPP_EXPORTED_FROM_ABI new_handler set_new_handler(new_handler) _NOEXCEPT; | |
| 151 | _LIBCPP_EXPORTED_FROM_ABI new_handler get_new_handler() _NOEXCEPT; | |
| 150 | 152 | |
| 151 | 153 | #elif defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 // !_LIBCPP_ABI_VCRUNTIME |
| 152 | 154 | |
| ... | ... | @@ -168,15 +170,15 @@ public: |
| 168 | 170 | }; |
| 169 | 171 | #endif // defined(_LIBCPP_ABI_VCRUNTIME) && defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 |
| 170 | 172 | |
| 171 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec | |
| 173 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_bad_alloc(); // not in C++ spec | |
| 172 | 174 | |
| 173 | 175 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 174 | 176 | void __throw_bad_array_new_length() |
| 175 | 177 | { |
| 176 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 178 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 177 | 179 | throw bad_array_new_length(); |
| 178 | 180 | #else |
| 179 | _VSTD::abort(); | |
| 181 | _LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode"); | |
| 180 | 182 | #endif |
| 181 | 183 | } |
| 182 | 184 | |
| ... | ... | @@ -189,14 +191,14 @@ enum align_val_t { __zero = 0, __max = (size_t)-1 }; |
| 189 | 191 | #endif |
| 190 | 192 | #endif |
| 191 | 193 | |
| 192 | #if _LIBCPP_STD_VER > 17 | |
| 194 | #if _LIBCPP_STD_VER >= 20 | |
| 193 | 195 | // Enable the declaration even if the compiler doesn't support the language |
| 194 | 196 | // feature. |
| 195 | 197 | struct destroying_delete_t { |
| 196 | 198 | explicit destroying_delete_t() = default; |
| 197 | 199 | }; |
| 198 | 200 | inline constexpr destroying_delete_t destroying_delete{}; |
| 199 | #endif // _LIBCPP_STD_VER > 17 | |
| 201 | #endif // _LIBCPP_STD_VER >= 20 | |
| 200 | 202 | |
| 201 | 203 | } // namespace std |
| 202 | 204 | |
| ... | ... | @@ -332,46 +334,6 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate_unsized(void* __ptr, s |
| 332 | 334 | #endif |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION) | |
| 336 | // Low-level helpers to call the aligned allocation and deallocation functions | |
| 337 | // on the target platform. This is used to implement libc++'s own memory | |
| 338 | // allocation routines -- if you need to allocate memory inside the library, | |
| 339 | // chances are that you want to use `__libcpp_allocate` instead. | |
| 340 | // | |
| 341 | // Returns the allocated memory, or `nullptr` on failure. | |
| 342 | inline _LIBCPP_INLINE_VISIBILITY void* __libcpp_aligned_alloc(std::size_t __alignment, std::size_t __size) { | |
| 343 | # if defined(_LIBCPP_MSVCRT_LIKE) | |
| 344 | return ::_aligned_malloc(__size, __alignment); | |
| 345 | # elif _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_C11_ALIGNED_ALLOC) | |
| 346 | // aligned_alloc() requires that __size is a multiple of __alignment, | |
| 347 | // but for C++ [new.delete.general], only states "if the value of an | |
| 348 | // alignment argument passed to any of these functions is not a valid | |
| 349 | // alignment value, the behavior is undefined". | |
| 350 | // To handle calls such as ::operator new(1, std::align_val_t(128)), we | |
| 351 | // round __size up to the next multiple of __alignment. | |
| 352 | size_t __rounded_size = (__size + __alignment - 1) & ~(__alignment - 1); | |
| 353 | // Rounding up could have wrapped around to zero, so we have to add another | |
| 354 | // max() ternary to the actual call site to avoid succeeded in that case. | |
| 355 | return ::aligned_alloc(__alignment, __size > __rounded_size ? __size : __rounded_size); | |
| 356 | # else | |
| 357 | void* __result = nullptr; | |
| 358 | (void)::posix_memalign(&__result, __alignment, __size); | |
| 359 | // If posix_memalign fails, __result is unmodified so we still return `nullptr`. | |
| 360 | return __result; | |
| 361 | # endif | |
| 362 | } | |
| 363 | ||
| 364 | inline _LIBCPP_INLINE_VISIBILITY | |
| 365 | void __libcpp_aligned_free(void* __ptr) { | |
| 366 | #if defined(_LIBCPP_MSVCRT_LIKE) | |
| 367 | ::_aligned_free(__ptr); | |
| 368 | #else | |
| 369 | ::free(__ptr); | |
| 370 | #endif | |
| 371 | } | |
| 372 | #endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION | |
| 373 | ||
| 374 | ||
| 375 | 337 | template <class _Tp> |
| 376 | 338 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI |
| 377 | 339 | _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT |
| ... | ... | @@ -381,7 +343,7 @@ _LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT |
| 381 | 343 | return __builtin_launder(__p); |
| 382 | 344 | } |
| 383 | 345 | |
| 384 | #if _LIBCPP_STD_VER > 14 | |
| 346 | #if _LIBCPP_STD_VER >= 17 | |
| 385 | 347 | template <class _Tp> |
| 386 | 348 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI |
| 387 | 349 | constexpr _Tp* launder(_Tp* __p) noexcept |
| ... | ... | @@ -390,7 +352,7 @@ constexpr _Tp* launder(_Tp* __p) noexcept |
| 390 | 352 | } |
| 391 | 353 | #endif |
| 392 | 354 | |
| 393 | #if _LIBCPP_STD_VER > 14 | |
| 355 | #if _LIBCPP_STD_VER >= 17 | |
| 394 | 356 | |
| 395 | 357 | #if defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) |
| 396 | 358 | |
| ... | ... | @@ -399,11 +361,12 @@ inline constexpr size_t hardware_constructive_interference_size = __GCC_CONSTRUC |
| 399 | 361 | |
| 400 | 362 | #endif // defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE) |
| 401 | 363 | |
| 402 | #endif // _LIBCPP_STD_VER > 14 | |
| 364 | #endif // _LIBCPP_STD_VER >= 17 | |
| 403 | 365 | |
| 404 | 366 | _LIBCPP_END_NAMESPACE_STD |
| 405 | 367 | |
| 406 | 368 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 369 | # include <exception> | |
| 407 | 370 | # include <type_traits> |
| 408 | 371 | #endif |
| 409 | 372 |
lib/libcxx/include/numbers+2-2| ... | ... | @@ -63,7 +63,7 @@ namespace std::numbers { |
| 63 | 63 | #include <__config> |
| 64 | 64 | #include <version> |
| 65 | 65 | |
| 66 | #if _LIBCPP_STD_VER > 17 | |
| 66 | #if _LIBCPP_STD_VER >= 20 | |
| 67 | 67 | |
| 68 | 68 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 69 | 69 | # pragma GCC system_header |
| ... | ... | @@ -128,7 +128,7 @@ inline constexpr double phi = phi_v<double>; |
| 128 | 128 | |
| 129 | 129 | _LIBCPP_END_NAMESPACE_STD |
| 130 | 130 | |
| 131 | #endif // _LIBCPP_STD_VER > 17 | |
| 131 | #endif // _LIBCPP_STD_VER >= 20 | |
| 132 | 132 | |
| 133 | 133 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 134 | 134 | # include <concepts> |
lib/libcxx/include/numeric+2-4| ... | ... | @@ -158,6 +158,8 @@ template<class T> |
| 158 | 158 | #include <__numeric/iota.h> |
| 159 | 159 | #include <__numeric/midpoint.h> |
| 160 | 160 | #include <__numeric/partial_sum.h> |
| 161 | #include <__numeric/pstl_reduce.h> | |
| 162 | #include <__numeric/pstl_transform_reduce.h> | |
| 161 | 163 | #include <__numeric/reduce.h> |
| 162 | 164 | #include <__numeric/transform_exclusive_scan.h> |
| 163 | 165 | #include <__numeric/transform_inclusive_scan.h> |
| ... | ... | @@ -167,10 +169,6 @@ template<class T> |
| 167 | 169 | # pragma GCC system_header |
| 168 | 170 | #endif |
| 169 | 171 | |
| 170 | #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 | |
| 171 | # include <__pstl_numeric> | |
| 172 | #endif | |
| 173 | ||
| 174 | 172 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 175 | 173 | # include <concepts> |
| 176 | 174 | # include <functional> |
lib/libcxx/include/optional+208-107| ... | ... | @@ -16,107 +16,126 @@ |
| 16 | 16 | // C++1z |
| 17 | 17 | |
| 18 | 18 | namespace std { |
| 19 | // 23.6.3, optional for object types | |
| 20 | template <class T> class optional; | |
| 19 | // [optional.optional], class template optional | |
| 20 | template <class T> | |
| 21 | class optional; | |
| 21 | 22 | |
| 22 | // 23.6.4, no-value state indicator | |
| 23 | template<class T> | |
| 24 | concept is-derived-from-optional = requires(const T& t) { // exposition only | |
| 25 | []<class U>(const optional<U>&){ }(t); | |
| 26 | }; | |
| 27 | ||
| 28 | // [optional.nullopt], no-value state indicator | |
| 23 | 29 | struct nullopt_t{see below }; |
| 24 | 30 | inline constexpr nullopt_t nullopt(unspecified ); |
| 25 | 31 | |
| 26 | // 23.6.5, class bad_optional_access | |
| 32 | // [optional.bad.access], class bad_optional_access | |
| 27 | 33 | class bad_optional_access; |
| 28 | 34 | |
| 29 | // 23.6.6, relational operators | |
| 35 | // [optional.relops], relational operators | |
| 30 | 36 | template <class T, class U> |
| 31 | constexpr bool operator==(const optional<T>&, const optional<U>&); | |
| 37 | constexpr bool operator==(const optional<T>&, const optional<U>&); | |
| 32 | 38 | template <class T, class U> |
| 33 | constexpr bool operator!=(const optional<T>&, const optional<U>&); | |
| 39 | constexpr bool operator!=(const optional<T>&, const optional<U>&); | |
| 34 | 40 | template <class T, class U> |
| 35 | constexpr bool operator<(const optional<T>&, const optional<U>&); | |
| 41 | constexpr bool operator<(const optional<T>&, const optional<U>&); | |
| 36 | 42 | template <class T, class U> |
| 37 | constexpr bool operator>(const optional<T>&, const optional<U>&); | |
| 43 | constexpr bool operator>(const optional<T>&, const optional<U>&); | |
| 38 | 44 | template <class T, class U> |
| 39 | constexpr bool operator<=(const optional<T>&, const optional<U>&); | |
| 45 | constexpr bool operator<=(const optional<T>&, const optional<U>&); | |
| 40 | 46 | template <class T, class U> |
| 41 | constexpr bool operator>=(const optional<T>&, const optional<U>&); | |
| 42 | ||
| 43 | // 23.6.7 comparison with nullopt | |
| 44 | template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; | |
| 45 | template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; | |
| 46 | template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; | |
| 47 | template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; | |
| 48 | template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; | |
| 49 | template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; | |
| 50 | template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; | |
| 51 | template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; | |
| 52 | template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; | |
| 53 | template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; | |
| 54 | template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; | |
| 55 | template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; | |
| 56 | ||
| 57 | // 23.6.8, comparison with T | |
| 58 | template <class T, class U> constexpr bool operator==(const optional<T>&, const U&); | |
| 59 | template <class T, class U> constexpr bool operator==(const T&, const optional<U>&); | |
| 60 | template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&); | |
| 61 | template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&); | |
| 62 | template <class T, class U> constexpr bool operator<(const optional<T>&, const U&); | |
| 63 | template <class T, class U> constexpr bool operator<(const T&, const optional<U>&); | |
| 64 | template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&); | |
| 65 | template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&); | |
| 66 | template <class T, class U> constexpr bool operator>(const optional<T>&, const U&); | |
| 67 | template <class T, class U> constexpr bool operator>(const T&, const optional<U>&); | |
| 68 | template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&); | |
| 69 | template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&); | |
| 70 | ||
| 71 | // 23.6.9, specialized algorithms | |
| 72 | template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 | |
| 73 | template <class T> constexpr optional<see below > make_optional(T&&); | |
| 74 | template <class T, class... Args> | |
| 47 | constexpr bool operator>=(const optional<T>&, const optional<U>&); | |
| 48 | template<class T, three_way_comparable_with<T> U> | |
| 49 | constexpr compare_three_way_result_t<T, U> | |
| 50 | operator<=>(const optional<T>&, const optional<U>&); // since C++20 | |
| 51 | ||
| 52 | // [optional.nullops], comparison with nullopt | |
| 53 | template<class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept; | |
| 54 | template<class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 55 | template<class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept; // until C++17 | |
| 56 | template<class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 57 | template<class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept; // until C++17 | |
| 58 | template<class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 59 | template<class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept; // until C++17 | |
| 60 | template<class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 61 | template<class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept; // until C++17 | |
| 62 | template<class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 63 | template<class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept; // until C++17 | |
| 64 | template<class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept; // until C++17 | |
| 65 | template<class T> | |
| 66 | constexpr strong_ordering operator<=>(const optional<T>&, nullopt_t) noexcept; // since C++20 | |
| 67 | ||
| 68 | // [optional.comp.with.t], comparison with T | |
| 69 | template<class T, class U> constexpr bool operator==(const optional<T>&, const U&); | |
| 70 | template<class T, class U> constexpr bool operator==(const T&, const optional<U>&); | |
| 71 | template<class T, class U> constexpr bool operator!=(const optional<T>&, const U&); | |
| 72 | template<class T, class U> constexpr bool operator!=(const T&, const optional<U>&); | |
| 73 | template<class T, class U> constexpr bool operator<(const optional<T>&, const U&); | |
| 74 | template<class T, class U> constexpr bool operator<(const T&, const optional<U>&); | |
| 75 | template<class T, class U> constexpr bool operator<=(const optional<T>&, const U&); | |
| 76 | template<class T, class U> constexpr bool operator<=(const T&, const optional<U>&); | |
| 77 | template<class T, class U> constexpr bool operator>(const optional<T>&, const U&); | |
| 78 | template<class T, class U> constexpr bool operator>(const T&, const optional<U>&); | |
| 79 | template<class T, class U> constexpr bool operator>=(const optional<T>&, const U&); | |
| 80 | template<class T, class U> constexpr bool operator>=(const T&, const optional<U>&); | |
| 81 | template<class T, class U> | |
| 82 | requires (!is-derived-from-optional<U>) && three_way_comparable_with<T, U> | |
| 83 | constexpr compare_three_way_result_t<T, U> | |
| 84 | operator<=>(const optional<T>&, const U&); // since C++20 | |
| 85 | ||
| 86 | // [optional.specalg], specialized algorithms | |
| 87 | template<class T> | |
| 88 | void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20 | |
| 89 | ||
| 90 | template<class T> | |
| 91 | constexpr optional<see below > make_optional(T&&); | |
| 92 | template<class T, class... Args> | |
| 75 | 93 | constexpr optional<T> make_optional(Args&&... args); |
| 76 | template <class T, class U, class... Args> | |
| 94 | template<class T, class U, class... Args> | |
| 77 | 95 | constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args); |
| 78 | 96 | |
| 79 | // 23.6.10, hash support | |
| 80 | template <class T> struct hash; | |
| 81 | template <class T> struct hash<optional<T>>; | |
| 97 | // [optional.hash], hash support | |
| 98 | template<class T> struct hash; | |
| 99 | template<class T> struct hash<optional<T>>; | |
| 82 | 100 | |
| 83 | template <class T> class optional { | |
| 101 | template<class T> | |
| 102 | class optional { | |
| 84 | 103 | public: |
| 85 | 104 | using value_type = T; |
| 86 | 105 | |
| 87 | // 23.6.3.1, constructors | |
| 106 | // [optional.ctor], constructors | |
| 88 | 107 | constexpr optional() noexcept; |
| 89 | 108 | constexpr optional(nullopt_t) noexcept; |
| 90 | 109 | constexpr optional(const optional &); |
| 91 | 110 | constexpr optional(optional &&) noexcept(see below); |
| 92 | template <class... Args> constexpr explicit optional(in_place_t, Args &&...); | |
| 93 | template <class U, class... Args> | |
| 111 | template<class... Args> | |
| 112 | constexpr explicit optional(in_place_t, Args &&...); | |
| 113 | template<class U, class... Args> | |
| 94 | 114 | constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...); |
| 95 | template <class U = T> | |
| 115 | template<class U = T> | |
| 96 | 116 | constexpr explicit(see-below) optional(U &&); |
| 97 | template <class U> | |
| 98 | explicit(see-below) optional(const optional<U> &); // constexpr in C++20 | |
| 99 | template <class U> | |
| 100 | explicit(see-below) optional(optional<U> &&); // constexpr in C++20 | |
| 117 | template<class U> | |
| 118 | explicit(see-below) optional(const optional<U> &); // constexpr in C++20 | |
| 119 | template<class U> | |
| 120 | explicit(see-below) optional(optional<U> &&); // constexpr in C++20 | |
| 101 | 121 | |
| 102 | // 23.6.3.2, destructor | |
| 122 | // [optional.dtor], destructor | |
| 103 | 123 | ~optional(); // constexpr in C++20 |
| 104 | 124 | |
| 105 | // 23.6.3.3, assignment | |
| 106 | optional &operator=(nullopt_t) noexcept; // constexpr in C++20 | |
| 125 | // [optional.assign], assignment | |
| 126 | optional &operator=(nullopt_t) noexcept; // constexpr in C++20 | |
| 107 | 127 | constexpr optional &operator=(const optional &); |
| 108 | 128 | constexpr optional &operator=(optional &&) noexcept(see below); |
| 109 | template <class U = T> optional &operator=(U &&); // constexpr in C++20 | |
| 110 | template <class U> optional &operator=(const optional<U> &); // constexpr in C++20 | |
| 111 | template <class U> optional &operator=(optional<U> &&); // constexpr in C++20 | |
| 112 | template <class... Args> T& emplace(Args &&...); // constexpr in C++20 | |
| 113 | template <class U, class... Args> | |
| 114 | T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 | |
| 115 | ||
| 116 | // 23.6.3.4, swap | |
| 129 | template<class U = T> optional &operator=(U &&); // constexpr in C++20 | |
| 130 | template<class U> optional &operator=(const optional<U> &); // constexpr in C++20 | |
| 131 | template<class U> optional &operator=(optional<U> &&); // constexpr in C++20 | |
| 132 | template<class... Args> T& emplace(Args &&...); // constexpr in C++20 | |
| 133 | template<class U, class... Args> T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20 | |
| 134 | ||
| 135 | // [optional.swap], swap | |
| 117 | 136 | void swap(optional &) noexcept(see below ); // constexpr in C++20 |
| 118 | 137 | |
| 119 | // 23.6.3.5, observers | |
| 138 | // [optional.observe], observers | |
| 120 | 139 | constexpr T const *operator->() const; |
| 121 | 140 | constexpr T *operator->(); |
| 122 | 141 | constexpr T const &operator*() const &; |
| ... | ... | @@ -129,8 +148,8 @@ namespace std { |
| 129 | 148 | constexpr T &value() &; |
| 130 | 149 | constexpr T &&value() &&; |
| 131 | 150 | constexpr const T &&value() const &&; |
| 132 | template <class U> constexpr T value_or(U &&) const &; | |
| 133 | template <class U> constexpr T value_or(U &&) &&; | |
| 151 | template<class U> constexpr T value_or(U &&) const &; | |
| 152 | template<class U> constexpr T value_or(U &&) &&; | |
| 134 | 153 | |
| 135 | 154 | // [optional.monadic], monadic operations |
| 136 | 155 | template<class F> constexpr auto and_then(F&& f) &; // since C++23 |
| ... | ... | @@ -144,15 +163,15 @@ namespace std { |
| 144 | 163 | template<class F> constexpr optional or_else(F&& f) &&; // since C++23 |
| 145 | 164 | template<class F> constexpr optional or_else(F&& f) const&; // since C++23 |
| 146 | 165 | |
| 147 | // 23.6.3.6, modifiers | |
| 148 | void reset() noexcept; // constexpr in C++20 | |
| 166 | // [optional.mod], modifiers | |
| 167 | void reset() noexcept; // constexpr in C++20 | |
| 149 | 168 | |
| 150 | 169 | private: |
| 151 | T *val; // exposition only | |
| 170 | T *val; // exposition only | |
| 152 | 171 | }; |
| 153 | 172 | |
| 154 | template<class T> | |
| 155 | optional(T) -> optional<T>; | |
| 173 | template<class T> | |
| 174 | optional(T) -> optional<T>; | |
| 156 | 175 | |
| 157 | 176 | } // namespace std |
| 158 | 177 | |
| ... | ... | @@ -160,21 +179,55 @@ template<class T> |
| 160 | 179 | |
| 161 | 180 | #include <__assert> // all public C++ headers provide the assertion handler |
| 162 | 181 | #include <__availability> |
| 182 | #include <__compare/compare_three_way_result.h> | |
| 183 | #include <__compare/three_way_comparable.h> | |
| 163 | 184 | #include <__concepts/invocable.h> |
| 164 | 185 | #include <__config> |
| 165 | 186 | #include <__functional/hash.h> |
| 166 | 187 | #include <__functional/invoke.h> |
| 188 | #include <__functional/reference_wrapper.h> | |
| 167 | 189 | #include <__functional/unary_function.h> |
| 190 | #include <__memory/addressof.h> | |
| 168 | 191 | #include <__memory/construct_at.h> |
| 169 | #include <__tuple_dir/sfinae_helpers.h> | |
| 192 | #include <__tuple/sfinae_helpers.h> | |
| 193 | #include <__type_traits/add_pointer.h> | |
| 194 | #include <__type_traits/conditional.h> | |
| 195 | #include <__type_traits/conjunction.h> | |
| 196 | #include <__type_traits/decay.h> | |
| 197 | #include <__type_traits/disjunction.h> | |
| 198 | #include <__type_traits/is_array.h> | |
| 199 | #include <__type_traits/is_assignable.h> | |
| 200 | #include <__type_traits/is_constructible.h> | |
| 201 | #include <__type_traits/is_convertible.h> | |
| 202 | #include <__type_traits/is_copy_assignable.h> | |
| 203 | #include <__type_traits/is_copy_constructible.h> | |
| 204 | #include <__type_traits/is_destructible.h> | |
| 205 | #include <__type_traits/is_move_assignable.h> | |
| 206 | #include <__type_traits/is_move_constructible.h> | |
| 207 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 208 | #include <__type_traits/is_nothrow_move_constructible.h> | |
| 209 | #include <__type_traits/is_object.h> | |
| 210 | #include <__type_traits/is_reference.h> | |
| 211 | #include <__type_traits/is_scalar.h> | |
| 212 | #include <__type_traits/is_swappable.h> | |
| 213 | #include <__type_traits/is_trivially_copy_assignable.h> | |
| 214 | #include <__type_traits/is_trivially_copy_constructible.h> | |
| 215 | #include <__type_traits/is_trivially_destructible.h> | |
| 216 | #include <__type_traits/is_trivially_move_assignable.h> | |
| 217 | #include <__type_traits/is_trivially_move_constructible.h> | |
| 218 | #include <__type_traits/negation.h> | |
| 219 | #include <__type_traits/remove_const.h> | |
| 220 | #include <__type_traits/remove_cvref.h> | |
| 221 | #include <__type_traits/remove_reference.h> | |
| 222 | #include <__utility/declval.h> | |
| 170 | 223 | #include <__utility/forward.h> |
| 171 | 224 | #include <__utility/in_place.h> |
| 172 | 225 | #include <__utility/move.h> |
| 173 | 226 | #include <__utility/swap.h> |
| 227 | #include <__verbose_abort> | |
| 174 | 228 | #include <initializer_list> |
| 175 | 229 | #include <new> |
| 176 | 230 | #include <stdexcept> |
| 177 | #include <type_traits> | |
| 178 | 231 | #include <version> |
| 179 | 232 | |
| 180 | 233 | // standard-mandated includes |
| ... | ... | @@ -186,10 +239,13 @@ template<class T> |
| 186 | 239 | # pragma GCC system_header |
| 187 | 240 | #endif |
| 188 | 241 | |
| 242 | _LIBCPP_PUSH_MACROS | |
| 243 | #include <__undef_macros> | |
| 244 | ||
| 189 | 245 | namespace std // purposefully not using versioning namespace |
| 190 | 246 | { |
| 191 | 247 | |
| 192 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access | |
| 248 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access | |
| 193 | 249 | : public exception |
| 194 | 250 | { |
| 195 | 251 | public: |
| ... | ... | @@ -200,7 +256,7 @@ public: |
| 200 | 256 | |
| 201 | 257 | } // namespace std |
| 202 | 258 | |
| 203 | #if _LIBCPP_STD_VER > 14 | |
| 259 | #if _LIBCPP_STD_VER >= 17 | |
| 204 | 260 | |
| 205 | 261 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 206 | 262 | |
| ... | ... | @@ -208,16 +264,16 @@ _LIBCPP_NORETURN |
| 208 | 264 | inline _LIBCPP_INLINE_VISIBILITY |
| 209 | 265 | _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS |
| 210 | 266 | void __throw_bad_optional_access() { |
| 211 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 267 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 212 | 268 | throw bad_optional_access(); |
| 213 | 269 | #else |
| 214 | _VSTD::abort(); | |
| 270 | _LIBCPP_VERBOSE_ABORT("bad_optional_access was thrown in -fno-exceptions mode"); | |
| 215 | 271 | #endif |
| 216 | 272 | } |
| 217 | 273 | |
| 218 | 274 | struct nullopt_t |
| 219 | 275 | { |
| 220 | struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; }; | |
| 276 | struct __secret_tag { explicit __secret_tag() = default; }; | |
| 221 | 277 | _LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {} |
| 222 | 278 | }; |
| 223 | 279 | |
| ... | ... | @@ -259,7 +315,7 @@ struct __optional_destruct_base<_Tp, false> |
| 259 | 315 | : __val_(_VSTD::forward<_Args>(__args)...), |
| 260 | 316 | __engaged_(true) {} |
| 261 | 317 | |
| 262 | #if _LIBCPP_STD_VER > 20 | |
| 318 | #if _LIBCPP_STD_VER >= 23 | |
| 263 | 319 | template <class _Fp, class... _Args> |
| 264 | 320 | _LIBCPP_HIDE_FROM_ABI |
| 265 | 321 | constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) |
| ... | ... | @@ -301,7 +357,7 @@ struct __optional_destruct_base<_Tp, true> |
| 301 | 357 | : __val_(_VSTD::forward<_Args>(__args)...), |
| 302 | 358 | __engaged_(true) {} |
| 303 | 359 | |
| 304 | #if _LIBCPP_STD_VER > 20 | |
| 360 | #if _LIBCPP_STD_VER >= 23 | |
| 305 | 361 | template <class _Fp, class... _Args> |
| 306 | 362 | _LIBCPP_HIDE_FROM_ABI |
| 307 | 363 | constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) |
| ... | ... | @@ -356,8 +412,8 @@ struct __optional_storage_base : __optional_destruct_base<_Tp> |
| 356 | 412 | _LIBCPP_INLINE_VISIBILITY |
| 357 | 413 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_Args&&... __args) |
| 358 | 414 | { |
| 359 | _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); | |
| 360 | #if _LIBCPP_STD_VER > 17 | |
| 415 | _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); | |
| 416 | #if _LIBCPP_STD_VER >= 20 | |
| 361 | 417 | _VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...); |
| 362 | 418 | #else |
| 363 | 419 | ::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...); |
| ... | ... | @@ -403,7 +459,7 @@ struct __optional_storage_base<_Tp, true> |
| 403 | 459 | __raw_type* __value_; |
| 404 | 460 | |
| 405 | 461 | template <class _Up> |
| 406 | static constexpr bool __can_bind_reference() { | |
| 462 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { | |
| 407 | 463 | using _RawUp = __libcpp_remove_reference_t<_Up>; |
| 408 | 464 | using _UpPtr = _RawUp*; |
| 409 | 465 | using _RawTp = __libcpp_remove_reference_t<_Tp>; |
| ... | ... | @@ -451,7 +507,7 @@ struct __optional_storage_base<_Tp, true> |
| 451 | 507 | _LIBCPP_INLINE_VISIBILITY |
| 452 | 508 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct(_UArg&& __val) |
| 453 | 509 | { |
| 454 | _LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage"); | |
| 510 | _LIBCPP_ASSERT_INTERNAL(!has_value(), "__construct called for engaged __optional_storage"); | |
| 455 | 511 | static_assert(__can_bind_reference<_UArg>(), |
| 456 | 512 | "Attempted to construct a reference element in tuple from a " |
| 457 | 513 | "possible temporary"); |
| ... | ... | @@ -623,12 +679,20 @@ using __optional_sfinae_assign_base_t = __sfinae_assign_base< |
| 623 | 679 | |
| 624 | 680 | template<class _Tp> |
| 625 | 681 | class optional; |
| 682 | ||
| 683 | #if _LIBCPP_STD_VER >= 20 | |
| 684 | ||
| 685 | template <class _Tp> | |
| 686 | concept __is_derived_from_optional = requires(const _Tp& __t) { []<class _Up>(const optional<_Up>&) {}(__t); }; | |
| 687 | ||
| 688 | # endif // _LIBCPP_STD_VER >= 20 | |
| 689 | ||
| 626 | 690 | template <class _Tp> |
| 627 | 691 | struct __is_std_optional : false_type {}; |
| 628 | 692 | template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {}; |
| 629 | 693 | |
| 630 | 694 | template <class _Tp> |
| 631 | class optional | |
| 695 | class _LIBCPP_DECLSPEC_EMPTY_BASES optional | |
| 632 | 696 | : private __optional_move_assign_base<_Tp> |
| 633 | 697 | , private __optional_sfinae_ctor_base_t<_Tp> |
| 634 | 698 | , private __optional_sfinae_assign_base_t<_Tp> |
| ... | ... | @@ -653,13 +717,13 @@ private: |
| 653 | 717 | // LWG2756: conditionally explicit conversion from _Up |
| 654 | 718 | struct _CheckOptionalArgsConstructor { |
| 655 | 719 | template <class _Up> |
| 656 | static constexpr bool __enable_implicit() { | |
| 720 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { | |
| 657 | 721 | return is_constructible_v<_Tp, _Up&&> && |
| 658 | 722 | is_convertible_v<_Up&&, _Tp>; |
| 659 | 723 | } |
| 660 | 724 | |
| 661 | 725 | template <class _Up> |
| 662 | static constexpr bool __enable_explicit() { | |
| 726 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { | |
| 663 | 727 | return is_constructible_v<_Tp, _Up&&> && |
| 664 | 728 | !is_convertible_v<_Up&&, _Tp>; |
| 665 | 729 | } |
| ... | ... | @@ -692,17 +756,17 @@ private: |
| 692 | 756 | is_assignable<_Tp&, _Opt const&&> |
| 693 | 757 | >; |
| 694 | 758 | template <class _Up, class _QUp = _QualUp> |
| 695 | static constexpr bool __enable_implicit() { | |
| 759 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_implicit() { | |
| 696 | 760 | return is_convertible<_QUp, _Tp>::value && |
| 697 | 761 | !__check_constructible_from_opt<_Up>::value; |
| 698 | 762 | } |
| 699 | 763 | template <class _Up, class _QUp = _QualUp> |
| 700 | static constexpr bool __enable_explicit() { | |
| 764 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_explicit() { | |
| 701 | 765 | return !is_convertible<_QUp, _Tp>::value && |
| 702 | 766 | !__check_constructible_from_opt<_Up>::value; |
| 703 | 767 | } |
| 704 | 768 | template <class _Up, class _QUp = _QualUp> |
| 705 | static constexpr bool __enable_assign() { | |
| 769 | _LIBCPP_HIDE_FROM_ABI static constexpr bool __enable_assign() { | |
| 706 | 770 | // Construction and assignability of _QUp to _Tp has already been |
| 707 | 771 | // checked. |
| 708 | 772 | return !__check_constructible_from_opt<_Up>::value && |
| ... | ... | @@ -805,7 +869,7 @@ public: |
| 805 | 869 | this->__construct_from(_VSTD::move(__v)); |
| 806 | 870 | } |
| 807 | 871 | |
| 808 | #if _LIBCPP_STD_VER > 20 | |
| 872 | #if _LIBCPP_STD_VER >= 23 | |
| 809 | 873 | template<class _Fp, class... _Args> |
| 810 | 874 | _LIBCPP_HIDE_FROM_ABI |
| 811 | 875 | constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args) |
| ... | ... | @@ -820,8 +884,8 @@ public: |
| 820 | 884 | return *this; |
| 821 | 885 | } |
| 822 | 886 | |
| 823 | constexpr optional& operator=(const optional&) = default; | |
| 824 | constexpr optional& operator=(optional&&) = default; | |
| 887 | _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(const optional&) = default; | |
| 888 | _LIBCPP_HIDE_FROM_ABI constexpr optional& operator=(optional&&) = default; | |
| 825 | 889 | |
| 826 | 890 | // LWG2756 |
| 827 | 891 | template <class _Up = value_type, |
| ... | ... | @@ -932,7 +996,7 @@ public: |
| 932 | 996 | add_pointer_t<value_type const> |
| 933 | 997 | operator->() const |
| 934 | 998 | { |
| 935 | _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); | |
| 999 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); | |
| 936 | 1000 | return _VSTD::addressof(this->__get()); |
| 937 | 1001 | } |
| 938 | 1002 | |
| ... | ... | @@ -941,7 +1005,7 @@ public: |
| 941 | 1005 | add_pointer_t<value_type> |
| 942 | 1006 | operator->() |
| 943 | 1007 | { |
| 944 | _LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value"); | |
| 1008 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator-> called on a disengaged value"); | |
| 945 | 1009 | return _VSTD::addressof(this->__get()); |
| 946 | 1010 | } |
| 947 | 1011 | |
| ... | ... | @@ -950,7 +1014,7 @@ public: |
| 950 | 1014 | const value_type& |
| 951 | 1015 | operator*() const& noexcept |
| 952 | 1016 | { |
| 953 | _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); | |
| 1017 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); | |
| 954 | 1018 | return this->__get(); |
| 955 | 1019 | } |
| 956 | 1020 | |
| ... | ... | @@ -959,7 +1023,7 @@ public: |
| 959 | 1023 | value_type& |
| 960 | 1024 | operator*() & noexcept |
| 961 | 1025 | { |
| 962 | _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); | |
| 1026 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); | |
| 963 | 1027 | return this->__get(); |
| 964 | 1028 | } |
| 965 | 1029 | |
| ... | ... | @@ -968,7 +1032,7 @@ public: |
| 968 | 1032 | value_type&& |
| 969 | 1033 | operator*() && noexcept |
| 970 | 1034 | { |
| 971 | _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); | |
| 1035 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); | |
| 972 | 1036 | return _VSTD::move(this->__get()); |
| 973 | 1037 | } |
| 974 | 1038 | |
| ... | ... | @@ -977,7 +1041,7 @@ public: |
| 977 | 1041 | const value_type&& |
| 978 | 1042 | operator*() const&& noexcept |
| 979 | 1043 | { |
| 980 | _LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value"); | |
| 1044 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(this->has_value(), "optional operator* called on a disengaged value"); | |
| 981 | 1045 | return _VSTD::move(this->__get()); |
| 982 | 1046 | } |
| 983 | 1047 | |
| ... | ... | @@ -1047,7 +1111,7 @@ public: |
| 1047 | 1111 | static_cast<value_type>(_VSTD::forward<_Up>(__v)); |
| 1048 | 1112 | } |
| 1049 | 1113 | |
| 1050 | #if _LIBCPP_STD_VER > 20 | |
| 1114 | #if _LIBCPP_STD_VER >= 23 | |
| 1051 | 1115 | template<class _Func> |
| 1052 | 1116 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS |
| 1053 | 1117 | constexpr auto and_then(_Func&& __f) & { |
| ... | ... | @@ -1171,7 +1235,7 @@ public: |
| 1171 | 1235 | return _VSTD::move(*this); |
| 1172 | 1236 | return _VSTD::forward<_Func>(__f)(); |
| 1173 | 1237 | } |
| 1174 | #endif // _LIBCPP_STD_VER > 20 | |
| 1238 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1175 | 1239 | |
| 1176 | 1240 | using __base::reset; |
| 1177 | 1241 | }; |
| ... | ... | @@ -1278,6 +1342,18 @@ operator>=(const optional<_Tp>& __x, const optional<_Up>& __y) |
| 1278 | 1342 | return *__x >= *__y; |
| 1279 | 1343 | } |
| 1280 | 1344 | |
| 1345 | #if _LIBCPP_STD_VER >= 20 | |
| 1346 | ||
| 1347 | template <class _Tp, three_way_comparable_with<_Tp> _Up> | |
| 1348 | _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> | |
| 1349 | operator<=>(const optional<_Tp>& __x, const optional<_Up>& __y) { | |
| 1350 | if (__x && __y) | |
| 1351 | return *__x <=> *__y; | |
| 1352 | return __x.has_value() <=> __y.has_value(); | |
| 1353 | } | |
| 1354 | ||
| 1355 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1356 | ||
| 1281 | 1357 | // Comparisons with nullopt |
| 1282 | 1358 | template <class _Tp> |
| 1283 | 1359 | _LIBCPP_INLINE_VISIBILITY constexpr |
| ... | ... | @@ -1287,6 +1363,8 @@ operator==(const optional<_Tp>& __x, nullopt_t) noexcept |
| 1287 | 1363 | return !static_cast<bool>(__x); |
| 1288 | 1364 | } |
| 1289 | 1365 | |
| 1366 | #if _LIBCPP_STD_VER <= 17 | |
| 1367 | ||
| 1290 | 1368 | template <class _Tp> |
| 1291 | 1369 | _LIBCPP_INLINE_VISIBILITY constexpr |
| 1292 | 1370 | bool |
| ... | ... | @@ -1375,6 +1453,15 @@ operator>=(nullopt_t, const optional<_Tp>& __x) noexcept |
| 1375 | 1453 | return !static_cast<bool>(__x); |
| 1376 | 1454 | } |
| 1377 | 1455 | |
| 1456 | #else // _LIBCPP_STD_VER <= 17 | |
| 1457 | ||
| 1458 | template <class _Tp> | |
| 1459 | _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const optional<_Tp>& __x, nullopt_t) noexcept { | |
| 1460 | return __x.has_value() <=> false; | |
| 1461 | } | |
| 1462 | ||
| 1463 | #endif // _LIBCPP_STD_VER <= 17 | |
| 1464 | ||
| 1378 | 1465 | // Comparisons with T |
| 1379 | 1466 | template <class _Tp, class _Up> |
| 1380 | 1467 | _LIBCPP_INLINE_VISIBILITY constexpr |
| ... | ... | @@ -1520,6 +1607,17 @@ operator>=(const _Tp& __v, const optional<_Up>& __x) |
| 1520 | 1607 | return static_cast<bool>(__x) ? __v >= *__x : true; |
| 1521 | 1608 | } |
| 1522 | 1609 | |
| 1610 | #if _LIBCPP_STD_VER >= 20 | |
| 1611 | ||
| 1612 | template <class _Tp, class _Up> | |
| 1613 | requires(!__is_derived_from_optional<_Up>) && three_way_comparable_with<_Tp, _Up> | |
| 1614 | _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Tp, _Up> | |
| 1615 | operator<=>(const optional<_Tp>& __x, const _Up& __v) { | |
| 1616 | return __x.has_value() ? *__x <=> __v : strong_ordering::less; | |
| 1617 | } | |
| 1618 | ||
| 1619 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1620 | ||
| 1523 | 1621 | |
| 1524 | 1622 | template <class _Tp> |
| 1525 | 1623 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1572,7 +1670,9 @@ struct _LIBCPP_TEMPLATE_VIS hash< |
| 1572 | 1670 | |
| 1573 | 1671 | _LIBCPP_END_NAMESPACE_STD |
| 1574 | 1672 | |
| 1575 | #endif // _LIBCPP_STD_VER > 14 | |
| 1673 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1674 | ||
| 1675 | _LIBCPP_POP_MACROS | |
| 1576 | 1676 | |
| 1577 | 1677 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1578 | 1678 | # include <atomic> |
| ... | ... | @@ -1583,6 +1683,7 @@ _LIBCPP_END_NAMESPACE_STD |
| 1583 | 1683 | # include <memory> |
| 1584 | 1684 | # include <ratio> |
| 1585 | 1685 | # include <tuple> |
| 1686 | # include <type_traits> | |
| 1586 | 1687 | # include <typeinfo> |
| 1587 | 1688 | # include <utility> |
| 1588 | 1689 | # include <variant> |
lib/libcxx/include/ostream+102-92| ... | ... | @@ -165,8 +165,16 @@ basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, cons |
| 165 | 165 | |
| 166 | 166 | #include <__assert> // all public C++ headers provide the assertion handler |
| 167 | 167 | #include <__config> |
| 168 | #include <__exception/operations.h> | |
| 169 | #include <__fwd/ostream.h> | |
| 168 | 170 | #include <__memory/shared_ptr.h> |
| 169 | 171 | #include <__memory/unique_ptr.h> |
| 172 | #include <__system_error/error_code.h> | |
| 173 | #include <__type_traits/conjunction.h> | |
| 174 | #include <__type_traits/enable_if.h> | |
| 175 | #include <__type_traits/is_base_of.h> | |
| 176 | #include <__type_traits/void_t.h> | |
| 177 | #include <__utility/declval.h> | |
| 170 | 178 | #include <bitset> |
| 171 | 179 | #include <ios> |
| 172 | 180 | #include <locale> |
| ... | ... | @@ -244,7 +252,7 @@ public: |
| 244 | 252 | basic_ostream& operator<<(long double __f); |
| 245 | 253 | basic_ostream& operator<<(const void* __p); |
| 246 | 254 | |
| 247 | #if _LIBCPP_STD_VER > 20 | |
| 255 | #if _LIBCPP_STD_VER >= 23 | |
| 248 | 256 | _LIBCPP_HIDE_FROM_ABI |
| 249 | 257 | basic_ostream& operator<<(const volatile void* __p) { |
| 250 | 258 | return operator<<(const_cast<const void*>(__p)); |
| ... | ... | @@ -253,7 +261,7 @@ public: |
| 253 | 261 | |
| 254 | 262 | basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb); |
| 255 | 263 | |
| 256 | #if _LIBCPP_STD_VER > 14 | |
| 264 | #if _LIBCPP_STD_VER >= 17 | |
| 257 | 265 | // LWG 2221 - nullptr. This is not backported to older standards modes. |
| 258 | 266 | // See https://reviews.llvm.org/D127033 for more info on the rationale. |
| 259 | 267 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -314,18 +322,18 @@ basic_ostream<_CharT, _Traits>::sentry::~sentry() |
| 314 | 322 | if (__os_.rdbuf() && __os_.good() && (__os_.flags() & ios_base::unitbuf) |
| 315 | 323 | && !uncaught_exception()) |
| 316 | 324 | { |
| 317 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 325 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 318 | 326 | try |
| 319 | 327 | { |
| 320 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 328 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 321 | 329 | if (__os_.rdbuf()->pubsync() == -1) |
| 322 | 330 | __os_.setstate(ios_base::badbit); |
| 323 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 331 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 324 | 332 | } |
| 325 | 333 | catch (...) |
| 326 | 334 | { |
| 327 | 335 | } |
| 328 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 336 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 329 | 337 | } |
| 330 | 338 | } |
| 331 | 339 | |
| ... | ... | @@ -352,19 +360,19 @@ template <class _CharT, class _Traits> |
| 352 | 360 | basic_ostream<_CharT, _Traits>& |
| 353 | 361 | basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_type>* __sb) |
| 354 | 362 | { |
| 355 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 363 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 356 | 364 | try |
| 357 | 365 | { |
| 358 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 366 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 359 | 367 | sentry __s(*this); |
| 360 | 368 | if (__s) |
| 361 | 369 | { |
| 362 | 370 | if (__sb) |
| 363 | 371 | { |
| 364 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 372 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 365 | 373 | try |
| 366 | 374 | { |
| 367 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 375 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 368 | 376 | typedef istreambuf_iterator<_CharT, _Traits> _Ip; |
| 369 | 377 | typedef ostreambuf_iterator<_CharT, _Traits> _Op; |
| 370 | 378 | _Ip __i(__sb); |
| ... | ... | @@ -379,24 +387,24 @@ basic_ostream<_CharT, _Traits>::operator<<(basic_streambuf<char_type, traits_typ |
| 379 | 387 | } |
| 380 | 388 | if (__c == 0) |
| 381 | 389 | this->setstate(ios_base::failbit); |
| 382 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 390 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 383 | 391 | } |
| 384 | 392 | catch (...) |
| 385 | 393 | { |
| 386 | 394 | this->__set_failbit_and_consider_rethrow(); |
| 387 | 395 | } |
| 388 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 396 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 389 | 397 | } |
| 390 | 398 | else |
| 391 | 399 | this->setstate(ios_base::badbit); |
| 392 | 400 | } |
| 393 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 401 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 394 | 402 | } |
| 395 | 403 | catch (...) |
| 396 | 404 | { |
| 397 | 405 | this->__set_badbit_and_consider_rethrow(); |
| 398 | 406 | } |
| 399 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 407 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 400 | 408 | return *this; |
| 401 | 409 | } |
| 402 | 410 | |
| ... | ... | @@ -404,10 +412,10 @@ template <class _CharT, class _Traits> |
| 404 | 412 | basic_ostream<_CharT, _Traits>& |
| 405 | 413 | basic_ostream<_CharT, _Traits>::operator<<(bool __n) |
| 406 | 414 | { |
| 407 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 415 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 408 | 416 | try |
| 409 | 417 | { |
| 410 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 418 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 411 | 419 | sentry __s(*this); |
| 412 | 420 | if (__s) |
| 413 | 421 | { |
| ... | ... | @@ -416,13 +424,13 @@ basic_ostream<_CharT, _Traits>::operator<<(bool __n) |
| 416 | 424 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 417 | 425 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 418 | 426 | } |
| 419 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 427 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 420 | 428 | } |
| 421 | 429 | catch (...) |
| 422 | 430 | { |
| 423 | 431 | this->__set_badbit_and_consider_rethrow(); |
| 424 | 432 | } |
| 425 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 433 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 426 | 434 | return *this; |
| 427 | 435 | } |
| 428 | 436 | |
| ... | ... | @@ -430,10 +438,10 @@ template <class _CharT, class _Traits> |
| 430 | 438 | basic_ostream<_CharT, _Traits>& |
| 431 | 439 | basic_ostream<_CharT, _Traits>::operator<<(short __n) |
| 432 | 440 | { |
| 433 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 441 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 434 | 442 | try |
| 435 | 443 | { |
| 436 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 444 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 437 | 445 | sentry __s(*this); |
| 438 | 446 | if (__s) |
| 439 | 447 | { |
| ... | ... | @@ -446,13 +454,13 @@ basic_ostream<_CharT, _Traits>::operator<<(short __n) |
| 446 | 454 | static_cast<long>(__n)).failed()) |
| 447 | 455 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 448 | 456 | } |
| 449 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 457 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 450 | 458 | } |
| 451 | 459 | catch (...) |
| 452 | 460 | { |
| 453 | 461 | this->__set_badbit_and_consider_rethrow(); |
| 454 | 462 | } |
| 455 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 463 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 456 | 464 | return *this; |
| 457 | 465 | } |
| 458 | 466 | |
| ... | ... | @@ -460,10 +468,10 @@ template <class _CharT, class _Traits> |
| 460 | 468 | basic_ostream<_CharT, _Traits>& |
| 461 | 469 | basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n) |
| 462 | 470 | { |
| 463 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 471 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 464 | 472 | try |
| 465 | 473 | { |
| 466 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 474 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 467 | 475 | sentry __s(*this); |
| 468 | 476 | if (__s) |
| 469 | 477 | { |
| ... | ... | @@ -472,13 +480,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned short __n) |
| 472 | 480 | if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed()) |
| 473 | 481 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 474 | 482 | } |
| 475 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 483 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 476 | 484 | } |
| 477 | 485 | catch (...) |
| 478 | 486 | { |
| 479 | 487 | this->__set_badbit_and_consider_rethrow(); |
| 480 | 488 | } |
| 481 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 489 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 482 | 490 | return *this; |
| 483 | 491 | } |
| 484 | 492 | |
| ... | ... | @@ -486,10 +494,10 @@ template <class _CharT, class _Traits> |
| 486 | 494 | basic_ostream<_CharT, _Traits>& |
| 487 | 495 | basic_ostream<_CharT, _Traits>::operator<<(int __n) |
| 488 | 496 | { |
| 489 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 497 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 490 | 498 | try |
| 491 | 499 | { |
| 492 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 500 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 493 | 501 | sentry __s(*this); |
| 494 | 502 | if (__s) |
| 495 | 503 | { |
| ... | ... | @@ -502,13 +510,13 @@ basic_ostream<_CharT, _Traits>::operator<<(int __n) |
| 502 | 510 | static_cast<long>(__n)).failed()) |
| 503 | 511 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 504 | 512 | } |
| 505 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 513 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 506 | 514 | } |
| 507 | 515 | catch (...) |
| 508 | 516 | { |
| 509 | 517 | this->__set_badbit_and_consider_rethrow(); |
| 510 | 518 | } |
| 511 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 519 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 512 | 520 | return *this; |
| 513 | 521 | } |
| 514 | 522 | |
| ... | ... | @@ -516,10 +524,10 @@ template <class _CharT, class _Traits> |
| 516 | 524 | basic_ostream<_CharT, _Traits>& |
| 517 | 525 | basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n) |
| 518 | 526 | { |
| 519 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 527 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 520 | 528 | try |
| 521 | 529 | { |
| 522 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 530 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 523 | 531 | sentry __s(*this); |
| 524 | 532 | if (__s) |
| 525 | 533 | { |
| ... | ... | @@ -528,13 +536,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned int __n) |
| 528 | 536 | if (__f.put(*this, *this, this->fill(), static_cast<unsigned long>(__n)).failed()) |
| 529 | 537 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 530 | 538 | } |
| 531 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 539 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 532 | 540 | } |
| 533 | 541 | catch (...) |
| 534 | 542 | { |
| 535 | 543 | this->__set_badbit_and_consider_rethrow(); |
| 536 | 544 | } |
| 537 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 545 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 538 | 546 | return *this; |
| 539 | 547 | } |
| 540 | 548 | |
| ... | ... | @@ -542,10 +550,10 @@ template <class _CharT, class _Traits> |
| 542 | 550 | basic_ostream<_CharT, _Traits>& |
| 543 | 551 | basic_ostream<_CharT, _Traits>::operator<<(long __n) |
| 544 | 552 | { |
| 545 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 553 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 546 | 554 | try |
| 547 | 555 | { |
| 548 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 556 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 549 | 557 | sentry __s(*this); |
| 550 | 558 | if (__s) |
| 551 | 559 | { |
| ... | ... | @@ -554,13 +562,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long __n) |
| 554 | 562 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 555 | 563 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 556 | 564 | } |
| 557 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 565 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 558 | 566 | } |
| 559 | 567 | catch (...) |
| 560 | 568 | { |
| 561 | 569 | this->__set_badbit_and_consider_rethrow(); |
| 562 | 570 | } |
| 563 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 571 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 564 | 572 | return *this; |
| 565 | 573 | } |
| 566 | 574 | |
| ... | ... | @@ -568,10 +576,10 @@ template <class _CharT, class _Traits> |
| 568 | 576 | basic_ostream<_CharT, _Traits>& |
| 569 | 577 | basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) |
| 570 | 578 | { |
| 571 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 579 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 572 | 580 | try |
| 573 | 581 | { |
| 574 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 582 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 575 | 583 | sentry __s(*this); |
| 576 | 584 | if (__s) |
| 577 | 585 | { |
| ... | ... | @@ -580,13 +588,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) |
| 580 | 588 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 581 | 589 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 582 | 590 | } |
| 583 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 591 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 584 | 592 | } |
| 585 | 593 | catch (...) |
| 586 | 594 | { |
| 587 | 595 | this->__set_badbit_and_consider_rethrow(); |
| 588 | 596 | } |
| 589 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 597 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 590 | 598 | return *this; |
| 591 | 599 | } |
| 592 | 600 | |
| ... | ... | @@ -594,10 +602,10 @@ template <class _CharT, class _Traits> |
| 594 | 602 | basic_ostream<_CharT, _Traits>& |
| 595 | 603 | basic_ostream<_CharT, _Traits>::operator<<(long long __n) |
| 596 | 604 | { |
| 597 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 605 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 598 | 606 | try |
| 599 | 607 | { |
| 600 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 608 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 601 | 609 | sentry __s(*this); |
| 602 | 610 | if (__s) |
| 603 | 611 | { |
| ... | ... | @@ -606,13 +614,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long long __n) |
| 606 | 614 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 607 | 615 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 608 | 616 | } |
| 609 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 617 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 610 | 618 | } |
| 611 | 619 | catch (...) |
| 612 | 620 | { |
| 613 | 621 | this->__set_badbit_and_consider_rethrow(); |
| 614 | 622 | } |
| 615 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 623 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 616 | 624 | return *this; |
| 617 | 625 | } |
| 618 | 626 | |
| ... | ... | @@ -620,10 +628,10 @@ template <class _CharT, class _Traits> |
| 620 | 628 | basic_ostream<_CharT, _Traits>& |
| 621 | 629 | basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) |
| 622 | 630 | { |
| 623 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 631 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 624 | 632 | try |
| 625 | 633 | { |
| 626 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 634 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 627 | 635 | sentry __s(*this); |
| 628 | 636 | if (__s) |
| 629 | 637 | { |
| ... | ... | @@ -632,13 +640,13 @@ basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) |
| 632 | 640 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 633 | 641 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 634 | 642 | } |
| 635 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 643 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 636 | 644 | } |
| 637 | 645 | catch (...) |
| 638 | 646 | { |
| 639 | 647 | this->__set_badbit_and_consider_rethrow(); |
| 640 | 648 | } |
| 641 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 649 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 642 | 650 | return *this; |
| 643 | 651 | } |
| 644 | 652 | |
| ... | ... | @@ -646,10 +654,10 @@ template <class _CharT, class _Traits> |
| 646 | 654 | basic_ostream<_CharT, _Traits>& |
| 647 | 655 | basic_ostream<_CharT, _Traits>::operator<<(float __n) |
| 648 | 656 | { |
| 649 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 657 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 650 | 658 | try |
| 651 | 659 | { |
| 652 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 660 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 653 | 661 | sentry __s(*this); |
| 654 | 662 | if (__s) |
| 655 | 663 | { |
| ... | ... | @@ -658,13 +666,13 @@ basic_ostream<_CharT, _Traits>::operator<<(float __n) |
| 658 | 666 | if (__f.put(*this, *this, this->fill(), static_cast<double>(__n)).failed()) |
| 659 | 667 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 660 | 668 | } |
| 661 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 669 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 662 | 670 | } |
| 663 | 671 | catch (...) |
| 664 | 672 | { |
| 665 | 673 | this->__set_badbit_and_consider_rethrow(); |
| 666 | 674 | } |
| 667 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 675 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 668 | 676 | return *this; |
| 669 | 677 | } |
| 670 | 678 | |
| ... | ... | @@ -672,10 +680,10 @@ template <class _CharT, class _Traits> |
| 672 | 680 | basic_ostream<_CharT, _Traits>& |
| 673 | 681 | basic_ostream<_CharT, _Traits>::operator<<(double __n) |
| 674 | 682 | { |
| 675 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 683 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 676 | 684 | try |
| 677 | 685 | { |
| 678 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 686 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 679 | 687 | sentry __s(*this); |
| 680 | 688 | if (__s) |
| 681 | 689 | { |
| ... | ... | @@ -684,13 +692,13 @@ basic_ostream<_CharT, _Traits>::operator<<(double __n) |
| 684 | 692 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 685 | 693 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 686 | 694 | } |
| 687 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 695 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 688 | 696 | } |
| 689 | 697 | catch (...) |
| 690 | 698 | { |
| 691 | 699 | this->__set_badbit_and_consider_rethrow(); |
| 692 | 700 | } |
| 693 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 701 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 694 | 702 | return *this; |
| 695 | 703 | } |
| 696 | 704 | |
| ... | ... | @@ -698,10 +706,10 @@ template <class _CharT, class _Traits> |
| 698 | 706 | basic_ostream<_CharT, _Traits>& |
| 699 | 707 | basic_ostream<_CharT, _Traits>::operator<<(long double __n) |
| 700 | 708 | { |
| 701 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 709 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 702 | 710 | try |
| 703 | 711 | { |
| 704 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 712 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 705 | 713 | sentry __s(*this); |
| 706 | 714 | if (__s) |
| 707 | 715 | { |
| ... | ... | @@ -710,13 +718,13 @@ basic_ostream<_CharT, _Traits>::operator<<(long double __n) |
| 710 | 718 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 711 | 719 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 712 | 720 | } |
| 713 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 721 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 714 | 722 | } |
| 715 | 723 | catch (...) |
| 716 | 724 | { |
| 717 | 725 | this->__set_badbit_and_consider_rethrow(); |
| 718 | 726 | } |
| 719 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 727 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 720 | 728 | return *this; |
| 721 | 729 | } |
| 722 | 730 | |
| ... | ... | @@ -724,10 +732,10 @@ template <class _CharT, class _Traits> |
| 724 | 732 | basic_ostream<_CharT, _Traits>& |
| 725 | 733 | basic_ostream<_CharT, _Traits>::operator<<(const void* __n) |
| 726 | 734 | { |
| 727 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 735 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 728 | 736 | try |
| 729 | 737 | { |
| 730 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 738 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 731 | 739 | sentry __s(*this); |
| 732 | 740 | if (__s) |
| 733 | 741 | { |
| ... | ... | @@ -736,13 +744,13 @@ basic_ostream<_CharT, _Traits>::operator<<(const void* __n) |
| 736 | 744 | if (__f.put(*this, *this, this->fill(), __n).failed()) |
| 737 | 745 | this->setstate(ios_base::badbit | ios_base::failbit); |
| 738 | 746 | } |
| 739 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 747 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 740 | 748 | } |
| 741 | 749 | catch (...) |
| 742 | 750 | { |
| 743 | 751 | this->__set_badbit_and_consider_rethrow(); |
| 744 | 752 | } |
| 745 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 753 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 746 | 754 | return *this; |
| 747 | 755 | } |
| 748 | 756 | |
| ... | ... | @@ -751,10 +759,10 @@ _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 751 | 759 | __put_character_sequence(basic_ostream<_CharT, _Traits>& __os, |
| 752 | 760 | const _CharT* __str, size_t __len) |
| 753 | 761 | { |
| 754 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 762 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 755 | 763 | try |
| 756 | 764 | { |
| 757 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 765 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 758 | 766 | typename basic_ostream<_CharT, _Traits>::sentry __s(__os); |
| 759 | 767 | if (__s) |
| 760 | 768 | { |
| ... | ... | @@ -769,13 +777,13 @@ __put_character_sequence(basic_ostream<_CharT, _Traits>& __os, |
| 769 | 777 | __os.fill()).failed()) |
| 770 | 778 | __os.setstate(ios_base::badbit | ios_base::failbit); |
| 771 | 779 | } |
| 772 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 780 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 773 | 781 | } |
| 774 | 782 | catch (...) |
| 775 | 783 | { |
| 776 | 784 | __os.__set_badbit_and_consider_rethrow(); |
| 777 | 785 | } |
| 778 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 786 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 779 | 787 | return __os; |
| 780 | 788 | } |
| 781 | 789 | |
| ... | ... | @@ -791,10 +799,10 @@ template<class _CharT, class _Traits> |
| 791 | 799 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 792 | 800 | operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn) |
| 793 | 801 | { |
| 794 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 802 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 795 | 803 | try |
| 796 | 804 | { |
| 797 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 805 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 798 | 806 | typename basic_ostream<_CharT, _Traits>::sentry __s(__os); |
| 799 | 807 | if (__s) |
| 800 | 808 | { |
| ... | ... | @@ -810,13 +818,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, char __cn) |
| 810 | 818 | __os.fill()).failed()) |
| 811 | 819 | __os.setstate(ios_base::badbit | ios_base::failbit); |
| 812 | 820 | } |
| 813 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 821 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 814 | 822 | } |
| 815 | 823 | catch (...) |
| 816 | 824 | { |
| 817 | 825 | __os.__set_badbit_and_consider_rethrow(); |
| 818 | 826 | } |
| 819 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 827 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 820 | 828 | return __os; |
| 821 | 829 | } |
| 822 | 830 | |
| ... | ... | @@ -852,10 +860,10 @@ template<class _CharT, class _Traits> |
| 852 | 860 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| 853 | 861 | operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn) |
| 854 | 862 | { |
| 855 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 863 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 856 | 864 | try |
| 857 | 865 | { |
| 858 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 866 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 859 | 867 | typename basic_ostream<_CharT, _Traits>::sentry __s(__os); |
| 860 | 868 | if (__s) |
| 861 | 869 | { |
| ... | ... | @@ -884,13 +892,13 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const char* __strn) |
| 884 | 892 | __os.fill()).failed()) |
| 885 | 893 | __os.setstate(ios_base::badbit | ios_base::failbit); |
| 886 | 894 | } |
| 887 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 895 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 888 | 896 | } |
| 889 | 897 | catch (...) |
| 890 | 898 | { |
| 891 | 899 | __os.__set_badbit_and_consider_rethrow(); |
| 892 | 900 | } |
| 893 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 901 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 894 | 902 | return __os; |
| 895 | 903 | } |
| 896 | 904 | |
| ... | ... | @@ -921,10 +929,10 @@ template <class _CharT, class _Traits> |
| 921 | 929 | basic_ostream<_CharT, _Traits>& |
| 922 | 930 | basic_ostream<_CharT, _Traits>::put(char_type __c) |
| 923 | 931 | { |
| 924 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 932 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 925 | 933 | try |
| 926 | 934 | { |
| 927 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 935 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 928 | 936 | sentry __s(*this); |
| 929 | 937 | if (__s) |
| 930 | 938 | { |
| ... | ... | @@ -934,13 +942,13 @@ basic_ostream<_CharT, _Traits>::put(char_type __c) |
| 934 | 942 | if (__o.failed()) |
| 935 | 943 | this->setstate(ios_base::badbit); |
| 936 | 944 | } |
| 937 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 945 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 938 | 946 | } |
| 939 | 947 | catch (...) |
| 940 | 948 | { |
| 941 | 949 | this->__set_badbit_and_consider_rethrow(); |
| 942 | 950 | } |
| 943 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 951 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 944 | 952 | return *this; |
| 945 | 953 | } |
| 946 | 954 | |
| ... | ... | @@ -948,23 +956,23 @@ template <class _CharT, class _Traits> |
| 948 | 956 | basic_ostream<_CharT, _Traits>& |
| 949 | 957 | basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) |
| 950 | 958 | { |
| 951 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 959 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 952 | 960 | try |
| 953 | 961 | { |
| 954 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 962 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 955 | 963 | sentry __sen(*this); |
| 956 | 964 | if (__sen && __n) |
| 957 | 965 | { |
| 958 | 966 | if (this->rdbuf()->sputn(__s, __n) != __n) |
| 959 | 967 | this->setstate(ios_base::badbit); |
| 960 | 968 | } |
| 961 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 969 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 962 | 970 | } |
| 963 | 971 | catch (...) |
| 964 | 972 | { |
| 965 | 973 | this->__set_badbit_and_consider_rethrow(); |
| 966 | 974 | } |
| 967 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 975 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 968 | 976 | return *this; |
| 969 | 977 | } |
| 970 | 978 | |
| ... | ... | @@ -972,10 +980,10 @@ template <class _CharT, class _Traits> |
| 972 | 980 | basic_ostream<_CharT, _Traits>& |
| 973 | 981 | basic_ostream<_CharT, _Traits>::flush() |
| 974 | 982 | { |
| 975 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 983 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 976 | 984 | try |
| 977 | 985 | { |
| 978 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 986 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 979 | 987 | if (this->rdbuf()) |
| 980 | 988 | { |
| 981 | 989 | sentry __s(*this); |
| ... | ... | @@ -985,13 +993,13 @@ basic_ostream<_CharT, _Traits>::flush() |
| 985 | 993 | this->setstate(ios_base::badbit); |
| 986 | 994 | } |
| 987 | 995 | } |
| 988 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 996 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 989 | 997 | } |
| 990 | 998 | catch (...) |
| 991 | 999 | { |
| 992 | 1000 | this->__set_badbit_and_consider_rethrow(); |
| 993 | 1001 | } |
| 994 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1002 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 995 | 1003 | return *this; |
| 996 | 1004 | } |
| 997 | 1005 | |
| ... | ... | @@ -1130,7 +1138,7 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x) |
| 1130 | 1138 | std::use_facet<ctype<_CharT> >(__os.getloc()).widen('1')); |
| 1131 | 1139 | } |
| 1132 | 1140 | |
| 1133 | #if _LIBCPP_STD_VER > 17 | |
| 1141 | #if _LIBCPP_STD_VER >= 20 | |
| 1134 | 1142 | |
| 1135 | 1143 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 1136 | 1144 | template <class _Traits> |
| ... | ... | @@ -1179,7 +1187,7 @@ basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const ch |
| 1179 | 1187 | template <class _Traits> |
| 1180 | 1188 | basic_ostream<char, _Traits>& operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete; |
| 1181 | 1189 | |
| 1182 | #endif // _LIBCPP_STD_VER > 17 | |
| 1190 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1183 | 1191 | |
| 1184 | 1192 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>; |
| 1185 | 1193 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -1189,7 +1197,9 @@ extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>; |
| 1189 | 1197 | _LIBCPP_END_NAMESPACE_STD |
| 1190 | 1198 | |
| 1191 | 1199 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1200 | # include <atomic> | |
| 1192 | 1201 | # include <concepts> |
| 1202 | # include <cstdlib> | |
| 1193 | 1203 | # include <iterator> |
| 1194 | 1204 | # include <type_traits> |
| 1195 | 1205 | #endif |
lib/libcxx/include/print created+389| ... | ... | @@ -0,0 +1,389 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_PRINT | |
| 11 | #define _LIBCPP_PRINT | |
| 12 | ||
| 13 | /* | |
| 14 | namespace std { | |
| 15 | // [print.fun], print functions | |
| 16 | template<class... Args> | |
| 17 | void print(format_string<Args...> fmt, Args&&... args); | |
| 18 | template<class... Args> | |
| 19 | void print(FILE* stream, format_string<Args...> fmt, Args&&... args); | |
| 20 | ||
| 21 | template<class... Args> | |
| 22 | void println(format_string<Args...> fmt, Args&&... args); | |
| 23 | template<class... Args> | |
| 24 | void println(FILE* stream, format_string<Args...> fmt, Args&&... args); | |
| 25 | ||
| 26 | void vprint_unicode(string_view fmt, format_args args); | |
| 27 | void vprint_unicode(FILE* stream, string_view fmt, format_args args); | |
| 28 | ||
| 29 | void vprint_nonunicode(string_view fmt, format_args args); | |
| 30 | void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); | |
| 31 | } | |
| 32 | */ | |
| 33 | ||
| 34 | #include <__assert> // all public C++ headers provide the assertion handler | |
| 35 | #include <__concepts/same_as.h> | |
| 36 | #include <__config> | |
| 37 | #include <__format/buffer.h> | |
| 38 | #include <__format/format_arg_store.h> | |
| 39 | #include <__format/format_args.h> | |
| 40 | #include <__format/format_context.h> | |
| 41 | #include <__format/format_error.h> | |
| 42 | #include <__format/format_functions.h> | |
| 43 | #include <__format/unicode.h> | |
| 44 | #include <__system_error/system_error.h> | |
| 45 | #include <__utility/forward.h> | |
| 46 | #include <cerrno> | |
| 47 | #include <cstdio> | |
| 48 | #include <string> | |
| 49 | #include <string_view> | |
| 50 | #include <version> | |
| 51 | ||
| 52 | #if __has_include(<unistd.h>) | |
| 53 | # include <unistd.h> | |
| 54 | #endif | |
| 55 | ||
| 56 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 57 | # pragma GCC system_header | |
| 58 | #endif | |
| 59 | ||
| 60 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 61 | ||
| 62 | #ifdef _WIN32 | |
| 63 | _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream); | |
| 64 | ||
| 65 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 66 | // A wrapper for WriteConsoleW which is used to write to the Windows | |
| 67 | // console. This function is in the dylib to avoid pulling in windows.h | |
| 68 | // in the library headers. The function itself uses some private parts | |
| 69 | // of the dylib too. | |
| 70 | // | |
| 71 | // The function does not depend on the language standard used. Guarding | |
| 72 | // it with C++23 would fail since the dylib is currently built using C++20. | |
| 73 | // | |
| 74 | // Note the function is only implemented on the Windows platform. | |
| 75 | _LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view); | |
| 76 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 77 | ||
| 78 | #endif // _WIN32 | |
| 79 | ||
| 80 | #if _LIBCPP_STD_VER >= 23 | |
| 81 | ||
| 82 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 83 | // This is the code to transcode UTF-8 to UTF-16. This is used on | |
| 84 | // Windows for the native Unicode API. The code is modeled to make it | |
| 85 | // easier to extend to | |
| 86 | // | |
| 87 | // P2728R0 Unicode in the Library, Part 1: UTF Transcoding | |
| 88 | // | |
| 89 | // This paper is still under heavy development so it makes no sense yet | |
| 90 | // to strictly follow the paper. | |
| 91 | namespace __unicode { | |
| 92 | ||
| 93 | // The names of these concepts are modelled after P2728R0, but the | |
| 94 | // implementation is not. char16_t may contain 32-bits so depending on the | |
| 95 | // number of bits is an issue. | |
| 96 | # ifdef _LIBCPP_SHORT_WCHAR | |
| 97 | template <class _Tp> | |
| 98 | concept __utf16_code_unit = | |
| 99 | same_as<_Tp, char16_t> | |
| 100 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 101 | || same_as<_Tp, wchar_t> | |
| 102 | # endif | |
| 103 | ; | |
| 104 | template <class _Tp> | |
| 105 | concept __utf32_code_unit = same_as<_Tp, char32_t>; | |
| 106 | # else // _LIBCPP_SHORT_WCHAR | |
| 107 | template <class _Tp> | |
| 108 | concept __utf16_code_unit = same_as<_Tp, char16_t>; | |
| 109 | template <class _Tp> | |
| 110 | concept __utf32_code_unit = | |
| 111 | same_as<_Tp, char32_t> | |
| 112 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 113 | || same_as<_Tp, wchar_t> | |
| 114 | # endif | |
| 115 | ; | |
| 116 | # endif // _LIBCPP_SHORT_WCHAR | |
| 117 | ||
| 118 | // Pass by reference since an output_iterator may not be copyable. | |
| 119 | template <class _OutIt> | |
| 120 | _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete; | |
| 121 | ||
| 122 | template <class _OutIt> | |
| 123 | requires __utf16_code_unit<iter_value_t<_OutIt>> | |
| 124 | _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { | |
| 125 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16"); | |
| 126 | ||
| 127 | if (__value < 0x10000) { | |
| 128 | *__out_it++ = __value; | |
| 129 | return; | |
| 130 | } | |
| 131 | ||
| 132 | __value -= 0x10000; | |
| 133 | *__out_it++ = 0xd800 + (__value >> 10); | |
| 134 | *__out_it++ = 0xdc00 + (__value & 0x3FF); | |
| 135 | } | |
| 136 | ||
| 137 | template <class _OutIt> | |
| 138 | requires __utf32_code_unit<iter_value_t<_OutIt>> | |
| 139 | _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { | |
| 140 | _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32"); | |
| 141 | *__out_it++ = __value; | |
| 142 | } | |
| 143 | ||
| 144 | template <class _OutIt, input_iterator _InIt> | |
| 145 | requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>) | |
| 146 | _LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) { | |
| 147 | // The __code_point_view has a basic_string_view interface. | |
| 148 | // When transcoding becomes part of the standard we probably want to | |
| 149 | // look at smarter algorithms. | |
| 150 | // For example, when processing a code point that is encoded in | |
| 151 | // 1 to 3 code units in UTF-8, the result will always be encoded | |
| 152 | // in 1 code unit in UTF-16 (code points that require 4 code | |
| 153 | // units in UTF-8 will require 2 code units in UTF-16). | |
| 154 | // | |
| 155 | // Note if P2728 is accepted types like int may become valid. In that case | |
| 156 | // the __code_point_view should use a span. Libc++ will remove support for | |
| 157 | // char_traits<int>. | |
| 158 | ||
| 159 | // TODO PRINT Validate with clang-tidy | |
| 160 | // NOLINTNEXTLINE(bugprone-dangling-handle) | |
| 161 | basic_string_view<iter_value_t<_InIt>> __data{__first, __last}; | |
| 162 | __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()}; | |
| 163 | while (!__view.__at_end()) | |
| 164 | __unicode::__encode(__out_it, __view.__consume().__code_point); | |
| 165 | return __out_it; | |
| 166 | } | |
| 167 | ||
| 168 | } // namespace __unicode | |
| 169 | ||
| 170 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 171 | ||
| 172 | namespace __print { | |
| 173 | ||
| 174 | // [print.fun]/2 | |
| 175 | // Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to: | |
| 176 | // vprint_unicode(stream, fmt.str, make_format_args(args...)); | |
| 177 | // Otherwise, equivalent to: | |
| 178 | // vprint_nonunicode(stream, fmt.str, make_format_args(args...)); | |
| 179 | // | |
| 180 | // Based on the compiler and its compilation flags this value is or is | |
| 181 | // not true. As mentioned in P2093R14 this only affects Windows. The | |
| 182 | // test below could also be done for | |
| 183 | // - GCC using __GNUC_EXECUTION_CHARSET_NAME | |
| 184 | // https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html | |
| 185 | // - Clang using __clang_literal_encoding__ | |
| 186 | // https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros | |
| 187 | // (note at the time of writing Clang is hard-coded to UTF-8.) | |
| 188 | // | |
| 189 | ||
| 190 | # ifdef _LIBCPP_HAS_NO_UNICODE | |
| 191 | inline constexpr bool __use_unicode = false; | |
| 192 | # elif defined(_MSVC_EXECUTION_CHARACTER_SET) | |
| 193 | // This is the same test MSVC STL uses in their implementation of <print> | |
| 194 | // See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers | |
| 195 | inline constexpr bool __use_unicode = _MSVC_EXECUTION_CHARACTER_SET == 65001; | |
| 196 | # else | |
| 197 | inline constexpr bool __use_unicode = true; | |
| 198 | # endif | |
| 199 | ||
| 200 | _LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) { | |
| 201 | # ifdef _WIN32 | |
| 202 | return std::__is_windows_terminal(__stream); | |
| 203 | # elif __has_include(<unistd.h>) | |
| 204 | return isatty(fileno(__stream)); | |
| 205 | # else | |
| 206 | # error "Provide a way to determine whether a FILE* is a terminal" | |
| 207 | # endif | |
| 208 | } | |
| 209 | ||
| 210 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 211 | _LIBCPP_HIDE_FROM_ABI inline void | |
| 212 | __vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) { | |
| 213 | _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream"); | |
| 214 | string __str = std::vformat(__fmt, __args); | |
| 215 | if (__write_nl) | |
| 216 | __str.push_back('\n'); | |
| 217 | ||
| 218 | size_t __size = fwrite(__str.data(), 1, __str.size(), __stream); | |
| 219 | if (__size < __str.size()) { | |
| 220 | if (std::feof(__stream)) | |
| 221 | std::__throw_system_error(EIO, "EOF while writing the formatted output"); | |
| 222 | std::__throw_system_error(std::ferror(__stream), "failed to write formatted output"); | |
| 223 | } | |
| 224 | } | |
| 225 | ||
| 226 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 227 | ||
| 228 | // Note these helper functions are mainly used to aid testing. | |
| 229 | // On POSIX systems and Windows the output is no longer considered a | |
| 230 | // terminal when the output is redirected. Typically during testing the | |
| 231 | // output is redirected to be able to capture it. This makes it hard to | |
| 232 | // test this code path. | |
| 233 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 234 | _LIBCPP_HIDE_FROM_ABI inline void | |
| 235 | __vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { | |
| 236 | // TODO PRINT Should flush errors throw too? | |
| 237 | if (__is_terminal) | |
| 238 | std::fflush(__stream); | |
| 239 | ||
| 240 | __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); | |
| 241 | } | |
| 242 | ||
| 243 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 244 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 245 | _LIBCPP_HIDE_FROM_ABI inline void | |
| 246 | __vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { | |
| 247 | if (!__is_terminal) | |
| 248 | return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); | |
| 249 | ||
| 250 | // TODO PRINT Should flush errors throw too? | |
| 251 | std::fflush(__stream); | |
| 252 | ||
| 253 | string __str = std::vformat(__fmt, __args); | |
| 254 | // UTF-16 uses the same number or less code units than UTF-8. | |
| 255 | // However the size of the code unit is 16 bits instead of 8 bits. | |
| 256 | // | |
| 257 | // The buffer uses the worst-case estimate and should never resize. | |
| 258 | // However when the string is large this could lead to OOM. Using a | |
| 259 | // smaller size might work, but since the buffer uses a grow factor | |
| 260 | // the final size might be larger when the estimate is wrong. | |
| 261 | // | |
| 262 | // TODO PRINT profile and improve the speed of this code. | |
| 263 | __format::__retarget_buffer<wchar_t> __buffer{__str.size()}; | |
| 264 | __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator()); | |
| 265 | if (__write_nl) | |
| 266 | __buffer.push_back(L'\n'); | |
| 267 | ||
| 268 | [[maybe_unused]] wstring_view __view = __buffer.__view(); | |
| 269 | ||
| 270 | // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change | |
| 271 | // the behavior in the test. This is not part of the public API. | |
| 272 | # ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION | |
| 273 | _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view); | |
| 274 | # elif defined(_WIN32) | |
| 275 | std::__write_to_windows_console(__stream, __view); | |
| 276 | # else | |
| 277 | std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and " | |
| 278 | "__write_to_windows_console is not available."); | |
| 279 | # endif | |
| 280 | } | |
| 281 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 282 | ||
| 283 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 284 | _LIBCPP_HIDE_FROM_ABI inline void | |
| 285 | __vprint_unicode([[maybe_unused]] FILE* __stream, | |
| 286 | [[maybe_unused]] string_view __fmt, | |
| 287 | [[maybe_unused]] format_args __args, | |
| 288 | [[maybe_unused]] bool __write_nl) { | |
| 289 | _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream"); | |
| 290 | ||
| 291 | // [print.fun] | |
| 292 | // 7 - Effects: If stream refers to a terminal capable of displaying | |
| 293 | // Unicode, writes out to the terminal using the native Unicode | |
| 294 | // API; if out contains invalid code units, the behavior is | |
| 295 | // undefined and implementations are encouraged to diagnose it. | |
| 296 | // Otherwise writes out to stream unchanged. If the native | |
| 297 | // Unicode API is used, the function flushes stream before | |
| 298 | // writing out. | |
| 299 | // 8 - Throws: Any exception thrown by the call to vformat | |
| 300 | // ([format.err.report]). system_error if writing to the terminal | |
| 301 | // or stream fails. May throw bad_alloc. | |
| 302 | // 9 - Recommended practice: If invoking the native Unicode API | |
| 303 | // requires transcoding, implementations should substitute | |
| 304 | // invalid code units with U+FFFD replacement character per the | |
| 305 | // Unicode Standard, Chapter 3.9 U+FFFD Substitution in | |
| 306 | // Conversion. | |
| 307 | ||
| 308 | // On non-Windows platforms the Unicode API is the normal file I/O API | |
| 309 | // so there the call can be forwarded to the non_unicode API. On | |
| 310 | // Windows there is a different API. This API requires transcoding. | |
| 311 | ||
| 312 | # ifndef _WIN32 | |
| 313 | __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); | |
| 314 | # elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) | |
| 315 | __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); | |
| 316 | # else | |
| 317 | # error "Windows builds with wchar_t disabled are not supported." | |
| 318 | # endif | |
| 319 | } | |
| 320 | ||
| 321 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 322 | ||
| 323 | } // namespace __print | |
| 324 | ||
| 325 | template <class... _Args> | |
| 326 | _LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { | |
| 327 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 328 | if constexpr (__print::__use_unicode) | |
| 329 | __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false); | |
| 330 | else | |
| 331 | __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); | |
| 332 | # else // _LIBCPP_HAS_NO_UNICODE | |
| 333 | __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); | |
| 334 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 335 | } | |
| 336 | ||
| 337 | template <class... _Args> | |
| 338 | _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) { | |
| 339 | std::print(stdout, __fmt, std::forward<_Args>(__args)...); | |
| 340 | } | |
| 341 | ||
| 342 | template <class... _Args> | |
| 343 | _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { | |
| 344 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 345 | // Note the wording in the Standard is inefficient. The output of | |
| 346 | // std::format is a std::string which is then copied. This solution | |
| 347 | // just appends a newline at the end of the output. | |
| 348 | if constexpr (__print::__use_unicode) | |
| 349 | __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true); | |
| 350 | else | |
| 351 | __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); | |
| 352 | # else // _LIBCPP_HAS_NO_UNICODE | |
| 353 | __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); | |
| 354 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 355 | } | |
| 356 | ||
| 357 | template <class... _Args> | |
| 358 | _LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) { | |
| 359 | std::println(stdout, __fmt, std::forward<_Args>(__args)...); | |
| 360 | } | |
| 361 | ||
| 362 | # ifndef _LIBCPP_HAS_NO_UNICODE | |
| 363 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 364 | _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) { | |
| 365 | __print::__vprint_unicode(__stream, __fmt, __args, false); | |
| 366 | } | |
| 367 | ||
| 368 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 369 | _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) { | |
| 370 | std::vprint_unicode(stdout, __fmt, __args); | |
| 371 | } | |
| 372 | ||
| 373 | # endif // _LIBCPP_HAS_NO_UNICODE | |
| 374 | ||
| 375 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 376 | _LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) { | |
| 377 | __print::__vprint_nonunicode(__stream, __fmt, __args, false); | |
| 378 | } | |
| 379 | ||
| 380 | template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). | |
| 381 | _LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) { | |
| 382 | std::vprint_nonunicode(stdout, __fmt, __args); | |
| 383 | } | |
| 384 | ||
| 385 | #endif // _LIBCPP_STD_VER >= 23 | |
| 386 | ||
| 387 | _LIBCPP_END_NAMESPACE_STD | |
| 388 | ||
| 389 | #endif // _LIBCPP_PRINT |
lib/libcxx/include/queue+193-24| ... | ... | @@ -43,6 +43,7 @@ public: |
| 43 | 43 | explicit queue(container_type&& c) |
| 44 | 44 | template<class InputIterator> |
| 45 | 45 | queue(InputIterator first, InputIterator last); // since C++23 |
| 46 | template<container-compatible-range<T> R> queue(from_range_t, R&& rg); // since C++23 | |
| 46 | 47 | template <class Alloc> |
| 47 | 48 | explicit queue(const Alloc& a); |
| 48 | 49 | template <class Alloc> |
| ... | ... | @@ -55,6 +56,8 @@ public: |
| 55 | 56 | queue(queue&& q, const Alloc& a); |
| 56 | 57 | template <class InputIterator, class Alloc> |
| 57 | 58 | queue(InputIterator first, InputIterator last, const Alloc&); // since C++23 |
| 59 | template<container-compatible-range<T> R, class Alloc> | |
| 60 | queue(from_range_t, R&& rg, const Alloc&); // since C++23 | |
| 58 | 61 | |
| 59 | 62 | bool empty() const; |
| 60 | 63 | size_type size() const; |
| ... | ... | @@ -66,6 +69,8 @@ public: |
| 66 | 69 | |
| 67 | 70 | void push(const value_type& v); |
| 68 | 71 | void push(value_type&& v); |
| 72 | template<container-compatible-range<T> R> | |
| 73 | void push_range(R&& rg); // C++23 | |
| 69 | 74 | template <class... Args> reference emplace(Args&&... args); // reference in C++17 |
| 70 | 75 | void pop(); |
| 71 | 76 | |
| ... | ... | @@ -78,6 +83,9 @@ template<class Container> |
| 78 | 83 | template<class InputIterator> |
| 79 | 84 | queue(InputIterator, InputIterator) -> queue<iter-value-type<InputIterator>>; // since C++23 |
| 80 | 85 | |
| 86 | template<ranges::input_range R> | |
| 87 | queue(from_range_t, R&&) -> queue<ranges::range_value_t<R>>; // since C++23 | |
| 88 | ||
| 81 | 89 | template<class Container, class Allocator> |
| 82 | 90 | queue(Container, Allocator) -> queue<typename Container::value_type, Container>; // C++17 |
| 83 | 91 | |
| ... | ... | @@ -86,6 +94,10 @@ template<class InputIterator, class Allocator> |
| 86 | 94 | -> queue<iter-value-type<InputIterator>, |
| 87 | 95 | deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 |
| 88 | 96 | |
| 97 | template<ranges::input_range R, class Allocator> | |
| 98 | queue(from_range_t, R&&, Allocator) | |
| 99 | -> queue<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23 | |
| 100 | ||
| 89 | 101 | template <class T, class Container> |
| 90 | 102 | bool operator==(const queue<T, Container>& x,const queue<T, Container>& y); |
| 91 | 103 | |
| ... | ... | @@ -104,6 +116,10 @@ template <class T, class Container> |
| 104 | 116 | template <class T, class Container> |
| 105 | 117 | bool operator<=(const queue<T, Container>& x,const queue<T, Container>& y); |
| 106 | 118 | |
| 119 | template<class T, three_way_comparable Container> | |
| 120 | compare_three_way_result_t<Container> | |
| 121 | operator<=>(const queue<T, Container>& x, const queue<T, Container>& y); // since C++20 | |
| 122 | ||
| 107 | 123 | template <class T, class Container> |
| 108 | 124 | void swap(queue<T, Container>& x, queue<T, Container>& y) |
| 109 | 125 | noexcept(noexcept(x.swap(y))); |
| ... | ... | @@ -138,6 +154,8 @@ public: |
| 138 | 154 | template <class InputIterator> |
| 139 | 155 | priority_queue(InputIterator first, InputIterator last, |
| 140 | 156 | const Compare& comp, Container&& c); |
| 157 | template <container-compatible-range<T> R> | |
| 158 | priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); // since C++23 | |
| 141 | 159 | template <class Alloc> |
| 142 | 160 | explicit priority_queue(const Alloc& a); |
| 143 | 161 | template <class Alloc> |
| ... | ... | @@ -160,6 +178,10 @@ public: |
| 160 | 178 | template <class InputIterator> |
| 161 | 179 | priority_queue(InputIterator first, InputIterator last, |
| 162 | 180 | const Compare& comp, Container&& c, const Alloc& a); |
| 181 | template <container-compatible-range<T> R, class Alloc> | |
| 182 | priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); // since C++23 | |
| 183 | template <container-compatible-range<T> R, class Alloc> | |
| 184 | priority_queue(from_range_t, R&& rg, const Alloc&); // since C++23 | |
| 163 | 185 | template <class Alloc> |
| 164 | 186 | priority_queue(const priority_queue& q, const Alloc& a); |
| 165 | 187 | template <class Alloc> |
| ... | ... | @@ -171,6 +193,8 @@ public: |
| 171 | 193 | |
| 172 | 194 | void push(const value_type& v); |
| 173 | 195 | void push(value_type&& v); |
| 196 | template<container-compatible-range<T> R> | |
| 197 | void push_range(R&& rg); // C++23 | |
| 174 | 198 | template <class... Args> void emplace(Args&&... args); |
| 175 | 199 | void pop(); |
| 176 | 200 | |
| ... | ... | @@ -189,6 +213,10 @@ template<class InputIterator, |
| 189 | 213 | priority_queue(InputIterator, InputIterator, Compare = Compare(), Container = Container()) |
| 190 | 214 | -> priority_queue<iter-value-type<InputIterator>, Container, Compare>; // C++17 |
| 191 | 215 | |
| 216 | template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>> | |
| 217 | priority_queue(from_range_t, R&&, Compare = Compare()) | |
| 218 | -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>>, Compare>; // C++23 | |
| 219 | ||
| 192 | 220 | template<class Compare, class Container, class Allocator> |
| 193 | 221 | priority_queue(Compare, Container, Allocator) |
| 194 | 222 | -> priority_queue<typename Container::value_type, Container, Compare>; // C++17 |
| ... | ... | @@ -208,6 +236,15 @@ template<class InputIterator, class Compare, class Container, class Allocator> |
| 208 | 236 | priority_queue(InputIterator, InputIterator, Compare, Container, Allocator) |
| 209 | 237 | -> priority_queue<typename Container::value_type, Container, Compare>; // C++17 |
| 210 | 238 | |
| 239 | template<ranges::input_range R, class Compare, class Allocator> | |
| 240 | priority_queue(from_range_t, R&&, Compare, Allocator) | |
| 241 | -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>, | |
| 242 | Compare>; // C++23 | |
| 243 | ||
| 244 | template<ranges::input_range R, class Allocator> | |
| 245 | priority_queue(from_range_t, R&&, Allocator) | |
| 246 | -> priority_queue<ranges::range_value_t<R>, vector<ranges::range_value_t<R>, Allocator>>; // C++23 | |
| 247 | ||
| 211 | 248 | template <class T, class Container, class Compare> |
| 212 | 249 | void swap(priority_queue<T, Container, Compare>& x, |
| 213 | 250 | priority_queue<T, Container, Compare>& y) |
| ... | ... | @@ -220,14 +257,19 @@ template <class T, class Container, class Compare> |
| 220 | 257 | #include <__algorithm/make_heap.h> |
| 221 | 258 | #include <__algorithm/pop_heap.h> |
| 222 | 259 | #include <__algorithm/push_heap.h> |
| 260 | #include <__algorithm/ranges_copy.h> | |
| 223 | 261 | #include <__assert> // all public C++ headers provide the assertion handler |
| 224 | 262 | #include <__config> |
| 225 | 263 | #include <__functional/operations.h> |
| 264 | #include <__iterator/back_insert_iterator.h> | |
| 226 | 265 | #include <__iterator/iterator_traits.h> |
| 227 | 266 | #include <__memory/uses_allocator.h> |
| 267 | #include <__ranges/access.h> | |
| 268 | #include <__ranges/concepts.h> | |
| 269 | #include <__ranges/container_compatible_range.h> | |
| 270 | #include <__ranges/from_range.h> | |
| 228 | 271 | #include <__utility/forward.h> |
| 229 | 272 | #include <deque> |
| 230 | #include <type_traits> | |
| 231 | 273 | #include <vector> |
| 232 | 274 | #include <version> |
| 233 | 275 | |
| ... | ... | @@ -278,18 +320,30 @@ public: |
| 278 | 320 | _LIBCPP_INLINE_VISIBILITY |
| 279 | 321 | queue(const queue& __q) : c(__q.c) {} |
| 280 | 322 | |
| 281 | #if _LIBCPP_STD_VER > 20 | |
| 323 | #if _LIBCPP_STD_VER >= 23 | |
| 282 | 324 | template <class _InputIterator, |
| 283 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> | |
| 325 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>> | |
| 284 | 326 | _LIBCPP_HIDE_FROM_ABI |
| 285 | 327 | queue(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} |
| 286 | 328 | |
| 329 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 330 | _LIBCPP_HIDE_FROM_ABI | |
| 331 | queue(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {} | |
| 332 | ||
| 287 | 333 | template <class _InputIterator, |
| 288 | 334 | class _Alloc, |
| 289 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 335 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 290 | 336 | class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> |
| 291 | 337 | _LIBCPP_HIDE_FROM_ABI |
| 292 | 338 | queue(_InputIterator __first, _InputIterator __second, const _Alloc& __alloc) : c(__first, __second, __alloc) {} |
| 339 | ||
| 340 | template <_ContainerCompatibleRange<_Tp> _Range, | |
| 341 | class _Alloc, | |
| 342 | class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> | |
| 343 | _LIBCPP_HIDE_FROM_ABI | |
| 344 | queue(from_range_t, _Range&& __range, const _Alloc& __alloc) | |
| 345 | : c(from_range, std::forward<_Range>(__range), __alloc) {} | |
| 346 | ||
| 293 | 347 | #endif |
| 294 | 348 | |
| 295 | 349 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -361,9 +415,24 @@ public: |
| 361 | 415 | #ifndef _LIBCPP_CXX03_LANG |
| 362 | 416 | _LIBCPP_INLINE_VISIBILITY |
| 363 | 417 | void push(value_type&& __v) {c.push_back(_VSTD::move(__v));} |
| 418 | ||
| 419 | #if _LIBCPP_STD_VER >= 23 | |
| 420 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 421 | _LIBCPP_HIDE_FROM_ABI | |
| 422 | void push_range(_Range&& __range) { | |
| 423 | if constexpr (requires (container_type& __c) { | |
| 424 | __c.append_range(std::forward<_Range>(__range)); | |
| 425 | }) { | |
| 426 | c.append_range(std::forward<_Range>(__range)); | |
| 427 | } else { | |
| 428 | ranges::copy(std::forward<_Range>(__range), std::back_inserter(c)); | |
| 429 | } | |
| 430 | } | |
| 431 | #endif | |
| 432 | ||
| 364 | 433 | template <class... _Args> |
| 365 | 434 | _LIBCPP_INLINE_VISIBILITY |
| 366 | #if _LIBCPP_STD_VER > 14 | |
| 435 | #if _LIBCPP_STD_VER >= 17 | |
| 367 | 436 | decltype(auto) emplace(_Args&&... __args) |
| 368 | 437 | { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} |
| 369 | 438 | #else |
| ... | ... | @@ -384,20 +453,20 @@ public: |
| 384 | 453 | |
| 385 | 454 | _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; } |
| 386 | 455 | |
| 387 | template <class _T1, class _C1> | |
| 456 | template <class _T1, class _OtherContainer> | |
| 388 | 457 | friend |
| 389 | 458 | _LIBCPP_INLINE_VISIBILITY |
| 390 | 459 | bool |
| 391 | operator==(const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); | |
| 460 | operator==(const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y); | |
| 392 | 461 | |
| 393 | template <class _T1, class _C1> | |
| 462 | template <class _T1, class _OtherContainer> | |
| 394 | 463 | friend |
| 395 | 464 | _LIBCPP_INLINE_VISIBILITY |
| 396 | 465 | bool |
| 397 | operator< (const queue<_T1, _C1>& __x,const queue<_T1, _C1>& __y); | |
| 466 | operator< (const queue<_T1, _OtherContainer>& __x,const queue<_T1, _OtherContainer>& __y); | |
| 398 | 467 | }; |
| 399 | 468 | |
| 400 | #if _LIBCPP_STD_VER > 14 | |
| 469 | #if _LIBCPP_STD_VER >= 17 | |
| 401 | 470 | template<class _Container, |
| 402 | 471 | class = enable_if_t<!__is_allocator<_Container>::value> |
| 403 | 472 | > |
| ... | ... | @@ -413,18 +482,28 @@ queue(_Container, _Alloc) |
| 413 | 482 | -> queue<typename _Container::value_type, _Container>; |
| 414 | 483 | #endif |
| 415 | 484 | |
| 416 | #if _LIBCPP_STD_VER > 20 | |
| 485 | #if _LIBCPP_STD_VER >= 23 | |
| 417 | 486 | template <class _InputIterator, |
| 418 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> | |
| 487 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>> | |
| 419 | 488 | queue(_InputIterator, _InputIterator) |
| 420 | 489 | -> queue<__iter_value_type<_InputIterator>>; |
| 421 | 490 | |
| 491 | template <ranges::input_range _Range> | |
| 492 | queue(from_range_t, _Range&&) | |
| 493 | -> queue<ranges::range_value_t<_Range>>; | |
| 494 | ||
| 422 | 495 | template <class _InputIterator, |
| 423 | 496 | class _Alloc, |
| 424 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 497 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 425 | 498 | class = __enable_if_t<__is_allocator<_Alloc>::value>> |
| 426 | 499 | queue(_InputIterator, _InputIterator, _Alloc) |
| 427 | 500 | -> queue<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; |
| 501 | ||
| 502 | template <ranges::input_range _Range, | |
| 503 | class _Alloc, | |
| 504 | class = __enable_if_t<__is_allocator<_Alloc>::value>> | |
| 505 | queue(from_range_t, _Range&&, _Alloc) | |
| 506 | -> queue<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>; | |
| 428 | 507 | #endif |
| 429 | 508 | |
| 430 | 509 | template <class _Tp, class _Container> |
| ... | ... | @@ -475,6 +554,17 @@ operator<=(const queue<_Tp, _Container>& __x,const queue<_Tp, _Container>& __y) |
| 475 | 554 | return !(__y < __x); |
| 476 | 555 | } |
| 477 | 556 | |
| 557 | #if _LIBCPP_STD_VER >= 20 | |
| 558 | ||
| 559 | template <class _Tp, three_way_comparable _Container> | |
| 560 | _LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container> | |
| 561 | operator<=>(const queue<_Tp, _Container>& __x, const queue<_Tp, _Container>& __y) { | |
| 562 | // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors | |
| 563 | return __x.__get_container() <=> __y.__get_container(); | |
| 564 | } | |
| 565 | ||
| 566 | #endif | |
| 567 | ||
| 478 | 568 | template <class _Tp, class _Container> |
| 479 | 569 | inline _LIBCPP_INLINE_VISIBILITY |
| 480 | 570 | __enable_if_t<__is_swappable<_Container>::value, void> |
| ... | ... | @@ -544,20 +634,31 @@ public: |
| 544 | 634 | _LIBCPP_INLINE_VISIBILITY |
| 545 | 635 | priority_queue(const value_compare& __comp, container_type&& __c); |
| 546 | 636 | #endif |
| 547 | template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 637 | template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 548 | 638 | _LIBCPP_INLINE_VISIBILITY |
| 549 | 639 | priority_queue(_InputIter __f, _InputIter __l, |
| 550 | 640 | const value_compare& __comp = value_compare()); |
| 551 | template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 641 | template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 552 | 642 | _LIBCPP_INLINE_VISIBILITY |
| 553 | 643 | priority_queue(_InputIter __f, _InputIter __l, |
| 554 | 644 | const value_compare& __comp, const container_type& __c); |
| 555 | 645 | #ifndef _LIBCPP_CXX03_LANG |
| 556 | template <class _InputIter, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 646 | template <class _InputIter, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 557 | 647 | _LIBCPP_INLINE_VISIBILITY |
| 558 | 648 | priority_queue(_InputIter __f, _InputIter __l, |
| 559 | 649 | const value_compare& __comp, container_type&& __c); |
| 560 | 650 | #endif // _LIBCPP_CXX03_LANG |
| 651 | ||
| 652 | #if _LIBCPP_STD_VER >= 23 | |
| 653 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 654 | _LIBCPP_HIDE_FROM_ABI | |
| 655 | priority_queue(from_range_t, _Range&& __range, const value_compare& __comp = value_compare()) | |
| 656 | : c(from_range, std::forward<_Range>(__range)), | |
| 657 | comp(__comp) { | |
| 658 | std::make_heap(c.begin(), c.end(), comp); | |
| 659 | } | |
| 660 | #endif | |
| 661 | ||
| 561 | 662 | template <class _Alloc> |
| 562 | 663 | _LIBCPP_INLINE_VISIBILITY |
| 563 | 664 | explicit priority_queue(const _Alloc& __a, |
| ... | ... | @@ -587,31 +688,55 @@ public: |
| 587 | 688 | __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); |
| 588 | 689 | #endif // _LIBCPP_CXX03_LANG |
| 589 | 690 | |
| 590 | template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 691 | template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 591 | 692 | _LIBCPP_INLINE_VISIBILITY |
| 592 | 693 | priority_queue(_InputIter __f, _InputIter __l, const _Alloc& __a, |
| 593 | 694 | __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); |
| 594 | 695 | |
| 595 | template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 696 | template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 596 | 697 | _LIBCPP_INLINE_VISIBILITY |
| 597 | 698 | priority_queue(_InputIter __f, _InputIter __l, |
| 598 | 699 | const value_compare& __comp, const _Alloc& __a, |
| 599 | 700 | __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); |
| 600 | 701 | |
| 601 | template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 702 | template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 602 | 703 | _LIBCPP_INLINE_VISIBILITY |
| 603 | 704 | priority_queue(_InputIter __f, _InputIter __l, |
| 604 | 705 | const value_compare& __comp, const container_type& __c, const _Alloc& __a, |
| 605 | 706 | __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); |
| 606 | 707 | |
| 607 | 708 | #ifndef _LIBCPP_CXX03_LANG |
| 608 | template <class _InputIter, class _Alloc, class = __enable_if_t<__is_cpp17_input_iterator<_InputIter>::value> > | |
| 709 | template <class _InputIter, class _Alloc, class = __enable_if_t<__has_input_iterator_category<_InputIter>::value> > | |
| 609 | 710 | _LIBCPP_INLINE_VISIBILITY |
| 610 | 711 | priority_queue(_InputIter __f, _InputIter __l, |
| 611 | 712 | const value_compare& __comp, container_type&& __c, const _Alloc& __a, |
| 612 | 713 | __enable_if_t<uses_allocator<container_type, _Alloc>::value>* = 0); |
| 613 | 714 | #endif // _LIBCPP_CXX03_LANG |
| 614 | 715 | |
| 716 | #if _LIBCPP_STD_VER >= 23 | |
| 717 | ||
| 718 | template <_ContainerCompatibleRange<_Tp> _Range, | |
| 719 | class _Alloc, | |
| 720 | class = enable_if_t<uses_allocator<_Container, _Alloc>::value>> | |
| 721 | _LIBCPP_HIDE_FROM_ABI | |
| 722 | priority_queue(from_range_t, _Range&& __range, const value_compare& __comp, const _Alloc& __a) | |
| 723 | : c(from_range, std::forward<_Range>(__range), __a), | |
| 724 | comp(__comp) { | |
| 725 | std::make_heap(c.begin(), c.end(), comp); | |
| 726 | } | |
| 727 | ||
| 728 | template <_ContainerCompatibleRange<_Tp> _Range, | |
| 729 | class _Alloc, | |
| 730 | class = enable_if_t<uses_allocator<_Container, _Alloc>::value>> | |
| 731 | _LIBCPP_HIDE_FROM_ABI | |
| 732 | priority_queue(from_range_t, _Range&& __range, const _Alloc& __a) | |
| 733 | : c(from_range, std::forward<_Range>(__range), __a), | |
| 734 | comp() { | |
| 735 | std::make_heap(c.begin(), c.end(), comp); | |
| 736 | } | |
| 737 | ||
| 738 | #endif | |
| 739 | ||
| 615 | 740 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY |
| 616 | 741 | bool empty() const {return c.empty();} |
| 617 | 742 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -624,6 +749,23 @@ public: |
| 624 | 749 | #ifndef _LIBCPP_CXX03_LANG |
| 625 | 750 | _LIBCPP_INLINE_VISIBILITY |
| 626 | 751 | void push(value_type&& __v); |
| 752 | ||
| 753 | #if _LIBCPP_STD_VER >= 23 | |
| 754 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 755 | _LIBCPP_HIDE_FROM_ABI | |
| 756 | void push_range(_Range&& __range) { | |
| 757 | if constexpr (requires (container_type& __c) { | |
| 758 | __c.append_range(std::forward<_Range>(__range)); | |
| 759 | }) { | |
| 760 | c.append_range(std::forward<_Range>(__range)); | |
| 761 | } else { | |
| 762 | ranges::copy(std::forward<_Range>(__range), std::back_inserter(c)); | |
| 763 | } | |
| 764 | ||
| 765 | std::make_heap(c.begin(), c.end(), comp); | |
| 766 | } | |
| 767 | #endif | |
| 768 | ||
| 627 | 769 | template <class... _Args> |
| 628 | 770 | _LIBCPP_INLINE_VISIBILITY |
| 629 | 771 | void emplace(_Args&&... __args); |
| ... | ... | @@ -651,7 +793,7 @@ priority_queue(_Compare, _Container) |
| 651 | 793 | template<class _InputIterator, |
| 652 | 794 | class _Compare = less<__iter_value_type<_InputIterator>>, |
| 653 | 795 | class _Container = vector<__iter_value_type<_InputIterator>>, |
| 654 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 796 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 655 | 797 | class = enable_if_t<!__is_allocator<_Compare>::value>, |
| 656 | 798 | class = enable_if_t<!__is_allocator<_Container>::value> |
| 657 | 799 | > |
| ... | ... | @@ -669,7 +811,7 @@ priority_queue(_Compare, _Container, _Alloc) |
| 669 | 811 | -> priority_queue<typename _Container::value_type, _Container, _Compare>; |
| 670 | 812 | |
| 671 | 813 | template<class _InputIterator, class _Allocator, |
| 672 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 814 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 673 | 815 | class = enable_if_t<__is_allocator<_Allocator>::value> |
| 674 | 816 | > |
| 675 | 817 | priority_queue(_InputIterator, _InputIterator, _Allocator) |
| ... | ... | @@ -678,7 +820,7 @@ priority_queue(_InputIterator, _InputIterator, _Allocator) |
| 678 | 820 | less<__iter_value_type<_InputIterator>>>; |
| 679 | 821 | |
| 680 | 822 | template<class _InputIterator, class _Compare, class _Allocator, |
| 681 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 823 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 682 | 824 | class = enable_if_t<!__is_allocator<_Compare>::value>, |
| 683 | 825 | class = enable_if_t<__is_allocator<_Allocator>::value> |
| 684 | 826 | > |
| ... | ... | @@ -687,7 +829,7 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Allocator) |
| 687 | 829 | vector<__iter_value_type<_InputIterator>, _Allocator>, _Compare>; |
| 688 | 830 | |
| 689 | 831 | template<class _InputIterator, class _Compare, class _Container, class _Alloc, |
| 690 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 832 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 691 | 833 | class = enable_if_t<!__is_allocator<_Compare>::value>, |
| 692 | 834 | class = enable_if_t<!__is_allocator<_Container>::value>, |
| 693 | 835 | class = enable_if_t<uses_allocator<_Container, _Alloc>::value> |
| ... | ... | @@ -696,6 +838,31 @@ priority_queue(_InputIterator, _InputIterator, _Compare, _Container, _Alloc) |
| 696 | 838 | -> priority_queue<typename _Container::value_type, _Container, _Compare>; |
| 697 | 839 | #endif |
| 698 | 840 | |
| 841 | #if _LIBCPP_STD_VER >= 23 | |
| 842 | ||
| 843 | template <ranges::input_range _Range, | |
| 844 | class _Compare = less<ranges::range_value_t<_Range>>, | |
| 845 | class = enable_if_t<!__is_allocator<_Compare>::value>> | |
| 846 | priority_queue(from_range_t, _Range&&, _Compare = _Compare()) | |
| 847 | -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>>, _Compare>; | |
| 848 | ||
| 849 | template <ranges::input_range _Range, | |
| 850 | class _Compare, | |
| 851 | class _Alloc, | |
| 852 | class = enable_if_t<!__is_allocator<_Compare>::value>, | |
| 853 | class = enable_if_t<__is_allocator<_Alloc>::value>> | |
| 854 | priority_queue(from_range_t, _Range&&, _Compare, _Alloc) | |
| 855 | -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>, | |
| 856 | _Compare>; | |
| 857 | ||
| 858 | template <ranges::input_range _Range, | |
| 859 | class _Alloc, | |
| 860 | class = enable_if_t<__is_allocator<_Alloc>::value>> | |
| 861 | priority_queue(from_range_t, _Range&&, _Alloc) | |
| 862 | -> priority_queue<ranges::range_value_t<_Range>, vector<ranges::range_value_t<_Range>, _Alloc>>; | |
| 863 | ||
| 864 | #endif | |
| 865 | ||
| 699 | 866 | template <class _Tp, class _Container, class _Compare> |
| 700 | 867 | inline |
| 701 | 868 | priority_queue<_Tp, _Container, _Compare>::priority_queue(const _Compare& __comp, |
| ... | ... | @@ -964,7 +1131,9 @@ _LIBCPP_END_NAMESPACE_STD |
| 964 | 1131 | |
| 965 | 1132 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 966 | 1133 | # include <concepts> |
| 1134 | # include <cstdlib> | |
| 967 | 1135 | # include <functional> |
| 1136 | # include <type_traits> | |
| 968 | 1137 | #endif |
| 969 | 1138 | |
| 970 | 1139 | #endif // _LIBCPP_QUEUE |
lib/libcxx/include/random+1| ... | ... | @@ -1734,6 +1734,7 @@ class piecewise_linear_distribution |
| 1734 | 1734 | # include <concepts> |
| 1735 | 1735 | # include <cstddef> |
| 1736 | 1736 | # include <cstdint> |
| 1737 | # include <cstdlib> | |
| 1737 | 1738 | # include <iosfwd> |
| 1738 | 1739 | # include <limits> |
| 1739 | 1740 | # include <numeric> |
lib/libcxx/include/ranges+41-6| ... | ... | @@ -49,6 +49,8 @@ namespace std::ranges { |
| 49 | 49 | using range_reference_t = iter_reference_t<iterator_t<R>>; |
| 50 | 50 | template<range R> |
| 51 | 51 | using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<R>>; |
| 52 | template <range R> | |
| 53 | using range_common_reference_t = iter_common_reference_t<iterator_t<R>>; | |
| 52 | 54 | |
| 53 | 55 | // [range.sized], sized ranges |
| 54 | 56 | template<class> |
| ... | ... | @@ -136,6 +138,16 @@ namespace std::ranges { |
| 136 | 138 | inline constexpr auto values = elements<1>; |
| 137 | 139 | } |
| 138 | 140 | |
| 141 | // [range.utility.conv], range conversions | |
| 142 | template<class C, input_range R, class... Args> requires (!view<C>) | |
| 143 | constexpr C to(R&& r, Args&&... args); // Since C++23 | |
| 144 | template<template<class...> class C, input_range R, class... Args> | |
| 145 | constexpr auto to(R&& r, Args&&... args); // Since C++23 | |
| 146 | template<class C, class... Args> requires (!view<C>) | |
| 147 | constexpr auto to(Args&&... args); // Since C++23 | |
| 148 | template<template<class...> class C, class... Args> | |
| 149 | constexpr auto to(Args&&... args); // Since C++23 | |
| 150 | ||
| 139 | 151 | // [range.empty], empty view |
| 140 | 152 | template<class T> |
| 141 | 153 | requires is_object_v<T> |
| ... | ... | @@ -250,6 +262,19 @@ namespace std::ranges { |
| 250 | 262 | template<class W, class Bound> |
| 251 | 263 | inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true; |
| 252 | 264 | |
| 265 | // [range.repeat], repeat view | |
| 266 | template<class T> | |
| 267 | concept integer-like-with-usable-difference-type = // exposition only | |
| 268 | is-signed-integer-like<T> || (is-integer-like<T> && weakly_incrementable<T>); | |
| 269 | ||
| 270 | template<move_constructible T, semiregular Bound = unreachable_sentinel_t> | |
| 271 | requires (is_object_v<T> && same_as<T, remove_cv_t<T>> && | |
| 272 | (integer-like-with-usable-difference-type<Bound> || | |
| 273 | same_as<Bound, unreachable_sentinel_t>)) | |
| 274 | class repeat_view; | |
| 275 | ||
| 276 | namespace views { inline constexpr unspecified repeat = unspecified; } | |
| 277 | ||
| 253 | 278 | // [range.join], join view |
| 254 | 279 | template<input_range V> |
| 255 | 280 | requires view<V> && input_range<range_reference_t<V>> |
| ... | ... | @@ -292,13 +317,13 @@ namespace std::ranges { |
| 292 | 317 | // [range.zip], zip view |
| 293 | 318 | template<input_range... Views> |
| 294 | 319 | requires (view<Views> && ...) && (sizeof...(Views) > 0) |
| 295 | class zip_view; // C++2b | |
| 320 | class zip_view; // C++23 | |
| 296 | 321 | |
| 297 | 322 | template<class... Views> |
| 298 | inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++2b | |
| 323 | inline constexpr bool enable_borrowed_range<zip_view<Views...>> = // C++23 | |
| 299 | 324 | (enable_borrowed_range<Views> && ...); |
| 300 | 325 | |
| 301 | namespace views { inline constexpr unspecified zip = unspecified; } // C++2b | |
| 326 | namespace views { inline constexpr unspecified zip = unspecified; } // C++23 | |
| 302 | 327 | |
| 303 | 328 | // [range.as.rvalue] |
| 304 | 329 | template <view V> |
| ... | ... | @@ -337,6 +362,9 @@ namespace std { |
| 337 | 362 | struct tuple_element<1, const ranges::subrange<I, S, K>> { |
| 338 | 363 | using type = S; |
| 339 | 364 | }; |
| 365 | ||
| 366 | struct from_range_t { explicit from_range_t() = default; }; // Since C++23 | |
| 367 | inline constexpr from_range_t from_range{}; // Since C++23 | |
| 340 | 368 | } |
| 341 | 369 | */ |
| 342 | 370 | |
| ... | ... | @@ -358,12 +386,14 @@ namespace std { |
| 358 | 386 | #include <__ranges/enable_borrowed_range.h> |
| 359 | 387 | #include <__ranges/enable_view.h> |
| 360 | 388 | #include <__ranges/filter_view.h> |
| 389 | #include <__ranges/from_range.h> | |
| 361 | 390 | #include <__ranges/iota_view.h> |
| 362 | 391 | #include <__ranges/join_view.h> |
| 363 | 392 | #include <__ranges/lazy_split_view.h> |
| 364 | 393 | #include <__ranges/rbegin.h> |
| 365 | 394 | #include <__ranges/ref_view.h> |
| 366 | 395 | #include <__ranges/rend.h> |
| 396 | #include <__ranges/repeat_view.h> | |
| 367 | 397 | #include <__ranges/reverse_view.h> |
| 368 | 398 | #include <__ranges/single_view.h> |
| 369 | 399 | #include <__ranges/size.h> |
| ... | ... | @@ -371,11 +401,11 @@ namespace std { |
| 371 | 401 | #include <__ranges/subrange.h> |
| 372 | 402 | #include <__ranges/take_view.h> |
| 373 | 403 | #include <__ranges/take_while_view.h> |
| 404 | #include <__ranges/to.h> | |
| 374 | 405 | #include <__ranges/transform_view.h> |
| 375 | 406 | #include <__ranges/view_interface.h> |
| 376 | 407 | #include <__ranges/views.h> |
| 377 | 408 | #include <__ranges/zip_view.h> |
| 378 | #include <type_traits> | |
| 379 | 409 | #include <version> |
| 380 | 410 | |
| 381 | 411 | #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) |
| ... | ... | @@ -390,11 +420,16 @@ namespace std { |
| 390 | 420 | #include <iterator> |
| 391 | 421 | |
| 392 | 422 | // [tuple.helper] |
| 393 | #include <__tuple_dir/tuple_element.h> | |
| 394 | #include <__tuple_dir/tuple_size.h> | |
| 423 | #include <__tuple/tuple_element.h> | |
| 424 | #include <__tuple/tuple_size.h> | |
| 395 | 425 | |
| 396 | 426 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 397 | 427 | # pragma GCC system_header |
| 398 | 428 | #endif |
| 399 | 429 | |
| 430 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 431 | # include <cstdlib> | |
| 432 | # include <type_traits> | |
| 433 | #endif | |
| 434 | ||
| 400 | 435 | #endif // _LIBCPP_RANGES |
lib/libcxx/include/ratio+5-1| ... | ... | @@ -40,6 +40,8 @@ template <class R1, class R2> struct ratio_greater; |
| 40 | 40 | template <class R1, class R2> struct ratio_greater_equal; |
| 41 | 41 | |
| 42 | 42 | // convenience SI typedefs |
| 43 | using quecto = ratio <1, 1'000'000'000'000'000'000'000'000'000'000>; // Since C++26; not supported | |
| 44 | using ronto = ratio <1, 1'000'000'000'000'000'000'000'000'000>; // Since C++26; not supported | |
| 43 | 45 | typedef ratio<1, 1000000000000000000000000> yocto; // not supported |
| 44 | 46 | typedef ratio<1, 1000000000000000000000> zepto; // not supported |
| 45 | 47 | typedef ratio<1, 1000000000000000000> atto; |
| ... | ... | @@ -60,6 +62,8 @@ typedef ratio< 1000000000000000, 1> peta; |
| 60 | 62 | typedef ratio< 1000000000000000000, 1> exa; |
| 61 | 63 | typedef ratio< 1000000000000000000000, 1> zetta; // not supported |
| 62 | 64 | typedef ratio<1000000000000000000000000, 1> yotta; // not supported |
| 65 | using ronna = ratio <1'000'000'000'000'000'000'000'000'000, 1>; // Since C++26; not supported | |
| 66 | using quetta = ratio <1'000'000'000'000'000'000'000'000'000'000, 1>; // Since C++26; not supported | |
| 63 | 67 | |
| 64 | 68 | // 20.11.5, ratio comparison |
| 65 | 69 | template <class R1, class R2> inline constexpr bool ratio_equal_v |
| ... | ... | @@ -501,7 +505,7 @@ struct __ratio_gcd |
| 501 | 505 | __static_lcm<_R1::den, _R2::den>::value> type; |
| 502 | 506 | }; |
| 503 | 507 | |
| 504 | #if _LIBCPP_STD_VER > 14 | |
| 508 | #if _LIBCPP_STD_VER >= 17 | |
| 505 | 509 | template <class _R1, class _R2> |
| 506 | 510 | inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value; |
| 507 | 511 |
lib/libcxx/include/regex+202-112| ... | ... | @@ -13,6 +13,7 @@ |
| 13 | 13 | /* |
| 14 | 14 | regex synopsis |
| 15 | 15 | |
| 16 | #include <compare> | |
| 16 | 17 | #include <initializer_list> |
| 17 | 18 | |
| 18 | 19 | namespace std |
| ... | ... | @@ -225,6 +226,8 @@ public: |
| 225 | 226 | int compare(const sub_match& s) const; |
| 226 | 227 | int compare(const string_type& s) const; |
| 227 | 228 | int compare(const value_type* s) const; |
| 229 | ||
| 230 | void swap(sub_match& s) noexcept(see below); | |
| 228 | 231 | }; |
| 229 | 232 | |
| 230 | 233 | typedef sub_match<const char*> csub_match; |
| ... | ... | @@ -237,50 +240,54 @@ template <class BiIter> |
| 237 | 240 | operator==(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 238 | 241 | |
| 239 | 242 | template <class BiIter> |
| 243 | auto | |
| 244 | operator<=>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); // Since C++20 | |
| 245 | ||
| 246 | template <class BiIter> // Removed in C++20 | |
| 240 | 247 | bool |
| 241 | 248 | operator!=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 242 | 249 | |
| 243 | template <class BiIter> | |
| 250 | template <class BiIter> // Removed in C++20 | |
| 244 | 251 | bool |
| 245 | 252 | operator<(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 246 | 253 | |
| 247 | template <class BiIter> | |
| 254 | template <class BiIter> // Removed in C++20 | |
| 248 | 255 | bool |
| 249 | 256 | operator<=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 250 | 257 | |
| 251 | template <class BiIter> | |
| 258 | template <class BiIter> // Removed in C++20 | |
| 252 | 259 | bool |
| 253 | 260 | operator>=(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 254 | 261 | |
| 255 | template <class BiIter> | |
| 262 | template <class BiIter> // Removed in C++20 | |
| 256 | 263 | bool |
| 257 | 264 | operator>(const sub_match<BiIter>& lhs, const sub_match<BiIter>& rhs); |
| 258 | 265 | |
| 259 | template <class BiIter, class ST, class SA> | |
| 266 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 260 | 267 | bool |
| 261 | 268 | operator==(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 262 | 269 | const sub_match<BiIter>& rhs); |
| 263 | 270 | |
| 264 | template <class BiIter, class ST, class SA> | |
| 271 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 265 | 272 | bool |
| 266 | 273 | operator!=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 267 | 274 | const sub_match<BiIter>& rhs); |
| 268 | 275 | |
| 269 | template <class BiIter, class ST, class SA> | |
| 276 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 270 | 277 | bool |
| 271 | 278 | operator<(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 272 | 279 | const sub_match<BiIter>& rhs); |
| 273 | 280 | |
| 274 | template <class BiIter, class ST, class SA> | |
| 281 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 275 | 282 | bool |
| 276 | 283 | operator>(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 277 | 284 | const sub_match<BiIter>& rhs); |
| 278 | 285 | |
| 279 | template <class BiIter, class ST, class SA> | |
| 286 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 280 | 287 | bool operator>=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 281 | 288 | const sub_match<BiIter>& rhs); |
| 282 | 289 | |
| 283 | template <class BiIter, class ST, class SA> | |
| 290 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 284 | 291 | bool |
| 285 | 292 | operator<=(const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& lhs, |
| 286 | 293 | const sub_match<BiIter>& rhs); |
| ... | ... | @@ -290,56 +297,62 @@ template <class BiIter, class ST, class SA> |
| 290 | 297 | operator==(const sub_match<BiIter>& lhs, |
| 291 | 298 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 292 | 299 | |
| 293 | template <class BiIter, class ST, class SA> | |
| 300 | template <class BiIter, class ST, class SA> // Since C++20 | |
| 301 | auto | |
| 302 | operator<=>(const sub_match<BiIter>& lhs, | |
| 303 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); | |
| 304 | ||
| 305 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 294 | 306 | bool |
| 295 | 307 | operator!=(const sub_match<BiIter>& lhs, |
| 296 | 308 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 297 | 309 | |
| 298 | template <class BiIter, class ST, class SA> | |
| 310 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 299 | 311 | bool |
| 300 | 312 | operator<(const sub_match<BiIter>& lhs, |
| 301 | 313 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 302 | 314 | |
| 303 | template <class BiIter, class ST, class SA> | |
| 304 | bool operator>(const sub_match<BiIter>& lhs, | |
| 315 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 316 | bool | |
| 317 | operator>(const sub_match<BiIter>& lhs, | |
| 305 | 318 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 306 | 319 | |
| 307 | template <class BiIter, class ST, class SA> | |
| 320 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 308 | 321 | bool |
| 309 | 322 | operator>=(const sub_match<BiIter>& lhs, |
| 310 | 323 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 311 | 324 | |
| 312 | template <class BiIter, class ST, class SA> | |
| 325 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 313 | 326 | bool |
| 314 | 327 | operator<=(const sub_match<BiIter>& lhs, |
| 315 | 328 | const basic_string<typename iterator_traits<BiIter>::value_type, ST, SA>& rhs); |
| 316 | 329 | |
| 317 | template <class BiIter> | |
| 330 | template <class BiIter> // Removed in C++20 | |
| 318 | 331 | bool |
| 319 | 332 | operator==(typename iterator_traits<BiIter>::value_type const* lhs, |
| 320 | 333 | const sub_match<BiIter>& rhs); |
| 321 | 334 | |
| 322 | template <class BiIter> | |
| 335 | template <class BiIter> // Removed in C++20 | |
| 323 | 336 | bool |
| 324 | 337 | operator!=(typename iterator_traits<BiIter>::value_type const* lhs, |
| 325 | 338 | const sub_match<BiIter>& rhs); |
| 326 | 339 | |
| 327 | template <class BiIter> | |
| 340 | template <class BiIter> // Removed in C++20 | |
| 328 | 341 | bool |
| 329 | 342 | operator<(typename iterator_traits<BiIter>::value_type const* lhs, |
| 330 | 343 | const sub_match<BiIter>& rhs); |
| 331 | 344 | |
| 332 | template <class BiIter> | |
| 345 | template <class BiIter> // Removed in C++20 | |
| 333 | 346 | bool |
| 334 | 347 | operator>(typename iterator_traits<BiIter>::value_type const* lhs, |
| 335 | 348 | const sub_match<BiIter>& rhs); |
| 336 | 349 | |
| 337 | template <class BiIter> | |
| 350 | template <class BiIter> // Removed in C++20 | |
| 338 | 351 | bool |
| 339 | 352 | operator>=(typename iterator_traits<BiIter>::value_type const* lhs, |
| 340 | 353 | const sub_match<BiIter>& rhs); |
| 341 | 354 | |
| 342 | template <class BiIter> | |
| 355 | template <class BiIter> // Removed in C++20 | |
| 343 | 356 | bool |
| 344 | 357 | operator<=(typename iterator_traits<BiIter>::value_type const* lhs, |
| 345 | 358 | const sub_match<BiIter>& rhs); |
| ... | ... | @@ -349,57 +362,62 @@ template <class BiIter> |
| 349 | 362 | operator==(const sub_match<BiIter>& lhs, |
| 350 | 363 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 351 | 364 | |
| 352 | template <class BiIter> | |
| 365 | template <class BiIter> // Since C++20 | |
| 366 | auto | |
| 367 | operator<=>(const sub_match<BiIter>& lhs, | |
| 368 | typename iterator_traits<BiIter>::value_type const* rhs); | |
| 369 | ||
| 370 | template <class BiIter, class ST, class SA> // Removed in C++20 | |
| 353 | 371 | bool |
| 354 | 372 | operator!=(const sub_match<BiIter>& lhs, |
| 355 | 373 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 356 | 374 | |
| 357 | template <class BiIter> | |
| 375 | template <class BiIter> // Removed in C++20 | |
| 358 | 376 | bool |
| 359 | 377 | operator<(const sub_match<BiIter>& lhs, |
| 360 | 378 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 361 | 379 | |
| 362 | template <class BiIter> | |
| 380 | template <class BiIter> // Removed in C++20 | |
| 363 | 381 | bool |
| 364 | 382 | operator>(const sub_match<BiIter>& lhs, |
| 365 | 383 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 366 | 384 | |
| 367 | template <class BiIter> | |
| 385 | template <class BiIter> // Removed in C++20 | |
| 368 | 386 | bool |
| 369 | 387 | operator>=(const sub_match<BiIter>& lhs, |
| 370 | 388 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 371 | 389 | |
| 372 | template <class BiIter> | |
| 390 | template <class BiIter> // Removed in C++20 | |
| 373 | 391 | bool |
| 374 | 392 | operator<=(const sub_match<BiIter>& lhs, |
| 375 | 393 | typename iterator_traits<BiIter>::value_type const* rhs); |
| 376 | 394 | |
| 377 | template <class BiIter> | |
| 395 | template <class BiIter> // Removed in C++20 | |
| 378 | 396 | bool |
| 379 | 397 | operator==(typename iterator_traits<BiIter>::value_type const& lhs, |
| 380 | 398 | const sub_match<BiIter>& rhs); |
| 381 | 399 | |
| 382 | template <class BiIter> | |
| 400 | template <class BiIter> // Removed in C++20 | |
| 383 | 401 | bool |
| 384 | 402 | operator!=(typename iterator_traits<BiIter>::value_type const& lhs, |
| 385 | 403 | const sub_match<BiIter>& rhs); |
| 386 | 404 | |
| 387 | template <class BiIter> | |
| 405 | template <class BiIter> // Removed in C++20 | |
| 388 | 406 | bool |
| 389 | 407 | operator<(typename iterator_traits<BiIter>::value_type const& lhs, |
| 390 | 408 | const sub_match<BiIter>& rhs); |
| 391 | 409 | |
| 392 | template <class BiIter> | |
| 410 | template <class BiIter> // Removed in C++20 | |
| 393 | 411 | bool |
| 394 | 412 | operator>(typename iterator_traits<BiIter>::value_type const& lhs, |
| 395 | 413 | const sub_match<BiIter>& rhs); |
| 396 | 414 | |
| 397 | template <class BiIter> | |
| 415 | template <class BiIter> // Removed in C++20 | |
| 398 | 416 | bool |
| 399 | 417 | operator>=(typename iterator_traits<BiIter>::value_type const& lhs, |
| 400 | 418 | const sub_match<BiIter>& rhs); |
| 401 | 419 | |
| 402 | template <class BiIter> | |
| 420 | template <class BiIter> // Removed in C++20 | |
| 403 | 421 | bool |
| 404 | 422 | operator<=(typename iterator_traits<BiIter>::value_type const& lhs, |
| 405 | 423 | const sub_match<BiIter>& rhs); |
| ... | ... | @@ -409,27 +427,32 @@ template <class BiIter> |
| 409 | 427 | operator==(const sub_match<BiIter>& lhs, |
| 410 | 428 | typename iterator_traits<BiIter>::value_type const& rhs); |
| 411 | 429 | |
| 412 | template <class BiIter> | |
| 430 | template <class BiIter> // Since C++20 | |
| 431 | auto | |
| 432 | operator<=>(const sub_match<BiIter>& lhs, | |
| 433 | typename iterator_traits<BiIter>::value_type const& rhs); | |
| 434 | ||
| 435 | template <class BiIter> // Removed in C++20 | |
| 413 | 436 | bool |
| 414 | 437 | operator!=(const sub_match<BiIter>& lhs, |
| 415 | 438 | typename iterator_traits<BiIter>::value_type const& rhs); |
| 416 | 439 | |
| 417 | template <class BiIter> | |
| 440 | template <class BiIter> // Removed in C++20 | |
| 418 | 441 | bool |
| 419 | 442 | operator<(const sub_match<BiIter>& lhs, |
| 420 | 443 | typename iterator_traits<BiIter>::value_type const& rhs); |
| 421 | 444 | |
| 422 | template <class BiIter> | |
| 445 | template <class BiIter> // Removed in C++20 | |
| 423 | 446 | bool |
| 424 | 447 | operator>(const sub_match<BiIter>& lhs, |
| 425 | 448 | typename iterator_traits<BiIter>::value_type const& rhs); |
| 426 | 449 | |
| 427 | template <class BiIter> | |
| 450 | template <class BiIter> // Removed in C++20 | |
| 428 | 451 | bool |
| 429 | 452 | operator>=(const sub_match<BiIter>& lhs, |
| 430 | 453 | typename iterator_traits<BiIter>::value_type const& rhs); |
| 431 | 454 | |
| 432 | template <class BiIter> | |
| 455 | template <class BiIter> // Removed in C++20 | |
| 433 | 456 | bool |
| 434 | 457 | operator<=(const sub_match<BiIter>& lhs, |
| 435 | 458 | typename iterator_traits<BiIter>::value_type const& rhs); |
| ... | ... | @@ -520,7 +543,7 @@ template <class BidirectionalIterator, class Allocator> |
| 520 | 543 | operator==(const match_results<BidirectionalIterator, Allocator>& m1, |
| 521 | 544 | const match_results<BidirectionalIterator, Allocator>& m2); |
| 522 | 545 | |
| 523 | template <class BidirectionalIterator, class Allocator> | |
| 546 | template <class BidirectionalIterator, class Allocator> // Removed in C++20 | |
| 524 | 547 | bool |
| 525 | 548 | operator!=(const match_results<BidirectionalIterator, Allocator>& m1, |
| 526 | 549 | const match_results<BidirectionalIterator, Allocator>& m2); |
| ... | ... | @@ -687,7 +710,8 @@ public: |
| 687 | 710 | regex_iterator& operator=(const regex_iterator&); |
| 688 | 711 | |
| 689 | 712 | bool operator==(const regex_iterator&) const; |
| 690 | bool operator!=(const regex_iterator&) const; | |
| 713 | bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } // since C++20 | |
| 714 | bool operator!=(const regex_iterator&) const; // Removed in C++20 | |
| 691 | 715 | |
| 692 | 716 | const value_type& operator*() const; |
| 693 | 717 | const value_type* operator->() const; |
| ... | ... | @@ -745,7 +769,8 @@ public: |
| 745 | 769 | regex_token_iterator& operator=(const regex_token_iterator&); |
| 746 | 770 | |
| 747 | 771 | bool operator==(const regex_token_iterator&) const; |
| 748 | bool operator!=(const regex_token_iterator&) const; | |
| 772 | bool operator==(default_sentinel_t) const { return *this == regex_token_iterator(); } // since C++20 | |
| 773 | bool operator!=(const regex_token_iterator&) const; // Removed in C++20 | |
| 749 | 774 | |
| 750 | 775 | const value_type& operator*() const; |
| 751 | 776 | const value_type* operator->() const; |
| ... | ... | @@ -765,15 +790,19 @@ typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator; |
| 765 | 790 | #include <__algorithm/find.h> |
| 766 | 791 | #include <__algorithm/search.h> |
| 767 | 792 | #include <__assert> // all public C++ headers provide the assertion handler |
| 793 | #include <__availability> | |
| 768 | 794 | #include <__config> |
| 769 | 795 | #include <__iterator/back_insert_iterator.h> |
| 796 | #include <__iterator/default_sentinel.h> | |
| 770 | 797 | #include <__iterator/wrap_iter.h> |
| 771 | 798 | #include <__locale> |
| 799 | #include <__memory/shared_ptr.h> | |
| 772 | 800 | #include <__memory_resource/polymorphic_allocator.h> |
| 801 | #include <__type_traits/is_swappable.h> | |
| 773 | 802 | #include <__utility/move.h> |
| 774 | 803 | #include <__utility/pair.h> |
| 775 | 804 | #include <__utility/swap.h> |
| 776 | #include <cstring> | |
| 805 | #include <__verbose_abort> | |
| 777 | 806 | #include <deque> |
| 778 | 807 | #include <stdexcept> |
| 779 | 808 | #include <string> |
| ... | ... | @@ -996,13 +1025,13 @@ enum error_type |
| 996 | 1025 | |
| 997 | 1026 | } // namespace regex_constants |
| 998 | 1027 | |
| 999 | class _LIBCPP_EXCEPTION_ABI regex_error | |
| 1028 | class _LIBCPP_EXPORTED_FROM_ABI regex_error | |
| 1000 | 1029 | : public runtime_error |
| 1001 | 1030 | { |
| 1002 | 1031 | regex_constants::error_type __code_; |
| 1003 | 1032 | public: |
| 1004 | 1033 | explicit regex_error(regex_constants::error_type __ecode); |
| 1005 | regex_error(const regex_error&) _NOEXCEPT = default; | |
| 1034 | _LIBCPP_HIDE_FROM_ABI regex_error(const regex_error&) _NOEXCEPT = default; | |
| 1006 | 1035 | ~regex_error() _NOEXCEPT override; |
| 1007 | 1036 | _LIBCPP_INLINE_VISIBILITY |
| 1008 | 1037 | regex_constants::error_type code() const {return __code_;} |
| ... | ... | @@ -1012,10 +1041,10 @@ template <regex_constants::error_type _Ev> |
| 1012 | 1041 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 1013 | 1042 | void __throw_regex_error() |
| 1014 | 1043 | { |
| 1015 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1044 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1016 | 1045 | throw regex_error(_Ev); |
| 1017 | 1046 | #else |
| 1018 | _VSTD::abort(); | |
| 1047 | _LIBCPP_VERBOSE_ABORT("regex_error was thrown in -fno-exceptions mode"); | |
| 1019 | 1048 | #endif |
| 1020 | 1049 | } |
| 1021 | 1050 | |
| ... | ... | @@ -1221,7 +1250,7 @@ regex_traits<_CharT>::__transform_primary(_ForwardIterator __f, |
| 1221 | 1250 | |
| 1222 | 1251 | // lookup_collatename is very FreeBSD-specific |
| 1223 | 1252 | |
| 1224 | _LIBCPP_FUNC_VIS string __get_collation_name(const char* __s); | |
| 1253 | _LIBCPP_EXPORTED_FROM_ABI string __get_collation_name(const char* __s); | |
| 1225 | 1254 | |
| 1226 | 1255 | template <class _CharT> |
| 1227 | 1256 | template <class _ForwardIterator> |
| ... | ... | @@ -1284,8 +1313,7 @@ regex_traits<_CharT>::__lookup_collatename(_ForwardIterator __f, |
| 1284 | 1313 | |
| 1285 | 1314 | // lookup_classname |
| 1286 | 1315 | |
| 1287 | regex_traits<char>::char_class_type _LIBCPP_FUNC_VIS | |
| 1288 | __get_classname(const char* __s, bool __icase); | |
| 1316 | regex_traits<char>::char_class_type _LIBCPP_EXPORTED_FROM_ABI __get_classname(const char* __s, bool __icase); | |
| 1289 | 1317 | |
| 1290 | 1318 | template <class _CharT> |
| 1291 | 1319 | template <class _ForwardIterator> |
| ... | ... | @@ -1467,7 +1495,7 @@ public: |
| 1467 | 1495 | _LIBCPP_INLINE_VISIBILITY |
| 1468 | 1496 | __end_state() {} |
| 1469 | 1497 | |
| 1470 | virtual void __exec(__state&) const; | |
| 1498 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1471 | 1499 | }; |
| 1472 | 1500 | |
| 1473 | 1501 | template <class _CharT> |
| ... | ... | @@ -1533,7 +1561,7 @@ public: |
| 1533 | 1561 | explicit __empty_state(__node<_CharT>* __s) |
| 1534 | 1562 | : base(__s) {} |
| 1535 | 1563 | |
| 1536 | virtual void __exec(__state&) const; | |
| 1564 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1537 | 1565 | }; |
| 1538 | 1566 | |
| 1539 | 1567 | template <class _CharT> |
| ... | ... | @@ -1559,7 +1587,7 @@ public: |
| 1559 | 1587 | explicit __empty_non_own_state(__node<_CharT>* __s) |
| 1560 | 1588 | : base(__s) {} |
| 1561 | 1589 | |
| 1562 | virtual void __exec(__state&) const; | |
| 1590 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1563 | 1591 | }; |
| 1564 | 1592 | |
| 1565 | 1593 | template <class _CharT> |
| ... | ... | @@ -1585,7 +1613,7 @@ public: |
| 1585 | 1613 | explicit __repeat_one_loop(__node<_CharT>* __s) |
| 1586 | 1614 | : base(__s) {} |
| 1587 | 1615 | |
| 1588 | virtual void __exec(__state&) const; | |
| 1616 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1589 | 1617 | }; |
| 1590 | 1618 | |
| 1591 | 1619 | template <class _CharT> |
| ... | ... | @@ -1611,7 +1639,7 @@ public: |
| 1611 | 1639 | explicit __owns_two_states(__node<_CharT>* __s1, base* __s2) |
| 1612 | 1640 | : base(__s1), __second_(__s2) {} |
| 1613 | 1641 | |
| 1614 | virtual ~__owns_two_states(); | |
| 1642 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__owns_two_states(); | |
| 1615 | 1643 | |
| 1616 | 1644 | _LIBCPP_INLINE_VISIBILITY |
| 1617 | 1645 | base* second() const {return __second_;} |
| ... | ... | @@ -1654,8 +1682,8 @@ public: |
| 1654 | 1682 | __mexp_begin_(__mexp_begin), __mexp_end_(__mexp_end), |
| 1655 | 1683 | __greedy_(__greedy) {} |
| 1656 | 1684 | |
| 1657 | virtual void __exec(__state& __s) const; | |
| 1658 | virtual void __exec_split(bool __second, __state& __s) const; | |
| 1685 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const; | |
| 1686 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const; | |
| 1659 | 1687 | |
| 1660 | 1688 | private: |
| 1661 | 1689 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1747,8 +1775,8 @@ public: |
| 1747 | 1775 | __owns_one_state<_CharT>* __s2) |
| 1748 | 1776 | : base(__s1, __s2) {} |
| 1749 | 1777 | |
| 1750 | virtual void __exec(__state& __s) const; | |
| 1751 | virtual void __exec_split(bool __second, __state& __s) const; | |
| 1778 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state& __s) const; | |
| 1779 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec_split(bool __second, __state& __s) const; | |
| 1752 | 1780 | }; |
| 1753 | 1781 | |
| 1754 | 1782 | template <class _CharT> |
| ... | ... | @@ -1785,7 +1813,7 @@ public: |
| 1785 | 1813 | explicit __begin_marked_subexpression(unsigned __mexp, __node<_CharT>* __s) |
| 1786 | 1814 | : base(__s), __mexp_(__mexp) {} |
| 1787 | 1815 | |
| 1788 | virtual void __exec(__state&) const; | |
| 1816 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1789 | 1817 | }; |
| 1790 | 1818 | |
| 1791 | 1819 | template <class _CharT> |
| ... | ... | @@ -1813,7 +1841,7 @@ public: |
| 1813 | 1841 | explicit __end_marked_subexpression(unsigned __mexp, __node<_CharT>* __s) |
| 1814 | 1842 | : base(__s), __mexp_(__mexp) {} |
| 1815 | 1843 | |
| 1816 | virtual void __exec(__state&) const; | |
| 1844 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1817 | 1845 | }; |
| 1818 | 1846 | |
| 1819 | 1847 | template <class _CharT> |
| ... | ... | @@ -1842,7 +1870,7 @@ public: |
| 1842 | 1870 | explicit __back_ref(unsigned __mexp, __node<_CharT>* __s) |
| 1843 | 1871 | : base(__s), __mexp_(__mexp) {} |
| 1844 | 1872 | |
| 1845 | virtual void __exec(__state&) const; | |
| 1873 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1846 | 1874 | }; |
| 1847 | 1875 | |
| 1848 | 1876 | template <class _CharT> |
| ... | ... | @@ -1893,7 +1921,7 @@ public: |
| 1893 | 1921 | __node<_CharT>* __s) |
| 1894 | 1922 | : base(__s), __traits_(__traits), __mexp_(__mexp) {} |
| 1895 | 1923 | |
| 1896 | virtual void __exec(__state&) const; | |
| 1924 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1897 | 1925 | }; |
| 1898 | 1926 | |
| 1899 | 1927 | template <class _CharT, class _Traits> |
| ... | ... | @@ -1948,7 +1976,7 @@ public: |
| 1948 | 1976 | __node<_CharT>* __s) |
| 1949 | 1977 | : base(__s), __traits_(__traits), __mexp_(__mexp) {} |
| 1950 | 1978 | |
| 1951 | virtual void __exec(__state&) const; | |
| 1979 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 1952 | 1980 | }; |
| 1953 | 1981 | |
| 1954 | 1982 | template <class _CharT, class _Traits> |
| ... | ... | @@ -2003,7 +2031,7 @@ public: |
| 2003 | 2031 | __node<_CharT>* __s) |
| 2004 | 2032 | : base(__s), __traits_(__traits), __invert_(__invert) {} |
| 2005 | 2033 | |
| 2006 | virtual void __exec(__state&) const; | |
| 2034 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2007 | 2035 | }; |
| 2008 | 2036 | |
| 2009 | 2037 | template <class _CharT, class _Traits> |
| ... | ... | @@ -2079,7 +2107,7 @@ public: |
| 2079 | 2107 | __l_anchor_multiline(bool __multiline, __node<_CharT>* __s) |
| 2080 | 2108 | : base(__s), __multiline_(__multiline) {} |
| 2081 | 2109 | |
| 2082 | virtual void __exec(__state&) const; | |
| 2110 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2083 | 2111 | }; |
| 2084 | 2112 | |
| 2085 | 2113 | template <class _CharT> |
| ... | ... | @@ -2123,7 +2151,7 @@ public: |
| 2123 | 2151 | __r_anchor_multiline(bool __multiline, __node<_CharT>* __s) |
| 2124 | 2152 | : base(__s), __multiline_(__multiline) {} |
| 2125 | 2153 | |
| 2126 | virtual void __exec(__state&) const; | |
| 2154 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2127 | 2155 | }; |
| 2128 | 2156 | |
| 2129 | 2157 | template <class _CharT> |
| ... | ... | @@ -2163,7 +2191,7 @@ public: |
| 2163 | 2191 | __match_any(__node<_CharT>* __s) |
| 2164 | 2192 | : base(__s) {} |
| 2165 | 2193 | |
| 2166 | virtual void __exec(__state&) const; | |
| 2194 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2167 | 2195 | }; |
| 2168 | 2196 | |
| 2169 | 2197 | template <class _CharT> |
| ... | ... | @@ -2201,9 +2229,9 @@ public: |
| 2201 | 2229 | void __exec(__state&) const override; |
| 2202 | 2230 | }; |
| 2203 | 2231 | |
| 2204 | template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<char>::__exec(__state&) const; | |
| 2232 | template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<char>::__exec(__state&) const; | |
| 2205 | 2233 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 2206 | template <> _LIBCPP_FUNC_VIS void __match_any_but_newline<wchar_t>::__exec(__state&) const; | |
| 2234 | template <> _LIBCPP_EXPORTED_FROM_ABI void __match_any_but_newline<wchar_t>::__exec(__state&) const; | |
| 2207 | 2235 | #endif |
| 2208 | 2236 | |
| 2209 | 2237 | // __match_char |
| ... | ... | @@ -2225,7 +2253,7 @@ public: |
| 2225 | 2253 | __match_char(_CharT __c, __node<_CharT>* __s) |
| 2226 | 2254 | : base(__s), __c_(__c) {} |
| 2227 | 2255 | |
| 2228 | virtual void __exec(__state&) const; | |
| 2256 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2229 | 2257 | }; |
| 2230 | 2258 | |
| 2231 | 2259 | template <class _CharT> |
| ... | ... | @@ -2265,7 +2293,7 @@ public: |
| 2265 | 2293 | __match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s) |
| 2266 | 2294 | : base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {} |
| 2267 | 2295 | |
| 2268 | virtual void __exec(__state&) const; | |
| 2296 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2269 | 2297 | }; |
| 2270 | 2298 | |
| 2271 | 2299 | template <class _CharT, class _Traits> |
| ... | ... | @@ -2306,7 +2334,7 @@ public: |
| 2306 | 2334 | __match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s) |
| 2307 | 2335 | : base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {} |
| 2308 | 2336 | |
| 2309 | virtual void __exec(__state&) const; | |
| 2337 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2310 | 2338 | }; |
| 2311 | 2339 | |
| 2312 | 2340 | template <class _CharT, class _Traits> |
| ... | ... | @@ -2361,7 +2389,7 @@ public: |
| 2361 | 2389 | __negate_(__negate), __icase_(__icase), __collate_(__collate), |
| 2362 | 2390 | __might_have_digraph_(__traits_.getloc().name() != "C") {} |
| 2363 | 2391 | |
| 2364 | virtual void __exec(__state&) const; | |
| 2392 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 2365 | 2393 | |
| 2366 | 2394 | _LIBCPP_INLINE_VISIBILITY |
| 2367 | 2395 | bool __negated() const {return __negate_;} |
| ... | ... | @@ -2750,7 +2778,7 @@ public: |
| 2750 | 2778 | |
| 2751 | 2779 | template <class _InputIterator> |
| 2752 | 2780 | _LIBCPP_INLINE_VISIBILITY |
| 2753 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value, basic_regex&>::type | |
| 2781 | typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value, basic_regex&>::type | |
| 2754 | 2782 | assign(_InputIterator __first, _InputIterator __last, |
| 2755 | 2783 | flag_type __f = regex_constants::ECMAScript) |
| 2756 | 2784 | { |
| ... | ... | @@ -2774,7 +2802,7 @@ public: |
| 2774 | 2802 | _LIBCPP_INLINE_VISIBILITY |
| 2775 | 2803 | typename enable_if |
| 2776 | 2804 | < |
| 2777 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2805 | __has_forward_iterator_category<_ForwardIterator>::value, | |
| 2778 | 2806 | basic_regex& |
| 2779 | 2807 | >::type |
| 2780 | 2808 | assign(_ForwardIterator __first, _ForwardIterator __last, |
| ... | ... | @@ -3082,7 +3110,7 @@ private: |
| 3082 | 3110 | |
| 3083 | 3111 | #if _LIBCPP_STD_VER >= 17 |
| 3084 | 3112 | template <class _ForwardIterator, |
| 3085 | class = typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value, nullptr_t>::type | |
| 3113 | class = typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value, nullptr_t>::type | |
| 3086 | 3114 | > |
| 3087 | 3115 | basic_regex(_ForwardIterator, _ForwardIterator, |
| 3088 | 3116 | regex_constants::syntax_option_type = regex_constants::ECMAScript) |
| ... | ... | @@ -3153,7 +3181,7 @@ public: |
| 3153 | 3181 | __lookahead(const basic_regex<_CharT, _Traits>& __exp, bool __invert, __node<_CharT>* __s, unsigned __mexp) |
| 3154 | 3182 | : base(__s), __exp_(__exp), __mexp_(__mexp), __invert_(__invert) {} |
| 3155 | 3183 | |
| 3156 | virtual void __exec(__state&) const; | |
| 3184 | _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __exec(__state&) const; | |
| 3157 | 3185 | }; |
| 3158 | 3186 | |
| 3159 | 3187 | template <class _CharT, class _Traits> |
| ... | ... | @@ -4131,9 +4159,9 @@ basic_regex<_CharT, _Traits>::__parse_equivalence_class(_ForwardIterator __first |
| 4131 | 4159 | { |
| 4132 | 4160 | // Found [= |
| 4133 | 4161 | // This means =] must exist |
| 4134 | value_type _Equal_close[2] = {'=', ']'}; | |
| 4135 | _ForwardIterator __temp = _VSTD::search(__first, __last, _Equal_close, | |
| 4136 | _Equal_close+2); | |
| 4162 | value_type __equal_close[2] = {'=', ']'}; | |
| 4163 | _ForwardIterator __temp = _VSTD::search(__first, __last, __equal_close, | |
| 4164 | __equal_close+2); | |
| 4137 | 4165 | if (__temp == __last) |
| 4138 | 4166 | __throw_regex_error<regex_constants::error_brack>(); |
| 4139 | 4167 | // [__first, __temp) contains all text in [= ... =] |
| ... | ... | @@ -4173,9 +4201,9 @@ basic_regex<_CharT, _Traits>::__parse_character_class(_ForwardIterator __first, |
| 4173 | 4201 | { |
| 4174 | 4202 | // Found [: |
| 4175 | 4203 | // This means :] must exist |
| 4176 | value_type _Colon_close[2] = {':', ']'}; | |
| 4177 | _ForwardIterator __temp = _VSTD::search(__first, __last, _Colon_close, | |
| 4178 | _Colon_close+2); | |
| 4204 | value_type __colon_close[2] = {':', ']'}; | |
| 4205 | _ForwardIterator __temp = _VSTD::search(__first, __last, __colon_close, | |
| 4206 | __colon_close+2); | |
| 4179 | 4207 | if (__temp == __last) |
| 4180 | 4208 | __throw_regex_error<regex_constants::error_brack>(); |
| 4181 | 4209 | // [__first, __temp) contains all text in [: ... :] |
| ... | ... | @@ -4198,9 +4226,9 @@ basic_regex<_CharT, _Traits>::__parse_collating_symbol(_ForwardIterator __first, |
| 4198 | 4226 | { |
| 4199 | 4227 | // Found [. |
| 4200 | 4228 | // This means .] must exist |
| 4201 | value_type _Dot_close[2] = {'.', ']'}; | |
| 4202 | _ForwardIterator __temp = _VSTD::search(__first, __last, _Dot_close, | |
| 4203 | _Dot_close+2); | |
| 4229 | value_type __dot_close[2] = {'.', ']'}; | |
| 4230 | _ForwardIterator __temp = _VSTD::search(__first, __last, __dot_close, | |
| 4231 | __dot_close+2); | |
| 4204 | 4232 | if (__temp == __last) |
| 4205 | 4233 | __throw_regex_error<regex_constants::error_brack>(); |
| 4206 | 4234 | // [__first, __temp) contains all text in [. ... .] |
| ... | ... | @@ -5009,6 +5037,16 @@ public: |
| 5009 | 5037 | _LIBCPP_INLINE_VISIBILITY |
| 5010 | 5038 | int compare(const value_type* __s) const |
| 5011 | 5039 | {return str().compare(__s);} |
| 5040 | ||
| 5041 | _LIBCPP_HIDE_FROM_ABI | |
| 5042 | void swap(sub_match& __s) | |
| 5043 | #ifndef _LIBCPP_CXX03_LANG | |
| 5044 | _NOEXCEPT(__is_nothrow_swappable<_BidirectionalIterator>::value) | |
| 5045 | #endif // _LIBCPP_CXX03_LANG | |
| 5046 | { | |
| 5047 | this->pair<_BidirectionalIterator, _BidirectionalIterator>::swap(__s); | |
| 5048 | std::swap(matched, __s.matched); | |
| 5049 | } | |
| 5012 | 5050 | }; |
| 5013 | 5051 | |
| 5014 | 5052 | template <class _BiIter> |
| ... | ... | @@ -5019,6 +5057,15 @@ operator==(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) |
| 5019 | 5057 | return __x.compare(__y) == 0; |
| 5020 | 5058 | } |
| 5021 | 5059 | |
| 5060 | #if _LIBCPP_STD_VER >= 20 | |
| 5061 | template<class _BiIter> | |
| 5062 | using __sub_match_cat = compare_three_way_result_t<basic_string<typename iterator_traits<_BiIter>::value_type>>; | |
| 5063 | ||
| 5064 | template <class _BiIter> | |
| 5065 | _LIBCPP_HIDE_FROM_ABI auto operator<=>(const sub_match<_BiIter>& __x, const sub_match<_BiIter>& __y) { | |
| 5066 | return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0); | |
| 5067 | } | |
| 5068 | #else // _LIBCPP_STD_VER >= 20 | |
| 5022 | 5069 | template <class _BiIter> |
| 5023 | 5070 | inline _LIBCPP_INLINE_VISIBILITY |
| 5024 | 5071 | bool |
| ... | ... | @@ -5111,6 +5158,7 @@ operator<=(const basic_string<typename iterator_traits<_BiIter>::value_type, _ST |
| 5111 | 5158 | { |
| 5112 | 5159 | return !(__y < __x); |
| 5113 | 5160 | } |
| 5161 | #endif // _LIBCPP_STD_VER >= 20 | |
| 5114 | 5162 | |
| 5115 | 5163 | template <class _BiIter, class _ST, class _SA> |
| 5116 | 5164 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -5121,6 +5169,14 @@ operator==(const sub_match<_BiIter>& __x, |
| 5121 | 5169 | return __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) == 0; |
| 5122 | 5170 | } |
| 5123 | 5171 | |
| 5172 | #if _LIBCPP_STD_VER >= 20 | |
| 5173 | template <class _BiIter, class _ST, class _SA> | |
| 5174 | _LIBCPP_HIDE_FROM_ABI auto operator<=>( | |
| 5175 | const sub_match<_BiIter>& __x, const basic_string<typename iterator_traits<_BiIter>::value_type, _ST, _SA>& __y) { | |
| 5176 | return static_cast<__sub_match_cat<_BiIter>>( | |
| 5177 | __x.compare(typename sub_match<_BiIter>::string_type(__y.data(), __y.size())) <=> 0); | |
| 5178 | } | |
| 5179 | #else // _LIBCPP_STD_VER >= 20 | |
| 5124 | 5180 | template <class _BiIter, class _ST, class _SA> |
| 5125 | 5181 | inline _LIBCPP_INLINE_VISIBILITY |
| 5126 | 5182 | bool |
| ... | ... | @@ -5218,6 +5274,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const* __x, |
| 5218 | 5274 | { |
| 5219 | 5275 | return !(__y < __x); |
| 5220 | 5276 | } |
| 5277 | #endif // _LIBCPP_STD_VER >= 20 | |
| 5221 | 5278 | |
| 5222 | 5279 | template <class _BiIter> |
| 5223 | 5280 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -5228,6 +5285,13 @@ operator==(const sub_match<_BiIter>& __x, |
| 5228 | 5285 | return __x.compare(__y) == 0; |
| 5229 | 5286 | } |
| 5230 | 5287 | |
| 5288 | #if _LIBCPP_STD_VER >= 20 | |
| 5289 | template <class _BiIter> | |
| 5290 | _LIBCPP_HIDE_FROM_ABI auto | |
| 5291 | operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const* __y) { | |
| 5292 | return static_cast<__sub_match_cat<_BiIter>>(__x.compare(__y) <=> 0); | |
| 5293 | } | |
| 5294 | #else // _LIBCPP_STD_VER >= 20 | |
| 5231 | 5295 | template <class _BiIter> |
| 5232 | 5296 | inline _LIBCPP_INLINE_VISIBILITY |
| 5233 | 5297 | bool |
| ... | ... | @@ -5328,6 +5392,7 @@ operator<=(typename iterator_traits<_BiIter>::value_type const& __x, |
| 5328 | 5392 | { |
| 5329 | 5393 | return !(__y < __x); |
| 5330 | 5394 | } |
| 5395 | #endif // _LIBCPP_STD_VER >= 20 | |
| 5331 | 5396 | |
| 5332 | 5397 | template <class _BiIter> |
| 5333 | 5398 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -5339,6 +5404,14 @@ operator==(const sub_match<_BiIter>& __x, |
| 5339 | 5404 | return __x.compare(string_type(1, __y)) == 0; |
| 5340 | 5405 | } |
| 5341 | 5406 | |
| 5407 | #if _LIBCPP_STD_VER >= 20 | |
| 5408 | template <class _BiIter> | |
| 5409 | _LIBCPP_HIDE_FROM_ABI auto | |
| 5410 | operator<=>(const sub_match<_BiIter>& __x, typename iterator_traits<_BiIter>::value_type const& __y) { | |
| 5411 | using string_type = basic_string<typename iterator_traits<_BiIter>::value_type>; | |
| 5412 | return static_cast<__sub_match_cat<_BiIter>>(__x.compare(string_type(1, __y)) <=> 0); | |
| 5413 | } | |
| 5414 | #else // _LIBCPP_STD_VER >= 20 | |
| 5342 | 5415 | template <class _BiIter> |
| 5343 | 5416 | inline _LIBCPP_INLINE_VISIBILITY |
| 5344 | 5417 | bool |
| ... | ... | @@ -5384,6 +5457,7 @@ operator<=(const sub_match<_BiIter>& __x, |
| 5384 | 5457 | { |
| 5385 | 5458 | return !(__y < __x); |
| 5386 | 5459 | } |
| 5460 | #endif // _LIBCPP_STD_VER >= 20 | |
| 5387 | 5461 | |
| 5388 | 5462 | template <class _CharT, class _ST, class _BiIter> |
| 5389 | 5463 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -5460,38 +5534,38 @@ public: |
| 5460 | 5534 | _LIBCPP_INLINE_VISIBILITY |
| 5461 | 5535 | difference_type length(size_type __sub = 0) const |
| 5462 | 5536 | { |
| 5463 | _LIBCPP_ASSERT(ready(), "match_results::length() called when not ready"); | |
| 5537 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::length() called when not ready"); | |
| 5464 | 5538 | return (*this)[__sub].length(); |
| 5465 | 5539 | } |
| 5466 | 5540 | _LIBCPP_INLINE_VISIBILITY |
| 5467 | 5541 | difference_type position(size_type __sub = 0) const |
| 5468 | 5542 | { |
| 5469 | _LIBCPP_ASSERT(ready(), "match_results::position() called when not ready"); | |
| 5543 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::position() called when not ready"); | |
| 5470 | 5544 | return _VSTD::distance(__position_start_, (*this)[__sub].first); |
| 5471 | 5545 | } |
| 5472 | 5546 | _LIBCPP_INLINE_VISIBILITY |
| 5473 | 5547 | string_type str(size_type __sub = 0) const |
| 5474 | 5548 | { |
| 5475 | _LIBCPP_ASSERT(ready(), "match_results::str() called when not ready"); | |
| 5549 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::str() called when not ready"); | |
| 5476 | 5550 | return (*this)[__sub].str(); |
| 5477 | 5551 | } |
| 5478 | 5552 | _LIBCPP_INLINE_VISIBILITY |
| 5479 | 5553 | const_reference operator[](size_type __n) const |
| 5480 | 5554 | { |
| 5481 | _LIBCPP_ASSERT(ready(), "match_results::operator[]() called when not ready"); | |
| 5555 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::operator[]() called when not ready"); | |
| 5482 | 5556 | return __n < __matches_.size() ? __matches_[__n] : __unmatched_; |
| 5483 | 5557 | } |
| 5484 | 5558 | |
| 5485 | 5559 | _LIBCPP_INLINE_VISIBILITY |
| 5486 | 5560 | const_reference prefix() const |
| 5487 | 5561 | { |
| 5488 | _LIBCPP_ASSERT(ready(), "match_results::prefix() called when not ready"); | |
| 5562 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::prefix() called when not ready"); | |
| 5489 | 5563 | return __prefix_; |
| 5490 | 5564 | } |
| 5491 | 5565 | _LIBCPP_INLINE_VISIBILITY |
| 5492 | 5566 | const_reference suffix() const |
| 5493 | 5567 | { |
| 5494 | _LIBCPP_ASSERT(ready(), "match_results::suffix() called when not ready"); | |
| 5568 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::suffix() called when not ready"); | |
| 5495 | 5569 | return __suffix_; |
| 5496 | 5570 | } |
| 5497 | 5571 | |
| ... | ... | @@ -5631,7 +5705,7 @@ match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output_i |
| 5631 | 5705 | const char_type* __fmt_first, const char_type* __fmt_last, |
| 5632 | 5706 | regex_constants::match_flag_type __flags) const |
| 5633 | 5707 | { |
| 5634 | _LIBCPP_ASSERT(ready(), "match_results::format() called when not ready"); | |
| 5708 | _LIBCPP_ASSERT_UNCATEGORIZED(ready(), "match_results::format() called when not ready"); | |
| 5635 | 5709 | if (__flags & regex_constants::format_sed) |
| 5636 | 5710 | { |
| 5637 | 5711 | for (; __fmt_first != __fmt_last; ++__fmt_first) |
| ... | ... | @@ -5747,6 +5821,7 @@ operator==(const match_results<_BidirectionalIterator, _Allocator>& __x, |
| 5747 | 5821 | __x.__suffix_ == __y.__suffix_; |
| 5748 | 5822 | } |
| 5749 | 5823 | |
| 5824 | #if _LIBCPP_STD_VER < 20 | |
| 5750 | 5825 | template <class _BidirectionalIterator, class _Allocator> |
| 5751 | 5826 | inline _LIBCPP_INLINE_VISIBILITY |
| 5752 | 5827 | bool |
| ... | ... | @@ -5755,6 +5830,7 @@ operator!=(const match_results<_BidirectionalIterator, _Allocator>& __x, |
| 5755 | 5830 | { |
| 5756 | 5831 | return !(__x == __y); |
| 5757 | 5832 | } |
| 5833 | #endif | |
| 5758 | 5834 | |
| 5759 | 5835 | template <class _BidirectionalIterator, class _Allocator> |
| 5760 | 5836 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -5861,7 +5937,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs( |
| 5861 | 5937 | { |
| 5862 | 5938 | deque<__state> __states; |
| 5863 | 5939 | ptrdiff_t __highest_j = 0; |
| 5864 | ptrdiff_t _Np = _VSTD::distance(__first, __last); | |
| 5940 | ptrdiff_t __np = _VSTD::distance(__first, __last); | |
| 5865 | 5941 | __node* __st = __start_.get(); |
| 5866 | 5942 | if (__st) |
| 5867 | 5943 | { |
| ... | ... | @@ -5904,7 +5980,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs( |
| 5904 | 5980 | if (!__matched || __highest_j < __s.__current_ - __s.__first_) |
| 5905 | 5981 | __highest_j = __s.__current_ - __s.__first_; |
| 5906 | 5982 | __matched = true; |
| 5907 | if (__highest_j == _Np) | |
| 5983 | if (__highest_j == __np) | |
| 5908 | 5984 | __states.clear(); |
| 5909 | 5985 | else |
| 5910 | 5986 | __states.pop_back(); |
| ... | ... | @@ -5956,7 +6032,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs( |
| 5956 | 6032 | vector<__state> __states; |
| 5957 | 6033 | __state __best_state; |
| 5958 | 6034 | ptrdiff_t __highest_j = 0; |
| 5959 | ptrdiff_t _Np = _VSTD::distance(__first, __last); | |
| 6035 | ptrdiff_t __np = _VSTD::distance(__first, __last); | |
| 5960 | 6036 | __node* __st = __start_.get(); |
| 5961 | 6037 | if (__st) |
| 5962 | 6038 | { |
| ... | ... | @@ -6008,7 +6084,7 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs( |
| 6008 | 6084 | __best_state = __s; |
| 6009 | 6085 | } |
| 6010 | 6086 | __matched = true; |
| 6011 | if (__highest_j == _Np) | |
| 6087 | if (__highest_j == __np) | |
| 6012 | 6088 | __states.clear(); |
| 6013 | 6089 | else |
| 6014 | 6090 | __states.pop_back(); |
| ... | ... | @@ -6214,7 +6290,7 @@ regex_search(const basic_string<_CharT, _ST, _SA>& __s, |
| 6214 | 6290 | return __r; |
| 6215 | 6291 | } |
| 6216 | 6292 | |
| 6217 | #if _LIBCPP_STD_VER > 11 | |
| 6293 | #if _LIBCPP_STD_VER >= 14 | |
| 6218 | 6294 | template <class _ST, class _SA, class _Ap, class _Cp, class _Tp> |
| 6219 | 6295 | bool |
| 6220 | 6296 | regex_search(const basic_string<_Cp, _ST, _SA>&& __s, |
| ... | ... | @@ -6277,7 +6353,7 @@ regex_match(const basic_string<_CharT, _ST, _SA>& __s, |
| 6277 | 6353 | return _VSTD::regex_match(__s.begin(), __s.end(), __m, __e, __flags); |
| 6278 | 6354 | } |
| 6279 | 6355 | |
| 6280 | #if _LIBCPP_STD_VER > 11 | |
| 6356 | #if _LIBCPP_STD_VER >= 14 | |
| 6281 | 6357 | template <class _ST, class _SA, class _Allocator, class _CharT, class _Traits> |
| 6282 | 6358 | inline _LIBCPP_INLINE_VISIBILITY |
| 6283 | 6359 | bool |
| ... | ... | @@ -6350,16 +6426,21 @@ public: |
| 6350 | 6426 | const regex_type& __re, |
| 6351 | 6427 | regex_constants::match_flag_type __m |
| 6352 | 6428 | = regex_constants::match_default); |
| 6353 | #if _LIBCPP_STD_VER > 11 | |
| 6429 | #if _LIBCPP_STD_VER >= 14 | |
| 6354 | 6430 | regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, |
| 6355 | 6431 | const regex_type&& __re, |
| 6356 | 6432 | regex_constants::match_flag_type __m |
| 6357 | 6433 | = regex_constants::match_default) = delete; |
| 6358 | 6434 | #endif |
| 6359 | 6435 | |
| 6360 | bool operator==(const regex_iterator& __x) const; | |
| 6436 | _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_iterator& __x) const; | |
| 6437 | #if _LIBCPP_STD_VER >= 20 | |
| 6438 | _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { return *this == regex_iterator(); } | |
| 6439 | #endif | |
| 6440 | #if _LIBCPP_STD_VER < 20 | |
| 6361 | 6441 | _LIBCPP_INLINE_VISIBILITY |
| 6362 | 6442 | bool operator!=(const regex_iterator& __x) const {return !(*this == __x);} |
| 6443 | #endif | |
| 6363 | 6444 | |
| 6364 | 6445 | _LIBCPP_INLINE_VISIBILITY |
| 6365 | 6446 | reference operator*() const {return __match_;} |
| ... | ... | @@ -6482,7 +6563,7 @@ public: |
| 6482 | 6563 | const regex_type& __re, int __submatch = 0, |
| 6483 | 6564 | regex_constants::match_flag_type __m = |
| 6484 | 6565 | regex_constants::match_default); |
| 6485 | #if _LIBCPP_STD_VER > 11 | |
| 6566 | #if _LIBCPP_STD_VER >= 14 | |
| 6486 | 6567 | regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, |
| 6487 | 6568 | const regex_type&& __re, int __submatch = 0, |
| 6488 | 6569 | regex_constants::match_flag_type __m = |
| ... | ... | @@ -6493,7 +6574,7 @@ public: |
| 6493 | 6574 | const regex_type& __re, const vector<int>& __submatches, |
| 6494 | 6575 | regex_constants::match_flag_type __m = |
| 6495 | 6576 | regex_constants::match_default); |
| 6496 | #if _LIBCPP_STD_VER > 11 | |
| 6577 | #if _LIBCPP_STD_VER >= 14 | |
| 6497 | 6578 | regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, |
| 6498 | 6579 | const regex_type&& __re, const vector<int>& __submatches, |
| 6499 | 6580 | regex_constants::match_flag_type __m = |
| ... | ... | @@ -6507,7 +6588,7 @@ public: |
| 6507 | 6588 | regex_constants::match_flag_type __m = |
| 6508 | 6589 | regex_constants::match_default); |
| 6509 | 6590 | |
| 6510 | #if _LIBCPP_STD_VER > 11 | |
| 6591 | #if _LIBCPP_STD_VER >= 14 | |
| 6511 | 6592 | regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b, |
| 6512 | 6593 | const regex_type&& __re, |
| 6513 | 6594 | initializer_list<int> __submatches, |
| ... | ... | @@ -6522,7 +6603,7 @@ public: |
| 6522 | 6603 | const int (&__submatches)[_Np], |
| 6523 | 6604 | regex_constants::match_flag_type __m = |
| 6524 | 6605 | regex_constants::match_default); |
| 6525 | #if _LIBCPP_STD_VER > 11 | |
| 6606 | #if _LIBCPP_STD_VER >= 14 | |
| 6526 | 6607 | template <size_t _Np> |
| 6527 | 6608 | regex_token_iterator(_BidirectionalIterator __a, |
| 6528 | 6609 | _BidirectionalIterator __b, |
| ... | ... | @@ -6535,9 +6616,16 @@ public: |
| 6535 | 6616 | regex_token_iterator(const regex_token_iterator&); |
| 6536 | 6617 | regex_token_iterator& operator=(const regex_token_iterator&); |
| 6537 | 6618 | |
| 6538 | bool operator==(const regex_token_iterator& __x) const; | |
| 6619 | _LIBCPP_HIDE_FROM_ABI bool operator==(const regex_token_iterator& __x) const; | |
| 6620 | #if _LIBCPP_STD_VER >= 20 | |
| 6621 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const { | |
| 6622 | return *this == regex_token_iterator(); | |
| 6623 | } | |
| 6624 | #endif | |
| 6625 | #if _LIBCPP_STD_VER < 20 | |
| 6539 | 6626 | _LIBCPP_INLINE_VISIBILITY |
| 6540 | 6627 | bool operator!=(const regex_token_iterator& __x) const {return !(*this == __x);} |
| 6628 | #endif | |
| 6541 | 6629 | |
| 6542 | 6630 | _LIBCPP_INLINE_VISIBILITY |
| 6543 | 6631 | const value_type& operator*() const {return *__result_;} |
| ... | ... | @@ -6844,18 +6932,18 @@ regex_replace(const _CharT* __s, |
| 6844 | 6932 | |
| 6845 | 6933 | _LIBCPP_END_NAMESPACE_STD |
| 6846 | 6934 | |
| 6847 | #if _LIBCPP_STD_VER > 14 | |
| 6935 | #if _LIBCPP_STD_VER >= 17 | |
| 6848 | 6936 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 6849 | 6937 | namespace pmr { |
| 6850 | 6938 | template <class _BidirT> |
| 6851 | using match_results = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>; | |
| 6939 | using match_results _LIBCPP_AVAILABILITY_PMR = std::match_results<_BidirT, polymorphic_allocator<std::sub_match<_BidirT>>>; | |
| 6852 | 6940 | |
| 6853 | using cmatch = match_results<const char*>; | |
| 6854 | using smatch = match_results<std::pmr::string::const_iterator>; | |
| 6941 | using cmatch _LIBCPP_AVAILABILITY_PMR = match_results<const char*>; | |
| 6942 | using smatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::string::const_iterator>; | |
| 6855 | 6943 | |
| 6856 | 6944 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 6857 | using wcmatch = match_results<const wchar_t*>; | |
| 6858 | using wsmatch = match_results<std::pmr::wstring::const_iterator>; | |
| 6945 | using wcmatch _LIBCPP_AVAILABILITY_PMR = match_results<const wchar_t*>; | |
| 6946 | using wsmatch _LIBCPP_AVAILABILITY_PMR = match_results<std::pmr::wstring::const_iterator>; | |
| 6859 | 6947 | #endif |
| 6860 | 6948 | } // namespace pmr |
| 6861 | 6949 | _LIBCPP_END_NAMESPACE_STD |
| ... | ... | @@ -6866,9 +6954,11 @@ _LIBCPP_POP_MACROS |
| 6866 | 6954 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 6867 | 6955 | # include <atomic> |
| 6868 | 6956 | # include <concepts> |
| 6957 | # include <cstdlib> | |
| 6869 | 6958 | # include <iosfwd> |
| 6870 | 6959 | # include <iterator> |
| 6871 | 6960 | # include <new> |
| 6961 | # include <type_traits> | |
| 6872 | 6962 | # include <typeinfo> |
| 6873 | 6963 | # include <utility> |
| 6874 | 6964 | #endif |
lib/libcxx/include/scoped_allocator+16-7| ... | ... | @@ -103,7 +103,7 @@ template <class OuterA1, class OuterA2, class... InnerAllocs> |
| 103 | 103 | template <class OuterA1, class OuterA2, class... InnerAllocs> |
| 104 | 104 | bool |
| 105 | 105 | operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, |
| 106 | const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; | |
| 106 | const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20 | |
| 107 | 107 | |
| 108 | 108 | } // std |
| 109 | 109 | |
| ... | ... | @@ -130,6 +130,9 @@ template <class OuterA1, class OuterA2, class... InnerAllocs> |
| 130 | 130 | # pragma GCC system_header |
| 131 | 131 | #endif |
| 132 | 132 | |
| 133 | _LIBCPP_PUSH_MACROS | |
| 134 | #include <__undef_macros> | |
| 135 | ||
| 133 | 136 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 134 | 137 | |
| 135 | 138 | #if !defined(_LIBCPP_CXX03_LANG) |
| ... | ... | @@ -531,7 +534,7 @@ public: |
| 531 | 534 | __p, _VSTD::forward<_Args>(__args)...);} |
| 532 | 535 | |
| 533 | 536 | template <class _T1, class _T2, class... _Args1, class... _Args2> |
| 534 | void construct(pair<_T1, _T2>* __p, piecewise_construct_t, | |
| 537 | _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, piecewise_construct_t, | |
| 535 | 538 | tuple<_Args1...> __x, tuple<_Args2...> __y) |
| 536 | 539 | { |
| 537 | 540 | typedef __outermost<outer_allocator_type> _OM; |
| ... | ... | @@ -555,25 +558,25 @@ public: |
| 555 | 558 | } |
| 556 | 559 | |
| 557 | 560 | template <class _T1, class _T2> |
| 558 | void construct(pair<_T1, _T2>* __p) | |
| 561 | _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p) | |
| 559 | 562 | { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); } |
| 560 | 563 | |
| 561 | 564 | template <class _T1, class _T2, class _Up, class _Vp> |
| 562 | void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { | |
| 565 | _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { | |
| 563 | 566 | construct(__p, piecewise_construct, |
| 564 | 567 | _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)), |
| 565 | 568 | _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y))); |
| 566 | 569 | } |
| 567 | 570 | |
| 568 | 571 | template <class _T1, class _T2, class _Up, class _Vp> |
| 569 | void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { | |
| 572 | _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { | |
| 570 | 573 | construct(__p, piecewise_construct, |
| 571 | 574 | _VSTD::forward_as_tuple(__x.first), |
| 572 | 575 | _VSTD::forward_as_tuple(__x.second)); |
| 573 | 576 | } |
| 574 | 577 | |
| 575 | 578 | template <class _T1, class _T2, class _Up, class _Vp> |
| 576 | void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { | |
| 579 | _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { | |
| 577 | 580 | construct(__p, piecewise_construct, |
| 578 | 581 | _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)), |
| 579 | 582 | _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second))); |
| ... | ... | @@ -678,7 +681,7 @@ private: |
| 678 | 681 | template <class...> friend class __scoped_allocator_storage; |
| 679 | 682 | }; |
| 680 | 683 | |
| 681 | #if _LIBCPP_STD_VER > 14 | |
| 684 | #if _LIBCPP_STD_VER >= 17 | |
| 682 | 685 | template<class _OuterAlloc, class... _InnerAllocs> |
| 683 | 686 | scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) |
| 684 | 687 | -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>; |
| ... | ... | @@ -703,6 +706,8 @@ operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& |
| 703 | 706 | __a.inner_allocator() == __b.inner_allocator(); |
| 704 | 707 | } |
| 705 | 708 | |
| 709 | #if _LIBCPP_STD_VER <= 17 | |
| 710 | ||
| 706 | 711 | template <class _OuterA1, class _OuterA2, class... _InnerAllocs> |
| 707 | 712 | inline _LIBCPP_INLINE_VISIBILITY |
| 708 | 713 | bool |
| ... | ... | @@ -712,10 +717,14 @@ operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, |
| 712 | 717 | return !(__a == __b); |
| 713 | 718 | } |
| 714 | 719 | |
| 720 | #endif // _LIBCPP_STD_VER <= 17 | |
| 721 | ||
| 715 | 722 | #endif // !defined(_LIBCPP_CXX03_LANG) |
| 716 | 723 | |
| 717 | 724 | _LIBCPP_END_NAMESPACE_STD |
| 718 | 725 | |
| 726 | _LIBCPP_POP_MACROS | |
| 727 | ||
| 719 | 728 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 720 | 729 | # include <atomic> |
| 721 | 730 | # include <climits> |
lib/libcxx/include/semaphore+42-17| ... | ... | @@ -46,12 +46,15 @@ using binary_semaphore = counting_semaphore<1>; |
| 46 | 46 | */ |
| 47 | 47 | |
| 48 | 48 | #include <__assert> // all public C++ headers provide the assertion handler |
| 49 | #include <__atomic/atomic_base.h> | |
| 50 | #include <__atomic/atomic_sync.h> | |
| 51 | #include <__atomic/memory_order.h> | |
| 49 | 52 | #include <__availability> |
| 50 | 53 | #include <__chrono/time_point.h> |
| 51 | 54 | #include <__config> |
| 52 | 55 | #include <__thread/timed_backoff_policy.h> |
| 53 | 56 | #include <__threading_support> |
| 54 | #include <atomic> | |
| 57 | #include <cstddef> | |
| 55 | 58 | #include <limits> |
| 56 | 59 | #include <version> |
| 57 | 60 | |
| ... | ... | @@ -78,6 +81,8 @@ functions. It avoids contention against users' own use of those facilities. |
| 78 | 81 | |
| 79 | 82 | */ |
| 80 | 83 | |
| 84 | #define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) | |
| 85 | ||
| 81 | 86 | class __atomic_semaphore_base |
| 82 | 87 | { |
| 83 | 88 | __atomic_base<ptrdiff_t> __a_; |
| ... | ... | @@ -90,9 +95,14 @@ public: |
| 90 | 95 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 91 | 96 | void release(ptrdiff_t __update = 1) |
| 92 | 97 | { |
| 93 | if(0 < __a_.fetch_add(__update, memory_order_release)) | |
| 94 | ; | |
| 95 | else if(__update > 1) | |
| 98 | auto __old = __a_.fetch_add(__update, memory_order_release); | |
| 99 | _LIBCPP_ASSERT_UNCATEGORIZED(__update <= _LIBCPP_SEMAPHORE_MAX - __old, "update is greater than the expected value"); | |
| 100 | ||
| 101 | if (__old > 0) | |
| 102 | { | |
| 103 | // Nothing to do | |
| 104 | } | |
| 105 | else if (__update > 1) | |
| 96 | 106 | __a_.notify_all(); |
| 97 | 107 | else |
| 98 | 108 | __a_.notify_one(); |
| ... | ... | @@ -106,11 +116,11 @@ public: |
| 106 | 116 | }; |
| 107 | 117 | __cxx_atomic_wait(&__a_.__a_, __test_fn); |
| 108 | 118 | } |
| 109 | template <class Rep, class Period> | |
| 119 | template <class _Rep, class _Period> | |
| 110 | 120 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 111 | bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) | |
| 121 | bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) | |
| 112 | 122 | { |
| 113 | if (__rel_time == chrono::duration<Rep, Period>::zero()) | |
| 123 | if (__rel_time == chrono::duration<_Rep, _Period>::zero()) | |
| 114 | 124 | return try_acquire(); |
| 115 | 125 | auto const __test_fn = [this]() { return try_acquire(); }; |
| 116 | 126 | return std::__libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy(), __rel_time); |
| ... | ... | @@ -128,20 +138,30 @@ public: |
| 128 | 138 | } |
| 129 | 139 | }; |
| 130 | 140 | |
| 131 | #define _LIBCPP_SEMAPHORE_MAX (numeric_limits<ptrdiff_t>::max()) | |
| 132 | ||
| 133 | 141 | template<ptrdiff_t __least_max_value = _LIBCPP_SEMAPHORE_MAX> |
| 134 | 142 | class counting_semaphore |
| 135 | 143 | { |
| 136 | 144 | __atomic_semaphore_base __semaphore_; |
| 137 | 145 | |
| 138 | 146 | public: |
| 147 | static_assert(__least_max_value >= 0, "The least maximum value must be a positive number"); | |
| 148 | ||
| 139 | 149 | static constexpr ptrdiff_t max() noexcept { |
| 140 | 150 | return __least_max_value; |
| 141 | 151 | } |
| 142 | 152 | |
| 143 | 153 | _LIBCPP_INLINE_VISIBILITY |
| 144 | constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) { } | |
| 154 | constexpr explicit counting_semaphore(ptrdiff_t __count) : __semaphore_(__count) | |
| 155 | { | |
| 156 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 157 | __count >= 0, | |
| 158 | "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " | |
| 159 | "initialized with a negative value"); | |
| 160 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 161 | __count <= max(), | |
| 162 | "counting_semaphore::counting_semaphore(ptrdiff_t): counting_semaphore cannot be " | |
| 163 | "initialized with a value greater than max()"); | |
| 164 | } | |
| 145 | 165 | ~counting_semaphore() = default; |
| 146 | 166 | |
| 147 | 167 | counting_semaphore(const counting_semaphore&) = delete; |
| ... | ... | @@ -150,6 +170,7 @@ public: |
| 150 | 170 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 151 | 171 | void release(ptrdiff_t __update = 1) |
| 152 | 172 | { |
| 173 | _LIBCPP_ASSERT_UNCATEGORIZED(__update >= 0, "counting_semaphore:release called with a negative value"); | |
| 153 | 174 | __semaphore_.release(__update); |
| 154 | 175 | } |
| 155 | 176 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -157,9 +178,9 @@ public: |
| 157 | 178 | { |
| 158 | 179 | __semaphore_.acquire(); |
| 159 | 180 | } |
| 160 | template<class Rep, class Period> | |
| 181 | template<class _Rep, class _Period> | |
| 161 | 182 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 162 | bool try_acquire_for(chrono::duration<Rep, Period> const& __rel_time) | |
| 183 | bool try_acquire_for(chrono::duration<_Rep, _Period> const& __rel_time) | |
| 163 | 184 | { |
| 164 | 185 | return __semaphore_.try_acquire_for(chrono::duration_cast<chrono::nanoseconds>(__rel_time)); |
| 165 | 186 | } |
| ... | ... | @@ -168,15 +189,15 @@ public: |
| 168 | 189 | { |
| 169 | 190 | return __semaphore_.try_acquire(); |
| 170 | 191 | } |
| 171 | template <class Clock, class Duration> | |
| 192 | template <class _Clock, class _Duration> | |
| 172 | 193 | _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY |
| 173 | bool try_acquire_until(chrono::time_point<Clock, Duration> const& __abs_time) | |
| 194 | bool try_acquire_until(chrono::time_point<_Clock, _Duration> const& __abs_time) | |
| 174 | 195 | { |
| 175 | auto const current = Clock::now(); | |
| 176 | if (current >= __abs_time) | |
| 196 | auto const __current = _Clock::now(); | |
| 197 | if (__current >= __abs_time) | |
| 177 | 198 | return try_acquire(); |
| 178 | 199 | else |
| 179 | return try_acquire_for(__abs_time - current); | |
| 200 | return try_acquire_for(__abs_time - __current); | |
| 180 | 201 | } |
| 181 | 202 | }; |
| 182 | 203 | |
| ... | ... | @@ -188,4 +209,8 @@ _LIBCPP_END_NAMESPACE_STD |
| 188 | 209 | |
| 189 | 210 | _LIBCPP_POP_MACROS |
| 190 | 211 | |
| 212 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 213 | # include <atomic> | |
| 214 | #endif | |
| 215 | ||
| 191 | 216 | #endif //_LIBCPP_SEMAPHORE |
lib/libcxx/include/set+216-55| ... | ... | @@ -56,6 +56,8 @@ public: |
| 56 | 56 | template <class InputIterator> |
| 57 | 57 | set(InputIterator first, InputIterator last, const value_compare& comp, |
| 58 | 58 | const allocator_type& a); |
| 59 | template<container-compatible-range<value_type> R> | |
| 60 | set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23 | |
| 59 | 61 | set(const set& s); |
| 60 | 62 | set(set&& s) |
| 61 | 63 | noexcept( |
| ... | ... | @@ -70,6 +72,9 @@ public: |
| 70 | 72 | template <class InputIterator> |
| 71 | 73 | set(InputIterator first, InputIterator last, const allocator_type& a) |
| 72 | 74 | : set(first, last, Compare(), a) {} // C++14 |
| 75 | template<container-compatible-range<value_type> R> | |
| 76 | set(from_range_t, R&& rg, const Allocator& a)) | |
| 77 | : set(from_range, std::forward<R>(rg), Compare(), a) { } // C++23 | |
| 73 | 78 | set(initializer_list<value_type> il, const allocator_type& a) |
| 74 | 79 | : set(il, Compare(), a) {} // C++14 |
| 75 | 80 | ~set(); |
| ... | ... | @@ -114,6 +119,8 @@ public: |
| 114 | 119 | iterator insert(const_iterator position, value_type&& v); |
| 115 | 120 | template <class InputIterator> |
| 116 | 121 | void insert(InputIterator first, InputIterator last); |
| 122 | template<container-compatible-range<value_type> R> | |
| 123 | void insert_range(R&& rg); // C++23 | |
| 117 | 124 | void insert(initializer_list<value_type> il); |
| 118 | 125 | |
| 119 | 126 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -190,6 +197,11 @@ set(InputIterator, InputIterator, |
| 190 | 197 | Compare = Compare(), Allocator = Allocator()) |
| 191 | 198 | -> set<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17 |
| 192 | 199 | |
| 200 | template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>, | |
| 201 | class Allocator = allocator<ranges::range_value_t<R>>> | |
| 202 | set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) | |
| 203 | -> set<ranges::range_value_t<R>, Compare, Allocator>; // C++23 | |
| 204 | ||
| 193 | 205 | template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> |
| 194 | 206 | set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator()) |
| 195 | 207 | -> set<Key, Compare, Allocator>; // C++17 |
| ... | ... | @@ -199,6 +211,10 @@ set(InputIterator, InputIterator, Allocator) |
| 199 | 211 | -> set<typename iterator_traits<InputIterator>::value_type, |
| 200 | 212 | less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 |
| 201 | 213 | |
| 214 | template<ranges::input_range R, class Allocator> | |
| 215 | set(from_range_t, R&&, Allocator) | |
| 216 | -> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 217 | ||
| 202 | 218 | template<class Key, class Allocator> |
| 203 | 219 | set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>; // C++17 |
| 204 | 220 | |
| ... | ... | @@ -210,27 +226,31 @@ operator==(const set<Key, Compare, Allocator>& x, |
| 210 | 226 | template <class Key, class Compare, class Allocator> |
| 211 | 227 | bool |
| 212 | 228 | operator< (const set<Key, Compare, Allocator>& x, |
| 213 | const set<Key, Compare, Allocator>& y); | |
| 229 | const set<Key, Compare, Allocator>& y); // removed in C++20 | |
| 214 | 230 | |
| 215 | 231 | template <class Key, class Compare, class Allocator> |
| 216 | 232 | bool |
| 217 | 233 | operator!=(const set<Key, Compare, Allocator>& x, |
| 218 | const set<Key, Compare, Allocator>& y); | |
| 234 | const set<Key, Compare, Allocator>& y); // removed in C++20 | |
| 219 | 235 | |
| 220 | 236 | template <class Key, class Compare, class Allocator> |
| 221 | 237 | bool |
| 222 | 238 | operator> (const set<Key, Compare, Allocator>& x, |
| 223 | const set<Key, Compare, Allocator>& y); | |
| 239 | const set<Key, Compare, Allocator>& y); // removed in C++20 | |
| 224 | 240 | |
| 225 | 241 | template <class Key, class Compare, class Allocator> |
| 226 | 242 | bool |
| 227 | 243 | operator>=(const set<Key, Compare, Allocator>& x, |
| 228 | const set<Key, Compare, Allocator>& y); | |
| 244 | const set<Key, Compare, Allocator>& y); // removed in C++20 | |
| 229 | 245 | |
| 230 | 246 | template <class Key, class Compare, class Allocator> |
| 231 | 247 | bool |
| 232 | 248 | operator<=(const set<Key, Compare, Allocator>& x, |
| 233 | const set<Key, Compare, Allocator>& y); | |
| 249 | const set<Key, Compare, Allocator>& y); // removed in C++20 | |
| 250 | ||
| 251 | template<class Key, class Compare, class Allocator> | |
| 252 | synth-three-way-result<Key> operator<=>(const set<Key, Compare, Allocator>& x, | |
| 253 | const set<Key, Compare, Allocator>& y); // since C++20 | |
| 234 | 254 | |
| 235 | 255 | // specialized algorithms: |
| 236 | 256 | template <class Key, class Compare, class Allocator> |
| ... | ... | @@ -280,6 +300,9 @@ public: |
| 280 | 300 | template <class InputIterator> |
| 281 | 301 | multiset(InputIterator first, InputIterator last, |
| 282 | 302 | const value_compare& comp, const allocator_type& a); |
| 303 | template<container-compatible-range<value_type> R> | |
| 304 | multiset(from_range_t, R&& rg, | |
| 305 | const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23 | |
| 283 | 306 | multiset(const multiset& s); |
| 284 | 307 | multiset(multiset&& s) |
| 285 | 308 | noexcept( |
| ... | ... | @@ -294,6 +317,9 @@ public: |
| 294 | 317 | template <class InputIterator> |
| 295 | 318 | multiset(InputIterator first, InputIterator last, const allocator_type& a) |
| 296 | 319 | : set(first, last, Compare(), a) {} // C++14 |
| 320 | template<container-compatible-range<value_type> R> | |
| 321 | multiset(from_range_t, R&& rg, const Allocator& a)) | |
| 322 | : multiset(from_range, std::forward<R>(rg), Compare(), a) { } // C++23 | |
| 297 | 323 | multiset(initializer_list<value_type> il, const allocator_type& a) |
| 298 | 324 | : set(il, Compare(), a) {} // C++14 |
| 299 | 325 | ~multiset(); |
| ... | ... | @@ -338,6 +364,8 @@ public: |
| 338 | 364 | iterator insert(const_iterator position, value_type&& v); |
| 339 | 365 | template <class InputIterator> |
| 340 | 366 | void insert(InputIterator first, InputIterator last); |
| 367 | template<container-compatible-range<value_type> R> | |
| 368 | void insert_range(R&& rg); // C++23 | |
| 341 | 369 | void insert(initializer_list<value_type> il); |
| 342 | 370 | |
| 343 | 371 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -415,6 +443,11 @@ multiset(InputIterator, InputIterator, |
| 415 | 443 | Compare = Compare(), Allocator = Allocator()) |
| 416 | 444 | -> multiset<typename iterator_traits<InputIterator>::value_type, Compare, Allocator>; // C++17 |
| 417 | 445 | |
| 446 | template<ranges::input_range R, class Compare = less<ranges::range_value_t<R>>, | |
| 447 | class Allocator = allocator<ranges::range_value_t<R>>> | |
| 448 | multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator()) | |
| 449 | -> multiset<ranges::range_value_t<R>, Compare, Allocator>; | |
| 450 | ||
| 418 | 451 | template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> |
| 419 | 452 | multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator()) |
| 420 | 453 | -> multiset<Key, Compare, Allocator>; // C++17 |
| ... | ... | @@ -424,6 +457,10 @@ multiset(InputIterator, InputIterator, Allocator) |
| 424 | 457 | -> multiset<typename iterator_traits<InputIterator>::value_type, |
| 425 | 458 | less<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 |
| 426 | 459 | |
| 460 | template<ranges::input_range R, class Allocator> | |
| 461 | multiset(from_range_t, R&&, Allocator) | |
| 462 | -> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; | |
| 463 | ||
| 427 | 464 | template<class Key, class Allocator> |
| 428 | 465 | multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>; // C++17 |
| 429 | 466 | |
| ... | ... | @@ -435,27 +472,31 @@ operator==(const multiset<Key, Compare, Allocator>& x, |
| 435 | 472 | template <class Key, class Compare, class Allocator> |
| 436 | 473 | bool |
| 437 | 474 | operator< (const multiset<Key, Compare, Allocator>& x, |
| 438 | const multiset<Key, Compare, Allocator>& y); | |
| 475 | const multiset<Key, Compare, Allocator>& y); // removed in C++20 | |
| 439 | 476 | |
| 440 | 477 | template <class Key, class Compare, class Allocator> |
| 441 | 478 | bool |
| 442 | 479 | operator!=(const multiset<Key, Compare, Allocator>& x, |
| 443 | const multiset<Key, Compare, Allocator>& y); | |
| 480 | const multiset<Key, Compare, Allocator>& y); // removed in C++20 | |
| 444 | 481 | |
| 445 | 482 | template <class Key, class Compare, class Allocator> |
| 446 | 483 | bool |
| 447 | 484 | operator> (const multiset<Key, Compare, Allocator>& x, |
| 448 | const multiset<Key, Compare, Allocator>& y); | |
| 485 | const multiset<Key, Compare, Allocator>& y); // removed in C++20 | |
| 449 | 486 | |
| 450 | 487 | template <class Key, class Compare, class Allocator> |
| 451 | 488 | bool |
| 452 | 489 | operator>=(const multiset<Key, Compare, Allocator>& x, |
| 453 | const multiset<Key, Compare, Allocator>& y); | |
| 490 | const multiset<Key, Compare, Allocator>& y); // removed in C++20 | |
| 454 | 491 | |
| 455 | 492 | template <class Key, class Compare, class Allocator> |
| 456 | 493 | bool |
| 457 | 494 | operator<=(const multiset<Key, Compare, Allocator>& x, |
| 458 | const multiset<Key, Compare, Allocator>& y); | |
| 495 | const multiset<Key, Compare, Allocator>& y); // removed in C++20 | |
| 496 | ||
| 497 | template<class Key, class Compare, class Allocator> | |
| 498 | synth-three-way-result<Key> operator<=>(const multiset<Key, Compare, Allocator>& x, | |
| 499 | const multiset<Key, Compare, Allocator>& y); // since C++20 | |
| 459 | 500 | |
| 460 | 501 | // specialized algorithms: |
| 461 | 502 | template <class Key, class Compare, class Allocator> |
| ... | ... | @@ -473,16 +514,22 @@ erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); // C++20 |
| 473 | 514 | |
| 474 | 515 | #include <__algorithm/equal.h> |
| 475 | 516 | #include <__algorithm/lexicographical_compare.h> |
| 517 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 476 | 518 | #include <__assert> // all public C++ headers provide the assertion handler |
| 519 | #include <__availability> | |
| 477 | 520 | #include <__config> |
| 478 | 521 | #include <__functional/is_transparent.h> |
| 479 | 522 | #include <__functional/operations.h> |
| 480 | 523 | #include <__iterator/erase_if_container.h> |
| 481 | 524 | #include <__iterator/iterator_traits.h> |
| 525 | #include <__iterator/ranges_iterator_traits.h> | |
| 482 | 526 | #include <__iterator/reverse_iterator.h> |
| 483 | 527 | #include <__memory/allocator.h> |
| 484 | 528 | #include <__memory_resource/polymorphic_allocator.h> |
| 485 | 529 | #include <__node_handle> |
| 530 | #include <__ranges/concepts.h> | |
| 531 | #include <__ranges/container_compatible_range.h> | |
| 532 | #include <__ranges/from_range.h> | |
| 486 | 533 | #include <__tree> |
| 487 | 534 | #include <__type_traits/is_allocator.h> |
| 488 | 535 | #include <__utility/forward.h> |
| ... | ... | @@ -547,7 +594,7 @@ public: |
| 547 | 594 | typedef _VSTD::reverse_iterator<iterator> reverse_iterator; |
| 548 | 595 | typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; |
| 549 | 596 | |
| 550 | #if _LIBCPP_STD_VER > 14 | |
| 597 | #if _LIBCPP_STD_VER >= 17 | |
| 551 | 598 | typedef __set_node_handle<typename __base::__node, allocator_type> node_type; |
| 552 | 599 | typedef __insert_return_type<iterator, node_type> insert_return_type; |
| 553 | 600 | #endif |
| ... | ... | @@ -593,13 +640,30 @@ public: |
| 593 | 640 | insert(__f, __l); |
| 594 | 641 | } |
| 595 | 642 | |
| 596 | #if _LIBCPP_STD_VER > 11 | |
| 643 | #if _LIBCPP_STD_VER >= 23 | |
| 644 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 645 | _LIBCPP_HIDE_FROM_ABI | |
| 646 | set(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(), | |
| 647 | const allocator_type& __a = allocator_type()) | |
| 648 | : __tree_(__comp, __a) { | |
| 649 | insert_range(std::forward<_Range>(__range)); | |
| 650 | } | |
| 651 | #endif | |
| 652 | ||
| 653 | #if _LIBCPP_STD_VER >= 14 | |
| 597 | 654 | template <class _InputIterator> |
| 598 | 655 | _LIBCPP_INLINE_VISIBILITY |
| 599 | 656 | set(_InputIterator __f, _InputIterator __l, const allocator_type& __a) |
| 600 | 657 | : set(__f, __l, key_compare(), __a) {} |
| 601 | 658 | #endif |
| 602 | 659 | |
| 660 | #if _LIBCPP_STD_VER >= 23 | |
| 661 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 662 | _LIBCPP_HIDE_FROM_ABI | |
| 663 | set(from_range_t, _Range&& __range, const allocator_type& __a) | |
| 664 | : set(from_range, std::forward<_Range>(__range), key_compare(), __a) {} | |
| 665 | #endif | |
| 666 | ||
| 603 | 667 | _LIBCPP_INLINE_VISIBILITY |
| 604 | 668 | set(const set& __s) |
| 605 | 669 | : __tree_(__s.__tree_) |
| ... | ... | @@ -633,7 +697,7 @@ public: |
| 633 | 697 | } |
| 634 | 698 | |
| 635 | 699 | #ifndef _LIBCPP_CXX03_LANG |
| 636 | set(set&& __s, const allocator_type& __a); | |
| 700 | _LIBCPP_HIDE_FROM_ABI set(set&& __s, const allocator_type& __a); | |
| 637 | 701 | |
| 638 | 702 | _LIBCPP_INLINE_VISIBILITY |
| 639 | 703 | set(initializer_list<value_type> __il, const value_compare& __comp = value_compare()) |
| ... | ... | @@ -650,7 +714,7 @@ public: |
| 650 | 714 | insert(__il.begin(), __il.end()); |
| 651 | 715 | } |
| 652 | 716 | |
| 653 | #if _LIBCPP_STD_VER > 11 | |
| 717 | #if _LIBCPP_STD_VER >= 14 | |
| 654 | 718 | _LIBCPP_INLINE_VISIBILITY |
| 655 | 719 | set(initializer_list<value_type> __il, const allocator_type& __a) |
| 656 | 720 | : set(__il, key_compare(), __a) {} |
| ... | ... | @@ -742,6 +806,17 @@ public: |
| 742 | 806 | __tree_.__insert_unique(__e, *__f); |
| 743 | 807 | } |
| 744 | 808 | |
| 809 | #if _LIBCPP_STD_VER >= 23 | |
| 810 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 811 | _LIBCPP_HIDE_FROM_ABI | |
| 812 | void insert_range(_Range&& __range) { | |
| 813 | const_iterator __end = cend(); | |
| 814 | for (auto&& __element : __range) { | |
| 815 | __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element)); | |
| 816 | } | |
| 817 | } | |
| 818 | #endif | |
| 819 | ||
| 745 | 820 | #ifndef _LIBCPP_CXX03_LANG |
| 746 | 821 | _LIBCPP_INLINE_VISIBILITY |
| 747 | 822 | pair<iterator,bool> insert(value_type&& __v) |
| ... | ... | @@ -767,11 +842,11 @@ public: |
| 767 | 842 | _LIBCPP_INLINE_VISIBILITY |
| 768 | 843 | void clear() _NOEXCEPT {__tree_.clear();} |
| 769 | 844 | |
| 770 | #if _LIBCPP_STD_VER > 14 | |
| 845 | #if _LIBCPP_STD_VER >= 17 | |
| 771 | 846 | _LIBCPP_INLINE_VISIBILITY |
| 772 | 847 | insert_return_type insert(node_type&& __nh) |
| 773 | 848 | { |
| 774 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 849 | _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 775 | 850 | "node_type with incompatible allocator passed to set::insert()"); |
| 776 | 851 | return __tree_.template __node_handle_insert_unique< |
| 777 | 852 | node_type, insert_return_type>(_VSTD::move(__nh)); |
| ... | ... | @@ -779,7 +854,7 @@ public: |
| 779 | 854 | _LIBCPP_INLINE_VISIBILITY |
| 780 | 855 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 781 | 856 | { |
| 782 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 857 | _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 783 | 858 | "node_type with incompatible allocator passed to set::insert()"); |
| 784 | 859 | return __tree_.template __node_handle_insert_unique<node_type>( |
| 785 | 860 | __hint, _VSTD::move(__nh)); |
| ... | ... | @@ -798,7 +873,7 @@ public: |
| 798 | 873 | _LIBCPP_INLINE_VISIBILITY |
| 799 | 874 | void merge(set<key_type, _Compare2, allocator_type>& __source) |
| 800 | 875 | { |
| 801 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 876 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 802 | 877 | "merging container with incompatible allocator"); |
| 803 | 878 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 804 | 879 | } |
| ... | ... | @@ -806,7 +881,7 @@ public: |
| 806 | 881 | _LIBCPP_INLINE_VISIBILITY |
| 807 | 882 | void merge(set<key_type, _Compare2, allocator_type>&& __source) |
| 808 | 883 | { |
| 809 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 884 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 810 | 885 | "merging container with incompatible allocator"); |
| 811 | 886 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 812 | 887 | } |
| ... | ... | @@ -814,7 +889,7 @@ public: |
| 814 | 889 | _LIBCPP_INLINE_VISIBILITY |
| 815 | 890 | void merge(multiset<key_type, _Compare2, allocator_type>& __source) |
| 816 | 891 | { |
| 817 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 892 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 818 | 893 | "merging container with incompatible allocator"); |
| 819 | 894 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 820 | 895 | } |
| ... | ... | @@ -822,7 +897,7 @@ public: |
| 822 | 897 | _LIBCPP_INLINE_VISIBILITY |
| 823 | 898 | void merge(multiset<key_type, _Compare2, allocator_type>&& __source) |
| 824 | 899 | { |
| 825 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 900 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 826 | 901 | "merging container with incompatible allocator"); |
| 827 | 902 | __tree_.__node_handle_merge_unique(__source.__tree_); |
| 828 | 903 | } |
| ... | ... | @@ -844,7 +919,7 @@ public: |
| 844 | 919 | iterator find(const key_type& __k) {return __tree_.find(__k);} |
| 845 | 920 | _LIBCPP_INLINE_VISIBILITY |
| 846 | 921 | const_iterator find(const key_type& __k) const {return __tree_.find(__k);} |
| 847 | #if _LIBCPP_STD_VER > 11 | |
| 922 | #if _LIBCPP_STD_VER >= 14 | |
| 848 | 923 | template <typename _K2> |
| 849 | 924 | _LIBCPP_INLINE_VISIBILITY |
| 850 | 925 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -858,21 +933,21 @@ public: |
| 858 | 933 | _LIBCPP_INLINE_VISIBILITY |
| 859 | 934 | size_type count(const key_type& __k) const |
| 860 | 935 | {return __tree_.__count_unique(__k);} |
| 861 | #if _LIBCPP_STD_VER > 11 | |
| 936 | #if _LIBCPP_STD_VER >= 14 | |
| 862 | 937 | template <typename _K2> |
| 863 | 938 | _LIBCPP_INLINE_VISIBILITY |
| 864 | 939 | typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type |
| 865 | 940 | count(const _K2& __k) const {return __tree_.__count_multi(__k);} |
| 866 | 941 | #endif |
| 867 | 942 | |
| 868 | #if _LIBCPP_STD_VER > 17 | |
| 943 | #if _LIBCPP_STD_VER >= 20 | |
| 869 | 944 | _LIBCPP_INLINE_VISIBILITY |
| 870 | 945 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 871 | 946 | template <typename _K2> |
| 872 | 947 | _LIBCPP_INLINE_VISIBILITY |
| 873 | 948 | typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type |
| 874 | 949 | contains(const _K2& __k) const { return find(__k) != end(); } |
| 875 | #endif // _LIBCPP_STD_VER > 17 | |
| 950 | #endif // _LIBCPP_STD_VER >= 20 | |
| 876 | 951 | |
| 877 | 952 | _LIBCPP_INLINE_VISIBILITY |
| 878 | 953 | iterator lower_bound(const key_type& __k) |
| ... | ... | @@ -880,7 +955,7 @@ public: |
| 880 | 955 | _LIBCPP_INLINE_VISIBILITY |
| 881 | 956 | const_iterator lower_bound(const key_type& __k) const |
| 882 | 957 | {return __tree_.lower_bound(__k);} |
| 883 | #if _LIBCPP_STD_VER > 11 | |
| 958 | #if _LIBCPP_STD_VER >= 14 | |
| 884 | 959 | template <typename _K2> |
| 885 | 960 | _LIBCPP_INLINE_VISIBILITY |
| 886 | 961 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -898,7 +973,7 @@ public: |
| 898 | 973 | _LIBCPP_INLINE_VISIBILITY |
| 899 | 974 | const_iterator upper_bound(const key_type& __k) const |
| 900 | 975 | {return __tree_.upper_bound(__k);} |
| 901 | #if _LIBCPP_STD_VER > 11 | |
| 976 | #if _LIBCPP_STD_VER >= 14 | |
| 902 | 977 | template <typename _K2> |
| 903 | 978 | _LIBCPP_INLINE_VISIBILITY |
| 904 | 979 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -915,7 +990,7 @@ public: |
| 915 | 990 | _LIBCPP_INLINE_VISIBILITY |
| 916 | 991 | pair<const_iterator,const_iterator> equal_range(const key_type& __k) const |
| 917 | 992 | {return __tree_.__equal_range_unique(__k);} |
| 918 | #if _LIBCPP_STD_VER > 11 | |
| 993 | #if _LIBCPP_STD_VER >= 14 | |
| 919 | 994 | template <typename _K2> |
| 920 | 995 | _LIBCPP_INLINE_VISIBILITY |
| 921 | 996 | typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type |
| ... | ... | @@ -931,12 +1006,21 @@ public: |
| 931 | 1006 | template<class _InputIterator, |
| 932 | 1007 | class _Compare = less<__iter_value_type<_InputIterator>>, |
| 933 | 1008 | class _Allocator = allocator<__iter_value_type<_InputIterator>>, |
| 934 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1009 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 935 | 1010 | class = enable_if_t<__is_allocator<_Allocator>::value, void>, |
| 936 | 1011 | class = enable_if_t<!__is_allocator<_Compare>::value, void>> |
| 937 | 1012 | set(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) |
| 938 | 1013 | -> set<__iter_value_type<_InputIterator>, _Compare, _Allocator>; |
| 939 | 1014 | |
| 1015 | #if _LIBCPP_STD_VER >= 23 | |
| 1016 | template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>, | |
| 1017 | class _Allocator = allocator<ranges::range_value_t<_Range>>, | |
| 1018 | class = enable_if_t<__is_allocator<_Allocator>::value, void>, | |
| 1019 | class = enable_if_t<!__is_allocator<_Compare>::value, void>> | |
| 1020 | set(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) | |
| 1021 | -> set<ranges::range_value_t<_Range>, _Compare, _Allocator>; | |
| 1022 | #endif | |
| 1023 | ||
| 940 | 1024 | template<class _Key, class _Compare = less<_Key>, |
| 941 | 1025 | class _Allocator = allocator<_Key>, |
| 942 | 1026 | class = enable_if_t<!__is_allocator<_Compare>::value, void>, |
| ... | ... | @@ -945,12 +1029,19 @@ set(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator()) |
| 945 | 1029 | -> set<_Key, _Compare, _Allocator>; |
| 946 | 1030 | |
| 947 | 1031 | template<class _InputIterator, class _Allocator, |
| 948 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1032 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 949 | 1033 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 950 | 1034 | set(_InputIterator, _InputIterator, _Allocator) |
| 951 | 1035 | -> set<__iter_value_type<_InputIterator>, |
| 952 | 1036 | less<__iter_value_type<_InputIterator>>, _Allocator>; |
| 953 | 1037 | |
| 1038 | #if _LIBCPP_STD_VER >= 23 | |
| 1039 | template <ranges::input_range _Range, class _Allocator, | |
| 1040 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 1041 | set(from_range_t, _Range&&, _Allocator) | |
| 1042 | -> set<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1043 | #endif | |
| 1044 | ||
| 954 | 1045 | template<class _Key, class _Allocator, |
| 955 | 1046 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 956 | 1047 | set(initializer_list<_Key>, _Allocator) |
| ... | ... | @@ -982,6 +1073,8 @@ operator==(const set<_Key, _Compare, _Allocator>& __x, |
| 982 | 1073 | return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 983 | 1074 | } |
| 984 | 1075 | |
| 1076 | #if _LIBCPP_STD_VER <= 17 | |
| 1077 | ||
| 985 | 1078 | template <class _Key, class _Compare, class _Allocator> |
| 986 | 1079 | inline _LIBCPP_INLINE_VISIBILITY |
| 987 | 1080 | bool |
| ... | ... | @@ -1027,6 +1120,17 @@ operator<=(const set<_Key, _Compare, _Allocator>& __x, |
| 1027 | 1120 | return !(__y < __x); |
| 1028 | 1121 | } |
| 1029 | 1122 | |
| 1123 | #else // _LIBCPP_STD_VER <= 17 | |
| 1124 | ||
| 1125 | template <class _Key, class _Allocator> | |
| 1126 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key> | |
| 1127 | operator<=>(const set<_Key, _Allocator>& __x, const set<_Key, _Allocator>& __y) { | |
| 1128 | return std::lexicographical_compare_three_way( | |
| 1129 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>); | |
| 1130 | } | |
| 1131 | ||
| 1132 | #endif // _LIBCPP_STD_VER <= 17 | |
| 1133 | ||
| 1030 | 1134 | // specialized algorithms: |
| 1031 | 1135 | template <class _Key, class _Compare, class _Allocator> |
| 1032 | 1136 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1038,7 +1142,7 @@ swap(set<_Key, _Compare, _Allocator>& __x, |
| 1038 | 1142 | __x.swap(__y); |
| 1039 | 1143 | } |
| 1040 | 1144 | |
| 1041 | #if _LIBCPP_STD_VER > 17 | |
| 1145 | #if _LIBCPP_STD_VER >= 20 | |
| 1042 | 1146 | template <class _Key, class _Compare, class _Allocator, class _Predicate> |
| 1043 | 1147 | inline _LIBCPP_INLINE_VISIBILITY |
| 1044 | 1148 | typename set<_Key, _Compare, _Allocator>::size_type |
| ... | ... | @@ -1084,7 +1188,7 @@ public: |
| 1084 | 1188 | typedef _VSTD::reverse_iterator<iterator> reverse_iterator; |
| 1085 | 1189 | typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; |
| 1086 | 1190 | |
| 1087 | #if _LIBCPP_STD_VER > 14 | |
| 1191 | #if _LIBCPP_STD_VER >= 17 | |
| 1088 | 1192 | typedef __set_node_handle<typename __base::__node, allocator_type> node_type; |
| 1089 | 1193 | #endif |
| 1090 | 1194 | |
| ... | ... | @@ -1121,7 +1225,7 @@ public: |
| 1121 | 1225 | insert(__f, __l); |
| 1122 | 1226 | } |
| 1123 | 1227 | |
| 1124 | #if _LIBCPP_STD_VER > 11 | |
| 1228 | #if _LIBCPP_STD_VER >= 14 | |
| 1125 | 1229 | template <class _InputIterator> |
| 1126 | 1230 | _LIBCPP_INLINE_VISIBILITY |
| 1127 | 1231 | multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) |
| ... | ... | @@ -1137,6 +1241,21 @@ public: |
| 1137 | 1241 | insert(__f, __l); |
| 1138 | 1242 | } |
| 1139 | 1243 | |
| 1244 | #if _LIBCPP_STD_VER >= 23 | |
| 1245 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1246 | _LIBCPP_HIDE_FROM_ABI | |
| 1247 | multiset(from_range_t, _Range&& __range, const key_compare& __comp = key_compare(), | |
| 1248 | const allocator_type& __a = allocator_type()) | |
| 1249 | : __tree_(__comp, __a) { | |
| 1250 | insert_range(std::forward<_Range>(__range)); | |
| 1251 | } | |
| 1252 | ||
| 1253 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1254 | _LIBCPP_HIDE_FROM_ABI | |
| 1255 | multiset(from_range_t, _Range&& __range, const allocator_type& __a) | |
| 1256 | : multiset(from_range, std::forward<_Range>(__range), key_compare(), __a) {} | |
| 1257 | #endif | |
| 1258 | ||
| 1140 | 1259 | _LIBCPP_INLINE_VISIBILITY |
| 1141 | 1260 | multiset(const multiset& __s) |
| 1142 | 1261 | : __tree_(__s.__tree_.value_comp(), |
| ... | ... | @@ -1158,7 +1277,7 @@ public: |
| 1158 | 1277 | _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) |
| 1159 | 1278 | : __tree_(_VSTD::move(__s.__tree_)) {} |
| 1160 | 1279 | |
| 1161 | multiset(multiset&& __s, const allocator_type& __a); | |
| 1280 | _LIBCPP_HIDE_FROM_ABI multiset(multiset&& __s, const allocator_type& __a); | |
| 1162 | 1281 | #endif // _LIBCPP_CXX03_LANG |
| 1163 | 1282 | _LIBCPP_INLINE_VISIBILITY |
| 1164 | 1283 | explicit multiset(const allocator_type& __a) |
| ... | ... | @@ -1186,7 +1305,7 @@ public: |
| 1186 | 1305 | insert(__il.begin(), __il.end()); |
| 1187 | 1306 | } |
| 1188 | 1307 | |
| 1189 | #if _LIBCPP_STD_VER > 11 | |
| 1308 | #if _LIBCPP_STD_VER >= 14 | |
| 1190 | 1309 | _LIBCPP_INLINE_VISIBILITY |
| 1191 | 1310 | multiset(initializer_list<value_type> __il, const allocator_type& __a) |
| 1192 | 1311 | : multiset(__il, key_compare(), __a) {} |
| ... | ... | @@ -1278,6 +1397,17 @@ public: |
| 1278 | 1397 | __tree_.__insert_multi(__e, *__f); |
| 1279 | 1398 | } |
| 1280 | 1399 | |
| 1400 | #if _LIBCPP_STD_VER >= 23 | |
| 1401 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1402 | _LIBCPP_HIDE_FROM_ABI | |
| 1403 | void insert_range(_Range&& __range) { | |
| 1404 | const_iterator __end = cend(); | |
| 1405 | for (auto&& __element : __range) { | |
| 1406 | __tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element)); | |
| 1407 | } | |
| 1408 | } | |
| 1409 | #endif | |
| 1410 | ||
| 1281 | 1411 | #ifndef _LIBCPP_CXX03_LANG |
| 1282 | 1412 | _LIBCPP_INLINE_VISIBILITY |
| 1283 | 1413 | iterator insert(value_type&& __v) |
| ... | ... | @@ -1302,11 +1432,11 @@ public: |
| 1302 | 1432 | _LIBCPP_INLINE_VISIBILITY |
| 1303 | 1433 | void clear() _NOEXCEPT {__tree_.clear();} |
| 1304 | 1434 | |
| 1305 | #if _LIBCPP_STD_VER > 14 | |
| 1435 | #if _LIBCPP_STD_VER >= 17 | |
| 1306 | 1436 | _LIBCPP_INLINE_VISIBILITY |
| 1307 | 1437 | iterator insert(node_type&& __nh) |
| 1308 | 1438 | { |
| 1309 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1439 | _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1310 | 1440 | "node_type with incompatible allocator passed to multiset::insert()"); |
| 1311 | 1441 | return __tree_.template __node_handle_insert_multi<node_type>( |
| 1312 | 1442 | _VSTD::move(__nh)); |
| ... | ... | @@ -1314,7 +1444,7 @@ public: |
| 1314 | 1444 | _LIBCPP_INLINE_VISIBILITY |
| 1315 | 1445 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 1316 | 1446 | { |
| 1317 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1447 | _LIBCPP_ASSERT_UNCATEGORIZED(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1318 | 1448 | "node_type with incompatible allocator passed to multiset::insert()"); |
| 1319 | 1449 | return __tree_.template __node_handle_insert_multi<node_type>( |
| 1320 | 1450 | __hint, _VSTD::move(__nh)); |
| ... | ... | @@ -1333,7 +1463,7 @@ public: |
| 1333 | 1463 | _LIBCPP_INLINE_VISIBILITY |
| 1334 | 1464 | void merge(multiset<key_type, _Compare2, allocator_type>& __source) |
| 1335 | 1465 | { |
| 1336 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1466 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 1337 | 1467 | "merging container with incompatible allocator"); |
| 1338 | 1468 | __tree_.__node_handle_merge_multi(__source.__tree_); |
| 1339 | 1469 | } |
| ... | ... | @@ -1341,7 +1471,7 @@ public: |
| 1341 | 1471 | _LIBCPP_INLINE_VISIBILITY |
| 1342 | 1472 | void merge(multiset<key_type, _Compare2, allocator_type>&& __source) |
| 1343 | 1473 | { |
| 1344 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1474 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 1345 | 1475 | "merging container with incompatible allocator"); |
| 1346 | 1476 | __tree_.__node_handle_merge_multi(__source.__tree_); |
| 1347 | 1477 | } |
| ... | ... | @@ -1349,7 +1479,7 @@ public: |
| 1349 | 1479 | _LIBCPP_INLINE_VISIBILITY |
| 1350 | 1480 | void merge(set<key_type, _Compare2, allocator_type>& __source) |
| 1351 | 1481 | { |
| 1352 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1482 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 1353 | 1483 | "merging container with incompatible allocator"); |
| 1354 | 1484 | __tree_.__node_handle_merge_multi(__source.__tree_); |
| 1355 | 1485 | } |
| ... | ... | @@ -1357,7 +1487,7 @@ public: |
| 1357 | 1487 | _LIBCPP_INLINE_VISIBILITY |
| 1358 | 1488 | void merge(set<key_type, _Compare2, allocator_type>&& __source) |
| 1359 | 1489 | { |
| 1360 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1490 | _LIBCPP_ASSERT_UNCATEGORIZED(__source.get_allocator() == get_allocator(), | |
| 1361 | 1491 | "merging container with incompatible allocator"); |
| 1362 | 1492 | __tree_.__node_handle_merge_multi(__source.__tree_); |
| 1363 | 1493 | } |
| ... | ... | @@ -1380,7 +1510,7 @@ public: |
| 1380 | 1510 | iterator find(const key_type& __k) {return __tree_.find(__k);} |
| 1381 | 1511 | _LIBCPP_INLINE_VISIBILITY |
| 1382 | 1512 | const_iterator find(const key_type& __k) const {return __tree_.find(__k);} |
| 1383 | #if _LIBCPP_STD_VER > 11 | |
| 1513 | #if _LIBCPP_STD_VER >= 14 | |
| 1384 | 1514 | template <typename _K2> |
| 1385 | 1515 | _LIBCPP_INLINE_VISIBILITY |
| 1386 | 1516 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -1394,21 +1524,21 @@ public: |
| 1394 | 1524 | _LIBCPP_INLINE_VISIBILITY |
| 1395 | 1525 | size_type count(const key_type& __k) const |
| 1396 | 1526 | {return __tree_.__count_multi(__k);} |
| 1397 | #if _LIBCPP_STD_VER > 11 | |
| 1527 | #if _LIBCPP_STD_VER >= 14 | |
| 1398 | 1528 | template <typename _K2> |
| 1399 | 1529 | _LIBCPP_INLINE_VISIBILITY |
| 1400 | 1530 | typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type |
| 1401 | 1531 | count(const _K2& __k) const {return __tree_.__count_multi(__k);} |
| 1402 | 1532 | #endif |
| 1403 | 1533 | |
| 1404 | #if _LIBCPP_STD_VER > 17 | |
| 1534 | #if _LIBCPP_STD_VER >= 20 | |
| 1405 | 1535 | _LIBCPP_INLINE_VISIBILITY |
| 1406 | 1536 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 1407 | 1537 | template <typename _K2> |
| 1408 | 1538 | _LIBCPP_INLINE_VISIBILITY |
| 1409 | 1539 | typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type |
| 1410 | 1540 | contains(const _K2& __k) const { return find(__k) != end(); } |
| 1411 | #endif // _LIBCPP_STD_VER > 17 | |
| 1541 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1412 | 1542 | |
| 1413 | 1543 | _LIBCPP_INLINE_VISIBILITY |
| 1414 | 1544 | iterator lower_bound(const key_type& __k) |
| ... | ... | @@ -1416,7 +1546,7 @@ public: |
| 1416 | 1546 | _LIBCPP_INLINE_VISIBILITY |
| 1417 | 1547 | const_iterator lower_bound(const key_type& __k) const |
| 1418 | 1548 | {return __tree_.lower_bound(__k);} |
| 1419 | #if _LIBCPP_STD_VER > 11 | |
| 1549 | #if _LIBCPP_STD_VER >= 14 | |
| 1420 | 1550 | template <typename _K2> |
| 1421 | 1551 | _LIBCPP_INLINE_VISIBILITY |
| 1422 | 1552 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -1434,7 +1564,7 @@ public: |
| 1434 | 1564 | _LIBCPP_INLINE_VISIBILITY |
| 1435 | 1565 | const_iterator upper_bound(const key_type& __k) const |
| 1436 | 1566 | {return __tree_.upper_bound(__k);} |
| 1437 | #if _LIBCPP_STD_VER > 11 | |
| 1567 | #if _LIBCPP_STD_VER >= 14 | |
| 1438 | 1568 | template <typename _K2> |
| 1439 | 1569 | _LIBCPP_INLINE_VISIBILITY |
| 1440 | 1570 | typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type |
| ... | ... | @@ -1451,7 +1581,7 @@ public: |
| 1451 | 1581 | _LIBCPP_INLINE_VISIBILITY |
| 1452 | 1582 | pair<const_iterator,const_iterator> equal_range(const key_type& __k) const |
| 1453 | 1583 | {return __tree_.__equal_range_multi(__k);} |
| 1454 | #if _LIBCPP_STD_VER > 11 | |
| 1584 | #if _LIBCPP_STD_VER >= 14 | |
| 1455 | 1585 | template <typename _K2> |
| 1456 | 1586 | _LIBCPP_INLINE_VISIBILITY |
| 1457 | 1587 | typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type |
| ... | ... | @@ -1467,12 +1597,21 @@ public: |
| 1467 | 1597 | template<class _InputIterator, |
| 1468 | 1598 | class _Compare = less<__iter_value_type<_InputIterator>>, |
| 1469 | 1599 | class _Allocator = allocator<__iter_value_type<_InputIterator>>, |
| 1470 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1600 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 1471 | 1601 | class = enable_if_t<__is_allocator<_Allocator>::value, void>, |
| 1472 | 1602 | class = enable_if_t<!__is_allocator<_Compare>::value, void>> |
| 1473 | 1603 | multiset(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) |
| 1474 | 1604 | -> multiset<__iter_value_type<_InputIterator>, _Compare, _Allocator>; |
| 1475 | 1605 | |
| 1606 | #if _LIBCPP_STD_VER >= 23 | |
| 1607 | template <ranges::input_range _Range, class _Compare = less<ranges::range_value_t<_Range>>, | |
| 1608 | class _Allocator = allocator<ranges::range_value_t<_Range>>, | |
| 1609 | class = enable_if_t<__is_allocator<_Allocator>::value, void>, | |
| 1610 | class = enable_if_t<!__is_allocator<_Compare>::value, void>> | |
| 1611 | multiset(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator()) | |
| 1612 | -> multiset<ranges::range_value_t<_Range>, _Compare, _Allocator>; | |
| 1613 | #endif | |
| 1614 | ||
| 1476 | 1615 | template<class _Key, class _Compare = less<_Key>, |
| 1477 | 1616 | class _Allocator = allocator<_Key>, |
| 1478 | 1617 | class = enable_if_t<__is_allocator<_Allocator>::value, void>, |
| ... | ... | @@ -1481,12 +1620,19 @@ multiset(initializer_list<_Key>, _Compare = _Compare(), _Allocator = _Allocator( |
| 1481 | 1620 | -> multiset<_Key, _Compare, _Allocator>; |
| 1482 | 1621 | |
| 1483 | 1622 | template<class _InputIterator, class _Allocator, |
| 1484 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value, void>, | |
| 1623 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>, | |
| 1485 | 1624 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 1486 | 1625 | multiset(_InputIterator, _InputIterator, _Allocator) |
| 1487 | 1626 | -> multiset<__iter_value_type<_InputIterator>, |
| 1488 | 1627 | less<__iter_value_type<_InputIterator>>, _Allocator>; |
| 1489 | 1628 | |
| 1629 | #if _LIBCPP_STD_VER >= 23 | |
| 1630 | template <ranges::input_range _Range, class _Allocator, | |
| 1631 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> | |
| 1632 | multiset(from_range_t, _Range&&, _Allocator) | |
| 1633 | -> multiset<ranges::range_value_t<_Range>, less<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1634 | #endif | |
| 1635 | ||
| 1490 | 1636 | template<class _Key, class _Allocator, |
| 1491 | 1637 | class = enable_if_t<__is_allocator<_Allocator>::value, void>> |
| 1492 | 1638 | multiset(initializer_list<_Key>, _Allocator) |
| ... | ... | @@ -1518,6 +1664,8 @@ operator==(const multiset<_Key, _Compare, _Allocator>& __x, |
| 1518 | 1664 | return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); |
| 1519 | 1665 | } |
| 1520 | 1666 | |
| 1667 | #if _LIBCPP_STD_VER <= 17 | |
| 1668 | ||
| 1521 | 1669 | template <class _Key, class _Compare, class _Allocator> |
| 1522 | 1670 | inline _LIBCPP_INLINE_VISIBILITY |
| 1523 | 1671 | bool |
| ... | ... | @@ -1563,6 +1711,17 @@ operator<=(const multiset<_Key, _Compare, _Allocator>& __x, |
| 1563 | 1711 | return !(__y < __x); |
| 1564 | 1712 | } |
| 1565 | 1713 | |
| 1714 | #else // _LIBCPP_STD_VER <= 17 | |
| 1715 | ||
| 1716 | template <class _Key, class _Allocator> | |
| 1717 | _LIBCPP_HIDE_FROM_ABI __synth_three_way_result<_Key> | |
| 1718 | operator<=>(const multiset<_Key, _Allocator>& __x, const multiset<_Key, _Allocator>& __y) { | |
| 1719 | return std::lexicographical_compare_three_way( | |
| 1720 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Key, _Key>); | |
| 1721 | } | |
| 1722 | ||
| 1723 | #endif // _LIBCPP_STD_VER <= 17 | |
| 1724 | ||
| 1566 | 1725 | template <class _Key, class _Compare, class _Allocator> |
| 1567 | 1726 | inline _LIBCPP_INLINE_VISIBILITY |
| 1568 | 1727 | void |
| ... | ... | @@ -1573,7 +1732,7 @@ swap(multiset<_Key, _Compare, _Allocator>& __x, |
| 1573 | 1732 | __x.swap(__y); |
| 1574 | 1733 | } |
| 1575 | 1734 | |
| 1576 | #if _LIBCPP_STD_VER > 17 | |
| 1735 | #if _LIBCPP_STD_VER >= 20 | |
| 1577 | 1736 | template <class _Key, class _Compare, class _Allocator, class _Predicate> |
| 1578 | 1737 | inline _LIBCPP_INLINE_VISIBILITY |
| 1579 | 1738 | typename multiset<_Key, _Compare, _Allocator>::size_type |
| ... | ... | @@ -1584,22 +1743,24 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 1584 | 1743 | |
| 1585 | 1744 | _LIBCPP_END_NAMESPACE_STD |
| 1586 | 1745 | |
| 1587 | #if _LIBCPP_STD_VER > 14 | |
| 1746 | #if _LIBCPP_STD_VER >= 17 | |
| 1588 | 1747 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 1589 | 1748 | namespace pmr { |
| 1590 | 1749 | template <class _KeyT, class _CompareT = std::less<_KeyT>> |
| 1591 | using set = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>; | |
| 1750 | using set _LIBCPP_AVAILABILITY_PMR = std::set<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>; | |
| 1592 | 1751 | |
| 1593 | 1752 | template <class _KeyT, class _CompareT = std::less<_KeyT>> |
| 1594 | using multiset = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>; | |
| 1753 | using multiset _LIBCPP_AVAILABILITY_PMR = std::multiset<_KeyT, _CompareT, polymorphic_allocator<_KeyT>>; | |
| 1595 | 1754 | } // namespace pmr |
| 1596 | 1755 | _LIBCPP_END_NAMESPACE_STD |
| 1597 | 1756 | #endif |
| 1598 | 1757 | |
| 1599 | 1758 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1600 | 1759 | # include <concepts> |
| 1760 | # include <cstdlib> | |
| 1601 | 1761 | # include <functional> |
| 1602 | 1762 | # include <iterator> |
| 1763 | # include <type_traits> | |
| 1603 | 1764 | #endif |
| 1604 | 1765 | |
| 1605 | 1766 | #endif // _LIBCPP_SET |
lib/libcxx/include/shared_mutex+262-305| ... | ... | @@ -124,386 +124,343 @@ template <class Mutex> |
| 124 | 124 | |
| 125 | 125 | #include <__assert> // all public C++ headers provide the assertion handler |
| 126 | 126 | #include <__availability> |
| 127 | #include <__chrono/duration.h> | |
| 128 | #include <__chrono/steady_clock.h> | |
| 129 | #include <__chrono/time_point.h> | |
| 130 | #include <__condition_variable/condition_variable.h> | |
| 127 | 131 | #include <__config> |
| 132 | #include <__memory/addressof.h> | |
| 133 | #include <__mutex/mutex.h> | |
| 134 | #include <__mutex/tag_types.h> | |
| 135 | #include <__mutex/unique_lock.h> | |
| 136 | #include <__system_error/system_error.h> | |
| 137 | #include <__utility/swap.h> | |
| 138 | #include <cerrno> | |
| 128 | 139 | #include <version> |
| 129 | 140 | |
| 130 | 141 | _LIBCPP_PUSH_MACROS |
| 131 | 142 | #include <__undef_macros> |
| 132 | 143 | |
| 144 | #if _LIBCPP_STD_VER >= 14 | |
| 133 | 145 | |
| 134 | #if _LIBCPP_STD_VER > 11 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 146 | # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 147 | # pragma GCC system_header | |
| 148 | # endif | |
| 135 | 149 | |
| 136 | #include <__mutex_base> | |
| 137 | ||
| 138 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 139 | # pragma GCC system_header | |
| 140 | #endif | |
| 141 | ||
| 142 | #ifdef _LIBCPP_HAS_NO_THREADS | |
| 143 | # error "<shared_mutex> is not supported since libc++ has been configured without support for threads." | |
| 144 | #endif | |
| 150 | # ifdef _LIBCPP_HAS_NO_THREADS | |
| 151 | # error "<shared_mutex> is not supported since libc++ has been configured without support for threads." | |
| 152 | # endif | |
| 145 | 153 | |
| 146 | 154 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 147 | 155 | |
| 148 | struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("shared_mutex")) | |
| 149 | __shared_mutex_base | |
| 150 | { | |
| 151 | mutex __mut_; | |
| 152 | condition_variable __gate1_; | |
| 153 | condition_variable __gate2_; | |
| 154 | unsigned __state_; | |
| 156 | struct _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base { | |
| 157 | mutex __mut_; | |
| 158 | condition_variable __gate1_; | |
| 159 | condition_variable __gate2_; | |
| 160 | unsigned __state_; | |
| 155 | 161 | |
| 156 | static const unsigned __write_entered_ = 1U << (sizeof(unsigned)*__CHAR_BIT__ - 1); | |
| 157 | static const unsigned __n_readers_ = ~__write_entered_; | |
| 162 | static const unsigned __write_entered_ = 1U << (sizeof(unsigned) * __CHAR_BIT__ - 1); | |
| 163 | static const unsigned __n_readers_ = ~__write_entered_; | |
| 158 | 164 | |
| 159 | __shared_mutex_base(); | |
| 160 | _LIBCPP_INLINE_VISIBILITY ~__shared_mutex_base() = default; | |
| 165 | __shared_mutex_base(); | |
| 166 | _LIBCPP_HIDE_FROM_ABI ~__shared_mutex_base() = default; | |
| 161 | 167 | |
| 162 | __shared_mutex_base(const __shared_mutex_base&) = delete; | |
| 163 | __shared_mutex_base& operator=(const __shared_mutex_base&) = delete; | |
| 168 | __shared_mutex_base(const __shared_mutex_base&) = delete; | |
| 169 | __shared_mutex_base& operator=(const __shared_mutex_base&) = delete; | |
| 164 | 170 | |
| 165 | // Exclusive ownership | |
| 166 | void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_capability()); // blocking | |
| 167 | bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)); | |
| 168 | void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability()); | |
| 171 | // Exclusive ownership | |
| 172 | void lock(); // blocking | |
| 173 | bool try_lock(); | |
| 174 | void unlock(); | |
| 169 | 175 | |
| 170 | // Shared ownership | |
| 171 | void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(acquire_shared_capability()); // blocking | |
| 172 | bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true)); | |
| 173 | void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(release_shared_capability()); | |
| 176 | // Shared ownership | |
| 177 | void lock_shared(); // blocking | |
| 178 | bool try_lock_shared(); | |
| 179 | void unlock_shared(); | |
| 174 | 180 | |
| 175 | // typedef implementation-defined native_handle_type; // See 30.2.3 | |
| 176 | // native_handle_type native_handle(); // See 30.2.3 | |
| 181 | // typedef implementation-defined native_handle_type; // See 30.2.3 | |
| 182 | // native_handle_type native_handle(); // See 30.2.3 | |
| 177 | 183 | }; |
| 178 | 184 | |
| 185 | # if _LIBCPP_STD_VER >= 17 | |
| 186 | class _LIBCPP_EXPORTED_FROM_ABI | |
| 187 | _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION(__capability__("shared_mutex")) shared_mutex { | |
| 188 | __shared_mutex_base __base_; | |
| 179 | 189 | |
| 180 | #if _LIBCPP_STD_VER > 14 | |
| 181 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_mutex | |
| 182 | { | |
| 183 | __shared_mutex_base __base_; | |
| 184 | 190 | public: |
| 185 | _LIBCPP_INLINE_VISIBILITY shared_mutex() : __base_() {} | |
| 186 | _LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default; | |
| 187 | ||
| 188 | shared_mutex(const shared_mutex&) = delete; | |
| 189 | shared_mutex& operator=(const shared_mutex&) = delete; | |
| 190 | ||
| 191 | // Exclusive ownership | |
| 192 | _LIBCPP_INLINE_VISIBILITY void lock() { return __base_.lock(); } | |
| 193 | _LIBCPP_INLINE_VISIBILITY bool try_lock() { return __base_.try_lock(); } | |
| 194 | _LIBCPP_INLINE_VISIBILITY void unlock() { return __base_.unlock(); } | |
| 195 | ||
| 196 | // Shared ownership | |
| 197 | _LIBCPP_INLINE_VISIBILITY void lock_shared() { return __base_.lock_shared(); } | |
| 198 | _LIBCPP_INLINE_VISIBILITY bool try_lock_shared() { return __base_.try_lock_shared(); } | |
| 199 | _LIBCPP_INLINE_VISIBILITY void unlock_shared() { return __base_.unlock_shared(); } | |
| 200 | ||
| 201 | // typedef __shared_mutex_base::native_handle_type native_handle_type; | |
| 202 | // _LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() { return __base::unlock_shared(); } | |
| 191 | _LIBCPP_HIDE_FROM_ABI shared_mutex() : __base_() {} | |
| 192 | _LIBCPP_HIDE_FROM_ABI ~shared_mutex() = default; | |
| 193 | ||
| 194 | shared_mutex(const shared_mutex&) = delete; | |
| 195 | shared_mutex& operator=(const shared_mutex&) = delete; | |
| 196 | ||
| 197 | // Exclusive ownership | |
| 198 | _LIBCPP_HIDE_FROM_ABI void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()) { | |
| 199 | return __base_.lock(); | |
| 200 | } | |
| 201 | _LIBCPP_HIDE_FROM_ABI bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) { | |
| 202 | return __base_.try_lock(); | |
| 203 | } | |
| 204 | _LIBCPP_HIDE_FROM_ABI void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()) { | |
| 205 | return __base_.unlock(); | |
| 206 | } | |
| 207 | ||
| 208 | // Shared ownership | |
| 209 | _LIBCPP_HIDE_FROM_ABI void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()) { | |
| 210 | return __base_.lock_shared(); | |
| 211 | } | |
| 212 | _LIBCPP_HIDE_FROM_ABI bool try_lock_shared() | |
| 213 | _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) { | |
| 214 | return __base_.try_lock_shared(); | |
| 215 | } | |
| 216 | _LIBCPP_HIDE_FROM_ABI void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()) { | |
| 217 | return __base_.unlock_shared(); | |
| 218 | } | |
| 219 | ||
| 220 | // typedef __shared_mutex_base::native_handle_type native_handle_type; | |
| 221 | // _LIBCPP_HIDE_FROM_ABI native_handle_type native_handle() { return __base::unlock_shared(); } | |
| 203 | 222 | }; |
| 204 | #endif | |
| 223 | # endif | |
| 205 | 224 | |
| 225 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_SHARED_MUTEX _LIBCPP_THREAD_SAFETY_ANNOTATION( | |
| 226 | __capability__("shared_timed_mutex")) shared_timed_mutex { | |
| 227 | __shared_mutex_base __base_; | |
| 206 | 228 | |
| 207 | class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_timed_mutex | |
| 208 | { | |
| 209 | __shared_mutex_base __base_; | |
| 210 | 229 | public: |
| 211 | shared_timed_mutex(); | |
| 212 | _LIBCPP_INLINE_VISIBILITY ~shared_timed_mutex() = default; | |
| 213 | ||
| 214 | shared_timed_mutex(const shared_timed_mutex&) = delete; | |
| 215 | shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; | |
| 216 | ||
| 217 | // Exclusive ownership | |
| 218 | void lock(); | |
| 219 | bool try_lock(); | |
| 220 | template <class _Rep, class _Period> | |
| 221 | _LIBCPP_INLINE_VISIBILITY | |
| 222 | bool | |
| 223 | try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) | |
| 224 | { | |
| 225 | return try_lock_until(chrono::steady_clock::now() + __rel_time); | |
| 226 | } | |
| 227 | template <class _Clock, class _Duration> | |
| 228 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 229 | bool | |
| 230 | try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time); | |
| 231 | void unlock(); | |
| 232 | ||
| 233 | // Shared ownership | |
| 234 | void lock_shared(); | |
| 235 | bool try_lock_shared(); | |
| 236 | template <class _Rep, class _Period> | |
| 237 | _LIBCPP_INLINE_VISIBILITY | |
| 238 | bool | |
| 239 | try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) | |
| 240 | { | |
| 241 | return try_lock_shared_until(chrono::steady_clock::now() + __rel_time); | |
| 242 | } | |
| 243 | template <class _Clock, class _Duration> | |
| 244 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 245 | bool | |
| 246 | try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time); | |
| 247 | void unlock_shared(); | |
| 230 | shared_timed_mutex(); | |
| 231 | _LIBCPP_HIDE_FROM_ABI ~shared_timed_mutex() = default; | |
| 232 | ||
| 233 | shared_timed_mutex(const shared_timed_mutex&) = delete; | |
| 234 | shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; | |
| 235 | ||
| 236 | // Exclusive ownership | |
| 237 | void lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_capability__()); | |
| 238 | bool try_lock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)); | |
| 239 | template <class _Rep, class _Period> | |
| 240 | _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time) | |
| 241 | _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)) { | |
| 242 | return try_lock_until(chrono::steady_clock::now() + __rel_time); | |
| 243 | } | |
| 244 | template <class _Clock, class _Duration> | |
| 245 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool | |
| 246 | try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 247 | _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_capability__(true)); | |
| 248 | void unlock() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_capability__()); | |
| 249 | ||
| 250 | // Shared ownership | |
| 251 | void lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__acquire_shared_capability__()); | |
| 252 | bool try_lock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)); | |
| 253 | template <class _Rep, class _Period> | |
| 254 | _LIBCPP_HIDE_FROM_ABI bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time) | |
| 255 | _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)) { | |
| 256 | return try_lock_shared_until(chrono::steady_clock::now() + __rel_time); | |
| 257 | } | |
| 258 | template <class _Clock, class _Duration> | |
| 259 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool | |
| 260 | try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 261 | _LIBCPP_THREAD_SAFETY_ANNOTATION(__try_acquire_shared_capability__(true)); | |
| 262 | void unlock_shared() _LIBCPP_THREAD_SAFETY_ANNOTATION(__release_shared_capability__()); | |
| 248 | 263 | }; |
| 249 | 264 | |
| 250 | 265 | template <class _Clock, class _Duration> |
| 251 | bool | |
| 252 | shared_timed_mutex::try_lock_until( | |
| 253 | const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 254 | { | |
| 255 | unique_lock<mutex> __lk(__base_.__mut_); | |
| 256 | if (__base_.__state_ & __base_.__write_entered_) | |
| 257 | { | |
| 258 | while (true) | |
| 259 | { | |
| 260 | cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time); | |
| 261 | if ((__base_.__state_ & __base_.__write_entered_) == 0) | |
| 262 | break; | |
| 263 | if (__status == cv_status::timeout) | |
| 264 | return false; | |
| 265 | } | |
| 266 | bool shared_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { | |
| 267 | unique_lock<mutex> __lk(__base_.__mut_); | |
| 268 | if (__base_.__state_ & __base_.__write_entered_) { | |
| 269 | while (true) { | |
| 270 | cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time); | |
| 271 | if ((__base_.__state_ & __base_.__write_entered_) == 0) | |
| 272 | break; | |
| 273 | if (__status == cv_status::timeout) | |
| 274 | return false; | |
| 266 | 275 | } |
| 267 | __base_.__state_ |= __base_.__write_entered_; | |
| 268 | if (__base_.__state_ & __base_.__n_readers_) | |
| 269 | { | |
| 270 | while (true) | |
| 271 | { | |
| 272 | cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time); | |
| 273 | if ((__base_.__state_ & __base_.__n_readers_) == 0) | |
| 274 | break; | |
| 275 | if (__status == cv_status::timeout) | |
| 276 | { | |
| 277 | __base_.__state_ &= ~__base_.__write_entered_; | |
| 278 | __base_.__gate1_.notify_all(); | |
| 279 | return false; | |
| 280 | } | |
| 281 | } | |
| 276 | } | |
| 277 | __base_.__state_ |= __base_.__write_entered_; | |
| 278 | if (__base_.__state_ & __base_.__n_readers_) { | |
| 279 | while (true) { | |
| 280 | cv_status __status = __base_.__gate2_.wait_until(__lk, __abs_time); | |
| 281 | if ((__base_.__state_ & __base_.__n_readers_) == 0) | |
| 282 | break; | |
| 283 | if (__status == cv_status::timeout) { | |
| 284 | __base_.__state_ &= ~__base_.__write_entered_; | |
| 285 | __base_.__gate1_.notify_all(); | |
| 286 | return false; | |
| 287 | } | |
| 282 | 288 | } |
| 283 | return true; | |
| 289 | } | |
| 290 | return true; | |
| 284 | 291 | } |
| 285 | 292 | |
| 286 | 293 | template <class _Clock, class _Duration> |
| 287 | bool | |
| 288 | shared_timed_mutex::try_lock_shared_until( | |
| 289 | const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 290 | { | |
| 291 | unique_lock<mutex> __lk(__base_.__mut_); | |
| 292 | if ((__base_.__state_ & __base_.__write_entered_) || (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) | |
| 293 | { | |
| 294 | while (true) | |
| 295 | { | |
| 296 | cv_status status = __base_.__gate1_.wait_until(__lk, __abs_time); | |
| 297 | if ((__base_.__state_ & __base_.__write_entered_) == 0 && | |
| 298 | (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_) | |
| 299 | break; | |
| 300 | if (status == cv_status::timeout) | |
| 301 | return false; | |
| 302 | } | |
| 294 | bool shared_timed_mutex::try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& __abs_time) { | |
| 295 | unique_lock<mutex> __lk(__base_.__mut_); | |
| 296 | if ((__base_.__state_ & __base_.__write_entered_) || | |
| 297 | (__base_.__state_ & __base_.__n_readers_) == __base_.__n_readers_) { | |
| 298 | while (true) { | |
| 299 | cv_status __status = __base_.__gate1_.wait_until(__lk, __abs_time); | |
| 300 | if ((__base_.__state_ & __base_.__write_entered_) == 0 && | |
| 301 | (__base_.__state_ & __base_.__n_readers_) < __base_.__n_readers_) | |
| 302 | break; | |
| 303 | if (__status == cv_status::timeout) | |
| 304 | return false; | |
| 303 | 305 | } |
| 304 | unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1; | |
| 305 | __base_.__state_ &= ~__base_.__n_readers_; | |
| 306 | __base_.__state_ |= __num_readers; | |
| 307 | return true; | |
| 306 | } | |
| 307 | unsigned __num_readers = (__base_.__state_ & __base_.__n_readers_) + 1; | |
| 308 | __base_.__state_ &= ~__base_.__n_readers_; | |
| 309 | __base_.__state_ |= __num_readers; | |
| 310 | return true; | |
| 308 | 311 | } |
| 309 | 312 | |
| 310 | 313 | template <class _Mutex> |
| 311 | class shared_lock | |
| 312 | { | |
| 314 | class shared_lock { | |
| 313 | 315 | public: |
| 314 | typedef _Mutex mutex_type; | |
| 316 | typedef _Mutex mutex_type; | |
| 315 | 317 | |
| 316 | 318 | private: |
| 317 | mutex_type* __m_; | |
| 318 | bool __owns_; | |
| 319 | mutex_type* __m_; | |
| 320 | bool __owns_; | |
| 319 | 321 | |
| 320 | 322 | public: |
| 321 | _LIBCPP_INLINE_VISIBILITY | |
| 322 | shared_lock() _NOEXCEPT | |
| 323 | : __m_(nullptr), | |
| 324 | __owns_(false) | |
| 325 | {} | |
| 326 | ||
| 327 | _LIBCPP_INLINE_VISIBILITY | |
| 328 | explicit shared_lock(mutex_type& __m) | |
| 329 | : __m_(_VSTD::addressof(__m)), | |
| 330 | __owns_(true) | |
| 331 | {__m_->lock_shared();} | |
| 332 | ||
| 333 | _LIBCPP_INLINE_VISIBILITY | |
| 334 | shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT | |
| 335 | : __m_(_VSTD::addressof(__m)), | |
| 336 | __owns_(false) | |
| 337 | {} | |
| 338 | ||
| 339 | _LIBCPP_INLINE_VISIBILITY | |
| 340 | shared_lock(mutex_type& __m, try_to_lock_t) | |
| 341 | : __m_(_VSTD::addressof(__m)), | |
| 342 | __owns_(__m.try_lock_shared()) | |
| 343 | {} | |
| 344 | ||
| 345 | _LIBCPP_INLINE_VISIBILITY | |
| 346 | shared_lock(mutex_type& __m, adopt_lock_t) | |
| 347 | : __m_(_VSTD::addressof(__m)), | |
| 348 | __owns_(true) | |
| 349 | {} | |
| 350 | ||
| 351 | template <class _Clock, class _Duration> | |
| 352 | _LIBCPP_INLINE_VISIBILITY | |
| 353 | shared_lock(mutex_type& __m, | |
| 354 | const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 355 | : __m_(_VSTD::addressof(__m)), | |
| 356 | __owns_(__m.try_lock_shared_until(__abs_time)) | |
| 357 | {} | |
| 358 | ||
| 359 | template <class _Rep, class _Period> | |
| 360 | _LIBCPP_INLINE_VISIBILITY | |
| 361 | shared_lock(mutex_type& __m, | |
| 362 | const chrono::duration<_Rep, _Period>& __rel_time) | |
| 363 | : __m_(_VSTD::addressof(__m)), | |
| 364 | __owns_(__m.try_lock_shared_for(__rel_time)) | |
| 365 | {} | |
| 366 | ||
| 367 | _LIBCPP_INLINE_VISIBILITY | |
| 368 | ~shared_lock() | |
| 369 | { | |
| 370 | if (__owns_) | |
| 371 | __m_->unlock_shared(); | |
| 372 | } | |
| 323 | _LIBCPP_HIDE_FROM_ABI shared_lock() _NOEXCEPT : __m_(nullptr), __owns_(false) {} | |
| 373 | 324 | |
| 374 | shared_lock(shared_lock const&) = delete; | |
| 375 | shared_lock& operator=(shared_lock const&) = delete; | |
| 325 | _LIBCPP_HIDE_FROM_ABI explicit shared_lock(mutex_type& __m) : __m_(_VSTD::addressof(__m)), __owns_(true) { | |
| 326 | __m_->lock_shared(); | |
| 327 | } | |
| 376 | 328 | |
| 377 | _LIBCPP_INLINE_VISIBILITY | |
| 378 | shared_lock(shared_lock&& __u) _NOEXCEPT | |
| 379 | : __m_(__u.__m_), | |
| 380 | __owns_(__u.__owns_) | |
| 381 | { | |
| 382 | __u.__m_ = nullptr; | |
| 383 | __u.__owns_ = false; | |
| 384 | } | |
| 385 | ||
| 386 | _LIBCPP_INLINE_VISIBILITY | |
| 387 | shared_lock& operator=(shared_lock&& __u) _NOEXCEPT | |
| 388 | { | |
| 389 | if (__owns_) | |
| 390 | __m_->unlock_shared(); | |
| 391 | __m_ = nullptr; | |
| 392 | __owns_ = false; | |
| 393 | __m_ = __u.__m_; | |
| 394 | __owns_ = __u.__owns_; | |
| 395 | __u.__m_ = nullptr; | |
| 396 | __u.__owns_ = false; | |
| 397 | return *this; | |
| 398 | } | |
| 329 | _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, defer_lock_t) _NOEXCEPT | |
| 330 | : __m_(_VSTD::addressof(__m)), | |
| 331 | __owns_(false) {} | |
| 399 | 332 | |
| 400 | void lock(); | |
| 401 | bool try_lock(); | |
| 402 | template <class Rep, class Period> | |
| 403 | bool try_lock_for(const chrono::duration<Rep, Period>& __rel_time); | |
| 404 | template <class Clock, class Duration> | |
| 405 | bool try_lock_until(const chrono::time_point<Clock, Duration>& __abs_time); | |
| 406 | void unlock(); | |
| 333 | _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, try_to_lock_t) | |
| 334 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared()) {} | |
| 407 | 335 | |
| 408 | // Setters | |
| 409 | _LIBCPP_INLINE_VISIBILITY | |
| 410 | void swap(shared_lock& __u) _NOEXCEPT | |
| 411 | { | |
| 412 | _VSTD::swap(__m_, __u.__m_); | |
| 413 | _VSTD::swap(__owns_, __u.__owns_); | |
| 414 | } | |
| 336 | _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, adopt_lock_t) : __m_(_VSTD::addressof(__m)), __owns_(true) {} | |
| 415 | 337 | |
| 416 | _LIBCPP_INLINE_VISIBILITY | |
| 417 | mutex_type* release() _NOEXCEPT | |
| 418 | { | |
| 419 | mutex_type* __m = __m_; | |
| 420 | __m_ = nullptr; | |
| 421 | __owns_ = false; | |
| 422 | return __m; | |
| 423 | } | |
| 338 | template <class _Clock, class _Duration> | |
| 339 | _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::time_point<_Clock, _Duration>& __abs_time) | |
| 340 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_until(__abs_time)) {} | |
| 424 | 341 | |
| 425 | // Getters | |
| 426 | _LIBCPP_INLINE_VISIBILITY | |
| 427 | bool owns_lock() const _NOEXCEPT {return __owns_;} | |
| 342 | template <class _Rep, class _Period> | |
| 343 | _LIBCPP_HIDE_FROM_ABI shared_lock(mutex_type& __m, const chrono::duration<_Rep, _Period>& __rel_time) | |
| 344 | : __m_(_VSTD::addressof(__m)), __owns_(__m.try_lock_shared_for(__rel_time)) {} | |
| 428 | 345 | |
| 429 | _LIBCPP_INLINE_VISIBILITY | |
| 430 | explicit operator bool () const _NOEXCEPT {return __owns_;} | |
| 346 | _LIBCPP_HIDE_FROM_ABI ~shared_lock() { | |
| 347 | if (__owns_) | |
| 348 | __m_->unlock_shared(); | |
| 349 | } | |
| 350 | ||
| 351 | shared_lock(shared_lock const&) = delete; | |
| 352 | shared_lock& operator=(shared_lock const&) = delete; | |
| 353 | ||
| 354 | _LIBCPP_HIDE_FROM_ABI shared_lock(shared_lock&& __u) _NOEXCEPT : __m_(__u.__m_), __owns_(__u.__owns_) { | |
| 355 | __u.__m_ = nullptr; | |
| 356 | __u.__owns_ = false; | |
| 357 | } | |
| 431 | 358 | |
| 432 | _LIBCPP_INLINE_VISIBILITY | |
| 433 | mutex_type* mutex() const _NOEXCEPT {return __m_;} | |
| 359 | _LIBCPP_HIDE_FROM_ABI shared_lock& operator=(shared_lock&& __u) _NOEXCEPT { | |
| 360 | if (__owns_) | |
| 361 | __m_->unlock_shared(); | |
| 362 | __m_ = nullptr; | |
| 363 | __owns_ = false; | |
| 364 | __m_ = __u.__m_; | |
| 365 | __owns_ = __u.__owns_; | |
| 366 | __u.__m_ = nullptr; | |
| 367 | __u.__owns_ = false; | |
| 368 | return *this; | |
| 369 | } | |
| 370 | ||
| 371 | _LIBCPP_HIDE_FROM_ABI void lock(); | |
| 372 | _LIBCPP_HIDE_FROM_ABI bool try_lock(); | |
| 373 | template <class _Rep, class _Period> | |
| 374 | _LIBCPP_HIDE_FROM_ABI bool try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time); | |
| 375 | template <class _Clock, class _Duration> | |
| 376 | _LIBCPP_HIDE_FROM_ABI bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time); | |
| 377 | _LIBCPP_HIDE_FROM_ABI void unlock(); | |
| 378 | ||
| 379 | // Setters | |
| 380 | _LIBCPP_HIDE_FROM_ABI void swap(shared_lock& __u) _NOEXCEPT { | |
| 381 | _VSTD::swap(__m_, __u.__m_); | |
| 382 | _VSTD::swap(__owns_, __u.__owns_); | |
| 383 | } | |
| 384 | ||
| 385 | _LIBCPP_HIDE_FROM_ABI mutex_type* release() _NOEXCEPT { | |
| 386 | mutex_type* __m = __m_; | |
| 387 | __m_ = nullptr; | |
| 388 | __owns_ = false; | |
| 389 | return __m; | |
| 390 | } | |
| 391 | ||
| 392 | // Getters | |
| 393 | _LIBCPP_HIDE_FROM_ABI bool owns_lock() const _NOEXCEPT { return __owns_; } | |
| 394 | ||
| 395 | _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __owns_; } | |
| 396 | ||
| 397 | _LIBCPP_HIDE_FROM_ABI mutex_type* mutex() const _NOEXCEPT { return __m_; } | |
| 434 | 398 | }; |
| 435 | 399 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(shared_lock); |
| 436 | 400 | |
| 437 | 401 | template <class _Mutex> |
| 438 | void | |
| 439 | shared_lock<_Mutex>::lock() | |
| 440 | { | |
| 441 | if (__m_ == nullptr) | |
| 442 | __throw_system_error(EPERM, "shared_lock::lock: references null mutex"); | |
| 443 | if (__owns_) | |
| 444 | __throw_system_error(EDEADLK, "shared_lock::lock: already locked"); | |
| 445 | __m_->lock_shared(); | |
| 446 | __owns_ = true; | |
| 402 | void shared_lock<_Mutex>::lock() { | |
| 403 | if (__m_ == nullptr) | |
| 404 | __throw_system_error(EPERM, "shared_lock::lock: references null mutex"); | |
| 405 | if (__owns_) | |
| 406 | __throw_system_error(EDEADLK, "shared_lock::lock: already locked"); | |
| 407 | __m_->lock_shared(); | |
| 408 | __owns_ = true; | |
| 447 | 409 | } |
| 448 | 410 | |
| 449 | 411 | template <class _Mutex> |
| 450 | bool | |
| 451 | shared_lock<_Mutex>::try_lock() | |
| 452 | { | |
| 453 | if (__m_ == nullptr) | |
| 454 | __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex"); | |
| 455 | if (__owns_) | |
| 456 | __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked"); | |
| 457 | __owns_ = __m_->try_lock_shared(); | |
| 458 | return __owns_; | |
| 412 | bool shared_lock<_Mutex>::try_lock() { | |
| 413 | if (__m_ == nullptr) | |
| 414 | __throw_system_error(EPERM, "shared_lock::try_lock: references null mutex"); | |
| 415 | if (__owns_) | |
| 416 | __throw_system_error(EDEADLK, "shared_lock::try_lock: already locked"); | |
| 417 | __owns_ = __m_->try_lock_shared(); | |
| 418 | return __owns_; | |
| 459 | 419 | } |
| 460 | 420 | |
| 461 | 421 | template <class _Mutex> |
| 462 | 422 | template <class _Rep, class _Period> |
| 463 | bool | |
| 464 | shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) | |
| 465 | { | |
| 466 | if (__m_ == nullptr) | |
| 467 | __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex"); | |
| 468 | if (__owns_) | |
| 469 | __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked"); | |
| 470 | __owns_ = __m_->try_lock_shared_for(__d); | |
| 471 | return __owns_; | |
| 423 | bool shared_lock<_Mutex>::try_lock_for(const chrono::duration<_Rep, _Period>& __d) { | |
| 424 | if (__m_ == nullptr) | |
| 425 | __throw_system_error(EPERM, "shared_lock::try_lock_for: references null mutex"); | |
| 426 | if (__owns_) | |
| 427 | __throw_system_error(EDEADLK, "shared_lock::try_lock_for: already locked"); | |
| 428 | __owns_ = __m_->try_lock_shared_for(__d); | |
| 429 | return __owns_; | |
| 472 | 430 | } |
| 473 | 431 | |
| 474 | 432 | template <class _Mutex> |
| 475 | 433 | template <class _Clock, class _Duration> |
| 476 | bool | |
| 477 | shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
| 478 | { | |
| 479 | if (__m_ == nullptr) | |
| 480 | __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex"); | |
| 481 | if (__owns_) | |
| 482 | __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked"); | |
| 483 | __owns_ = __m_->try_lock_shared_until(__t); | |
| 484 | return __owns_; | |
| 434 | bool shared_lock<_Mutex>::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { | |
| 435 | if (__m_ == nullptr) | |
| 436 | __throw_system_error(EPERM, "shared_lock::try_lock_until: references null mutex"); | |
| 437 | if (__owns_) | |
| 438 | __throw_system_error(EDEADLK, "shared_lock::try_lock_until: already locked"); | |
| 439 | __owns_ = __m_->try_lock_shared_until(__t); | |
| 440 | return __owns_; | |
| 485 | 441 | } |
| 486 | 442 | |
| 487 | 443 | template <class _Mutex> |
| 488 | void | |
| 489 | shared_lock<_Mutex>::unlock() | |
| 490 | { | |
| 491 | if (!__owns_) | |
| 492 | __throw_system_error(EPERM, "shared_lock::unlock: not locked"); | |
| 493 | __m_->unlock_shared(); | |
| 494 | __owns_ = false; | |
| 444 | void shared_lock<_Mutex>::unlock() { | |
| 445 | if (!__owns_) | |
| 446 | __throw_system_error(EPERM, "shared_lock::unlock: not locked"); | |
| 447 | __m_->unlock_shared(); | |
| 448 | __owns_ = false; | |
| 495 | 449 | } |
| 496 | 450 | |
| 497 | 451 | template <class _Mutex> |
| 498 | inline _LIBCPP_INLINE_VISIBILITY | |
| 499 | void | |
| 500 | swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT | |
| 501 | {__x.swap(__y);} | |
| 452 | inline _LIBCPP_HIDE_FROM_ABI void swap(shared_lock<_Mutex>& __x, shared_lock<_Mutex>& __y) _NOEXCEPT { | |
| 453 | __x.swap(__y); | |
| 454 | } | |
| 502 | 455 | |
| 503 | 456 | _LIBCPP_END_NAMESPACE_STD |
| 504 | 457 | |
| 505 | #endif // _LIBCPP_STD_VER > 11 | |
| 458 | #endif // _LIBCPP_STD_VER >= 14 | |
| 506 | 459 | |
| 507 | 460 | _LIBCPP_POP_MACROS |
| 508 | 461 | |
| 462 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 463 | # include <system_error> | |
| 464 | #endif | |
| 465 | ||
| 509 | 466 | #endif // _LIBCPP_SHARED_MUTEX |
lib/libcxx/include/span+57-50| ... | ... | @@ -71,7 +71,6 @@ public: |
| 71 | 71 | constexpr span(const span& other) noexcept = default; |
| 72 | 72 | template <class OtherElementType, size_t OtherExtent> |
| 73 | 73 | constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; |
| 74 | ~span() noexcept = default; | |
| 75 | 74 | constexpr span& operator=(const span& other) noexcept = default; |
| 76 | 75 | |
| 77 | 76 | // [span.sub], span subviews |
| ... | ... | @@ -129,7 +128,6 @@ template<class R> |
| 129 | 128 | |
| 130 | 129 | #include <__assert> // all public C++ headers provide the assertion handler |
| 131 | 130 | #include <__config> |
| 132 | #include <__debug> | |
| 133 | 131 | #include <__fwd/span.h> |
| 134 | 132 | #include <__iterator/bounded_iter.h> |
| 135 | 133 | #include <__iterator/concepts.h> |
| ... | ... | @@ -141,11 +139,14 @@ template<class R> |
| 141 | 139 | #include <__ranges/enable_borrowed_range.h> |
| 142 | 140 | #include <__ranges/enable_view.h> |
| 143 | 141 | #include <__ranges/size.h> |
| 142 | #include <__type_traits/is_convertible.h> | |
| 143 | #include <__type_traits/remove_cvref.h> | |
| 144 | #include <__type_traits/remove_reference.h> | |
| 145 | #include <__type_traits/type_identity.h> | |
| 144 | 146 | #include <__utility/forward.h> |
| 145 | 147 | #include <array> // for array |
| 146 | 148 | #include <cstddef> // for byte |
| 147 | 149 | #include <limits> |
| 148 | #include <type_traits> // for remove_cv, etc | |
| 149 | 150 | #include <version> |
| 150 | 151 | |
| 151 | 152 | // standard-mandated includes |
| ... | ... | @@ -166,7 +167,7 @@ _LIBCPP_PUSH_MACROS |
| 166 | 167 | |
| 167 | 168 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 168 | 169 | |
| 169 | #if _LIBCPP_STD_VER > 17 | |
| 170 | #if _LIBCPP_STD_VER >= 20 | |
| 170 | 171 | |
| 171 | 172 | template <class _Tp> |
| 172 | 173 | struct __is_std_array : false_type {}; |
| ... | ... | @@ -211,7 +212,7 @@ public: |
| 211 | 212 | using const_pointer = const _Tp *; |
| 212 | 213 | using reference = _Tp &; |
| 213 | 214 | using const_reference = const _Tp &; |
| 214 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 215 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 215 | 216 | using iterator = __bounded_iter<pointer>; |
| 216 | 217 | #else |
| 217 | 218 | using iterator = __wrap_iter<pointer>; |
| ... | ... | @@ -232,16 +233,18 @@ public: |
| 232 | 233 | constexpr explicit span(_It __first, size_type __count) |
| 233 | 234 | : __data_{_VSTD::to_address(__first)} { |
| 234 | 235 | (void)__count; |
| 235 | _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); | |
| 236 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); | |
| 236 | 237 | } |
| 237 | 238 | |
| 238 | 239 | template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> |
| 239 | 240 | _LIBCPP_INLINE_VISIBILITY |
| 240 | 241 | constexpr explicit span(_It __first, _End __last) : __data_{_VSTD::to_address(__first)} { |
| 241 | (void)__last; | |
| 242 | _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)"); | |
| 243 | _LIBCPP_ASSERT(__last - __first == _Extent, | |
| 244 | "invalid range in span's constructor (iterator, sentinel): last - first != extent"); | |
| 242 | // [span.cons]/10 | |
| 243 | // Throws: When and what last - first throws. | |
| 244 | [[maybe_unused]] auto __dist = __last - __first; | |
| 245 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); | |
| 246 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 247 | __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); | |
| 245 | 248 | } |
| 246 | 249 | |
| 247 | 250 | _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} |
| ... | ... | @@ -258,7 +261,8 @@ public: |
| 258 | 261 | template <__span_compatible_range<element_type> _Range> |
| 259 | 262 | _LIBCPP_INLINE_VISIBILITY |
| 260 | 263 | constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { |
| 261 | _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); | |
| 264 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 265 | ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); | |
| 262 | 266 | } |
| 263 | 267 | |
| 264 | 268 | template <__span_array_convertible<element_type> _OtherElementType> |
| ... | ... | @@ -269,10 +273,10 @@ public: |
| 269 | 273 | template <__span_array_convertible<element_type> _OtherElementType> |
| 270 | 274 | _LIBCPP_INLINE_VISIBILITY |
| 271 | 275 | constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept |
| 272 | : __data_{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } | |
| 273 | ||
| 274 | ||
| 275 | // ~span() noexcept = default; | |
| 276 | : __data_{__other.data()} { | |
| 277 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 278 | _Extent == __other.size(), "size mismatch in span's constructor (other span)"); | |
| 279 | } | |
| 276 | 280 | |
| 277 | 281 | template <size_t _Count> |
| 278 | 282 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -293,14 +297,14 @@ public: |
| 293 | 297 | _LIBCPP_INLINE_VISIBILITY |
| 294 | 298 | constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept |
| 295 | 299 | { |
| 296 | _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range"); | |
| 300 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); | |
| 297 | 301 | return {data(), __count}; |
| 298 | 302 | } |
| 299 | 303 | |
| 300 | 304 | _LIBCPP_INLINE_VISIBILITY |
| 301 | 305 | constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept |
| 302 | 306 | { |
| 303 | _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range"); | |
| 307 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); | |
| 304 | 308 | return {data() + size() - __count, __count}; |
| 305 | 309 | } |
| 306 | 310 | |
| ... | ... | @@ -321,11 +325,12 @@ public: |
| 321 | 325 | constexpr span<element_type, dynamic_extent> |
| 322 | 326 | subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept |
| 323 | 327 | { |
| 324 | _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); | |
| 325 | _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range"); | |
| 328 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 329 | __offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); | |
| 326 | 330 | if (__count == dynamic_extent) |
| 327 | 331 | return {data() + __offset, size() - __offset}; |
| 328 | _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); | |
| 332 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 333 | __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); | |
| 329 | 334 | return {data() + __offset, __count}; |
| 330 | 335 | } |
| 331 | 336 | |
| ... | ... | @@ -335,19 +340,19 @@ public: |
| 335 | 340 | |
| 336 | 341 | _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept |
| 337 | 342 | { |
| 338 | _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range"); | |
| 343 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); | |
| 339 | 344 | return __data_[__idx]; |
| 340 | 345 | } |
| 341 | 346 | |
| 342 | 347 | _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept |
| 343 | 348 | { |
| 344 | _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span"); | |
| 349 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); | |
| 345 | 350 | return __data_[0]; |
| 346 | 351 | } |
| 347 | 352 | |
| 348 | 353 | _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept |
| 349 | 354 | { |
| 350 | _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span"); | |
| 355 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); | |
| 351 | 356 | return __data_[size()-1]; |
| 352 | 357 | } |
| 353 | 358 | |
| ... | ... | @@ -355,17 +360,17 @@ public: |
| 355 | 360 | |
| 356 | 361 | // [span.iter], span iterator support |
| 357 | 362 | _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { |
| 358 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 363 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 359 | 364 | return std::__make_bounded_iter(data(), data(), data() + size()); |
| 360 | 365 | #else |
| 361 | return iterator(this, data()); | |
| 366 | return iterator(data()); | |
| 362 | 367 | #endif |
| 363 | 368 | } |
| 364 | 369 | _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { |
| 365 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 370 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 366 | 371 | return std::__make_bounded_iter(data() + size(), data(), data() + size()); |
| 367 | 372 | #else |
| 368 | return iterator(this, data() + size()); | |
| 373 | return iterator(data() + size()); | |
| 369 | 374 | #endif |
| 370 | 375 | } |
| 371 | 376 | _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } |
| ... | ... | @@ -394,7 +399,7 @@ public: |
| 394 | 399 | using const_pointer = const _Tp *; |
| 395 | 400 | using reference = _Tp &; |
| 396 | 401 | using const_reference = const _Tp &; |
| 397 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 402 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 398 | 403 | using iterator = __bounded_iter<pointer>; |
| 399 | 404 | #else |
| 400 | 405 | using iterator = __wrap_iter<pointer>; |
| ... | ... | @@ -417,7 +422,8 @@ public: |
| 417 | 422 | template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> |
| 418 | 423 | _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last) |
| 419 | 424 | : __data_(_VSTD::to_address(__first)), __size_(__last - __first) { |
| 420 | _LIBCPP_ASSERT(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); | |
| 425 | _LIBCPP_ASSERT_VALID_INPUT_RANGE( | |
| 426 | __last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); | |
| 421 | 427 | } |
| 422 | 428 | |
| 423 | 429 | template <size_t _Sz> |
| ... | ... | @@ -442,13 +448,11 @@ public: |
| 442 | 448 | constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept |
| 443 | 449 | : __data_{__other.data()}, __size_{__other.size()} {} |
| 444 | 450 | |
| 445 | // ~span() noexcept = default; | |
| 446 | ||
| 447 | 451 | template <size_t _Count> |
| 448 | 452 | _LIBCPP_INLINE_VISIBILITY |
| 449 | 453 | constexpr span<element_type, _Count> first() const noexcept |
| 450 | 454 | { |
| 451 | _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range"); | |
| 455 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); | |
| 452 | 456 | return span<element_type, _Count>{data(), _Count}; |
| 453 | 457 | } |
| 454 | 458 | |
| ... | ... | @@ -456,21 +460,21 @@ public: |
| 456 | 460 | _LIBCPP_INLINE_VISIBILITY |
| 457 | 461 | constexpr span<element_type, _Count> last() const noexcept |
| 458 | 462 | { |
| 459 | _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range"); | |
| 463 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); | |
| 460 | 464 | return span<element_type, _Count>{data() + size() - _Count, _Count}; |
| 461 | 465 | } |
| 462 | 466 | |
| 463 | 467 | _LIBCPP_INLINE_VISIBILITY |
| 464 | 468 | constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept |
| 465 | 469 | { |
| 466 | _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range"); | |
| 470 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); | |
| 467 | 471 | return {data(), __count}; |
| 468 | 472 | } |
| 469 | 473 | |
| 470 | 474 | _LIBCPP_INLINE_VISIBILITY |
| 471 | 475 | constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept |
| 472 | 476 | { |
| 473 | _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range"); | |
| 477 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); | |
| 474 | 478 | return {data() + size() - __count, __count}; |
| 475 | 479 | } |
| 476 | 480 | |
| ... | ... | @@ -478,8 +482,10 @@ public: |
| 478 | 482 | _LIBCPP_INLINE_VISIBILITY |
| 479 | 483 | constexpr span<element_type, _Count> subspan() const noexcept |
| 480 | 484 | { |
| 481 | _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); | |
| 482 | _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); | |
| 485 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 486 | _Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); | |
| 487 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, | |
| 488 | "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); | |
| 483 | 489 | return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; |
| 484 | 490 | } |
| 485 | 491 | |
| ... | ... | @@ -487,11 +493,11 @@ public: |
| 487 | 493 | _LIBCPP_INLINE_VISIBILITY |
| 488 | 494 | subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept |
| 489 | 495 | { |
| 490 | _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); | |
| 491 | _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range"); | |
| 496 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); | |
| 492 | 497 | if (__count == dynamic_extent) |
| 493 | 498 | return {data() + __offset, size() - __offset}; |
| 494 | _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); | |
| 499 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 500 | __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); | |
| 495 | 501 | return {data() + __offset, __count}; |
| 496 | 502 | } |
| 497 | 503 | |
| ... | ... | @@ -501,19 +507,19 @@ public: |
| 501 | 507 | |
| 502 | 508 | _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept |
| 503 | 509 | { |
| 504 | _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range"); | |
| 510 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); | |
| 505 | 511 | return __data_[__idx]; |
| 506 | 512 | } |
| 507 | 513 | |
| 508 | 514 | _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept |
| 509 | 515 | { |
| 510 | _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span"); | |
| 516 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); | |
| 511 | 517 | return __data_[0]; |
| 512 | 518 | } |
| 513 | 519 | |
| 514 | 520 | _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept |
| 515 | 521 | { |
| 516 | _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span"); | |
| 522 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); | |
| 517 | 523 | return __data_[size()-1]; |
| 518 | 524 | } |
| 519 | 525 | |
| ... | ... | @@ -522,17 +528,17 @@ public: |
| 522 | 528 | |
| 523 | 529 | // [span.iter], span iterator support |
| 524 | 530 | _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { |
| 525 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 531 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 526 | 532 | return std::__make_bounded_iter(data(), data(), data() + size()); |
| 527 | 533 | #else |
| 528 | return iterator(this, data()); | |
| 534 | return iterator(data()); | |
| 529 | 535 | #endif |
| 530 | 536 | } |
| 531 | 537 | _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { |
| 532 | #ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING | |
| 538 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 533 | 539 | return std::__make_bounded_iter(data() + size(), data(), data() + size()); |
| 534 | 540 | #else |
| 535 | return iterator(this, data() + size()); | |
| 541 | return iterator(data() + size()); | |
| 536 | 542 | #endif |
| 537 | 543 | } |
| 538 | 544 | _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } |
| ... | ... | @@ -566,10 +572,10 @@ _LIBCPP_INLINE_VISIBILITY |
| 566 | 572 | auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept |
| 567 | 573 | { return __s.__as_writable_bytes(); } |
| 568 | 574 | |
| 569 | #if _LIBCPP_STD_VER > 17 | |
| 575 | #if _LIBCPP_STD_VER >= 20 | |
| 570 | 576 | template<contiguous_iterator _It, class _EndOrSize> |
| 571 | 577 | span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; |
| 572 | #endif // _LIBCPP_STD_VER > 17 | |
| 578 | #endif // _LIBCPP_STD_VER >= 20 | |
| 573 | 579 | |
| 574 | 580 | template<class _Tp, size_t _Sz> |
| 575 | 581 | span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; |
| ... | ... | @@ -583,7 +589,7 @@ template<class _Tp, size_t _Sz> |
| 583 | 589 | template<ranges::contiguous_range _Range> |
| 584 | 590 | span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; |
| 585 | 591 | |
| 586 | #endif // _LIBCPP_STD_VER > 17 | |
| 592 | #endif // _LIBCPP_STD_VER >= 20 | |
| 587 | 593 | |
| 588 | 594 | _LIBCPP_END_NAMESPACE_STD |
| 589 | 595 | |
| ... | ... | @@ -593,6 +599,7 @@ _LIBCPP_POP_MACROS |
| 593 | 599 | # include <concepts> |
| 594 | 600 | # include <functional> |
| 595 | 601 | # include <iterator> |
| 602 | # include <type_traits> | |
| 596 | 603 | #endif |
| 597 | 604 | |
| 598 | 605 | #endif // _LIBCPP_SPAN |
lib/libcxx/include/sstream+403-82| ... | ... | @@ -30,17 +30,41 @@ public: |
| 30 | 30 | explicit basic_stringbuf(ios_base::openmode which = ios_base::in | ios_base::out); // before C++20 |
| 31 | 31 | basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} // C++20 |
| 32 | 32 | explicit basic_stringbuf(ios_base::openmode which); // C++20 |
| 33 | explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& str, | |
| 33 | explicit basic_stringbuf(const basic_string<char_type, traits_type, allocator_type>& s, | |
| 34 | 34 | ios_base::openmode which = ios_base::in | ios_base::out); |
| 35 | explicit basic_stringbuf(const allocator_type& a) | |
| 36 | : basic_stringbuf(ios_base::in | ios_base::out, a) {} // C++20 | |
| 37 | basic_stringbuf(ios_base::openmode which, const allocator_type& a); // C++20 | |
| 38 | explicit basic_stringbuf(basic_string<char_type, traits_type, allocator_type>&& s, | |
| 39 | ios_base::openmode which = ios_base::in | ios_base::out); // C++20 | |
| 40 | template <class SAlloc> | |
| 41 | basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a) | |
| 42 | : basic_stringbuf(s, ios_base::in | ios_base::out, a) {} // C++20 | |
| 43 | template <class SAlloc> | |
| 44 | basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 45 | ios_base::openmode which, const allocator_type& a); // C++20 | |
| 46 | template <class SAlloc> | |
| 47 | explicit basic_stringbuf(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 48 | ios_base::openmode which = ios_base::in | ios_base::out); // C++20 | |
| 35 | 49 | basic_stringbuf(basic_stringbuf&& rhs); |
| 50 | basic_stringbuf(basic_stringbuf&& rhs, const allocator_type& a); // C++20 | |
| 36 | 51 | |
| 37 | 52 | // [stringbuf.assign] Assign and swap: |
| 38 | 53 | basic_stringbuf& operator=(basic_stringbuf&& rhs); |
| 39 | void swap(basic_stringbuf& rhs); | |
| 54 | void swap(basic_stringbuf& rhs) noexcept(see below); // conditionally noexcept since C++20 | |
| 40 | 55 | |
| 41 | 56 | // [stringbuf.members] Member functions: |
| 42 | basic_string<char_type, traits_type, allocator_type> str() const; | |
| 57 | allocator_type get_allocator() const noexcept; // C++20 | |
| 58 | basic_string<char_type, traits_type, allocator_type> str() const; // before C++20 | |
| 59 | basic_string<char_type, traits_type, allocator_type> str() const &; // C++20 | |
| 60 | template <class SAlloc> | |
| 61 | basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20 | |
| 62 | basic_string<char_type, traits_type, allocator_type> str() &&; // C++20 | |
| 63 | basic_string_view<char_type, traits_type> view() const noexcept; // C++20 | |
| 43 | 64 | void str(const basic_string<char_type, traits_type, allocator_type>& s); |
| 65 | template <class SAlloc> | |
| 66 | void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20 | |
| 67 | void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20 | |
| 44 | 68 | |
| 45 | 69 | protected: |
| 46 | 70 | // [stringbuf.virtuals] Overridden virtual functions: |
| ... | ... | @@ -56,8 +80,8 @@ protected: |
| 56 | 80 | |
| 57 | 81 | // [stringbuf.assign] non member swap |
| 58 | 82 | template <class charT, class traits, class Allocator> |
| 59 | void swap(basic_stringbuf<charT, traits, Allocator>& x, | |
| 60 | basic_stringbuf<charT, traits, Allocator>& y); | |
| 83 | void swap(basic_stringbuf<charT, traits, Allocator>& x, | |
| 84 | basic_stringbuf<charT, traits, Allocator>& y); // conditionally noexcept since C++20 | |
| 61 | 85 | |
| 62 | 86 | typedef basic_stringbuf<char> stringbuf; |
| 63 | 87 | typedef basic_stringbuf<wchar_t> wstringbuf; |
| ... | ... | @@ -76,12 +100,23 @@ public: |
| 76 | 100 | typedef Allocator allocator_type; |
| 77 | 101 | |
| 78 | 102 | // [istringstream.cons] Constructors: |
| 79 | explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20 | |
| 80 | basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20 | |
| 81 | explicit basic_istringstream(ios_base::openmode which); // C++20 | |
| 82 | ||
| 83 | explicit basic_istringstream(const basic_string<char_type, traits_type,allocator_type>& str, | |
| 103 | explicit basic_istringstream(ios_base::openmode which = ios_base::in); // before C++20 | |
| 104 | basic_istringstream() : basic_istringstream(ios_base::in) {} // C++20 | |
| 105 | explicit basic_istringstream(ios_base::openmode which); // C++20 | |
| 106 | explicit basic_istringstream(const basic_string<char_type, traits_type, allocator_type>& s, | |
| 84 | 107 | ios_base::openmode which = ios_base::in); |
| 108 | basic_istringstream(ios_base::openmode which, const allocator_type& a); // C++20 | |
| 109 | explicit basic_istringstream(basic_string<char_type, traits_type, allocator_type>&& s, | |
| 110 | ios_base::openmode which = ios_base::in); // C++20 | |
| 111 | template <class SAlloc> | |
| 112 | basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a) | |
| 113 | : basic_istringstream(s, ios_base::in, a) {} // C++20 | |
| 114 | template <class SAlloc> | |
| 115 | basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 116 | ios_base::openmode which, const allocator_type& a); // C++20 | |
| 117 | template <class SAlloc> | |
| 118 | explicit basic_istringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 119 | ios_base::openmode which = ios_base::in); // C++20 | |
| 85 | 120 | basic_istringstream(basic_istringstream&& rhs); |
| 86 | 121 | |
| 87 | 122 | // [istringstream.assign] Assign and swap: |
| ... | ... | @@ -90,13 +125,21 @@ public: |
| 90 | 125 | |
| 91 | 126 | // [istringstream.members] Member functions: |
| 92 | 127 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; |
| 93 | basic_string<char_type, traits_type, allocator_type> str() const; | |
| 128 | basic_string<char_type, traits_type, allocator_type> str() const; // before C++20 | |
| 129 | basic_string<char_type, traits_type, allocator_type> str() const &; // C++20 | |
| 130 | template <class SAlloc> | |
| 131 | basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20 | |
| 132 | basic_string<char_type, traits_type, allocator_type> str() &&; // C++20 | |
| 133 | basic_string_view<char_type, traits_type> view() const noexcept; // C++20 | |
| 94 | 134 | void str(const basic_string<char_type, traits_type, allocator_type>& s); |
| 135 | template <class SAlloc> | |
| 136 | void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20 | |
| 137 | void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20 | |
| 95 | 138 | }; |
| 96 | 139 | |
| 97 | 140 | template <class charT, class traits, class Allocator> |
| 98 | void swap(basic_istringstream<charT, traits, Allocator>& x, | |
| 99 | basic_istringstream<charT, traits, Allocator>& y); | |
| 141 | void swap(basic_istringstream<charT, traits, Allocator>& x, | |
| 142 | basic_istringstream<charT, traits, Allocator>& y); | |
| 100 | 143 | |
| 101 | 144 | typedef basic_istringstream<char> istringstream; |
| 102 | 145 | typedef basic_istringstream<wchar_t> wistringstream; |
| ... | ... | @@ -116,12 +159,23 @@ public: |
| 116 | 159 | typedef Allocator allocator_type; |
| 117 | 160 | |
| 118 | 161 | // [ostringstream.cons] Constructors: |
| 119 | explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20 | |
| 120 | basic_ostringstream() : basic_ostringstream(ios_base::out) {} // C++20 | |
| 121 | explicit basic_ostringstream(ios_base::openmode which); // C++20 | |
| 122 | ||
| 123 | explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& str, | |
| 162 | explicit basic_ostringstream(ios_base::openmode which = ios_base::out); // before C++20 | |
| 163 | basic_ostringstream() : basic_ostringstream(ios_base::out) {} // C++20 | |
| 164 | explicit basic_ostringstream(ios_base::openmode which); // C++20 | |
| 165 | explicit basic_ostringstream(const basic_string<char_type, traits_type, allocator_type>& s, | |
| 124 | 166 | ios_base::openmode which = ios_base::out); |
| 167 | basic_ostringstream(ios_base::openmode which, const allocator_type& a); // C++20 | |
| 168 | explicit basic_ostringstream(basic_string<char_type, traits_type, allocator_type>&& s, | |
| 169 | ios_base::openmode which = ios_base::out); // C++20 | |
| 170 | template <class SAlloc> | |
| 171 | basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a) | |
| 172 | : basic_ostringstream(s, ios_base::out, a) {} // C++20 | |
| 173 | template <class SAlloc> | |
| 174 | basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 175 | ios_base::openmode which, const allocator_type& a); // C++20 | |
| 176 | template <class SAlloc> | |
| 177 | explicit basic_ostringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 178 | ios_base::openmode which = ios_base::out); // C++20 | |
| 125 | 179 | basic_ostringstream(basic_ostringstream&& rhs); |
| 126 | 180 | |
| 127 | 181 | // [ostringstream.assign] Assign and swap: |
| ... | ... | @@ -130,13 +184,21 @@ public: |
| 130 | 184 | |
| 131 | 185 | // [ostringstream.members] Member functions: |
| 132 | 186 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; |
| 133 | basic_string<char_type, traits_type, allocator_type> str() const; | |
| 187 | basic_string<char_type, traits_type, allocator_type> str() const; // before C++20 | |
| 188 | basic_string<char_type, traits_type, allocator_type> str() const &; // C++20 | |
| 189 | template <class SAlloc> | |
| 190 | basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20 | |
| 191 | basic_string<char_type, traits_type, allocator_type> str() &&; // C++20 | |
| 192 | basic_string_view<char_type, traits_type> view() const noexcept; // C++20 | |
| 134 | 193 | void str(const basic_string<char_type, traits_type, allocator_type>& s); |
| 194 | template <class SAlloc> | |
| 195 | void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20 | |
| 196 | void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20 | |
| 135 | 197 | }; |
| 136 | 198 | |
| 137 | 199 | template <class charT, class traits, class Allocator> |
| 138 | void swap(basic_ostringstream<charT, traits, Allocator>& x, | |
| 139 | basic_ostringstream<charT, traits, Allocator>& y); | |
| 200 | void swap(basic_ostringstream<charT, traits, Allocator>& x, | |
| 201 | basic_ostringstream<charT, traits, Allocator>& y); | |
| 140 | 202 | |
| 141 | 203 | typedef basic_ostringstream<char> ostringstream; |
| 142 | 204 | typedef basic_ostringstream<wchar_t> wostringstream; |
| ... | ... | @@ -159,9 +221,20 @@ public: |
| 159 | 221 | explicit basic_stringstream(ios_base::openmode which = ios_base::out | ios_base::in); // before C++20 |
| 160 | 222 | basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} // C++20 |
| 161 | 223 | explicit basic_stringstream(ios_base::openmode which); // C++20 |
| 162 | ||
| 163 | explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& str, | |
| 164 | ios_base::openmode which = ios_base::out|ios_base::in); | |
| 224 | explicit basic_stringstream(const basic_string<char_type, traits_type, allocator_type>& s, | |
| 225 | ios_base::openmode which = ios_base::out | ios_base::in); | |
| 226 | basic_stringstream(ios_base::openmode which, const allocator_type& a); // C++20 | |
| 227 | explicit basic_stringstream(basic_string<char_type, traits_type, allocator_type>&& s, | |
| 228 | ios_base::openmode which = ios_base::out | ios_base::in); // C++20 | |
| 229 | template <class SAlloc> | |
| 230 | basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, const allocator_type& a) | |
| 231 | : basic_stringstream(s, ios_base::out | ios_base::in, a) {} // C++20 | |
| 232 | template <class SAlloc> | |
| 233 | basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 234 | ios_base::openmode which, const allocator_type& a); // C++20 | |
| 235 | template <class SAlloc> | |
| 236 | explicit basic_stringstream(const basic_string<char_type, traits_type, SAlloc>& s, | |
| 237 | ios_base::openmode which = ios_base::out | ios_base::in); // C++20 | |
| 165 | 238 | basic_stringstream(basic_stringstream&& rhs); |
| 166 | 239 | |
| 167 | 240 | // [stringstream.assign] Assign and swap: |
| ... | ... | @@ -170,13 +243,21 @@ public: |
| 170 | 243 | |
| 171 | 244 | // [stringstream.members] Member functions: |
| 172 | 245 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const; |
| 173 | basic_string<char_type, traits_type, allocator_type> str() const; | |
| 174 | void str(const basic_string<char_type, traits_type, allocator_type>& str); | |
| 246 | basic_string<char_type, traits_type, allocator_type> str() const; // before C++20 | |
| 247 | basic_string<char_type, traits_type, allocator_type> str() const &; // C++20 | |
| 248 | template <class SAlloc> | |
| 249 | basic_string<char_type, traits_type, SAlloc> str(const SAlloc& sa) const; // C++20 | |
| 250 | basic_string<char_type, traits_type, allocator_type> str() &&; // C++20 | |
| 251 | basic_string_view<char_type, traits_type> view() const noexcept; // C++20 | |
| 252 | void str(const basic_string<char_type, traits_type, allocator_type>& s); | |
| 253 | template <class SAlloc> | |
| 254 | void str(const basic_string<char_type, traits_type, SAlloc>& s); // C++20 | |
| 255 | void str(basic_string<char_type, traits_type, allocator_type>&& s); // C++20 | |
| 175 | 256 | }; |
| 176 | 257 | |
| 177 | 258 | template <class charT, class traits, class Allocator> |
| 178 | void swap(basic_stringstream<charT, traits, Allocator>& x, | |
| 179 | basic_stringstream<charT, traits, Allocator>& y); | |
| 259 | void swap(basic_stringstream<charT, traits, Allocator>& x, | |
| 260 | basic_stringstream<charT, traits, Allocator>& y); | |
| 180 | 261 | |
| 181 | 262 | typedef basic_stringstream<char> stringstream; |
| 182 | 263 | typedef basic_stringstream<wchar_t> wstringstream; |
| ... | ... | @@ -187,6 +268,7 @@ typedef basic_stringstream<wchar_t> wstringstream; |
| 187 | 268 | |
| 188 | 269 | #include <__assert> // all public C++ headers provide the assertion handler |
| 189 | 270 | #include <__config> |
| 271 | #include <__fwd/sstream.h> | |
| 190 | 272 | #include <__utility/swap.h> |
| 191 | 273 | #include <istream> |
| 192 | 274 | #include <ostream> |
| ... | ... | @@ -201,6 +283,14 @@ _LIBCPP_PUSH_MACROS |
| 201 | 283 | #include <__undef_macros> |
| 202 | 284 | |
| 203 | 285 | |
| 286 | // TODO(LLVM-19): Remove this once we drop support for Clang 16, | |
| 287 | // which had this bug: https://github.com/llvm/llvm-project/issues/40363 | |
| 288 | #ifdef _WIN32 | |
| 289 | #define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_ALWAYS_INLINE | |
| 290 | #else | |
| 291 | #define _LIBCPP_HIDE_FROM_ABI_SSTREAM _LIBCPP_HIDE_FROM_ABI | |
| 292 | #endif | |
| 293 | ||
| 204 | 294 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 205 | 295 | |
| 206 | 296 | // Class template basic_stringbuf [stringbuf] |
| ... | ... | @@ -224,6 +314,8 @@ private: |
| 224 | 314 | string_type __str_; |
| 225 | 315 | mutable char_type* __hm_; |
| 226 | 316 | ios_base::openmode __mode_; |
| 317 | _LIBCPP_HIDE_FROM_ABI void __init_buf_ptrs(); | |
| 318 | _LIBCPP_HIDE_FROM_ABI void __move_init(basic_stringbuf&& __rhs); | |
| 227 | 319 | |
| 228 | 320 | public: |
| 229 | 321 | // [stringbuf.cons] constructors: |
| ... | ... | @@ -243,15 +335,110 @@ public: |
| 243 | 335 | str(__s); |
| 244 | 336 | } |
| 245 | 337 | |
| 246 | basic_stringbuf(basic_stringbuf&& __rhs); | |
| 338 | #if _LIBCPP_STD_VER >= 20 | |
| 339 | _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const allocator_type& __a) | |
| 340 | : basic_stringbuf(ios_base::in | ios_base::out, __a) {} | |
| 341 | ||
| 342 | _LIBCPP_HIDE_FROM_ABI basic_stringbuf(ios_base::openmode __wch, const allocator_type& __a) | |
| 343 | : __str_(__a), __hm_(nullptr), __mode_(__wch) {} | |
| 344 | ||
| 345 | _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(string_type&& __s, | |
| 346 | ios_base::openmode __wch = ios_base::in | ios_base::out) | |
| 347 | : __str_(std::move(__s)), __hm_(nullptr), __mode_(__wch) { | |
| 348 | __init_buf_ptrs(); | |
| 349 | } | |
| 350 | ||
| 351 | template <class _SAlloc> | |
| 352 | _LIBCPP_HIDE_FROM_ABI | |
| 353 | basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, const allocator_type& __a) | |
| 354 | : basic_stringbuf(__s, ios_base::in | ios_base::out, __a) {} | |
| 355 | ||
| 356 | template <class _SAlloc> | |
| 357 | _LIBCPP_HIDE_FROM_ABI basic_stringbuf( | |
| 358 | const basic_string<char_type, traits_type, _SAlloc>& __s, ios_base::openmode __wch, const allocator_type& __a) | |
| 359 | : __str_(__s, __a), __hm_(nullptr), __mode_(__wch) { | |
| 360 | __init_buf_ptrs(); | |
| 361 | } | |
| 362 | ||
| 363 | template <class _SAlloc> | |
| 364 | requires (!is_same_v<_SAlloc, allocator_type>) | |
| 365 | _LIBCPP_HIDE_FROM_ABI explicit basic_stringbuf(const basic_string<char_type, traits_type, _SAlloc>& __s, | |
| 366 | ios_base::openmode __wch = ios_base::in | ios_base::out) | |
| 367 | : __str_(__s), __hm_(nullptr), __mode_(__wch) { | |
| 368 | __init_buf_ptrs(); | |
| 369 | } | |
| 370 | #endif // _LIBCPP_STD_VER >= 20 | |
| 371 | ||
| 372 | basic_stringbuf(basic_stringbuf&& __rhs) : __mode_(__rhs.__mode_) { __move_init(std::move(__rhs)); } | |
| 373 | ||
| 374 | #if _LIBCPP_STD_VER >= 20 | |
| 375 | _LIBCPP_HIDE_FROM_ABI basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a) | |
| 376 | : basic_stringbuf(__rhs.__mode_, __a) { | |
| 377 | __move_init(std::move(__rhs)); | |
| 378 | } | |
| 379 | #endif | |
| 247 | 380 | |
| 248 | 381 | // [stringbuf.assign] Assign and swap: |
| 249 | 382 | basic_stringbuf& operator=(basic_stringbuf&& __rhs); |
| 250 | void swap(basic_stringbuf& __rhs); | |
| 383 | void swap(basic_stringbuf& __rhs) | |
| 384 | #if _LIBCPP_STD_VER >= 20 | |
| 385 | noexcept(allocator_traits<allocator_type>::propagate_on_container_swap::value || | |
| 386 | allocator_traits<allocator_type>::is_always_equal::value) | |
| 387 | #endif | |
| 388 | ; | |
| 251 | 389 | |
| 252 | 390 | // [stringbuf.members] Member functions: |
| 391 | ||
| 392 | #if _LIBCPP_STD_VER >= 20 | |
| 393 | _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const noexcept { return __str_.get_allocator(); } | |
| 394 | #endif | |
| 395 | ||
| 396 | #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 253 | 397 | string_type str() const; |
| 254 | void str(const string_type& __s); | |
| 398 | #else | |
| 399 | _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() const & { return str(__str_.get_allocator()); } | |
| 400 | ||
| 401 | _LIBCPP_HIDE_FROM_ABI_SSTREAM string_type str() && { | |
| 402 | string_type __result; | |
| 403 | const basic_string_view<_CharT, _Traits> __view = view(); | |
| 404 | if (!__view.empty()) { | |
| 405 | auto __pos = __view.data() - __str_.data(); | |
| 406 | __result.assign(std::move(__str_), __pos, __view.size()); | |
| 407 | } | |
| 408 | __str_.clear(); | |
| 409 | __init_buf_ptrs(); | |
| 410 | return __result; | |
| 411 | } | |
| 412 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 413 | ||
| 414 | #if _LIBCPP_STD_VER >= 20 | |
| 415 | template <class _SAlloc> | |
| 416 | requires __is_allocator<_SAlloc>::value | |
| 417 | _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const { | |
| 418 | return basic_string<_CharT, _Traits, _SAlloc>(view(), __sa); | |
| 419 | } | |
| 420 | ||
| 421 | _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept; | |
| 422 | #endif | |
| 423 | ||
| 424 | void str(const string_type& __s) { | |
| 425 | __str_ = __s; | |
| 426 | __init_buf_ptrs(); | |
| 427 | } | |
| 428 | ||
| 429 | #if _LIBCPP_STD_VER >= 20 | |
| 430 | template <class _SAlloc> | |
| 431 | requires (!is_same_v<_SAlloc, allocator_type>) | |
| 432 | _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) { | |
| 433 | __str_ = __s; | |
| 434 | __init_buf_ptrs(); | |
| 435 | } | |
| 436 | ||
| 437 | _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { | |
| 438 | __str_ = std::move(__s); | |
| 439 | __init_buf_ptrs(); | |
| 440 | } | |
| 441 | #endif // _LIBCPP_STD_VER >= 20 | |
| 255 | 442 | |
| 256 | 443 | protected: |
| 257 | 444 | // [stringbuf.virtuals] Overridden virtual functions: |
| ... | ... | @@ -268,9 +455,7 @@ protected: |
| 268 | 455 | }; |
| 269 | 456 | |
| 270 | 457 | template <class _CharT, class _Traits, class _Allocator> |
| 271 | basic_stringbuf<_CharT, _Traits, _Allocator>::basic_stringbuf(basic_stringbuf&& __rhs) | |
| 272 | : __mode_(__rhs.__mode_) | |
| 273 | { | |
| 458 | _LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__move_init(basic_stringbuf&& __rhs) { | |
| 274 | 459 | char_type* __p = const_cast<char_type*>(__rhs.__str_.data()); |
| 275 | 460 | ptrdiff_t __binp = -1; |
| 276 | 461 | ptrdiff_t __ninp = -1; |
| ... | ... | @@ -359,6 +544,10 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::operator=(basic_stringbuf&& __rhs) |
| 359 | 544 | template <class _CharT, class _Traits, class _Allocator> |
| 360 | 545 | void |
| 361 | 546 | basic_stringbuf<_CharT, _Traits, _Allocator>::swap(basic_stringbuf& __rhs) |
| 547 | #if _LIBCPP_STD_VER >= 20 | |
| 548 | noexcept(allocator_traits<_Allocator>::propagate_on_container_swap::value || | |
| 549 | allocator_traits<_Allocator>::is_always_equal::value) | |
| 550 | #endif | |
| 362 | 551 | { |
| 363 | 552 | char_type* __p = const_cast<char_type*>(__rhs.__str_.data()); |
| 364 | 553 | ptrdiff_t __rbinp = -1; |
| ... | ... | @@ -438,49 +627,42 @@ inline _LIBCPP_INLINE_VISIBILITY |
| 438 | 627 | void |
| 439 | 628 | swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, |
| 440 | 629 | basic_stringbuf<_CharT, _Traits, _Allocator>& __y) |
| 630 | #if _LIBCPP_STD_VER >= 20 | |
| 631 | noexcept(noexcept(__x.swap(__y))) | |
| 632 | #endif | |
| 441 | 633 | { |
| 442 | 634 | __x.swap(__y); |
| 443 | 635 | } |
| 444 | 636 | |
| 637 | #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 445 | 638 | template <class _CharT, class _Traits, class _Allocator> |
| 446 | 639 | basic_string<_CharT, _Traits, _Allocator> |
| 447 | basic_stringbuf<_CharT, _Traits, _Allocator>::str() const | |
| 448 | { | |
| 449 | if (__mode_ & ios_base::out) | |
| 450 | { | |
| 640 | basic_stringbuf<_CharT, _Traits, _Allocator>::str() const { | |
| 641 | if (__mode_ & ios_base::out) { | |
| 451 | 642 | if (__hm_ < this->pptr()) |
| 452 | 643 | __hm_ = this->pptr(); |
| 453 | 644 | return string_type(this->pbase(), __hm_, __str_.get_allocator()); |
| 454 | } | |
| 455 | else if (__mode_ & ios_base::in) | |
| 645 | } else if (__mode_ & ios_base::in) | |
| 456 | 646 | return string_type(this->eback(), this->egptr(), __str_.get_allocator()); |
| 457 | 647 | return string_type(__str_.get_allocator()); |
| 458 | 648 | } |
| 649 | #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 459 | 650 | |
| 460 | 651 | template <class _CharT, class _Traits, class _Allocator> |
| 461 | void | |
| 462 | basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s) | |
| 463 | { | |
| 464 | __str_ = __s; | |
| 652 | _LIBCPP_HIDE_FROM_ABI void basic_stringbuf<_CharT, _Traits, _Allocator>::__init_buf_ptrs() { | |
| 465 | 653 | __hm_ = nullptr; |
| 466 | if (__mode_ & ios_base::in) | |
| 467 | { | |
| 468 | __hm_ = const_cast<char_type*>(__str_.data()) + __str_.size(); | |
| 469 | this->setg(const_cast<char_type*>(__str_.data()), | |
| 470 | const_cast<char_type*>(__str_.data()), | |
| 471 | __hm_); | |
| 654 | char_type* __data = const_cast<char_type*>(__str_.data()); | |
| 655 | typename string_type::size_type __sz = __str_.size(); | |
| 656 | if (__mode_ & ios_base::in) { | |
| 657 | __hm_ = __data + __sz; | |
| 658 | this->setg(__data, __data, __hm_); | |
| 472 | 659 | } |
| 473 | if (__mode_ & ios_base::out) | |
| 474 | { | |
| 475 | typename string_type::size_type __sz = __str_.size(); | |
| 476 | __hm_ = const_cast<char_type*>(__str_.data()) + __sz; | |
| 660 | if (__mode_ & ios_base::out) { | |
| 661 | __hm_ = __data + __sz; | |
| 477 | 662 | __str_.resize(__str_.capacity()); |
| 478 | this->setp(const_cast<char_type*>(__str_.data()), | |
| 479 | const_cast<char_type*>(__str_.data()) + __str_.size()); | |
| 480 | if (__mode_ & (ios_base::app | ios_base::ate)) | |
| 481 | { | |
| 482 | while (__sz > INT_MAX) | |
| 483 | { | |
| 663 | this->setp(__data, __data + __str_.size()); | |
| 664 | if (__mode_ & (ios_base::app | ios_base::ate)) { | |
| 665 | while (__sz > INT_MAX) { | |
| 484 | 666 | this->pbump(INT_MAX); |
| 485 | 667 | __sz -= INT_MAX; |
| 486 | 668 | } |
| ... | ... | @@ -490,6 +672,20 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::str(const string_type& __s) |
| 490 | 672 | } |
| 491 | 673 | } |
| 492 | 674 | |
| 675 | #if _LIBCPP_STD_VER >= 20 | |
| 676 | template <class _CharT, class _Traits, class _Allocator> | |
| 677 | _LIBCPP_HIDE_FROM_ABI basic_string_view<_CharT, _Traits> | |
| 678 | basic_stringbuf<_CharT, _Traits, _Allocator>::view() const noexcept { | |
| 679 | if (__mode_ & ios_base::out) { | |
| 680 | if (__hm_ < this->pptr()) | |
| 681 | __hm_ = this->pptr(); | |
| 682 | return basic_string_view<_CharT, _Traits>(this->pbase(), __hm_); | |
| 683 | } else if (__mode_ & ios_base::in) | |
| 684 | return basic_string_view<_CharT, _Traits>(this->eback(), this->egptr()); | |
| 685 | return basic_string_view<_CharT, _Traits>(); | |
| 686 | } | |
| 687 | #endif // _LIBCPP_STD_VER >= 20 | |
| 688 | ||
| 493 | 689 | template <class _CharT, class _Traits, class _Allocator> |
| 494 | 690 | typename basic_stringbuf<_CharT, _Traits, _Allocator>::int_type |
| 495 | 691 | basic_stringbuf<_CharT, _Traits, _Allocator>::underflow() |
| ... | ... | @@ -536,16 +732,16 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c) |
| 536 | 732 | { |
| 537 | 733 | if (!traits_type::eq_int_type(__c, traits_type::eof())) |
| 538 | 734 | { |
| 539 | ptrdiff_t __ninp = this->gptr() - this->eback(); | |
| 735 | ptrdiff_t __ninp = this->gptr() - this->eback(); | |
| 540 | 736 | if (this->pptr() == this->epptr()) |
| 541 | 737 | { |
| 542 | 738 | if (!(__mode_ & ios_base::out)) |
| 543 | 739 | return traits_type::eof(); |
| 544 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 740 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 545 | 741 | try |
| 546 | 742 | { |
| 547 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 548 | ptrdiff_t __nout = this->pptr() - this->pbase(); | |
| 743 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 744 | ptrdiff_t __nout = this->pptr() - this->pbase(); | |
| 549 | 745 | ptrdiff_t __hm = __hm_ - this->pbase(); |
| 550 | 746 | __str_.push_back(char_type()); |
| 551 | 747 | __str_.resize(__str_.capacity()); |
| ... | ... | @@ -553,13 +749,13 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::overflow(int_type __c) |
| 553 | 749 | this->setp(__p, __p + __str_.size()); |
| 554 | 750 | this->__pbump(__nout); |
| 555 | 751 | __hm_ = this->pbase() + __hm; |
| 556 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 752 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 557 | 753 | } |
| 558 | 754 | catch (...) |
| 559 | 755 | { |
| 560 | 756 | return traits_type::eof(); |
| 561 | 757 | } |
| 562 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 758 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 563 | 759 | } |
| 564 | 760 | __hm_ = _VSTD::max(this->pptr() + 1, __hm_); |
| 565 | 761 | if (__mode_ & ios_base::in) |
| ... | ... | @@ -619,7 +815,7 @@ basic_stringbuf<_CharT, _Traits, _Allocator>::seekoff(off_type __off, |
| 619 | 815 | if (__wch & ios_base::out) |
| 620 | 816 | { |
| 621 | 817 | this->setp(this->pbase(), this->epptr()); |
| 622 | this->pbump(__noff); | |
| 818 | this->__pbump(__noff); | |
| 623 | 819 | } |
| 624 | 820 | return pos_type(__noff); |
| 625 | 821 | } |
| ... | ... | @@ -660,6 +856,28 @@ public: |
| 660 | 856 | , __sb_(__s, __wch | ios_base::in) |
| 661 | 857 | { } |
| 662 | 858 | |
| 859 | #if _LIBCPP_STD_VER >= 20 | |
| 860 | _LIBCPP_HIDE_FROM_ABI basic_istringstream(ios_base::openmode __wch, const _Allocator& __a) | |
| 861 | : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::in, __a) {} | |
| 862 | ||
| 863 | _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(string_type&& __s, ios_base::openmode __wch = ios_base::in) | |
| 864 | : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::in) {} | |
| 865 | ||
| 866 | template <class _SAlloc> | |
| 867 | _LIBCPP_HIDE_FROM_ABI basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a) | |
| 868 | : basic_istringstream(__s, ios_base::in, __a) {} | |
| 869 | ||
| 870 | template <class _SAlloc> | |
| 871 | _LIBCPP_HIDE_FROM_ABI basic_istringstream( | |
| 872 | const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a) | |
| 873 | : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in, __a) {} | |
| 874 | ||
| 875 | template <class _SAlloc> | |
| 876 | _LIBCPP_HIDE_FROM_ABI explicit basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, | |
| 877 | ios_base::openmode __wch = ios_base::in) | |
| 878 | : basic_istream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::in) {} | |
| 879 | #endif // _LIBCPP_STD_VER >= 20 | |
| 880 | ||
| 663 | 881 | _LIBCPP_INLINE_VISIBILITY |
| 664 | 882 | basic_istringstream(basic_istringstream&& __rhs) |
| 665 | 883 | : basic_istream<_CharT, _Traits>(_VSTD::move(__rhs)) |
| ... | ... | @@ -685,14 +903,33 @@ public: |
| 685 | 903 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const { |
| 686 | 904 | return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_); |
| 687 | 905 | } |
| 688 | _LIBCPP_INLINE_VISIBILITY | |
| 689 | string_type str() const { | |
| 690 | return __sb_.str(); | |
| 906 | ||
| 907 | #if _LIBCPP_STD_VER >= 20 | |
| 908 | _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); } | |
| 909 | ||
| 910 | template <class _SAlloc> | |
| 911 | requires __is_allocator<_SAlloc>::value | |
| 912 | _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const { | |
| 913 | return __sb_.str(__sa); | |
| 691 | 914 | } |
| 692 | _LIBCPP_INLINE_VISIBILITY | |
| 693 | void str(const string_type& __s) { | |
| 915 | ||
| 916 | _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); } | |
| 917 | ||
| 918 | _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); } | |
| 919 | #else // _LIBCPP_STD_VER >= 20 | |
| 920 | _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); } | |
| 921 | #endif // _LIBCPP_STD_VER >= 20 | |
| 922 | ||
| 923 | _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); } | |
| 924 | ||
| 925 | #if _LIBCPP_STD_VER >= 20 | |
| 926 | template <class _SAlloc> | |
| 927 | _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) { | |
| 694 | 928 | __sb_.str(__s); |
| 695 | 929 | } |
| 930 | ||
| 931 | _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); } | |
| 932 | #endif // _LIBCPP_STD_VER >= 20 | |
| 696 | 933 | }; |
| 697 | 934 | |
| 698 | 935 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -740,6 +977,29 @@ public: |
| 740 | 977 | , __sb_(__s, __wch | ios_base::out) |
| 741 | 978 | { } |
| 742 | 979 | |
| 980 | #if _LIBCPP_STD_VER >= 20 | |
| 981 | _LIBCPP_HIDE_FROM_ABI basic_ostringstream(ios_base::openmode __wch, const _Allocator& __a) | |
| 982 | : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch | ios_base::out, __a) {} | |
| 983 | ||
| 984 | _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out) | |
| 985 | : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch | ios_base::out) {} | |
| 986 | ||
| 987 | template <class _SAlloc> | |
| 988 | _LIBCPP_HIDE_FROM_ABI basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a) | |
| 989 | : basic_ostringstream(__s, ios_base::out, __a) {} | |
| 990 | ||
| 991 | template <class _SAlloc> | |
| 992 | _LIBCPP_HIDE_FROM_ABI basic_ostringstream( | |
| 993 | const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a) | |
| 994 | : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out, __a) {} | |
| 995 | ||
| 996 | template <class _SAlloc> | |
| 997 | requires (!is_same_v<_SAlloc, allocator_type>) | |
| 998 | _LIBCPP_HIDE_FROM_ABI explicit basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, | |
| 999 | ios_base::openmode __wch = ios_base::out) | |
| 1000 | : basic_ostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch | ios_base::out) {} | |
| 1001 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1002 | ||
| 743 | 1003 | _LIBCPP_INLINE_VISIBILITY |
| 744 | 1004 | basic_ostringstream(basic_ostringstream&& __rhs) |
| 745 | 1005 | : basic_ostream<_CharT, _Traits>(_VSTD::move(__rhs)) |
| ... | ... | @@ -766,14 +1026,33 @@ public: |
| 766 | 1026 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const { |
| 767 | 1027 | return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_); |
| 768 | 1028 | } |
| 769 | _LIBCPP_INLINE_VISIBILITY | |
| 770 | string_type str() const { | |
| 771 | return __sb_.str(); | |
| 1029 | ||
| 1030 | #if _LIBCPP_STD_VER >= 20 | |
| 1031 | _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); } | |
| 1032 | ||
| 1033 | template <class _SAlloc> | |
| 1034 | requires __is_allocator<_SAlloc>::value | |
| 1035 | _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const { | |
| 1036 | return __sb_.str(__sa); | |
| 772 | 1037 | } |
| 773 | _LIBCPP_INLINE_VISIBILITY | |
| 774 | void str(const string_type& __s) { | |
| 1038 | ||
| 1039 | _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); } | |
| 1040 | ||
| 1041 | _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); } | |
| 1042 | #else // _LIBCPP_STD_VER >= 20 | |
| 1043 | _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); } | |
| 1044 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1045 | ||
| 1046 | _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); } | |
| 1047 | ||
| 1048 | #if _LIBCPP_STD_VER >= 20 | |
| 1049 | template <class _SAlloc> | |
| 1050 | _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) { | |
| 775 | 1051 | __sb_.str(__s); |
| 776 | 1052 | } |
| 1053 | ||
| 1054 | _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); } | |
| 1055 | #endif // _LIBCPP_STD_VER >= 20 | |
| 777 | 1056 | }; |
| 778 | 1057 | |
| 779 | 1058 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -821,6 +1100,29 @@ public: |
| 821 | 1100 | , __sb_(__s, __wch) |
| 822 | 1101 | { } |
| 823 | 1102 | |
| 1103 | #if _LIBCPP_STD_VER >= 20 | |
| 1104 | _LIBCPP_HIDE_FROM_ABI basic_stringstream(ios_base::openmode __wch, const _Allocator& __a) | |
| 1105 | : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__wch, __a) {} | |
| 1106 | ||
| 1107 | _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(string_type&& __s, ios_base::openmode __wch = ios_base::out | ios_base::in) | |
| 1108 | : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(std::move(__s), __wch) {} | |
| 1109 | ||
| 1110 | template <class _SAlloc> | |
| 1111 | _LIBCPP_HIDE_FROM_ABI basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, const _Allocator& __a) | |
| 1112 | : basic_stringstream(__s, ios_base::out | ios_base::in, __a) {} | |
| 1113 | ||
| 1114 | template <class _SAlloc> | |
| 1115 | _LIBCPP_HIDE_FROM_ABI basic_stringstream( | |
| 1116 | const basic_string<_CharT, _Traits, _SAlloc>& __s, ios_base::openmode __wch, const _Allocator& __a) | |
| 1117 | : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch, __a) {} | |
| 1118 | ||
| 1119 | template <class _SAlloc> | |
| 1120 | requires (!is_same_v<_SAlloc, allocator_type>) | |
| 1121 | _LIBCPP_HIDE_FROM_ABI explicit basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __s, | |
| 1122 | ios_base::openmode __wch = ios_base::out | ios_base::in) | |
| 1123 | : basic_iostream<_CharT, _Traits>(std::addressof(__sb_)), __sb_(__s, __wch) {} | |
| 1124 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1125 | ||
| 824 | 1126 | _LIBCPP_INLINE_VISIBILITY |
| 825 | 1127 | basic_stringstream(basic_stringstream&& __rhs) |
| 826 | 1128 | : basic_iostream<_CharT, _Traits>(_VSTD::move(__rhs)) |
| ... | ... | @@ -846,14 +1148,33 @@ public: |
| 846 | 1148 | basic_stringbuf<char_type, traits_type, allocator_type>* rdbuf() const { |
| 847 | 1149 | return const_cast<basic_stringbuf<char_type, traits_type, allocator_type>*>(&__sb_); |
| 848 | 1150 | } |
| 849 | _LIBCPP_INLINE_VISIBILITY | |
| 850 | string_type str() const { | |
| 851 | return __sb_.str(); | |
| 1151 | ||
| 1152 | #if _LIBCPP_STD_VER >= 20 | |
| 1153 | _LIBCPP_HIDE_FROM_ABI string_type str() const & { return __sb_.str(); } | |
| 1154 | ||
| 1155 | template <class _SAlloc> | |
| 1156 | requires __is_allocator<_SAlloc>::value | |
| 1157 | _LIBCPP_HIDE_FROM_ABI basic_string<char_type, traits_type, _SAlloc> str(const _SAlloc& __sa) const { | |
| 1158 | return __sb_.str(__sa); | |
| 852 | 1159 | } |
| 853 | _LIBCPP_INLINE_VISIBILITY | |
| 854 | void str(const string_type& __s) { | |
| 1160 | ||
| 1161 | _LIBCPP_HIDE_FROM_ABI string_type str() && { return std::move(__sb_).str(); } | |
| 1162 | ||
| 1163 | _LIBCPP_HIDE_FROM_ABI basic_string_view<char_type, traits_type> view() const noexcept { return __sb_.view(); } | |
| 1164 | #else // _LIBCPP_STD_VER >= 20 | |
| 1165 | _LIBCPP_HIDE_FROM_ABI string_type str() const { return __sb_.str(); } | |
| 1166 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1167 | ||
| 1168 | _LIBCPP_HIDE_FROM_ABI void str(const string_type& __s) { __sb_.str(__s); } | |
| 1169 | ||
| 1170 | #if _LIBCPP_STD_VER >= 20 | |
| 1171 | template <class _SAlloc> | |
| 1172 | _LIBCPP_HIDE_FROM_ABI void str(const basic_string<char_type, traits_type, _SAlloc>& __s) { | |
| 855 | 1173 | __sb_.str(__s); |
| 856 | 1174 | } |
| 1175 | ||
| 1176 | _LIBCPP_HIDE_FROM_ABI void str(string_type&& __s) { __sb_.str(std::move(__s)); } | |
| 1177 | #endif // _LIBCPP_STD_VER >= 20 | |
| 857 | 1178 | }; |
| 858 | 1179 | |
| 859 | 1180 | template <class _CharT, class _Traits, class _Allocator> |
lib/libcxx/include/stack+82-13| ... | ... | @@ -42,6 +42,7 @@ public: |
| 42 | 42 | explicit stack(const container_type& c); |
| 43 | 43 | explicit stack(container_type&& c); |
| 44 | 44 | template <class InputIterator> stack(InputIterator first, InputIterator last); // since C++23 |
| 45 | template<container-compatible-range<T> R> stack(from_range_t, R&& rg); // since C++23 | |
| 45 | 46 | template <class Alloc> explicit stack(const Alloc& a); |
| 46 | 47 | template <class Alloc> stack(const container_type& c, const Alloc& a); |
| 47 | 48 | template <class Alloc> stack(container_type&& c, const Alloc& a); |
| ... | ... | @@ -49,6 +50,8 @@ public: |
| 49 | 50 | template <class Alloc> stack(stack&& c, const Alloc& a); |
| 50 | 51 | template<class InputIterator, class Alloc> |
| 51 | 52 | stack(InputIterator first, InputIterator last, const Alloc&); // since C++23 |
| 53 | template<container-compatible-range<T> R, class Alloc> | |
| 54 | stack(from_range_t, R&& rg, const Alloc&); // since C++23 | |
| 52 | 55 | |
| 53 | 56 | bool empty() const; |
| 54 | 57 | size_type size() const; |
| ... | ... | @@ -57,6 +60,8 @@ public: |
| 57 | 60 | |
| 58 | 61 | void push(const value_type& x); |
| 59 | 62 | void push(value_type&& x); |
| 63 | template<container-compatible-range<T> R> | |
| 64 | void push_range(R&& rg); // C++23 | |
| 60 | 65 | template <class... Args> reference emplace(Args&&... args); // reference in C++17 |
| 61 | 66 | void pop(); |
| 62 | 67 | |
| ... | ... | @@ -69,6 +74,9 @@ template<class Container> |
| 69 | 74 | template<class InputIterator> |
| 70 | 75 | stack(InputIterator, InputIterator) -> stack<iter-value-type<InputIterator>>; // since C++23 |
| 71 | 76 | |
| 77 | template<ranges::input_range R> | |
| 78 | stack(from_range_t, R&&) -> stack<ranges::range_value_t<R>>; // since C++23 | |
| 79 | ||
| 72 | 80 | template<class Container, class Allocator> |
| 73 | 81 | stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17 |
| 74 | 82 | |
| ... | ... | @@ -77,6 +85,10 @@ template<class InputIterator, class Allocator> |
| 77 | 85 | -> stack<iter-value-type<InputIterator>, |
| 78 | 86 | deque<iter-value-type<InputIterator>, Allocator>>; // since C++23 |
| 79 | 87 | |
| 88 | template<ranges::input_range R, class Allocator> | |
| 89 | stack(from_range_t, R&&, Allocator) | |
| 90 | -> stack<ranges::range_value_t<R>, deque<ranges::range_value_t<R>, Allocator>>; // since C++23 | |
| 91 | ||
| 80 | 92 | template <class T, class Container> |
| 81 | 93 | bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); |
| 82 | 94 | template <class T, class Container> |
| ... | ... | @@ -89,6 +101,9 @@ template <class T, class Container> |
| 89 | 101 | bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); |
| 90 | 102 | template <class T, class Container> |
| 91 | 103 | bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); |
| 104 | template<class T, three_way_comparable Container> | |
| 105 | compare_three_way_result_t<Container> | |
| 106 | operator<=>(const stack<T, Container>& x, const stack<T, Container>& y); // since C++20 | |
| 92 | 107 | |
| 93 | 108 | template <class T, class Container> |
| 94 | 109 | void swap(stack<T, Container>& x, stack<T, Container>& y) |
| ... | ... | @@ -98,13 +113,19 @@ template <class T, class Container> |
| 98 | 113 | |
| 99 | 114 | */ |
| 100 | 115 | |
| 116 | #include <__algorithm/ranges_copy.h> | |
| 101 | 117 | #include <__assert> // all public C++ headers provide the assertion handler |
| 102 | 118 | #include <__config> |
| 119 | #include <__iterator/back_insert_iterator.h> | |
| 103 | 120 | #include <__iterator/iterator_traits.h> |
| 104 | 121 | #include <__memory/uses_allocator.h> |
| 122 | #include <__ranges/access.h> | |
| 123 | #include <__ranges/concepts.h> | |
| 124 | #include <__ranges/container_compatible_range.h> | |
| 125 | #include <__ranges/from_range.h> | |
| 126 | #include <__type_traits/is_same.h> | |
| 105 | 127 | #include <__utility/forward.h> |
| 106 | 128 | #include <deque> |
| 107 | #include <type_traits> | |
| 108 | 129 | #include <version> |
| 109 | 130 | |
| 110 | 131 | // standard-mandated includes |
| ... | ... | @@ -204,18 +225,30 @@ public: |
| 204 | 225 | : c(_VSTD::move(__s.c), __a) {} |
| 205 | 226 | #endif // _LIBCPP_CXX03_LANG |
| 206 | 227 | |
| 207 | #if _LIBCPP_STD_VER > 20 | |
| 228 | #if _LIBCPP_STD_VER >= 23 | |
| 208 | 229 | template <class _InputIterator, |
| 209 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> | |
| 230 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>> | |
| 210 | 231 | _LIBCPP_HIDE_FROM_ABI |
| 211 | 232 | stack(_InputIterator __first, _InputIterator __last) : c(__first, __last) {} |
| 212 | 233 | |
| 234 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 235 | _LIBCPP_HIDE_FROM_ABI | |
| 236 | stack(from_range_t, _Range&& __range) : c(from_range, std::forward<_Range>(__range)) {} | |
| 237 | ||
| 213 | 238 | template <class _InputIterator, |
| 214 | 239 | class _Alloc, |
| 215 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 240 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 216 | 241 | class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> |
| 217 | 242 | _LIBCPP_HIDE_FROM_ABI |
| 218 | 243 | stack(_InputIterator __first, _InputIterator __last, const _Alloc& __alloc) : c(__first, __last, __alloc) {} |
| 244 | ||
| 245 | template <_ContainerCompatibleRange<_Tp> _Range, | |
| 246 | class _Alloc, | |
| 247 | class = __enable_if_t<uses_allocator<container_type, _Alloc>::value>> | |
| 248 | _LIBCPP_HIDE_FROM_ABI | |
| 249 | stack(from_range_t, _Range&& __range, const _Alloc& __alloc) | |
| 250 | : c(from_range, std::forward<_Range>(__range), __alloc) {} | |
| 251 | ||
| 219 | 252 | #endif |
| 220 | 253 | |
| 221 | 254 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -233,9 +266,23 @@ public: |
| 233 | 266 | _LIBCPP_INLINE_VISIBILITY |
| 234 | 267 | void push(value_type&& __v) {c.push_back(_VSTD::move(__v));} |
| 235 | 268 | |
| 269 | #if _LIBCPP_STD_VER >= 23 | |
| 270 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 271 | _LIBCPP_HIDE_FROM_ABI | |
| 272 | void push_range(_Range&& __range) { | |
| 273 | if constexpr (requires (container_type& __c) { | |
| 274 | __c.append_range(std::forward<_Range>(__range)); | |
| 275 | }) { | |
| 276 | c.append_range(std::forward<_Range>(__range)); | |
| 277 | } else { | |
| 278 | ranges::copy(std::forward<_Range>(__range), std::back_inserter(c)); | |
| 279 | } | |
| 280 | } | |
| 281 | #endif | |
| 282 | ||
| 236 | 283 | template <class... _Args> |
| 237 | 284 | _LIBCPP_INLINE_VISIBILITY |
| 238 | #if _LIBCPP_STD_VER > 14 | |
| 285 | #if _LIBCPP_STD_VER >= 17 | |
| 239 | 286 | decltype(auto) emplace(_Args&&... __args) |
| 240 | 287 | { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} |
| 241 | 288 | #else |
| ... | ... | @@ -257,18 +304,18 @@ public: |
| 257 | 304 | |
| 258 | 305 | _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI const _Container& __get_container() const { return c; } |
| 259 | 306 | |
| 260 | template <class T1, class _C1> | |
| 307 | template <class _T1, class _OtherContainer> | |
| 261 | 308 | friend |
| 262 | 309 | bool |
| 263 | operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); | |
| 310 | operator==(const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y); | |
| 264 | 311 | |
| 265 | template <class T1, class _C1> | |
| 312 | template <class _T1, class _OtherContainer> | |
| 266 | 313 | friend |
| 267 | 314 | bool |
| 268 | operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); | |
| 315 | operator< (const stack<_T1, _OtherContainer>& __x, const stack<_T1, _OtherContainer>& __y); | |
| 269 | 316 | }; |
| 270 | 317 | |
| 271 | #if _LIBCPP_STD_VER > 14 | |
| 318 | #if _LIBCPP_STD_VER >= 17 | |
| 272 | 319 | template<class _Container, |
| 273 | 320 | class = enable_if_t<!__is_allocator<_Container>::value> |
| 274 | 321 | > |
| ... | ... | @@ -284,18 +331,28 @@ stack(_Container, _Alloc) |
| 284 | 331 | -> stack<typename _Container::value_type, _Container>; |
| 285 | 332 | #endif |
| 286 | 333 | |
| 287 | #if _LIBCPP_STD_VER > 20 | |
| 334 | #if _LIBCPP_STD_VER >= 23 | |
| 288 | 335 | template<class _InputIterator, |
| 289 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>> | |
| 336 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>> | |
| 290 | 337 | stack(_InputIterator, _InputIterator) |
| 291 | 338 | -> stack<__iter_value_type<_InputIterator>>; |
| 292 | 339 | |
| 340 | template <ranges::input_range _Range> | |
| 341 | stack(from_range_t, _Range&&) -> stack<ranges::range_value_t<_Range>>; | |
| 342 | ||
| 293 | 343 | template<class _InputIterator, |
| 294 | 344 | class _Alloc, |
| 295 | class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 345 | class = __enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 296 | 346 | class = __enable_if_t<__is_allocator<_Alloc>::value>> |
| 297 | 347 | stack(_InputIterator, _InputIterator, _Alloc) |
| 298 | 348 | -> stack<__iter_value_type<_InputIterator>, deque<__iter_value_type<_InputIterator>, _Alloc>>; |
| 349 | ||
| 350 | template <ranges::input_range _Range, | |
| 351 | class _Alloc, | |
| 352 | class = __enable_if_t<__is_allocator<_Alloc>::value>> | |
| 353 | stack(from_range_t, _Range&&, _Alloc) | |
| 354 | -> stack<ranges::range_value_t<_Range>, deque<ranges::range_value_t<_Range>, _Alloc>>; | |
| 355 | ||
| 299 | 356 | #endif |
| 300 | 357 | |
| 301 | 358 | template <class _Tp, class _Container> |
| ... | ... | @@ -346,6 +403,17 @@ operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) |
| 346 | 403 | return !(__y < __x); |
| 347 | 404 | } |
| 348 | 405 | |
| 406 | #if _LIBCPP_STD_VER >= 20 | |
| 407 | ||
| 408 | template <class _Tp, three_way_comparable _Container> | |
| 409 | _LIBCPP_HIDE_FROM_ABI compare_three_way_result_t<_Container> | |
| 410 | operator<=>(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) { | |
| 411 | // clang 16 bug: declaring `friend operator<=>` causes "use of overloaded operator '*' is ambiguous" errors | |
| 412 | return __x.__get_container() <=> __y.__get_container(); | |
| 413 | } | |
| 414 | ||
| 415 | #endif | |
| 416 | ||
| 349 | 417 | template <class _Tp, class _Container> |
| 350 | 418 | inline _LIBCPP_INLINE_VISIBILITY |
| 351 | 419 | __enable_if_t<__is_swappable<_Container>::value, void> |
| ... | ... | @@ -366,6 +434,7 @@ _LIBCPP_END_NAMESPACE_STD |
| 366 | 434 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 367 | 435 | # include <concepts> |
| 368 | 436 | # include <functional> |
| 437 | # include <type_traits> | |
| 369 | 438 | #endif |
| 370 | 439 | |
| 371 | 440 | #endif // _LIBCPP_STACK |
lib/libcxx/include/stdatomic.h+2-2| ... | ... | @@ -121,7 +121,7 @@ using std::atomic_signal_fence // see below |
| 121 | 121 | # pragma GCC system_header |
| 122 | 122 | #endif |
| 123 | 123 | |
| 124 | #if defined(__cplusplus) && _LIBCPP_STD_VER > 20 | |
| 124 | #if defined(__cplusplus) && _LIBCPP_STD_VER >= 23 | |
| 125 | 125 | |
| 126 | 126 | #include <atomic> |
| 127 | 127 | #include <version> |
| ... | ... | @@ -230,6 +230,6 @@ using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS; |
| 230 | 230 | # include_next <stdatomic.h> |
| 231 | 231 | # endif |
| 232 | 232 | |
| 233 | #endif // defined(__cplusplus) && _LIBCPP_STD_VER > 20 | |
| 233 | #endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23 | |
| 234 | 234 | |
| 235 | 235 | #endif // _LIBCPP_STDATOMIC_H |
lib/libcxx/include/stdexcept+41-44| ... | ... | @@ -43,8 +43,8 @@ public: |
| 43 | 43 | |
| 44 | 44 | #include <__assert> // all public C++ headers provide the assertion handler |
| 45 | 45 | #include <__config> |
| 46 | #include <cstdlib> | |
| 47 | #include <exception> | |
| 46 | #include <__exception/exception.h> | |
| 47 | #include <__verbose_abort> | |
| 48 | 48 | #include <iosfwd> // for string forward decl |
| 49 | 49 | |
| 50 | 50 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| ... | ... | @@ -65,7 +65,7 @@ public: |
| 65 | 65 | __libcpp_refstring& operator=(const __libcpp_refstring& __s) _NOEXCEPT; |
| 66 | 66 | ~__libcpp_refstring(); |
| 67 | 67 | |
| 68 | const char* c_str() const _NOEXCEPT {return __imp_;} | |
| 68 | _LIBCPP_HIDE_FROM_ABI const char* c_str() const _NOEXCEPT {return __imp_;} | |
| 69 | 69 | }; |
| 70 | 70 | #endif // !_LIBCPP_ABI_VCRUNTIME |
| 71 | 71 | |
| ... | ... | @@ -74,7 +74,7 @@ _LIBCPP_END_NAMESPACE_STD |
| 74 | 74 | namespace std // purposefully not using versioning namespace |
| 75 | 75 | { |
| 76 | 76 | |
| 77 | class _LIBCPP_EXCEPTION_ABI logic_error | |
| 77 | class _LIBCPP_EXPORTED_FROM_ABI logic_error | |
| 78 | 78 | : public exception |
| 79 | 79 | { |
| 80 | 80 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| ... | ... | @@ -97,7 +97,7 @@ public: |
| 97 | 97 | #endif |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | class _LIBCPP_EXCEPTION_ABI runtime_error | |
| 100 | class _LIBCPP_EXPORTED_FROM_ABI runtime_error | |
| 101 | 101 | : public exception |
| 102 | 102 | { |
| 103 | 103 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| ... | ... | @@ -120,7 +120,7 @@ public: |
| 120 | 120 | #endif // _LIBCPP_ABI_VCRUNTIME |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | class _LIBCPP_EXCEPTION_ABI domain_error | |
| 123 | class _LIBCPP_EXPORTED_FROM_ABI domain_error | |
| 124 | 124 | : public logic_error |
| 125 | 125 | { |
| 126 | 126 | public: |
| ... | ... | @@ -128,12 +128,12 @@ public: |
| 128 | 128 | _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s) : logic_error(__s) {} |
| 129 | 129 | |
| 130 | 130 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 131 | domain_error(const domain_error&) _NOEXCEPT = default; | |
| 131 | _LIBCPP_HIDE_FROM_ABI domain_error(const domain_error&) _NOEXCEPT = default; | |
| 132 | 132 | ~domain_error() _NOEXCEPT override; |
| 133 | 133 | #endif |
| 134 | 134 | }; |
| 135 | 135 | |
| 136 | class _LIBCPP_EXCEPTION_ABI invalid_argument | |
| 136 | class _LIBCPP_EXPORTED_FROM_ABI invalid_argument | |
| 137 | 137 | : public logic_error |
| 138 | 138 | { |
| 139 | 139 | public: |
| ... | ... | @@ -141,24 +141,24 @@ public: |
| 141 | 141 | _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s) : logic_error(__s) {} |
| 142 | 142 | |
| 143 | 143 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 144 | invalid_argument(const invalid_argument&) _NOEXCEPT = default; | |
| 144 | _LIBCPP_HIDE_FROM_ABI invalid_argument(const invalid_argument&) _NOEXCEPT = default; | |
| 145 | 145 | ~invalid_argument() _NOEXCEPT override; |
| 146 | 146 | #endif |
| 147 | 147 | }; |
| 148 | 148 | |
| 149 | class _LIBCPP_EXCEPTION_ABI length_error | |
| 149 | class _LIBCPP_EXPORTED_FROM_ABI length_error | |
| 150 | 150 | : public logic_error |
| 151 | 151 | { |
| 152 | 152 | public: |
| 153 | 153 | _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {} |
| 154 | 154 | _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s) : logic_error(__s) {} |
| 155 | 155 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 156 | length_error(const length_error&) _NOEXCEPT = default; | |
| 156 | _LIBCPP_HIDE_FROM_ABI length_error(const length_error&) _NOEXCEPT = default; | |
| 157 | 157 | ~length_error() _NOEXCEPT override; |
| 158 | 158 | #endif |
| 159 | 159 | }; |
| 160 | 160 | |
| 161 | class _LIBCPP_EXCEPTION_ABI out_of_range | |
| 161 | class _LIBCPP_EXPORTED_FROM_ABI out_of_range | |
| 162 | 162 | : public logic_error |
| 163 | 163 | { |
| 164 | 164 | public: |
| ... | ... | @@ -166,12 +166,12 @@ public: |
| 166 | 166 | _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s) : logic_error(__s) {} |
| 167 | 167 | |
| 168 | 168 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 169 | out_of_range(const out_of_range&) _NOEXCEPT = default; | |
| 169 | _LIBCPP_HIDE_FROM_ABI out_of_range(const out_of_range&) _NOEXCEPT = default; | |
| 170 | 170 | ~out_of_range() _NOEXCEPT override; |
| 171 | 171 | #endif |
| 172 | 172 | }; |
| 173 | 173 | |
| 174 | class _LIBCPP_EXCEPTION_ABI range_error | |
| 174 | class _LIBCPP_EXPORTED_FROM_ABI range_error | |
| 175 | 175 | : public runtime_error |
| 176 | 176 | { |
| 177 | 177 | public: |
| ... | ... | @@ -179,12 +179,12 @@ public: |
| 179 | 179 | _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s) : runtime_error(__s) {} |
| 180 | 180 | |
| 181 | 181 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 182 | range_error(const range_error&) _NOEXCEPT = default; | |
| 182 | _LIBCPP_HIDE_FROM_ABI range_error(const range_error&) _NOEXCEPT = default; | |
| 183 | 183 | ~range_error() _NOEXCEPT override; |
| 184 | 184 | #endif |
| 185 | 185 | }; |
| 186 | 186 | |
| 187 | class _LIBCPP_EXCEPTION_ABI overflow_error | |
| 187 | class _LIBCPP_EXPORTED_FROM_ABI overflow_error | |
| 188 | 188 | : public runtime_error |
| 189 | 189 | { |
| 190 | 190 | public: |
| ... | ... | @@ -192,12 +192,12 @@ public: |
| 192 | 192 | _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s) : runtime_error(__s) {} |
| 193 | 193 | |
| 194 | 194 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 195 | overflow_error(const overflow_error&) _NOEXCEPT = default; | |
| 195 | _LIBCPP_HIDE_FROM_ABI overflow_error(const overflow_error&) _NOEXCEPT = default; | |
| 196 | 196 | ~overflow_error() _NOEXCEPT override; |
| 197 | 197 | #endif |
| 198 | 198 | }; |
| 199 | 199 | |
| 200 | class _LIBCPP_EXCEPTION_ABI underflow_error | |
| 200 | class _LIBCPP_EXPORTED_FROM_ABI underflow_error | |
| 201 | 201 | : public runtime_error |
| 202 | 202 | { |
| 203 | 203 | public: |
| ... | ... | @@ -205,7 +205,7 @@ public: |
| 205 | 205 | _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s) : runtime_error(__s) {} |
| 206 | 206 | |
| 207 | 207 | #ifndef _LIBCPP_ABI_VCRUNTIME |
| 208 | underflow_error(const underflow_error&) _NOEXCEPT = default; | |
| 208 | _LIBCPP_HIDE_FROM_ABI underflow_error(const underflow_error&) _NOEXCEPT = default; | |
| 209 | 209 | ~underflow_error() _NOEXCEPT override; |
| 210 | 210 | #endif |
| 211 | 211 | }; |
| ... | ... | @@ -215,96 +215,93 @@ public: |
| 215 | 215 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 216 | 216 | |
| 217 | 217 | // in the dylib |
| 218 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); | |
| 218 | _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void __throw_runtime_error(const char*); | |
| 219 | 219 | |
| 220 | 220 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 221 | 221 | void __throw_logic_error(const char*__msg) |
| 222 | 222 | { |
| 223 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 223 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 224 | 224 | throw logic_error(__msg); |
| 225 | 225 | #else |
| 226 | ((void)__msg); | |
| 227 | _VSTD::abort(); | |
| 226 | _LIBCPP_VERBOSE_ABORT("logic_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 228 | 227 | #endif |
| 229 | 228 | } |
| 230 | 229 | |
| 231 | 230 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 232 | 231 | void __throw_domain_error(const char*__msg) |
| 233 | 232 | { |
| 234 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 233 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 235 | 234 | throw domain_error(__msg); |
| 236 | 235 | #else |
| 237 | ((void)__msg); | |
| 238 | _VSTD::abort(); | |
| 236 | _LIBCPP_VERBOSE_ABORT("domain_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 239 | 237 | #endif |
| 240 | 238 | } |
| 241 | 239 | |
| 242 | 240 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 243 | 241 | void __throw_invalid_argument(const char*__msg) |
| 244 | 242 | { |
| 245 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 243 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 246 | 244 | throw invalid_argument(__msg); |
| 247 | 245 | #else |
| 248 | ((void)__msg); | |
| 249 | _VSTD::abort(); | |
| 246 | _LIBCPP_VERBOSE_ABORT("invalid_argument was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 250 | 247 | #endif |
| 251 | 248 | } |
| 252 | 249 | |
| 253 | 250 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 254 | 251 | void __throw_length_error(const char*__msg) |
| 255 | 252 | { |
| 256 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 253 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 257 | 254 | throw length_error(__msg); |
| 258 | 255 | #else |
| 259 | ((void)__msg); | |
| 260 | _VSTD::abort(); | |
| 256 | _LIBCPP_VERBOSE_ABORT("length_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 261 | 257 | #endif |
| 262 | 258 | } |
| 263 | 259 | |
| 264 | 260 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 265 | 261 | void __throw_out_of_range(const char*__msg) |
| 266 | 262 | { |
| 267 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 263 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 268 | 264 | throw out_of_range(__msg); |
| 269 | 265 | #else |
| 270 | ((void)__msg); | |
| 271 | _VSTD::abort(); | |
| 266 | _LIBCPP_VERBOSE_ABORT("out_of_range was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 272 | 267 | #endif |
| 273 | 268 | } |
| 274 | 269 | |
| 275 | 270 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 276 | 271 | void __throw_range_error(const char*__msg) |
| 277 | 272 | { |
| 278 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 273 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 279 | 274 | throw range_error(__msg); |
| 280 | 275 | #else |
| 281 | ((void)__msg); | |
| 282 | _VSTD::abort(); | |
| 276 | _LIBCPP_VERBOSE_ABORT("range_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 283 | 277 | #endif |
| 284 | 278 | } |
| 285 | 279 | |
| 286 | 280 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 287 | 281 | void __throw_overflow_error(const char*__msg) |
| 288 | 282 | { |
| 289 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 283 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 290 | 284 | throw overflow_error(__msg); |
| 291 | 285 | #else |
| 292 | ((void)__msg); | |
| 293 | _VSTD::abort(); | |
| 286 | _LIBCPP_VERBOSE_ABORT("overflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 294 | 287 | #endif |
| 295 | 288 | } |
| 296 | 289 | |
| 297 | 290 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 298 | 291 | void __throw_underflow_error(const char*__msg) |
| 299 | 292 | { |
| 300 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 293 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 301 | 294 | throw underflow_error(__msg); |
| 302 | 295 | #else |
| 303 | ((void)__msg); | |
| 304 | _VSTD::abort(); | |
| 296 | _LIBCPP_VERBOSE_ABORT("underflow_error was thrown in -fno-exceptions mode with message \"%s\"", __msg); | |
| 305 | 297 | #endif |
| 306 | 298 | } |
| 307 | 299 | |
| 308 | 300 | _LIBCPP_END_NAMESPACE_STD |
| 309 | 301 | |
| 302 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 303 | # include <cstdlib> | |
| 304 | # include <exception> | |
| 305 | #endif | |
| 306 | ||
| 310 | 307 | #endif // _LIBCPP_STDEXCEPT |
lib/libcxx/include/stdlib.h+4-6| ... | ... | @@ -109,16 +109,15 @@ extern "C++" { |
| 109 | 109 | #endif |
| 110 | 110 | |
| 111 | 111 | // MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined |
| 112 | #if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) | |
| 112 | #if !defined(_LIBCPP_MSVCRT) | |
| 113 | 113 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long abs(long __x) _NOEXCEPT { |
| 114 | 114 | return __builtin_labs(__x); |
| 115 | 115 | } |
| 116 | 116 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT { |
| 117 | 117 | return __builtin_llabs(__x); |
| 118 | 118 | } |
| 119 | #endif // !defined(_LIBCPP_MSVCRT) && !defined(__sun__) | |
| 119 | #endif // !defined(_LIBCPP_MSVCRT) | |
| 120 | 120 | |
| 121 | #if !defined(__sun__) | |
| 122 | 121 | _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY float abs(float __lcpp_x) _NOEXCEPT { |
| 123 | 122 | return __builtin_fabsf(__lcpp_x); // Use builtins to prevent needing math.h |
| 124 | 123 | } |
| ... | ... | @@ -131,7 +130,6 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY long double |
| 131 | 130 | abs(long double __lcpp_x) _NOEXCEPT { |
| 132 | 131 | return __builtin_fabsl(__lcpp_x); |
| 133 | 132 | } |
| 134 | #endif // !defined(__sun__) | |
| 135 | 133 | |
| 136 | 134 | // div |
| 137 | 135 | |
| ... | ... | @@ -146,7 +144,7 @@ abs(long double __lcpp_x) _NOEXCEPT { |
| 146 | 144 | #endif |
| 147 | 145 | |
| 148 | 146 | // MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined |
| 149 | #if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) | |
| 147 | #if !defined(_LIBCPP_MSVCRT) | |
| 150 | 148 | inline _LIBCPP_INLINE_VISIBILITY ldiv_t div(long __x, long __y) _NOEXCEPT { |
| 151 | 149 | return ::ldiv(__x, __y); |
| 152 | 150 | } |
| ... | ... | @@ -156,7 +154,7 @@ inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, |
| 156 | 154 | return ::lldiv(__x, __y); |
| 157 | 155 | } |
| 158 | 156 | #endif |
| 159 | #endif // _LIBCPP_MSVCRT / __sun__ | |
| 157 | #endif // _LIBCPP_MSVCRT | |
| 160 | 158 | } // extern "C++" |
| 161 | 159 | #endif // __cplusplus |
| 162 | 160 |
lib/libcxx/include/stop_token created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_STOP_TOKEN | |
| 11 | #define _LIBCPP_STOP_TOKEN | |
| 12 | ||
| 13 | /* | |
| 14 | ||
| 15 | namespace std { | |
| 16 | // [stoptoken], class stop_token | |
| 17 | class stop_token; | |
| 18 | ||
| 19 | // [stopsource], class stop_source | |
| 20 | class stop_source; | |
| 21 | ||
| 22 | // no-shared-stop-state indicator | |
| 23 | struct nostopstate_t { | |
| 24 | explicit nostopstate_t() = default; | |
| 25 | }; | |
| 26 | inline constexpr nostopstate_t nostopstate{}; | |
| 27 | ||
| 28 | // [stopcallback], class template stop_callback | |
| 29 | template<class Callback> | |
| 30 | class stop_callback; | |
| 31 | ||
| 32 | */ | |
| 33 | ||
| 34 | #include <__assert> // all public C++ headers provide the assertion handler | |
| 35 | #include <__config> | |
| 36 | #include <__stop_token/stop_callback.h> | |
| 37 | #include <__stop_token/stop_source.h> | |
| 38 | #include <__stop_token/stop_token.h> | |
| 39 | #include <version> | |
| 40 | ||
| 41 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 42 | # pragma GCC system_header | |
| 43 | #endif | |
| 44 | ||
| 45 | #ifdef _LIBCPP_HAS_NO_THREADS | |
| 46 | # error "<stop_token> is not supported since libc++ has been configured without support for threads." | |
| 47 | #endif | |
| 48 | ||
| 49 | #endif // _LIBCPP_STOP_TOKEN |
lib/libcxx/include/streambuf+1-2| ... | ... | @@ -109,6 +109,7 @@ protected: |
| 109 | 109 | |
| 110 | 110 | #include <__assert> // all public C++ headers provide the assertion handler |
| 111 | 111 | #include <__config> |
| 112 | #include <__fwd/streambuf.h> | |
| 112 | 113 | #include <cstdint> |
| 113 | 114 | #include <ios> |
| 114 | 115 | #include <iosfwd> |
| ... | ... | @@ -489,11 +490,9 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type) |
| 489 | 490 | } |
| 490 | 491 | |
| 491 | 492 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>; |
| 492 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>; | |
| 493 | 493 | |
| 494 | 494 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 495 | 495 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>; |
| 496 | extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>; | |
| 497 | 496 | #endif |
| 498 | 497 | |
| 499 | 498 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/include/string+686-854| ... | ... | @@ -119,11 +119,13 @@ public: |
| 119 | 119 | explicit basic_string(const T& t, const Allocator& a = Allocator()); // C++17, constexpr since C++20 |
| 120 | 120 | basic_string(const value_type* s, const allocator_type& a = allocator_type()); // constexpr since C++20 |
| 121 | 121 | basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type()); // constexpr since C++20 |
| 122 | basic_string(nullptr_t) = delete; // C++2b | |
| 122 | basic_string(nullptr_t) = delete; // C++23 | |
| 123 | 123 | basic_string(size_type n, value_type c, const allocator_type& a = allocator_type()); // constexpr since C++20 |
| 124 | 124 | template<class InputIterator> |
| 125 | 125 | basic_string(InputIterator begin, InputIterator end, |
| 126 | 126 | const allocator_type& a = allocator_type()); // constexpr since C++20 |
| 127 | template<container-compatible-range<charT> R> | |
| 128 | constexpr basic_string(from_range_t, R&& rg, const Allocator& a = Allocator()); // since C++23 | |
| 127 | 129 | basic_string(initializer_list<value_type>, const Allocator& = Allocator()); // constexpr since C++20 |
| 128 | 130 | basic_string(const basic_string&, const Allocator&); // constexpr since C++20 |
| 129 | 131 | basic_string(basic_string&&, const Allocator&); // constexpr since C++20 |
| ... | ... | @@ -140,7 +142,7 @@ public: |
| 140 | 142 | allocator_type::propagate_on_container_move_assignment::value || |
| 141 | 143 | allocator_type::is_always_equal::value ); // C++17, constexpr since C++20 |
| 142 | 144 | basic_string& operator=(const value_type* s); // constexpr since C++20 |
| 143 | basic_string& operator=(nullptr_t) = delete; // C++2b | |
| 145 | basic_string& operator=(nullptr_t) = delete; // C++23 | |
| 144 | 146 | basic_string& operator=(value_type c); // constexpr since C++20 |
| 145 | 147 | basic_string& operator=(initializer_list<value_type>); // constexpr since C++20 |
| 146 | 148 | |
| ... | ... | @@ -200,6 +202,8 @@ public: |
| 200 | 202 | basic_string& append(size_type n, value_type c); // constexpr since C++20 |
| 201 | 203 | template<class InputIterator> |
| 202 | 204 | basic_string& append(InputIterator first, InputIterator last); // constexpr since C++20 |
| 205 | template<container-compatible-range<charT> R> | |
| 206 | constexpr basic_string& append_range(R&& rg); // C++23 | |
| 203 | 207 | basic_string& append(initializer_list<value_type>); // constexpr since C++20 |
| 204 | 208 | |
| 205 | 209 | void push_back(value_type c); // constexpr since C++20 |
| ... | ... | @@ -221,6 +225,8 @@ public: |
| 221 | 225 | basic_string& assign(size_type n, value_type c); // constexpr since C++20 |
| 222 | 226 | template<class InputIterator> |
| 223 | 227 | basic_string& assign(InputIterator first, InputIterator last); // constexpr since C++20 |
| 228 | template<container-compatible-range<charT> R> | |
| 229 | constexpr basic_string& assign_range(R&& rg); // C++23 | |
| 224 | 230 | basic_string& assign(initializer_list<value_type>); // constexpr since C++20 |
| 225 | 231 | |
| 226 | 232 | basic_string& insert(size_type pos1, const basic_string& str); // constexpr since C++20 |
| ... | ... | @@ -237,6 +243,8 @@ public: |
| 237 | 243 | iterator insert(const_iterator p, size_type n, value_type c); // constexpr since C++20 |
| 238 | 244 | template<class InputIterator> |
| 239 | 245 | iterator insert(const_iterator p, InputIterator first, InputIterator last); // constexpr since C++20 |
| 246 | template<container-compatible-range<charT> R> | |
| 247 | constexpr iterator insert_range(const_iterator p, R&& rg); // C++23 | |
| 240 | 248 | iterator insert(const_iterator p, initializer_list<value_type>); // constexpr since C++20 |
| 241 | 249 | |
| 242 | 250 | basic_string& erase(size_type pos = 0, size_type n = npos); // constexpr since C++20 |
| ... | ... | @@ -262,6 +270,8 @@ public: |
| 262 | 270 | basic_string& replace(const_iterator i1, const_iterator i2, size_type n, value_type c); // constexpr since C++20 |
| 263 | 271 | template<class InputIterator> |
| 264 | 272 | basic_string& replace(const_iterator i1, const_iterator i2, InputIterator j1, InputIterator j2); // constexpr since C++20 |
| 273 | template<container-compatible-range<charT> R> | |
| 274 | constexpr basic_string& replace_with_range(const_iterator i1, const_iterator i2, R&& rg); // C++23 | |
| 265 | 275 | basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<value_type>); // constexpr since C++20 |
| 266 | 276 | |
| 267 | 277 | size_type copy(value_type* s, size_type n, size_type pos = 0) const; // constexpr since C++20 |
| ... | ... | @@ -342,9 +352,9 @@ public: |
| 342 | 352 | constexpr bool ends_with(charT c) const noexcept; // C++20 |
| 343 | 353 | constexpr bool ends_with(const charT* s) const; // C++20 |
| 344 | 354 | |
| 345 | constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++2b | |
| 346 | constexpr bool contains(charT c) const noexcept; // C++2b | |
| 347 | constexpr bool contains(const charT* s) const; // C++2b | |
| 355 | constexpr bool contains(basic_string_view<charT, traits> sv) const noexcept; // C++23 | |
| 356 | constexpr bool contains(charT c) const noexcept; // C++23 | |
| 357 | constexpr bool contains(const charT* s) const; // C++23 | |
| 348 | 358 | }; |
| 349 | 359 | |
| 350 | 360 | template<class InputIterator, |
| ... | ... | @@ -354,6 +364,26 @@ basic_string(InputIterator, InputIterator, Allocator = Allocator()) |
| 354 | 364 | char_traits<typename iterator_traits<InputIterator>::value_type>, |
| 355 | 365 | Allocator>; // C++17 |
| 356 | 366 | |
| 367 | template<ranges::input_range R, | |
| 368 | class Allocator = allocator<ranges::range_value_t<R>>> | |
| 369 | basic_string(from_range_t, R&&, Allocator = Allocator()) | |
| 370 | -> basic_string<ranges::range_value_t<R>, char_traits<ranges::range_value_t<R>>, | |
| 371 | Allocator>; // C++23 | |
| 372 | ||
| 373 | template<class charT, | |
| 374 | class traits, | |
| 375 | class Allocator = allocator<charT>> | |
| 376 | explicit basic_string(basic_string_view<charT, traits>, const Allocator& = Allocator()) | |
| 377 | -> basic_string<charT, traits, Allocator>; // C++17 | |
| 378 | ||
| 379 | template<class charT, | |
| 380 | class traits, | |
| 381 | class Allocator = allocator<charT>> | |
| 382 | basic_string(basic_string_view<charT, traits>, | |
| 383 | typename see below::size_type, typename see below::size_type, | |
| 384 | const Allocator& = Allocator()) | |
| 385 | -> basic_string<charT, traits, Allocator>; // C++17 | |
| 386 | ||
| 357 | 387 | template<class charT, class traits, class Allocator> |
| 358 | 388 | basic_string<charT, traits, Allocator> |
| 359 | 389 | operator+(const basic_string<charT, traits, Allocator>& lhs, |
| ... | ... | @@ -524,11 +554,11 @@ template <> struct hash<u16string>; |
| 524 | 554 | template <> struct hash<u32string>; |
| 525 | 555 | template <> struct hash<wstring>; |
| 526 | 556 | |
| 527 | basic_string<char> operator "" s( const char *str, size_t len ); // C++14, constexpr since C++20 | |
| 528 | basic_string<wchar_t> operator "" s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 529 | constexpr basic_string<char8_t> operator "" s( const char8_t *str, size_t len ); // C++20 | |
| 530 | basic_string<char16_t> operator "" s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 531 | basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 557 | basic_string<char> operator""s( const char *str, size_t len ); // C++14, constexpr since C++20 | |
| 558 | basic_string<wchar_t> operator""s( const wchar_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 559 | constexpr basic_string<char8_t> operator""s( const char8_t *str, size_t len ); // C++20 | |
| 560 | basic_string<char16_t> operator""s( const char16_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 561 | basic_string<char32_t> operator""s( const char32_t *str, size_t len ); // C++14, constexpr since C++20 | |
| 532 | 562 | |
| 533 | 563 | } // std |
| 534 | 564 | |
| ... | ... | @@ -540,7 +570,6 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); |
| 540 | 570 | #include <__algorithm/remove_if.h> |
| 541 | 571 | #include <__assert> // all public C++ headers provide the assertion handler |
| 542 | 572 | #include <__config> |
| 543 | #include <__debug> | |
| 544 | 573 | #include <__format/enable_insertable.h> |
| 545 | 574 | #include <__functional/hash.h> |
| 546 | 575 | #include <__functional/unary_function.h> |
| ... | ... | @@ -550,6 +579,7 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); |
| 550 | 579 | #include <__iterator/iterator_traits.h> |
| 551 | 580 | #include <__iterator/reverse_iterator.h> |
| 552 | 581 | #include <__iterator/wrap_iter.h> |
| 582 | #include <__memory/addressof.h> | |
| 553 | 583 | #include <__memory/allocate_at_least.h> |
| 554 | 584 | #include <__memory/allocator.h> |
| 555 | 585 | #include <__memory/allocator_traits.h> |
| ... | ... | @@ -558,23 +588,38 @@ basic_string<char32_t> operator "" s( const char32_t *str, size_t len ); |
| 558 | 588 | #include <__memory/pointer_traits.h> |
| 559 | 589 | #include <__memory/swap_allocator.h> |
| 560 | 590 | #include <__memory_resource/polymorphic_allocator.h> |
| 591 | #include <__ranges/access.h> | |
| 592 | #include <__ranges/concepts.h> | |
| 593 | #include <__ranges/container_compatible_range.h> | |
| 594 | #include <__ranges/from_range.h> | |
| 595 | #include <__ranges/size.h> | |
| 561 | 596 | #include <__string/char_traits.h> |
| 562 | 597 | #include <__string/extern_template_lists.h> |
| 563 | 598 | #include <__type_traits/is_allocator.h> |
| 599 | #include <__type_traits/is_array.h> | |
| 600 | #include <__type_traits/is_convertible.h> | |
| 601 | #include <__type_traits/is_nothrow_default_constructible.h> | |
| 602 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 603 | #include <__type_traits/is_same.h> | |
| 604 | #include <__type_traits/is_standard_layout.h> | |
| 605 | #include <__type_traits/is_trivial.h> | |
| 564 | 606 | #include <__type_traits/noexcept_move_assign_container.h> |
| 607 | #include <__type_traits/remove_cvref.h> | |
| 608 | #include <__type_traits/void_t.h> | |
| 565 | 609 | #include <__utility/auto_cast.h> |
| 610 | #include <__utility/declval.h> | |
| 611 | #include <__utility/forward.h> | |
| 612 | #include <__utility/is_pointer_in_range.h> | |
| 566 | 613 | #include <__utility/move.h> |
| 567 | 614 | #include <__utility/swap.h> |
| 568 | 615 | #include <__utility/unreachable.h> |
| 569 | 616 | #include <climits> |
| 570 | 617 | #include <cstdint> |
| 571 | 618 | #include <cstdio> // EOF |
| 572 | #include <cstdlib> | |
| 573 | 619 | #include <cstring> |
| 574 | 620 | #include <limits> |
| 575 | 621 | #include <stdexcept> |
| 576 | 622 | #include <string_view> |
| 577 | #include <type_traits> | |
| 578 | 623 | #include <version> |
| 579 | 624 | |
| 580 | 625 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -632,7 +677,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 632 | 677 | basic_string<_CharT, _Traits, _Allocator> |
| 633 | 678 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __x, _CharT __y); |
| 634 | 679 | |
| 635 | extern template _LIBCPP_FUNC_VIS string operator+<char, char_traits<char>, allocator<char> >(char const*, string const&); | |
| 680 | extern template _LIBCPP_EXPORTED_FROM_ABI string operator+ | |
| 681 | <char, char_traits<char>, allocator<char> >(char const*, string const&); | |
| 636 | 682 | |
| 637 | 683 | template <class _Iter> |
| 638 | 684 | struct __string_is_trivial_iterator : public false_type {}; |
| ... | ... | @@ -652,6 +698,7 @@ struct __can_be_converted_to_string_view : public _BoolConstant< |
| 652 | 698 | > {}; |
| 653 | 699 | |
| 654 | 700 | struct __uninitialized_size_tag {}; |
| 701 | struct __init_with_sentinel_tag {}; | |
| 655 | 702 | |
| 656 | 703 | template<class _CharT, class _Traits, class _Allocator> |
| 657 | 704 | class basic_string |
| ... | ... | @@ -810,15 +857,21 @@ private: |
| 810 | 857 | __set_long_pointer(__allocation); |
| 811 | 858 | __set_long_size(__size); |
| 812 | 859 | } |
| 813 | std::__debug_db_insert_c(this); | |
| 860 | } | |
| 861 | ||
| 862 | template <class _Iter, class _Sent> | |
| 863 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 864 | basic_string(__init_with_sentinel_tag, _Iter __first, _Sent __last, const allocator_type& __a) | |
| 865 | : __r_(__default_init_tag(), __a) { | |
| 866 | __init_with_sentinel(std::move(__first), std::move(__last)); | |
| 814 | 867 | } |
| 815 | 868 | |
| 816 | 869 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator __make_iterator(pointer __p) { |
| 817 | return iterator(this, __p); | |
| 870 | return iterator(__p); | |
| 818 | 871 | } |
| 819 | 872 | |
| 820 | 873 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_iterator __make_const_iterator(const_pointer __p) const { |
| 821 | return const_iterator(this, __p); | |
| 874 | return const_iterator(__p); | |
| 822 | 875 | } |
| 823 | 876 | |
| 824 | 877 | public: |
| ... | ... | @@ -827,7 +880,6 @@ public: |
| 827 | 880 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string() |
| 828 | 881 | _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) |
| 829 | 882 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 830 | std::__debug_db_insert_c(this); | |
| 831 | 883 | __default_init(); |
| 832 | 884 | } |
| 833 | 885 | |
| ... | ... | @@ -838,12 +890,24 @@ public: |
| 838 | 890 | _NOEXCEPT |
| 839 | 891 | #endif |
| 840 | 892 | : __r_(__default_init_tag(), __a) { |
| 841 | std::__debug_db_insert_c(this); | |
| 842 | 893 | __default_init(); |
| 843 | 894 | } |
| 844 | 895 | |
| 845 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str); | |
| 846 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a); | |
| 896 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str) | |
| 897 | : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) { | |
| 898 | if (!__str.__is_long()) | |
| 899 | __r_.first() = __str.__r_.first(); | |
| 900 | else | |
| 901 | __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); | |
| 902 | } | |
| 903 | ||
| 904 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const basic_string& __str, const allocator_type& __a) | |
| 905 | : __r_(__default_init_tag(), __a) { | |
| 906 | if (!__str.__is_long()) | |
| 907 | __r_.first() = __str.__r_.first(); | |
| 908 | else | |
| 909 | __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), __str.__get_long_size()); | |
| 910 | } | |
| 847 | 911 | |
| 848 | 912 | #ifndef _LIBCPP_CXX03_LANG |
| 849 | 913 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str) |
| ... | ... | @@ -854,9 +918,6 @@ public: |
| 854 | 918 | # endif |
| 855 | 919 | : __r_(std::move(__str.__r_)) { |
| 856 | 920 | __str.__default_init(); |
| 857 | std::__debug_db_insert_c(this); | |
| 858 | if (__is_long()) | |
| 859 | std::__debug_db_swap(this, &__str); | |
| 860 | 921 | } |
| 861 | 922 | |
| 862 | 923 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(basic_string&& __str, const allocator_type& __a) |
| ... | ... | @@ -869,49 +930,47 @@ public: |
| 869 | 930 | __r_.first() = __str.__r_.first(); |
| 870 | 931 | __str.__default_init(); |
| 871 | 932 | } |
| 872 | std::__debug_db_insert_c(this); | |
| 873 | if (__is_long()) | |
| 874 | std::__debug_db_swap(this, &__str); | |
| 875 | 933 | } |
| 876 | 934 | #endif // _LIBCPP_CXX03_LANG |
| 877 | 935 | |
| 878 | template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > | |
| 936 | template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> | |
| 879 | 937 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s) |
| 880 | 938 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 881 | _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr"); | |
| 939 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*) detected nullptr"); | |
| 882 | 940 | __init(__s, traits_type::length(__s)); |
| 883 | std::__debug_db_insert_c(this); | |
| 884 | 941 | } |
| 885 | 942 | |
| 886 | template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > | |
| 887 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a); | |
| 943 | template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> | |
| 944 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, const _Allocator& __a) | |
| 945 | : __r_(__default_init_tag(), __a) { | |
| 946 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); | |
| 947 | __init(__s, traits_type::length(__s)); | |
| 948 | } | |
| 888 | 949 | |
| 889 | #if _LIBCPP_STD_VER > 20 | |
| 950 | #if _LIBCPP_STD_VER >= 23 | |
| 890 | 951 | basic_string(nullptr_t) = delete; |
| 891 | 952 | #endif |
| 892 | 953 | |
| 893 | 954 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(const _CharT* __s, size_type __n) |
| 894 | 955 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 895 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); | |
| 956 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr"); | |
| 896 | 957 | __init(__s, __n); |
| 897 | std::__debug_db_insert_c(this); | |
| 898 | 958 | } |
| 899 | 959 | |
| 900 | 960 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 901 | 961 | basic_string(const _CharT* __s, size_type __n, const _Allocator& __a) |
| 902 | 962 | : __r_(__default_init_tag(), __a) { |
| 903 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr"); | |
| 963 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, | |
| 964 | "basic_string(const char*, n, allocator) detected nullptr"); | |
| 904 | 965 | __init(__s, __n); |
| 905 | std::__debug_db_insert_c(this); | |
| 906 | 966 | } |
| 907 | 967 | |
| 908 | 968 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c) |
| 909 | 969 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 910 | 970 | __init(__n, __c); |
| 911 | std::__debug_db_insert_c(this); | |
| 912 | 971 | } |
| 913 | 972 | |
| 914 | #if _LIBCPP_STD_VER > 20 | |
| 973 | #if _LIBCPP_STD_VER >= 23 | |
| 915 | 974 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 916 | 975 | basic_string(basic_string&& __str, size_type __pos, const _Allocator& __alloc = _Allocator()) |
| 917 | 976 | : basic_string(std::move(__str), __pos, npos, __alloc) {} |
| ... | ... | @@ -934,18 +993,23 @@ public: |
| 934 | 993 | // Perform a copy because the allocators are not compatible. |
| 935 | 994 | __init(__str.data() + __pos, __len); |
| 936 | 995 | } |
| 937 | ||
| 938 | std::__debug_db_insert_c(this); | |
| 939 | if (__is_long()) | |
| 940 | std::__debug_db_swap(this, &__str); | |
| 941 | 996 | } |
| 942 | 997 | #endif |
| 943 | 998 | |
| 944 | template <class = __enable_if_t<__is_allocator<_Allocator>::value, nullptr_t> > | |
| 945 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a); | |
| 999 | template <__enable_if_t<__is_allocator<_Allocator>::value, int> = 0> | |
| 1000 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(size_type __n, _CharT __c, const _Allocator& __a) | |
| 1001 | : __r_(__default_init_tag(), __a) { | |
| 1002 | __init(__n, __c); | |
| 1003 | } | |
| 946 | 1004 | |
| 947 | 1005 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 948 | basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()); | |
| 1006 | basic_string(const basic_string& __str, size_type __pos, size_type __n, const _Allocator& __a = _Allocator()) | |
| 1007 | : __r_(__default_init_tag(), __a) { | |
| 1008 | size_type __str_sz = __str.size(); | |
| 1009 | if (__pos > __str_sz) | |
| 1010 | __throw_out_of_range(); | |
| 1011 | __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); | |
| 1012 | } | |
| 949 | 1013 | |
| 950 | 1014 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 951 | 1015 | basic_string(const basic_string& __str, size_type __pos, const _Allocator& __a = _Allocator()) |
| ... | ... | @@ -954,65 +1018,91 @@ public: |
| 954 | 1018 | if (__pos > __str_sz) |
| 955 | 1019 | __throw_out_of_range(); |
| 956 | 1020 | __init(__str.data() + __pos, __str_sz - __pos); |
| 957 | std::__debug_db_insert_c(this); | |
| 958 | 1021 | } |
| 959 | 1022 | |
| 960 | 1023 | template <class _Tp, |
| 961 | class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 962 | !__is_same_uncvref<_Tp, basic_string>::value> > | |
| 1024 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1025 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1026 | int> = 0> | |
| 963 | 1027 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 964 | basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()); | |
| 1028 | basic_string(const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a = allocator_type()) | |
| 1029 | : __r_(__default_init_tag(), __a) { | |
| 1030 | __self_view __sv0 = __t; | |
| 1031 | __self_view __sv = __sv0.substr(__pos, __n); | |
| 1032 | __init(__sv.data(), __sv.size()); | |
| 1033 | } | |
| 965 | 1034 | |
| 966 | 1035 | template <class _Tp, |
| 967 | class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 968 | !__is_same_uncvref<_Tp, basic_string>::value> > | |
| 969 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string( | |
| 970 | const _Tp& __t); | |
| 1036 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1037 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1038 | int> = 0> | |
| 1039 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string(const _Tp& __t) | |
| 1040 | : __r_(__default_init_tag(), __default_init_tag()) { | |
| 1041 | __self_view __sv = __t; | |
| 1042 | __init(__sv.data(), __sv.size()); | |
| 1043 | } | |
| 971 | 1044 | |
| 972 | 1045 | template <class _Tp, |
| 973 | class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 974 | !__is_same_uncvref<_Tp, basic_string>::value> > | |
| 1046 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1047 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1048 | int> = 0> | |
| 975 | 1049 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit basic_string( |
| 976 | const _Tp& __t, const allocator_type& __a); | |
| 1050 | const _Tp& __t, const allocator_type& __a) | |
| 1051 | : __r_(__default_init_tag(), __a) { | |
| 1052 | __self_view __sv = __t; | |
| 1053 | __init(__sv.data(), __sv.size()); | |
| 1054 | } | |
| 977 | 1055 | |
| 978 | template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > | |
| 1056 | template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 979 | 1057 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(_InputIterator __first, _InputIterator __last) |
| 980 | 1058 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 981 | 1059 | __init(__first, __last); |
| 982 | std::__debug_db_insert_c(this); | |
| 983 | 1060 | } |
| 984 | 1061 | |
| 985 | template <class _InputIterator, class = __enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value> > | |
| 1062 | template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 986 | 1063 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 987 | 1064 | basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a) |
| 988 | 1065 | : __r_(__default_init_tag(), __a) { |
| 989 | 1066 | __init(__first, __last); |
| 990 | std::__debug_db_insert_c(this); | |
| 991 | 1067 | } |
| 992 | 1068 | |
| 1069 | #if _LIBCPP_STD_VER >= 23 | |
| 1070 | template <_ContainerCompatibleRange<_CharT> _Range> | |
| 1071 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 1072 | basic_string(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) | |
| 1073 | : __r_(__default_init_tag(), __a) { | |
| 1074 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 1075 | __init_with_size(ranges::begin(__range), ranges::end(__range), ranges::distance(__range)); | |
| 1076 | } else { | |
| 1077 | __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 1078 | } | |
| 1079 | } | |
| 1080 | #endif | |
| 1081 | ||
| 993 | 1082 | #ifndef _LIBCPP_CXX03_LANG |
| 994 | 1083 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il) |
| 995 | 1084 | : __r_(__default_init_tag(), __default_init_tag()) { |
| 996 | 1085 | __init(__il.begin(), __il.end()); |
| 997 | std::__debug_db_insert_c(this); | |
| 998 | 1086 | } |
| 999 | 1087 | |
| 1000 | 1088 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string(initializer_list<_CharT> __il, const _Allocator& __a) |
| 1001 | 1089 | : __r_(__default_init_tag(), __a) { |
| 1002 | 1090 | __init(__il.begin(), __il.end()); |
| 1003 | std::__debug_db_insert_c(this); | |
| 1004 | 1091 | } |
| 1005 | 1092 | #endif // _LIBCPP_CXX03_LANG |
| 1006 | 1093 | |
| 1007 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string(); | |
| 1094 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 ~basic_string() { | |
| 1095 | if (__is_long()) | |
| 1096 | __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); | |
| 1097 | } | |
| 1008 | 1098 | |
| 1009 | 1099 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1010 | 1100 | operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); } |
| 1011 | 1101 | |
| 1012 | 1102 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const basic_string& __str); |
| 1013 | 1103 | |
| 1014 | template <class _Tp, class = __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1015 | !__is_same_uncvref<_Tp, basic_string>::value> > | |
| 1104 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1105 | !__is_same_uncvref<_Tp, basic_string>::value, int> = 0> | |
| 1016 | 1106 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(const _Tp& __t) { |
| 1017 | 1107 | __self_view __sv = __t; |
| 1018 | 1108 | return assign(__sv); |
| ... | ... | @@ -1030,7 +1120,7 @@ public: |
| 1030 | 1120 | #endif |
| 1031 | 1121 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1032 | 1122 | basic_string& operator=(const value_type* __s) {return assign(__s);} |
| 1033 | #if _LIBCPP_STD_VER > 20 | |
| 1123 | #if _LIBCPP_STD_VER >= 23 | |
| 1034 | 1124 | basic_string& operator=(nullptr_t) = delete; |
| 1035 | 1125 | #endif |
| 1036 | 1126 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& operator=(value_type __c); |
| ... | ... | @@ -1097,7 +1187,7 @@ public: |
| 1097 | 1187 | |
| 1098 | 1188 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void reserve(size_type __requested_capacity); |
| 1099 | 1189 | |
| 1100 | #if _LIBCPP_STD_VER > 20 | |
| 1190 | #if _LIBCPP_STD_VER >= 23 | |
| 1101 | 1191 | template <class _Op> |
| 1102 | 1192 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 1103 | 1193 | void resize_and_overwrite(size_type __n, _Op __op) { |
| ... | ... | @@ -1116,12 +1206,12 @@ public: |
| 1116 | 1206 | bool empty() const _NOEXCEPT {return size() == 0;} |
| 1117 | 1207 | |
| 1118 | 1208 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __pos) const _NOEXCEPT { |
| 1119 | _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); | |
| 1209 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); | |
| 1120 | 1210 | return *(data() + __pos); |
| 1121 | 1211 | } |
| 1122 | 1212 | |
| 1123 | 1213 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](size_type __pos) _NOEXCEPT { |
| 1124 | _LIBCPP_ASSERT(__pos <= size(), "string index out of bounds"); | |
| 1214 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos <= size(), "string index out of bounds"); | |
| 1125 | 1215 | return *(__get_pointer() + __pos); |
| 1126 | 1216 | } |
| 1127 | 1217 | |
| ... | ... | @@ -1132,14 +1222,11 @@ public: |
| 1132 | 1222 | return append(__str); |
| 1133 | 1223 | } |
| 1134 | 1224 | |
| 1135 | template <class _Tp> | |
| 1136 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1137 | __enable_if_t | |
| 1138 | < | |
| 1139 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 1140 | && !__is_same_uncvref<_Tp, basic_string >::value, | |
| 1141 | basic_string& | |
| 1142 | > | |
| 1225 | template <class _Tp, | |
| 1226 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1227 | !__is_same_uncvref<_Tp, basic_string >::value, | |
| 1228 | int> = 0> | |
| 1229 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1143 | 1230 | operator+=(const _Tp& __t) { |
| 1144 | 1231 | __self_view __sv = __t; return append(__sv); |
| 1145 | 1232 | } |
| ... | ... | @@ -1162,25 +1249,27 @@ public: |
| 1162 | 1249 | return append(__str.data(), __str.size()); |
| 1163 | 1250 | } |
| 1164 | 1251 | |
| 1165 | template <class _Tp> | |
| 1166 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1167 | __enable_if_t< | |
| 1168 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 1169 | && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1170 | basic_string& | |
| 1171 | > | |
| 1172 | append(const _Tp& __t) { __self_view __sv = __t; return append(__sv.data(), __sv.size()); } | |
| 1252 | template <class _Tp, | |
| 1253 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1254 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1255 | int> = 0> | |
| 1256 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1257 | append(const _Tp& __t) { | |
| 1258 | __self_view __sv = __t; | |
| 1259 | return append(__sv.data(), __sv.size()); | |
| 1260 | } | |
| 1261 | ||
| 1173 | 1262 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const basic_string& __str, size_type __pos, size_type __n=npos); |
| 1174 | 1263 | |
| 1175 | template <class _Tp> | |
| 1264 | template <class _Tp, | |
| 1265 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1266 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1267 | int> = 0> | |
| 1176 | 1268 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1177 | __enable_if_t | |
| 1178 | < | |
| 1179 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 1180 | && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1181 | basic_string& | |
| 1182 | > | |
| 1183 | append(const _Tp& __t, size_type __pos, size_type __n=npos); | |
| 1269 | ||
| 1270 | basic_string& | |
| 1271 | append(const _Tp& __t, size_type __pos, size_type __n = npos); | |
| 1272 | ||
| 1184 | 1273 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s, size_type __n); |
| 1185 | 1274 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(const value_type* __s); |
| 1186 | 1275 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& append(size_type __n, value_type __c); |
| ... | ... | @@ -1188,29 +1277,27 @@ public: |
| 1188 | 1277 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1189 | 1278 | void __append_default_init(size_type __n); |
| 1190 | 1279 | |
| 1191 | template<class _InputIterator> | |
| 1192 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 1193 | __enable_if_t | |
| 1194 | < | |
| 1195 | __is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 1196 | basic_string& | |
| 1197 | > | |
| 1198 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1280 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 1281 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1199 | 1282 | append(_InputIterator __first, _InputIterator __last) { |
| 1200 | const basic_string __temp(__first, __last, __alloc()); | |
| 1201 | append(__temp.data(), __temp.size()); | |
| 1202 | return *this; | |
| 1283 | const basic_string __temp(__first, __last, __alloc()); | |
| 1284 | append(__temp.data(), __temp.size()); | |
| 1285 | return *this; | |
| 1203 | 1286 | } |
| 1204 | template<class _ForwardIterator> | |
| 1205 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 1206 | __enable_if_t | |
| 1207 | < | |
| 1208 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 1209 | basic_string& | |
| 1210 | > | |
| 1211 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1287 | ||
| 1288 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> | |
| 1289 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1212 | 1290 | append(_ForwardIterator __first, _ForwardIterator __last); |
| 1213 | 1291 | |
| 1292 | #if _LIBCPP_STD_VER >= 23 | |
| 1293 | template <_ContainerCompatibleRange<_CharT> _Range> | |
| 1294 | _LIBCPP_HIDE_FROM_ABI | |
| 1295 | constexpr basic_string& append_range(_Range&& __range) { | |
| 1296 | insert_range(end(), std::forward<_Range>(__range)); | |
| 1297 | return *this; | |
| 1298 | } | |
| 1299 | #endif | |
| 1300 | ||
| 1214 | 1301 | #ifndef _LIBCPP_CXX03_LANG |
| 1215 | 1302 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1216 | 1303 | basic_string& append(initializer_list<value_type> __il) {return append(__il.begin(), __il.size());} |
| ... | ... | @@ -1220,33 +1307,32 @@ public: |
| 1220 | 1307 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back(); |
| 1221 | 1308 | |
| 1222 | 1309 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() _NOEXCEPT { |
| 1223 | _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); | |
| 1310 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); | |
| 1224 | 1311 | return *__get_pointer(); |
| 1225 | 1312 | } |
| 1226 | 1313 | |
| 1227 | 1314 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const _NOEXCEPT { |
| 1228 | _LIBCPP_ASSERT(!empty(), "string::front(): string is empty"); | |
| 1315 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::front(): string is empty"); | |
| 1229 | 1316 | return *data(); |
| 1230 | 1317 | } |
| 1231 | 1318 | |
| 1232 | 1319 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference back() _NOEXCEPT { |
| 1233 | _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); | |
| 1320 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); | |
| 1234 | 1321 | return *(__get_pointer() + size() - 1); |
| 1235 | 1322 | } |
| 1236 | 1323 | |
| 1237 | 1324 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const _NOEXCEPT { |
| 1238 | _LIBCPP_ASSERT(!empty(), "string::back(): string is empty"); | |
| 1325 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::back(): string is empty"); | |
| 1239 | 1326 | return *(data() + size() - 1); |
| 1240 | 1327 | } |
| 1241 | 1328 | |
| 1242 | template <class _Tp> | |
| 1243 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1244 | __enable_if_t | |
| 1245 | < | |
| 1246 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1247 | basic_string& | |
| 1248 | > | |
| 1249 | assign(const _Tp & __t) { __self_view __sv = __t; return assign(__sv.data(), __sv.size()); } | |
| 1329 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1330 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1331 | assign(const _Tp& __t) { | |
| 1332 | __self_view __sv = __t; | |
| 1333 | return assign(__sv.data(), __sv.size()); | |
| 1334 | } | |
| 1335 | ||
| 1250 | 1336 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1251 | 1337 | basic_string& assign(const basic_string& __str) { return *this = __str; } |
| 1252 | 1338 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -1256,34 +1342,42 @@ public: |
| 1256 | 1342 | {*this = std::move(__str); return *this;} |
| 1257 | 1343 | #endif |
| 1258 | 1344 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const basic_string& __str, size_type __pos, size_type __n=npos); |
| 1259 | template <class _Tp> | |
| 1260 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1261 | __enable_if_t | |
| 1262 | < | |
| 1263 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 1264 | && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1265 | basic_string& | |
| 1266 | > | |
| 1267 | assign(const _Tp & __t, size_type __pos, size_type __n=npos); | |
| 1345 | ||
| 1346 | template <class _Tp, | |
| 1347 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1348 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1349 | int> = 0> | |
| 1350 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1351 | assign(const _Tp& __t, size_type __pos, size_type __n = npos); | |
| 1352 | ||
| 1268 | 1353 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s, size_type __n); |
| 1269 | 1354 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(const value_type* __s); |
| 1270 | 1355 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& assign(size_type __n, value_type __c); |
| 1271 | template<class _InputIterator> | |
| 1272 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1273 | __enable_if_t | |
| 1274 | < | |
| 1275 | __is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 1276 | basic_string& | |
| 1277 | > | |
| 1278 | assign(_InputIterator __first, _InputIterator __last); | |
| 1279 | template<class _ForwardIterator> | |
| 1280 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1281 | __enable_if_t | |
| 1282 | < | |
| 1283 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 1284 | basic_string& | |
| 1285 | > | |
| 1286 | assign(_ForwardIterator __first, _ForwardIterator __last); | |
| 1356 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 1357 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1358 | assign(_InputIterator __first, _InputIterator __last); | |
| 1359 | ||
| 1360 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> | |
| 1361 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1362 | assign(_ForwardIterator __first, _ForwardIterator __last); | |
| 1363 | ||
| 1364 | #if _LIBCPP_STD_VER >= 23 | |
| 1365 | template <_ContainerCompatibleRange<_CharT> _Range> | |
| 1366 | _LIBCPP_HIDE_FROM_ABI | |
| 1367 | constexpr basic_string& assign_range(_Range&& __range) { | |
| 1368 | if constexpr (__string_is_trivial_iterator<ranges::iterator_t<_Range>>::value && | |
| 1369 | (ranges::forward_range<_Range> || ranges::sized_range<_Range>)) { | |
| 1370 | size_type __n = static_cast<size_type>(ranges::distance(__range)); | |
| 1371 | __assign_trivial(ranges::begin(__range), ranges::end(__range), __n); | |
| 1372 | ||
| 1373 | } else { | |
| 1374 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 1375 | } | |
| 1376 | ||
| 1377 | return *this; | |
| 1378 | } | |
| 1379 | #endif | |
| 1380 | ||
| 1287 | 1381 | #ifndef _LIBCPP_CXX03_LANG |
| 1288 | 1382 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1289 | 1383 | basic_string& assign(initializer_list<value_type> __il) {return assign(__il.begin(), __il.size());} |
| ... | ... | @@ -1294,56 +1388,57 @@ public: |
| 1294 | 1388 | return insert(__pos1, __str.data(), __str.size()); |
| 1295 | 1389 | } |
| 1296 | 1390 | |
| 1297 | template <class _Tp> | |
| 1298 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1299 | __enable_if_t | |
| 1300 | < | |
| 1301 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1302 | basic_string& | |
| 1303 | > | |
| 1304 | insert(size_type __pos1, const _Tp& __t) | |
| 1305 | { __self_view __sv = __t; return insert(__pos1, __sv.data(), __sv.size()); } | |
| 1391 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1392 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1393 | insert(size_type __pos1, const _Tp& __t) { | |
| 1394 | __self_view __sv = __t; | |
| 1395 | return insert(__pos1, __sv.data(), __sv.size()); | |
| 1396 | } | |
| 1306 | 1397 | |
| 1307 | template <class _Tp> | |
| 1308 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1309 | __enable_if_t | |
| 1310 | < | |
| 1311 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1312 | basic_string& | |
| 1313 | > | |
| 1314 | insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n=npos); | |
| 1315 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1316 | basic_string& insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n=npos); | |
| 1317 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); | |
| 1318 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s); | |
| 1319 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c); | |
| 1320 | _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c); | |
| 1398 | template <class _Tp, | |
| 1399 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1400 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1401 | int> = 0> | |
| 1402 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1403 | insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n = npos); | |
| 1404 | ||
| 1405 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1406 | insert(size_type __pos1, const basic_string& __str, size_type __pos2, size_type __n = npos); | |
| 1407 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s, size_type __n); | |
| 1408 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, const value_type* __s); | |
| 1409 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& insert(size_type __pos, size_type __n, value_type __c); | |
| 1410 | _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __pos, value_type __c); | |
| 1411 | ||
| 1412 | #if _LIBCPP_STD_VER >= 23 | |
| 1413 | template <_ContainerCompatibleRange<_CharT> _Range> | |
| 1414 | _LIBCPP_HIDE_FROM_ABI | |
| 1415 | constexpr iterator insert_range(const_iterator __position, _Range&& __range) { | |
| 1416 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 1417 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 1418 | return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); | |
| 1419 | ||
| 1420 | } else { | |
| 1421 | basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); | |
| 1422 | return insert(__position, __temp.data(), __temp.data() + __temp.size()); | |
| 1423 | } | |
| 1424 | } | |
| 1425 | #endif | |
| 1321 | 1426 | |
| 1322 | 1427 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator |
| 1323 | 1428 | insert(const_iterator __pos, size_type __n, value_type __c) { |
| 1324 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, | |
| 1325 | "string::insert(iterator, n, value) called with an iterator not referring to this string"); | |
| 1326 | 1429 | difference_type __p = __pos - begin(); |
| 1327 | 1430 | insert(static_cast<size_type>(__p), __n, __c); |
| 1328 | 1431 | return begin() + __p; |
| 1329 | 1432 | } |
| 1330 | 1433 | |
| 1331 | template<class _InputIterator> | |
| 1332 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1333 | __enable_if_t | |
| 1334 | < | |
| 1335 | __is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 1336 | iterator | |
| 1337 | > | |
| 1338 | insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); | |
| 1339 | template<class _ForwardIterator> | |
| 1340 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1341 | __enable_if_t | |
| 1342 | < | |
| 1343 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 1344 | iterator | |
| 1345 | > | |
| 1346 | insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); | |
| 1434 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 1435 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator | |
| 1436 | insert(const_iterator __pos, _InputIterator __first, _InputIterator __last); | |
| 1437 | ||
| 1438 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> | |
| 1439 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator | |
| 1440 | insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last); | |
| 1441 | ||
| 1347 | 1442 | #ifndef _LIBCPP_CXX03_LANG |
| 1348 | 1443 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1349 | 1444 | iterator insert(const_iterator __pos, initializer_list<value_type> __il) |
| ... | ... | @@ -1361,28 +1456,27 @@ public: |
| 1361 | 1456 | return replace(__pos1, __n1, __str.data(), __str.size()); |
| 1362 | 1457 | } |
| 1363 | 1458 | |
| 1364 | template <class _Tp> | |
| 1365 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1366 | __enable_if_t | |
| 1367 | < | |
| 1368 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1369 | basic_string& | |
| 1370 | > | |
| 1371 | replace(size_type __pos1, size_type __n1, const _Tp& __t) { __self_view __sv = __t; return replace(__pos1, __n1, __sv.data(), __sv.size()); } | |
| 1372 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1373 | basic_string& replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2=npos); | |
| 1374 | template <class _Tp> | |
| 1375 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1376 | __enable_if_t | |
| 1377 | < | |
| 1378 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1379 | basic_string& | |
| 1380 | > | |
| 1381 | replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos); | |
| 1382 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1383 | basic_string& replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); | |
| 1384 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); | |
| 1385 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); | |
| 1459 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1460 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1461 | replace(size_type __pos1, size_type __n1, const _Tp& __t) { | |
| 1462 | __self_view __sv = __t; | |
| 1463 | return replace(__pos1, __n1, __sv.data(), __sv.size()); | |
| 1464 | } | |
| 1465 | ||
| 1466 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1467 | replace(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, size_type __n2 = npos); | |
| 1468 | ||
| 1469 | template <class _Tp, | |
| 1470 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1471 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1472 | int> = 0> | |
| 1473 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1474 | replace(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos); | |
| 1475 | ||
| 1476 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1477 | replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2); | |
| 1478 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, const value_type* __s); | |
| 1479 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& replace(size_type __pos, size_type __n1, size_type __n2, value_type __c); | |
| 1386 | 1480 | |
| 1387 | 1481 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& |
| 1388 | 1482 | replace(const_iterator __i1, const_iterator __i2, const basic_string& __str) { |
| ... | ... | @@ -1390,14 +1484,12 @@ public: |
| 1390 | 1484 | static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __str.data(), __str.size()); |
| 1391 | 1485 | } |
| 1392 | 1486 | |
| 1393 | template <class _Tp> | |
| 1394 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1395 | __enable_if_t | |
| 1396 | < | |
| 1397 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1398 | basic_string& | |
| 1399 | > | |
| 1400 | replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { __self_view __sv = __t; return replace(__i1 - begin(), __i2 - __i1, __sv); } | |
| 1487 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1488 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1489 | replace(const_iterator __i1, const_iterator __i2, const _Tp& __t) { | |
| 1490 | __self_view __sv = __t; | |
| 1491 | return replace(__i1 - begin(), __i2 - __i1, __sv); | |
| 1492 | } | |
| 1401 | 1493 | |
| 1402 | 1494 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& |
| 1403 | 1495 | replace(const_iterator __i1, const_iterator __i2, const value_type* __s, size_type __n) { |
| ... | ... | @@ -1414,14 +1506,19 @@ public: |
| 1414 | 1506 | return replace(static_cast<size_type>(__i1 - begin()), static_cast<size_type>(__i2 - __i1), __n, __c); |
| 1415 | 1507 | } |
| 1416 | 1508 | |
| 1417 | template<class _InputIterator> | |
| 1418 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1419 | __enable_if_t | |
| 1420 | < | |
| 1421 | __is_cpp17_input_iterator<_InputIterator>::value, | |
| 1422 | basic_string& | |
| 1423 | > | |
| 1424 | replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); | |
| 1509 | template <class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 1510 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string& | |
| 1511 | replace(const_iterator __i1, const_iterator __i2, _InputIterator __j1, _InputIterator __j2); | |
| 1512 | ||
| 1513 | #if _LIBCPP_STD_VER >= 23 | |
| 1514 | template <_ContainerCompatibleRange<_CharT> _Range> | |
| 1515 | _LIBCPP_HIDE_FROM_ABI | |
| 1516 | constexpr basic_string& replace_with_range(const_iterator __i1, const_iterator __i2, _Range&& __range) { | |
| 1517 | basic_string __temp(from_range, std::forward<_Range>(__range), __alloc()); | |
| 1518 | return replace(__i1, __i2, __temp); | |
| 1519 | } | |
| 1520 | #endif | |
| 1521 | ||
| 1425 | 1522 | #ifndef _LIBCPP_CXX03_LANG |
| 1426 | 1523 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1427 | 1524 | basic_string& replace(const_iterator __i1, const_iterator __i2, initializer_list<value_type> __il) |
| ... | ... | @@ -1460,7 +1557,7 @@ public: |
| 1460 | 1557 | const value_type* c_str() const _NOEXCEPT {return data();} |
| 1461 | 1558 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1462 | 1559 | const value_type* data() const _NOEXCEPT {return std::__to_address(__get_pointer());} |
| 1463 | #if _LIBCPP_STD_VER > 14 || defined(_LIBCPP_BUILDING_LIBRARY) | |
| 1560 | #if _LIBCPP_STD_VER >= 17 | |
| 1464 | 1561 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1465 | 1562 | value_type* data() _NOEXCEPT {return std::__to_address(__get_pointer());} |
| 1466 | 1563 | #endif |
| ... | ... | @@ -1471,16 +1568,11 @@ public: |
| 1471 | 1568 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1472 | 1569 | size_type find(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; |
| 1473 | 1570 | |
| 1474 | template <class _Tp> | |
| 1475 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1476 | __enable_if_t | |
| 1477 | < | |
| 1478 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1479 | size_type | |
| 1480 | > | |
| 1481 | find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; | |
| 1482 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1483 | size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; | |
| 1571 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1572 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1573 | find(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; | |
| 1574 | ||
| 1575 | _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; | |
| 1484 | 1576 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1485 | 1577 | size_type find(const value_type* __s, size_type __pos = 0) const _NOEXCEPT; |
| 1486 | 1578 | _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type find(value_type __c, size_type __pos = 0) const _NOEXCEPT; |
| ... | ... | @@ -1488,14 +1580,10 @@ public: |
| 1488 | 1580 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1489 | 1581 | size_type rfind(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; |
| 1490 | 1582 | |
| 1491 | template <class _Tp> | |
| 1492 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1493 | __enable_if_t | |
| 1494 | < | |
| 1495 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1496 | size_type | |
| 1497 | > | |
| 1498 | rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1583 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1584 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1585 | rfind(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1586 | ||
| 1499 | 1587 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1500 | 1588 | size_type rfind(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; |
| 1501 | 1589 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1505,14 +1593,10 @@ public: |
| 1505 | 1593 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1506 | 1594 | size_type find_first_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; |
| 1507 | 1595 | |
| 1508 | template <class _Tp> | |
| 1509 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1510 | __enable_if_t | |
| 1511 | < | |
| 1512 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1513 | size_type | |
| 1514 | > | |
| 1515 | find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; | |
| 1596 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1597 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1598 | find_first_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; | |
| 1599 | ||
| 1516 | 1600 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1517 | 1601 | size_type find_first_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; |
| 1518 | 1602 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1523,14 +1607,10 @@ public: |
| 1523 | 1607 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1524 | 1608 | size_type find_last_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; |
| 1525 | 1609 | |
| 1526 | template <class _Tp> | |
| 1527 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1528 | __enable_if_t | |
| 1529 | < | |
| 1530 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1531 | size_type | |
| 1532 | > | |
| 1533 | find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1610 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1611 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1612 | find_last_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1613 | ||
| 1534 | 1614 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1535 | 1615 | size_type find_last_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; |
| 1536 | 1616 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1541,14 +1621,10 @@ public: |
| 1541 | 1621 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1542 | 1622 | size_type find_first_not_of(const basic_string& __str, size_type __pos = 0) const _NOEXCEPT; |
| 1543 | 1623 | |
| 1544 | template <class _Tp> | |
| 1545 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1546 | __enable_if_t | |
| 1547 | < | |
| 1548 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1549 | size_type | |
| 1550 | > | |
| 1551 | find_first_not_of(const _Tp &__t, size_type __pos = 0) const _NOEXCEPT; | |
| 1624 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1625 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1626 | find_first_not_of(const _Tp& __t, size_type __pos = 0) const _NOEXCEPT; | |
| 1627 | ||
| 1552 | 1628 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1553 | 1629 | size_type find_first_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; |
| 1554 | 1630 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1559,14 +1635,10 @@ public: |
| 1559 | 1635 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1560 | 1636 | size_type find_last_not_of(const basic_string& __str, size_type __pos = npos) const _NOEXCEPT; |
| 1561 | 1637 | |
| 1562 | template <class _Tp> | |
| 1563 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1564 | __enable_if_t | |
| 1565 | < | |
| 1566 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1567 | size_type | |
| 1568 | > | |
| 1569 | find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1638 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1639 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type | |
| 1640 | find_last_not_of(const _Tp& __t, size_type __pos = npos) const _NOEXCEPT; | |
| 1641 | ||
| 1570 | 1642 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1571 | 1643 | size_type find_last_not_of(const value_type* __s, size_type __pos, size_type __n) const _NOEXCEPT; |
| 1572 | 1644 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1577,23 +1649,13 @@ public: |
| 1577 | 1649 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1578 | 1650 | int compare(const basic_string& __str) const _NOEXCEPT; |
| 1579 | 1651 | |
| 1580 | template <class _Tp> | |
| 1581 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1582 | __enable_if_t | |
| 1583 | < | |
| 1584 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1585 | int | |
| 1586 | > | |
| 1587 | compare(const _Tp &__t) const _NOEXCEPT; | |
| 1652 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1653 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int | |
| 1654 | compare(const _Tp& __t) const _NOEXCEPT; | |
| 1588 | 1655 | |
| 1589 | template <class _Tp> | |
| 1590 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1591 | __enable_if_t | |
| 1592 | < | |
| 1593 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 1594 | int | |
| 1595 | > | |
| 1596 | compare(size_type __pos1, size_type __n1, const _Tp& __t) const; | |
| 1656 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> = 0> | |
| 1657 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS _LIBCPP_CONSTEXPR_SINCE_CXX20 int | |
| 1658 | compare(size_type __pos1, size_type __n1, const _Tp& __t) const; | |
| 1597 | 1659 | |
| 1598 | 1660 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1599 | 1661 | int compare(size_type __pos1, size_type __n1, const basic_string& __str) const; |
| ... | ... | @@ -1601,20 +1663,19 @@ public: |
| 1601 | 1663 | int compare(size_type __pos1, size_type __n1, const basic_string& __str, size_type __pos2, |
| 1602 | 1664 | size_type __n2 = npos) const; |
| 1603 | 1665 | |
| 1604 | template <class _Tp> | |
| 1605 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1606 | __enable_if_t | |
| 1607 | < | |
| 1608 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1609 | int | |
| 1610 | > | |
| 1611 | compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2=npos) const; | |
| 1666 | template <class _Tp, | |
| 1667 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 1668 | !__is_same_uncvref<_Tp, basic_string>::value, | |
| 1669 | int> = 0> | |
| 1670 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 int | |
| 1671 | compare(size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2 = npos) const; | |
| 1672 | ||
| 1612 | 1673 | _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(const value_type* __s) const _NOEXCEPT; |
| 1613 | 1674 | _LIBCPP_CONSTEXPR_SINCE_CXX20 int compare(size_type __pos1, size_type __n1, const value_type* __s) const; |
| 1614 | 1675 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1615 | 1676 | int compare(size_type __pos1, size_type __n1, const value_type* __s, size_type __n2) const; |
| 1616 | 1677 | |
| 1617 | #if _LIBCPP_STD_VER > 17 | |
| 1678 | #if _LIBCPP_STD_VER >= 20 | |
| 1618 | 1679 | constexpr _LIBCPP_HIDE_FROM_ABI |
| 1619 | 1680 | bool starts_with(__self_view __sv) const noexcept |
| 1620 | 1681 | { return __self_view(data(), size()).starts_with(__sv); } |
| ... | ... | @@ -1640,7 +1701,7 @@ public: |
| 1640 | 1701 | { return ends_with(__self_view(__s)); } |
| 1641 | 1702 | #endif |
| 1642 | 1703 | |
| 1643 | #if _LIBCPP_STD_VER > 20 | |
| 1704 | #if _LIBCPP_STD_VER >= 23 | |
| 1644 | 1705 | constexpr _LIBCPP_HIDE_FROM_ABI |
| 1645 | 1706 | bool contains(__self_view __sv) const noexcept |
| 1646 | 1707 | { return __self_view(data(), size()).contains(__sv); } |
| ... | ... | @@ -1658,15 +1719,6 @@ public: |
| 1658 | 1719 | |
| 1659 | 1720 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __clear_and_shrink() _NOEXCEPT; |
| 1660 | 1721 | |
| 1661 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1662 | ||
| 1663 | bool __dereferenceable(const const_iterator* __i) const; | |
| 1664 | bool __decrementable(const const_iterator* __i) const; | |
| 1665 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1666 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 1667 | ||
| 1668 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 1669 | ||
| 1670 | 1722 | private: |
| 1671 | 1723 | template<class _Alloc> |
| 1672 | 1724 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1683,7 +1735,7 @@ private: |
| 1683 | 1735 | } |
| 1684 | 1736 | |
| 1685 | 1737 | static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __begin_lifetime(pointer __begin, size_type __n) { |
| 1686 | #if _LIBCPP_STD_VER > 17 | |
| 1738 | #if _LIBCPP_STD_VER >= 20 | |
| 1687 | 1739 | if (__libcpp_is_constant_evaluated()) { |
| 1688 | 1740 | for (size_type __i = 0; __i != __n; ++__i) |
| 1689 | 1741 | std::construct_at(std::addressof(__begin[__i])); |
| ... | ... | @@ -1691,7 +1743,7 @@ private: |
| 1691 | 1743 | #else |
| 1692 | 1744 | (void)__begin; |
| 1693 | 1745 | (void)__n; |
| 1694 | #endif // _LIBCPP_STD_VER > 17 | |
| 1746 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1695 | 1747 | } |
| 1696 | 1748 | |
| 1697 | 1749 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __default_init() { |
| ... | ... | @@ -1716,9 +1768,17 @@ private: |
| 1716 | 1768 | return !__libcpp_is_constant_evaluated() && (__sz < __min_cap); |
| 1717 | 1769 | } |
| 1718 | 1770 | |
| 1719 | template <class _ForwardIterator> | |
| 1771 | template <class _Iterator, class _Sentinel> | |
| 1772 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1773 | void __assign_trivial(_Iterator __first, _Sentinel __last, size_type __n); | |
| 1774 | ||
| 1775 | template <class _Iterator, class _Sentinel> | |
| 1776 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1777 | void __assign_with_sentinel(_Iterator __first, _Sentinel __last); | |
| 1778 | ||
| 1779 | template <class _ForwardIterator, class _Sentinel> | |
| 1720 | 1780 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 1721 | iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _ForwardIterator __last) { | |
| 1781 | iterator __insert_from_safe_copy(size_type __n, size_type __ip, _ForwardIterator __first, _Sentinel __last) { | |
| 1722 | 1782 | size_type __sz = size(); |
| 1723 | 1783 | size_type __cap = capacity(); |
| 1724 | 1784 | value_type* __p; |
| ... | ... | @@ -1731,7 +1791,7 @@ private: |
| 1731 | 1791 | } |
| 1732 | 1792 | else |
| 1733 | 1793 | { |
| 1734 | __grow_by(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); | |
| 1794 | __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __ip, 0, __n); | |
| 1735 | 1795 | __p = std::__to_address(__get_long_pointer()); |
| 1736 | 1796 | } |
| 1737 | 1797 | __sz += __n; |
| ... | ... | @@ -1743,19 +1803,25 @@ private: |
| 1743 | 1803 | return begin() + __ip; |
| 1744 | 1804 | } |
| 1745 | 1805 | |
| 1806 | template<class _Iterator, class _Sentinel> | |
| 1807 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1808 | iterator __insert_with_size(const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n); | |
| 1809 | ||
| 1746 | 1810 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 allocator_type& __alloc() _NOEXCEPT { return __r_.second(); } |
| 1747 | 1811 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const allocator_type& __alloc() const _NOEXCEPT { return __r_.second(); } |
| 1748 | 1812 | |
| 1749 | 1813 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1750 | 1814 | void __set_short_size(size_type __s) _NOEXCEPT { |
| 1751 | _LIBCPP_ASSERT(__s < __min_cap, "__s should never be greater than or equal to the short string capacity"); | |
| 1815 | _LIBCPP_ASSERT_INTERNAL( | |
| 1816 | __s < __min_cap, "__s should never be greater than or equal to the short string capacity"); | |
| 1752 | 1817 | __r_.first().__s.__size_ = __s; |
| 1753 | 1818 | __r_.first().__s.__is_long_ = false; |
| 1754 | 1819 | } |
| 1755 | 1820 | |
| 1756 | 1821 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1757 | 1822 | size_type __get_short_size() const _NOEXCEPT { |
| 1758 | _LIBCPP_ASSERT(!__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); | |
| 1823 | _LIBCPP_ASSERT_INTERNAL( | |
| 1824 | !__r_.first().__s.__is_long_, "String has to be short when trying to get the short size"); | |
| 1759 | 1825 | return __r_.first().__s.__size_; |
| 1760 | 1826 | } |
| 1761 | 1827 | |
| ... | ... | @@ -1839,25 +1905,29 @@ private: |
| 1839 | 1905 | // to only inline the fast path code directly in the ctor. |
| 1840 | 1906 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init_copy_ctor_external(const value_type* __s, size_type __sz); |
| 1841 | 1907 | |
| 1842 | template <class _InputIterator> | |
| 1843 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1844 | __enable_if_t | |
| 1845 | < | |
| 1846 | __is_exactly_cpp17_input_iterator<_InputIterator>::value | |
| 1847 | > | |
| 1848 | __init(_InputIterator __first, _InputIterator __last); | |
| 1908 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> = 0> | |
| 1909 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_InputIterator __first, _InputIterator __last); | |
| 1849 | 1910 | |
| 1850 | template <class _ForwardIterator> | |
| 1851 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1852 | __enable_if_t | |
| 1853 | < | |
| 1854 | __is_cpp17_forward_iterator<_ForwardIterator>::value | |
| 1855 | > | |
| 1856 | __init(_ForwardIterator __first, _ForwardIterator __last); | |
| 1911 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0> | |
| 1912 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 void __init(_ForwardIterator __first, _ForwardIterator __last); | |
| 1913 | ||
| 1914 | template <class _InputIterator, class _Sentinel> | |
| 1915 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1916 | void __init_with_sentinel(_InputIterator __first, _Sentinel __last); | |
| 1917 | template <class _InputIterator, class _Sentinel> | |
| 1918 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1919 | void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __sz); | |
| 1857 | 1920 | |
| 1858 | 1921 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1922 | #if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 | |
| 1923 | _LIBCPP_HIDE_FROM_ABI | |
| 1924 | #endif | |
| 1925 | _LIBCPP_DEPRECATED_("use __grow_by_without_replace") | |
| 1859 | 1926 | void __grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, |
| 1860 | 1927 | size_type __n_copy, size_type __n_del, size_type __n_add = 0); |
| 1928 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1929 | void __grow_by_without_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, | |
| 1930 | size_type __n_copy, size_type __n_del, size_type __n_add = 0); | |
| 1861 | 1931 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1862 | 1932 | void __grow_by_and_replace(size_type __old_cap, size_type __delta_cap, size_type __old_sz, |
| 1863 | 1933 | size_type __n_copy, size_type __n_del, |
| ... | ... | @@ -1918,7 +1988,7 @@ private: |
| 1918 | 1988 | _NOEXCEPT_(__alloc_traits::is_always_equal::value); |
| 1919 | 1989 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1920 | 1990 | void __move_assign(basic_string& __str, true_type) |
| 1921 | #if _LIBCPP_STD_VER > 14 | |
| 1991 | #if _LIBCPP_STD_VER >= 17 | |
| 1922 | 1992 | _NOEXCEPT; |
| 1923 | 1993 | #else |
| 1924 | 1994 | _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value); |
| ... | ... | @@ -1962,21 +2032,13 @@ private: |
| 1962 | 2032 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1963 | 2033 | basic_string& __null_terminate_at(value_type* __p, size_type __newsz) { |
| 1964 | 2034 | __set_size(__newsz); |
| 1965 | __invalidate_iterators_past(__newsz); | |
| 1966 | 2035 | traits_type::assign(__p[__newsz], value_type()); |
| 1967 | 2036 | return *this; |
| 1968 | 2037 | } |
| 1969 | 2038 | |
| 1970 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __invalidate_iterators_past(size_type); | |
| 1971 | ||
| 1972 | template<class _Tp> | |
| 1973 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 1974 | bool __addr_in_range(_Tp&& __t) const { | |
| 1975 | // assume that the ranges overlap, because we can't check during constant evaluation | |
| 1976 | if (__libcpp_is_constant_evaluated()) | |
| 1977 | return true; | |
| 1978 | const volatile void *__p = std::addressof(__t); | |
| 1979 | return data() <= __p && __p <= data() + size(); | |
| 2039 | template <class _Tp> | |
| 2040 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __addr_in_range(const _Tp& __v) const { | |
| 2041 | return std::__is_pointer_in_range(data(), data() + size() + 1, std::addressof(__v)); | |
| 1980 | 2042 | } |
| 1981 | 2043 | |
| 1982 | 2044 | _LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -2017,7 +2079,7 @@ private: |
| 2017 | 2079 | template<class _InputIterator, |
| 2018 | 2080 | class _CharT = __iter_value_type<_InputIterator>, |
| 2019 | 2081 | class _Allocator = allocator<_CharT>, |
| 2020 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 2082 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 2021 | 2083 | class = enable_if_t<__is_allocator<_Allocator>::value> |
| 2022 | 2084 | > |
| 2023 | 2085 | basic_string(_InputIterator, _InputIterator, _Allocator = _Allocator()) |
| ... | ... | @@ -2041,35 +2103,14 @@ basic_string(basic_string_view<_CharT, _Traits>, _Sz, _Sz, const _Allocator& = _ |
| 2041 | 2103 | -> basic_string<_CharT, _Traits, _Allocator>; |
| 2042 | 2104 | #endif |
| 2043 | 2105 | |
| 2044 | template <class _CharT, class _Traits, class _Allocator> | |
| 2045 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2046 | void | |
| 2047 | basic_string<_CharT, _Traits, _Allocator>::__invalidate_iterators_past(size_type __pos) | |
| 2048 | { | |
| 2049 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2050 | if (!__libcpp_is_constant_evaluated()) { | |
| 2051 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 2052 | if (__c) | |
| 2053 | { | |
| 2054 | const_pointer __new_last = __get_pointer() + __pos; | |
| 2055 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) | |
| 2056 | { | |
| 2057 | --__p; | |
| 2058 | const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); | |
| 2059 | if (__i->base() > __new_last) | |
| 2060 | { | |
| 2061 | (*__p)->__c_ = nullptr; | |
| 2062 | if (--__c->end_ != __p) | |
| 2063 | std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 2064 | } | |
| 2065 | } | |
| 2066 | __get_db()->unlock(); | |
| 2067 | } | |
| 2068 | } | |
| 2069 | #else | |
| 2070 | (void)__pos; | |
| 2071 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 2072 | } | |
| 2106 | #if _LIBCPP_STD_VER >= 23 | |
| 2107 | template <ranges::input_range _Range, | |
| 2108 | class _Allocator = allocator<ranges::range_value_t<_Range>>, | |
| 2109 | class = enable_if_t<__is_allocator<_Allocator>::value> | |
| 2110 | > | |
| 2111 | basic_string(from_range_t, _Range&&, _Allocator = _Allocator()) | |
| 2112 | -> basic_string<ranges::range_value_t<_Range>, char_traits<ranges::range_value_t<_Range>>, _Allocator>; | |
| 2113 | #endif | |
| 2073 | 2114 | |
| 2074 | 2115 | template <class _CharT, class _Traits, class _Allocator> |
| 2075 | 2116 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -2128,44 +2169,6 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty |
| 2128 | 2169 | traits_type::assign(__p[__sz], value_type()); |
| 2129 | 2170 | } |
| 2130 | 2171 | |
| 2131 | template <class _CharT, class _Traits, class _Allocator> | |
| 2132 | template <class> | |
| 2133 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2134 | basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a) | |
| 2135 | : __r_(__default_init_tag(), __a) | |
| 2136 | { | |
| 2137 | _LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr"); | |
| 2138 | __init(__s, traits_type::length(__s)); | |
| 2139 | std::__debug_db_insert_c(this); | |
| 2140 | } | |
| 2141 | ||
| 2142 | template <class _CharT, class _Traits, class _Allocator> | |
| 2143 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2144 | basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str) | |
| 2145 | : __r_(__default_init_tag(), __alloc_traits::select_on_container_copy_construction(__str.__alloc())) | |
| 2146 | { | |
| 2147 | if (!__str.__is_long()) | |
| 2148 | __r_.first() = __str.__r_.first(); | |
| 2149 | else | |
| 2150 | __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), | |
| 2151 | __str.__get_long_size()); | |
| 2152 | std::__debug_db_insert_c(this); | |
| 2153 | } | |
| 2154 | ||
| 2155 | template <class _CharT, class _Traits, class _Allocator> | |
| 2156 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2157 | basic_string<_CharT, _Traits, _Allocator>::basic_string( | |
| 2158 | const basic_string& __str, const allocator_type& __a) | |
| 2159 | : __r_(__default_init_tag(), __a) | |
| 2160 | { | |
| 2161 | if (!__str.__is_long()) | |
| 2162 | __r_.first() = __str.__r_.first(); | |
| 2163 | else | |
| 2164 | __init_copy_ctor_external(std::__to_address(__str.__get_long_pointer()), | |
| 2165 | __str.__get_long_size()); | |
| 2166 | std::__debug_db_insert_c(this); | |
| 2167 | } | |
| 2168 | ||
| 2169 | 2172 | template <class _CharT, class _Traits, class _Allocator> |
| 2170 | 2173 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2171 | 2174 | void basic_string<_CharT, _Traits, _Allocator>::__init_copy_ctor_external( |
| ... | ... | @@ -2220,81 +2223,26 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c) |
| 2220 | 2223 | } |
| 2221 | 2224 | |
| 2222 | 2225 | template <class _CharT, class _Traits, class _Allocator> |
| 2223 | template <class> | |
| 2224 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2225 | basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a) | |
| 2226 | : __r_(__default_init_tag(), __a) | |
| 2227 | { | |
| 2228 | __init(__n, __c); | |
| 2229 | std::__debug_db_insert_c(this); | |
| 2230 | } | |
| 2231 | ||
| 2232 | template <class _CharT, class _Traits, class _Allocator> | |
| 2233 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2234 | basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, | |
| 2235 | size_type __pos, size_type __n, | |
| 2236 | const _Allocator& __a) | |
| 2237 | : __r_(__default_init_tag(), __a) | |
| 2238 | { | |
| 2239 | size_type __str_sz = __str.size(); | |
| 2240 | if (__pos > __str_sz) | |
| 2241 | __throw_out_of_range(); | |
| 2242 | __init(__str.data() + __pos, std::min(__n, __str_sz - __pos)); | |
| 2243 | std::__debug_db_insert_c(this); | |
| 2244 | } | |
| 2245 | ||
| 2246 | template <class _CharT, class _Traits, class _Allocator> | |
| 2247 | template <class _Tp, class> | |
| 2248 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2249 | basic_string<_CharT, _Traits, _Allocator>::basic_string( | |
| 2250 | const _Tp& __t, size_type __pos, size_type __n, const allocator_type& __a) | |
| 2251 | : __r_(__default_init_tag(), __a) | |
| 2252 | { | |
| 2253 | __self_view __sv0 = __t; | |
| 2254 | __self_view __sv = __sv0.substr(__pos, __n); | |
| 2255 | __init(__sv.data(), __sv.size()); | |
| 2256 | std::__debug_db_insert_c(this); | |
| 2257 | } | |
| 2258 | ||
| 2259 | template <class _CharT, class _Traits, class _Allocator> | |
| 2260 | template <class _Tp, class> | |
| 2261 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2262 | basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t) | |
| 2263 | : __r_(__default_init_tag(), __default_init_tag()) | |
| 2264 | { | |
| 2265 | __self_view __sv = __t; | |
| 2266 | __init(__sv.data(), __sv.size()); | |
| 2267 | std::__debug_db_insert_c(this); | |
| 2268 | } | |
| 2269 | ||
| 2270 | template <class _CharT, class _Traits, class _Allocator> | |
| 2271 | template <class _Tp, class> | |
| 2226 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > | |
| 2272 | 2227 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2273 | basic_string<_CharT, _Traits, _Allocator>::basic_string(const _Tp & __t, const _Allocator& __a) | |
| 2274 | : __r_(__default_init_tag(), __a) | |
| 2228 | void basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) | |
| 2275 | 2229 | { |
| 2276 | __self_view __sv = __t; | |
| 2277 | __init(__sv.data(), __sv.size()); | |
| 2278 | std::__debug_db_insert_c(this); | |
| 2230 | __init_with_sentinel(std::move(__first), std::move(__last)); | |
| 2279 | 2231 | } |
| 2280 | 2232 | |
| 2281 | 2233 | template <class _CharT, class _Traits, class _Allocator> |
| 2282 | template <class _InputIterator> | |
| 2283 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2284 | __enable_if_t | |
| 2285 | < | |
| 2286 | __is_exactly_cpp17_input_iterator<_InputIterator>::value | |
| 2287 | > | |
| 2288 | basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _InputIterator __last) | |
| 2289 | { | |
| 2234 | template <class _InputIterator, class _Sentinel> | |
| 2235 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2236 | void basic_string<_CharT, _Traits, _Allocator>::__init_with_sentinel(_InputIterator __first, _Sentinel __last) { | |
| 2290 | 2237 | __default_init(); |
| 2291 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2238 | ||
| 2239 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2292 | 2240 | try |
| 2293 | 2241 | { |
| 2294 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2242 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2295 | 2243 | for (; __first != __last; ++__first) |
| 2296 | 2244 | push_back(*__first); |
| 2297 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2245 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2298 | 2246 | } |
| 2299 | 2247 | catch (...) |
| 2300 | 2248 | { |
| ... | ... | @@ -2302,28 +2250,35 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_InputIterator __first, _Input |
| 2302 | 2250 | __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); |
| 2303 | 2251 | throw; |
| 2304 | 2252 | } |
| 2305 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2253 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2306 | 2254 | } |
| 2307 | 2255 | |
| 2308 | 2256 | template <class _CharT, class _Traits, class _Allocator> |
| 2309 | template <class _ForwardIterator> | |
| 2310 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2311 | __enable_if_t | |
| 2312 | < | |
| 2313 | __is_cpp17_forward_iterator<_ForwardIterator>::value | |
| 2314 | > | |
| 2257 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > | |
| 2258 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void | |
| 2315 | 2259 | basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _ForwardIterator __last) |
| 2316 | 2260 | { |
| 2261 | size_type __sz = static_cast<size_type>(std::distance(__first, __last)); | |
| 2262 | __init_with_size(__first, __last, __sz); | |
| 2263 | } | |
| 2264 | ||
| 2265 | template <class _CharT, class _Traits, class _Allocator> | |
| 2266 | template <class _InputIterator, class _Sentinel> | |
| 2267 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2268 | void basic_string<_CharT, _Traits, _Allocator>::__init_with_size( | |
| 2269 | _InputIterator __first, _Sentinel __last, size_type __sz) { | |
| 2317 | 2270 | if (__libcpp_is_constant_evaluated()) |
| 2318 | 2271 | __r_.first() = __rep(); |
| 2319 | size_type __sz = static_cast<size_type>(std::distance(__first, __last)); | |
| 2272 | ||
| 2320 | 2273 | if (__sz > max_size()) |
| 2321 | 2274 | __throw_length_error(); |
| 2275 | ||
| 2322 | 2276 | pointer __p; |
| 2323 | 2277 | if (__fits_in_sso(__sz)) |
| 2324 | 2278 | { |
| 2325 | 2279 | __set_short_size(__sz); |
| 2326 | 2280 | __p = __get_short_pointer(); |
| 2281 | ||
| 2327 | 2282 | } |
| 2328 | 2283 | else |
| 2329 | 2284 | { |
| ... | ... | @@ -2335,14 +2290,14 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For |
| 2335 | 2290 | __set_long_size(__sz); |
| 2336 | 2291 | } |
| 2337 | 2292 | |
| 2338 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2293 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2339 | 2294 | try |
| 2340 | 2295 | { |
| 2341 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2296 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2342 | 2297 | for (; __first != __last; ++__first, (void) ++__p) |
| 2343 | 2298 | traits_type::assign(*__p, *__first); |
| 2344 | 2299 | traits_type::assign(*__p, value_type()); |
| 2345 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2300 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2346 | 2301 | } |
| 2347 | 2302 | catch (...) |
| 2348 | 2303 | { |
| ... | ... | @@ -2350,16 +2305,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(_ForwardIterator __first, _For |
| 2350 | 2305 | __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); |
| 2351 | 2306 | throw; |
| 2352 | 2307 | } |
| 2353 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2354 | } | |
| 2355 | ||
| 2356 | template <class _CharT, class _Traits, class _Allocator> | |
| 2357 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2358 | basic_string<_CharT, _Traits, _Allocator>::~basic_string() | |
| 2359 | { | |
| 2360 | std::__debug_db_erase_c(this); | |
| 2361 | if (__is_long()) | |
| 2362 | __alloc_traits::deallocate(__alloc(), __get_long_pointer(), __get_long_cap()); | |
| 2308 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2363 | 2309 | } |
| 2364 | 2310 | |
| 2365 | 2311 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -2379,7 +2325,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace |
| 2379 | 2325 | auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); |
| 2380 | 2326 | pointer __p = __allocation.ptr; |
| 2381 | 2327 | __begin_lifetime(__p, __allocation.count); |
| 2382 | std::__debug_db_invalidate_all(this); | |
| 2383 | 2328 | if (__n_copy != 0) |
| 2384 | 2329 | traits_type::copy(std::__to_address(__p), |
| 2385 | 2330 | std::__to_address(__old_p), __n_copy); |
| ... | ... | @@ -2398,9 +2343,16 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by_and_replace |
| 2398 | 2343 | traits_type::assign(__p[__old_sz], value_type()); |
| 2399 | 2344 | } |
| 2400 | 2345 | |
| 2346 | // __grow_by is deprecated because it does not set the size. It may not update the size when the size is changed, and it | |
| 2347 | // may also not set the size at all when the string was short initially. This leads to unpredictable size value. It is | |
| 2348 | // not removed or changed to avoid breaking the ABI. | |
| 2401 | 2349 | template <class _CharT, class _Traits, class _Allocator> |
| 2402 | 2350 | void |
| 2403 | 2351 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2352 | #if _LIBCPP_ABI_VERSION >= 2 // We want to use the function in the dylib in ABIv1 | |
| 2353 | _LIBCPP_HIDE_FROM_ABI | |
| 2354 | #endif | |
| 2355 | _LIBCPP_DEPRECATED_("use __grow_by_without_replace") | |
| 2404 | 2356 | basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_type __delta_cap, size_type __old_sz, |
| 2405 | 2357 | size_type __n_copy, size_type __n_del, size_type __n_add) |
| 2406 | 2358 | { |
| ... | ... | @@ -2414,7 +2366,6 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t |
| 2414 | 2366 | auto __allocation = std::__allocate_at_least(__alloc(), __cap + 1); |
| 2415 | 2367 | pointer __p = __allocation.ptr; |
| 2416 | 2368 | __begin_lifetime(__p, __allocation.count); |
| 2417 | std::__debug_db_invalidate_all(this); | |
| 2418 | 2369 | if (__n_copy != 0) |
| 2419 | 2370 | traits_type::copy(std::__to_address(__p), |
| 2420 | 2371 | std::__to_address(__old_p), __n_copy); |
| ... | ... | @@ -2429,6 +2380,21 @@ basic_string<_CharT, _Traits, _Allocator>::__grow_by(size_type __old_cap, size_t |
| 2429 | 2380 | __set_long_cap(__allocation.count); |
| 2430 | 2381 | } |
| 2431 | 2382 | |
| 2383 | template <class _CharT, class _Traits, class _Allocator> | |
| 2384 | void _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2385 | basic_string<_CharT, _Traits, _Allocator>::__grow_by_without_replace( | |
| 2386 | size_type __old_cap, | |
| 2387 | size_type __delta_cap, | |
| 2388 | size_type __old_sz, | |
| 2389 | size_type __n_copy, | |
| 2390 | size_type __n_del, | |
| 2391 | size_type __n_add) { | |
| 2392 | _LIBCPP_SUPPRESS_DEPRECATED_PUSH | |
| 2393 | __grow_by(__old_cap, __delta_cap, __old_sz, __n_copy, __n_del, __n_add); | |
| 2394 | _LIBCPP_SUPPRESS_DEPRECATED_POP | |
| 2395 | __set_long_size(__old_sz - __n_del + __n_add); | |
| 2396 | } | |
| 2397 | ||
| 2432 | 2398 | // assign |
| 2433 | 2399 | |
| 2434 | 2400 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -2443,7 +2409,6 @@ basic_string<_CharT, _Traits, _Allocator>::__assign_no_alias( |
| 2443 | 2409 | __is_short ? __set_short_size(__n) : __set_long_size(__n); |
| 2444 | 2410 | traits_type::copy(std::__to_address(__p), __s, __n); |
| 2445 | 2411 | traits_type::assign(__p[__n], value_type()); |
| 2446 | __invalidate_iterators_past(__n); | |
| 2447 | 2412 | } else { |
| 2448 | 2413 | size_type __sz = __is_short ? __get_short_size() : __get_long_size(); |
| 2449 | 2414 | __grow_by_and_replace(__cap - 1, __n - __cap + 1, __sz, 0, __sz, __n, __s); |
| ... | ... | @@ -2473,7 +2438,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2473 | 2438 | basic_string<_CharT, _Traits, _Allocator>& |
| 2474 | 2439 | basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s, size_type __n) |
| 2475 | 2440 | { |
| 2476 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::assign received nullptr"); | |
| 2441 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::assign received nullptr"); | |
| 2477 | 2442 | return (__builtin_constant_p(__n) && __fits_in_sso(__n)) |
| 2478 | 2443 | ? __assign_short(__s, __n) |
| 2479 | 2444 | : __assign_external(__s, __n); |
| ... | ... | @@ -2488,7 +2453,7 @@ basic_string<_CharT, _Traits, _Allocator>::assign(size_type __n, value_type __c) |
| 2488 | 2453 | if (__cap < __n) |
| 2489 | 2454 | { |
| 2490 | 2455 | size_type __sz = size(); |
| 2491 | __grow_by(__cap, __n - __cap, __sz, 0, __sz); | |
| 2456 | __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); | |
| 2492 | 2457 | } |
| 2493 | 2458 | value_type* __p = std::__to_address(__get_pointer()); |
| 2494 | 2459 | traits_type::assign(__p, __n, __c); |
| ... | ... | @@ -2513,7 +2478,6 @@ basic_string<_CharT, _Traits, _Allocator>::operator=(value_type __c) |
| 2513 | 2478 | } |
| 2514 | 2479 | traits_type::assign(*__p, __c); |
| 2515 | 2480 | traits_type::assign(*++__p, value_type()); |
| 2516 | __invalidate_iterators_past(1); | |
| 2517 | 2481 | return *this; |
| 2518 | 2482 | } |
| 2519 | 2483 | |
| ... | ... | @@ -2522,7 +2486,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2522 | 2486 | basic_string<_CharT, _Traits, _Allocator>& |
| 2523 | 2487 | basic_string<_CharT, _Traits, _Allocator>::operator=(const basic_string& __str) |
| 2524 | 2488 | { |
| 2525 | if (this != &__str) { | |
| 2489 | if (this != std::addressof(__str)) { | |
| 2526 | 2490 | __copy_assign_alloc(__str); |
| 2527 | 2491 | if (!__is_long()) { |
| 2528 | 2492 | if (!__str.__is_long()) { |
| ... | ... | @@ -2555,7 +2519,7 @@ template <class _CharT, class _Traits, class _Allocator> |
| 2555 | 2519 | inline _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2556 | 2520 | void |
| 2557 | 2521 | basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, true_type) |
| 2558 | #if _LIBCPP_STD_VER > 14 | |
| 2522 | #if _LIBCPP_STD_VER >= 17 | |
| 2559 | 2523 | _NOEXCEPT |
| 2560 | 2524 | #else |
| 2561 | 2525 | _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) |
| ... | ... | @@ -2584,55 +2548,62 @@ basic_string<_CharT, _Traits, _Allocator>::__move_assign(basic_string& __str, tr |
| 2584 | 2548 | #endif |
| 2585 | 2549 | |
| 2586 | 2550 | template <class _CharT, class _Traits, class _Allocator> |
| 2587 | template<class _InputIterator> | |
| 2588 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2589 | __enable_if_t | |
| 2590 | < | |
| 2591 | __is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 2592 | basic_string<_CharT, _Traits, _Allocator>& | |
| 2593 | > | |
| 2551 | template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > | |
| 2552 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2594 | 2553 | basic_string<_CharT, _Traits, _Allocator>::assign(_InputIterator __first, _InputIterator __last) |
| 2595 | 2554 | { |
| 2596 | const basic_string __temp(__first, __last, __alloc()); | |
| 2597 | assign(__temp.data(), __temp.size()); | |
| 2598 | return *this; | |
| 2555 | __assign_with_sentinel(__first, __last); | |
| 2556 | return *this; | |
| 2599 | 2557 | } |
| 2600 | 2558 | |
| 2601 | 2559 | template <class _CharT, class _Traits, class _Allocator> |
| 2602 | template<class _ForwardIterator> | |
| 2603 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2604 | __enable_if_t | |
| 2605 | < | |
| 2606 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2607 | basic_string<_CharT, _Traits, _Allocator>& | |
| 2608 | > | |
| 2560 | template <class _InputIterator, class _Sentinel> | |
| 2561 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2562 | void | |
| 2563 | basic_string<_CharT, _Traits, _Allocator>::__assign_with_sentinel(_InputIterator __first, _Sentinel __last) { | |
| 2564 | const basic_string __temp(__init_with_sentinel_tag(), std::move(__first), std::move(__last), __alloc()); | |
| 2565 | assign(__temp.data(), __temp.size()); | |
| 2566 | } | |
| 2567 | ||
| 2568 | template <class _CharT, class _Traits, class _Allocator> | |
| 2569 | template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > | |
| 2570 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2609 | 2571 | basic_string<_CharT, _Traits, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) |
| 2610 | 2572 | { |
| 2611 | size_type __cap = capacity(); | |
| 2612 | size_type __n = __string_is_trivial_iterator<_ForwardIterator>::value ? | |
| 2613 | static_cast<size_type>(std::distance(__first, __last)) : 0; | |
| 2573 | if (__string_is_trivial_iterator<_ForwardIterator>::value) { | |
| 2574 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2575 | __assign_trivial(__first, __last, __n); | |
| 2576 | } else { | |
| 2577 | __assign_with_sentinel(__first, __last); | |
| 2578 | } | |
| 2614 | 2579 | |
| 2615 | if (__string_is_trivial_iterator<_ForwardIterator>::value && | |
| 2616 | (__cap >= __n || !__addr_in_range(*__first))) | |
| 2617 | { | |
| 2618 | if (__cap < __n) | |
| 2619 | { | |
| 2620 | size_type __sz = size(); | |
| 2621 | __grow_by(__cap, __n - __cap, __sz, 0, __sz); | |
| 2622 | } | |
| 2623 | pointer __p = __get_pointer(); | |
| 2624 | for (; __first != __last; ++__p, (void) ++__first) | |
| 2625 | traits_type::assign(*__p, *__first); | |
| 2626 | traits_type::assign(*__p, value_type()); | |
| 2627 | __set_size(__n); | |
| 2628 | __invalidate_iterators_past(__n); | |
| 2629 | } | |
| 2630 | else | |
| 2631 | { | |
| 2632 | const basic_string __temp(__first, __last, __alloc()); | |
| 2633 | assign(__temp.data(), __temp.size()); | |
| 2580 | return *this; | |
| 2581 | } | |
| 2582 | ||
| 2583 | template <class _CharT, class _Traits, class _Allocator> | |
| 2584 | template <class _Iterator, class _Sentinel> | |
| 2585 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2586 | void | |
| 2587 | basic_string<_CharT, _Traits, _Allocator>::__assign_trivial(_Iterator __first, _Sentinel __last, size_type __n) { | |
| 2588 | _LIBCPP_ASSERT_INTERNAL( | |
| 2589 | __string_is_trivial_iterator<_Iterator>::value, "The iterator type given to `__assign_trivial` must be trivial"); | |
| 2590 | ||
| 2591 | size_type __cap = capacity(); | |
| 2592 | if (__cap < __n) { | |
| 2593 | // Unlike `append` functions, if the input range points into the string itself, there is no case that the input | |
| 2594 | // range could get invalidated by reallocation: | |
| 2595 | // 1. If the input range is a subset of the string itself, its size cannot exceed the capacity of the string, | |
| 2596 | // thus no reallocation would happen. | |
| 2597 | // 2. In the exotic case where the input range is the byte representation of the string itself, the string | |
| 2598 | // object itself stays valid even if reallocation happens. | |
| 2599 | size_type __sz = size(); | |
| 2600 | __grow_by_without_replace(__cap, __n - __cap, __sz, 0, __sz); | |
| 2634 | 2601 | } |
| 2635 | return *this; | |
| 2602 | pointer __p = __get_pointer(); | |
| 2603 | for (; __first != __last; ++__p, (void) ++__first) | |
| 2604 | traits_type::assign(*__p, *__first); | |
| 2605 | traits_type::assign(*__p, value_type()); | |
| 2606 | __set_size(__n); | |
| 2636 | 2607 | } |
| 2637 | 2608 | |
| 2638 | 2609 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -2647,16 +2618,12 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const basic_string& __str, siz |
| 2647 | 2618 | } |
| 2648 | 2619 | |
| 2649 | 2620 | template <class _CharT, class _Traits, class _Allocator> |
| 2650 | template <class _Tp> | |
| 2651 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2652 | __enable_if_t | |
| 2653 | < | |
| 2654 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 2655 | && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2656 | basic_string<_CharT, _Traits, _Allocator>& | |
| 2657 | > | |
| 2658 | basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __pos, size_type __n) | |
| 2659 | { | |
| 2621 | template <class _Tp, | |
| 2622 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 2623 | !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2624 | int> > | |
| 2625 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2626 | basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp& __t, size_type __pos, size_type __n) { | |
| 2660 | 2627 | __self_view __sv = __t; |
| 2661 | 2628 | size_type __sz = __sv.size(); |
| 2662 | 2629 | if (__pos > __sz) |
| ... | ... | @@ -2664,7 +2631,6 @@ basic_string<_CharT, _Traits, _Allocator>::assign(const _Tp & __t, size_type __p |
| 2664 | 2631 | return assign(__sv.data() + __pos, std::min(__n, __sz - __pos)); |
| 2665 | 2632 | } |
| 2666 | 2633 | |
| 2667 | ||
| 2668 | 2634 | template <class _CharT, class _Traits, class _Allocator> |
| 2669 | 2635 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2670 | 2636 | basic_string<_CharT, _Traits, _Allocator>& |
| ... | ... | @@ -2677,7 +2643,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2677 | 2643 | basic_string<_CharT, _Traits, _Allocator>& |
| 2678 | 2644 | basic_string<_CharT, _Traits, _Allocator>::assign(const value_type* __s) |
| 2679 | 2645 | { |
| 2680 | _LIBCPP_ASSERT(__s != nullptr, "string::assign received nullptr"); | |
| 2646 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::assign received nullptr"); | |
| 2681 | 2647 | return __builtin_constant_p(*__s) |
| 2682 | 2648 | ? (__fits_in_sso(traits_type::length(__s)) |
| 2683 | 2649 | ? __assign_short(__s, traits_type::length(__s)) |
| ... | ... | @@ -2691,7 +2657,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2691 | 2657 | basic_string<_CharT, _Traits, _Allocator>& |
| 2692 | 2658 | basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s, size_type __n) |
| 2693 | 2659 | { |
| 2694 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::append received nullptr"); | |
| 2660 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::append received nullptr"); | |
| 2695 | 2661 | size_type __cap = capacity(); |
| 2696 | 2662 | size_type __sz = size(); |
| 2697 | 2663 | if (__cap - __sz >= __n) |
| ... | ... | @@ -2720,7 +2686,7 @@ basic_string<_CharT, _Traits, _Allocator>::append(size_type __n, value_type __c) |
| 2720 | 2686 | size_type __cap = capacity(); |
| 2721 | 2687 | size_type __sz = size(); |
| 2722 | 2688 | if (__cap - __sz < __n) |
| 2723 | __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2689 | __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2724 | 2690 | pointer __p = __get_pointer(); |
| 2725 | 2691 | traits_type::assign(std::__to_address(__p) + __sz, __n, __c); |
| 2726 | 2692 | __sz += __n; |
| ... | ... | @@ -2739,7 +2705,7 @@ basic_string<_CharT, _Traits, _Allocator>::__append_default_init(size_type __n) |
| 2739 | 2705 | size_type __cap = capacity(); |
| 2740 | 2706 | size_type __sz = size(); |
| 2741 | 2707 | if (__cap - __sz < __n) |
| 2742 | __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2708 | __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2743 | 2709 | pointer __p = __get_pointer(); |
| 2744 | 2710 | __sz += __n; |
| 2745 | 2711 | __set_size(__sz); |
| ... | ... | @@ -2767,7 +2733,7 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) |
| 2767 | 2733 | } |
| 2768 | 2734 | if (__sz == __cap) |
| 2769 | 2735 | { |
| 2770 | __grow_by(__cap, 1, __sz, __sz, 0); | |
| 2736 | __grow_by_without_replace(__cap, 1, __sz, __sz, 0); | |
| 2771 | 2737 | __is_short = false; // the string is always long after __grow_by |
| 2772 | 2738 | } |
| 2773 | 2739 | pointer __p = __get_pointer(); |
| ... | ... | @@ -2786,13 +2752,8 @@ basic_string<_CharT, _Traits, _Allocator>::push_back(value_type __c) |
| 2786 | 2752 | } |
| 2787 | 2753 | |
| 2788 | 2754 | template <class _CharT, class _Traits, class _Allocator> |
| 2789 | template<class _ForwardIterator> | |
| 2790 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2791 | __enable_if_t | |
| 2792 | < | |
| 2793 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2794 | basic_string<_CharT, _Traits, _Allocator>& | |
| 2795 | > | |
| 2755 | template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > | |
| 2756 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2796 | 2757 | basic_string<_CharT, _Traits, _Allocator>::append( |
| 2797 | 2758 | _ForwardIterator __first, _ForwardIterator __last) |
| 2798 | 2759 | { |
| ... | ... | @@ -2805,7 +2766,7 @@ basic_string<_CharT, _Traits, _Allocator>::append( |
| 2805 | 2766 | !__addr_in_range(*__first)) |
| 2806 | 2767 | { |
| 2807 | 2768 | if (__cap - __sz < __n) |
| 2808 | __grow_by(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2769 | __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __sz, 0); | |
| 2809 | 2770 | pointer __p = __get_pointer() + __sz; |
| 2810 | 2771 | for (; __first != __last; ++__p, (void) ++__first) |
| 2811 | 2772 | traits_type::assign(*__p, *__first); |
| ... | ... | @@ -2833,15 +2794,12 @@ basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str, siz |
| 2833 | 2794 | } |
| 2834 | 2795 | |
| 2835 | 2796 | template <class _CharT, class _Traits, class _Allocator> |
| 2836 | template <class _Tp> | |
| 2837 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2838 | __enable_if_t | |
| 2839 | < | |
| 2840 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2841 | basic_string<_CharT, _Traits, _Allocator>& | |
| 2842 | > | |
| 2843 | basic_string<_CharT, _Traits, _Allocator>::append(const _Tp & __t, size_type __pos, size_type __n) | |
| 2844 | { | |
| 2797 | template <class _Tp, | |
| 2798 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 2799 | !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2800 | int> > | |
| 2801 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2802 | basic_string<_CharT, _Traits, _Allocator>::append(const _Tp& __t, size_type __pos, size_type __n) { | |
| 2845 | 2803 | __self_view __sv = __t; |
| 2846 | 2804 | size_type __sz = __sv.size(); |
| 2847 | 2805 | if (__pos > __sz) |
| ... | ... | @@ -2854,7 +2812,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2854 | 2812 | basic_string<_CharT, _Traits, _Allocator>& |
| 2855 | 2813 | basic_string<_CharT, _Traits, _Allocator>::append(const value_type* __s) |
| 2856 | 2814 | { |
| 2857 | _LIBCPP_ASSERT(__s != nullptr, "string::append received nullptr"); | |
| 2815 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::append received nullptr"); | |
| 2858 | 2816 | return append(__s, traits_type::length(__s)); |
| 2859 | 2817 | } |
| 2860 | 2818 | |
| ... | ... | @@ -2865,7 +2823,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2865 | 2823 | basic_string<_CharT, _Traits, _Allocator>& |
| 2866 | 2824 | basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s, size_type __n) |
| 2867 | 2825 | { |
| 2868 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::insert received nullptr"); | |
| 2826 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::insert received nullptr"); | |
| 2869 | 2827 | size_type __sz = size(); |
| 2870 | 2828 | if (__pos > __sz) |
| 2871 | 2829 | __throw_out_of_range(); |
| ... | ... | @@ -2921,7 +2879,7 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n |
| 2921 | 2879 | } |
| 2922 | 2880 | else |
| 2923 | 2881 | { |
| 2924 | __grow_by(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); | |
| 2882 | __grow_by_without_replace(__cap, __sz + __n - __cap, __sz, __pos, 0, __n); | |
| 2925 | 2883 | __p = std::__to_address(__get_long_pointer()); |
| 2926 | 2884 | } |
| 2927 | 2885 | traits_type::assign(__p + __pos, __n, __c); |
| ... | ... | @@ -2933,47 +2891,40 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, size_type __n |
| 2933 | 2891 | } |
| 2934 | 2892 | |
| 2935 | 2893 | template <class _CharT, class _Traits, class _Allocator> |
| 2936 | template<class _InputIterator> | |
| 2937 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2938 | __enable_if_t | |
| 2939 | < | |
| 2940 | __is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 2941 | typename basic_string<_CharT, _Traits, _Allocator>::iterator | |
| 2942 | > | |
| 2894 | template<class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value, int> > | |
| 2895 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator | |
| 2943 | 2896 | basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _InputIterator __first, _InputIterator __last) |
| 2944 | 2897 | { |
| 2945 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, | |
| 2946 | "string::insert(iterator, range) called with an iterator not" | |
| 2947 | " referring to this string"); | |
| 2948 | 2898 | const basic_string __temp(__first, __last, __alloc()); |
| 2949 | 2899 | return insert(__pos, __temp.data(), __temp.data() + __temp.size()); |
| 2950 | 2900 | } |
| 2951 | 2901 | |
| 2952 | 2902 | template <class _CharT, class _Traits, class _Allocator> |
| 2953 | template<class _ForwardIterator> | |
| 2954 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2955 | __enable_if_t | |
| 2956 | < | |
| 2957 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2958 | typename basic_string<_CharT, _Traits, _Allocator>::iterator | |
| 2959 | > | |
| 2903 | template<class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> > | |
| 2904 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::iterator | |
| 2960 | 2905 | basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, _ForwardIterator __first, _ForwardIterator __last) |
| 2961 | 2906 | { |
| 2962 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, | |
| 2963 | "string::insert(iterator, range) called with an iterator not referring to this string"); | |
| 2907 | auto __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2908 | return __insert_with_size(__pos, __first, __last, __n); | |
| 2909 | } | |
| 2964 | 2910 | |
| 2911 | template <class _CharT, class _Traits, class _Allocator> | |
| 2912 | template<class _Iterator, class _Sentinel> | |
| 2913 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2914 | typename basic_string<_CharT, _Traits, _Allocator>::iterator | |
| 2915 | basic_string<_CharT, _Traits, _Allocator>::__insert_with_size( | |
| 2916 | const_iterator __pos, _Iterator __first, _Sentinel __last, size_type __n) { | |
| 2965 | 2917 | size_type __ip = static_cast<size_type>(__pos - begin()); |
| 2966 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2967 | 2918 | if (__n == 0) |
| 2968 | 2919 | return begin() + __ip; |
| 2969 | 2920 | |
| 2970 | if (__string_is_trivial_iterator<_ForwardIterator>::value && !__addr_in_range(*__first)) | |
| 2921 | if (__string_is_trivial_iterator<_Iterator>::value && !__addr_in_range(*__first)) | |
| 2971 | 2922 | { |
| 2972 | 2923 | return __insert_from_safe_copy(__n, __ip, __first, __last); |
| 2973 | 2924 | } |
| 2974 | 2925 | else |
| 2975 | 2926 | { |
| 2976 | const basic_string __temp(__first, __last, __alloc()); | |
| 2927 | const basic_string __temp(__init_with_sentinel_tag(), __first, __last, __alloc()); | |
| 2977 | 2928 | return __insert_from_safe_copy(__n, __ip, __temp.begin(), __temp.end()); |
| 2978 | 2929 | } |
| 2979 | 2930 | } |
| ... | ... | @@ -2991,16 +2942,12 @@ basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const basic_ |
| 2991 | 2942 | } |
| 2992 | 2943 | |
| 2993 | 2944 | template <class _CharT, class _Traits, class _Allocator> |
| 2994 | template <class _Tp> | |
| 2995 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2996 | __enable_if_t | |
| 2997 | < | |
| 2998 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2999 | basic_string<_CharT, _Traits, _Allocator>& | |
| 3000 | > | |
| 3001 | basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, | |
| 3002 | size_type __pos2, size_type __n) | |
| 3003 | { | |
| 2945 | template <class _Tp, | |
| 2946 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 2947 | !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 2948 | int> > | |
| 2949 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 2950 | basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos1, const _Tp& __t, size_type __pos2, size_type __n) { | |
| 3004 | 2951 | __self_view __sv = __t; |
| 3005 | 2952 | size_type __str_sz = __sv.size(); |
| 3006 | 2953 | if (__pos2 > __str_sz) |
| ... | ... | @@ -3013,7 +2960,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3013 | 2960 | basic_string<_CharT, _Traits, _Allocator>& |
| 3014 | 2961 | basic_string<_CharT, _Traits, _Allocator>::insert(size_type __pos, const value_type* __s) |
| 3015 | 2962 | { |
| 3016 | _LIBCPP_ASSERT(__s != nullptr, "string::insert received nullptr"); | |
| 2963 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::insert received nullptr"); | |
| 3017 | 2964 | return insert(__pos, __s, traits_type::length(__s)); |
| 3018 | 2965 | } |
| 3019 | 2966 | |
| ... | ... | @@ -3022,17 +2969,13 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3022 | 2969 | typename basic_string<_CharT, _Traits, _Allocator>::iterator |
| 3023 | 2970 | basic_string<_CharT, _Traits, _Allocator>::insert(const_iterator __pos, value_type __c) |
| 3024 | 2971 | { |
| 3025 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, | |
| 3026 | "string::insert(iterator, character) called with an iterator not" | |
| 3027 | " referring to this string"); | |
| 3028 | ||
| 3029 | 2972 | size_type __ip = static_cast<size_type>(__pos - begin()); |
| 3030 | 2973 | size_type __sz = size(); |
| 3031 | 2974 | size_type __cap = capacity(); |
| 3032 | 2975 | value_type* __p; |
| 3033 | 2976 | if (__cap == __sz) |
| 3034 | 2977 | { |
| 3035 | __grow_by(__cap, 1, __sz, __ip, 0, 1); | |
| 2978 | __grow_by_without_replace(__cap, 1, __sz, __ip, 0, 1); | |
| 3036 | 2979 | __p = std::__to_address(__get_long_pointer()); |
| 3037 | 2980 | } |
| 3038 | 2981 | else |
| ... | ... | @@ -3056,7 +2999,7 @@ basic_string<_CharT, _Traits, _Allocator>& |
| 3056 | 2999 | basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s, size_type __n2) |
| 3057 | 3000 | _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK |
| 3058 | 3001 | { |
| 3059 | _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); | |
| 3002 | _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::replace received nullptr"); | |
| 3060 | 3003 | size_type __sz = size(); |
| 3061 | 3004 | if (__pos > __sz) |
| 3062 | 3005 | __throw_out_of_range(); |
| ... | ... | @@ -3064,10 +3007,6 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ |
| 3064 | 3007 | size_type __cap = capacity(); |
| 3065 | 3008 | if (__cap - __sz + __n1 >= __n2) |
| 3066 | 3009 | { |
| 3067 | if (__libcpp_is_constant_evaluated()) { | |
| 3068 | __grow_by_and_replace(__cap, 0, __sz, __pos, __n1, __n2, __s); | |
| 3069 | return *this; | |
| 3070 | } | |
| 3071 | 3010 | value_type* __p = std::__to_address(__get_pointer()); |
| 3072 | 3011 | if (__n1 != __n2) |
| 3073 | 3012 | { |
| ... | ... | @@ -3080,7 +3019,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ |
| 3080 | 3019 | traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move); |
| 3081 | 3020 | return __null_terminate_at(__p, __sz + (__n2 - __n1)); |
| 3082 | 3021 | } |
| 3083 | if (__p + __pos < __s && __s < __p + __sz) | |
| 3022 | if (std::__is_pointer_in_range(__p + __pos + 1, __p + __sz, __s)) | |
| 3084 | 3023 | { |
| 3085 | 3024 | if (__p + __pos + __n1 <= __s) |
| 3086 | 3025 | __s += __n2 - __n1; |
| ... | ... | @@ -3127,7 +3066,7 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ |
| 3127 | 3066 | } |
| 3128 | 3067 | else |
| 3129 | 3068 | { |
| 3130 | __grow_by(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); | |
| 3069 | __grow_by_without_replace(__cap, __sz - __n1 + __n2 - __cap, __sz, __pos, __n1, __n2); | |
| 3131 | 3070 | __p = std::__to_address(__get_long_pointer()); |
| 3132 | 3071 | } |
| 3133 | 3072 | traits_type::assign(__p + __pos, __n2, __c); |
| ... | ... | @@ -3135,13 +3074,8 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __ |
| 3135 | 3074 | } |
| 3136 | 3075 | |
| 3137 | 3076 | template <class _CharT, class _Traits, class _Allocator> |
| 3138 | template<class _InputIterator> | |
| 3139 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3140 | __enable_if_t | |
| 3141 | < | |
| 3142 | __is_cpp17_input_iterator<_InputIterator>::value, | |
| 3143 | basic_string<_CharT, _Traits, _Allocator>& | |
| 3144 | > | |
| 3077 | template<class _InputIterator, __enable_if_t<__has_input_iterator_category<_InputIterator>::value, int> > | |
| 3078 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 3145 | 3079 | basic_string<_CharT, _Traits, _Allocator>::replace(const_iterator __i1, const_iterator __i2, |
| 3146 | 3080 | _InputIterator __j1, _InputIterator __j2) |
| 3147 | 3081 | { |
| ... | ... | @@ -3162,16 +3096,13 @@ basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type _ |
| 3162 | 3096 | } |
| 3163 | 3097 | |
| 3164 | 3098 | template <class _CharT, class _Traits, class _Allocator> |
| 3165 | template <class _Tp> | |
| 3166 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3167 | __enable_if_t | |
| 3168 | < | |
| 3169 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 3170 | basic_string<_CharT, _Traits, _Allocator>& | |
| 3171 | > | |
| 3172 | basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos1, size_type __n1, const _Tp& __t, | |
| 3173 | size_type __pos2, size_type __n2) | |
| 3174 | { | |
| 3099 | template <class _Tp, | |
| 3100 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 3101 | !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 3102 | int> > | |
| 3103 | _LIBCPP_CONSTEXPR_SINCE_CXX20 basic_string<_CharT, _Traits, _Allocator>& | |
| 3104 | basic_string<_CharT, _Traits, _Allocator>::replace( | |
| 3105 | size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) { | |
| 3175 | 3106 | __self_view __sv = __t; |
| 3176 | 3107 | size_type __str_sz = __sv.size(); |
| 3177 | 3108 | if (__pos2 > __str_sz) |
| ... | ... | @@ -3184,7 +3115,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3184 | 3115 | basic_string<_CharT, _Traits, _Allocator>& |
| 3185 | 3116 | basic_string<_CharT, _Traits, _Allocator>::replace(size_type __pos, size_type __n1, const value_type* __s) |
| 3186 | 3117 | { |
| 3187 | _LIBCPP_ASSERT(__s != nullptr, "string::replace received nullptr"); | |
| 3118 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::replace received nullptr"); | |
| 3188 | 3119 | return replace(__pos, __n1, __s, traits_type::length(__s)); |
| 3189 | 3120 | } |
| 3190 | 3121 | |
| ... | ... | @@ -3230,11 +3161,8 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3230 | 3161 | typename basic_string<_CharT, _Traits, _Allocator>::iterator |
| 3231 | 3162 | basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __pos) |
| 3232 | 3163 | { |
| 3233 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__pos) == this, | |
| 3234 | "string::erase(iterator) called with an iterator not" | |
| 3235 | " referring to this string"); | |
| 3236 | ||
| 3237 | _LIBCPP_ASSERT(__pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); | |
| 3164 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( | |
| 3165 | __pos != end(), "string::erase(iterator) called with a non-dereferenceable iterator"); | |
| 3238 | 3166 | iterator __b = begin(); |
| 3239 | 3167 | size_type __r = static_cast<size_type>(__pos - __b); |
| 3240 | 3168 | erase(__r, 1); |
| ... | ... | @@ -3246,11 +3174,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3246 | 3174 | typename basic_string<_CharT, _Traits, _Allocator>::iterator |
| 3247 | 3175 | basic_string<_CharT, _Traits, _Allocator>::erase(const_iterator __first, const_iterator __last) |
| 3248 | 3176 | { |
| 3249 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, | |
| 3250 | "string::erase(iterator, iterator) called with an iterator not" | |
| 3251 | " referring to this string"); | |
| 3252 | ||
| 3253 | _LIBCPP_ASSERT(__first <= __last, "string::erase(first, last) called with invalid range"); | |
| 3177 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "string::erase(first, last) called with invalid range"); | |
| 3254 | 3178 | iterator __b = begin(); |
| 3255 | 3179 | size_type __r = static_cast<size_type>(__first - __b); |
| 3256 | 3180 | erase(__r, static_cast<size_type>(__last - __first)); |
| ... | ... | @@ -3262,7 +3186,7 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3262 | 3186 | void |
| 3263 | 3187 | basic_string<_CharT, _Traits, _Allocator>::pop_back() |
| 3264 | 3188 | { |
| 3265 | _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty"); | |
| 3189 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string::pop_back(): string is already empty"); | |
| 3266 | 3190 | __erase_to_end(size() - 1); |
| 3267 | 3191 | } |
| 3268 | 3192 | |
| ... | ... | @@ -3271,7 +3195,6 @@ inline _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3271 | 3195 | void |
| 3272 | 3196 | basic_string<_CharT, _Traits, _Allocator>::clear() _NOEXCEPT |
| 3273 | 3197 | { |
| 3274 | std::__debug_db_invalidate_all(this); | |
| 3275 | 3198 | if (__is_long()) |
| 3276 | 3199 | { |
| 3277 | 3200 | traits_type::assign(*__get_long_pointer(), value_type()); |
| ... | ... | @@ -3365,23 +3288,23 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target |
| 3365 | 3288 | } |
| 3366 | 3289 | else |
| 3367 | 3290 | { |
| 3368 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3291 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3369 | 3292 | try |
| 3370 | 3293 | { |
| 3371 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3294 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3372 | 3295 | auto __allocation = std::__allocate_at_least(__alloc(), __target_capacity + 1); |
| 3373 | 3296 | __new_data = __allocation.ptr; |
| 3374 | 3297 | __target_capacity = __allocation.count - 1; |
| 3375 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3298 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3376 | 3299 | } |
| 3377 | 3300 | catch (...) |
| 3378 | 3301 | { |
| 3379 | 3302 | return; |
| 3380 | 3303 | } |
| 3381 | #else // _LIBCPP_NO_EXCEPTIONS | |
| 3304 | #else // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3382 | 3305 | if (__new_data == nullptr) |
| 3383 | 3306 | return; |
| 3384 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3307 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3385 | 3308 | } |
| 3386 | 3309 | __begin_lifetime(__new_data, __target_capacity + 1); |
| 3387 | 3310 | __now_long = true; |
| ... | ... | @@ -3400,7 +3323,6 @@ basic_string<_CharT, _Traits, _Allocator>::__shrink_or_extend(size_type __target |
| 3400 | 3323 | } |
| 3401 | 3324 | else |
| 3402 | 3325 | __set_short_size(__sz); |
| 3403 | std::__debug_db_invalidate_all(this); | |
| 3404 | 3326 | } |
| 3405 | 3327 | |
| 3406 | 3328 | template <class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -3447,13 +3369,7 @@ basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str) |
| 3447 | 3369 | __is_nothrow_swappable<allocator_type>::value) |
| 3448 | 3370 | #endif |
| 3449 | 3371 | { |
| 3450 | if (!__is_long()) | |
| 3451 | std::__debug_db_invalidate_all(this); | |
| 3452 | if (!__str.__is_long()) | |
| 3453 | std::__debug_db_invalidate_all(&__str); | |
| 3454 | std::__debug_db_swap(this, &__str); | |
| 3455 | ||
| 3456 | _LIBCPP_ASSERT( | |
| 3372 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( | |
| 3457 | 3373 | __alloc_traits::propagate_on_container_swap::value || |
| 3458 | 3374 | __alloc_traits::is_always_equal::value || |
| 3459 | 3375 | __alloc() == __str.__alloc(), "swapping non-equal allocators"); |
| ... | ... | @@ -3479,7 +3395,7 @@ basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, |
| 3479 | 3395 | size_type __pos, |
| 3480 | 3396 | size_type __n) const _NOEXCEPT |
| 3481 | 3397 | { |
| 3482 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find(): received nullptr"); | |
| 3398 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find(): received nullptr"); | |
| 3483 | 3399 | return std::__str_find<value_type, size_type, traits_type, npos> |
| 3484 | 3400 | (data(), size(), __s, __pos, __n); |
| 3485 | 3401 | } |
| ... | ... | @@ -3495,13 +3411,8 @@ basic_string<_CharT, _Traits, _Allocator>::find(const basic_string& __str, |
| 3495 | 3411 | } |
| 3496 | 3412 | |
| 3497 | 3413 | template<class _CharT, class _Traits, class _Allocator> |
| 3498 | template <class _Tp> | |
| 3499 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3500 | __enable_if_t | |
| 3501 | < | |
| 3502 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3503 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3504 | > | |
| 3414 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3415 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3505 | 3416 | basic_string<_CharT, _Traits, _Allocator>::find(const _Tp &__t, |
| 3506 | 3417 | size_type __pos) const _NOEXCEPT |
| 3507 | 3418 | { |
| ... | ... | @@ -3516,7 +3427,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3516 | 3427 | basic_string<_CharT, _Traits, _Allocator>::find(const value_type* __s, |
| 3517 | 3428 | size_type __pos) const _NOEXCEPT |
| 3518 | 3429 | { |
| 3519 | _LIBCPP_ASSERT(__s != nullptr, "string::find(): received nullptr"); | |
| 3430 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find(): received nullptr"); | |
| 3520 | 3431 | return std::__str_find<value_type, size_type, traits_type, npos> |
| 3521 | 3432 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3522 | 3433 | } |
| ... | ... | @@ -3540,7 +3451,7 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, |
| 3540 | 3451 | size_type __pos, |
| 3541 | 3452 | size_type __n) const _NOEXCEPT |
| 3542 | 3453 | { |
| 3543 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); | |
| 3454 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::rfind(): received nullptr"); | |
| 3544 | 3455 | return std::__str_rfind<value_type, size_type, traits_type, npos> |
| 3545 | 3456 | (data(), size(), __s, __pos, __n); |
| 3546 | 3457 | } |
| ... | ... | @@ -3556,13 +3467,8 @@ basic_string<_CharT, _Traits, _Allocator>::rfind(const basic_string& __str, |
| 3556 | 3467 | } |
| 3557 | 3468 | |
| 3558 | 3469 | template<class _CharT, class _Traits, class _Allocator> |
| 3559 | template <class _Tp> | |
| 3560 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3561 | __enable_if_t | |
| 3562 | < | |
| 3563 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3564 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3565 | > | |
| 3470 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3471 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3566 | 3472 | basic_string<_CharT, _Traits, _Allocator>::rfind(const _Tp& __t, |
| 3567 | 3473 | size_type __pos) const _NOEXCEPT |
| 3568 | 3474 | { |
| ... | ... | @@ -3577,7 +3483,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3577 | 3483 | basic_string<_CharT, _Traits, _Allocator>::rfind(const value_type* __s, |
| 3578 | 3484 | size_type __pos) const _NOEXCEPT |
| 3579 | 3485 | { |
| 3580 | _LIBCPP_ASSERT(__s != nullptr, "string::rfind(): received nullptr"); | |
| 3486 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::rfind(): received nullptr"); | |
| 3581 | 3487 | return std::__str_rfind<value_type, size_type, traits_type, npos> |
| 3582 | 3488 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3583 | 3489 | } |
| ... | ... | @@ -3601,7 +3507,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, |
| 3601 | 3507 | size_type __pos, |
| 3602 | 3508 | size_type __n) const _NOEXCEPT |
| 3603 | 3509 | { |
| 3604 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); | |
| 3510 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_of(): received nullptr"); | |
| 3605 | 3511 | return std::__str_find_first_of<value_type, size_type, traits_type, npos> |
| 3606 | 3512 | (data(), size(), __s, __pos, __n); |
| 3607 | 3513 | } |
| ... | ... | @@ -3617,13 +3523,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_of(const basic_string& __s |
| 3617 | 3523 | } |
| 3618 | 3524 | |
| 3619 | 3525 | template<class _CharT, class _Traits, class _Allocator> |
| 3620 | template <class _Tp> | |
| 3621 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3622 | __enable_if_t | |
| 3623 | < | |
| 3624 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3625 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3626 | > | |
| 3526 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3527 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3627 | 3528 | basic_string<_CharT, _Traits, _Allocator>::find_first_of(const _Tp& __t, |
| 3628 | 3529 | size_type __pos) const _NOEXCEPT |
| 3629 | 3530 | { |
| ... | ... | @@ -3638,7 +3539,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3638 | 3539 | basic_string<_CharT, _Traits, _Allocator>::find_first_of(const value_type* __s, |
| 3639 | 3540 | size_type __pos) const _NOEXCEPT |
| 3640 | 3541 | { |
| 3641 | _LIBCPP_ASSERT(__s != nullptr, "string::find_first_of(): received nullptr"); | |
| 3542 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_of(): received nullptr"); | |
| 3642 | 3543 | return std::__str_find_first_of<value_type, size_type, traits_type, npos> |
| 3643 | 3544 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3644 | 3545 | } |
| ... | ... | @@ -3661,7 +3562,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, |
| 3661 | 3562 | size_type __pos, |
| 3662 | 3563 | size_type __n) const _NOEXCEPT |
| 3663 | 3564 | { |
| 3664 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); | |
| 3565 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_of(): received nullptr"); | |
| 3665 | 3566 | return std::__str_find_last_of<value_type, size_type, traits_type, npos> |
| 3666 | 3567 | (data(), size(), __s, __pos, __n); |
| 3667 | 3568 | } |
| ... | ... | @@ -3677,13 +3578,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_of(const basic_string& __st |
| 3677 | 3578 | } |
| 3678 | 3579 | |
| 3679 | 3580 | template<class _CharT, class _Traits, class _Allocator> |
| 3680 | template <class _Tp> | |
| 3681 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3682 | __enable_if_t | |
| 3683 | < | |
| 3684 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3685 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3686 | > | |
| 3581 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3582 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3687 | 3583 | basic_string<_CharT, _Traits, _Allocator>::find_last_of(const _Tp& __t, |
| 3688 | 3584 | size_type __pos) const _NOEXCEPT |
| 3689 | 3585 | { |
| ... | ... | @@ -3698,7 +3594,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3698 | 3594 | basic_string<_CharT, _Traits, _Allocator>::find_last_of(const value_type* __s, |
| 3699 | 3595 | size_type __pos) const _NOEXCEPT |
| 3700 | 3596 | { |
| 3701 | _LIBCPP_ASSERT(__s != nullptr, "string::find_last_of(): received nullptr"); | |
| 3597 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_of(): received nullptr"); | |
| 3702 | 3598 | return std::__str_find_last_of<value_type, size_type, traits_type, npos> |
| 3703 | 3599 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3704 | 3600 | } |
| ... | ... | @@ -3721,7 +3617,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* _ |
| 3721 | 3617 | size_type __pos, |
| 3722 | 3618 | size_type __n) const _NOEXCEPT |
| 3723 | 3619 | { |
| 3724 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); | |
| 3620 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_first_not_of(): received nullptr"); | |
| 3725 | 3621 | return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> |
| 3726 | 3622 | (data(), size(), __s, __pos, __n); |
| 3727 | 3623 | } |
| ... | ... | @@ -3737,13 +3633,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const basic_string& |
| 3737 | 3633 | } |
| 3738 | 3634 | |
| 3739 | 3635 | template<class _CharT, class _Traits, class _Allocator> |
| 3740 | template <class _Tp> | |
| 3741 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3742 | __enable_if_t | |
| 3743 | < | |
| 3744 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3745 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3746 | > | |
| 3636 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3637 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3747 | 3638 | basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const _Tp& __t, |
| 3748 | 3639 | size_type __pos) const _NOEXCEPT |
| 3749 | 3640 | { |
| ... | ... | @@ -3758,7 +3649,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3758 | 3649 | basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(const value_type* __s, |
| 3759 | 3650 | size_type __pos) const _NOEXCEPT |
| 3760 | 3651 | { |
| 3761 | _LIBCPP_ASSERT(__s != nullptr, "string::find_first_not_of(): received nullptr"); | |
| 3652 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_first_not_of(): received nullptr"); | |
| 3762 | 3653 | return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> |
| 3763 | 3654 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3764 | 3655 | } |
| ... | ... | @@ -3782,7 +3673,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __ |
| 3782 | 3673 | size_type __pos, |
| 3783 | 3674 | size_type __n) const _NOEXCEPT |
| 3784 | 3675 | { |
| 3785 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); | |
| 3676 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string::find_last_not_of(): received nullptr"); | |
| 3786 | 3677 | return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> |
| 3787 | 3678 | (data(), size(), __s, __pos, __n); |
| 3788 | 3679 | } |
| ... | ... | @@ -3798,13 +3689,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const basic_string& |
| 3798 | 3689 | } |
| 3799 | 3690 | |
| 3800 | 3691 | template<class _CharT, class _Traits, class _Allocator> |
| 3801 | template <class _Tp> | |
| 3802 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3803 | __enable_if_t | |
| 3804 | < | |
| 3805 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3806 | typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3807 | > | |
| 3692 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3693 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename basic_string<_CharT, _Traits, _Allocator>::size_type | |
| 3808 | 3694 | basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const _Tp& __t, |
| 3809 | 3695 | size_type __pos) const _NOEXCEPT |
| 3810 | 3696 | { |
| ... | ... | @@ -3819,7 +3705,7 @@ typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 3819 | 3705 | basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(const value_type* __s, |
| 3820 | 3706 | size_type __pos) const _NOEXCEPT |
| 3821 | 3707 | { |
| 3822 | _LIBCPP_ASSERT(__s != nullptr, "string::find_last_not_of(): received nullptr"); | |
| 3708 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::find_last_not_of(): received nullptr"); | |
| 3823 | 3709 | return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> |
| 3824 | 3710 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 3825 | 3711 | } |
| ... | ... | @@ -3837,13 +3723,8 @@ basic_string<_CharT, _Traits, _Allocator>::find_last_not_of(value_type __c, |
| 3837 | 3723 | // compare |
| 3838 | 3724 | |
| 3839 | 3725 | template <class _CharT, class _Traits, class _Allocator> |
| 3840 | template <class _Tp> | |
| 3841 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3842 | __enable_if_t | |
| 3843 | < | |
| 3844 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3845 | int | |
| 3846 | > | |
| 3726 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3727 | _LIBCPP_CONSTEXPR_SINCE_CXX20 int | |
| 3847 | 3728 | basic_string<_CharT, _Traits, _Allocator>::compare(const _Tp& __t) const _NOEXCEPT |
| 3848 | 3729 | { |
| 3849 | 3730 | __self_view __sv = __t; |
| ... | ... | @@ -3876,7 +3757,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, |
| 3876 | 3757 | const value_type* __s, |
| 3877 | 3758 | size_type __n2) const |
| 3878 | 3759 | { |
| 3879 | _LIBCPP_ASSERT(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); | |
| 3760 | _LIBCPP_ASSERT_UNCATEGORIZED(__n2 == 0 || __s != nullptr, "string::compare(): received nullptr"); | |
| 3880 | 3761 | size_type __sz = size(); |
| 3881 | 3762 | if (__pos1 > __sz || __n2 == npos) |
| 3882 | 3763 | __throw_out_of_range(); |
| ... | ... | @@ -3893,13 +3774,8 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, |
| 3893 | 3774 | } |
| 3894 | 3775 | |
| 3895 | 3776 | template <class _CharT, class _Traits, class _Allocator> |
| 3896 | template <class _Tp> | |
| 3897 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3898 | __enable_if_t | |
| 3899 | < | |
| 3900 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, | |
| 3901 | int | |
| 3902 | > | |
| 3777 | template <class _Tp, __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, int> > | |
| 3778 | _LIBCPP_CONSTEXPR_SINCE_CXX20 int | |
| 3903 | 3779 | basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, |
| 3904 | 3780 | size_type __n1, |
| 3905 | 3781 | const _Tp& __t) const |
| ... | ... | @@ -3919,20 +3795,12 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, |
| 3919 | 3795 | } |
| 3920 | 3796 | |
| 3921 | 3797 | template <class _CharT, class _Traits, class _Allocator> |
| 3922 | template <class _Tp> | |
| 3923 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3924 | __enable_if_t | |
| 3925 | < | |
| 3926 | __can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value | |
| 3927 | && !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 3928 | int | |
| 3929 | > | |
| 3930 | basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, | |
| 3931 | size_type __n1, | |
| 3932 | const _Tp& __t, | |
| 3933 | size_type __pos2, | |
| 3934 | size_type __n2) const | |
| 3935 | { | |
| 3798 | template <class _Tp, | |
| 3799 | __enable_if_t<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value && | |
| 3800 | !__is_same_uncvref<_Tp, basic_string<_CharT, _Traits, _Allocator> >::value, | |
| 3801 | int> > | |
| 3802 | _LIBCPP_CONSTEXPR_SINCE_CXX20 int basic_string<_CharT, _Traits, _Allocator>::compare( | |
| 3803 | size_type __pos1, size_type __n1, const _Tp& __t, size_type __pos2, size_type __n2) const { | |
| 3936 | 3804 | __self_view __sv = __t; |
| 3937 | 3805 | return __self_view(*this).substr(__pos1, __n1).compare(__sv.substr(__pos2, __n2)); |
| 3938 | 3806 | } |
| ... | ... | @@ -3954,7 +3822,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3954 | 3822 | int |
| 3955 | 3823 | basic_string<_CharT, _Traits, _Allocator>::compare(const value_type* __s) const _NOEXCEPT |
| 3956 | 3824 | { |
| 3957 | _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); | |
| 3825 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr"); | |
| 3958 | 3826 | return compare(0, npos, __s, traits_type::length(__s)); |
| 3959 | 3827 | } |
| 3960 | 3828 | |
| ... | ... | @@ -3965,7 +3833,7 @@ basic_string<_CharT, _Traits, _Allocator>::compare(size_type __pos1, |
| 3965 | 3833 | size_type __n1, |
| 3966 | 3834 | const value_type* __s) const |
| 3967 | 3835 | { |
| 3968 | _LIBCPP_ASSERT(__s != nullptr, "string::compare(): received nullptr"); | |
| 3836 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string::compare(): received nullptr"); | |
| 3969 | 3837 | return compare(__pos1, __n1, __s, traits_type::length(__s)); |
| 3970 | 3838 | } |
| 3971 | 3839 | |
| ... | ... | @@ -3982,7 +3850,7 @@ basic_string<_CharT, _Traits, _Allocator>::__invariants() const |
| 3982 | 3850 | return false; |
| 3983 | 3851 | if (data() == nullptr) |
| 3984 | 3852 | return false; |
| 3985 | if (data()[size()] != value_type()) | |
| 3853 | if (!_Traits::eq(data()[size()], value_type())) | |
| 3986 | 3854 | return false; |
| 3987 | 3855 | return true; |
| 3988 | 3856 | } |
| ... | ... | @@ -4010,7 +3878,7 @@ bool |
| 4010 | 3878 | operator==(const basic_string<_CharT, _Traits, _Allocator>& __lhs, |
| 4011 | 3879 | const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT |
| 4012 | 3880 | { |
| 4013 | #if _LIBCPP_STD_VER > 17 | |
| 3881 | #if _LIBCPP_STD_VER >= 20 | |
| 4014 | 3882 | return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); |
| 4015 | 3883 | #else |
| 4016 | 3884 | size_t __lhs_sz = __lhs.size(); |
| ... | ... | @@ -4047,7 +3915,7 @@ operator==(const _CharT* __lhs, |
| 4047 | 3915 | const basic_string<_CharT, _Traits, _Allocator>& __rhs) _NOEXCEPT |
| 4048 | 3916 | { |
| 4049 | 3917 | typedef basic_string<_CharT, _Traits, _Allocator> _String; |
| 4050 | _LIBCPP_ASSERT(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); | |
| 3918 | _LIBCPP_ASSERT_UNCATEGORIZED(__lhs != nullptr, "operator==(char*, basic_string): received nullptr"); | |
| 4051 | 3919 | size_t __lhs_len = _Traits::length(__lhs); |
| 4052 | 3920 | if (__lhs_len != __rhs.size()) return false; |
| 4053 | 3921 | return __rhs.compare(0, _String::npos, __lhs, __lhs_len) == 0; |
| ... | ... | @@ -4060,18 +3928,18 @@ bool |
| 4060 | 3928 | operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs, |
| 4061 | 3929 | const _CharT* __rhs) _NOEXCEPT |
| 4062 | 3930 | { |
| 4063 | #if _LIBCPP_STD_VER > 17 | |
| 3931 | #if _LIBCPP_STD_VER >= 20 | |
| 4064 | 3932 | return basic_string_view<_CharT, _Traits>(__lhs) == basic_string_view<_CharT, _Traits>(__rhs); |
| 4065 | 3933 | #else |
| 4066 | 3934 | typedef basic_string<_CharT, _Traits, _Allocator> _String; |
| 4067 | _LIBCPP_ASSERT(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); | |
| 3935 | _LIBCPP_ASSERT_UNCATEGORIZED(__rhs != nullptr, "operator==(basic_string, char*): received nullptr"); | |
| 4068 | 3936 | size_t __rhs_len = _Traits::length(__rhs); |
| 4069 | 3937 | if (__rhs_len != __lhs.size()) return false; |
| 4070 | 3938 | return __lhs.compare(0, _String::npos, __rhs, __rhs_len) == 0; |
| 4071 | 3939 | #endif |
| 4072 | 3940 | } |
| 4073 | 3941 | |
| 4074 | #if _LIBCPP_STD_VER > 17 | |
| 3942 | #if _LIBCPP_STD_VER >= 20 | |
| 4075 | 3943 | |
| 4076 | 3944 | template <class _CharT, class _Traits, class _Allocator> |
| 4077 | 3945 | _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>( |
| ... | ... | @@ -4086,7 +3954,7 @@ operator<=>(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const _CharT |
| 4086 | 3954 | return basic_string_view<_CharT, _Traits>(__lhs) <=> basic_string_view<_CharT, _Traits>(__rhs); |
| 4087 | 3955 | } |
| 4088 | 3956 | |
| 4089 | #else // _LIBCPP_STD_VER > 17 | |
| 3957 | #else // _LIBCPP_STD_VER >= 20 | |
| 4090 | 3958 | |
| 4091 | 3959 | template<class _CharT, class _Traits, class _Allocator> |
| 4092 | 3960 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -4230,7 +4098,7 @@ operator>=(const _CharT* __lhs, |
| 4230 | 4098 | { |
| 4231 | 4099 | return !(__lhs < __rhs); |
| 4232 | 4100 | } |
| 4233 | #endif // _LIBCPP_STD_VER > 17 | |
| 4101 | #endif // _LIBCPP_STD_VER >= 20 | |
| 4234 | 4102 | |
| 4235 | 4103 | // operator + |
| 4236 | 4104 | |
| ... | ... | @@ -4397,46 +4265,46 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs, |
| 4397 | 4265 | __lhs.swap(__rhs); |
| 4398 | 4266 | } |
| 4399 | 4267 | |
| 4400 | _LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4401 | _LIBCPP_FUNC_VIS long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4402 | _LIBCPP_FUNC_VIS unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4403 | _LIBCPP_FUNC_VIS long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4404 | _LIBCPP_FUNC_VIS unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4268 | _LIBCPP_EXPORTED_FROM_ABI int stoi (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4269 | _LIBCPP_EXPORTED_FROM_ABI long stol (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4270 | _LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4271 | _LIBCPP_EXPORTED_FROM_ABI long long stoll (const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4272 | _LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const string& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4405 | 4273 | |
| 4406 | _LIBCPP_FUNC_VIS float stof (const string& __str, size_t* __idx = nullptr); | |
| 4407 | _LIBCPP_FUNC_VIS double stod (const string& __str, size_t* __idx = nullptr); | |
| 4408 | _LIBCPP_FUNC_VIS long double stold(const string& __str, size_t* __idx = nullptr); | |
| 4274 | _LIBCPP_EXPORTED_FROM_ABI float stof (const string& __str, size_t* __idx = nullptr); | |
| 4275 | _LIBCPP_EXPORTED_FROM_ABI double stod (const string& __str, size_t* __idx = nullptr); | |
| 4276 | _LIBCPP_EXPORTED_FROM_ABI long double stold(const string& __str, size_t* __idx = nullptr); | |
| 4409 | 4277 | |
| 4410 | _LIBCPP_FUNC_VIS string to_string(int __val); | |
| 4411 | _LIBCPP_FUNC_VIS string to_string(unsigned __val); | |
| 4412 | _LIBCPP_FUNC_VIS string to_string(long __val); | |
| 4413 | _LIBCPP_FUNC_VIS string to_string(unsigned long __val); | |
| 4414 | _LIBCPP_FUNC_VIS string to_string(long long __val); | |
| 4415 | _LIBCPP_FUNC_VIS string to_string(unsigned long long __val); | |
| 4416 | _LIBCPP_FUNC_VIS string to_string(float __val); | |
| 4417 | _LIBCPP_FUNC_VIS string to_string(double __val); | |
| 4418 | _LIBCPP_FUNC_VIS string to_string(long double __val); | |
| 4278 | _LIBCPP_EXPORTED_FROM_ABI string to_string(int __val); | |
| 4279 | _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned __val); | |
| 4280 | _LIBCPP_EXPORTED_FROM_ABI string to_string(long __val); | |
| 4281 | _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long __val); | |
| 4282 | _LIBCPP_EXPORTED_FROM_ABI string to_string(long long __val); | |
| 4283 | _LIBCPP_EXPORTED_FROM_ABI string to_string(unsigned long long __val); | |
| 4284 | _LIBCPP_EXPORTED_FROM_ABI string to_string(float __val); | |
| 4285 | _LIBCPP_EXPORTED_FROM_ABI string to_string(double __val); | |
| 4286 | _LIBCPP_EXPORTED_FROM_ABI string to_string(long double __val); | |
| 4419 | 4287 | |
| 4420 | 4288 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 4421 | _LIBCPP_FUNC_VIS int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4422 | _LIBCPP_FUNC_VIS long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4423 | _LIBCPP_FUNC_VIS unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4424 | _LIBCPP_FUNC_VIS long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4425 | _LIBCPP_FUNC_VIS unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4426 | ||
| 4427 | _LIBCPP_FUNC_VIS float stof (const wstring& __str, size_t* __idx = nullptr); | |
| 4428 | _LIBCPP_FUNC_VIS double stod (const wstring& __str, size_t* __idx = nullptr); | |
| 4429 | _LIBCPP_FUNC_VIS long double stold(const wstring& __str, size_t* __idx = nullptr); | |
| 4430 | ||
| 4431 | _LIBCPP_FUNC_VIS wstring to_wstring(int __val); | |
| 4432 | _LIBCPP_FUNC_VIS wstring to_wstring(unsigned __val); | |
| 4433 | _LIBCPP_FUNC_VIS wstring to_wstring(long __val); | |
| 4434 | _LIBCPP_FUNC_VIS wstring to_wstring(unsigned long __val); | |
| 4435 | _LIBCPP_FUNC_VIS wstring to_wstring(long long __val); | |
| 4436 | _LIBCPP_FUNC_VIS wstring to_wstring(unsigned long long __val); | |
| 4437 | _LIBCPP_FUNC_VIS wstring to_wstring(float __val); | |
| 4438 | _LIBCPP_FUNC_VIS wstring to_wstring(double __val); | |
| 4439 | _LIBCPP_FUNC_VIS wstring to_wstring(long double __val); | |
| 4289 | _LIBCPP_EXPORTED_FROM_ABI int stoi (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4290 | _LIBCPP_EXPORTED_FROM_ABI long stol (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4291 | _LIBCPP_EXPORTED_FROM_ABI unsigned long stoul (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4292 | _LIBCPP_EXPORTED_FROM_ABI long long stoll (const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4293 | _LIBCPP_EXPORTED_FROM_ABI unsigned long long stoull(const wstring& __str, size_t* __idx = nullptr, int __base = 10); | |
| 4294 | ||
| 4295 | _LIBCPP_EXPORTED_FROM_ABI float stof (const wstring& __str, size_t* __idx = nullptr); | |
| 4296 | _LIBCPP_EXPORTED_FROM_ABI double stod (const wstring& __str, size_t* __idx = nullptr); | |
| 4297 | _LIBCPP_EXPORTED_FROM_ABI long double stold(const wstring& __str, size_t* __idx = nullptr); | |
| 4298 | ||
| 4299 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(int __val); | |
| 4300 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned __val); | |
| 4301 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long __val); | |
| 4302 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long __val); | |
| 4303 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long long __val); | |
| 4304 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(unsigned long long __val); | |
| 4305 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(float __val); | |
| 4306 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(double __val); | |
| 4307 | _LIBCPP_EXPORTED_FROM_ABI wstring to_wstring(long double __val); | |
| 4440 | 4308 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 4441 | 4309 | |
| 4442 | 4310 | template<class _CharT, class _Traits, class _Allocator> |
| ... | ... | @@ -4445,11 +4313,11 @@ const typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| 4445 | 4313 | basic_string<_CharT, _Traits, _Allocator>::npos; |
| 4446 | 4314 | |
| 4447 | 4315 | template <class _CharT, class _Allocator> |
| 4448 | struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> | |
| 4449 | { | |
| 4450 | size_t | |
| 4451 | operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT | |
| 4452 | { return std::__do_string_hash(__val.data(), __val.data() + __val.size()); } | |
| 4316 | struct __string_hash : public __unary_function<basic_string<_CharT, char_traits<_CharT>, _Allocator>, size_t> { | |
| 4317 | _LIBCPP_HIDE_FROM_ABI size_t | |
| 4318 | operator()(const basic_string<_CharT, char_traits<_CharT>, _Allocator>& __val) const _NOEXCEPT { | |
| 4319 | return std::__do_string_hash(__val.data(), __val.data() + __val.size()); | |
| 4320 | } | |
| 4453 | 4321 | }; |
| 4454 | 4322 | |
| 4455 | 4323 | template <class _Allocator> |
| ... | ... | @@ -4504,7 +4372,7 @@ basic_istream<_CharT, _Traits>& |
| 4504 | 4372 | getline(basic_istream<_CharT, _Traits>&& __is, |
| 4505 | 4373 | basic_string<_CharT, _Traits, _Allocator>& __str); |
| 4506 | 4374 | |
| 4507 | #if _LIBCPP_STD_VER > 17 | |
| 4375 | #if _LIBCPP_STD_VER >= 20 | |
| 4508 | 4376 | template <class _CharT, class _Traits, class _Allocator, class _Up> |
| 4509 | 4377 | inline _LIBCPP_HIDE_FROM_ABI |
| 4510 | 4378 | typename basic_string<_CharT, _Traits, _Allocator>::size_type |
| ... | ... | @@ -4526,57 +4394,21 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 4526 | 4394 | } |
| 4527 | 4395 | #endif |
| 4528 | 4396 | |
| 4529 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 4530 | ||
| 4531 | template<class _CharT, class _Traits, class _Allocator> | |
| 4532 | bool | |
| 4533 | basic_string<_CharT, _Traits, _Allocator>::__dereferenceable(const const_iterator* __i) const | |
| 4534 | { | |
| 4535 | return data() <= std::__to_address(__i->base()) && | |
| 4536 | std::__to_address(__i->base()) < data() + size(); | |
| 4537 | } | |
| 4538 | ||
| 4539 | template<class _CharT, class _Traits, class _Allocator> | |
| 4540 | bool | |
| 4541 | basic_string<_CharT, _Traits, _Allocator>::__decrementable(const const_iterator* __i) const | |
| 4542 | { | |
| 4543 | return data() < std::__to_address(__i->base()) && | |
| 4544 | std::__to_address(__i->base()) <= data() + size(); | |
| 4545 | } | |
| 4546 | ||
| 4547 | template<class _CharT, class _Traits, class _Allocator> | |
| 4548 | bool | |
| 4549 | basic_string<_CharT, _Traits, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 4550 | { | |
| 4551 | const value_type* __p = std::__to_address(__i->base()) + __n; | |
| 4552 | return data() <= __p && __p <= data() + size(); | |
| 4553 | } | |
| 4554 | ||
| 4555 | template<class _CharT, class _Traits, class _Allocator> | |
| 4556 | bool | |
| 4557 | basic_string<_CharT, _Traits, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 4558 | { | |
| 4559 | const value_type* __p = std::__to_address(__i->base()) + __n; | |
| 4560 | return data() <= __p && __p < data() + size(); | |
| 4561 | } | |
| 4562 | ||
| 4563 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 4564 | ||
| 4565 | #if _LIBCPP_STD_VER > 11 | |
| 4397 | #if _LIBCPP_STD_VER >= 14 | |
| 4566 | 4398 | // Literal suffixes for basic_string [basic.string.literals] |
| 4567 | 4399 | inline namespace literals |
| 4568 | 4400 | { |
| 4569 | 4401 | inline namespace string_literals |
| 4570 | 4402 | { |
| 4571 | 4403 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 4572 | basic_string<char> operator "" s( const char *__str, size_t __len ) | |
| 4404 | basic_string<char> operator""s( const char *__str, size_t __len ) | |
| 4573 | 4405 | { |
| 4574 | 4406 | return basic_string<char> (__str, __len); |
| 4575 | 4407 | } |
| 4576 | 4408 | |
| 4577 | 4409 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 4578 | 4410 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 4579 | basic_string<wchar_t> operator "" s( const wchar_t *__str, size_t __len ) | |
| 4411 | basic_string<wchar_t> operator""s( const wchar_t *__str, size_t __len ) | |
| 4580 | 4412 | { |
| 4581 | 4413 | return basic_string<wchar_t> (__str, __len); |
| 4582 | 4414 | } |
| ... | ... | @@ -4584,27 +4416,27 @@ inline namespace literals |
| 4584 | 4416 | |
| 4585 | 4417 | #ifndef _LIBCPP_HAS_NO_CHAR8_T |
| 4586 | 4418 | inline _LIBCPP_HIDE_FROM_ABI constexpr |
| 4587 | basic_string<char8_t> operator "" s(const char8_t *__str, size_t __len) | |
| 4419 | basic_string<char8_t> operator""s(const char8_t *__str, size_t __len) | |
| 4588 | 4420 | { |
| 4589 | 4421 | return basic_string<char8_t> (__str, __len); |
| 4590 | 4422 | } |
| 4591 | 4423 | #endif |
| 4592 | 4424 | |
| 4593 | 4425 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 4594 | basic_string<char16_t> operator "" s( const char16_t *__str, size_t __len ) | |
| 4426 | basic_string<char16_t> operator""s( const char16_t *__str, size_t __len ) | |
| 4595 | 4427 | { |
| 4596 | 4428 | return basic_string<char16_t> (__str, __len); |
| 4597 | 4429 | } |
| 4598 | 4430 | |
| 4599 | 4431 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 4600 | basic_string<char32_t> operator "" s( const char32_t *__str, size_t __len ) | |
| 4432 | basic_string<char32_t> operator""s( const char32_t *__str, size_t __len ) | |
| 4601 | 4433 | { |
| 4602 | 4434 | return basic_string<char32_t> (__str, __len); |
| 4603 | 4435 | } |
| 4604 | 4436 | } // namespace string_literals |
| 4605 | 4437 | } // namespace literals |
| 4606 | 4438 | |
| 4607 | #if _LIBCPP_STD_VER > 17 | |
| 4439 | #if _LIBCPP_STD_VER >= 20 | |
| 4608 | 4440 | template <> |
| 4609 | 4441 | inline constexpr bool __format::__enable_insertable<std::basic_string<char>> = true; |
| 4610 | 4442 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -4622,12 +4454,12 @@ _LIBCPP_POP_MACROS |
| 4622 | 4454 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 4623 | 4455 | # include <algorithm> |
| 4624 | 4456 | # include <concepts> |
| 4625 | # include <functional> | |
| 4457 | # include <cstdlib> | |
| 4626 | 4458 | # include <iterator> |
| 4627 | 4459 | # include <new> |
| 4460 | # include <type_traits> | |
| 4628 | 4461 | # include <typeinfo> |
| 4629 | 4462 | # include <utility> |
| 4630 | # include <vector> | |
| 4631 | 4463 | #endif |
| 4632 | 4464 | |
| 4633 | 4465 | #endif // _LIBCPP_STRING |
lib/libcxx/include/string.h+1-2| ... | ... | @@ -64,8 +64,7 @@ size_t strlen(const char* s); |
| 64 | 64 | // MSVCRT, GNU libc and its derivates may already have the correct prototype in |
| 65 | 65 | // <string.h>. This macro can be defined by users if their C library provides |
| 66 | 66 | // the right signature. |
| 67 | #if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || \ | |
| 68 | defined(__sun__) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) | |
| 67 | #if defined(__CORRECT_ISO_CPP_STRING_H_PROTO) || defined(_LIBCPP_MSVCRT) || defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_) | |
| 69 | 68 | #define _LIBCPP_STRING_H_HAS_CONST_OVERLOADS |
| 70 | 69 | #endif |
| 71 | 70 |
lib/libcxx/include/string_view+102-67| ... | ... | @@ -90,7 +90,7 @@ namespace std { |
| 90 | 90 | basic_string_view& operator=(const basic_string_view&) noexcept = default; |
| 91 | 91 | template<class Allocator> |
| 92 | 92 | constexpr basic_string_view(const charT* str); |
| 93 | basic_string_view(nullptr_t) = delete; // C++2b | |
| 93 | basic_string_view(nullptr_t) = delete; // C++23 | |
| 94 | 94 | constexpr basic_string_view(const charT* str, size_type len); |
| 95 | 95 | template <class It, class End> |
| 96 | 96 | constexpr basic_string_view(It begin, End end); // C++20 |
| ... | ... | @@ -168,9 +168,9 @@ namespace std { |
| 168 | 168 | constexpr bool ends_with(charT c) const noexcept; // C++20 |
| 169 | 169 | constexpr bool ends_with(const charT* s) const; // C++20 |
| 170 | 170 | |
| 171 | constexpr bool contains(basic_string_view s) const noexcept; // C++2b | |
| 172 | constexpr bool contains(charT c) const noexcept; // C++2b | |
| 173 | constexpr bool contains(const charT* s) const; // C++2b | |
| 171 | constexpr bool contains(basic_string_view s) const noexcept; // C++23 | |
| 172 | constexpr bool contains(charT c) const noexcept; // C++23 | |
| 173 | constexpr bool contains(const charT* s) const; // C++23 | |
| 174 | 174 | |
| 175 | 175 | private: |
| 176 | 176 | const_pointer data_; // exposition only |
| ... | ... | @@ -191,11 +191,11 @@ namespace std { |
| 191 | 191 | template <> struct hash<u32string_view>; |
| 192 | 192 | template <> struct hash<wstring_view>; |
| 193 | 193 | |
| 194 | constexpr basic_string_view<char> operator "" sv(const char *str, size_t len) noexcept; | |
| 195 | constexpr basic_string_view<wchar_t> operator "" sv(const wchar_t *str, size_t len) noexcept; | |
| 196 | constexpr basic_string_view<char8_t> operator "" sv(const char8_t *str, size_t len) noexcept; // C++20 | |
| 197 | constexpr basic_string_view<char16_t> operator "" sv(const char16_t *str, size_t len) noexcept; | |
| 198 | constexpr basic_string_view<char32_t> operator "" sv(const char32_t *str, size_t len) noexcept; | |
| 194 | constexpr basic_string_view<char> operator""sv(const char *str, size_t len) noexcept; | |
| 195 | constexpr basic_string_view<wchar_t> operator""sv(const wchar_t *str, size_t len) noexcept; | |
| 196 | constexpr basic_string_view<char8_t> operator""sv(const char8_t *str, size_t len) noexcept; // C++20 | |
| 197 | constexpr basic_string_view<char16_t> operator""sv(const char16_t *str, size_t len) noexcept; | |
| 198 | constexpr basic_string_view<char32_t> operator""sv(const char32_t *str, size_t len) noexcept; | |
| 199 | 199 | |
| 200 | 200 | } // namespace std |
| 201 | 201 | |
| ... | ... | @@ -208,8 +208,9 @@ namespace std { |
| 208 | 208 | #include <__functional/hash.h> |
| 209 | 209 | #include <__functional/unary_function.h> |
| 210 | 210 | #include <__fwd/string_view.h> |
| 211 | #include <__iterator/bounded_iter.h> | |
| 211 | 212 | #include <__iterator/concepts.h> |
| 212 | #include <__iterator/readable_traits.h> | |
| 213 | #include <__iterator/iterator_traits.h> | |
| 213 | 214 | #include <__iterator/reverse_iterator.h> |
| 214 | 215 | #include <__memory/pointer_traits.h> |
| 215 | 216 | #include <__ranges/concepts.h> |
| ... | ... | @@ -218,10 +219,18 @@ namespace std { |
| 218 | 219 | #include <__ranges/enable_view.h> |
| 219 | 220 | #include <__ranges/size.h> |
| 220 | 221 | #include <__string/char_traits.h> |
| 222 | #include <__type_traits/is_array.h> | |
| 223 | #include <__type_traits/is_convertible.h> | |
| 224 | #include <__type_traits/is_same.h> | |
| 225 | #include <__type_traits/is_standard_layout.h> | |
| 226 | #include <__type_traits/is_trivial.h> | |
| 227 | #include <__type_traits/remove_cvref.h> | |
| 228 | #include <__type_traits/remove_reference.h> | |
| 229 | #include <__type_traits/type_identity.h> | |
| 230 | #include <cstddef> | |
| 221 | 231 | #include <iosfwd> |
| 222 | 232 | #include <limits> |
| 223 | 233 | #include <stdexcept> |
| 224 | #include <type_traits> | |
| 225 | 234 | #include <version> |
| 226 | 235 | |
| 227 | 236 | // standard-mandated includes |
| ... | ... | @@ -252,7 +261,9 @@ template <class _Traits> |
| 252 | 261 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR |
| 253 | 262 | inline size_t __char_traits_length_checked(const typename _Traits::char_type* __s) _NOEXCEPT { |
| 254 | 263 | // This needs to be a single statement for C++11 constexpr |
| 255 | return _LIBCPP_ASSERT(__s != nullptr, "null pointer passed to non-null argument of char_traits<...>::length"), _Traits::length(__s); | |
| 264 | return _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, | |
| 265 | "null pointer passed to non-null argument of char_traits<...>::length"), | |
| 266 | _Traits::length(__s); | |
| 256 | 267 | } |
| 257 | 268 | |
| 258 | 269 | template<class _CharT, class _Traits> |
| ... | ... | @@ -265,7 +276,11 @@ public: |
| 265 | 276 | using const_pointer = const _CharT*; |
| 266 | 277 | using reference = _CharT&; |
| 267 | 278 | using const_reference = const _CharT&; |
| 279 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 280 | using const_iterator = __bounded_iter<const_pointer>; | |
| 281 | #else | |
| 268 | 282 | using const_iterator = const_pointer; // See [string.view.iterators] |
| 283 | #endif | |
| 269 | 284 | using iterator = const_iterator; |
| 270 | 285 | using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; |
| 271 | 286 | using reverse_iterator = const_reverse_iterator; |
| ... | ... | @@ -293,22 +308,27 @@ public: |
| 293 | 308 | basic_string_view(const _CharT* __s, size_type __len) _NOEXCEPT |
| 294 | 309 | : __data_(__s), __size_(__len) |
| 295 | 310 | { |
| 296 | #if _LIBCPP_STD_VER > 11 | |
| 297 | _LIBCPP_ASSERT(__len == 0 || __s != nullptr, "string_view::string_view(_CharT *, size_t): received nullptr"); | |
| 311 | #if _LIBCPP_STD_VER >= 14 | |
| 312 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 313 | __len <= static_cast<size_type>(numeric_limits<difference_type>::max()), | |
| 314 | "string_view::string_view(_CharT *, size_t): length does not fit in difference_type"); | |
| 315 | _LIBCPP_ASSERT_UNCATEGORIZED(__len == 0 || __s != nullptr, | |
| 316 | "string_view::string_view(_CharT *, size_t): received nullptr"); | |
| 298 | 317 | #endif |
| 299 | 318 | } |
| 300 | 319 | |
| 301 | #if _LIBCPP_STD_VER > 17 | |
| 320 | #if _LIBCPP_STD_VER >= 20 | |
| 302 | 321 | template <contiguous_iterator _It, sized_sentinel_for<_It> _End> |
| 303 | 322 | requires (is_same_v<iter_value_t<_It>, _CharT> && !is_convertible_v<_End, size_type>) |
| 304 | 323 | constexpr _LIBCPP_HIDE_FROM_ABI basic_string_view(_It __begin, _End __end) |
| 305 | 324 | : __data_(_VSTD::to_address(__begin)), __size_(__end - __begin) |
| 306 | 325 | { |
| 307 | _LIBCPP_ASSERT((__end - __begin) >= 0, "std::string_view::string_view(iterator, sentinel) received invalid range"); | |
| 326 | _LIBCPP_ASSERT_VALID_INPUT_RANGE((__end - __begin) >= 0, | |
| 327 | "std::string_view::string_view(iterator, sentinel) received invalid range"); | |
| 308 | 328 | } |
| 309 | #endif // _LIBCPP_STD_VER > 17 | |
| 329 | #endif // _LIBCPP_STD_VER >= 20 | |
| 310 | 330 | |
| 311 | #if _LIBCPP_STD_VER > 20 | |
| 331 | #if _LIBCPP_STD_VER >= 23 | |
| 312 | 332 | template <class _Range> |
| 313 | 333 | requires ( |
| 314 | 334 | !is_same_v<remove_cvref_t<_Range>, basic_string_view> && |
| ... | ... | @@ -318,20 +338,17 @@ public: |
| 318 | 338 | !is_convertible_v<_Range, const _CharT*> && |
| 319 | 339 | (!requires(remove_cvref_t<_Range>& __d) { |
| 320 | 340 | __d.operator _VSTD::basic_string_view<_CharT, _Traits>(); |
| 321 | }) && | |
| 322 | (!requires { | |
| 323 | typename remove_reference_t<_Range>::traits_type; | |
| 324 | } || is_same_v<typename remove_reference_t<_Range>::traits_type, _Traits>) | |
| 341 | }) | |
| 325 | 342 | ) |
| 326 | 343 | constexpr explicit _LIBCPP_HIDE_FROM_ABI |
| 327 | 344 | basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {} |
| 328 | #endif // _LIBCPP_STD_VER > 20 | |
| 345 | #endif // _LIBCPP_STD_VER >= 23 | |
| 329 | 346 | |
| 330 | 347 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 331 | 348 | basic_string_view(const _CharT* __s) |
| 332 | 349 | : __data_(__s), __size_(_VSTD::__char_traits_length_checked<_Traits>(__s)) {} |
| 333 | 350 | |
| 334 | #if _LIBCPP_STD_VER > 20 | |
| 351 | #if _LIBCPP_STD_VER >= 23 | |
| 335 | 352 | basic_string_view(nullptr_t) = delete; |
| 336 | 353 | #endif |
| 337 | 354 | |
| ... | ... | @@ -343,10 +360,22 @@ public: |
| 343 | 360 | const_iterator end() const _NOEXCEPT { return cend(); } |
| 344 | 361 | |
| 345 | 362 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 346 | const_iterator cbegin() const _NOEXCEPT { return __data_; } | |
| 363 | const_iterator cbegin() const _NOEXCEPT { | |
| 364 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 365 | return std::__make_bounded_iter(data(), data(), data() + size()); | |
| 366 | #else | |
| 367 | return __data_; | |
| 368 | #endif | |
| 369 | } | |
| 347 | 370 | |
| 348 | 371 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 349 | const_iterator cend() const _NOEXCEPT { return __data_ + __size_; } | |
| 372 | const_iterator cend() const _NOEXCEPT { | |
| 373 | #ifdef _LIBCPP_ABI_BOUNDED_ITERATORS | |
| 374 | return std::__make_bounded_iter(data() + size(), data(), data() + size()); | |
| 375 | #else | |
| 376 | return __data_ + __size_; | |
| 377 | #endif | |
| 378 | } | |
| 350 | 379 | |
| 351 | 380 | _LIBCPP_CONSTEXPR_SINCE_CXX17 _LIBCPP_INLINE_VISIBILITY |
| 352 | 381 | const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(cend()); } |
| ... | ... | @@ -376,7 +405,7 @@ public: |
| 376 | 405 | // [string.view.access], element access |
| 377 | 406 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 378 | 407 | const_reference operator[](size_type __pos) const _NOEXCEPT { |
| 379 | return _LIBCPP_ASSERT(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; | |
| 408 | return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__pos < size(), "string_view[] index out of bounds"), __data_[__pos]; | |
| 380 | 409 | } |
| 381 | 410 | |
| 382 | 411 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -390,13 +419,14 @@ public: |
| 390 | 419 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 391 | 420 | const_reference front() const _NOEXCEPT |
| 392 | 421 | { |
| 393 | return _LIBCPP_ASSERT(!empty(), "string_view::front(): string is empty"), __data_[0]; | |
| 422 | return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::front(): string is empty"), __data_[0]; | |
| 394 | 423 | } |
| 395 | 424 | |
| 396 | 425 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| 397 | 426 | const_reference back() const _NOEXCEPT |
| 398 | 427 | { |
| 399 | return _LIBCPP_ASSERT(!empty(), "string_view::back(): string is empty"), __data_[__size_-1]; | |
| 428 | return _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "string_view::back(): string is empty"), | |
| 429 | __data_[__size_ - 1]; | |
| 400 | 430 | } |
| 401 | 431 | |
| 402 | 432 | _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -406,7 +436,7 @@ public: |
| 406 | 436 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 407 | 437 | void remove_prefix(size_type __n) _NOEXCEPT |
| 408 | 438 | { |
| 409 | _LIBCPP_ASSERT(__n <= size(), "remove_prefix() can't remove more than size()"); | |
| 439 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_prefix() can't remove more than size()"); | |
| 410 | 440 | __data_ += __n; |
| 411 | 441 | __size_ -= __n; |
| 412 | 442 | } |
| ... | ... | @@ -414,7 +444,7 @@ public: |
| 414 | 444 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 415 | 445 | void remove_suffix(size_type __n) _NOEXCEPT |
| 416 | 446 | { |
| 417 | _LIBCPP_ASSERT(__n <= size(), "remove_suffix() can't remove more than size()"); | |
| 447 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n <= size(), "remove_suffix() can't remove more than size()"); | |
| 418 | 448 | __size_ -= __n; |
| 419 | 449 | } |
| 420 | 450 | |
| ... | ... | @@ -492,7 +522,7 @@ public: |
| 492 | 522 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 493 | 523 | size_type find(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT |
| 494 | 524 | { |
| 495 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); | |
| 525 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); | |
| 496 | 526 | return std::__str_find<value_type, size_type, traits_type, npos> |
| 497 | 527 | (data(), size(), __s.data(), __pos, __s.size()); |
| 498 | 528 | } |
| ... | ... | @@ -507,7 +537,7 @@ public: |
| 507 | 537 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 508 | 538 | size_type find(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 509 | 539 | { |
| 510 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); | |
| 540 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find(): received nullptr"); | |
| 511 | 541 | return std::__str_find<value_type, size_type, traits_type, npos> |
| 512 | 542 | (data(), size(), __s, __pos, __n); |
| 513 | 543 | } |
| ... | ... | @@ -515,7 +545,7 @@ public: |
| 515 | 545 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 516 | 546 | size_type find(const _CharT* __s, size_type __pos = 0) const _NOEXCEPT |
| 517 | 547 | { |
| 518 | _LIBCPP_ASSERT(__s != nullptr, "string_view::find(): received nullptr"); | |
| 548 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find(): received nullptr"); | |
| 519 | 549 | return std::__str_find<value_type, size_type, traits_type, npos> |
| 520 | 550 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 521 | 551 | } |
| ... | ... | @@ -524,7 +554,7 @@ public: |
| 524 | 554 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 525 | 555 | size_type rfind(basic_string_view __s, size_type __pos = npos) const _NOEXCEPT |
| 526 | 556 | { |
| 527 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); | |
| 557 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, "string_view::find(): received nullptr"); | |
| 528 | 558 | return std::__str_rfind<value_type, size_type, traits_type, npos> |
| 529 | 559 | (data(), size(), __s.data(), __pos, __s.size()); |
| 530 | 560 | } |
| ... | ... | @@ -539,7 +569,7 @@ public: |
| 539 | 569 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 540 | 570 | size_type rfind(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 541 | 571 | { |
| 542 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); | |
| 572 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::rfind(): received nullptr"); | |
| 543 | 573 | return std::__str_rfind<value_type, size_type, traits_type, npos> |
| 544 | 574 | (data(), size(), __s, __pos, __n); |
| 545 | 575 | } |
| ... | ... | @@ -547,7 +577,7 @@ public: |
| 547 | 577 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 548 | 578 | size_type rfind(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT |
| 549 | 579 | { |
| 550 | _LIBCPP_ASSERT(__s != nullptr, "string_view::rfind(): received nullptr"); | |
| 580 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::rfind(): received nullptr"); | |
| 551 | 581 | return std::__str_rfind<value_type, size_type, traits_type, npos> |
| 552 | 582 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 553 | 583 | } |
| ... | ... | @@ -556,7 +586,8 @@ public: |
| 556 | 586 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 557 | 587 | size_type find_first_of(basic_string_view __s, size_type __pos = 0) const _NOEXCEPT |
| 558 | 588 | { |
| 559 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_of(): received nullptr"); | |
| 589 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, | |
| 590 | "string_view::find_first_of(): received nullptr"); | |
| 560 | 591 | return std::__str_find_first_of<value_type, size_type, traits_type, npos> |
| 561 | 592 | (data(), size(), __s.data(), __pos, __s.size()); |
| 562 | 593 | } |
| ... | ... | @@ -568,7 +599,7 @@ public: |
| 568 | 599 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 569 | 600 | size_type find_first_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 570 | 601 | { |
| 571 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); | |
| 602 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_of(): received nullptr"); | |
| 572 | 603 | return std::__str_find_first_of<value_type, size_type, traits_type, npos> |
| 573 | 604 | (data(), size(), __s, __pos, __n); |
| 574 | 605 | } |
| ... | ... | @@ -576,7 +607,7 @@ public: |
| 576 | 607 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 577 | 608 | size_type find_first_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT |
| 578 | 609 | { |
| 579 | _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_of(): received nullptr"); | |
| 610 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_of(): received nullptr"); | |
| 580 | 611 | return std::__str_find_first_of<value_type, size_type, traits_type, npos> |
| 581 | 612 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 582 | 613 | } |
| ... | ... | @@ -585,7 +616,8 @@ public: |
| 585 | 616 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 586 | 617 | size_type find_last_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT |
| 587 | 618 | { |
| 588 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_of(): received nullptr"); | |
| 619 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, | |
| 620 | "string_view::find_last_of(): received nullptr"); | |
| 589 | 621 | return std::__str_find_last_of<value_type, size_type, traits_type, npos> |
| 590 | 622 | (data(), size(), __s.data(), __pos, __s.size()); |
| 591 | 623 | } |
| ... | ... | @@ -597,7 +629,7 @@ public: |
| 597 | 629 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 598 | 630 | size_type find_last_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 599 | 631 | { |
| 600 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); | |
| 632 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_of(): received nullptr"); | |
| 601 | 633 | return std::__str_find_last_of<value_type, size_type, traits_type, npos> |
| 602 | 634 | (data(), size(), __s, __pos, __n); |
| 603 | 635 | } |
| ... | ... | @@ -605,7 +637,7 @@ public: |
| 605 | 637 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 606 | 638 | size_type find_last_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT |
| 607 | 639 | { |
| 608 | _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_of(): received nullptr"); | |
| 640 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_of(): received nullptr"); | |
| 609 | 641 | return std::__str_find_last_of<value_type, size_type, traits_type, npos> |
| 610 | 642 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 611 | 643 | } |
| ... | ... | @@ -614,7 +646,8 @@ public: |
| 614 | 646 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 615 | 647 | size_type find_first_not_of(basic_string_view __s, size_type __pos=0) const _NOEXCEPT |
| 616 | 648 | { |
| 617 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_first_not_of(): received nullptr"); | |
| 649 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, | |
| 650 | "string_view::find_first_not_of(): received nullptr"); | |
| 618 | 651 | return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> |
| 619 | 652 | (data(), size(), __s.data(), __pos, __s.size()); |
| 620 | 653 | } |
| ... | ... | @@ -629,7 +662,7 @@ public: |
| 629 | 662 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 630 | 663 | size_type find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 631 | 664 | { |
| 632 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); | |
| 665 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_first_not_of(): received nullptr"); | |
| 633 | 666 | return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> |
| 634 | 667 | (data(), size(), __s, __pos, __n); |
| 635 | 668 | } |
| ... | ... | @@ -637,7 +670,7 @@ public: |
| 637 | 670 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 638 | 671 | size_type find_first_not_of(const _CharT* __s, size_type __pos=0) const _NOEXCEPT |
| 639 | 672 | { |
| 640 | _LIBCPP_ASSERT(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); | |
| 673 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_first_not_of(): received nullptr"); | |
| 641 | 674 | return std::__str_find_first_not_of<value_type, size_type, traits_type, npos> |
| 642 | 675 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 643 | 676 | } |
| ... | ... | @@ -646,7 +679,8 @@ public: |
| 646 | 679 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 647 | 680 | size_type find_last_not_of(basic_string_view __s, size_type __pos=npos) const _NOEXCEPT |
| 648 | 681 | { |
| 649 | _LIBCPP_ASSERT(__s.size() == 0 || __s.data() != nullptr, "string_view::find_last_not_of(): received nullptr"); | |
| 682 | _LIBCPP_ASSERT_UNCATEGORIZED(__s.size() == 0 || __s.data() != nullptr, | |
| 683 | "string_view::find_last_not_of(): received nullptr"); | |
| 650 | 684 | return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> |
| 651 | 685 | (data(), size(), __s.data(), __pos, __s.size()); |
| 652 | 686 | } |
| ... | ... | @@ -661,7 +695,7 @@ public: |
| 661 | 695 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 662 | 696 | size_type find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const _NOEXCEPT |
| 663 | 697 | { |
| 664 | _LIBCPP_ASSERT(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); | |
| 698 | _LIBCPP_ASSERT_UNCATEGORIZED(__n == 0 || __s != nullptr, "string_view::find_last_not_of(): received nullptr"); | |
| 665 | 699 | return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> |
| 666 | 700 | (data(), size(), __s, __pos, __n); |
| 667 | 701 | } |
| ... | ... | @@ -669,12 +703,12 @@ public: |
| 669 | 703 | _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY |
| 670 | 704 | size_type find_last_not_of(const _CharT* __s, size_type __pos=npos) const _NOEXCEPT |
| 671 | 705 | { |
| 672 | _LIBCPP_ASSERT(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); | |
| 706 | _LIBCPP_ASSERT_UNCATEGORIZED(__s != nullptr, "string_view::find_last_not_of(): received nullptr"); | |
| 673 | 707 | return std::__str_find_last_not_of<value_type, size_type, traits_type, npos> |
| 674 | 708 | (data(), size(), __s, __pos, traits_type::length(__s)); |
| 675 | 709 | } |
| 676 | 710 | |
| 677 | #if _LIBCPP_STD_VER > 17 | |
| 711 | #if _LIBCPP_STD_VER >= 20 | |
| 678 | 712 | constexpr _LIBCPP_INLINE_VISIBILITY |
| 679 | 713 | bool starts_with(basic_string_view __s) const noexcept |
| 680 | 714 | { return size() >= __s.size() && compare(0, __s.size(), __s) == 0; } |
| ... | ... | @@ -700,7 +734,7 @@ public: |
| 700 | 734 | { return ends_with(basic_string_view(__s)); } |
| 701 | 735 | #endif |
| 702 | 736 | |
| 703 | #if _LIBCPP_STD_VER > 20 | |
| 737 | #if _LIBCPP_STD_VER >= 23 | |
| 704 | 738 | constexpr _LIBCPP_INLINE_VISIBILITY |
| 705 | 739 | bool contains(basic_string_view __sv) const noexcept |
| 706 | 740 | { return find(__sv) != npos; } |
| ... | ... | @@ -720,23 +754,23 @@ private: |
| 720 | 754 | }; |
| 721 | 755 | _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_string_view); |
| 722 | 756 | |
| 723 | #if _LIBCPP_STD_VER > 17 | |
| 757 | #if _LIBCPP_STD_VER >= 20 | |
| 724 | 758 | template <class _CharT, class _Traits> |
| 725 | 759 | inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true; |
| 726 | 760 | |
| 727 | 761 | template <class _CharT, class _Traits> |
| 728 | 762 | inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true; |
| 729 | #endif // _LIBCPP_STD_VER > 17 | |
| 763 | #endif // _LIBCPP_STD_VER >= 20 | |
| 730 | 764 | |
| 731 | 765 | // [string.view.deduct] |
| 732 | 766 | |
| 733 | #if _LIBCPP_STD_VER > 17 | |
| 767 | #if _LIBCPP_STD_VER >= 20 | |
| 734 | 768 | template <contiguous_iterator _It, sized_sentinel_for<_It> _End> |
| 735 | 769 | basic_string_view(_It, _End) -> basic_string_view<iter_value_t<_It>>; |
| 736 | #endif // _LIBCPP_STD_VER > 17 | |
| 770 | #endif // _LIBCPP_STD_VER >= 20 | |
| 737 | 771 | |
| 738 | 772 | |
| 739 | #if _LIBCPP_STD_VER > 20 | |
| 773 | #if _LIBCPP_STD_VER >= 23 | |
| 740 | 774 | template <ranges::contiguous_range _Range> |
| 741 | 775 | basic_string_view(_Range) -> basic_string_view<ranges::range_value_t<_Range>>; |
| 742 | 776 | #endif |
| ... | ... | @@ -773,11 +807,11 @@ bool operator==(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, |
| 773 | 807 | if (__lhs.size() != __rhs.size()) return false; |
| 774 | 808 | return __lhs.compare(__rhs) == 0; |
| 775 | 809 | } |
| 776 | #endif // _LIBCPP_STD_VER > 17 | |
| 810 | #endif // _LIBCPP_STD_VER >= 20 | |
| 777 | 811 | |
| 778 | 812 | // operator <=> |
| 779 | 813 | |
| 780 | #if _LIBCPP_STD_VER > 17 | |
| 814 | #if _LIBCPP_STD_VER >= 20 | |
| 781 | 815 | |
| 782 | 816 | template <class _CharT, class _Traits> |
| 783 | 817 | _LIBCPP_HIDE_FROM_ABI constexpr auto |
| ... | ... | @@ -807,7 +841,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>( |
| 807 | 841 | } |
| 808 | 842 | } |
| 809 | 843 | |
| 810 | #else // _LIBCPP_STD_VER > 17 | |
| 844 | #else // _LIBCPP_STD_VER >= 20 | |
| 811 | 845 | |
| 812 | 846 | // operator != |
| 813 | 847 | template<class _CharT, class _Traits> |
| ... | ... | @@ -940,7 +974,7 @@ bool operator>=(__type_identity_t<basic_string_view<_CharT, _Traits> > __lhs, |
| 940 | 974 | return __lhs.compare(__rhs) >= 0; |
| 941 | 975 | } |
| 942 | 976 | |
| 943 | #endif // _LIBCPP_STD_VER > 17 | |
| 977 | #endif // _LIBCPP_STD_VER >= 20 | |
| 944 | 978 | |
| 945 | 979 | template<class _CharT, class _Traits> |
| 946 | 980 | _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& |
| ... | ... | @@ -976,20 +1010,20 @@ template <> |
| 976 | 1010 | struct hash<basic_string_view<wchar_t, char_traits<wchar_t> > > : __string_view_hash<wchar_t> {}; |
| 977 | 1011 | #endif |
| 978 | 1012 | |
| 979 | #if _LIBCPP_STD_VER > 11 | |
| 1013 | #if _LIBCPP_STD_VER >= 14 | |
| 980 | 1014 | inline namespace literals |
| 981 | 1015 | { |
| 982 | 1016 | inline namespace string_view_literals |
| 983 | 1017 | { |
| 984 | 1018 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 985 | basic_string_view<char> operator "" sv(const char *__str, size_t __len) _NOEXCEPT | |
| 1019 | basic_string_view<char> operator""sv(const char *__str, size_t __len) _NOEXCEPT | |
| 986 | 1020 | { |
| 987 | 1021 | return basic_string_view<char> (__str, __len); |
| 988 | 1022 | } |
| 989 | 1023 | |
| 990 | 1024 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 991 | 1025 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 992 | basic_string_view<wchar_t> operator "" sv(const wchar_t *__str, size_t __len) _NOEXCEPT | |
| 1026 | basic_string_view<wchar_t> operator""sv(const wchar_t *__str, size_t __len) _NOEXCEPT | |
| 993 | 1027 | { |
| 994 | 1028 | return basic_string_view<wchar_t> (__str, __len); |
| 995 | 1029 | } |
| ... | ... | @@ -997,20 +1031,20 @@ inline namespace literals |
| 997 | 1031 | |
| 998 | 1032 | #ifndef _LIBCPP_HAS_NO_CHAR8_T |
| 999 | 1033 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 1000 | basic_string_view<char8_t> operator "" sv(const char8_t *__str, size_t __len) _NOEXCEPT | |
| 1034 | basic_string_view<char8_t> operator""sv(const char8_t *__str, size_t __len) _NOEXCEPT | |
| 1001 | 1035 | { |
| 1002 | 1036 | return basic_string_view<char8_t> (__str, __len); |
| 1003 | 1037 | } |
| 1004 | 1038 | #endif |
| 1005 | 1039 | |
| 1006 | 1040 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 1007 | basic_string_view<char16_t> operator "" sv(const char16_t *__str, size_t __len) _NOEXCEPT | |
| 1041 | basic_string_view<char16_t> operator""sv(const char16_t *__str, size_t __len) _NOEXCEPT | |
| 1008 | 1042 | { |
| 1009 | 1043 | return basic_string_view<char16_t> (__str, __len); |
| 1010 | 1044 | } |
| 1011 | 1045 | |
| 1012 | 1046 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR |
| 1013 | basic_string_view<char32_t> operator "" sv(const char32_t *__str, size_t __len) _NOEXCEPT | |
| 1047 | basic_string_view<char32_t> operator""sv(const char32_t *__str, size_t __len) _NOEXCEPT | |
| 1014 | 1048 | { |
| 1015 | 1049 | return basic_string_view<char32_t> (__str, __len); |
| 1016 | 1050 | } |
| ... | ... | @@ -1024,8 +1058,9 @@ _LIBCPP_POP_MACROS |
| 1024 | 1058 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1025 | 1059 | # include <algorithm> |
| 1026 | 1060 | # include <concepts> |
| 1027 | # include <functional> | |
| 1061 | # include <cstdlib> | |
| 1028 | 1062 | # include <iterator> |
| 1063 | # include <type_traits> | |
| 1029 | 1064 | #endif |
| 1030 | 1065 | |
| 1031 | 1066 | #endif // _LIBCPP_STRING_VIEW |
lib/libcxx/include/strstream+11-11| ... | ... | @@ -141,12 +141,12 @@ private: |
| 141 | 141 | |
| 142 | 142 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 143 | 143 | |
| 144 | class _LIBCPP_TYPE_VIS strstreambuf | |
| 144 | class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstreambuf | |
| 145 | 145 | : public streambuf |
| 146 | 146 | { |
| 147 | 147 | public: |
| 148 | 148 | #ifndef _LIBCPP_CXX03_LANG |
| 149 | strstreambuf() : strstreambuf(0) {} | |
| 149 | _LIBCPP_HIDE_FROM_ABI strstreambuf() : strstreambuf(0) {} | |
| 150 | 150 | explicit strstreambuf(streamsize __alsize); |
| 151 | 151 | #else |
| 152 | 152 | explicit strstreambuf(streamsize __alsize = 0); |
| ... | ... | @@ -237,7 +237,7 @@ strstreambuf::operator=(strstreambuf&& __rhs) |
| 237 | 237 | |
| 238 | 238 | #endif // _LIBCPP_CXX03_LANG |
| 239 | 239 | |
| 240 | class _LIBCPP_TYPE_VIS istrstream | |
| 240 | class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI istrstream | |
| 241 | 241 | : public istream |
| 242 | 242 | { |
| 243 | 243 | public: |
| ... | ... | @@ -256,8 +256,8 @@ public: |
| 256 | 256 | |
| 257 | 257 | #ifndef _LIBCPP_CXX03_LANG |
| 258 | 258 | _LIBCPP_INLINE_VISIBILITY |
| 259 | istrstream(istrstream&& __rhs) | |
| 260 | : istream(_VSTD::move(__rhs)), | |
| 259 | istrstream(istrstream&& __rhs) // extension | |
| 260 | : istream(_VSTD::move(static_cast<istream&>(__rhs))), | |
| 261 | 261 | __sb_(_VSTD::move(__rhs.__sb_)) |
| 262 | 262 | { |
| 263 | 263 | istream::set_rdbuf(&__sb_); |
| ... | ... | @@ -290,7 +290,7 @@ private: |
| 290 | 290 | strstreambuf __sb_; |
| 291 | 291 | }; |
| 292 | 292 | |
| 293 | class _LIBCPP_TYPE_VIS ostrstream | |
| 293 | class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI ostrstream | |
| 294 | 294 | : public ostream |
| 295 | 295 | { |
| 296 | 296 | public: |
| ... | ... | @@ -305,8 +305,8 @@ public: |
| 305 | 305 | |
| 306 | 306 | #ifndef _LIBCPP_CXX03_LANG |
| 307 | 307 | _LIBCPP_INLINE_VISIBILITY |
| 308 | ostrstream(ostrstream&& __rhs) | |
| 309 | : ostream(_VSTD::move(__rhs)), | |
| 308 | ostrstream(ostrstream&& __rhs) // extension | |
| 309 | : ostream(_VSTD::move(static_cast<ostream&>(__rhs))), | |
| 310 | 310 | __sb_(_VSTD::move(__rhs.__sb_)) |
| 311 | 311 | { |
| 312 | 312 | ostream::set_rdbuf(&__sb_); |
| ... | ... | @@ -343,7 +343,7 @@ private: |
| 343 | 343 | strstreambuf __sb_; // exposition only |
| 344 | 344 | }; |
| 345 | 345 | |
| 346 | class _LIBCPP_TYPE_VIS strstream | |
| 346 | class _LIBCPP_DEPRECATED _LIBCPP_EXPORTED_FROM_ABI strstream | |
| 347 | 347 | : public iostream |
| 348 | 348 | { |
| 349 | 349 | public: |
| ... | ... | @@ -365,8 +365,8 @@ public: |
| 365 | 365 | |
| 366 | 366 | #ifndef _LIBCPP_CXX03_LANG |
| 367 | 367 | _LIBCPP_INLINE_VISIBILITY |
| 368 | strstream(strstream&& __rhs) | |
| 369 | : iostream(_VSTD::move(__rhs)), | |
| 368 | strstream(strstream&& __rhs) // extension | |
| 369 | : iostream(_VSTD::move(static_cast<iostream&>(__rhs))), | |
| 370 | 370 | __sb_(_VSTD::move(__rhs.__sb_)) |
| 371 | 371 | { |
| 372 | 372 | iostream::set_rdbuf(&__sb_); |
lib/libcxx/include/system_error+10-386| ... | ... | @@ -146,13 +146,11 @@ template <> struct hash<std::error_condition>; |
| 146 | 146 | |
| 147 | 147 | #include <__assert> // all public C++ headers provide the assertion handler |
| 148 | 148 | #include <__config> |
| 149 | #include <__errc> | |
| 150 | #include <__functional/hash.h> | |
| 151 | #include <__functional/unary_function.h> | |
| 152 | #include <__memory/addressof.h> | |
| 153 | #include <stdexcept> | |
| 154 | #include <string> | |
| 155 | #include <type_traits> | |
| 149 | #include <__system_error/errc.h> | |
| 150 | #include <__system_error/error_category.h> | |
| 151 | #include <__system_error/error_code.h> | |
| 152 | #include <__system_error/error_condition.h> | |
| 153 | #include <__system_error/system_error.h> | |
| 156 | 154 | #include <version> |
| 157 | 155 | |
| 158 | 156 | // standard-mandated includes |
| ... | ... | @@ -164,385 +162,11 @@ template <> struct hash<std::error_condition>; |
| 164 | 162 | # pragma GCC system_header |
| 165 | 163 | #endif |
| 166 | 164 | |
| 167 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 168 | ||
| 169 | // is_error_code_enum | |
| 170 | ||
| 171 | template <class _Tp> | |
| 172 | struct _LIBCPP_TEMPLATE_VIS is_error_code_enum | |
| 173 | : public false_type {}; | |
| 174 | ||
| 175 | #if _LIBCPP_STD_VER > 14 | |
| 176 | template <class _Tp> | |
| 177 | inline constexpr bool is_error_code_enum_v = is_error_code_enum<_Tp>::value; | |
| 178 | #endif | |
| 179 | ||
| 180 | // is_error_condition_enum | |
| 181 | ||
| 182 | template <class _Tp> | |
| 183 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum | |
| 184 | : public false_type {}; | |
| 185 | ||
| 186 | #if _LIBCPP_STD_VER > 14 | |
| 187 | template <class _Tp> | |
| 188 | inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<_Tp>::value; | |
| 189 | #endif | |
| 190 | ||
| 191 | template <> | |
| 192 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc> | |
| 193 | : true_type { }; | |
| 194 | ||
| 195 | #ifdef _LIBCPP_CXX03_LANG | |
| 196 | template <> | |
| 197 | struct _LIBCPP_TEMPLATE_VIS is_error_condition_enum<errc::__lx> | |
| 198 | : true_type { }; | |
| 199 | #endif | |
| 200 | ||
| 201 | class _LIBCPP_TYPE_VIS error_condition; | |
| 202 | class _LIBCPP_TYPE_VIS error_code; | |
| 203 | ||
| 204 | // class error_category | |
| 205 | ||
| 206 | class _LIBCPP_HIDDEN __do_message; | |
| 207 | ||
| 208 | class _LIBCPP_TYPE_VIS error_category | |
| 209 | { | |
| 210 | public: | |
| 211 | virtual ~error_category() _NOEXCEPT; | |
| 212 | ||
| 213 | #if defined(_LIBCPP_ERROR_CATEGORY_DEFINE_LEGACY_INLINE_FUNCTIONS) | |
| 214 | error_category() noexcept; | |
| 215 | #else | |
| 216 | _LIBCPP_INLINE_VISIBILITY | |
| 217 | _LIBCPP_CONSTEXPR_SINCE_CXX14 error_category() _NOEXCEPT = default; | |
| 165 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 166 | # include <cstdint> | |
| 167 | # include <cstring> | |
| 168 | # include <limits> | |
| 169 | # include <type_traits> | |
| 218 | 170 | #endif |
| 219 | error_category(const error_category&) = delete; | |
| 220 | error_category& operator=(const error_category&) = delete; | |
| 221 | ||
| 222 | virtual const char* name() const _NOEXCEPT = 0; | |
| 223 | virtual error_condition default_error_condition(int __ev) const _NOEXCEPT; | |
| 224 | virtual bool equivalent(int __code, const error_condition& __condition) const _NOEXCEPT; | |
| 225 | virtual bool equivalent(const error_code& __code, int __condition) const _NOEXCEPT; | |
| 226 | virtual string message(int __ev) const = 0; | |
| 227 | ||
| 228 | _LIBCPP_INLINE_VISIBILITY | |
| 229 | bool operator==(const error_category& __rhs) const _NOEXCEPT {return this == &__rhs;} | |
| 230 | ||
| 231 | #if _LIBCPP_STD_VER > 17 | |
| 232 | ||
| 233 | _LIBCPP_HIDE_FROM_ABI | |
| 234 | strong_ordering operator<=>(const error_category& __rhs) const noexcept {return compare_three_way()(this, std::addressof(__rhs));} | |
| 235 | ||
| 236 | #else // _LIBCPP_STD_VER > 17 | |
| 237 | ||
| 238 | _LIBCPP_INLINE_VISIBILITY | |
| 239 | bool operator!=(const error_category& __rhs) const _NOEXCEPT {return !(*this == __rhs);} | |
| 240 | ||
| 241 | _LIBCPP_INLINE_VISIBILITY | |
| 242 | bool operator< (const error_category& __rhs) const _NOEXCEPT {return this < &__rhs;} | |
| 243 | ||
| 244 | #endif // _LIBCPP_STD_VER > 17 | |
| 245 | ||
| 246 | friend class _LIBCPP_HIDDEN __do_message; | |
| 247 | }; | |
| 248 | ||
| 249 | class _LIBCPP_HIDDEN __do_message | |
| 250 | : public error_category | |
| 251 | { | |
| 252 | public: | |
| 253 | string message(int __ev) const override; | |
| 254 | }; | |
| 255 | ||
| 256 | _LIBCPP_FUNC_VIS const error_category& generic_category() _NOEXCEPT; | |
| 257 | _LIBCPP_FUNC_VIS const error_category& system_category() _NOEXCEPT; | |
| 258 | ||
| 259 | namespace __adl_only { | |
| 260 | // Those cause ADL to trigger but they are not viable candidates, | |
| 261 | // so they are never actually selected. | |
| 262 | void make_error_condition() = delete; | |
| 263 | void make_error_code() = delete; | |
| 264 | } // namespace __adl_only | |
| 265 | ||
| 266 | class _LIBCPP_TYPE_VIS error_condition | |
| 267 | { | |
| 268 | int __val_; | |
| 269 | const error_category* __cat_; | |
| 270 | public: | |
| 271 | _LIBCPP_INLINE_VISIBILITY | |
| 272 | error_condition() _NOEXCEPT : __val_(0), __cat_(&generic_category()) {} | |
| 273 | ||
| 274 | _LIBCPP_INLINE_VISIBILITY | |
| 275 | error_condition(int __val, const error_category& __cat) _NOEXCEPT | |
| 276 | : __val_(__val), __cat_(&__cat) {} | |
| 277 | ||
| 278 | template <class _Ep> | |
| 279 | _LIBCPP_INLINE_VISIBILITY | |
| 280 | error_condition(_Ep __e, | |
| 281 | typename enable_if<is_error_condition_enum<_Ep>::value>::type* = nullptr | |
| 282 | ) _NOEXCEPT | |
| 283 | { | |
| 284 | using __adl_only::make_error_condition; | |
| 285 | *this = make_error_condition(__e); | |
| 286 | } | |
| 287 | ||
| 288 | _LIBCPP_INLINE_VISIBILITY | |
| 289 | void assign(int __val, const error_category& __cat) _NOEXCEPT | |
| 290 | { | |
| 291 | __val_ = __val; | |
| 292 | __cat_ = &__cat; | |
| 293 | } | |
| 294 | ||
| 295 | template <class _Ep> | |
| 296 | _LIBCPP_INLINE_VISIBILITY | |
| 297 | typename enable_if | |
| 298 | < | |
| 299 | is_error_condition_enum<_Ep>::value, | |
| 300 | error_condition& | |
| 301 | >::type | |
| 302 | operator=(_Ep __e) _NOEXCEPT | |
| 303 | { | |
| 304 | using __adl_only::make_error_condition; | |
| 305 | *this = make_error_condition(__e); | |
| 306 | return *this; | |
| 307 | } | |
| 308 | ||
| 309 | _LIBCPP_INLINE_VISIBILITY | |
| 310 | void clear() _NOEXCEPT | |
| 311 | { | |
| 312 | __val_ = 0; | |
| 313 | __cat_ = &generic_category(); | |
| 314 | } | |
| 315 | ||
| 316 | _LIBCPP_INLINE_VISIBILITY | |
| 317 | int value() const _NOEXCEPT {return __val_;} | |
| 318 | ||
| 319 | _LIBCPP_INLINE_VISIBILITY | |
| 320 | const error_category& category() const _NOEXCEPT {return *__cat_;} | |
| 321 | string message() const; | |
| 322 | ||
| 323 | _LIBCPP_INLINE_VISIBILITY | |
| 324 | explicit operator bool() const _NOEXCEPT {return __val_ != 0;} | |
| 325 | }; | |
| 326 | ||
| 327 | inline _LIBCPP_INLINE_VISIBILITY | |
| 328 | error_condition | |
| 329 | make_error_condition(errc __e) _NOEXCEPT | |
| 330 | { | |
| 331 | return error_condition(static_cast<int>(__e), generic_category()); | |
| 332 | } | |
| 333 | ||
| 334 | // error_code | |
| 335 | ||
| 336 | class _LIBCPP_TYPE_VIS error_code | |
| 337 | { | |
| 338 | int __val_; | |
| 339 | const error_category* __cat_; | |
| 340 | public: | |
| 341 | _LIBCPP_INLINE_VISIBILITY | |
| 342 | error_code() _NOEXCEPT : __val_(0), __cat_(&system_category()) {} | |
| 343 | ||
| 344 | _LIBCPP_INLINE_VISIBILITY | |
| 345 | error_code(int __val, const error_category& __cat) _NOEXCEPT | |
| 346 | : __val_(__val), __cat_(&__cat) {} | |
| 347 | ||
| 348 | template <class _Ep> | |
| 349 | _LIBCPP_INLINE_VISIBILITY | |
| 350 | error_code(_Ep __e, | |
| 351 | typename enable_if<is_error_code_enum<_Ep>::value>::type* = nullptr | |
| 352 | ) _NOEXCEPT | |
| 353 | { | |
| 354 | using __adl_only::make_error_code; | |
| 355 | *this = make_error_code(__e); | |
| 356 | } | |
| 357 | ||
| 358 | _LIBCPP_INLINE_VISIBILITY | |
| 359 | void assign(int __val, const error_category& __cat) _NOEXCEPT | |
| 360 | { | |
| 361 | __val_ = __val; | |
| 362 | __cat_ = &__cat; | |
| 363 | } | |
| 364 | ||
| 365 | template <class _Ep> | |
| 366 | _LIBCPP_INLINE_VISIBILITY | |
| 367 | typename enable_if | |
| 368 | < | |
| 369 | is_error_code_enum<_Ep>::value, | |
| 370 | error_code& | |
| 371 | >::type | |
| 372 | operator=(_Ep __e) _NOEXCEPT | |
| 373 | { | |
| 374 | using __adl_only::make_error_code; | |
| 375 | *this = make_error_code(__e); | |
| 376 | return *this; | |
| 377 | } | |
| 378 | ||
| 379 | _LIBCPP_INLINE_VISIBILITY | |
| 380 | void clear() _NOEXCEPT | |
| 381 | { | |
| 382 | __val_ = 0; | |
| 383 | __cat_ = &system_category(); | |
| 384 | } | |
| 385 | ||
| 386 | _LIBCPP_INLINE_VISIBILITY | |
| 387 | int value() const _NOEXCEPT {return __val_;} | |
| 388 | ||
| 389 | _LIBCPP_INLINE_VISIBILITY | |
| 390 | const error_category& category() const _NOEXCEPT {return *__cat_;} | |
| 391 | ||
| 392 | _LIBCPP_INLINE_VISIBILITY | |
| 393 | error_condition default_error_condition() const _NOEXCEPT | |
| 394 | {return __cat_->default_error_condition(__val_);} | |
| 395 | ||
| 396 | string message() const; | |
| 397 | ||
| 398 | _LIBCPP_INLINE_VISIBILITY | |
| 399 | explicit operator bool() const _NOEXCEPT {return __val_ != 0;} | |
| 400 | }; | |
| 401 | ||
| 402 | inline _LIBCPP_INLINE_VISIBILITY | |
| 403 | error_code | |
| 404 | make_error_code(errc __e) _NOEXCEPT | |
| 405 | { | |
| 406 | return error_code(static_cast<int>(__e), generic_category()); | |
| 407 | } | |
| 408 | ||
| 409 | inline _LIBCPP_INLINE_VISIBILITY | |
| 410 | bool | |
| 411 | operator==(const error_code& __x, const error_code& __y) _NOEXCEPT | |
| 412 | { | |
| 413 | return __x.category() == __y.category() && __x.value() == __y.value(); | |
| 414 | } | |
| 415 | ||
| 416 | inline _LIBCPP_INLINE_VISIBILITY | |
| 417 | bool | |
| 418 | operator==(const error_code& __x, const error_condition& __y) _NOEXCEPT | |
| 419 | { | |
| 420 | return __x.category().equivalent(__x.value(), __y) | |
| 421 | || __y.category().equivalent(__x, __y.value()); | |
| 422 | } | |
| 423 | ||
| 424 | #if _LIBCPP_STD_VER <= 17 | |
| 425 | inline _LIBCPP_INLINE_VISIBILITY | |
| 426 | bool | |
| 427 | operator==(const error_condition& __x, const error_code& __y) _NOEXCEPT | |
| 428 | { | |
| 429 | return __y == __x; | |
| 430 | } | |
| 431 | #endif | |
| 432 | ||
| 433 | inline _LIBCPP_INLINE_VISIBILITY | |
| 434 | bool | |
| 435 | operator==(const error_condition& __x, const error_condition& __y) _NOEXCEPT | |
| 436 | { | |
| 437 | return __x.category() == __y.category() && __x.value() == __y.value(); | |
| 438 | } | |
| 439 | ||
| 440 | #if _LIBCPP_STD_VER <= 17 | |
| 441 | ||
| 442 | inline _LIBCPP_INLINE_VISIBILITY | |
| 443 | bool | |
| 444 | operator!=(const error_code& __x, const error_code& __y) _NOEXCEPT | |
| 445 | {return !(__x == __y);} | |
| 446 | ||
| 447 | inline _LIBCPP_INLINE_VISIBILITY | |
| 448 | bool | |
| 449 | operator!=(const error_code& __x, const error_condition& __y) _NOEXCEPT | |
| 450 | {return !(__x == __y);} | |
| 451 | ||
| 452 | inline _LIBCPP_INLINE_VISIBILITY | |
| 453 | bool | |
| 454 | operator!=(const error_condition& __x, const error_code& __y) _NOEXCEPT | |
| 455 | {return !(__x == __y);} | |
| 456 | ||
| 457 | inline _LIBCPP_INLINE_VISIBILITY | |
| 458 | bool | |
| 459 | operator!=(const error_condition& __x, const error_condition& __y) _NOEXCEPT | |
| 460 | {return !(__x == __y);} | |
| 461 | ||
| 462 | inline _LIBCPP_INLINE_VISIBILITY | |
| 463 | bool | |
| 464 | operator<(const error_condition& __x, const error_condition& __y) _NOEXCEPT | |
| 465 | { | |
| 466 | return __x.category() < __y.category() | |
| 467 | || (__x.category() == __y.category() && __x.value() < __y.value()); | |
| 468 | } | |
| 469 | ||
| 470 | inline _LIBCPP_INLINE_VISIBILITY | |
| 471 | bool | |
| 472 | operator<(const error_code& __x, const error_code& __y) _NOEXCEPT | |
| 473 | { | |
| 474 | return __x.category() < __y.category() | |
| 475 | || (__x.category() == __y.category() && __x.value() < __y.value()); | |
| 476 | } | |
| 477 | ||
| 478 | #else // _LIBCPP_STD_VER <= 17 | |
| 479 | ||
| 480 | inline _LIBCPP_HIDE_FROM_ABI strong_ordering | |
| 481 | operator<=>(const error_code& __x, const error_code& __y) noexcept | |
| 482 | { | |
| 483 | if (auto __c = __x.category() <=> __y.category(); __c != 0) | |
| 484 | return __c; | |
| 485 | return __x.value() <=> __y.value(); | |
| 486 | } | |
| 487 | ||
| 488 | inline _LIBCPP_HIDE_FROM_ABI strong_ordering | |
| 489 | operator<=>(const error_condition& __x, const error_condition& __y) noexcept | |
| 490 | { | |
| 491 | if (auto __c = __x.category() <=> __y.category(); __c != 0) | |
| 492 | return __c; | |
| 493 | return __x.value() <=> __y.value(); | |
| 494 | } | |
| 495 | ||
| 496 | #endif // _LIBCPP_STD_VER <= 17 | |
| 497 | ||
| 498 | template <> | |
| 499 | struct _LIBCPP_TEMPLATE_VIS hash<error_code> | |
| 500 | : public __unary_function<error_code, size_t> | |
| 501 | { | |
| 502 | _LIBCPP_INLINE_VISIBILITY | |
| 503 | size_t operator()(const error_code& __ec) const _NOEXCEPT | |
| 504 | { | |
| 505 | return static_cast<size_t>(__ec.value()); | |
| 506 | } | |
| 507 | }; | |
| 508 | ||
| 509 | template <> | |
| 510 | struct _LIBCPP_TEMPLATE_VIS hash<error_condition> | |
| 511 | : public __unary_function<error_condition, size_t> | |
| 512 | { | |
| 513 | _LIBCPP_INLINE_VISIBILITY | |
| 514 | size_t operator()(const error_condition& __ec) const _NOEXCEPT | |
| 515 | { | |
| 516 | return static_cast<size_t>(__ec.value()); | |
| 517 | } | |
| 518 | }; | |
| 519 | ||
| 520 | // system_error | |
| 521 | ||
| 522 | class _LIBCPP_TYPE_VIS system_error | |
| 523 | : public runtime_error | |
| 524 | { | |
| 525 | error_code __ec_; | |
| 526 | public: | |
| 527 | system_error(error_code __ec, const string& __what_arg); | |
| 528 | system_error(error_code __ec, const char* __what_arg); | |
| 529 | system_error(error_code __ec); | |
| 530 | system_error(int __ev, const error_category& __ecat, const string& __what_arg); | |
| 531 | system_error(int __ev, const error_category& __ecat, const char* __what_arg); | |
| 532 | system_error(int __ev, const error_category& __ecat); | |
| 533 | system_error(const system_error&) _NOEXCEPT = default; | |
| 534 | ~system_error() _NOEXCEPT override; | |
| 535 | ||
| 536 | _LIBCPP_INLINE_VISIBILITY | |
| 537 | const error_code& code() const _NOEXCEPT {return __ec_;} | |
| 538 | ||
| 539 | private: | |
| 540 | static string __init(const error_code&, string); | |
| 541 | }; | |
| 542 | ||
| 543 | _LIBCPP_NORETURN _LIBCPP_FUNC_VIS | |
| 544 | void __throw_system_error(int __ev, const char* __what_arg); | |
| 545 | ||
| 546 | _LIBCPP_END_NAMESPACE_STD | |
| 547 | 171 | |
| 548 | 172 | #endif // _LIBCPP_SYSTEM_ERROR |
lib/libcxx/include/thread+16-307| ... | ... | @@ -64,6 +64,9 @@ template<class charT, class traits> |
| 64 | 64 | basic_ostream<charT, traits>& |
| 65 | 65 | operator<<(basic_ostream<charT, traits>& out, thread::id id); |
| 66 | 66 | |
| 67 | template<class charT> | |
| 68 | struct formatter<thread::id, charT>; | |
| 69 | ||
| 67 | 70 | namespace this_thread |
| 68 | 71 | { |
| 69 | 72 | |
| ... | ... | @@ -84,19 +87,12 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); |
| 84 | 87 | */ |
| 85 | 88 | |
| 86 | 89 | #include <__assert> // all public C++ headers provide the assertion handler |
| 90 | #include <__availability> | |
| 87 | 91 | #include <__config> |
| 88 | #include <__functional/hash.h> | |
| 89 | #include <__memory/unique_ptr.h> | |
| 90 | #include <__mutex_base> | |
| 91 | #include <__thread/poll_with_backoff.h> | |
| 92 | #include <__thread/timed_backoff_policy.h> | |
| 92 | #include <__thread/formatter.h> | |
| 93 | #include <__thread/this_thread.h> | |
| 94 | #include <__thread/thread.h> | |
| 93 | 95 | #include <__threading_support> |
| 94 | #include <__utility/forward.h> | |
| 95 | #include <cstddef> | |
| 96 | #include <iosfwd> | |
| 97 | #include <system_error> | |
| 98 | #include <tuple> | |
| 99 | #include <type_traits> | |
| 100 | 96 | #include <version> |
| 101 | 97 | |
| 102 | 98 | // standard-mandated includes |
| ... | ... | @@ -108,314 +104,27 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time); |
| 108 | 104 | # pragma GCC system_header |
| 109 | 105 | #endif |
| 110 | 106 | |
| 111 | _LIBCPP_PUSH_MACROS | |
| 112 | #include <__undef_macros> | |
| 113 | ||
| 114 | 107 | #ifdef _LIBCPP_HAS_NO_THREADS |
| 115 | 108 | # error "<thread> is not supported since libc++ has been configured without support for threads." |
| 116 | 109 | #endif |
| 117 | 110 | |
| 118 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 119 | ||
| 120 | template <class _Tp> class __thread_specific_ptr; | |
| 121 | class _LIBCPP_TYPE_VIS __thread_struct; | |
| 122 | class _LIBCPP_HIDDEN __thread_struct_imp; | |
| 123 | class __assoc_sub_state; | |
| 124 | ||
| 125 | _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); | |
| 126 | ||
| 127 | class _LIBCPP_TYPE_VIS __thread_struct | |
| 128 | { | |
| 129 | __thread_struct_imp* __p_; | |
| 130 | ||
| 131 | __thread_struct(const __thread_struct&); | |
| 132 | __thread_struct& operator=(const __thread_struct&); | |
| 133 | public: | |
| 134 | __thread_struct(); | |
| 135 | ~__thread_struct(); | |
| 136 | ||
| 137 | void notify_all_at_thread_exit(condition_variable*, mutex*); | |
| 138 | void __make_ready_at_thread_exit(__assoc_sub_state*); | |
| 139 | }; | |
| 140 | ||
| 141 | template <class _Tp> | |
| 142 | class __thread_specific_ptr | |
| 143 | { | |
| 144 | __libcpp_tls_key __key_; | |
| 145 | ||
| 146 | // Only __thread_local_data() may construct a __thread_specific_ptr | |
| 147 | // and only with _Tp == __thread_struct. | |
| 148 | static_assert((is_same<_Tp, __thread_struct>::value), ""); | |
| 149 | __thread_specific_ptr(); | |
| 150 | friend _LIBCPP_FUNC_VIS __thread_specific_ptr<__thread_struct>& __thread_local_data(); | |
| 151 | ||
| 152 | __thread_specific_ptr(const __thread_specific_ptr&); | |
| 153 | __thread_specific_ptr& operator=(const __thread_specific_ptr&); | |
| 154 | ||
| 155 | _LIBCPP_HIDDEN static void _LIBCPP_TLS_DESTRUCTOR_CC __at_thread_exit(void*); | |
| 156 | ||
| 157 | public: | |
| 158 | typedef _Tp* pointer; | |
| 159 | ||
| 160 | ~__thread_specific_ptr(); | |
| 161 | ||
| 162 | _LIBCPP_INLINE_VISIBILITY | |
| 163 | pointer get() const {return static_cast<_Tp*>(__libcpp_tls_get(__key_));} | |
| 164 | _LIBCPP_INLINE_VISIBILITY | |
| 165 | pointer operator*() const {return *get();} | |
| 166 | _LIBCPP_INLINE_VISIBILITY | |
| 167 | pointer operator->() const {return get();} | |
| 168 | void set_pointer(pointer __p); | |
| 169 | }; | |
| 170 | ||
| 171 | template <class _Tp> | |
| 172 | void _LIBCPP_TLS_DESTRUCTOR_CC | |
| 173 | __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p) | |
| 174 | { | |
| 175 | delete static_cast<pointer>(__p); | |
| 176 | } | |
| 177 | ||
| 178 | template <class _Tp> | |
| 179 | __thread_specific_ptr<_Tp>::__thread_specific_ptr() | |
| 180 | { | |
| 181 | int __ec = | |
| 182 | __libcpp_tls_create(&__key_, &__thread_specific_ptr::__at_thread_exit); | |
| 183 | if (__ec) | |
| 184 | __throw_system_error(__ec, "__thread_specific_ptr construction failed"); | |
| 185 | } | |
| 186 | ||
| 187 | template <class _Tp> | |
| 188 | __thread_specific_ptr<_Tp>::~__thread_specific_ptr() | |
| 189 | { | |
| 190 | // __thread_specific_ptr is only created with a static storage duration | |
| 191 | // so this destructor is only invoked during program termination. Invoking | |
| 192 | // pthread_key_delete(__key_) may prevent other threads from deleting their | |
| 193 | // thread local data. For this reason we leak the key. | |
| 194 | } | |
| 195 | ||
| 196 | template <class _Tp> | |
| 197 | void | |
| 198 | __thread_specific_ptr<_Tp>::set_pointer(pointer __p) | |
| 199 | { | |
| 200 | _LIBCPP_ASSERT(get() == nullptr, | |
| 201 | "Attempting to overwrite thread local data"); | |
| 202 | std::__libcpp_tls_set(__key_, __p); | |
| 203 | } | |
| 204 | ||
| 205 | template<> | |
| 206 | struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> | |
| 207 | : public __unary_function<__thread_id, size_t> | |
| 208 | { | |
| 209 | _LIBCPP_INLINE_VISIBILITY | |
| 210 | size_t operator()(__thread_id __v) const _NOEXCEPT | |
| 211 | { | |
| 212 | return hash<__libcpp_thread_id>()(__v.__id_); | |
| 213 | } | |
| 214 | }; | |
| 215 | ||
| 216 | template<class _CharT, class _Traits> | |
| 217 | _LIBCPP_INLINE_VISIBILITY | |
| 218 | basic_ostream<_CharT, _Traits>& | |
| 219 | operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) | |
| 220 | {return __os << __id.__id_;} | |
| 221 | ||
| 222 | class _LIBCPP_TYPE_VIS thread | |
| 223 | { | |
| 224 | __libcpp_thread_t __t_; | |
| 225 | ||
| 226 | thread(const thread&); | |
| 227 | thread& operator=(const thread&); | |
| 228 | public: | |
| 229 | typedef __thread_id id; | |
| 230 | typedef __libcpp_thread_t native_handle_type; | |
| 231 | ||
| 232 | _LIBCPP_INLINE_VISIBILITY | |
| 233 | thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} | |
| 234 | #ifndef _LIBCPP_CXX03_LANG | |
| 235 | template <class _Fp, class ..._Args, | |
| 236 | class = __enable_if_t<!is_same<__remove_cvref_t<_Fp>, thread>::value> > | |
| 237 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 238 | explicit thread(_Fp&& __f, _Args&&... __args); | |
| 239 | #else // _LIBCPP_CXX03_LANG | |
| 240 | template <class _Fp> | |
| 241 | _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS | |
| 242 | explicit thread(_Fp __f); | |
| 111 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) | |
| 112 | # include <cstddef> | |
| 113 | # include <ctime> | |
| 114 | # include <iosfwd> | |
| 115 | # include <ratio> | |
| 243 | 116 | #endif |
| 244 | ~thread(); | |
| 245 | ||
| 246 | _LIBCPP_INLINE_VISIBILITY | |
| 247 | thread(thread&& __t) _NOEXCEPT : __t_(__t.__t_) { | |
| 248 | __t.__t_ = _LIBCPP_NULL_THREAD; | |
| 249 | } | |
| 250 | ||
| 251 | _LIBCPP_INLINE_VISIBILITY | |
| 252 | thread& operator=(thread&& __t) _NOEXCEPT { | |
| 253 | if (!__libcpp_thread_isnull(&__t_)) | |
| 254 | terminate(); | |
| 255 | __t_ = __t.__t_; | |
| 256 | __t.__t_ = _LIBCPP_NULL_THREAD; | |
| 257 | return *this; | |
| 258 | } | |
| 259 | ||
| 260 | _LIBCPP_INLINE_VISIBILITY | |
| 261 | void swap(thread& __t) _NOEXCEPT {_VSTD::swap(__t_, __t.__t_);} | |
| 262 | ||
| 263 | _LIBCPP_INLINE_VISIBILITY | |
| 264 | bool joinable() const _NOEXCEPT {return !__libcpp_thread_isnull(&__t_);} | |
| 265 | void join(); | |
| 266 | void detach(); | |
| 267 | _LIBCPP_INLINE_VISIBILITY | |
| 268 | id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);} | |
| 269 | _LIBCPP_INLINE_VISIBILITY | |
| 270 | native_handle_type native_handle() _NOEXCEPT {return __t_;} | |
| 271 | ||
| 272 | static unsigned hardware_concurrency() _NOEXCEPT; | |
| 273 | }; | |
| 274 | ||
| 275 | #ifndef _LIBCPP_CXX03_LANG | |
| 276 | ||
| 277 | template <class _TSp, class _Fp, class ..._Args, size_t ..._Indices> | |
| 278 | inline _LIBCPP_INLINE_VISIBILITY | |
| 279 | void | |
| 280 | __thread_execute(tuple<_TSp, _Fp, _Args...>& __t, __tuple_indices<_Indices...>) | |
| 281 | { | |
| 282 | _VSTD::__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); | |
| 283 | } | |
| 284 | ||
| 285 | template <class _Fp> | |
| 286 | _LIBCPP_INLINE_VISIBILITY | |
| 287 | void* __thread_proxy(void* __vp) | |
| 288 | { | |
| 289 | // _Fp = tuple< unique_ptr<__thread_struct>, Functor, Args...> | |
| 290 | unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
| 291 | __thread_local_data().set_pointer(_VSTD::get<0>(*__p.get()).release()); | |
| 292 | typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 2>::type _Index; | |
| 293 | _VSTD::__thread_execute(*__p.get(), _Index()); | |
| 294 | return nullptr; | |
| 295 | } | |
| 296 | ||
| 297 | template <class _Fp, class ..._Args, | |
| 298 | class | |
| 299 | > | |
| 300 | thread::thread(_Fp&& __f, _Args&&... __args) | |
| 301 | { | |
| 302 | typedef unique_ptr<__thread_struct> _TSPtr; | |
| 303 | _TSPtr __tsp(new __thread_struct); | |
| 304 | typedef tuple<_TSPtr, typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; | |
| 305 | unique_ptr<_Gp> __p( | |
| 306 | new _Gp(_VSTD::move(__tsp), | |
| 307 | _VSTD::forward<_Fp>(__f), | |
| 308 | _VSTD::forward<_Args>(__args)...)); | |
| 309 | int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
| 310 | if (__ec == 0) | |
| 311 | __p.release(); | |
| 312 | else | |
| 313 | __throw_system_error(__ec, "thread constructor failed"); | |
| 314 | } | |
| 315 | ||
| 316 | #else // _LIBCPP_CXX03_LANG | |
| 317 | ||
| 318 | template <class _Fp> | |
| 319 | struct __thread_invoke_pair { | |
| 320 | // This type is used to pass memory for thread local storage and a functor | |
| 321 | // to a newly created thread because std::pair doesn't work with | |
| 322 | // std::unique_ptr in C++03. | |
| 323 | __thread_invoke_pair(_Fp& __f) : __tsp_(new __thread_struct), __fn_(__f) {} | |
| 324 | unique_ptr<__thread_struct> __tsp_; | |
| 325 | _Fp __fn_; | |
| 326 | }; | |
| 327 | ||
| 328 | template <class _Fp> | |
| 329 | _LIBCPP_HIDE_FROM_ABI void* __thread_proxy_cxx03(void* __vp) | |
| 330 | { | |
| 331 | unique_ptr<_Fp> __p(static_cast<_Fp*>(__vp)); | |
| 332 | __thread_local_data().set_pointer(__p->__tsp_.release()); | |
| 333 | (__p->__fn_)(); | |
| 334 | return nullptr; | |
| 335 | } | |
| 336 | ||
| 337 | template <class _Fp> | |
| 338 | thread::thread(_Fp __f) | |
| 339 | { | |
| 340 | ||
| 341 | typedef __thread_invoke_pair<_Fp> _InvokePair; | |
| 342 | typedef unique_ptr<_InvokePair> _PairPtr; | |
| 343 | _PairPtr __pp(new _InvokePair(__f)); | |
| 344 | int __ec = _VSTD::__libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get()); | |
| 345 | if (__ec == 0) | |
| 346 | __pp.release(); | |
| 347 | else | |
| 348 | __throw_system_error(__ec, "thread constructor failed"); | |
| 349 | } | |
| 350 | ||
| 351 | #endif // _LIBCPP_CXX03_LANG | |
| 352 | ||
| 353 | inline _LIBCPP_INLINE_VISIBILITY | |
| 354 | void swap(thread& __x, thread& __y) _NOEXCEPT {__x.swap(__y);} | |
| 355 | ||
| 356 | namespace this_thread | |
| 357 | { | |
| 358 | ||
| 359 | _LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& __ns); | |
| 360 | ||
| 361 | template <class _Rep, class _Period> | |
| 362 | _LIBCPP_HIDE_FROM_ABI void | |
| 363 | sleep_for(const chrono::duration<_Rep, _Period>& __d) | |
| 364 | { | |
| 365 | if (__d > chrono::duration<_Rep, _Period>::zero()) | |
| 366 | { | |
| 367 | // The standard guarantees a 64bit signed integer resolution for nanoseconds, | |
| 368 | // so use INT64_MAX / 1e9 as cut-off point. Use a constant to avoid <climits> | |
| 369 | // and issues with long double folding on PowerPC with GCC. | |
| 370 | _LIBCPP_CONSTEXPR chrono::duration<long double> _Max = | |
| 371 | chrono::duration<long double>(9223372036.0L); | |
| 372 | chrono::nanoseconds __ns; | |
| 373 | if (__d < _Max) | |
| 374 | { | |
| 375 | __ns = chrono::duration_cast<chrono::nanoseconds>(__d); | |
| 376 | if (__ns < __d) | |
| 377 | ++__ns; | |
| 378 | } | |
| 379 | else | |
| 380 | __ns = chrono::nanoseconds::max(); | |
| 381 | this_thread::sleep_for(__ns); | |
| 382 | } | |
| 383 | } | |
| 384 | ||
| 385 | template <class _Clock, class _Duration> | |
| 386 | _LIBCPP_HIDE_FROM_ABI void | |
| 387 | sleep_until(const chrono::time_point<_Clock, _Duration>& __t) | |
| 388 | { | |
| 389 | mutex __mut; | |
| 390 | condition_variable __cv; | |
| 391 | unique_lock<mutex> __lk(__mut); | |
| 392 | while (_Clock::now() < __t) | |
| 393 | __cv.wait_until(__lk, __t); | |
| 394 | } | |
| 395 | ||
| 396 | template <class _Duration> | |
| 397 | inline _LIBCPP_INLINE_VISIBILITY | |
| 398 | void | |
| 399 | sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t) | |
| 400 | { | |
| 401 | this_thread::sleep_for(__t - chrono::steady_clock::now()); | |
| 402 | } | |
| 403 | ||
| 404 | inline _LIBCPP_INLINE_VISIBILITY | |
| 405 | void yield() _NOEXCEPT {__libcpp_thread_yield();} | |
| 406 | ||
| 407 | } // namespace this_thread | |
| 408 | ||
| 409 | _LIBCPP_END_NAMESPACE_STD | |
| 410 | ||
| 411 | _LIBCPP_POP_MACROS | |
| 412 | 117 | |
| 413 | 118 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 17 |
| 414 | 119 | # include <chrono> |
| 415 | 120 | #endif |
| 416 | 121 | |
| 417 | 122 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 123 | # include <cstring> | |
| 418 | 124 | # include <functional> |
| 125 | # include <new> | |
| 126 | # include <system_error> | |
| 127 | # include <type_traits> | |
| 419 | 128 | #endif |
| 420 | 129 | |
| 421 | 130 | #endif // _LIBCPP_THREAD |
lib/libcxx/include/tuple+65-54| ... | ... | @@ -206,10 +206,18 @@ template <class... Types> |
| 206 | 206 | #include <__compare/synth_three_way.h> |
| 207 | 207 | #include <__config> |
| 208 | 208 | #include <__functional/invoke.h> |
| 209 | #include <__functional/unwrap_ref.h> | |
| 210 | 209 | #include <__fwd/array.h> |
| 210 | #include <__fwd/get.h> | |
| 211 | #include <__fwd/tuple.h> | |
| 211 | 212 | #include <__memory/allocator_arg_t.h> |
| 212 | 213 | #include <__memory/uses_allocator.h> |
| 214 | #include <__tuple/make_tuple_types.h> | |
| 215 | #include <__tuple/sfinae_helpers.h> | |
| 216 | #include <__tuple/tuple_element.h> | |
| 217 | #include <__tuple/tuple_indices.h> | |
| 218 | #include <__tuple/tuple_like_ext.h> | |
| 219 | #include <__tuple/tuple_size.h> | |
| 220 | #include <__tuple/tuple_types.h> | |
| 213 | 221 | #include <__type_traits/apply_cv.h> |
| 214 | 222 | #include <__type_traits/common_reference.h> |
| 215 | 223 | #include <__type_traits/common_type.h> |
| ... | ... | @@ -244,6 +252,7 @@ template <class... Types> |
| 244 | 252 | #include <__type_traits/negation.h> |
| 245 | 253 | #include <__type_traits/remove_cvref.h> |
| 246 | 254 | #include <__type_traits/remove_reference.h> |
| 255 | #include <__type_traits/unwrap_ref.h> | |
| 247 | 256 | #include <__utility/forward.h> |
| 248 | 257 | #include <__utility/integer_sequence.h> |
| 249 | 258 | #include <__utility/move.h> |
| ... | ... | @@ -262,6 +271,9 @@ template <class... Types> |
| 262 | 271 | # pragma GCC system_header |
| 263 | 272 | #endif |
| 264 | 273 | |
| 274 | _LIBCPP_PUSH_MACROS | |
| 275 | #include <__undef_macros> | |
| 276 | ||
| 265 | 277 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 266 | 278 | |
| 267 | 279 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -295,7 +307,7 @@ class __tuple_leaf |
| 295 | 307 | _Hp __value_; |
| 296 | 308 | |
| 297 | 309 | template <class _Tp> |
| 298 | static constexpr bool __can_bind_reference() { | |
| 310 | static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() { | |
| 299 | 311 | #if __has_keyword(__reference_binds_to_temporary) |
| 300 | 312 | return !__reference_binds_to_temporary(_Hp, _Tp); |
| 301 | 313 | #else |
| ... | ... | @@ -367,8 +379,8 @@ public: |
| 367 | 379 | {static_assert(!is_reference<_Hp>::value, |
| 368 | 380 | "Attempted to uses-allocator construct a reference element in a tuple");} |
| 369 | 381 | |
| 370 | __tuple_leaf(const __tuple_leaf& __t) = default; | |
| 371 | __tuple_leaf(__tuple_leaf&& __t) = default; | |
| 382 | _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default; | |
| 383 | _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default; | |
| 372 | 384 | |
| 373 | 385 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| 374 | 386 | int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) |
| ... | ... | @@ -865,7 +877,7 @@ public: |
| 865 | 877 | : __base_(allocator_arg_t(), __a, __t) |
| 866 | 878 | { } |
| 867 | 879 | |
| 868 | #if _LIBCPP_STD_VER > 20 | |
| 880 | #if _LIBCPP_STD_VER >= 23 | |
| 869 | 881 | // tuple(tuple<U...>&) constructors (including allocator_arg_t variants) |
| 870 | 882 | |
| 871 | 883 | template <class... _Up, enable_if_t< |
| ... | ... | @@ -879,7 +891,7 @@ public: |
| 879 | 891 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 880 | 892 | explicit(!(is_convertible_v<_Up&, _Tp> && ...)) |
| 881 | 893 | tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {} |
| 882 | #endif // _LIBCPP_STD_VER > 20 | |
| 894 | #endif // _LIBCPP_STD_VER >= 23 | |
| 883 | 895 | |
| 884 | 896 | // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants) |
| 885 | 897 | |
| ... | ... | @@ -929,7 +941,7 @@ public: |
| 929 | 941 | : __base_(allocator_arg_t(), __a, _VSTD::move(__t)) |
| 930 | 942 | { } |
| 931 | 943 | |
| 932 | #if _LIBCPP_STD_VER > 20 | |
| 944 | #if _LIBCPP_STD_VER >= 23 | |
| 933 | 945 | // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants) |
| 934 | 946 | |
| 935 | 947 | template <class... _Up, enable_if_t< |
| ... | ... | @@ -944,17 +956,17 @@ public: |
| 944 | 956 | explicit(!(is_convertible_v<const _Up&&, _Tp> && ...)) |
| 945 | 957 | tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t) |
| 946 | 958 | : __base_(allocator_arg_t(), __alloc, std::move(__t)) {} |
| 947 | #endif // _LIBCPP_STD_VER > 20 | |
| 959 | #endif // _LIBCPP_STD_VER >= 23 | |
| 948 | 960 | |
| 949 | 961 | // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants) |
| 950 | 962 | |
| 951 | template <template <class...> class Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple> | |
| 963 | template <template <class...> class _Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple> | |
| 952 | 964 | struct _CtorPredicateFromPair : false_type{}; |
| 953 | 965 | |
| 954 | template <template <class...> class Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> | |
| 955 | struct _CtorPredicateFromPair<Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And< | |
| 956 | Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >, | |
| 957 | Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> > | |
| 966 | template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> | |
| 967 | struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And< | |
| 968 | _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >, | |
| 969 | _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> > | |
| 958 | 970 | > {}; |
| 959 | 971 | |
| 960 | 972 | template <class _Pair> |
| ... | ... | @@ -1018,7 +1030,7 @@ public: |
| 1018 | 1030 | : __base_(allocator_arg_t(), __a, __p) |
| 1019 | 1031 | { } |
| 1020 | 1032 | |
| 1021 | #if _LIBCPP_STD_VER > 20 | |
| 1033 | #if _LIBCPP_STD_VER >= 23 | |
| 1022 | 1034 | // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants) |
| 1023 | 1035 | |
| 1024 | 1036 | template <class _U1, class _U2, enable_if_t< |
| ... | ... | @@ -1082,7 +1094,7 @@ public: |
| 1082 | 1094 | : __base_(allocator_arg_t(), __a, _VSTD::move(__p)) |
| 1083 | 1095 | { } |
| 1084 | 1096 | |
| 1085 | #if _LIBCPP_STD_VER > 20 | |
| 1097 | #if _LIBCPP_STD_VER >= 23 | |
| 1086 | 1098 | // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants) |
| 1087 | 1099 | |
| 1088 | 1100 | template <class _U1, class _U2, enable_if_t< |
| ... | ... | @@ -1097,7 +1109,7 @@ public: |
| 1097 | 1109 | explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value) |
| 1098 | 1110 | tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p) |
| 1099 | 1111 | : __base_(allocator_arg_t(), __alloc, std::move(__p)) {} |
| 1100 | #endif // _LIBCPP_STD_VER > 20 | |
| 1112 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1101 | 1113 | |
| 1102 | 1114 | // [tuple.assign] |
| 1103 | 1115 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| ... | ... | @@ -1109,7 +1121,7 @@ public: |
| 1109 | 1121 | return *this; |
| 1110 | 1122 | } |
| 1111 | 1123 | |
| 1112 | #if _LIBCPP_STD_VER > 20 | |
| 1124 | #if _LIBCPP_STD_VER >= 23 | |
| 1113 | 1125 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 1114 | 1126 | const tuple& operator=(tuple const& __tuple) const |
| 1115 | 1127 | requires (_And<is_copy_assignable<const _Tp>...>::value) { |
| ... | ... | @@ -1126,7 +1138,7 @@ public: |
| 1126 | 1138 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
| 1127 | 1139 | return *this; |
| 1128 | 1140 | } |
| 1129 | #endif // _LIBCPP_STD_VER > 20 | |
| 1141 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1130 | 1142 | |
| 1131 | 1143 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1132 | 1144 | tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple) |
| ... | ... | @@ -1170,7 +1182,7 @@ public: |
| 1170 | 1182 | } |
| 1171 | 1183 | |
| 1172 | 1184 | |
| 1173 | #if _LIBCPP_STD_VER > 20 | |
| 1185 | #if _LIBCPP_STD_VER >= 23 | |
| 1174 | 1186 | template <class... _UTypes, enable_if_t< |
| 1175 | 1187 | _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>, |
| 1176 | 1188 | is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr> |
| ... | ... | @@ -1193,17 +1205,17 @@ public: |
| 1193 | 1205 | typename __make_tuple_indices<sizeof...(_Tp)>::type()); |
| 1194 | 1206 | return *this; |
| 1195 | 1207 | } |
| 1196 | #endif // _LIBCPP_STD_VER > 20 | |
| 1208 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1197 | 1209 | |
| 1198 | template <template<class...> class Pred, bool _Const, | |
| 1210 | template <template<class...> class _Pred, bool _Const, | |
| 1199 | 1211 | class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple> |
| 1200 | 1212 | struct _AssignPredicateFromPair : false_type {}; |
| 1201 | 1213 | |
| 1202 | template <template<class...> class Pred, bool _Const, | |
| 1214 | template <template<class...> class _Pred, bool _Const, | |
| 1203 | 1215 | class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2> |
| 1204 | struct _AssignPredicateFromPair<Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : | |
| 1205 | _And<Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >, | |
| 1206 | Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> > | |
| 1216 | struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : | |
| 1217 | _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >, | |
| 1218 | _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> > | |
| 1207 | 1219 | > {}; |
| 1208 | 1220 | |
| 1209 | 1221 | template <bool _Const, class _Pair> |
| ... | ... | @@ -1212,7 +1224,7 @@ public: |
| 1212 | 1224 | template <bool _Const, class _Pair> |
| 1213 | 1225 | struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {}; |
| 1214 | 1226 | |
| 1215 | #if _LIBCPP_STD_VER > 20 | |
| 1227 | #if _LIBCPP_STD_VER >= 23 | |
| 1216 | 1228 | template <class _U1, class _U2, enable_if_t< |
| 1217 | 1229 | _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr> |
| 1218 | 1230 | _LIBCPP_HIDE_FROM_ABI constexpr |
| ... | ... | @@ -1232,7 +1244,7 @@ public: |
| 1232 | 1244 | std::get<1>(*this) = std::move(__pair.second); |
| 1233 | 1245 | return *this; |
| 1234 | 1246 | } |
| 1235 | #endif // _LIBCPP_STD_VER > 20 | |
| 1247 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1236 | 1248 | |
| 1237 | 1249 | template<class _Up1, class _Up2, __enable_if_t< |
| 1238 | 1250 | _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value |
| ... | ... | @@ -1296,20 +1308,19 @@ public: |
| 1296 | 1308 | void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
| 1297 | 1309 | {__base_.swap(__t.__base_);} |
| 1298 | 1310 | |
| 1299 | #if _LIBCPP_STD_VER > 20 | |
| 1311 | #if _LIBCPP_STD_VER >= 23 | |
| 1300 | 1312 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 1301 | 1313 | void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) { |
| 1302 | 1314 | __base_.swap(__t.__base_); |
| 1303 | 1315 | } |
| 1304 | #endif // _LIBCPP_STD_VER > 20 | |
| 1316 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1305 | 1317 | }; |
| 1306 | 1318 | |
| 1307 | 1319 | template <> |
| 1308 | 1320 | class _LIBCPP_TEMPLATE_VIS tuple<> |
| 1309 | 1321 | { |
| 1310 | 1322 | public: |
| 1311 | _LIBCPP_INLINE_VISIBILITY constexpr | |
| 1312 | tuple() _NOEXCEPT = default; | |
| 1323 | constexpr tuple() _NOEXCEPT = default; | |
| 1313 | 1324 | template <class _Alloc> |
| 1314 | 1325 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1315 | 1326 | tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {} |
| ... | ... | @@ -1324,12 +1335,12 @@ public: |
| 1324 | 1335 | tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {} |
| 1325 | 1336 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1326 | 1337 | void swap(tuple&) _NOEXCEPT {} |
| 1327 | #if _LIBCPP_STD_VER > 20 | |
| 1338 | #if _LIBCPP_STD_VER >= 23 | |
| 1328 | 1339 | _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {} |
| 1329 | 1340 | #endif |
| 1330 | 1341 | }; |
| 1331 | 1342 | |
| 1332 | #if _LIBCPP_STD_VER > 20 | |
| 1343 | #if _LIBCPP_STD_VER >= 23 | |
| 1333 | 1344 | template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual> |
| 1334 | 1345 | requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } |
| 1335 | 1346 | struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> { |
| ... | ... | @@ -1341,9 +1352,9 @@ template <class... _TTypes, class... _UTypes> |
| 1341 | 1352 | struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> { |
| 1342 | 1353 | using type = tuple<common_type_t<_TTypes, _UTypes>...>; |
| 1343 | 1354 | }; |
| 1344 | #endif // _LIBCPP_STD_VER > 20 | |
| 1355 | #endif // _LIBCPP_STD_VER >= 23 | |
| 1345 | 1356 | |
| 1346 | #if _LIBCPP_STD_VER > 14 | |
| 1357 | #if _LIBCPP_STD_VER >= 17 | |
| 1347 | 1358 | template <class ..._Tp> |
| 1348 | 1359 | tuple(_Tp...) -> tuple<_Tp...>; |
| 1349 | 1360 | template <class _Tp1, class _Tp2> |
| ... | ... | @@ -1363,7 +1374,7 @@ swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) |
| 1363 | 1374 | _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) |
| 1364 | 1375 | {__t.swap(__u);} |
| 1365 | 1376 | |
| 1366 | #if _LIBCPP_STD_VER > 20 | |
| 1377 | #if _LIBCPP_STD_VER >= 23 | |
| 1367 | 1378 | template <class... _Tp> |
| 1368 | 1379 | _LIBCPP_HIDE_FROM_ABI constexpr |
| 1369 | 1380 | enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void> |
| ... | ... | @@ -1413,7 +1424,7 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT |
| 1413 | 1424 | static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get()); |
| 1414 | 1425 | } |
| 1415 | 1426 | |
| 1416 | #if _LIBCPP_STD_VER > 11 | |
| 1427 | #if _LIBCPP_STD_VER >= 14 | |
| 1417 | 1428 | |
| 1418 | 1429 | namespace __find_detail { |
| 1419 | 1430 | |
| ... | ... | @@ -1501,9 +1512,13 @@ struct __ignore_t |
| 1501 | 1512 | const __ignore_t& operator=(_Tp&&) const {return *this;} |
| 1502 | 1513 | }; |
| 1503 | 1514 | |
| 1515 | # if _LIBCPP_STD_VER >= 17 | |
| 1516 | inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); | |
| 1517 | # else | |
| 1504 | 1518 | namespace { |
| 1505 | 1519 | constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); |
| 1506 | 1520 | } // namespace |
| 1521 | # endif | |
| 1507 | 1522 | |
| 1508 | 1523 | template <class... _Tp> |
| 1509 | 1524 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| ... | ... | @@ -1552,7 +1567,7 @@ operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
| 1552 | 1567 | return __tuple_equal<sizeof...(_Tp)>()(__x, __y); |
| 1553 | 1568 | } |
| 1554 | 1569 | |
| 1555 | #if _LIBCPP_STD_VER > 17 | |
| 1570 | #if _LIBCPP_STD_VER >= 20 | |
| 1556 | 1571 | |
| 1557 | 1572 | // operator<=> |
| 1558 | 1573 | |
| ... | ... | @@ -1574,7 +1589,7 @@ operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
| 1574 | 1589 | return _VSTD::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{}); |
| 1575 | 1590 | } |
| 1576 | 1591 | |
| 1577 | #else // _LIBCPP_STD_VER > 17 | |
| 1592 | #else // _LIBCPP_STD_VER >= 20 | |
| 1578 | 1593 | |
| 1579 | 1594 | template <class ..._Tp, class ..._Up> |
| 1580 | 1595 | inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 |
| ... | ... | @@ -1644,7 +1659,7 @@ operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) |
| 1644 | 1659 | return !(__y < __x); |
| 1645 | 1660 | } |
| 1646 | 1661 | |
| 1647 | #endif // _LIBCPP_STD_VER > 17 | |
| 1662 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1648 | 1663 | |
| 1649 | 1664 | // tuple_cat |
| 1650 | 1665 | |
| ... | ... | @@ -1712,17 +1727,15 @@ template <class ..._Types, size_t ..._I0, class _Tuple0> |
| 1712 | 1727 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> |
| 1713 | 1728 | { |
| 1714 | 1729 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0; |
| 1715 | typedef tuple<_Types..., typename __apply_cv<_Tuple0, | |
| 1716 | typename tuple_element<_I0, _T0>::type>::type&&...> type; | |
| 1730 | typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type; | |
| 1717 | 1731 | }; |
| 1718 | 1732 | |
| 1719 | 1733 | template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples> |
| 1720 | 1734 | struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, |
| 1721 | 1735 | _Tuple0, _Tuple1, _Tuples...> |
| 1722 | 1736 | : public __tuple_cat_return_ref_imp< |
| 1723 | tuple<_Types..., typename __apply_cv<_Tuple0, | |
| 1724 | typename tuple_element<_I0, | |
| 1725 | __libcpp_remove_reference_t<_Tuple0> >::type>::type&&...>, | |
| 1737 | tuple<_Types..., __apply_cv_t<_Tuple0, | |
| 1738 | typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>, | |
| 1726 | 1739 | typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type, |
| 1727 | 1740 | _Tuple1, _Tuples...> |
| 1728 | 1741 | { |
| ... | ... | @@ -1762,13 +1775,9 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J |
| 1762 | 1775 | (void)__t; // avoid unused parameter warning on GCC when _I0 is empty |
| 1763 | 1776 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0; |
| 1764 | 1777 | typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1; |
| 1765 | return __tuple_cat< | |
| 1766 | tuple<_Types..., | |
| 1767 | typename __apply_cv<_Tuple0, typename tuple_element< | |
| 1768 | _J0, _T0>::type>::type&&...>, | |
| 1769 | typename __make_tuple_indices<sizeof...(_Types) + | |
| 1770 | tuple_size<_T0>::value>::type, | |
| 1771 | typename __make_tuple_indices<tuple_size<_T1>::value>::type>()( | |
| 1778 | return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>, | |
| 1779 | typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type, | |
| 1780 | typename __make_tuple_indices<tuple_size<_T1>::value>::type>()( | |
| 1772 | 1781 | _VSTD::forward_as_tuple( |
| 1773 | 1782 | _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))..., |
| 1774 | 1783 | _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...), |
| ... | ... | @@ -1803,7 +1812,7 @@ pair<_T1, _T2>::pair(piecewise_construct_t, |
| 1803 | 1812 | { |
| 1804 | 1813 | } |
| 1805 | 1814 | |
| 1806 | #if _LIBCPP_STD_VER > 14 | |
| 1815 | #if _LIBCPP_STD_VER >= 17 | |
| 1807 | 1816 | template <class _Tp> |
| 1808 | 1817 | inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; |
| 1809 | 1818 | |
| ... | ... | @@ -1845,12 +1854,14 @@ _LIBCPP_NOEXCEPT_RETURN( |
| 1845 | 1854 | |
| 1846 | 1855 | #undef _LIBCPP_NOEXCEPT_RETURN |
| 1847 | 1856 | |
| 1848 | #endif // _LIBCPP_STD_VER > 14 | |
| 1857 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1849 | 1858 | |
| 1850 | 1859 | #endif // !defined(_LIBCPP_CXX03_LANG) |
| 1851 | 1860 | |
| 1852 | 1861 | _LIBCPP_END_NAMESPACE_STD |
| 1853 | 1862 | |
| 1863 | _LIBCPP_POP_MACROS | |
| 1864 | ||
| 1854 | 1865 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1855 | 1866 | # include <exception> |
| 1856 | 1867 | # include <iosfwd> |
lib/libcxx/include/type_traits+4-3| ... | ... | @@ -51,7 +51,7 @@ namespace std |
| 51 | 51 | template <class T> struct is_arithmetic; |
| 52 | 52 | template <class T> struct is_fundamental; |
| 53 | 53 | template <class T> struct is_member_pointer; |
| 54 | template <class T> struct is_scoped_enum; // C++2b | |
| 54 | template <class T> struct is_scoped_enum; // C++23 | |
| 55 | 55 | template <class T> struct is_scalar; |
| 56 | 56 | template <class T> struct is_object; |
| 57 | 57 | template <class T> struct is_compound; |
| ... | ... | @@ -286,7 +286,7 @@ namespace std |
| 286 | 286 | template <class T> inline constexpr bool is_member_pointer_v |
| 287 | 287 | = is_member_pointer<T>::value; // C++17 |
| 288 | 288 | template <class T> inline constexpr bool is_scoped_enum_v |
| 289 | = is_scoped_enum<T>::value; // C++2b | |
| 289 | = is_scoped_enum<T>::value; // C++23 | |
| 290 | 290 | |
| 291 | 291 | // See C++14 20.10.4.3, type properties |
| 292 | 292 | template <class T> inline constexpr bool is_const_v |
| ... | ... | @@ -418,7 +418,6 @@ namespace std |
| 418 | 418 | */ |
| 419 | 419 | #include <__assert> // all public C++ headers provide the assertion handler |
| 420 | 420 | #include <__config> |
| 421 | #include <__functional/invoke.h> | |
| 422 | 421 | #include <__fwd/hash.h> // This is https://llvm.org/PR56938 |
| 423 | 422 | #include <__type_traits/add_const.h> |
| 424 | 423 | #include <__type_traits/add_cv.h> |
| ... | ... | @@ -443,6 +442,7 @@ namespace std |
| 443 | 442 | #include <__type_traits/has_unique_object_representation.h> |
| 444 | 443 | #include <__type_traits/has_virtual_destructor.h> |
| 445 | 444 | #include <__type_traits/integral_constant.h> |
| 445 | #include <__type_traits/invoke.h> | |
| 446 | 446 | #include <__type_traits/is_abstract.h> |
| 447 | 447 | #include <__type_traits/is_aggregate.h> |
| 448 | 448 | #include <__type_traits/is_arithmetic.h> |
| ... | ... | @@ -532,6 +532,7 @@ namespace std |
| 532 | 532 | #include <__type_traits/result_of.h> |
| 533 | 533 | #include <__type_traits/type_identity.h> |
| 534 | 534 | #include <__type_traits/underlying_type.h> |
| 535 | #include <__type_traits/unwrap_ref.h> | |
| 535 | 536 | #include <__type_traits/void_t.h> |
| 536 | 537 | #include <__utility/declval.h> |
| 537 | 538 | #include <cstddef> |
lib/libcxx/include/typeindex+1-1| ... | ... | @@ -87,7 +87,7 @@ public: |
| 87 | 87 | _LIBCPP_INLINE_VISIBILITY |
| 88 | 88 | bool operator>=(const type_index& __y) const _NOEXCEPT |
| 89 | 89 | {return !__t_->before(*__y.__t_);} |
| 90 | #if _LIBCPP_STD_VER > 17 | |
| 90 | #if _LIBCPP_STD_VER >= 20 | |
| 91 | 91 | _LIBCPP_HIDE_FROM_ABI |
| 92 | 92 | strong_ordering operator<=>(const type_index& __y) const noexcept { |
| 93 | 93 | if (*__t_ == *__y.__t_) |
lib/libcxx/include/typeinfo+32-16| ... | ... | @@ -7,8 +7,8 @@ |
| 7 | 7 | // |
| 8 | 8 | //===----------------------------------------------------------------------===// |
| 9 | 9 | |
| 10 | #ifndef __LIBCPP_TYPEINFO | |
| 11 | #define __LIBCPP_TYPEINFO | |
| 10 | #ifndef _LIBCPP_TYPEINFO | |
| 11 | #define _LIBCPP_TYPEINFO | |
| 12 | 12 | |
| 13 | 13 | /* |
| 14 | 14 | |
| ... | ... | @@ -21,7 +21,7 @@ class type_info |
| 21 | 21 | public: |
| 22 | 22 | virtual ~type_info(); |
| 23 | 23 | |
| 24 | bool operator==(const type_info& rhs) const noexcept; | |
| 24 | bool operator==(const type_info& rhs) const noexcept; // constexpr since C++23 | |
| 25 | 25 | bool operator!=(const type_info& rhs) const noexcept; // removed in C++20 |
| 26 | 26 | |
| 27 | 27 | bool before(const type_info& rhs) const noexcept; |
| ... | ... | @@ -59,11 +59,11 @@ public: |
| 59 | 59 | #include <__assert> // all public C++ headers provide the assertion handler |
| 60 | 60 | #include <__availability> |
| 61 | 61 | #include <__config> |
| 62 | #include <__exception/exception.h> | |
| 63 | #include <__type_traits/is_constant_evaluated.h> | |
| 64 | #include <__verbose_abort> | |
| 62 | 65 | #include <cstddef> |
| 63 | 66 | #include <cstdint> |
| 64 | #include <cstdlib> | |
| 65 | #include <exception> | |
| 66 | #include <type_traits> | |
| 67 | 67 | |
| 68 | 68 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 69 | 69 | # pragma GCC system_header |
| ... | ... | @@ -79,7 +79,7 @@ namespace std // purposefully not using versioning namespace |
| 79 | 79 | |
| 80 | 80 | #if defined(_LIBCPP_ABI_MICROSOFT) |
| 81 | 81 | |
| 82 | class _LIBCPP_EXCEPTION_ABI type_info | |
| 82 | class _LIBCPP_EXPORTED_FROM_ABI type_info | |
| 83 | 83 | { |
| 84 | 84 | type_info& operator=(const type_info&); |
| 85 | 85 | type_info(const type_info&); |
| ... | ... | @@ -104,8 +104,13 @@ public: |
| 104 | 104 | |
| 105 | 105 | size_t hash_code() const _NOEXCEPT; |
| 106 | 106 | |
| 107 | _LIBCPP_INLINE_VISIBILITY | |
| 107 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 108 | 108 | bool operator==(const type_info& __arg) const _NOEXCEPT { |
| 109 | // When evaluated in a constant expression, both type infos simply can't come | |
| 110 | // from different translation units, so it is sufficient to compare their addresses. | |
| 111 | if (__libcpp_is_constant_evaluated()) { | |
| 112 | return this == &__arg; | |
| 113 | } | |
| 109 | 114 | return __compare(__arg) == 0; |
| 110 | 115 | } |
| 111 | 116 | |
| ... | ... | @@ -294,7 +299,7 @@ struct __type_info_implementations { |
| 294 | 299 | __impl; |
| 295 | 300 | }; |
| 296 | 301 | |
| 297 | class _LIBCPP_EXCEPTION_ABI type_info | |
| 302 | class _LIBCPP_EXPORTED_FROM_ABI type_info | |
| 298 | 303 | { |
| 299 | 304 | type_info& operator=(const type_info&); |
| 300 | 305 | type_info(const type_info&); |
| ... | ... | @@ -330,9 +335,14 @@ public: |
| 330 | 335 | return __impl::__hash(__type_name); |
| 331 | 336 | } |
| 332 | 337 | |
| 333 | _LIBCPP_INLINE_VISIBILITY | |
| 338 | _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23 | |
| 334 | 339 | bool operator==(const type_info& __arg) const _NOEXCEPT |
| 335 | 340 | { |
| 341 | // When evaluated in a constant expression, both type infos simply can't come | |
| 342 | // from different translation units, so it is sufficient to compare their addresses. | |
| 343 | if (__libcpp_is_constant_evaluated()) { | |
| 344 | return this == &__arg; | |
| 345 | } | |
| 336 | 346 | return __impl::__eq(__type_name, __arg.__type_name); |
| 337 | 347 | } |
| 338 | 348 | |
| ... | ... | @@ -344,17 +354,17 @@ public: |
| 344 | 354 | }; |
| 345 | 355 | #endif // defined(_LIBCPP_ABI_MICROSOFT) |
| 346 | 356 | |
| 347 | class _LIBCPP_EXCEPTION_ABI bad_cast | |
| 357 | class _LIBCPP_EXPORTED_FROM_ABI bad_cast | |
| 348 | 358 | : public exception |
| 349 | 359 | { |
| 350 | 360 | public: |
| 351 | 361 | bad_cast() _NOEXCEPT; |
| 352 | bad_cast(const bad_cast&) _NOEXCEPT = default; | |
| 362 | _LIBCPP_HIDE_FROM_ABI bad_cast(const bad_cast&) _NOEXCEPT = default; | |
| 353 | 363 | ~bad_cast() _NOEXCEPT override; |
| 354 | 364 | const char* what() const _NOEXCEPT override; |
| 355 | 365 | }; |
| 356 | 366 | |
| 357 | class _LIBCPP_EXCEPTION_ABI bad_typeid | |
| 367 | class _LIBCPP_EXPORTED_FROM_ABI bad_typeid | |
| 358 | 368 | : public exception |
| 359 | 369 | { |
| 360 | 370 | public: |
| ... | ... | @@ -395,12 +405,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 395 | 405 | _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY |
| 396 | 406 | void __throw_bad_cast() |
| 397 | 407 | { |
| 398 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 408 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 399 | 409 | throw bad_cast(); |
| 400 | 410 | #else |
| 401 | _VSTD::abort(); | |
| 411 | _LIBCPP_VERBOSE_ABORT("bad_cast was thrown in -fno-exceptions mode"); | |
| 402 | 412 | #endif |
| 403 | 413 | } |
| 404 | 414 | _LIBCPP_END_NAMESPACE_STD |
| 405 | 415 | |
| 406 | #endif // __LIBCPP_TYPEINFO | |
| 416 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 | |
| 417 | # include <cstdlib> | |
| 418 | # include <exception> | |
| 419 | # include <type_traits> | |
| 420 | #endif | |
| 421 | ||
| 422 | #endif // _LIBCPP_TYPEINFO |
lib/libcxx/include/uchar.h+3-1| ... | ... | @@ -42,10 +42,12 @@ size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps); |
| 42 | 42 | |
| 43 | 43 | // Some platforms don't implement <uchar.h> and we don't want to give a hard |
| 44 | 44 | // error on those platforms. When the platform doesn't provide <uchar.h>, at |
| 45 | // least include <stddef.h> so we get the declaration for size_t. | |
| 45 | // least include <stddef.h> so we get the declaration for size_t, and try to | |
| 46 | // get the declaration of mbstate_t too. | |
| 46 | 47 | #if __has_include_next(<uchar.h>) |
| 47 | 48 | # include_next <uchar.h> |
| 48 | 49 | #else |
| 50 | # include <__mbstate_t.h> | |
| 49 | 51 | # include <stddef.h> |
| 50 | 52 | #endif |
| 51 | 53 |
lib/libcxx/include/unordered_map+343-191| ... | ... | @@ -59,6 +59,11 @@ public: |
| 59 | 59 | size_type n = 0, const hasher& hf = hasher(), |
| 60 | 60 | const key_equal& eql = key_equal(), |
| 61 | 61 | const allocator_type& a = allocator_type()); |
| 62 | template<container-compatible-range<value_type> R> | |
| 63 | unordered_map(from_range_t, R&& rg, size_type n = see below, | |
| 64 | const hasher& hf = hasher(), const key_equal& eql = key_equal(), | |
| 65 | const allocator_type& a = allocator_type()); // C++23 | |
| 66 | ||
| 62 | 67 | explicit unordered_map(const allocator_type&); |
| 63 | 68 | unordered_map(const unordered_map&); |
| 64 | 69 | unordered_map(const unordered_map&, const Allocator&); |
| ... | ... | @@ -82,6 +87,12 @@ public: |
| 82 | 87 | unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, |
| 83 | 88 | const allocator_type& a) |
| 84 | 89 | : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 |
| 90 | template<container-compatible-range<value_type> R> | |
| 91 | unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) | |
| 92 | : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 | |
| 93 | template<container-compatible-range<value_type> R> | |
| 94 | unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) | |
| 95 | : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 | |
| 85 | 96 | unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a) |
| 86 | 97 | : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 |
| 87 | 98 | unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, |
| ... | ... | @@ -122,6 +133,8 @@ public: |
| 122 | 133 | iterator insert(const_iterator hint, P&& obj); |
| 123 | 134 | template <class InputIterator> |
| 124 | 135 | void insert(InputIterator first, InputIterator last); |
| 136 | template<container-compatible-range<value_type> R> | |
| 137 | void insert_range(R&& rg); // C++23 | |
| 125 | 138 | void insert(initializer_list<value_type>); |
| 126 | 139 | |
| 127 | 140 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -224,6 +237,13 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type = see |
| 224 | 237 | -> unordered_map<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred, |
| 225 | 238 | Allocator>; // C++17 |
| 226 | 239 | |
| 240 | template<ranges::input_range R, class Hash = hash<range-key-type<R>>, | |
| 241 | class Pred = equal_to<range-key-type<R>>, | |
| 242 | class Allocator = allocator<range-to-alloc-type<R>>> | |
| 243 | unordered_map(from_range_t, R&&, typename see below::size_type = see below, | |
| 244 | Hash = Hash(), Pred = Pred(), Allocator = Allocator()) | |
| 245 | -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23 | |
| 246 | ||
| 227 | 247 | template<class Key, class T, class Hash = hash<Key>, |
| 228 | 248 | class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> |
| 229 | 249 | unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type = see below, |
| ... | ... | @@ -245,6 +265,21 @@ unordered_map(InputIterator, InputIterator, typename see below::size_type, Hash, |
| 245 | 265 | -> unordered_map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash, |
| 246 | 266 | equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 |
| 247 | 267 | |
| 268 | template<ranges::input_range R, class Allocator> | |
| 269 | unordered_map(from_range_t, R&&, typename see below::size_type, Allocator) | |
| 270 | -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>, | |
| 271 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 272 | ||
| 273 | template<ranges::input_range R, class Allocator> | |
| 274 | unordered_map(from_range_t, R&&, Allocator) | |
| 275 | -> unordered_map<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>, | |
| 276 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 277 | ||
| 278 | template<ranges::input_range R, class Hash, class Allocator> | |
| 279 | unordered_map(from_range_t, R&&, typename see below::size_type, Hash, Allocator) | |
| 280 | -> unordered_map<range-key-type<R>, range-mapped-type<R>, Hash, | |
| 281 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 282 | ||
| 248 | 283 | template<class Key, class T, typename Allocator> |
| 249 | 284 | unordered_map(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator) |
| 250 | 285 | -> unordered_map<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 |
| ... | ... | @@ -270,7 +305,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> |
| 270 | 305 | template <class Key, class T, class Hash, class Pred, class Alloc> |
| 271 | 306 | bool |
| 272 | 307 | operator!=(const unordered_map<Key, T, Hash, Pred, Alloc>& x, |
| 273 | const unordered_map<Key, T, Hash, Pred, Alloc>& y); | |
| 308 | const unordered_map<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20 | |
| 274 | 309 | |
| 275 | 310 | template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>, |
| 276 | 311 | class Alloc = allocator<pair<const Key, T>>> |
| ... | ... | @@ -311,6 +346,10 @@ public: |
| 311 | 346 | size_type n = 0, const hasher& hf = hasher(), |
| 312 | 347 | const key_equal& eql = key_equal(), |
| 313 | 348 | const allocator_type& a = allocator_type()); |
| 349 | template<container-compatible-range<value_type> R> | |
| 350 | unordered_multimap(from_range_t, R&& rg, size_type n = see below, | |
| 351 | const hasher& hf = hasher(), const key_equal& eql = key_equal(), | |
| 352 | const allocator_type& a = allocator_type()); // C++23 | |
| 314 | 353 | explicit unordered_multimap(const allocator_type&); |
| 315 | 354 | unordered_multimap(const unordered_multimap&); |
| 316 | 355 | unordered_multimap(const unordered_multimap&, const Allocator&); |
| ... | ... | @@ -334,6 +373,12 @@ public: |
| 334 | 373 | unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, |
| 335 | 374 | const allocator_type& a) |
| 336 | 375 | : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 |
| 376 | template<container-compatible-range<value_type> R> | |
| 377 | unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) | |
| 378 | : unordered_multimap(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 | |
| 379 | template<container-compatible-range<value_type> R> | |
| 380 | unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) | |
| 381 | : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 | |
| 337 | 382 | unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a) |
| 338 | 383 | : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 |
| 339 | 384 | unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, |
| ... | ... | @@ -374,6 +419,8 @@ public: |
| 374 | 419 | iterator insert(const_iterator hint, P&& obj); |
| 375 | 420 | template <class InputIterator> |
| 376 | 421 | void insert(InputIterator first, InputIterator last); |
| 422 | template<container-compatible-range<value_type> R> | |
| 423 | void insert_range(R&& rg); // C++23 | |
| 377 | 424 | void insert(initializer_list<value_type>); |
| 378 | 425 | |
| 379 | 426 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -453,6 +500,13 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type = |
| 453 | 500 | -> unordered_multimap<iter_key_t<InputIterator>, iter_value_t<InputIterator>, Hash, Pred, |
| 454 | 501 | Allocator>; // C++17 |
| 455 | 502 | |
| 503 | template<ranges::input_range R, class Hash = hash<range-key-type<R>>, | |
| 504 | class Pred = equal_to<range-key-type<R>>, | |
| 505 | class Allocator = allocator<range-to-alloc-type<R>>> | |
| 506 | unordered_multimap(from_range_t, R&&, typename see below::size_type = see below, | |
| 507 | Hash = Hash(), Pred = Pred(), Allocator = Allocator()) | |
| 508 | -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash, Pred, Allocator>; // C++23 | |
| 509 | ||
| 456 | 510 | template<class Key, class T, class Hash = hash<Key>, |
| 457 | 511 | class Pred = equal_to<Key>, class Allocator = allocator<pair<const Key, T>>> |
| 458 | 512 | unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type = see below, |
| ... | ... | @@ -474,6 +528,21 @@ unordered_multimap(InputIterator, InputIterator, typename see below::size_type, |
| 474 | 528 | -> unordered_multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Hash, |
| 475 | 529 | equal_to<iter_key_t<InputIterator>>, Allocator>; // C++17 |
| 476 | 530 | |
| 531 | template<ranges::input_range R, class Allocator> | |
| 532 | unordered_multimap(from_range_t, R&&, typename see below::size_type, Allocator) | |
| 533 | -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>, | |
| 534 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 535 | ||
| 536 | template<ranges::input_range R, class Allocator> | |
| 537 | unordered_multimap(from_range_t, R&&, Allocator) | |
| 538 | -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, hash<range-key-type<R>>, | |
| 539 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 540 | ||
| 541 | template<ranges::input_range R, class Hash, class Allocator> | |
| 542 | unordered_multimap(from_range_t, R&&, typename see below::size_type, Hash, Allocator) | |
| 543 | -> unordered_multimap<range-key-type<R>, range-mapped-type<R>, Hash, | |
| 544 | equal_to<range-key-type<R>>, Allocator>; // C++23 | |
| 545 | ||
| 477 | 546 | template<class Key, class T, typename Allocator> |
| 478 | 547 | unordered_multimap(initializer_list<pair<const Key, T>>, typename see below::size_type, Allocator) |
| 479 | 548 | -> unordered_multimap<Key, T, hash<Key>, equal_to<Key>, Allocator>; // C++17 |
| ... | ... | @@ -508,7 +577,7 @@ template <class Key, class T, class Hash, class Pred, class Alloc> |
| 508 | 577 | template <class Key, class T, class Hash, class Pred, class Alloc> |
| 509 | 578 | bool |
| 510 | 579 | operator!=(const unordered_multimap<Key, T, Hash, Pred, Alloc>& x, |
| 511 | const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); | |
| 580 | const unordered_multimap<Key, T, Hash, Pred, Alloc>& y); // Removed in C++20 | |
| 512 | 581 | |
| 513 | 582 | } // std |
| 514 | 583 | |
| ... | ... | @@ -516,19 +585,24 @@ template <class Key, class T, class Hash, class Pred, class Alloc> |
| 516 | 585 | |
| 517 | 586 | #include <__algorithm/is_permutation.h> |
| 518 | 587 | #include <__assert> // all public C++ headers provide the assertion handler |
| 588 | #include <__availability> | |
| 519 | 589 | #include <__config> |
| 520 | #include <__debug> | |
| 521 | 590 | #include <__functional/is_transparent.h> |
| 522 | 591 | #include <__functional/operations.h> |
| 523 | 592 | #include <__hash_table> |
| 524 | 593 | #include <__iterator/distance.h> |
| 525 | 594 | #include <__iterator/erase_if_container.h> |
| 526 | 595 | #include <__iterator/iterator_traits.h> |
| 596 | #include <__iterator/ranges_iterator_traits.h> | |
| 527 | 597 | #include <__memory/addressof.h> |
| 528 | 598 | #include <__memory/allocator.h> |
| 529 | 599 | #include <__memory_resource/polymorphic_allocator.h> |
| 530 | 600 | #include <__node_handle> |
| 601 | #include <__ranges/concepts.h> | |
| 602 | #include <__ranges/container_compatible_range.h> | |
| 603 | #include <__ranges/from_range.h> | |
| 531 | 604 | #include <__type_traits/is_allocator.h> |
| 605 | #include <__type_traits/type_identity.h> | |
| 532 | 606 | #include <__utility/forward.h> |
| 533 | 607 | #include <stdexcept> |
| 534 | 608 | #include <tuple> |
| ... | ... | @@ -575,7 +649,7 @@ public: |
| 575 | 649 | _LIBCPP_INLINE_VISIBILITY |
| 576 | 650 | size_t operator()(const _Key& __x) const |
| 577 | 651 | {return static_cast<const _Hash&>(*this)(__x);} |
| 578 | #if _LIBCPP_STD_VER > 17 | |
| 652 | #if _LIBCPP_STD_VER >= 20 | |
| 579 | 653 | template <typename _K2> |
| 580 | 654 | _LIBCPP_INLINE_VISIBILITY |
| 581 | 655 | size_t operator()(const _K2& __x) const |
| ... | ... | @@ -611,7 +685,7 @@ public: |
| 611 | 685 | _LIBCPP_INLINE_VISIBILITY |
| 612 | 686 | size_t operator()(const _Key& __x) const |
| 613 | 687 | {return __hash_(__x);} |
| 614 | #if _LIBCPP_STD_VER > 17 | |
| 688 | #if _LIBCPP_STD_VER >= 20 | |
| 615 | 689 | template <typename _K2> |
| 616 | 690 | _LIBCPP_INLINE_VISIBILITY |
| 617 | 691 | size_t operator()(const _K2& __x) const |
| ... | ... | @@ -661,7 +735,7 @@ public: |
| 661 | 735 | _LIBCPP_INLINE_VISIBILITY |
| 662 | 736 | bool operator()(const _Key& __x, const _Cp& __y) const |
| 663 | 737 | {return static_cast<const _Pred&>(*this)(__x, __y.__get_value().first);} |
| 664 | #if _LIBCPP_STD_VER > 17 | |
| 738 | #if _LIBCPP_STD_VER >= 20 | |
| 665 | 739 | template <typename _K2> |
| 666 | 740 | _LIBCPP_INLINE_VISIBILITY |
| 667 | 741 | bool operator()(const _Cp& __x, const _K2& __y) const |
| ... | ... | @@ -712,7 +786,7 @@ public: |
| 712 | 786 | _LIBCPP_INLINE_VISIBILITY |
| 713 | 787 | bool operator()(const _Key& __x, const _Cp& __y) const |
| 714 | 788 | {return __pred_(__x, __y.__get_value().first);} |
| 715 | #if _LIBCPP_STD_VER > 17 | |
| 789 | #if _LIBCPP_STD_VER >= 20 | |
| 716 | 790 | template <typename _K2> |
| 717 | 791 | _LIBCPP_INLINE_VISIBILITY |
| 718 | 792 | bool operator()(const _Cp& __x, const _K2& __y) const |
| ... | ... | @@ -825,7 +899,7 @@ public: |
| 825 | 899 | _LIBCPP_INLINE_VISIBILITY |
| 826 | 900 | value_type& __get_value() |
| 827 | 901 | { |
| 828 | #if _LIBCPP_STD_VER > 14 | |
| 902 | #if _LIBCPP_STD_VER >= 17 | |
| 829 | 903 | return *_VSTD::launder(_VSTD::addressof(__cc_)); |
| 830 | 904 | #else |
| 831 | 905 | return __cc_; |
| ... | ... | @@ -835,7 +909,7 @@ public: |
| 835 | 909 | _LIBCPP_INLINE_VISIBILITY |
| 836 | 910 | const value_type& __get_value() const |
| 837 | 911 | { |
| 838 | #if _LIBCPP_STD_VER > 14 | |
| 912 | #if _LIBCPP_STD_VER >= 17 | |
| 839 | 913 | return *_VSTD::launder(_VSTD::addressof(__cc_)); |
| 840 | 914 | #else |
| 841 | 915 | return __cc_; |
| ... | ... | @@ -953,9 +1027,11 @@ public: |
| 953 | 1027 | friend _LIBCPP_INLINE_VISIBILITY |
| 954 | 1028 | bool operator==(const __hash_map_iterator& __x, const __hash_map_iterator& __y) |
| 955 | 1029 | {return __x.__i_ == __y.__i_;} |
| 1030 | #if _LIBCPP_STD_VER <= 17 | |
| 956 | 1031 | friend _LIBCPP_INLINE_VISIBILITY |
| 957 | 1032 | bool operator!=(const __hash_map_iterator& __x, const __hash_map_iterator& __y) |
| 958 | 1033 | {return __x.__i_ != __y.__i_;} |
| 1034 | #endif | |
| 959 | 1035 | |
| 960 | 1036 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; |
| 961 | 1037 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; |
| ... | ... | @@ -1007,9 +1083,11 @@ public: |
| 1007 | 1083 | friend _LIBCPP_INLINE_VISIBILITY |
| 1008 | 1084 | bool operator==(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) |
| 1009 | 1085 | {return __x.__i_ == __y.__i_;} |
| 1086 | #if _LIBCPP_STD_VER <= 17 | |
| 1010 | 1087 | friend _LIBCPP_INLINE_VISIBILITY |
| 1011 | 1088 | bool operator!=(const __hash_map_const_iterator& __x, const __hash_map_const_iterator& __y) |
| 1012 | 1089 | {return __x.__i_ != __y.__i_;} |
| 1090 | #endif | |
| 1013 | 1091 | |
| 1014 | 1092 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_map; |
| 1015 | 1093 | template <class, class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; |
| ... | ... | @@ -1035,7 +1113,7 @@ public: |
| 1035 | 1113 | typedef value_type& reference; |
| 1036 | 1114 | typedef const value_type& const_reference; |
| 1037 | 1115 | static_assert((is_same<value_type, typename allocator_type::value_type>::value), |
| 1038 | "Invalid allocator::value_type"); | |
| 1116 | "Allocator::value_type must be same type as value_type"); | |
| 1039 | 1117 | |
| 1040 | 1118 | private: |
| 1041 | 1119 | typedef __hash_value_type<key_type, mapped_type> __value_type; |
| ... | ... | @@ -1075,7 +1153,7 @@ public: |
| 1075 | 1153 | typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; |
| 1076 | 1154 | typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; |
| 1077 | 1155 | |
| 1078 | #if _LIBCPP_STD_VER > 14 | |
| 1156 | #if _LIBCPP_STD_VER >= 17 | |
| 1079 | 1157 | typedef __map_node_handle<__node, allocator_type> node_type; |
| 1080 | 1158 | typedef __insert_return_type<iterator, node_type> insert_return_type; |
| 1081 | 1159 | #endif |
| ... | ... | @@ -1089,41 +1167,55 @@ public: |
| 1089 | 1167 | unordered_map() |
| 1090 | 1168 | _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) |
| 1091 | 1169 | { |
| 1092 | _VSTD::__debug_db_insert_c(this); | |
| 1093 | 1170 | } |
| 1094 | explicit unordered_map(size_type __n, const hasher& __hf = hasher(), | |
| 1171 | explicit _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf = hasher(), | |
| 1095 | 1172 | const key_equal& __eql = key_equal()); |
| 1096 | unordered_map(size_type __n, const hasher& __hf, | |
| 1173 | _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf, | |
| 1097 | 1174 | const key_equal& __eql, |
| 1098 | 1175 | const allocator_type& __a); |
| 1099 | 1176 | template <class _InputIterator> |
| 1100 | unordered_map(_InputIterator __first, _InputIterator __last); | |
| 1177 | _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last); | |
| 1101 | 1178 | template <class _InputIterator> |
| 1102 | unordered_map(_InputIterator __first, _InputIterator __last, | |
| 1179 | _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last, | |
| 1103 | 1180 | size_type __n, const hasher& __hf = hasher(), |
| 1104 | 1181 | const key_equal& __eql = key_equal()); |
| 1105 | 1182 | template <class _InputIterator> |
| 1106 | unordered_map(_InputIterator __first, _InputIterator __last, | |
| 1183 | _LIBCPP_HIDE_FROM_ABI unordered_map(_InputIterator __first, _InputIterator __last, | |
| 1107 | 1184 | size_type __n, const hasher& __hf, |
| 1108 | 1185 | const key_equal& __eql, |
| 1109 | 1186 | const allocator_type& __a); |
| 1187 | ||
| 1188 | #if _LIBCPP_STD_VER >= 23 | |
| 1189 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1190 | _LIBCPP_HIDE_FROM_ABI | |
| 1191 | unordered_map(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, | |
| 1192 | const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), | |
| 1193 | const allocator_type& __a = allocator_type()) | |
| 1194 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) { | |
| 1195 | if (__n > 0) { | |
| 1196 | __table_.__rehash_unique(__n); | |
| 1197 | } | |
| 1198 | insert_range(std::forward<_Range>(__range)); | |
| 1199 | } | |
| 1200 | #endif | |
| 1201 | ||
| 1110 | 1202 | _LIBCPP_INLINE_VISIBILITY |
| 1111 | 1203 | explicit unordered_map(const allocator_type& __a); |
| 1112 | unordered_map(const unordered_map& __u); | |
| 1113 | unordered_map(const unordered_map& __u, const allocator_type& __a); | |
| 1204 | _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u); | |
| 1205 | _LIBCPP_HIDE_FROM_ABI unordered_map(const unordered_map& __u, const allocator_type& __a); | |
| 1114 | 1206 | #ifndef _LIBCPP_CXX03_LANG |
| 1115 | 1207 | _LIBCPP_INLINE_VISIBILITY |
| 1116 | 1208 | unordered_map(unordered_map&& __u) |
| 1117 | 1209 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); |
| 1118 | unordered_map(unordered_map&& __u, const allocator_type& __a); | |
| 1119 | unordered_map(initializer_list<value_type> __il); | |
| 1120 | unordered_map(initializer_list<value_type> __il, size_type __n, | |
| 1210 | _LIBCPP_HIDE_FROM_ABI unordered_map(unordered_map&& __u, const allocator_type& __a); | |
| 1211 | _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il); | |
| 1212 | _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n, | |
| 1121 | 1213 | const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); |
| 1122 | unordered_map(initializer_list<value_type> __il, size_type __n, | |
| 1214 | _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list<value_type> __il, size_type __n, | |
| 1123 | 1215 | const hasher& __hf, const key_equal& __eql, |
| 1124 | 1216 | const allocator_type& __a); |
| 1125 | 1217 | #endif // _LIBCPP_CXX03_LANG |
| 1126 | #if _LIBCPP_STD_VER > 11 | |
| 1218 | #if _LIBCPP_STD_VER >= 14 | |
| 1127 | 1219 | _LIBCPP_INLINE_VISIBILITY |
| 1128 | 1220 | unordered_map(size_type __n, const allocator_type& __a) |
| 1129 | 1221 | : unordered_map(__n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -1139,6 +1231,19 @@ public: |
| 1139 | 1231 | unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, |
| 1140 | 1232 | const allocator_type& __a) |
| 1141 | 1233 | : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {} |
| 1234 | ||
| 1235 | #if _LIBCPP_STD_VER >= 23 | |
| 1236 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1237 | _LIBCPP_HIDE_FROM_ABI | |
| 1238 | unordered_map(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) | |
| 1239 | : unordered_map(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} | |
| 1240 | ||
| 1241 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1242 | _LIBCPP_HIDE_FROM_ABI | |
| 1243 | unordered_map(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) | |
| 1244 | : unordered_map(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} | |
| 1245 | #endif | |
| 1246 | ||
| 1142 | 1247 | _LIBCPP_INLINE_VISIBILITY |
| 1143 | 1248 | unordered_map(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) |
| 1144 | 1249 | : unordered_map(__il, __n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -1205,11 +1310,7 @@ public: |
| 1205 | 1310 | pair<iterator, bool> insert(const value_type& __x) |
| 1206 | 1311 | {return __table_.__insert_unique(__x);} |
| 1207 | 1312 | |
| 1208 | iterator insert(const_iterator __p, const value_type& __x) { | |
| 1209 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1210 | "unordered_map::insert(const_iterator, const value_type&) called with an iterator not " | |
| 1211 | "referring to this unordered_map"); | |
| 1212 | ((void)__p); | |
| 1313 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, const value_type& __x) { | |
| 1213 | 1314 | return insert(__x).first; |
| 1214 | 1315 | } |
| 1215 | 1316 | |
| ... | ... | @@ -1217,6 +1318,16 @@ public: |
| 1217 | 1318 | _LIBCPP_INLINE_VISIBILITY |
| 1218 | 1319 | void insert(_InputIterator __first, _InputIterator __last); |
| 1219 | 1320 | |
| 1321 | #if _LIBCPP_STD_VER >= 23 | |
| 1322 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1323 | _LIBCPP_HIDE_FROM_ABI | |
| 1324 | void insert_range(_Range&& __range) { | |
| 1325 | for (auto&& __element : __range) { | |
| 1326 | __table_.__insert_unique(std::forward<decltype(__element)>(__element)); | |
| 1327 | } | |
| 1328 | } | |
| 1329 | #endif | |
| 1330 | ||
| 1220 | 1331 | #ifndef _LIBCPP_CXX03_LANG |
| 1221 | 1332 | _LIBCPP_INLINE_VISIBILITY |
| 1222 | 1333 | void insert(initializer_list<value_type> __il) |
| ... | ... | @@ -1226,11 +1337,7 @@ public: |
| 1226 | 1337 | pair<iterator, bool> insert(value_type&& __x) |
| 1227 | 1338 | {return __table_.__insert_unique(_VSTD::move(__x));} |
| 1228 | 1339 | |
| 1229 | iterator insert(const_iterator __p, value_type&& __x) { | |
| 1230 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1231 | "unordered_map::insert(const_iterator, const value_type&) called with an iterator not" | |
| 1232 | " referring to this unordered_map"); | |
| 1233 | ((void)__p); | |
| 1340 | _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator, value_type&& __x) { | |
| 1234 | 1341 | return __table_.__insert_unique(_VSTD::move(__x)).first; |
| 1235 | 1342 | } |
| 1236 | 1343 | |
| ... | ... | @@ -1243,12 +1350,8 @@ public: |
| 1243 | 1350 | template <class _Pp, |
| 1244 | 1351 | class = __enable_if_t<is_constructible<value_type, _Pp>::value> > |
| 1245 | 1352 | _LIBCPP_INLINE_VISIBILITY |
| 1246 | iterator insert(const_iterator __p, _Pp&& __x) | |
| 1353 | iterator insert(const_iterator, _Pp&& __x) | |
| 1247 | 1354 | { |
| 1248 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1249 | "unordered_map::insert(const_iterator, value_type&&) called with an iterator not" | |
| 1250 | " referring to this unordered_map"); | |
| 1251 | ((void)__p); | |
| 1252 | 1355 | return insert(_VSTD::forward<_Pp>(__x)).first; |
| 1253 | 1356 | } |
| 1254 | 1357 | |
| ... | ... | @@ -1260,17 +1363,13 @@ public: |
| 1260 | 1363 | |
| 1261 | 1364 | template <class... _Args> |
| 1262 | 1365 | _LIBCPP_INLINE_VISIBILITY |
| 1263 | iterator emplace_hint(const_iterator __p, _Args&&... __args) { | |
| 1264 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, | |
| 1265 | "unordered_map::emplace_hint(const_iterator, args...) called with an iterator not" | |
| 1266 | " referring to this unordered_map"); | |
| 1267 | ((void)__p); | |
| 1366 | iterator emplace_hint(const_iterator, _Args&&... __args) { | |
| 1268 | 1367 | return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first; |
| 1269 | 1368 | } |
| 1270 | 1369 | |
| 1271 | 1370 | #endif // _LIBCPP_CXX03_LANG |
| 1272 | 1371 | |
| 1273 | #if _LIBCPP_STD_VER > 14 | |
| 1372 | #if _LIBCPP_STD_VER >= 17 | |
| 1274 | 1373 | template <class... _Args> |
| 1275 | 1374 | _LIBCPP_INLINE_VISIBILITY |
| 1276 | 1375 | pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) |
| ... | ... | @@ -1291,23 +1390,15 @@ public: |
| 1291 | 1390 | |
| 1292 | 1391 | template <class... _Args> |
| 1293 | 1392 | _LIBCPP_INLINE_VISIBILITY |
| 1294 | iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) | |
| 1393 | iterator try_emplace(const_iterator, const key_type& __k, _Args&&... __args) | |
| 1295 | 1394 | { |
| 1296 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, | |
| 1297 | "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" | |
| 1298 | " referring to this unordered_map"); | |
| 1299 | ((void)__h); | |
| 1300 | 1395 | return try_emplace(__k, _VSTD::forward<_Args>(__args)...).first; |
| 1301 | 1396 | } |
| 1302 | 1397 | |
| 1303 | 1398 | template <class... _Args> |
| 1304 | 1399 | _LIBCPP_INLINE_VISIBILITY |
| 1305 | iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) | |
| 1400 | iterator try_emplace(const_iterator, key_type&& __k, _Args&&... __args) | |
| 1306 | 1401 | { |
| 1307 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__h)) == this, | |
| 1308 | "unordered_map::try_emplace(const_iterator, key, args...) called with an iterator not" | |
| 1309 | " referring to this unordered_map"); | |
| 1310 | ((void)__h); | |
| 1311 | 1402 | return try_emplace(_VSTD::move(__k), _VSTD::forward<_Args>(__args)...).first; |
| 1312 | 1403 | } |
| 1313 | 1404 | |
| ... | ... | @@ -1339,7 +1430,6 @@ public: |
| 1339 | 1430 | _LIBCPP_INLINE_VISIBILITY |
| 1340 | 1431 | iterator insert_or_assign(const_iterator, const key_type& __k, _Vp&& __v) |
| 1341 | 1432 | { |
| 1342 | // FIXME: Add debug mode checking for the iterator input | |
| 1343 | 1433 | return insert_or_assign(__k, _VSTD::forward<_Vp>(__v)).first; |
| 1344 | 1434 | } |
| 1345 | 1435 | |
| ... | ... | @@ -1347,10 +1437,9 @@ public: |
| 1347 | 1437 | _LIBCPP_INLINE_VISIBILITY |
| 1348 | 1438 | iterator insert_or_assign(const_iterator, key_type&& __k, _Vp&& __v) |
| 1349 | 1439 | { |
| 1350 | // FIXME: Add debug mode checking for the iterator input | |
| 1351 | 1440 | return insert_or_assign(_VSTD::move(__k), _VSTD::forward<_Vp>(__v)).first; |
| 1352 | 1441 | } |
| 1353 | #endif // _LIBCPP_STD_VER > 14 | |
| 1442 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1354 | 1443 | |
| 1355 | 1444 | _LIBCPP_INLINE_VISIBILITY |
| 1356 | 1445 | iterator erase(const_iterator __p) {return __table_.erase(__p.__i_);} |
| ... | ... | @@ -1364,11 +1453,11 @@ public: |
| 1364 | 1453 | _LIBCPP_INLINE_VISIBILITY |
| 1365 | 1454 | void clear() _NOEXCEPT {__table_.clear();} |
| 1366 | 1455 | |
| 1367 | #if _LIBCPP_STD_VER > 14 | |
| 1456 | #if _LIBCPP_STD_VER >= 17 | |
| 1368 | 1457 | _LIBCPP_INLINE_VISIBILITY |
| 1369 | 1458 | insert_return_type insert(node_type&& __nh) |
| 1370 | 1459 | { |
| 1371 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1460 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1372 | 1461 | "node_type with incompatible allocator passed to unordered_map::insert()"); |
| 1373 | 1462 | return __table_.template __node_handle_insert_unique< |
| 1374 | 1463 | node_type, insert_return_type>(_VSTD::move(__nh)); |
| ... | ... | @@ -1376,7 +1465,7 @@ public: |
| 1376 | 1465 | _LIBCPP_INLINE_VISIBILITY |
| 1377 | 1466 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 1378 | 1467 | { |
| 1379 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1468 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1380 | 1469 | "node_type with incompatible allocator passed to unordered_map::insert()"); |
| 1381 | 1470 | return __table_.template __node_handle_insert_unique<node_type>( |
| 1382 | 1471 | __hint.__i_, _VSTD::move(__nh)); |
| ... | ... | @@ -1397,32 +1486,32 @@ public: |
| 1397 | 1486 | _LIBCPP_INLINE_VISIBILITY |
| 1398 | 1487 | void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) |
| 1399 | 1488 | { |
| 1400 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1401 | "merging container with incompatible allocator"); | |
| 1489 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1490 | "merging container with incompatible allocator"); | |
| 1402 | 1491 | return __table_.__node_handle_merge_unique(__source.__table_); |
| 1403 | 1492 | } |
| 1404 | 1493 | template <class _H2, class _P2> |
| 1405 | 1494 | _LIBCPP_INLINE_VISIBILITY |
| 1406 | 1495 | void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) |
| 1407 | 1496 | { |
| 1408 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1409 | "merging container with incompatible allocator"); | |
| 1497 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1498 | "merging container with incompatible allocator"); | |
| 1410 | 1499 | return __table_.__node_handle_merge_unique(__source.__table_); |
| 1411 | 1500 | } |
| 1412 | 1501 | template <class _H2, class _P2> |
| 1413 | 1502 | _LIBCPP_INLINE_VISIBILITY |
| 1414 | 1503 | void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) |
| 1415 | 1504 | { |
| 1416 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1417 | "merging container with incompatible allocator"); | |
| 1505 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1506 | "merging container with incompatible allocator"); | |
| 1418 | 1507 | return __table_.__node_handle_merge_unique(__source.__table_); |
| 1419 | 1508 | } |
| 1420 | 1509 | template <class _H2, class _P2> |
| 1421 | 1510 | _LIBCPP_INLINE_VISIBILITY |
| 1422 | 1511 | void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) |
| 1423 | 1512 | { |
| 1424 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1425 | "merging container with incompatible allocator"); | |
| 1513 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1514 | "merging container with incompatible allocator"); | |
| 1426 | 1515 | return __table_.__node_handle_merge_unique(__source.__table_); |
| 1427 | 1516 | } |
| 1428 | 1517 | #endif |
| ... | ... | @@ -1443,31 +1532,31 @@ public: |
| 1443 | 1532 | iterator find(const key_type& __k) {return __table_.find(__k);} |
| 1444 | 1533 | _LIBCPP_INLINE_VISIBILITY |
| 1445 | 1534 | const_iterator find(const key_type& __k) const {return __table_.find(__k);} |
| 1446 | #if _LIBCPP_STD_VER > 17 | |
| 1535 | #if _LIBCPP_STD_VER >= 20 | |
| 1447 | 1536 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1448 | 1537 | _LIBCPP_INLINE_VISIBILITY |
| 1449 | 1538 | iterator find(const _K2& __k) {return __table_.find(__k);} |
| 1450 | 1539 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1451 | 1540 | _LIBCPP_INLINE_VISIBILITY |
| 1452 | 1541 | const_iterator find(const _K2& __k) const {return __table_.find(__k);} |
| 1453 | #endif // _LIBCPP_STD_VER > 17 | |
| 1542 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1454 | 1543 | |
| 1455 | 1544 | _LIBCPP_INLINE_VISIBILITY |
| 1456 | 1545 | size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} |
| 1457 | #if _LIBCPP_STD_VER > 17 | |
| 1546 | #if _LIBCPP_STD_VER >= 20 | |
| 1458 | 1547 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1459 | 1548 | _LIBCPP_INLINE_VISIBILITY |
| 1460 | 1549 | size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} |
| 1461 | #endif // _LIBCPP_STD_VER > 17 | |
| 1550 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1462 | 1551 | |
| 1463 | #if _LIBCPP_STD_VER > 17 | |
| 1552 | #if _LIBCPP_STD_VER >= 20 | |
| 1464 | 1553 | _LIBCPP_INLINE_VISIBILITY |
| 1465 | 1554 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 1466 | 1555 | |
| 1467 | 1556 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1468 | 1557 | _LIBCPP_INLINE_VISIBILITY |
| 1469 | 1558 | bool contains(const _K2& __k) const {return find(__k) != end();} |
| 1470 | #endif // _LIBCPP_STD_VER > 17 | |
| 1559 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1471 | 1560 | |
| 1472 | 1561 | _LIBCPP_INLINE_VISIBILITY |
| 1473 | 1562 | pair<iterator, iterator> equal_range(const key_type& __k) |
| ... | ... | @@ -1475,7 +1564,7 @@ public: |
| 1475 | 1564 | _LIBCPP_INLINE_VISIBILITY |
| 1476 | 1565 | pair<const_iterator, const_iterator> equal_range(const key_type& __k) const |
| 1477 | 1566 | {return __table_.__equal_range_unique(__k);} |
| 1478 | #if _LIBCPP_STD_VER > 17 | |
| 1567 | #if _LIBCPP_STD_VER >= 20 | |
| 1479 | 1568 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1480 | 1569 | _LIBCPP_INLINE_VISIBILITY |
| 1481 | 1570 | pair<iterator, iterator> equal_range(const _K2& __k) |
| ... | ... | @@ -1484,15 +1573,15 @@ public: |
| 1484 | 1573 | _LIBCPP_INLINE_VISIBILITY |
| 1485 | 1574 | pair<const_iterator, const_iterator> equal_range(const _K2& __k) const |
| 1486 | 1575 | {return __table_.__equal_range_unique(__k);} |
| 1487 | #endif // _LIBCPP_STD_VER > 17 | |
| 1576 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1488 | 1577 | |
| 1489 | mapped_type& operator[](const key_type& __k); | |
| 1578 | _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k); | |
| 1490 | 1579 | #ifndef _LIBCPP_CXX03_LANG |
| 1491 | mapped_type& operator[](key_type&& __k); | |
| 1580 | _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k); | |
| 1492 | 1581 | #endif |
| 1493 | 1582 | |
| 1494 | mapped_type& at(const key_type& __k); | |
| 1495 | const mapped_type& at(const key_type& __k) const; | |
| 1583 | _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k); | |
| 1584 | _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const; | |
| 1496 | 1585 | |
| 1497 | 1586 | _LIBCPP_INLINE_VISIBILITY |
| 1498 | 1587 | size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} |
| ... | ... | @@ -1529,23 +1618,10 @@ public: |
| 1529 | 1618 | _LIBCPP_INLINE_VISIBILITY |
| 1530 | 1619 | void reserve(size_type __n) {__table_.__reserve_unique(__n);} |
| 1531 | 1620 | |
| 1532 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1533 | ||
| 1534 | bool __dereferenceable(const const_iterator* __i) const | |
| 1535 | {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));} | |
| 1536 | bool __decrementable(const const_iterator* __i) const | |
| 1537 | {return __table_.__decrementable(_VSTD::addressof(__i->__i_));} | |
| 1538 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1539 | {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} | |
| 1540 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1541 | {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} | |
| 1542 | ||
| 1543 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 1544 | ||
| 1545 | 1621 | private: |
| 1546 | 1622 | |
| 1547 | 1623 | #ifdef _LIBCPP_CXX03_LANG |
| 1548 | __node_holder __construct_node_with_key(const key_type& __k); | |
| 1624 | _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k); | |
| 1549 | 1625 | #endif |
| 1550 | 1626 | }; |
| 1551 | 1627 | |
| ... | ... | @@ -1554,7 +1630,7 @@ template<class _InputIterator, |
| 1554 | 1630 | class _Hash = hash<__iter_key_type<_InputIterator>>, |
| 1555 | 1631 | class _Pred = equal_to<__iter_key_type<_InputIterator>>, |
| 1556 | 1632 | class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, |
| 1557 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1633 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1558 | 1634 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 1559 | 1635 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 1560 | 1636 | class = enable_if_t<!__is_allocator<_Pred>::value>, |
| ... | ... | @@ -1563,6 +1639,20 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat |
| 1563 | 1639 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) |
| 1564 | 1640 | -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; |
| 1565 | 1641 | |
| 1642 | #if _LIBCPP_STD_VER >= 23 | |
| 1643 | template <ranges::input_range _Range, | |
| 1644 | class _Hash = hash<__range_key_type<_Range>>, | |
| 1645 | class _Pred = equal_to<__range_key_type<_Range>>, | |
| 1646 | class _Allocator = allocator<__range_to_alloc_type<_Range>>, | |
| 1647 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 1648 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 1649 | class = enable_if_t<!__is_allocator<_Pred>::value>, | |
| 1650 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1651 | unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, | |
| 1652 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) | |
| 1653 | -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>; // C++23 | |
| 1654 | #endif | |
| 1655 | ||
| 1566 | 1656 | template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, |
| 1567 | 1657 | class _Pred = equal_to<remove_const_t<_Key>>, |
| 1568 | 1658 | class _Allocator = allocator<pair<const _Key, _Tp>>, |
| ... | ... | @@ -1575,21 +1665,21 @@ unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allo |
| 1575 | 1665 | -> unordered_map<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; |
| 1576 | 1666 | |
| 1577 | 1667 | template<class _InputIterator, class _Allocator, |
| 1578 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1668 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1579 | 1669 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 1580 | 1670 | unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| 1581 | 1671 | -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 1582 | 1672 | hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 1583 | 1673 | |
| 1584 | 1674 | template<class _InputIterator, class _Allocator, |
| 1585 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1675 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1586 | 1676 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 1587 | 1677 | unordered_map(_InputIterator, _InputIterator, _Allocator) |
| 1588 | 1678 | -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 1589 | 1679 | hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 1590 | 1680 | |
| 1591 | 1681 | template<class _InputIterator, class _Hash, class _Allocator, |
| 1592 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1682 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1593 | 1683 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 1594 | 1684 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 1595 | 1685 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| ... | ... | @@ -1597,6 +1687,30 @@ unordered_map(_InputIterator, _InputIterator, typename allocator_traits<_Allocat |
| 1597 | 1687 | -> unordered_map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 1598 | 1688 | _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 1599 | 1689 | |
| 1690 | #if _LIBCPP_STD_VER >= 23 | |
| 1691 | ||
| 1692 | template <ranges::input_range _Range, class _Allocator, | |
| 1693 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1694 | unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) | |
| 1695 | -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>, | |
| 1696 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 1697 | ||
| 1698 | template <ranges::input_range _Range, class _Allocator, | |
| 1699 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1700 | unordered_map(from_range_t, _Range&&, _Allocator) | |
| 1701 | -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>, | |
| 1702 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 1703 | ||
| 1704 | template <ranges::input_range _Range, class _Hash, class _Allocator, | |
| 1705 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 1706 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 1707 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1708 | unordered_map(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) | |
| 1709 | -> unordered_map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, | |
| 1710 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 1711 | ||
| 1712 | #endif | |
| 1713 | ||
| 1600 | 1714 | template<class _Key, class _Tp, class _Allocator, |
| 1601 | 1715 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 1602 | 1716 | unordered_map(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| ... | ... | @@ -1625,7 +1739,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1625 | 1739 | size_type __n, const hasher& __hf, const key_equal& __eql) |
| 1626 | 1740 | : __table_(__hf, __eql) |
| 1627 | 1741 | { |
| 1628 | _VSTD::__debug_db_insert_c(this); | |
| 1629 | 1742 | __table_.__rehash_unique(__n); |
| 1630 | 1743 | } |
| 1631 | 1744 | |
| ... | ... | @@ -1635,7 +1748,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1635 | 1748 | const allocator_type& __a) |
| 1636 | 1749 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 1637 | 1750 | { |
| 1638 | _VSTD::__debug_db_insert_c(this); | |
| 1639 | 1751 | __table_.__rehash_unique(__n); |
| 1640 | 1752 | } |
| 1641 | 1753 | |
| ... | ... | @@ -1645,7 +1757,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1645 | 1757 | const allocator_type& __a) |
| 1646 | 1758 | : __table_(typename __table::allocator_type(__a)) |
| 1647 | 1759 | { |
| 1648 | _VSTD::__debug_db_insert_c(this); | |
| 1649 | 1760 | } |
| 1650 | 1761 | |
| 1651 | 1762 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1653,7 +1764,6 @@ template <class _InputIterator> |
| 1653 | 1764 | unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1654 | 1765 | _InputIterator __first, _InputIterator __last) |
| 1655 | 1766 | { |
| 1656 | _VSTD::__debug_db_insert_c(this); | |
| 1657 | 1767 | insert(__first, __last); |
| 1658 | 1768 | } |
| 1659 | 1769 | |
| ... | ... | @@ -1664,7 +1774,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1664 | 1774 | const hasher& __hf, const key_equal& __eql) |
| 1665 | 1775 | : __table_(__hf, __eql) |
| 1666 | 1776 | { |
| 1667 | _VSTD::__debug_db_insert_c(this); | |
| 1668 | 1777 | __table_.__rehash_unique(__n); |
| 1669 | 1778 | insert(__first, __last); |
| 1670 | 1779 | } |
| ... | ... | @@ -1676,7 +1785,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1676 | 1785 | const hasher& __hf, const key_equal& __eql, const allocator_type& __a) |
| 1677 | 1786 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 1678 | 1787 | { |
| 1679 | _VSTD::__debug_db_insert_c(this); | |
| 1680 | 1788 | __table_.__rehash_unique(__n); |
| 1681 | 1789 | insert(__first, __last); |
| 1682 | 1790 | } |
| ... | ... | @@ -1686,7 +1794,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1686 | 1794 | const unordered_map& __u) |
| 1687 | 1795 | : __table_(__u.__table_) |
| 1688 | 1796 | { |
| 1689 | _VSTD::__debug_db_insert_c(this); | |
| 1690 | 1797 | __table_.__rehash_unique(__u.bucket_count()); |
| 1691 | 1798 | insert(__u.begin(), __u.end()); |
| 1692 | 1799 | } |
| ... | ... | @@ -1696,7 +1803,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1696 | 1803 | const unordered_map& __u, const allocator_type& __a) |
| 1697 | 1804 | : __table_(__u.__table_, typename __table::allocator_type(__a)) |
| 1698 | 1805 | { |
| 1699 | _VSTD::__debug_db_insert_c(this); | |
| 1700 | 1806 | __table_.__rehash_unique(__u.bucket_count()); |
| 1701 | 1807 | insert(__u.begin(), __u.end()); |
| 1702 | 1808 | } |
| ... | ... | @@ -1710,8 +1816,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1710 | 1816 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) |
| 1711 | 1817 | : __table_(_VSTD::move(__u.__table_)) |
| 1712 | 1818 | { |
| 1713 | _VSTD::__debug_db_insert_c(this); | |
| 1714 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1715 | 1819 | } |
| 1716 | 1820 | |
| 1717 | 1821 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1719,7 +1823,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1719 | 1823 | unordered_map&& __u, const allocator_type& __a) |
| 1720 | 1824 | : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) |
| 1721 | 1825 | { |
| 1722 | _VSTD::__debug_db_insert_c(this); | |
| 1723 | 1826 | if (__a != __u.get_allocator()) |
| 1724 | 1827 | { |
| 1725 | 1828 | iterator __i = __u.begin(); |
| ... | ... | @@ -1728,15 +1831,12 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1728 | 1831 | __u.__table_.remove((__i++).__i_)->__value_.__move()); |
| 1729 | 1832 | } |
| 1730 | 1833 | } |
| 1731 | else | |
| 1732 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1733 | 1834 | } |
| 1734 | 1835 | |
| 1735 | 1836 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| 1736 | 1837 | unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1737 | 1838 | initializer_list<value_type> __il) |
| 1738 | 1839 | { |
| 1739 | _VSTD::__debug_db_insert_c(this); | |
| 1740 | 1840 | insert(__il.begin(), __il.end()); |
| 1741 | 1841 | } |
| 1742 | 1842 | |
| ... | ... | @@ -1746,7 +1846,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1746 | 1846 | const key_equal& __eql) |
| 1747 | 1847 | : __table_(__hf, __eql) |
| 1748 | 1848 | { |
| 1749 | _VSTD::__debug_db_insert_c(this); | |
| 1750 | 1849 | __table_.__rehash_unique(__n); |
| 1751 | 1850 | insert(__il.begin(), __il.end()); |
| 1752 | 1851 | } |
| ... | ... | @@ -1757,7 +1856,6 @@ unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( |
| 1757 | 1856 | const key_equal& __eql, const allocator_type& __a) |
| 1758 | 1857 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 1759 | 1858 | { |
| 1760 | _VSTD::__debug_db_insert_c(this); | |
| 1761 | 1859 | __table_.__rehash_unique(__n); |
| 1762 | 1860 | insert(__il.begin(), __il.end()); |
| 1763 | 1861 | } |
| ... | ... | @@ -1874,7 +1972,7 @@ swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 1874 | 1972 | __x.swap(__y); |
| 1875 | 1973 | } |
| 1876 | 1974 | |
| 1877 | #if _LIBCPP_STD_VER > 17 | |
| 1975 | #if _LIBCPP_STD_VER >= 20 | |
| 1878 | 1976 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, |
| 1879 | 1977 | class _Predicate> |
| 1880 | 1978 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1904,6 +2002,8 @@ operator==(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 1904 | 2002 | return true; |
| 1905 | 2003 | } |
| 1906 | 2004 | |
| 2005 | #if _LIBCPP_STD_VER <= 17 | |
| 2006 | ||
| 1907 | 2007 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| 1908 | 2008 | inline _LIBCPP_INLINE_VISIBILITY |
| 1909 | 2009 | bool |
| ... | ... | @@ -1913,6 +2013,8 @@ operator!=(const unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 1913 | 2013 | return !(__x == __y); |
| 1914 | 2014 | } |
| 1915 | 2015 | |
| 2016 | #endif | |
| 2017 | ||
| 1916 | 2018 | template <class _Key, class _Tp, class _Hash = hash<_Key>, class _Pred = equal_to<_Key>, |
| 1917 | 2019 | class _Alloc = allocator<pair<const _Key, _Tp> > > |
| 1918 | 2020 | class _LIBCPP_TEMPLATE_VIS unordered_multimap |
| ... | ... | @@ -1928,7 +2030,7 @@ public: |
| 1928 | 2030 | typedef value_type& reference; |
| 1929 | 2031 | typedef const value_type& const_reference; |
| 1930 | 2032 | static_assert((is_same<value_type, typename allocator_type::value_type>::value), |
| 1931 | "Invalid allocator::value_type"); | |
| 2033 | "Allocator::value_type must be same type as value_type"); | |
| 1932 | 2034 | |
| 1933 | 2035 | private: |
| 1934 | 2036 | typedef __hash_value_type<key_type, mapped_type> __value_type; |
| ... | ... | @@ -1967,7 +2069,7 @@ private: |
| 1967 | 2069 | typedef __hash_map_iterator<typename __table::local_iterator> local_iterator; |
| 1968 | 2070 | typedef __hash_map_const_iterator<typename __table::const_local_iterator> const_local_iterator; |
| 1969 | 2071 | |
| 1970 | #if _LIBCPP_STD_VER > 14 | |
| 2072 | #if _LIBCPP_STD_VER >= 17 | |
| 1971 | 2073 | typedef __map_node_handle<__node, allocator_type> node_type; |
| 1972 | 2074 | #endif |
| 1973 | 2075 | |
| ... | ... | @@ -1980,42 +2082,56 @@ private: |
| 1980 | 2082 | unordered_multimap() |
| 1981 | 2083 | _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) |
| 1982 | 2084 | { |
| 1983 | _VSTD::__debug_db_insert_c(this); | |
| 1984 | 2085 | } |
| 1985 | explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), | |
| 2086 | explicit _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf = hasher(), | |
| 1986 | 2087 | const key_equal& __eql = key_equal()); |
| 1987 | unordered_multimap(size_type __n, const hasher& __hf, | |
| 2088 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf, | |
| 1988 | 2089 | const key_equal& __eql, |
| 1989 | 2090 | const allocator_type& __a); |
| 1990 | 2091 | template <class _InputIterator> |
| 1991 | unordered_multimap(_InputIterator __first, _InputIterator __last); | |
| 2092 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last); | |
| 1992 | 2093 | template <class _InputIterator> |
| 1993 | unordered_multimap(_InputIterator __first, _InputIterator __last, | |
| 2094 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last, | |
| 1994 | 2095 | size_type __n, const hasher& __hf = hasher(), |
| 1995 | 2096 | const key_equal& __eql = key_equal()); |
| 1996 | 2097 | template <class _InputIterator> |
| 1997 | unordered_multimap(_InputIterator __first, _InputIterator __last, | |
| 2098 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(_InputIterator __first, _InputIterator __last, | |
| 1998 | 2099 | size_type __n, const hasher& __hf, |
| 1999 | 2100 | const key_equal& __eql, |
| 2000 | 2101 | const allocator_type& __a); |
| 2102 | ||
| 2103 | #if _LIBCPP_STD_VER >= 23 | |
| 2104 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 2105 | _LIBCPP_HIDE_FROM_ABI | |
| 2106 | unordered_multimap(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, | |
| 2107 | const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), | |
| 2108 | const allocator_type& __a = allocator_type()) | |
| 2109 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) { | |
| 2110 | if (__n > 0) { | |
| 2111 | __table_.__rehash_multi(__n); | |
| 2112 | } | |
| 2113 | insert_range(std::forward<_Range>(__range)); | |
| 2114 | } | |
| 2115 | #endif | |
| 2116 | ||
| 2001 | 2117 | _LIBCPP_INLINE_VISIBILITY |
| 2002 | 2118 | explicit unordered_multimap(const allocator_type& __a); |
| 2003 | unordered_multimap(const unordered_multimap& __u); | |
| 2004 | unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); | |
| 2119 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u); | |
| 2120 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); | |
| 2005 | 2121 | #ifndef _LIBCPP_CXX03_LANG |
| 2006 | 2122 | _LIBCPP_INLINE_VISIBILITY |
| 2007 | 2123 | unordered_multimap(unordered_multimap&& __u) |
| 2008 | 2124 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); |
| 2009 | unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); | |
| 2010 | unordered_multimap(initializer_list<value_type> __il); | |
| 2011 | unordered_multimap(initializer_list<value_type> __il, size_type __n, | |
| 2125 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); | |
| 2126 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il); | |
| 2127 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n, | |
| 2012 | 2128 | const hasher& __hf = hasher(), |
| 2013 | 2129 | const key_equal& __eql = key_equal()); |
| 2014 | unordered_multimap(initializer_list<value_type> __il, size_type __n, | |
| 2130 | _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list<value_type> __il, size_type __n, | |
| 2015 | 2131 | const hasher& __hf, const key_equal& __eql, |
| 2016 | 2132 | const allocator_type& __a); |
| 2017 | 2133 | #endif // _LIBCPP_CXX03_LANG |
| 2018 | #if _LIBCPP_STD_VER > 11 | |
| 2134 | #if _LIBCPP_STD_VER >= 14 | |
| 2019 | 2135 | _LIBCPP_INLINE_VISIBILITY |
| 2020 | 2136 | unordered_multimap(size_type __n, const allocator_type& __a) |
| 2021 | 2137 | : unordered_multimap(__n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -2031,6 +2147,19 @@ private: |
| 2031 | 2147 | unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, |
| 2032 | 2148 | const allocator_type& __a) |
| 2033 | 2149 | : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {} |
| 2150 | ||
| 2151 | #if _LIBCPP_STD_VER >= 23 | |
| 2152 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 2153 | _LIBCPP_HIDE_FROM_ABI | |
| 2154 | unordered_multimap(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) | |
| 2155 | : unordered_multimap(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} | |
| 2156 | ||
| 2157 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 2158 | _LIBCPP_HIDE_FROM_ABI | |
| 2159 | unordered_multimap(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) | |
| 2160 | : unordered_multimap(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} | |
| 2161 | #endif | |
| 2162 | ||
| 2034 | 2163 | _LIBCPP_INLINE_VISIBILITY |
| 2035 | 2164 | unordered_multimap(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) |
| 2036 | 2165 | : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -2104,6 +2233,16 @@ private: |
| 2104 | 2233 | _LIBCPP_INLINE_VISIBILITY |
| 2105 | 2234 | void insert(_InputIterator __first, _InputIterator __last); |
| 2106 | 2235 | |
| 2236 | #if _LIBCPP_STD_VER >= 23 | |
| 2237 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 2238 | _LIBCPP_HIDE_FROM_ABI | |
| 2239 | void insert_range(_Range&& __range) { | |
| 2240 | for (auto&& __element : __range) { | |
| 2241 | __table_.__insert_multi(std::forward<decltype(__element)>(__element)); | |
| 2242 | } | |
| 2243 | } | |
| 2244 | #endif | |
| 2245 | ||
| 2107 | 2246 | #ifndef _LIBCPP_CXX03_LANG |
| 2108 | 2247 | _LIBCPP_INLINE_VISIBILITY |
| 2109 | 2248 | void insert(initializer_list<value_type> __il) |
| ... | ... | @@ -2128,12 +2267,12 @@ private: |
| 2128 | 2267 | {return __table_.__insert_multi(__p.__i_, _VSTD::forward<_Pp>(__x));} |
| 2129 | 2268 | |
| 2130 | 2269 | template <class... _Args> |
| 2131 | iterator emplace(_Args&&... __args) { | |
| 2270 | _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) { | |
| 2132 | 2271 | return __table_.__emplace_multi(_VSTD::forward<_Args>(__args)...); |
| 2133 | 2272 | } |
| 2134 | 2273 | |
| 2135 | 2274 | template <class... _Args> |
| 2136 | iterator emplace_hint(const_iterator __p, _Args&&... __args) { | |
| 2275 | _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) { | |
| 2137 | 2276 | return __table_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); |
| 2138 | 2277 | } |
| 2139 | 2278 | #endif // _LIBCPP_CXX03_LANG |
| ... | ... | @@ -2151,11 +2290,11 @@ private: |
| 2151 | 2290 | _LIBCPP_INLINE_VISIBILITY |
| 2152 | 2291 | void clear() _NOEXCEPT {__table_.clear();} |
| 2153 | 2292 | |
| 2154 | #if _LIBCPP_STD_VER > 14 | |
| 2293 | #if _LIBCPP_STD_VER >= 17 | |
| 2155 | 2294 | _LIBCPP_INLINE_VISIBILITY |
| 2156 | 2295 | iterator insert(node_type&& __nh) |
| 2157 | 2296 | { |
| 2158 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2297 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2159 | 2298 | "node_type with incompatible allocator passed to unordered_multimap::insert()"); |
| 2160 | 2299 | return __table_.template __node_handle_insert_multi<node_type>( |
| 2161 | 2300 | _VSTD::move(__nh)); |
| ... | ... | @@ -2163,7 +2302,7 @@ private: |
| 2163 | 2302 | _LIBCPP_INLINE_VISIBILITY |
| 2164 | 2303 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 2165 | 2304 | { |
| 2166 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2305 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 2167 | 2306 | "node_type with incompatible allocator passed to unordered_multimap::insert()"); |
| 2168 | 2307 | return __table_.template __node_handle_insert_multi<node_type>( |
| 2169 | 2308 | __hint.__i_, _VSTD::move(__nh)); |
| ... | ... | @@ -2184,32 +2323,32 @@ private: |
| 2184 | 2323 | _LIBCPP_INLINE_VISIBILITY |
| 2185 | 2324 | void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>& __source) |
| 2186 | 2325 | { |
| 2187 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2188 | "merging container with incompatible allocator"); | |
| 2326 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2327 | "merging container with incompatible allocator"); | |
| 2189 | 2328 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 2190 | 2329 | } |
| 2191 | 2330 | template <class _H2, class _P2> |
| 2192 | 2331 | _LIBCPP_INLINE_VISIBILITY |
| 2193 | 2332 | void merge(unordered_multimap<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) |
| 2194 | 2333 | { |
| 2195 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2196 | "merging container with incompatible allocator"); | |
| 2334 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2335 | "merging container with incompatible allocator"); | |
| 2197 | 2336 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 2198 | 2337 | } |
| 2199 | 2338 | template <class _H2, class _P2> |
| 2200 | 2339 | _LIBCPP_INLINE_VISIBILITY |
| 2201 | 2340 | void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>& __source) |
| 2202 | 2341 | { |
| 2203 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2204 | "merging container with incompatible allocator"); | |
| 2342 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2343 | "merging container with incompatible allocator"); | |
| 2205 | 2344 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 2206 | 2345 | } |
| 2207 | 2346 | template <class _H2, class _P2> |
| 2208 | 2347 | _LIBCPP_INLINE_VISIBILITY |
| 2209 | 2348 | void merge(unordered_map<key_type, mapped_type, _H2, _P2, allocator_type>&& __source) |
| 2210 | 2349 | { |
| 2211 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 2212 | "merging container with incompatible allocator"); | |
| 2350 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 2351 | "merging container with incompatible allocator"); | |
| 2213 | 2352 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 2214 | 2353 | } |
| 2215 | 2354 | #endif |
| ... | ... | @@ -2230,31 +2369,31 @@ private: |
| 2230 | 2369 | iterator find(const key_type& __k) {return __table_.find(__k);} |
| 2231 | 2370 | _LIBCPP_INLINE_VISIBILITY |
| 2232 | 2371 | const_iterator find(const key_type& __k) const {return __table_.find(__k);} |
| 2233 | #if _LIBCPP_STD_VER > 17 | |
| 2372 | #if _LIBCPP_STD_VER >= 20 | |
| 2234 | 2373 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 2235 | 2374 | _LIBCPP_INLINE_VISIBILITY |
| 2236 | 2375 | iterator find(const _K2& __k) {return __table_.find(__k);} |
| 2237 | 2376 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 2238 | 2377 | _LIBCPP_INLINE_VISIBILITY |
| 2239 | 2378 | const_iterator find(const _K2& __k) const {return __table_.find(__k);} |
| 2240 | #endif // _LIBCPP_STD_VER > 17 | |
| 2379 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2241 | 2380 | |
| 2242 | 2381 | _LIBCPP_INLINE_VISIBILITY |
| 2243 | 2382 | size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} |
| 2244 | #if _LIBCPP_STD_VER > 17 | |
| 2383 | #if _LIBCPP_STD_VER >= 20 | |
| 2245 | 2384 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 2246 | 2385 | _LIBCPP_INLINE_VISIBILITY |
| 2247 | 2386 | size_type count(const _K2& __k) const {return __table_.__count_multi(__k);} |
| 2248 | #endif // _LIBCPP_STD_VER > 17 | |
| 2387 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2249 | 2388 | |
| 2250 | #if _LIBCPP_STD_VER > 17 | |
| 2389 | #if _LIBCPP_STD_VER >= 20 | |
| 2251 | 2390 | _LIBCPP_INLINE_VISIBILITY |
| 2252 | 2391 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 2253 | 2392 | |
| 2254 | 2393 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 2255 | 2394 | _LIBCPP_INLINE_VISIBILITY |
| 2256 | 2395 | bool contains(const _K2& __k) const {return find(__k) != end();} |
| 2257 | #endif // _LIBCPP_STD_VER > 17 | |
| 2396 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2258 | 2397 | |
| 2259 | 2398 | _LIBCPP_INLINE_VISIBILITY |
| 2260 | 2399 | pair<iterator, iterator> equal_range(const key_type& __k) |
| ... | ... | @@ -2262,7 +2401,7 @@ private: |
| 2262 | 2401 | _LIBCPP_INLINE_VISIBILITY |
| 2263 | 2402 | pair<const_iterator, const_iterator> equal_range(const key_type& __k) const |
| 2264 | 2403 | {return __table_.__equal_range_multi(__k);} |
| 2265 | #if _LIBCPP_STD_VER > 17 | |
| 2404 | #if _LIBCPP_STD_VER >= 20 | |
| 2266 | 2405 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 2267 | 2406 | _LIBCPP_INLINE_VISIBILITY |
| 2268 | 2407 | pair<iterator, iterator> equal_range(const _K2& __k) |
| ... | ... | @@ -2271,7 +2410,7 @@ private: |
| 2271 | 2410 | _LIBCPP_INLINE_VISIBILITY |
| 2272 | 2411 | pair<const_iterator, const_iterator> equal_range(const _K2& __k) const |
| 2273 | 2412 | {return __table_.__equal_range_multi(__k);} |
| 2274 | #endif // _LIBCPP_STD_VER > 17 | |
| 2413 | #endif // _LIBCPP_STD_VER >= 20 | |
| 2275 | 2414 | |
| 2276 | 2415 | _LIBCPP_INLINE_VISIBILITY |
| 2277 | 2416 | size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} |
| ... | ... | @@ -2308,21 +2447,6 @@ private: |
| 2308 | 2447 | void rehash(size_type __n) {__table_.__rehash_multi(__n);} |
| 2309 | 2448 | _LIBCPP_INLINE_VISIBILITY |
| 2310 | 2449 | void reserve(size_type __n) {__table_.__reserve_multi(__n);} |
| 2311 | ||
| 2312 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2313 | ||
| 2314 | bool __dereferenceable(const const_iterator* __i) const | |
| 2315 | {return __table_.__dereferenceable(_VSTD::addressof(__i->__i_));} | |
| 2316 | bool __decrementable(const const_iterator* __i) const | |
| 2317 | {return __table_.__decrementable(_VSTD::addressof(__i->__i_));} | |
| 2318 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 2319 | {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} | |
| 2320 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 2321 | {return __table_.__addable(_VSTD::addressof(__i->__i_), __n);} | |
| 2322 | ||
| 2323 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 2324 | ||
| 2325 | ||
| 2326 | 2450 | }; |
| 2327 | 2451 | |
| 2328 | 2452 | #if _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -2330,7 +2454,7 @@ template<class _InputIterator, |
| 2330 | 2454 | class _Hash = hash<__iter_key_type<_InputIterator>>, |
| 2331 | 2455 | class _Pred = equal_to<__iter_key_type<_InputIterator>>, |
| 2332 | 2456 | class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, |
| 2333 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 2457 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 2334 | 2458 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 2335 | 2459 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 2336 | 2460 | class = enable_if_t<!__is_allocator<_Pred>::value>, |
| ... | ... | @@ -2339,6 +2463,20 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al |
| 2339 | 2463 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) |
| 2340 | 2464 | -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Hash, _Pred, _Allocator>; |
| 2341 | 2465 | |
| 2466 | #if _LIBCPP_STD_VER >= 23 | |
| 2467 | template <ranges::input_range _Range, | |
| 2468 | class _Hash = hash<__range_key_type<_Range>>, | |
| 2469 | class _Pred = equal_to<__range_key_type<_Range>>, | |
| 2470 | class _Allocator = allocator<__range_to_alloc_type<_Range>>, | |
| 2471 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 2472 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 2473 | class = enable_if_t<!__is_allocator<_Pred>::value>, | |
| 2474 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 2475 | unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, | |
| 2476 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) | |
| 2477 | -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, _Pred, _Allocator>; | |
| 2478 | #endif | |
| 2479 | ||
| 2342 | 2480 | template<class _Key, class _Tp, class _Hash = hash<remove_const_t<_Key>>, |
| 2343 | 2481 | class _Pred = equal_to<remove_const_t<_Key>>, |
| 2344 | 2482 | class _Allocator = allocator<pair<const _Key, _Tp>>, |
| ... | ... | @@ -2351,21 +2489,21 @@ unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits< |
| 2351 | 2489 | -> unordered_multimap<remove_const_t<_Key>, _Tp, _Hash, _Pred, _Allocator>; |
| 2352 | 2490 | |
| 2353 | 2491 | template<class _InputIterator, class _Allocator, |
| 2354 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 2492 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 2355 | 2493 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 2356 | 2494 | unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| 2357 | 2495 | -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 2358 | 2496 | hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 2359 | 2497 | |
| 2360 | 2498 | template<class _InputIterator, class _Allocator, |
| 2361 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 2499 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 2362 | 2500 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 2363 | 2501 | unordered_multimap(_InputIterator, _InputIterator, _Allocator) |
| 2364 | 2502 | -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 2365 | 2503 | hash<__iter_key_type<_InputIterator>>, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 2366 | 2504 | |
| 2367 | 2505 | template<class _InputIterator, class _Hash, class _Allocator, |
| 2368 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 2506 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 2369 | 2507 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 2370 | 2508 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 2371 | 2509 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| ... | ... | @@ -2373,6 +2511,30 @@ unordered_multimap(_InputIterator, _InputIterator, typename allocator_traits<_Al |
| 2373 | 2511 | -> unordered_multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, |
| 2374 | 2512 | _Hash, equal_to<__iter_key_type<_InputIterator>>, _Allocator>; |
| 2375 | 2513 | |
| 2514 | #if _LIBCPP_STD_VER >= 23 | |
| 2515 | ||
| 2516 | template <ranges::input_range _Range, class _Allocator, | |
| 2517 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 2518 | unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) | |
| 2519 | -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>, | |
| 2520 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 2521 | ||
| 2522 | template <ranges::input_range _Range, class _Allocator, | |
| 2523 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 2524 | unordered_multimap(from_range_t, _Range&&, _Allocator) | |
| 2525 | -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, hash<__range_key_type<_Range>>, | |
| 2526 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 2527 | ||
| 2528 | template <ranges::input_range _Range, class _Hash, class _Allocator, | |
| 2529 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 2530 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 2531 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 2532 | unordered_multimap(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) | |
| 2533 | -> unordered_multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Hash, | |
| 2534 | equal_to<__range_key_type<_Range>>, _Allocator>; | |
| 2535 | ||
| 2536 | #endif | |
| 2537 | ||
| 2376 | 2538 | template<class _Key, class _Tp, class _Allocator, |
| 2377 | 2539 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 2378 | 2540 | unordered_multimap(initializer_list<pair<_Key, _Tp>>, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| ... | ... | @@ -2401,7 +2563,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2401 | 2563 | size_type __n, const hasher& __hf, const key_equal& __eql) |
| 2402 | 2564 | : __table_(__hf, __eql) |
| 2403 | 2565 | { |
| 2404 | _VSTD::__debug_db_insert_c(this); | |
| 2405 | 2566 | __table_.__rehash_multi(__n); |
| 2406 | 2567 | } |
| 2407 | 2568 | |
| ... | ... | @@ -2411,7 +2572,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2411 | 2572 | const allocator_type& __a) |
| 2412 | 2573 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 2413 | 2574 | { |
| 2414 | _VSTD::__debug_db_insert_c(this); | |
| 2415 | 2575 | __table_.__rehash_multi(__n); |
| 2416 | 2576 | } |
| 2417 | 2577 | |
| ... | ... | @@ -2420,7 +2580,6 @@ template <class _InputIterator> |
| 2420 | 2580 | unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2421 | 2581 | _InputIterator __first, _InputIterator __last) |
| 2422 | 2582 | { |
| 2423 | _VSTD::__debug_db_insert_c(this); | |
| 2424 | 2583 | insert(__first, __last); |
| 2425 | 2584 | } |
| 2426 | 2585 | |
| ... | ... | @@ -2431,7 +2590,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2431 | 2590 | const hasher& __hf, const key_equal& __eql) |
| 2432 | 2591 | : __table_(__hf, __eql) |
| 2433 | 2592 | { |
| 2434 | _VSTD::__debug_db_insert_c(this); | |
| 2435 | 2593 | __table_.__rehash_multi(__n); |
| 2436 | 2594 | insert(__first, __last); |
| 2437 | 2595 | } |
| ... | ... | @@ -2443,7 +2601,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2443 | 2601 | const hasher& __hf, const key_equal& __eql, const allocator_type& __a) |
| 2444 | 2602 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 2445 | 2603 | { |
| 2446 | _VSTD::__debug_db_insert_c(this); | |
| 2447 | 2604 | __table_.__rehash_multi(__n); |
| 2448 | 2605 | insert(__first, __last); |
| 2449 | 2606 | } |
| ... | ... | @@ -2454,7 +2611,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2454 | 2611 | const allocator_type& __a) |
| 2455 | 2612 | : __table_(typename __table::allocator_type(__a)) |
| 2456 | 2613 | { |
| 2457 | _VSTD::__debug_db_insert_c(this); | |
| 2458 | 2614 | } |
| 2459 | 2615 | |
| 2460 | 2616 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -2462,7 +2618,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2462 | 2618 | const unordered_multimap& __u) |
| 2463 | 2619 | : __table_(__u.__table_) |
| 2464 | 2620 | { |
| 2465 | _VSTD::__debug_db_insert_c(this); | |
| 2466 | 2621 | __table_.__rehash_multi(__u.bucket_count()); |
| 2467 | 2622 | insert(__u.begin(), __u.end()); |
| 2468 | 2623 | } |
| ... | ... | @@ -2472,7 +2627,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2472 | 2627 | const unordered_multimap& __u, const allocator_type& __a) |
| 2473 | 2628 | : __table_(__u.__table_, typename __table::allocator_type(__a)) |
| 2474 | 2629 | { |
| 2475 | _VSTD::__debug_db_insert_c(this); | |
| 2476 | 2630 | __table_.__rehash_multi(__u.bucket_count()); |
| 2477 | 2631 | insert(__u.begin(), __u.end()); |
| 2478 | 2632 | } |
| ... | ... | @@ -2486,8 +2640,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2486 | 2640 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) |
| 2487 | 2641 | : __table_(_VSTD::move(__u.__table_)) |
| 2488 | 2642 | { |
| 2489 | _VSTD::__debug_db_insert_c(this); | |
| 2490 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 2491 | 2643 | } |
| 2492 | 2644 | |
| 2493 | 2645 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -2495,7 +2647,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2495 | 2647 | unordered_multimap&& __u, const allocator_type& __a) |
| 2496 | 2648 | : __table_(_VSTD::move(__u.__table_), typename __table::allocator_type(__a)) |
| 2497 | 2649 | { |
| 2498 | _VSTD::__debug_db_insert_c(this); | |
| 2499 | 2650 | if (__a != __u.get_allocator()) |
| 2500 | 2651 | { |
| 2501 | 2652 | iterator __i = __u.begin(); |
| ... | ... | @@ -2505,15 +2656,12 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2505 | 2656 | __u.__table_.remove((__i++).__i_)->__value_.__move()); |
| 2506 | 2657 | } |
| 2507 | 2658 | } |
| 2508 | else | |
| 2509 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 2510 | 2659 | } |
| 2511 | 2660 | |
| 2512 | 2661 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| 2513 | 2662 | unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2514 | 2663 | initializer_list<value_type> __il) |
| 2515 | 2664 | { |
| 2516 | _VSTD::__debug_db_insert_c(this); | |
| 2517 | 2665 | insert(__il.begin(), __il.end()); |
| 2518 | 2666 | } |
| 2519 | 2667 | |
| ... | ... | @@ -2523,7 +2671,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2523 | 2671 | const key_equal& __eql) |
| 2524 | 2672 | : __table_(__hf, __eql) |
| 2525 | 2673 | { |
| 2526 | _VSTD::__debug_db_insert_c(this); | |
| 2527 | 2674 | __table_.__rehash_multi(__n); |
| 2528 | 2675 | insert(__il.begin(), __il.end()); |
| 2529 | 2676 | } |
| ... | ... | @@ -2534,7 +2681,6 @@ unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( |
| 2534 | 2681 | const key_equal& __eql, const allocator_type& __a) |
| 2535 | 2682 | : __table_(__hf, __eql, typename __table::allocator_type(__a)) |
| 2536 | 2683 | { |
| 2537 | _VSTD::__debug_db_insert_c(this); | |
| 2538 | 2684 | __table_.__rehash_multi(__n); |
| 2539 | 2685 | insert(__il.begin(), __il.end()); |
| 2540 | 2686 | } |
| ... | ... | @@ -2584,7 +2730,7 @@ swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 2584 | 2730 | __x.swap(__y); |
| 2585 | 2731 | } |
| 2586 | 2732 | |
| 2587 | #if _LIBCPP_STD_VER > 17 | |
| 2733 | #if _LIBCPP_STD_VER >= 20 | |
| 2588 | 2734 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc, |
| 2589 | 2735 | class _Predicate> |
| 2590 | 2736 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -2618,6 +2764,8 @@ operator==(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 2618 | 2764 | return true; |
| 2619 | 2765 | } |
| 2620 | 2766 | |
| 2767 | #if _LIBCPP_STD_VER <= 17 | |
| 2768 | ||
| 2621 | 2769 | template <class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> |
| 2622 | 2770 | inline _LIBCPP_INLINE_VISIBILITY |
| 2623 | 2771 | bool |
| ... | ... | @@ -2627,17 +2775,19 @@ operator!=(const unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, |
| 2627 | 2775 | return !(__x == __y); |
| 2628 | 2776 | } |
| 2629 | 2777 | |
| 2778 | #endif | |
| 2779 | ||
| 2630 | 2780 | _LIBCPP_END_NAMESPACE_STD |
| 2631 | 2781 | |
| 2632 | #if _LIBCPP_STD_VER > 14 | |
| 2782 | #if _LIBCPP_STD_VER >= 17 | |
| 2633 | 2783 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 2634 | 2784 | namespace pmr { |
| 2635 | 2785 | template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> |
| 2636 | using unordered_map = | |
| 2786 | using unordered_map _LIBCPP_AVAILABILITY_PMR = | |
| 2637 | 2787 | std::unordered_map<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; |
| 2638 | 2788 | |
| 2639 | 2789 | template <class _KeyT, class _ValueT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> |
| 2640 | using unordered_multimap = | |
| 2790 | using unordered_multimap _LIBCPP_AVAILABILITY_PMR = | |
| 2641 | 2791 | std::unordered_multimap<_KeyT, _ValueT, _HashT, _PredT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>; |
| 2642 | 2792 | } // namespace pmr |
| 2643 | 2793 | _LIBCPP_END_NAMESPACE_STD |
| ... | ... | @@ -2647,7 +2797,9 @@ _LIBCPP_END_NAMESPACE_STD |
| 2647 | 2797 | # include <algorithm> |
| 2648 | 2798 | # include <bit> |
| 2649 | 2799 | # include <concepts> |
| 2800 | # include <cstdlib> | |
| 2650 | 2801 | # include <iterator> |
| 2802 | # include <type_traits> | |
| 2651 | 2803 | #endif |
| 2652 | 2804 | |
| 2653 | 2805 | #endif // _LIBCPP_UNORDERED_MAP |
lib/libcxx/include/unordered_set+321-163| ... | ... | @@ -58,6 +58,10 @@ public: |
| 58 | 58 | size_type n = 0, const hasher& hf = hasher(), |
| 59 | 59 | const key_equal& eql = key_equal(), |
| 60 | 60 | const allocator_type& a = allocator_type()); |
| 61 | template<container-compatible-range<value_type> R> | |
| 62 | unordered_set(from_range_t, R&& rg, size_type n = see below, | |
| 63 | const hasher& hf = hasher(), const key_equal& eql = key_equal(), | |
| 64 | const allocator_type& a = allocator_type()); // C++23 | |
| 61 | 65 | explicit unordered_set(const allocator_type&); |
| 62 | 66 | unordered_set(const unordered_set&); |
| 63 | 67 | unordered_set(const unordered_set&, const Allocator&); |
| ... | ... | @@ -77,6 +81,12 @@ public: |
| 77 | 81 | template <class InputIterator> |
| 78 | 82 | unordered_set(InputIterator f, InputIterator l, size_type n, |
| 79 | 83 | const hasher& hf, const allocator_type& a); // C++14 |
| 84 | template<container-compatible-range<value_type> R> | |
| 85 | unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) | |
| 86 | : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 | |
| 87 | template<container-compatible-range<value_type> R> | |
| 88 | unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) | |
| 89 | : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 | |
| 80 | 90 | unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 |
| 81 | 91 | unordered_set(initializer_list<value_type> il, size_type n, |
| 82 | 92 | const hasher& hf, const allocator_type& a); // C++14 |
| ... | ... | @@ -113,6 +123,8 @@ public: |
| 113 | 123 | iterator insert(const_iterator hint, value_type&& obj); |
| 114 | 124 | template <class InputIterator> |
| 115 | 125 | void insert(InputIterator first, InputIterator last); |
| 126 | template<container-compatible-range<value_type> R> | |
| 127 | void insert_range(R&& rg); // C++23 | |
| 116 | 128 | void insert(initializer_list<value_type>); |
| 117 | 129 | |
| 118 | 130 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -191,6 +203,13 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type = see |
| 191 | 203 | -> unordered_set<typename iterator_traits<InputIterator>::value_type, |
| 192 | 204 | Hash, Pred, Allocator>; // C++17 |
| 193 | 205 | |
| 206 | template<ranges::input_range R, | |
| 207 | class Hash = hash<ranges::range_value_t<R>>, | |
| 208 | class Pred = equal_to<ranges::range_value_t<R>>, | |
| 209 | class Allocator = allocator<ranges::range_value_t<R>>> | |
| 210 | unordered_set(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) | |
| 211 | -> unordered_set<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23 | |
| 212 | ||
| 194 | 213 | template<class T, class Hash = hash<T>, |
| 195 | 214 | class Pred = equal_to<T>, class Allocator = allocator<T>> |
| 196 | 215 | unordered_set(initializer_list<T>, typename see below::size_type = see below, |
| ... | ... | @@ -211,6 +230,21 @@ unordered_set(InputIterator, InputIterator, typename see below::size_type, |
| 211 | 230 | equal_to<typename iterator_traits<InputIterator>::value_type>, |
| 212 | 231 | Allocator>; // C++17 |
| 213 | 232 | |
| 233 | template<ranges::input_range R, class Allocator> | |
| 234 | unordered_set(from_range_t, R&&, typename see below::size_type, Allocator) | |
| 235 | -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, | |
| 236 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 237 | ||
| 238 | template<ranges::input_range R, class Allocator> | |
| 239 | unordered_set(from_range_t, R&&, Allocator) | |
| 240 | -> unordered_set<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, | |
| 241 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 242 | ||
| 243 | template<ranges::input_range R, class Hash, class Allocator> | |
| 244 | unordered_set(from_range_t, R&&, typename see below::size_type, Hash, Allocator) | |
| 245 | -> unordered_set<ranges::range_value_t<R>, Hash, | |
| 246 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 247 | ||
| 214 | 248 | template<class T, class Allocator> |
| 215 | 249 | unordered_set(initializer_list<T>, typename see below::size_type, Allocator) |
| 216 | 250 | -> unordered_set<T, hash<T>, equal_to<T>, Allocator>; // C++17 |
| ... | ... | @@ -232,7 +266,7 @@ template <class Value, class Hash, class Pred, class Alloc> |
| 232 | 266 | template <class Value, class Hash, class Pred, class Alloc> |
| 233 | 267 | bool |
| 234 | 268 | operator!=(const unordered_set<Value, Hash, Pred, Alloc>& x, |
| 235 | const unordered_set<Value, Hash, Pred, Alloc>& y); | |
| 269 | const unordered_set<Value, Hash, Pred, Alloc>& y); // removed in C++20 | |
| 236 | 270 | |
| 237 | 271 | template <class Value, class Hash = hash<Value>, class Pred = equal_to<Value>, |
| 238 | 272 | class Alloc = allocator<Value>> |
| ... | ... | @@ -272,6 +306,10 @@ public: |
| 272 | 306 | size_type n = 0, const hasher& hf = hasher(), |
| 273 | 307 | const key_equal& eql = key_equal(), |
| 274 | 308 | const allocator_type& a = allocator_type()); |
| 309 | template<container-compatible-range<value_type> R> | |
| 310 | unordered_multiset(from_range_t, R&& rg, size_type n = see below, | |
| 311 | const hasher& hf = hasher(), const key_equal& eql = key_equal(), | |
| 312 | const allocator_type& a = allocator_type()); // C++23 | |
| 275 | 313 | explicit unordered_multiset(const allocator_type&); |
| 276 | 314 | unordered_multiset(const unordered_multiset&); |
| 277 | 315 | unordered_multiset(const unordered_multiset&, const Allocator&); |
| ... | ... | @@ -291,6 +329,12 @@ public: |
| 291 | 329 | template <class InputIterator> |
| 292 | 330 | unordered_multiset(InputIterator f, InputIterator l, size_type n, |
| 293 | 331 | const hasher& hf, const allocator_type& a); // C++14 |
| 332 | template<container-compatible-range<value_type> R> | |
| 333 | unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) | |
| 334 | : unordered_multiset(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } // C++23 | |
| 335 | template<container-compatible-range<value_type> R> | |
| 336 | unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) | |
| 337 | : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } // C++23 | |
| 294 | 338 | unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a); // C++14 |
| 295 | 339 | unordered_multiset(initializer_list<value_type> il, size_type n, |
| 296 | 340 | const hasher& hf, const allocator_type& a); // C++14 |
| ... | ... | @@ -327,6 +371,8 @@ public: |
| 327 | 371 | iterator insert(const_iterator hint, value_type&& obj); |
| 328 | 372 | template <class InputIterator> |
| 329 | 373 | void insert(InputIterator first, InputIterator last); |
| 374 | template<container-compatible-range<value_type> R> | |
| 375 | void insert_range(R&& rg); // C++23 | |
| 330 | 376 | void insert(initializer_list<value_type>); |
| 331 | 377 | |
| 332 | 378 | node_type extract(const_iterator position); // C++17 |
| ... | ... | @@ -405,6 +451,13 @@ unordered_multiset(InputIterator, InputIterator, see below::size_type = see belo |
| 405 | 451 | -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, |
| 406 | 452 | Hash, Pred, Allocator>; // C++17 |
| 407 | 453 | |
| 454 | template<ranges::input_range R, | |
| 455 | class Hash = hash<ranges::range_value_t<R>>, | |
| 456 | class Pred = equal_to<ranges::range_value_t<R>>, | |
| 457 | class Allocator = allocator<ranges::range_value_t<R>>> | |
| 458 | unordered_multiset(from_range_t, R&&, typename see below::size_type = see below, Hash = Hash(), Pred = Pred(), Allocator = Allocator()) | |
| 459 | -> unordered_multiset<ranges::range_value_t<R>, Hash, Pred, Allocator>; // C++23 | |
| 460 | ||
| 408 | 461 | template<class T, class Hash = hash<T>, |
| 409 | 462 | class Pred = equal_to<T>, class Allocator = allocator<T>> |
| 410 | 463 | unordered_multiset(initializer_list<T>, typename see below::size_type = see below, |
| ... | ... | @@ -424,6 +477,21 @@ unordered_multiset(InputIterator, InputIterator, typename see below::size_type, |
| 424 | 477 | -> unordered_multiset<typename iterator_traits<InputIterator>::value_type, Hash, |
| 425 | 478 | equal_to<typename iterator_traits<InputIterator>::value_type>, Allocator>; // C++17 |
| 426 | 479 | |
| 480 | template<ranges::input_range R, class Allocator> | |
| 481 | unordered_multiset(from_range_t, R&&, typename see below::size_type, Allocator) | |
| 482 | -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, | |
| 483 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 484 | ||
| 485 | template<ranges::input_range R, class Allocator> | |
| 486 | unordered_multiset(from_range_t, R&&, Allocator) | |
| 487 | -> unordered_multiset<ranges::range_value_t<R>, hash<ranges::range_value_t<R>>, | |
| 488 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 489 | ||
| 490 | template<ranges::input_range R, class Hash, class Allocator> | |
| 491 | unordered_multiset(from_range_t, R&&, typename see below::size_type, Hash, Allocator) | |
| 492 | -> unordered_multiset<ranges::range_value_t<R>, Hash, | |
| 493 | equal_to<ranges::range_value_t<R>>, Allocator>; // C++23 | |
| 494 | ||
| 427 | 495 | template<class T, class Allocator> |
| 428 | 496 | unordered_multiset(initializer_list<T>, typename see below::size_type, Allocator) |
| 429 | 497 | -> unordered_multiset<T, hash<T>, equal_to<T>, Allocator>; // C++17 |
| ... | ... | @@ -454,25 +522,29 @@ template <class Value, class Hash, class Pred, class Alloc> |
| 454 | 522 | template <class Value, class Hash, class Pred, class Alloc> |
| 455 | 523 | bool |
| 456 | 524 | operator!=(const unordered_multiset<Value, Hash, Pred, Alloc>& x, |
| 457 | const unordered_multiset<Value, Hash, Pred, Alloc>& y); | |
| 525 | const unordered_multiset<Value, Hash, Pred, Alloc>& y); // removed in C++20 | |
| 458 | 526 | } // std |
| 459 | 527 | |
| 460 | 528 | */ |
| 461 | 529 | |
| 462 | 530 | #include <__algorithm/is_permutation.h> |
| 463 | 531 | #include <__assert> // all public C++ headers provide the assertion handler |
| 532 | #include <__availability> | |
| 464 | 533 | #include <__config> |
| 465 | #include <__debug> | |
| 466 | 534 | #include <__functional/is_transparent.h> |
| 467 | 535 | #include <__functional/operations.h> |
| 468 | 536 | #include <__hash_table> |
| 469 | 537 | #include <__iterator/distance.h> |
| 470 | 538 | #include <__iterator/erase_if_container.h> |
| 471 | 539 | #include <__iterator/iterator_traits.h> |
| 540 | #include <__iterator/ranges_iterator_traits.h> | |
| 472 | 541 | #include <__memory/addressof.h> |
| 473 | 542 | #include <__memory/allocator.h> |
| 474 | 543 | #include <__memory_resource/polymorphic_allocator.h> |
| 475 | 544 | #include <__node_handle> |
| 545 | #include <__ranges/concepts.h> | |
| 546 | #include <__ranges/container_compatible_range.h> | |
| 547 | #include <__ranges/from_range.h> | |
| 476 | 548 | #include <__type_traits/is_allocator.h> |
| 477 | 549 | #include <__utility/forward.h> |
| 478 | 550 | #include <version> |
| ... | ... | @@ -513,7 +585,7 @@ public: |
| 513 | 585 | typedef value_type& reference; |
| 514 | 586 | typedef const value_type& const_reference; |
| 515 | 587 | static_assert((is_same<value_type, typename allocator_type::value_type>::value), |
| 516 | "Invalid allocator::value_type"); | |
| 588 | "Allocator::value_type must be same type as value_type"); | |
| 517 | 589 | |
| 518 | 590 | static_assert(is_same<allocator_type, __rebind_alloc<allocator_traits<allocator_type>, value_type> >::value, |
| 519 | 591 | "[allocator.requirements] states that rebinding an allocator to the same type should result in the " |
| ... | ... | @@ -535,7 +607,7 @@ public: |
| 535 | 607 | typedef typename __table::const_local_iterator local_iterator; |
| 536 | 608 | typedef typename __table::const_local_iterator const_local_iterator; |
| 537 | 609 | |
| 538 | #if _LIBCPP_STD_VER > 14 | |
| 610 | #if _LIBCPP_STD_VER >= 17 | |
| 539 | 611 | typedef __set_node_handle<typename __table::__node, allocator_type> node_type; |
| 540 | 612 | typedef __insert_return_type<iterator, node_type> insert_return_type; |
| 541 | 613 | #endif |
| ... | ... | @@ -549,11 +621,10 @@ public: |
| 549 | 621 | unordered_set() |
| 550 | 622 | _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) |
| 551 | 623 | { |
| 552 | _VSTD::__debug_db_insert_c(this); | |
| 553 | 624 | } |
| 554 | explicit unordered_set(size_type __n, const hasher& __hf = hasher(), | |
| 625 | explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(), | |
| 555 | 626 | const key_equal& __eql = key_equal()); |
| 556 | #if _LIBCPP_STD_VER > 11 | |
| 627 | #if _LIBCPP_STD_VER >= 14 | |
| 557 | 628 | inline _LIBCPP_INLINE_VISIBILITY |
| 558 | 629 | unordered_set(size_type __n, const allocator_type& __a) |
| 559 | 630 | : unordered_set(__n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -561,46 +632,74 @@ public: |
| 561 | 632 | unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) |
| 562 | 633 | : unordered_set(__n, __hf, key_equal(), __a) {} |
| 563 | 634 | #endif |
| 564 | unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, | |
| 635 | _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, | |
| 565 | 636 | const allocator_type& __a); |
| 566 | 637 | template <class _InputIterator> |
| 567 | unordered_set(_InputIterator __first, _InputIterator __last); | |
| 638 | _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last); | |
| 568 | 639 | template <class _InputIterator> |
| 569 | unordered_set(_InputIterator __first, _InputIterator __last, | |
| 640 | _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, | |
| 570 | 641 | size_type __n, const hasher& __hf = hasher(), |
| 571 | 642 | const key_equal& __eql = key_equal()); |
| 572 | 643 | template <class _InputIterator> |
| 573 | unordered_set(_InputIterator __first, _InputIterator __last, | |
| 644 | _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, | |
| 574 | 645 | size_type __n, const hasher& __hf, const key_equal& __eql, |
| 575 | 646 | const allocator_type& __a); |
| 576 | #if _LIBCPP_STD_VER > 11 | |
| 647 | ||
| 648 | #if _LIBCPP_STD_VER >= 23 | |
| 649 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 650 | _LIBCPP_HIDE_FROM_ABI | |
| 651 | unordered_set(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, | |
| 652 | const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), | |
| 653 | const allocator_type& __a = allocator_type()) | |
| 654 | : __table_(__hf, __eql, __a) { | |
| 655 | if (__n > 0) { | |
| 656 | __table_.__rehash_unique(__n); | |
| 657 | } | |
| 658 | insert_range(std::forward<_Range>(__range)); | |
| 659 | } | |
| 660 | #endif | |
| 661 | ||
| 662 | #if _LIBCPP_STD_VER >= 14 | |
| 577 | 663 | template <class _InputIterator> |
| 578 | 664 | inline _LIBCPP_INLINE_VISIBILITY |
| 579 | 665 | unordered_set(_InputIterator __first, _InputIterator __last, |
| 580 | 666 | size_type __n, const allocator_type& __a) |
| 581 | 667 | : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) {} |
| 582 | 668 | template <class _InputIterator> |
| 583 | unordered_set(_InputIterator __first, _InputIterator __last, | |
| 669 | _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, | |
| 584 | 670 | size_type __n, const hasher& __hf, const allocator_type& __a) |
| 585 | 671 | : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} |
| 586 | 672 | #endif |
| 673 | ||
| 674 | #if _LIBCPP_STD_VER >= 23 | |
| 675 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 676 | _LIBCPP_HIDE_FROM_ABI | |
| 677 | unordered_set(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) | |
| 678 | : unordered_set(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} | |
| 679 | ||
| 680 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 681 | _LIBCPP_HIDE_FROM_ABI | |
| 682 | unordered_set(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) | |
| 683 | : unordered_set(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} | |
| 684 | #endif | |
| 685 | ||
| 587 | 686 | _LIBCPP_INLINE_VISIBILITY |
| 588 | 687 | explicit unordered_set(const allocator_type& __a); |
| 589 | unordered_set(const unordered_set& __u); | |
| 590 | unordered_set(const unordered_set& __u, const allocator_type& __a); | |
| 688 | _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u); | |
| 689 | _LIBCPP_HIDE_FROM_ABI unordered_set(const unordered_set& __u, const allocator_type& __a); | |
| 591 | 690 | #ifndef _LIBCPP_CXX03_LANG |
| 592 | 691 | _LIBCPP_INLINE_VISIBILITY |
| 593 | 692 | unordered_set(unordered_set&& __u) |
| 594 | 693 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); |
| 595 | unordered_set(unordered_set&& __u, const allocator_type& __a); | |
| 596 | unordered_set(initializer_list<value_type> __il); | |
| 597 | unordered_set(initializer_list<value_type> __il, size_type __n, | |
| 694 | _LIBCPP_HIDE_FROM_ABI unordered_set(unordered_set&& __u, const allocator_type& __a); | |
| 695 | _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il); | |
| 696 | _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n, | |
| 598 | 697 | const hasher& __hf = hasher(), |
| 599 | 698 | const key_equal& __eql = key_equal()); |
| 600 | unordered_set(initializer_list<value_type> __il, size_type __n, | |
| 699 | _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list<value_type> __il, size_type __n, | |
| 601 | 700 | const hasher& __hf, const key_equal& __eql, |
| 602 | 701 | const allocator_type& __a); |
| 603 | #if _LIBCPP_STD_VER > 11 | |
| 702 | #if _LIBCPP_STD_VER >= 14 | |
| 604 | 703 | inline _LIBCPP_INLINE_VISIBILITY |
| 605 | 704 | unordered_set(initializer_list<value_type> __il, size_type __n, |
| 606 | 705 | const allocator_type& __a) |
| ... | ... | @@ -661,11 +760,7 @@ public: |
| 661 | 760 | {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);} |
| 662 | 761 | template <class... _Args> |
| 663 | 762 | _LIBCPP_INLINE_VISIBILITY |
| 664 | iterator emplace_hint(const_iterator __p, _Args&&... __args) { | |
| 665 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, | |
| 666 | "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not" | |
| 667 | " referring to this unordered_set"); | |
| 668 | (void)__p; | |
| 763 | iterator emplace_hint(const_iterator, _Args&&... __args) { | |
| 669 | 764 | return __table_.__emplace_unique(std::forward<_Args>(__args)...).first; |
| 670 | 765 | } |
| 671 | 766 | |
| ... | ... | @@ -673,11 +768,7 @@ public: |
| 673 | 768 | pair<iterator, bool> insert(value_type&& __x) |
| 674 | 769 | {return __table_.__insert_unique(_VSTD::move(__x));} |
| 675 | 770 | _LIBCPP_INLINE_VISIBILITY |
| 676 | iterator insert(const_iterator __p, value_type&& __x) { | |
| 677 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, | |
| 678 | "unordered_set::insert(const_iterator, value_type&&) called with an iterator not" | |
| 679 | " referring to this unordered_set"); | |
| 680 | (void)__p; | |
| 771 | iterator insert(const_iterator, value_type&& __x) { | |
| 681 | 772 | return insert(std::move(__x)).first; |
| 682 | 773 | } |
| 683 | 774 | |
| ... | ... | @@ -690,17 +781,23 @@ public: |
| 690 | 781 | {return __table_.__insert_unique(__x);} |
| 691 | 782 | |
| 692 | 783 | _LIBCPP_INLINE_VISIBILITY |
| 693 | iterator insert(const_iterator __p, const value_type& __x) { | |
| 694 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this, | |
| 695 | "unordered_set::insert(const_iterator, const value_type&) called with an iterator not" | |
| 696 | " referring to this unordered_set"); | |
| 697 | (void)__p; | |
| 784 | iterator insert(const_iterator, const value_type& __x) { | |
| 698 | 785 | return insert(__x).first; |
| 699 | 786 | } |
| 700 | 787 | template <class _InputIterator> |
| 701 | 788 | _LIBCPP_INLINE_VISIBILITY |
| 702 | 789 | void insert(_InputIterator __first, _InputIterator __last); |
| 703 | 790 | |
| 791 | #if _LIBCPP_STD_VER >= 23 | |
| 792 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 793 | _LIBCPP_HIDE_FROM_ABI | |
| 794 | void insert_range(_Range&& __range) { | |
| 795 | for (auto&& __element : __range) { | |
| 796 | __table_.__insert_unique(std::forward<decltype(__element)>(__element)); | |
| 797 | } | |
| 798 | } | |
| 799 | #endif | |
| 800 | ||
| 704 | 801 | _LIBCPP_INLINE_VISIBILITY |
| 705 | 802 | iterator erase(const_iterator __p) {return __table_.erase(__p);} |
| 706 | 803 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -711,11 +808,11 @@ public: |
| 711 | 808 | _LIBCPP_INLINE_VISIBILITY |
| 712 | 809 | void clear() _NOEXCEPT {__table_.clear();} |
| 713 | 810 | |
| 714 | #if _LIBCPP_STD_VER > 14 | |
| 811 | #if _LIBCPP_STD_VER >= 17 | |
| 715 | 812 | _LIBCPP_INLINE_VISIBILITY |
| 716 | 813 | insert_return_type insert(node_type&& __nh) |
| 717 | 814 | { |
| 718 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 815 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 719 | 816 | "node_type with incompatible allocator passed to unordered_set::insert()"); |
| 720 | 817 | return __table_.template __node_handle_insert_unique< |
| 721 | 818 | node_type, insert_return_type>(_VSTD::move(__nh)); |
| ... | ... | @@ -723,7 +820,7 @@ public: |
| 723 | 820 | _LIBCPP_INLINE_VISIBILITY |
| 724 | 821 | iterator insert(const_iterator __h, node_type&& __nh) |
| 725 | 822 | { |
| 726 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 823 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 727 | 824 | "node_type with incompatible allocator passed to unordered_set::insert()"); |
| 728 | 825 | return __table_.template __node_handle_insert_unique<node_type>( |
| 729 | 826 | __h, _VSTD::move(__nh)); |
| ... | ... | @@ -743,32 +840,32 @@ public: |
| 743 | 840 | _LIBCPP_INLINE_VISIBILITY |
| 744 | 841 | void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) |
| 745 | 842 | { |
| 746 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 747 | "merging container with incompatible allocator"); | |
| 843 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 844 | "merging container with incompatible allocator"); | |
| 748 | 845 | __table_.__node_handle_merge_unique(__source.__table_); |
| 749 | 846 | } |
| 750 | 847 | template<class _H2, class _P2> |
| 751 | 848 | _LIBCPP_INLINE_VISIBILITY |
| 752 | 849 | void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) |
| 753 | 850 | { |
| 754 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 755 | "merging container with incompatible allocator"); | |
| 851 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 852 | "merging container with incompatible allocator"); | |
| 756 | 853 | __table_.__node_handle_merge_unique(__source.__table_); |
| 757 | 854 | } |
| 758 | 855 | template<class _H2, class _P2> |
| 759 | 856 | _LIBCPP_INLINE_VISIBILITY |
| 760 | 857 | void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) |
| 761 | 858 | { |
| 762 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 763 | "merging container with incompatible allocator"); | |
| 859 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 860 | "merging container with incompatible allocator"); | |
| 764 | 861 | __table_.__node_handle_merge_unique(__source.__table_); |
| 765 | 862 | } |
| 766 | 863 | template<class _H2, class _P2> |
| 767 | 864 | _LIBCPP_INLINE_VISIBILITY |
| 768 | 865 | void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) |
| 769 | 866 | { |
| 770 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 771 | "merging container with incompatible allocator"); | |
| 867 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 868 | "merging container with incompatible allocator"); | |
| 772 | 869 | __table_.__node_handle_merge_unique(__source.__table_); |
| 773 | 870 | } |
| 774 | 871 | #endif |
| ... | ... | @@ -787,31 +884,31 @@ public: |
| 787 | 884 | iterator find(const key_type& __k) {return __table_.find(__k);} |
| 788 | 885 | _LIBCPP_INLINE_VISIBILITY |
| 789 | 886 | const_iterator find(const key_type& __k) const {return __table_.find(__k);} |
| 790 | #if _LIBCPP_STD_VER > 17 | |
| 887 | #if _LIBCPP_STD_VER >= 20 | |
| 791 | 888 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 792 | 889 | _LIBCPP_INLINE_VISIBILITY |
| 793 | 890 | iterator find(const _K2& __k) {return __table_.find(__k);} |
| 794 | 891 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 795 | 892 | _LIBCPP_INLINE_VISIBILITY |
| 796 | 893 | const_iterator find(const _K2& __k) const {return __table_.find(__k);} |
| 797 | #endif // _LIBCPP_STD_VER > 17 | |
| 894 | #endif // _LIBCPP_STD_VER >= 20 | |
| 798 | 895 | |
| 799 | 896 | _LIBCPP_INLINE_VISIBILITY |
| 800 | 897 | size_type count(const key_type& __k) const {return __table_.__count_unique(__k);} |
| 801 | #if _LIBCPP_STD_VER > 17 | |
| 898 | #if _LIBCPP_STD_VER >= 20 | |
| 802 | 899 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 803 | 900 | _LIBCPP_INLINE_VISIBILITY |
| 804 | 901 | size_type count(const _K2& __k) const {return __table_.__count_unique(__k);} |
| 805 | #endif // _LIBCPP_STD_VER > 17 | |
| 902 | #endif // _LIBCPP_STD_VER >= 20 | |
| 806 | 903 | |
| 807 | #if _LIBCPP_STD_VER > 17 | |
| 904 | #if _LIBCPP_STD_VER >= 20 | |
| 808 | 905 | _LIBCPP_INLINE_VISIBILITY |
| 809 | 906 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 810 | 907 | |
| 811 | 908 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 812 | 909 | _LIBCPP_INLINE_VISIBILITY |
| 813 | 910 | bool contains(const _K2& __k) const {return find(__k) != end();} |
| 814 | #endif // _LIBCPP_STD_VER > 17 | |
| 911 | #endif // _LIBCPP_STD_VER >= 20 | |
| 815 | 912 | |
| 816 | 913 | _LIBCPP_INLINE_VISIBILITY |
| 817 | 914 | pair<iterator, iterator> equal_range(const key_type& __k) |
| ... | ... | @@ -819,7 +916,7 @@ public: |
| 819 | 916 | _LIBCPP_INLINE_VISIBILITY |
| 820 | 917 | pair<const_iterator, const_iterator> equal_range(const key_type& __k) const |
| 821 | 918 | {return __table_.__equal_range_unique(__k);} |
| 822 | #if _LIBCPP_STD_VER > 17 | |
| 919 | #if _LIBCPP_STD_VER >= 20 | |
| 823 | 920 | template <class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 824 | 921 | _LIBCPP_INLINE_VISIBILITY |
| 825 | 922 | pair<iterator, iterator> equal_range(const _K2& __k) |
| ... | ... | @@ -828,7 +925,7 @@ public: |
| 828 | 925 | _LIBCPP_INLINE_VISIBILITY |
| 829 | 926 | pair<const_iterator, const_iterator> equal_range(const _K2& __k) const |
| 830 | 927 | {return __table_.__equal_range_unique(__k);} |
| 831 | #endif // _LIBCPP_STD_VER > 17 | |
| 928 | #endif // _LIBCPP_STD_VER >= 20 | |
| 832 | 929 | |
| 833 | 930 | _LIBCPP_INLINE_VISIBILITY |
| 834 | 931 | size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} |
| ... | ... | @@ -863,20 +960,6 @@ public: |
| 863 | 960 | void rehash(size_type __n) {__table_.__rehash_unique(__n);} |
| 864 | 961 | _LIBCPP_INLINE_VISIBILITY |
| 865 | 962 | void reserve(size_type __n) {__table_.__reserve_unique(__n);} |
| 866 | ||
| 867 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 868 | ||
| 869 | bool __dereferenceable(const const_iterator* __i) const | |
| 870 | {return __table_.__dereferenceable(__i);} | |
| 871 | bool __decrementable(const const_iterator* __i) const | |
| 872 | {return __table_.__decrementable(__i);} | |
| 873 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 874 | {return __table_.__addable(__i, __n);} | |
| 875 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 876 | {return __table_.__addable(__i, __n);} | |
| 877 | ||
| 878 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 879 | ||
| 880 | 963 | }; |
| 881 | 964 | |
| 882 | 965 | #if _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -884,7 +967,7 @@ template<class _InputIterator, |
| 884 | 967 | class _Hash = hash<__iter_value_type<_InputIterator>>, |
| 885 | 968 | class _Pred = equal_to<__iter_value_type<_InputIterator>>, |
| 886 | 969 | class _Allocator = allocator<__iter_value_type<_InputIterator>>, |
| 887 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 970 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 888 | 971 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 889 | 972 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 890 | 973 | class = enable_if_t<!__is_allocator<_Pred>::value>, |
| ... | ... | @@ -893,6 +976,20 @@ unordered_set(_InputIterator, _InputIterator, typename allocator_traits<_Allocat |
| 893 | 976 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) |
| 894 | 977 | -> unordered_set<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; |
| 895 | 978 | |
| 979 | #if _LIBCPP_STD_VER >= 23 | |
| 980 | template <ranges::input_range _Range, | |
| 981 | class _Hash = hash<ranges::range_value_t<_Range>>, | |
| 982 | class _Pred = equal_to<ranges::range_value_t<_Range>>, | |
| 983 | class _Allocator = allocator<ranges::range_value_t<_Range>>, | |
| 984 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 985 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 986 | class = enable_if_t<!__is_allocator<_Pred>::value>, | |
| 987 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 988 | unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, | |
| 989 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) | |
| 990 | -> unordered_set<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23 | |
| 991 | #endif | |
| 992 | ||
| 896 | 993 | template<class _Tp, class _Hash = hash<_Tp>, |
| 897 | 994 | class _Pred = equal_to<_Tp>, |
| 898 | 995 | class _Allocator = allocator<_Tp>, |
| ... | ... | @@ -905,7 +1002,7 @@ unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size |
| 905 | 1002 | -> unordered_set<_Tp, _Hash, _Pred, _Allocator>; |
| 906 | 1003 | |
| 907 | 1004 | template<class _InputIterator, class _Allocator, |
| 908 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1005 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 909 | 1006 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 910 | 1007 | unordered_set(_InputIterator, _InputIterator, |
| 911 | 1008 | typename allocator_traits<_Allocator>::size_type, _Allocator) |
| ... | ... | @@ -915,7 +1012,7 @@ unordered_set(_InputIterator, _InputIterator, |
| 915 | 1012 | _Allocator>; |
| 916 | 1013 | |
| 917 | 1014 | template<class _InputIterator, class _Hash, class _Allocator, |
| 918 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1015 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 919 | 1016 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 920 | 1017 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 921 | 1018 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| ... | ... | @@ -925,6 +1022,29 @@ unordered_set(_InputIterator, _InputIterator, |
| 925 | 1022 | equal_to<__iter_value_type<_InputIterator>>, |
| 926 | 1023 | _Allocator>; |
| 927 | 1024 | |
| 1025 | #if _LIBCPP_STD_VER >= 23 | |
| 1026 | ||
| 1027 | template <ranges::input_range _Range, class _Allocator, | |
| 1028 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1029 | unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) | |
| 1030 | -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, | |
| 1031 | equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1032 | ||
| 1033 | template <ranges::input_range _Range, class _Allocator, | |
| 1034 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1035 | unordered_set(from_range_t, _Range&&, _Allocator) | |
| 1036 | -> unordered_set<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, | |
| 1037 | equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1038 | ||
| 1039 | template <ranges::input_range _Range, class _Hash, class _Allocator, | |
| 1040 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 1041 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 1042 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1043 | unordered_set(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) | |
| 1044 | -> unordered_set<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1045 | ||
| 1046 | #endif | |
| 1047 | ||
| 928 | 1048 | template<class _Tp, class _Allocator, |
| 929 | 1049 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 930 | 1050 | unordered_set(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| ... | ... | @@ -943,7 +1063,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, |
| 943 | 1063 | const hasher& __hf, const key_equal& __eql) |
| 944 | 1064 | : __table_(__hf, __eql) |
| 945 | 1065 | { |
| 946 | _VSTD::__debug_db_insert_c(this); | |
| 947 | 1066 | __table_.__rehash_unique(__n); |
| 948 | 1067 | } |
| 949 | 1068 | |
| ... | ... | @@ -952,7 +1071,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set(size_type __n, |
| 952 | 1071 | const hasher& __hf, const key_equal& __eql, const allocator_type& __a) |
| 953 | 1072 | : __table_(__hf, __eql, __a) |
| 954 | 1073 | { |
| 955 | _VSTD::__debug_db_insert_c(this); | |
| 956 | 1074 | __table_.__rehash_unique(__n); |
| 957 | 1075 | } |
| 958 | 1076 | |
| ... | ... | @@ -961,7 +1079,6 @@ template <class _InputIterator> |
| 961 | 1079 | unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 962 | 1080 | _InputIterator __first, _InputIterator __last) |
| 963 | 1081 | { |
| 964 | _VSTD::__debug_db_insert_c(this); | |
| 965 | 1082 | insert(__first, __last); |
| 966 | 1083 | } |
| 967 | 1084 | |
| ... | ... | @@ -972,7 +1089,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 972 | 1089 | const hasher& __hf, const key_equal& __eql) |
| 973 | 1090 | : __table_(__hf, __eql) |
| 974 | 1091 | { |
| 975 | _VSTD::__debug_db_insert_c(this); | |
| 976 | 1092 | __table_.__rehash_unique(__n); |
| 977 | 1093 | insert(__first, __last); |
| 978 | 1094 | } |
| ... | ... | @@ -984,7 +1100,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 984 | 1100 | const hasher& __hf, const key_equal& __eql, const allocator_type& __a) |
| 985 | 1101 | : __table_(__hf, __eql, __a) |
| 986 | 1102 | { |
| 987 | _VSTD::__debug_db_insert_c(this); | |
| 988 | 1103 | __table_.__rehash_unique(__n); |
| 989 | 1104 | insert(__first, __last); |
| 990 | 1105 | } |
| ... | ... | @@ -995,7 +1110,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 995 | 1110 | const allocator_type& __a) |
| 996 | 1111 | : __table_(__a) |
| 997 | 1112 | { |
| 998 | _VSTD::__debug_db_insert_c(this); | |
| 999 | 1113 | } |
| 1000 | 1114 | |
| 1001 | 1115 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1003,7 +1117,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1003 | 1117 | const unordered_set& __u) |
| 1004 | 1118 | : __table_(__u.__table_) |
| 1005 | 1119 | { |
| 1006 | _VSTD::__debug_db_insert_c(this); | |
| 1007 | 1120 | __table_.__rehash_unique(__u.bucket_count()); |
| 1008 | 1121 | insert(__u.begin(), __u.end()); |
| 1009 | 1122 | } |
| ... | ... | @@ -1013,7 +1126,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1013 | 1126 | const unordered_set& __u, const allocator_type& __a) |
| 1014 | 1127 | : __table_(__u.__table_, __a) |
| 1015 | 1128 | { |
| 1016 | _VSTD::__debug_db_insert_c(this); | |
| 1017 | 1129 | __table_.__rehash_unique(__u.bucket_count()); |
| 1018 | 1130 | insert(__u.begin(), __u.end()); |
| 1019 | 1131 | } |
| ... | ... | @@ -1027,8 +1139,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1027 | 1139 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) |
| 1028 | 1140 | : __table_(_VSTD::move(__u.__table_)) |
| 1029 | 1141 | { |
| 1030 | _VSTD::__debug_db_insert_c(this); | |
| 1031 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1032 | 1142 | } |
| 1033 | 1143 | |
| 1034 | 1144 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1036,22 +1146,18 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1036 | 1146 | unordered_set&& __u, const allocator_type& __a) |
| 1037 | 1147 | : __table_(_VSTD::move(__u.__table_), __a) |
| 1038 | 1148 | { |
| 1039 | _VSTD::__debug_db_insert_c(this); | |
| 1040 | 1149 | if (__a != __u.get_allocator()) |
| 1041 | 1150 | { |
| 1042 | 1151 | iterator __i = __u.begin(); |
| 1043 | 1152 | while (__u.size() != 0) |
| 1044 | 1153 | __table_.__insert_unique(_VSTD::move(__u.__table_.remove(__i++)->__value_)); |
| 1045 | 1154 | } |
| 1046 | else | |
| 1047 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1048 | 1155 | } |
| 1049 | 1156 | |
| 1050 | 1157 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| 1051 | 1158 | unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1052 | 1159 | initializer_list<value_type> __il) |
| 1053 | 1160 | { |
| 1054 | _VSTD::__debug_db_insert_c(this); | |
| 1055 | 1161 | insert(__il.begin(), __il.end()); |
| 1056 | 1162 | } |
| 1057 | 1163 | |
| ... | ... | @@ -1061,7 +1167,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1061 | 1167 | const key_equal& __eql) |
| 1062 | 1168 | : __table_(__hf, __eql) |
| 1063 | 1169 | { |
| 1064 | _VSTD::__debug_db_insert_c(this); | |
| 1065 | 1170 | __table_.__rehash_unique(__n); |
| 1066 | 1171 | insert(__il.begin(), __il.end()); |
| 1067 | 1172 | } |
| ... | ... | @@ -1072,7 +1177,6 @@ unordered_set<_Value, _Hash, _Pred, _Alloc>::unordered_set( |
| 1072 | 1177 | const key_equal& __eql, const allocator_type& __a) |
| 1073 | 1178 | : __table_(__hf, __eql, __a) |
| 1074 | 1179 | { |
| 1075 | _VSTD::__debug_db_insert_c(this); | |
| 1076 | 1180 | __table_.__rehash_unique(__n); |
| 1077 | 1181 | insert(__il.begin(), __il.end()); |
| 1078 | 1182 | } |
| ... | ... | @@ -1120,7 +1224,7 @@ swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1120 | 1224 | __x.swap(__y); |
| 1121 | 1225 | } |
| 1122 | 1226 | |
| 1123 | #if _LIBCPP_STD_VER > 17 | |
| 1227 | #if _LIBCPP_STD_VER >= 20 | |
| 1124 | 1228 | template <class _Value, class _Hash, class _Pred, class _Alloc, |
| 1125 | 1229 | class _Predicate> |
| 1126 | 1230 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1150,6 +1254,8 @@ operator==(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1150 | 1254 | return true; |
| 1151 | 1255 | } |
| 1152 | 1256 | |
| 1257 | #if _LIBCPP_STD_VER <= 17 | |
| 1258 | ||
| 1153 | 1259 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| 1154 | 1260 | inline _LIBCPP_INLINE_VISIBILITY |
| 1155 | 1261 | bool |
| ... | ... | @@ -1159,6 +1265,8 @@ operator!=(const unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1159 | 1265 | return !(__x == __y); |
| 1160 | 1266 | } |
| 1161 | 1267 | |
| 1268 | #endif | |
| 1269 | ||
| 1162 | 1270 | template <class _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, |
| 1163 | 1271 | class _Alloc = allocator<_Value> > |
| 1164 | 1272 | class _LIBCPP_TEMPLATE_VIS unordered_multiset |
| ... | ... | @@ -1173,7 +1281,7 @@ public: |
| 1173 | 1281 | typedef value_type& reference; |
| 1174 | 1282 | typedef const value_type& const_reference; |
| 1175 | 1283 | static_assert((is_same<value_type, typename allocator_type::value_type>::value), |
| 1176 | "Invalid allocator::value_type"); | |
| 1284 | "Allocator::value_type must be same type as value_type"); | |
| 1177 | 1285 | |
| 1178 | 1286 | private: |
| 1179 | 1287 | typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table; |
| ... | ... | @@ -1191,7 +1299,7 @@ public: |
| 1191 | 1299 | typedef typename __table::const_local_iterator local_iterator; |
| 1192 | 1300 | typedef typename __table::const_local_iterator const_local_iterator; |
| 1193 | 1301 | |
| 1194 | #if _LIBCPP_STD_VER > 14 | |
| 1302 | #if _LIBCPP_STD_VER >= 17 | |
| 1195 | 1303 | typedef __set_node_handle<typename __table::__node, allocator_type> node_type; |
| 1196 | 1304 | #endif |
| 1197 | 1305 | |
| ... | ... | @@ -1204,13 +1312,12 @@ public: |
| 1204 | 1312 | unordered_multiset() |
| 1205 | 1313 | _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) |
| 1206 | 1314 | { |
| 1207 | _VSTD::__debug_db_insert_c(this); | |
| 1208 | 1315 | } |
| 1209 | explicit unordered_multiset(size_type __n, const hasher& __hf = hasher(), | |
| 1316 | explicit _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf = hasher(), | |
| 1210 | 1317 | const key_equal& __eql = key_equal()); |
| 1211 | unordered_multiset(size_type __n, const hasher& __hf, | |
| 1318 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, | |
| 1212 | 1319 | const key_equal& __eql, const allocator_type& __a); |
| 1213 | #if _LIBCPP_STD_VER > 11 | |
| 1320 | #if _LIBCPP_STD_VER >= 14 | |
| 1214 | 1321 | inline _LIBCPP_INLINE_VISIBILITY |
| 1215 | 1322 | unordered_multiset(size_type __n, const allocator_type& __a) |
| 1216 | 1323 | : unordered_multiset(__n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -1219,16 +1326,31 @@ public: |
| 1219 | 1326 | : unordered_multiset(__n, __hf, key_equal(), __a) {} |
| 1220 | 1327 | #endif |
| 1221 | 1328 | template <class _InputIterator> |
| 1222 | unordered_multiset(_InputIterator __first, _InputIterator __last); | |
| 1329 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last); | |
| 1223 | 1330 | template <class _InputIterator> |
| 1224 | unordered_multiset(_InputIterator __first, _InputIterator __last, | |
| 1331 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, | |
| 1225 | 1332 | size_type __n, const hasher& __hf = hasher(), |
| 1226 | 1333 | const key_equal& __eql = key_equal()); |
| 1227 | 1334 | template <class _InputIterator> |
| 1228 | unordered_multiset(_InputIterator __first, _InputIterator __last, | |
| 1335 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, | |
| 1229 | 1336 | size_type __n , const hasher& __hf, |
| 1230 | 1337 | const key_equal& __eql, const allocator_type& __a); |
| 1231 | #if _LIBCPP_STD_VER > 11 | |
| 1338 | ||
| 1339 | #if _LIBCPP_STD_VER >= 23 | |
| 1340 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1341 | _LIBCPP_HIDE_FROM_ABI | |
| 1342 | unordered_multiset(from_range_t, _Range&& __range, size_type __n = /*implementation-defined*/0, | |
| 1343 | const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), | |
| 1344 | const allocator_type& __a = allocator_type()) | |
| 1345 | : __table_(__hf, __eql, __a) { | |
| 1346 | if (__n > 0) { | |
| 1347 | __table_.__rehash_multi(__n); | |
| 1348 | } | |
| 1349 | insert_range(std::forward<_Range>(__range)); | |
| 1350 | } | |
| 1351 | #endif | |
| 1352 | ||
| 1353 | #if _LIBCPP_STD_VER >= 14 | |
| 1232 | 1354 | template <class _InputIterator> |
| 1233 | 1355 | inline _LIBCPP_INLINE_VISIBILITY |
| 1234 | 1356 | unordered_multiset(_InputIterator __first, _InputIterator __last, |
| ... | ... | @@ -1240,23 +1362,36 @@ public: |
| 1240 | 1362 | size_type __n, const hasher& __hf, const allocator_type& __a) |
| 1241 | 1363 | : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} |
| 1242 | 1364 | #endif |
| 1365 | ||
| 1366 | #if _LIBCPP_STD_VER >= 23 | |
| 1367 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1368 | _LIBCPP_HIDE_FROM_ABI | |
| 1369 | unordered_multiset(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) | |
| 1370 | : unordered_multiset(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} | |
| 1371 | ||
| 1372 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1373 | _LIBCPP_HIDE_FROM_ABI | |
| 1374 | unordered_multiset(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) | |
| 1375 | : unordered_multiset(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} | |
| 1376 | #endif | |
| 1377 | ||
| 1243 | 1378 | _LIBCPP_INLINE_VISIBILITY |
| 1244 | 1379 | explicit unordered_multiset(const allocator_type& __a); |
| 1245 | unordered_multiset(const unordered_multiset& __u); | |
| 1246 | unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); | |
| 1380 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u); | |
| 1381 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(const unordered_multiset& __u, const allocator_type& __a); | |
| 1247 | 1382 | #ifndef _LIBCPP_CXX03_LANG |
| 1248 | 1383 | _LIBCPP_INLINE_VISIBILITY |
| 1249 | 1384 | unordered_multiset(unordered_multiset&& __u) |
| 1250 | 1385 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); |
| 1251 | unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); | |
| 1252 | unordered_multiset(initializer_list<value_type> __il); | |
| 1253 | unordered_multiset(initializer_list<value_type> __il, size_type __n, | |
| 1386 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(unordered_multiset&& __u, const allocator_type& __a); | |
| 1387 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il); | |
| 1388 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n, | |
| 1254 | 1389 | const hasher& __hf = hasher(), |
| 1255 | 1390 | const key_equal& __eql = key_equal()); |
| 1256 | unordered_multiset(initializer_list<value_type> __il, size_type __n, | |
| 1391 | _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list<value_type> __il, size_type __n, | |
| 1257 | 1392 | const hasher& __hf, const key_equal& __eql, |
| 1258 | 1393 | const allocator_type& __a); |
| 1259 | #if _LIBCPP_STD_VER > 11 | |
| 1394 | #if _LIBCPP_STD_VER >= 14 | |
| 1260 | 1395 | inline _LIBCPP_INLINE_VISIBILITY |
| 1261 | 1396 | unordered_multiset(initializer_list<value_type> __il, size_type __n, const allocator_type& __a) |
| 1262 | 1397 | : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {} |
| ... | ... | @@ -1280,7 +1415,7 @@ public: |
| 1280 | 1415 | _LIBCPP_INLINE_VISIBILITY |
| 1281 | 1416 | unordered_multiset& operator=(unordered_multiset&& __u) |
| 1282 | 1417 | _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); |
| 1283 | unordered_multiset& operator=(initializer_list<value_type> __il); | |
| 1418 | _LIBCPP_HIDE_FROM_ABI unordered_multiset& operator=(initializer_list<value_type> __il); | |
| 1284 | 1419 | #endif // _LIBCPP_CXX03_LANG |
| 1285 | 1420 | |
| 1286 | 1421 | _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1338,11 +1473,21 @@ public: |
| 1338 | 1473 | _LIBCPP_INLINE_VISIBILITY |
| 1339 | 1474 | void insert(_InputIterator __first, _InputIterator __last); |
| 1340 | 1475 | |
| 1341 | #if _LIBCPP_STD_VER > 14 | |
| 1476 | #if _LIBCPP_STD_VER >= 23 | |
| 1477 | template <_ContainerCompatibleRange<value_type> _Range> | |
| 1478 | _LIBCPP_HIDE_FROM_ABI | |
| 1479 | void insert_range(_Range&& __range) { | |
| 1480 | for (auto&& __element : __range) { | |
| 1481 | __table_.__insert_multi(std::forward<decltype(__element)>(__element)); | |
| 1482 | } | |
| 1483 | } | |
| 1484 | #endif | |
| 1485 | ||
| 1486 | #if _LIBCPP_STD_VER >= 17 | |
| 1342 | 1487 | _LIBCPP_INLINE_VISIBILITY |
| 1343 | 1488 | iterator insert(node_type&& __nh) |
| 1344 | 1489 | { |
| 1345 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1490 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1346 | 1491 | "node_type with incompatible allocator passed to unordered_multiset::insert()"); |
| 1347 | 1492 | return __table_.template __node_handle_insert_multi<node_type>( |
| 1348 | 1493 | _VSTD::move(__nh)); |
| ... | ... | @@ -1350,7 +1495,7 @@ public: |
| 1350 | 1495 | _LIBCPP_INLINE_VISIBILITY |
| 1351 | 1496 | iterator insert(const_iterator __hint, node_type&& __nh) |
| 1352 | 1497 | { |
| 1353 | _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1498 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(), | |
| 1354 | 1499 | "node_type with incompatible allocator passed to unordered_multiset::insert()"); |
| 1355 | 1500 | return __table_.template __node_handle_insert_multi<node_type>( |
| 1356 | 1501 | __hint, _VSTD::move(__nh)); |
| ... | ... | @@ -1371,32 +1516,32 @@ public: |
| 1371 | 1516 | _LIBCPP_INLINE_VISIBILITY |
| 1372 | 1517 | void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>& __source) |
| 1373 | 1518 | { |
| 1374 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1375 | "merging container with incompatible allocator"); | |
| 1519 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1520 | "merging container with incompatible allocator"); | |
| 1376 | 1521 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 1377 | 1522 | } |
| 1378 | 1523 | template <class _H2, class _P2> |
| 1379 | 1524 | _LIBCPP_INLINE_VISIBILITY |
| 1380 | 1525 | void merge(unordered_multiset<key_type, _H2, _P2, allocator_type>&& __source) |
| 1381 | 1526 | { |
| 1382 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1383 | "merging container with incompatible allocator"); | |
| 1527 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1528 | "merging container with incompatible allocator"); | |
| 1384 | 1529 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 1385 | 1530 | } |
| 1386 | 1531 | template <class _H2, class _P2> |
| 1387 | 1532 | _LIBCPP_INLINE_VISIBILITY |
| 1388 | 1533 | void merge(unordered_set<key_type, _H2, _P2, allocator_type>& __source) |
| 1389 | 1534 | { |
| 1390 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1391 | "merging container with incompatible allocator"); | |
| 1535 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1536 | "merging container with incompatible allocator"); | |
| 1392 | 1537 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 1393 | 1538 | } |
| 1394 | 1539 | template <class _H2, class _P2> |
| 1395 | 1540 | _LIBCPP_INLINE_VISIBILITY |
| 1396 | 1541 | void merge(unordered_set<key_type, _H2, _P2, allocator_type>&& __source) |
| 1397 | 1542 | { |
| 1398 | _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), | |
| 1399 | "merging container with incompatible allocator"); | |
| 1543 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__source.get_allocator() == get_allocator(), | |
| 1544 | "merging container with incompatible allocator"); | |
| 1400 | 1545 | return __table_.__node_handle_merge_multi(__source.__table_); |
| 1401 | 1546 | } |
| 1402 | 1547 | #endif |
| ... | ... | @@ -1425,31 +1570,31 @@ public: |
| 1425 | 1570 | iterator find(const key_type& __k) {return __table_.find(__k);} |
| 1426 | 1571 | _LIBCPP_INLINE_VISIBILITY |
| 1427 | 1572 | const_iterator find(const key_type& __k) const {return __table_.find(__k);} |
| 1428 | #if _LIBCPP_STD_VER > 17 | |
| 1573 | #if _LIBCPP_STD_VER >= 20 | |
| 1429 | 1574 | template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1430 | 1575 | _LIBCPP_INLINE_VISIBILITY |
| 1431 | 1576 | iterator find(const _K2& __k) {return __table_.find(__k);} |
| 1432 | 1577 | template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1433 | 1578 | _LIBCPP_INLINE_VISIBILITY |
| 1434 | 1579 | const_iterator find(const _K2& __k) const {return __table_.find(__k);} |
| 1435 | #endif // _LIBCPP_STD_VER > 17 | |
| 1580 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1436 | 1581 | |
| 1437 | 1582 | _LIBCPP_INLINE_VISIBILITY |
| 1438 | 1583 | size_type count(const key_type& __k) const {return __table_.__count_multi(__k);} |
| 1439 | #if _LIBCPP_STD_VER > 17 | |
| 1584 | #if _LIBCPP_STD_VER >= 20 | |
| 1440 | 1585 | template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1441 | 1586 | _LIBCPP_INLINE_VISIBILITY |
| 1442 | 1587 | size_type count(const _K2& __k) const {return __table_.__count_multi(__k);} |
| 1443 | #endif // _LIBCPP_STD_VER > 17 | |
| 1588 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1444 | 1589 | |
| 1445 | #if _LIBCPP_STD_VER > 17 | |
| 1590 | #if _LIBCPP_STD_VER >= 20 | |
| 1446 | 1591 | _LIBCPP_INLINE_VISIBILITY |
| 1447 | 1592 | bool contains(const key_type& __k) const {return find(__k) != end();} |
| 1448 | 1593 | |
| 1449 | 1594 | template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1450 | 1595 | _LIBCPP_INLINE_VISIBILITY |
| 1451 | 1596 | bool contains(const _K2& __k) const {return find(__k) != end();} |
| 1452 | #endif // _LIBCPP_STD_VER > 17 | |
| 1597 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1453 | 1598 | |
| 1454 | 1599 | _LIBCPP_INLINE_VISIBILITY |
| 1455 | 1600 | pair<iterator, iterator> equal_range(const key_type& __k) |
| ... | ... | @@ -1457,7 +1602,7 @@ public: |
| 1457 | 1602 | _LIBCPP_INLINE_VISIBILITY |
| 1458 | 1603 | pair<const_iterator, const_iterator> equal_range(const key_type& __k) const |
| 1459 | 1604 | {return __table_.__equal_range_multi(__k);} |
| 1460 | #if _LIBCPP_STD_VER > 17 | |
| 1605 | #if _LIBCPP_STD_VER >= 20 | |
| 1461 | 1606 | template<class _K2, enable_if_t<__is_transparent<hasher, _K2>::value && __is_transparent<key_equal, _K2>::value>* = nullptr> |
| 1462 | 1607 | _LIBCPP_INLINE_VISIBILITY |
| 1463 | 1608 | pair<iterator, iterator> equal_range(const _K2& __k) |
| ... | ... | @@ -1466,7 +1611,7 @@ public: |
| 1466 | 1611 | _LIBCPP_INLINE_VISIBILITY |
| 1467 | 1612 | pair<const_iterator, const_iterator> equal_range(const _K2& __k) const |
| 1468 | 1613 | {return __table_.__equal_range_multi(__k);} |
| 1469 | #endif // _LIBCPP_STD_VER > 17 | |
| 1614 | #endif // _LIBCPP_STD_VER >= 20 | |
| 1470 | 1615 | |
| 1471 | 1616 | _LIBCPP_INLINE_VISIBILITY |
| 1472 | 1617 | size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} |
| ... | ... | @@ -1501,20 +1646,6 @@ public: |
| 1501 | 1646 | void rehash(size_type __n) {__table_.__rehash_multi(__n);} |
| 1502 | 1647 | _LIBCPP_INLINE_VISIBILITY |
| 1503 | 1648 | void reserve(size_type __n) {__table_.__reserve_multi(__n);} |
| 1504 | ||
| 1505 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1506 | ||
| 1507 | bool __dereferenceable(const const_iterator* __i) const | |
| 1508 | {return __table_.__dereferenceable(__i);} | |
| 1509 | bool __decrementable(const const_iterator* __i) const | |
| 1510 | {return __table_.__decrementable(__i);} | |
| 1511 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1512 | {return __table_.__addable(__i, __n);} | |
| 1513 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1514 | {return __table_.__addable(__i, __n);} | |
| 1515 | ||
| 1516 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 1517 | ||
| 1518 | 1649 | }; |
| 1519 | 1650 | |
| 1520 | 1651 | #if _LIBCPP_STD_VER >= 17 |
| ... | ... | @@ -1522,7 +1653,7 @@ template<class _InputIterator, |
| 1522 | 1653 | class _Hash = hash<__iter_value_type<_InputIterator>>, |
| 1523 | 1654 | class _Pred = equal_to<__iter_value_type<_InputIterator>>, |
| 1524 | 1655 | class _Allocator = allocator<__iter_value_type<_InputIterator>>, |
| 1525 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1656 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1526 | 1657 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 1527 | 1658 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 1528 | 1659 | class = enable_if_t<!__is_allocator<_Pred>::value>, |
| ... | ... | @@ -1531,6 +1662,20 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al |
| 1531 | 1662 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) |
| 1532 | 1663 | -> unordered_multiset<__iter_value_type<_InputIterator>, _Hash, _Pred, _Allocator>; |
| 1533 | 1664 | |
| 1665 | #if _LIBCPP_STD_VER >= 23 | |
| 1666 | template <ranges::input_range _Range, | |
| 1667 | class _Hash = hash<ranges::range_value_t<_Range>>, | |
| 1668 | class _Pred = equal_to<ranges::range_value_t<_Range>>, | |
| 1669 | class _Allocator = allocator<ranges::range_value_t<_Range>>, | |
| 1670 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 1671 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 1672 | class = enable_if_t<!__is_allocator<_Pred>::value>, | |
| 1673 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1674 | unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type = 0, | |
| 1675 | _Hash = _Hash(), _Pred = _Pred(), _Allocator = _Allocator()) | |
| 1676 | -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, _Pred, _Allocator>; // C++23 | |
| 1677 | #endif | |
| 1678 | ||
| 1534 | 1679 | template<class _Tp, class _Hash = hash<_Tp>, |
| 1535 | 1680 | class _Pred = equal_to<_Tp>, class _Allocator = allocator<_Tp>, |
| 1536 | 1681 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| ... | ... | @@ -1542,7 +1687,7 @@ unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>: |
| 1542 | 1687 | -> unordered_multiset<_Tp, _Hash, _Pred, _Allocator>; |
| 1543 | 1688 | |
| 1544 | 1689 | template<class _InputIterator, class _Allocator, |
| 1545 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1690 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1546 | 1691 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 1547 | 1692 | unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| 1548 | 1693 | -> unordered_multiset<__iter_value_type<_InputIterator>, |
| ... | ... | @@ -1551,7 +1696,7 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al |
| 1551 | 1696 | _Allocator>; |
| 1552 | 1697 | |
| 1553 | 1698 | template<class _InputIterator, class _Hash, class _Allocator, |
| 1554 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1699 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 1555 | 1700 | class = enable_if_t<!__is_allocator<_Hash>::value>, |
| 1556 | 1701 | class = enable_if_t<!is_integral<_Hash>::value>, |
| 1557 | 1702 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| ... | ... | @@ -1561,6 +1706,29 @@ unordered_multiset(_InputIterator, _InputIterator, typename allocator_traits<_Al |
| 1561 | 1706 | equal_to<__iter_value_type<_InputIterator>>, |
| 1562 | 1707 | _Allocator>; |
| 1563 | 1708 | |
| 1709 | #if _LIBCPP_STD_VER >= 23 | |
| 1710 | ||
| 1711 | template <ranges::input_range _Range, class _Allocator, | |
| 1712 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1713 | unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Allocator) | |
| 1714 | -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, | |
| 1715 | equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1716 | ||
| 1717 | template <ranges::input_range _Range, class _Allocator, | |
| 1718 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1719 | unordered_multiset(from_range_t, _Range&&, _Allocator) | |
| 1720 | -> unordered_multiset<ranges::range_value_t<_Range>, hash<ranges::range_value_t<_Range>>, | |
| 1721 | equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1722 | ||
| 1723 | template <ranges::input_range _Range, class _Hash, class _Allocator, | |
| 1724 | class = enable_if_t<!__is_allocator<_Hash>::value>, | |
| 1725 | class = enable_if_t<!is_integral<_Hash>::value>, | |
| 1726 | class = enable_if_t<__is_allocator<_Allocator>::value>> | |
| 1727 | unordered_multiset(from_range_t, _Range&&, typename allocator_traits<_Allocator>::size_type, _Hash, _Allocator) | |
| 1728 | -> unordered_multiset<ranges::range_value_t<_Range>, _Hash, equal_to<ranges::range_value_t<_Range>>, _Allocator>; | |
| 1729 | ||
| 1730 | #endif | |
| 1731 | ||
| 1564 | 1732 | template<class _Tp, class _Allocator, |
| 1565 | 1733 | class = enable_if_t<__is_allocator<_Allocator>::value>> |
| 1566 | 1734 | unordered_multiset(initializer_list<_Tp>, typename allocator_traits<_Allocator>::size_type, _Allocator) |
| ... | ... | @@ -1579,7 +1747,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1579 | 1747 | size_type __n, const hasher& __hf, const key_equal& __eql) |
| 1580 | 1748 | : __table_(__hf, __eql) |
| 1581 | 1749 | { |
| 1582 | _VSTD::__debug_db_insert_c(this); | |
| 1583 | 1750 | __table_.__rehash_multi(__n); |
| 1584 | 1751 | } |
| 1585 | 1752 | |
| ... | ... | @@ -1589,7 +1756,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1589 | 1756 | const allocator_type& __a) |
| 1590 | 1757 | : __table_(__hf, __eql, __a) |
| 1591 | 1758 | { |
| 1592 | _VSTD::__debug_db_insert_c(this); | |
| 1593 | 1759 | __table_.__rehash_multi(__n); |
| 1594 | 1760 | } |
| 1595 | 1761 | |
| ... | ... | @@ -1598,7 +1764,6 @@ template <class _InputIterator> |
| 1598 | 1764 | unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1599 | 1765 | _InputIterator __first, _InputIterator __last) |
| 1600 | 1766 | { |
| 1601 | _VSTD::__debug_db_insert_c(this); | |
| 1602 | 1767 | insert(__first, __last); |
| 1603 | 1768 | } |
| 1604 | 1769 | |
| ... | ... | @@ -1609,7 +1774,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1609 | 1774 | const hasher& __hf, const key_equal& __eql) |
| 1610 | 1775 | : __table_(__hf, __eql) |
| 1611 | 1776 | { |
| 1612 | _VSTD::__debug_db_insert_c(this); | |
| 1613 | 1777 | __table_.__rehash_multi(__n); |
| 1614 | 1778 | insert(__first, __last); |
| 1615 | 1779 | } |
| ... | ... | @@ -1621,7 +1785,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1621 | 1785 | const hasher& __hf, const key_equal& __eql, const allocator_type& __a) |
| 1622 | 1786 | : __table_(__hf, __eql, __a) |
| 1623 | 1787 | { |
| 1624 | _VSTD::__debug_db_insert_c(this); | |
| 1625 | 1788 | __table_.__rehash_multi(__n); |
| 1626 | 1789 | insert(__first, __last); |
| 1627 | 1790 | } |
| ... | ... | @@ -1632,7 +1795,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1632 | 1795 | const allocator_type& __a) |
| 1633 | 1796 | : __table_(__a) |
| 1634 | 1797 | { |
| 1635 | _VSTD::__debug_db_insert_c(this); | |
| 1636 | 1798 | } |
| 1637 | 1799 | |
| 1638 | 1800 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1640,7 +1802,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1640 | 1802 | const unordered_multiset& __u) |
| 1641 | 1803 | : __table_(__u.__table_) |
| 1642 | 1804 | { |
| 1643 | _VSTD::__debug_db_insert_c(this); | |
| 1644 | 1805 | __table_.__rehash_multi(__u.bucket_count()); |
| 1645 | 1806 | insert(__u.begin(), __u.end()); |
| 1646 | 1807 | } |
| ... | ... | @@ -1650,7 +1811,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1650 | 1811 | const unordered_multiset& __u, const allocator_type& __a) |
| 1651 | 1812 | : __table_(__u.__table_, __a) |
| 1652 | 1813 | { |
| 1653 | _VSTD::__debug_db_insert_c(this); | |
| 1654 | 1814 | __table_.__rehash_multi(__u.bucket_count()); |
| 1655 | 1815 | insert(__u.begin(), __u.end()); |
| 1656 | 1816 | } |
| ... | ... | @@ -1664,8 +1824,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1664 | 1824 | _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) |
| 1665 | 1825 | : __table_(_VSTD::move(__u.__table_)) |
| 1666 | 1826 | { |
| 1667 | _VSTD::__debug_db_insert_c(this); | |
| 1668 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1669 | 1827 | } |
| 1670 | 1828 | |
| 1671 | 1829 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| ... | ... | @@ -1673,22 +1831,18 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1673 | 1831 | unordered_multiset&& __u, const allocator_type& __a) |
| 1674 | 1832 | : __table_(_VSTD::move(__u.__table_), __a) |
| 1675 | 1833 | { |
| 1676 | _VSTD::__debug_db_insert_c(this); | |
| 1677 | 1834 | if (__a != __u.get_allocator()) |
| 1678 | 1835 | { |
| 1679 | 1836 | iterator __i = __u.begin(); |
| 1680 | 1837 | while (__u.size() != 0) |
| 1681 | 1838 | __table_.__insert_multi(_VSTD::move(__u.__table_.remove(__i++)->__value_)); |
| 1682 | 1839 | } |
| 1683 | else | |
| 1684 | std::__debug_db_swap(this, std::addressof(__u)); | |
| 1685 | 1840 | } |
| 1686 | 1841 | |
| 1687 | 1842 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| 1688 | 1843 | unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1689 | 1844 | initializer_list<value_type> __il) |
| 1690 | 1845 | { |
| 1691 | _VSTD::__debug_db_insert_c(this); | |
| 1692 | 1846 | insert(__il.begin(), __il.end()); |
| 1693 | 1847 | } |
| 1694 | 1848 | |
| ... | ... | @@ -1698,7 +1852,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1698 | 1852 | const key_equal& __eql) |
| 1699 | 1853 | : __table_(__hf, __eql) |
| 1700 | 1854 | { |
| 1701 | _VSTD::__debug_db_insert_c(this); | |
| 1702 | 1855 | __table_.__rehash_multi(__n); |
| 1703 | 1856 | insert(__il.begin(), __il.end()); |
| 1704 | 1857 | } |
| ... | ... | @@ -1709,7 +1862,6 @@ unordered_multiset<_Value, _Hash, _Pred, _Alloc>::unordered_multiset( |
| 1709 | 1862 | const key_equal& __eql, const allocator_type& __a) |
| 1710 | 1863 | : __table_(__hf, __eql, __a) |
| 1711 | 1864 | { |
| 1712 | _VSTD::__debug_db_insert_c(this); | |
| 1713 | 1865 | __table_.__rehash_multi(__n); |
| 1714 | 1866 | insert(__il.begin(), __il.end()); |
| 1715 | 1867 | } |
| ... | ... | @@ -1758,7 +1910,7 @@ swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1758 | 1910 | __x.swap(__y); |
| 1759 | 1911 | } |
| 1760 | 1912 | |
| 1761 | #if _LIBCPP_STD_VER > 17 | |
| 1913 | #if _LIBCPP_STD_VER >= 20 | |
| 1762 | 1914 | template <class _Value, class _Hash, class _Pred, class _Alloc, |
| 1763 | 1915 | class _Predicate> |
| 1764 | 1916 | inline _LIBCPP_INLINE_VISIBILITY |
| ... | ... | @@ -1792,6 +1944,8 @@ operator==(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1792 | 1944 | return true; |
| 1793 | 1945 | } |
| 1794 | 1946 | |
| 1947 | #if _LIBCPP_STD_VER <= 17 | |
| 1948 | ||
| 1795 | 1949 | template <class _Value, class _Hash, class _Pred, class _Alloc> |
| 1796 | 1950 | inline _LIBCPP_INLINE_VISIBILITY |
| 1797 | 1951 | bool |
| ... | ... | @@ -1801,24 +1955,28 @@ operator!=(const unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, |
| 1801 | 1955 | return !(__x == __y); |
| 1802 | 1956 | } |
| 1803 | 1957 | |
| 1958 | #endif | |
| 1959 | ||
| 1804 | 1960 | _LIBCPP_END_NAMESPACE_STD |
| 1805 | 1961 | |
| 1806 | #if _LIBCPP_STD_VER > 14 | |
| 1962 | #if _LIBCPP_STD_VER >= 17 | |
| 1807 | 1963 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 1808 | 1964 | namespace pmr { |
| 1809 | 1965 | template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> |
| 1810 | using unordered_set = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; | |
| 1966 | using unordered_set _LIBCPP_AVAILABILITY_PMR = std::unordered_set<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; | |
| 1811 | 1967 | |
| 1812 | 1968 | template <class _KeyT, class _HashT = std::hash<_KeyT>, class _PredT = std::equal_to<_KeyT>> |
| 1813 | using unordered_multiset = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; | |
| 1969 | using unordered_multiset _LIBCPP_AVAILABILITY_PMR = std::unordered_multiset<_KeyT, _HashT, _PredT, polymorphic_allocator<_KeyT>>; | |
| 1814 | 1970 | } // namespace pmr |
| 1815 | 1971 | _LIBCPP_END_NAMESPACE_STD |
| 1816 | 1972 | #endif |
| 1817 | 1973 | |
| 1818 | 1974 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1819 | 1975 | # include <concepts> |
| 1976 | # include <cstdlib> | |
| 1820 | 1977 | # include <functional> |
| 1821 | 1978 | # include <iterator> |
| 1979 | # include <type_traits> | |
| 1822 | 1980 | #endif |
| 1823 | 1981 | |
| 1824 | 1982 | #endif // _LIBCPP_UNORDERED_SET |
lib/libcxx/include/utility+30-21| ... | ... | @@ -84,14 +84,15 @@ struct pair |
| 84 | 84 | explicit(see-below) constexpr pair(); |
| 85 | 85 | explicit(see-below) pair(const T1& x, const T2& y); // constexpr in C++14 |
| 86 | 86 | template <class U = T1, class V = T2> explicit(see-below) pair(U&&, V&&); // constexpr in C++14 |
| 87 | template <class U, class V> constexpr explicit(see below) pair(pair<U, V>&); // since C++23 | |
| 87 | template <class U, class V> constexpr explicit(see-below) pair(pair<U, V>&); // since C++23 | |
| 88 | 88 | template <class U, class V> explicit(see-below) pair(const pair<U, V>& p); // constexpr in C++14 |
| 89 | 89 | template <class U, class V> explicit(see-below) pair(pair<U, V>&& p); // constexpr in C++14 |
| 90 | 90 | template <class U, class V> |
| 91 | constexpr explicit(see below) pair(const pair<U, V>&&); // since C++23 | |
| 91 | constexpr explicit(see-below) pair(const pair<U, V>&&); // since C++23 | |
| 92 | template <pair-like P> constexpr explicit(see-below) pair(P&&); // since C++23 | |
| 92 | 93 | template <class... Args1, class... Args2> |
| 93 | pair(piecewise_construct_t, tuple<Args1...> first_args, | |
| 94 | tuple<Args2...> second_args); // constexpr in C++20 | |
| 94 | pair(piecewise_construct_t, tuple<Args1...> first_args, // constexpr in C++20 | |
| 95 | tuple<Args2...> second_args); | |
| 95 | 96 | |
| 96 | 97 | constexpr const pair& operator=(const pair& p) const; // since C++23 |
| 97 | 98 | template <class U, class V> pair& operator=(const pair<U, V>& p); // constexpr in C++20 |
| ... | ... | @@ -103,6 +104,8 @@ struct pair |
| 103 | 104 | template <class U, class V> pair& operator=(pair<U, V>&& p); // constexpr in C++20 |
| 104 | 105 | template <class U, class V> |
| 105 | 106 | constexpr const pair& operator=(pair<U, V>&& p) const; // since C++23 |
| 107 | template <pair-like P> constexpr pair& operator=(P&&); // since C++23 | |
| 108 | template <pair-like P> constexpr const pair& operator=(P&&) const; // since C++23 | |
| 106 | 109 | |
| 107 | 110 | void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> && |
| 108 | 111 | is_nothrow_swappable_v<T2>); // constexpr in C++20 |
| ... | ... | @@ -117,24 +120,30 @@ struct common_type<pair<T1, T2>, pair<U1, U2>>; |
| 117 | 120 | |
| 118 | 121 | template<class T1, class T2> pair(T1, T2) -> pair<T1, T2>; |
| 119 | 122 | |
| 120 | template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14 | |
| 121 | template <class T1, class T2> bool operator!=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20 | |
| 122 | template <class T1, class T2> bool operator< (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20 | |
| 123 | template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20 | |
| 124 | template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20 | |
| 125 | template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14, removed in C++20 | |
| 126 | template <class T1, class T2> | |
| 127 | constexpr common_comparison_type_t<synth-three-way-result<T1>, | |
| 128 | synth-three-way-result<T2>> | |
| 129 | operator<=>(const pair<T1,T2>&, const pair<T1,T2>&); // C++20 | |
| 123 | template <class T1, class T2, class U1, class U2> | |
| 124 | bool operator==(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14 | |
| 125 | template <class T1, class T2, class U1, class U2> | |
| 126 | bool operator!=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20 | |
| 127 | template <class T1, class T2, class U1, class U2> | |
| 128 | bool operator< (const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20 | |
| 129 | template <class T1, class T2, class U1, class U2> | |
| 130 | bool operator> (const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20 | |
| 131 | template <class T1, class T2, class U1, class U2> | |
| 132 | bool operator>=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20 | |
| 133 | template <class T1, class T2, class U1, class U2> | |
| 134 | bool operator<=(const pair<T1,T2>&, const pair<U1,U2>&); // constexpr in C++14, removed in C++20 | |
| 135 | template <class T1, class T2, class U1, class U2> | |
| 136 | constexpr common_comparison_type_t<synth-three-way-result<T1,U1>, | |
| 137 | synth-three-way-result<T2,U2>> | |
| 138 | operator<=>(const pair<T1,T2>&, const pair<U1,U2>&); // C++20 | |
| 130 | 139 | |
| 131 | 140 | template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); // constexpr in C++14 |
| 132 | 141 | template <class T1, class T2> |
| 133 | 142 | void |
| 134 | 143 | swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20 |
| 135 | 144 | |
| 136 | template<class T1, class T2> | |
| 137 | constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); // since C++23 | |
| 145 | template<class T1, class T2> // since C++23 | |
| 146 | constexpr void swap(const pair<T1, T2>& x, const pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); | |
| 138 | 147 | |
| 139 | 148 | struct piecewise_construct_t { explicit piecewise_construct_t() = default; }; |
| 140 | 149 | inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); |
| ... | ... | @@ -208,8 +217,8 @@ template<class... T> |
| 208 | 217 | using index_sequence_for = make_index_sequence<sizeof...(T)>; |
| 209 | 218 | |
| 210 | 219 | template<class T, class U=T> |
| 211 | constexpr T exchange(T& obj, U&& new_value) | |
| 212 | noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value); // constexpr in C++17, noexcept in C++23 | |
| 220 | constexpr T exchange(T& obj, U&& new_value) // constexpr in C++17, noexcept in C++23 | |
| 221 | noexcept(is_nothrow_move_constructible<T>::value && is_nothrow_assignable<T&, U>::value); | |
| 213 | 222 | |
| 214 | 223 | // 20.2.7, in-place construction // C++17 |
| 215 | 224 | struct in_place_t { |
| ... | ... | @@ -231,7 +240,7 @@ template <size_t I> |
| 231 | 240 | |
| 232 | 241 | // [utility.underlying], to_underlying |
| 233 | 242 | template <class T> |
| 234 | constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++2b | |
| 243 | constexpr underlying_type_t<T> to_underlying( T value ) noexcept; // C++23 | |
| 235 | 244 | |
| 236 | 245 | } // std |
| 237 | 246 | |
| ... | ... | @@ -266,8 +275,8 @@ template <class T> |
| 266 | 275 | #include <initializer_list> |
| 267 | 276 | |
| 268 | 277 | // [tuple.helper] |
| 269 | #include <__tuple_dir/tuple_element.h> | |
| 270 | #include <__tuple_dir/tuple_size.h> | |
| 278 | #include <__tuple/tuple_element.h> | |
| 279 | #include <__tuple/tuple_size.h> | |
| 271 | 280 | |
| 272 | 281 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
| 273 | 282 | # pragma GCC system_header |
lib/libcxx/include/valarray+61-47| ... | ... | @@ -116,6 +116,8 @@ public: |
| 116 | 116 | size_t start() const; |
| 117 | 117 | size_t size() const; |
| 118 | 118 | size_t stride() const; |
| 119 | ||
| 120 | friend bool operator==(const slice& x, const slice& y); // since C++20 | |
| 119 | 121 | }; |
| 120 | 122 | |
| 121 | 123 | template <class T> |
| ... | ... | @@ -351,8 +353,10 @@ template <class T> unspecified2 end(const valarray<T>& v); |
| 351 | 353 | #include <__assert> // all public C++ headers provide the assertion handler |
| 352 | 354 | #include <__config> |
| 353 | 355 | #include <__functional/operations.h> |
| 356 | #include <__memory/addressof.h> | |
| 354 | 357 | #include <__memory/allocator.h> |
| 355 | 358 | #include <__memory/uninitialized_algorithms.h> |
| 359 | #include <__type_traits/decay.h> | |
| 356 | 360 | #include <__type_traits/remove_reference.h> |
| 357 | 361 | #include <__utility/move.h> |
| 358 | 362 | #include <__utility/swap.h> |
| ... | ... | @@ -400,10 +404,18 @@ public: |
| 400 | 404 | _LIBCPP_INLINE_VISIBILITY size_t start() const {return __start_;} |
| 401 | 405 | _LIBCPP_INLINE_VISIBILITY size_t size() const {return __size_;} |
| 402 | 406 | _LIBCPP_INLINE_VISIBILITY size_t stride() const {return __stride_;} |
| 407 | ||
| 408 | #if _LIBCPP_STD_VER >= 20 | |
| 409 | ||
| 410 | _LIBCPP_HIDE_FROM_ABI friend bool operator==(const slice& __x, const slice& __y) { | |
| 411 | return __x.start() == __y.start() && __x.size() == __y.size() && __x.stride() == __y.stride(); | |
| 412 | } | |
| 413 | ||
| 414 | #endif | |
| 403 | 415 | }; |
| 404 | 416 | |
| 405 | 417 | template <class _Tp> class _LIBCPP_TEMPLATE_VIS slice_array; |
| 406 | class _LIBCPP_TYPE_VIS gslice; | |
| 418 | class _LIBCPP_EXPORTED_FROM_ABI gslice; | |
| 407 | 419 | template <class _Tp> class _LIBCPP_TEMPLATE_VIS gslice_array; |
| 408 | 420 | template <class _Tp> class _LIBCPP_TEMPLATE_VIS mask_array; |
| 409 | 421 | template <class _Tp> class _LIBCPP_TEMPLATE_VIS indirect_array; |
| ... | ... | @@ -432,7 +444,7 @@ template <class _Op, class _A0> |
| 432 | 444 | struct _UnaryOp |
| 433 | 445 | { |
| 434 | 446 | typedef typename _Op::__result_type __result_type; |
| 435 | typedef typename decay<__result_type>::type value_type; | |
| 447 | using value_type = __decay_t<__result_type>; | |
| 436 | 448 | |
| 437 | 449 | _Op __op_; |
| 438 | 450 | _A0 __a0_; |
| ... | ... | @@ -451,7 +463,7 @@ template <class _Op, class _A0, class _A1> |
| 451 | 463 | struct _BinaryOp |
| 452 | 464 | { |
| 453 | 465 | typedef typename _Op::__result_type __result_type; |
| 454 | typedef typename decay<__result_type>::type value_type; | |
| 466 | using value_type = __decay_t<__result_type>; | |
| 455 | 467 | |
| 456 | 468 | _Op __op_; |
| 457 | 469 | _A0 __a0_; |
| ... | ... | @@ -1104,18 +1116,18 @@ private: |
| 1104 | 1116 | valarray& __assign_range(const value_type* __f, const value_type* __l); |
| 1105 | 1117 | }; |
| 1106 | 1118 | |
| 1107 | #if _LIBCPP_STD_VER > 14 | |
| 1119 | #if _LIBCPP_STD_VER >= 17 | |
| 1108 | 1120 | template<class _Tp, size_t _Size> |
| 1109 | 1121 | valarray(const _Tp(&)[_Size], size_t) -> valarray<_Tp>; |
| 1110 | 1122 | #endif |
| 1111 | 1123 | |
| 1112 | extern template _LIBCPP_FUNC_VIS void valarray<size_t>::resize(size_t, size_t); | |
| 1124 | extern template _LIBCPP_EXPORTED_FROM_ABI void valarray<size_t>::resize(size_t, size_t); | |
| 1113 | 1125 | |
| 1114 | 1126 | template <class _Op, class _Tp> |
| 1115 | 1127 | struct _UnaryOp<_Op, valarray<_Tp> > |
| 1116 | 1128 | { |
| 1117 | 1129 | typedef typename _Op::__result_type __result_type; |
| 1118 | typedef typename decay<__result_type>::type value_type; | |
| 1130 | using value_type = __decay_t<__result_type>; | |
| 1119 | 1131 | |
| 1120 | 1132 | _Op __op_; |
| 1121 | 1133 | const valarray<_Tp>& __a0_; |
| ... | ... | @@ -1134,7 +1146,7 @@ template <class _Op, class _Tp, class _A1> |
| 1134 | 1146 | struct _BinaryOp<_Op, valarray<_Tp>, _A1> |
| 1135 | 1147 | { |
| 1136 | 1148 | typedef typename _Op::__result_type __result_type; |
| 1137 | typedef typename decay<__result_type>::type value_type; | |
| 1149 | using value_type = __decay_t<__result_type>; | |
| 1138 | 1150 | |
| 1139 | 1151 | _Op __op_; |
| 1140 | 1152 | const valarray<_Tp>& __a0_; |
| ... | ... | @@ -1155,7 +1167,7 @@ template <class _Op, class _A0, class _Tp> |
| 1155 | 1167 | struct _BinaryOp<_Op, _A0, valarray<_Tp> > |
| 1156 | 1168 | { |
| 1157 | 1169 | typedef typename _Op::__result_type __result_type; |
| 1158 | typedef typename decay<__result_type>::type value_type; | |
| 1170 | using value_type = __decay_t<__result_type>; | |
| 1159 | 1171 | |
| 1160 | 1172 | _Op __op_; |
| 1161 | 1173 | _A0 __a0_; |
| ... | ... | @@ -1176,7 +1188,7 @@ template <class _Op, class _Tp> |
| 1176 | 1188 | struct _BinaryOp<_Op, valarray<_Tp>, valarray<_Tp> > |
| 1177 | 1189 | { |
| 1178 | 1190 | typedef typename _Op::__result_type __result_type; |
| 1179 | typedef typename decay<__result_type>::type value_type; | |
| 1191 | using value_type = __decay_t<__result_type>; | |
| 1180 | 1192 | |
| 1181 | 1193 | _Op __op_; |
| 1182 | 1194 | const valarray<_Tp>& __a0_; |
| ... | ... | @@ -1326,7 +1338,6 @@ private: |
| 1326 | 1338 | {} |
| 1327 | 1339 | |
| 1328 | 1340 | template <class> friend class valarray; |
| 1329 | template <class> friend class sliceExpr; | |
| 1330 | 1341 | }; |
| 1331 | 1342 | |
| 1332 | 1343 | template <class _Tp> |
| ... | ... | @@ -1527,7 +1538,7 @@ slice_array<_Tp>::operator=(const value_type& __x) const |
| 1527 | 1538 | |
| 1528 | 1539 | // gslice |
| 1529 | 1540 | |
| 1530 | class _LIBCPP_TYPE_VIS gslice | |
| 1541 | class _LIBCPP_EXPORTED_FROM_ABI gslice | |
| 1531 | 1542 | { |
| 1532 | 1543 | valarray<size_t> __size_; |
| 1533 | 1544 | valarray<size_t> __stride_; |
| ... | ... | @@ -2818,20 +2829,20 @@ valarray<_Tp>::valarray(size_t __n) |
| 2818 | 2829 | if (__n) |
| 2819 | 2830 | { |
| 2820 | 2831 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 2821 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2832 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2822 | 2833 | try |
| 2823 | 2834 | { |
| 2824 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2835 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2825 | 2836 | for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) |
| 2826 | 2837 | ::new ((void*)__end_) value_type(); |
| 2827 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2838 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2828 | 2839 | } |
| 2829 | 2840 | catch (...) |
| 2830 | 2841 | { |
| 2831 | 2842 | __clear(__n); |
| 2832 | 2843 | throw; |
| 2833 | 2844 | } |
| 2834 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2845 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2835 | 2846 | } |
| 2836 | 2847 | } |
| 2837 | 2848 | |
| ... | ... | @@ -2852,20 +2863,20 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n) |
| 2852 | 2863 | if (__n) |
| 2853 | 2864 | { |
| 2854 | 2865 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 2855 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2866 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2856 | 2867 | try |
| 2857 | 2868 | { |
| 2858 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2869 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2859 | 2870 | for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left) |
| 2860 | 2871 | ::new ((void*)__end_) value_type(*__p); |
| 2861 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2872 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2862 | 2873 | } |
| 2863 | 2874 | catch (...) |
| 2864 | 2875 | { |
| 2865 | 2876 | __clear(__n); |
| 2866 | 2877 | throw; |
| 2867 | 2878 | } |
| 2868 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2879 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2869 | 2880 | } |
| 2870 | 2881 | } |
| 2871 | 2882 | |
| ... | ... | @@ -2877,20 +2888,20 @@ valarray<_Tp>::valarray(const valarray& __v) |
| 2877 | 2888 | if (__v.size()) |
| 2878 | 2889 | { |
| 2879 | 2890 | __begin_ = __end_ = allocator<value_type>().allocate(__v.size()); |
| 2880 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2891 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2881 | 2892 | try |
| 2882 | 2893 | { |
| 2883 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2894 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2884 | 2895 | for (value_type* __p = __v.__begin_; __p != __v.__end_; ++__end_, ++__p) |
| 2885 | 2896 | ::new ((void*)__end_) value_type(*__p); |
| 2886 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2897 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2887 | 2898 | } |
| 2888 | 2899 | catch (...) |
| 2889 | 2900 | { |
| 2890 | 2901 | __clear(__v.size()); |
| 2891 | 2902 | throw; |
| 2892 | 2903 | } |
| 2893 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2904 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2894 | 2905 | } |
| 2895 | 2906 | } |
| 2896 | 2907 | |
| ... | ... | @@ -2914,21 +2925,21 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) |
| 2914 | 2925 | if (__n) |
| 2915 | 2926 | { |
| 2916 | 2927 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 2917 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2928 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2918 | 2929 | try |
| 2919 | 2930 | { |
| 2920 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2931 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2921 | 2932 | size_t __n_left = __n; |
| 2922 | 2933 | for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left) |
| 2923 | 2934 | ::new ((void*)__end_) value_type(*__p); |
| 2924 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2935 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2925 | 2936 | } |
| 2926 | 2937 | catch (...) |
| 2927 | 2938 | { |
| 2928 | 2939 | __clear(__n); |
| 2929 | 2940 | throw; |
| 2930 | 2941 | } |
| 2931 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2942 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2932 | 2943 | } |
| 2933 | 2944 | } |
| 2934 | 2945 | |
| ... | ... | @@ -2943,21 +2954,21 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) |
| 2943 | 2954 | if (__n) |
| 2944 | 2955 | { |
| 2945 | 2956 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 2946 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2957 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2947 | 2958 | try |
| 2948 | 2959 | { |
| 2949 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2960 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2950 | 2961 | size_t __n_left = __n; |
| 2951 | 2962 | for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left) |
| 2952 | 2963 | ::new ((void*)__end_) value_type(*__p); |
| 2953 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2964 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2954 | 2965 | } |
| 2955 | 2966 | catch (...) |
| 2956 | 2967 | { |
| 2957 | 2968 | __clear(__n); |
| 2958 | 2969 | throw; |
| 2959 | 2970 | } |
| 2960 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2971 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2961 | 2972 | } |
| 2962 | 2973 | } |
| 2963 | 2974 | |
| ... | ... | @@ -2970,23 +2981,23 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) |
| 2970 | 2981 | if (__n) |
| 2971 | 2982 | { |
| 2972 | 2983 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 2973 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2984 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2974 | 2985 | try |
| 2975 | 2986 | { |
| 2976 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2987 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2977 | 2988 | typedef const size_t* _Ip; |
| 2978 | 2989 | const value_type* __s = __ga.__vp_; |
| 2979 | 2990 | for (_Ip __i = __ga.__1d_.__begin_, __e = __ga.__1d_.__end_; |
| 2980 | 2991 | __i != __e; ++__i, ++__end_) |
| 2981 | 2992 | ::new ((void*)__end_) value_type(__s[*__i]); |
| 2982 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2993 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2983 | 2994 | } |
| 2984 | 2995 | catch (...) |
| 2985 | 2996 | { |
| 2986 | 2997 | __clear(__n); |
| 2987 | 2998 | throw; |
| 2988 | 2999 | } |
| 2989 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3000 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2990 | 3001 | } |
| 2991 | 3002 | } |
| 2992 | 3003 | |
| ... | ... | @@ -2999,23 +3010,23 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) |
| 2999 | 3010 | if (__n) |
| 3000 | 3011 | { |
| 3001 | 3012 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 3002 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3013 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3003 | 3014 | try |
| 3004 | 3015 | { |
| 3005 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3016 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3006 | 3017 | typedef const size_t* _Ip; |
| 3007 | 3018 | const value_type* __s = __ma.__vp_; |
| 3008 | 3019 | for (_Ip __i = __ma.__1d_.__begin_, __e = __ma.__1d_.__end_; |
| 3009 | 3020 | __i != __e; ++__i, ++__end_) |
| 3010 | 3021 | ::new ((void*)__end_) value_type(__s[*__i]); |
| 3011 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3022 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3012 | 3023 | } |
| 3013 | 3024 | catch (...) |
| 3014 | 3025 | { |
| 3015 | 3026 | __clear(__n); |
| 3016 | 3027 | throw; |
| 3017 | 3028 | } |
| 3018 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3029 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3019 | 3030 | } |
| 3020 | 3031 | } |
| 3021 | 3032 | |
| ... | ... | @@ -3028,23 +3039,23 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) |
| 3028 | 3039 | if (__n) |
| 3029 | 3040 | { |
| 3030 | 3041 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 3031 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3042 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3032 | 3043 | try |
| 3033 | 3044 | { |
| 3034 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3045 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3035 | 3046 | typedef const size_t* _Ip; |
| 3036 | 3047 | const value_type* __s = __ia.__vp_; |
| 3037 | 3048 | for (_Ip __i = __ia.__1d_.__begin_, __e = __ia.__1d_.__end_; |
| 3038 | 3049 | __i != __e; ++__i, ++__end_) |
| 3039 | 3050 | ::new ((void*)__end_) value_type(__s[*__i]); |
| 3040 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3051 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3041 | 3052 | } |
| 3042 | 3053 | catch (...) |
| 3043 | 3054 | { |
| 3044 | 3055 | __clear(__n); |
| 3045 | 3056 | throw; |
| 3046 | 3057 | } |
| 3047 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3058 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3048 | 3059 | } |
| 3049 | 3060 | } |
| 3050 | 3061 | |
| ... | ... | @@ -3753,20 +3764,20 @@ valarray<_Tp>::resize(size_t __n, value_type __x) |
| 3753 | 3764 | if (__n) |
| 3754 | 3765 | { |
| 3755 | 3766 | __begin_ = __end_ = allocator<value_type>().allocate(__n); |
| 3756 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3767 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3757 | 3768 | try |
| 3758 | 3769 | { |
| 3759 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3770 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3760 | 3771 | for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) |
| 3761 | 3772 | ::new ((void*)__end_) value_type(__x); |
| 3762 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3773 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3763 | 3774 | } |
| 3764 | 3775 | catch (...) |
| 3765 | 3776 | { |
| 3766 | 3777 | __clear(__n); |
| 3767 | 3778 | throw; |
| 3768 | 3779 | } |
| 3769 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3780 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3770 | 3781 | } |
| 3771 | 3782 | } |
| 3772 | 3783 | |
| ... | ... | @@ -4933,8 +4944,11 @@ _LIBCPP_POP_MACROS |
| 4933 | 4944 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 4934 | 4945 | # include <algorithm> |
| 4935 | 4946 | # include <concepts> |
| 4947 | # include <cstdlib> | |
| 4936 | 4948 | # include <cstring> |
| 4937 | 4949 | # include <functional> |
| 4950 | # include <stdexcept> | |
| 4951 | # include <type_traits> | |
| 4938 | 4952 | #endif |
| 4939 | 4953 | |
| 4940 | 4954 | #endif // _LIBCPP_VALARRAY |
lib/libcxx/include/variant+35-31| ... | ... | @@ -210,10 +210,12 @@ namespace std { |
| 210 | 210 | #include <__compare/compare_three_way_result.h> |
| 211 | 211 | #include <__compare/three_way_comparable.h> |
| 212 | 212 | #include <__config> |
| 213 | #include <__exception/exception.h> | |
| 213 | 214 | #include <__functional/hash.h> |
| 214 | 215 | #include <__functional/invoke.h> |
| 215 | 216 | #include <__functional/operations.h> |
| 216 | 217 | #include <__functional/unary_function.h> |
| 218 | #include <__memory/addressof.h> | |
| 217 | 219 | #include <__type_traits/add_const.h> |
| 218 | 220 | #include <__type_traits/add_cv.h> |
| 219 | 221 | #include <__type_traits/add_pointer.h> |
| ... | ... | @@ -231,12 +233,13 @@ namespace std { |
| 231 | 233 | #include <__type_traits/remove_const.h> |
| 232 | 234 | #include <__type_traits/type_identity.h> |
| 233 | 235 | #include <__type_traits/void_t.h> |
| 236 | #include <__utility/declval.h> | |
| 234 | 237 | #include <__utility/forward.h> |
| 235 | 238 | #include <__utility/in_place.h> |
| 236 | 239 | #include <__utility/move.h> |
| 237 | 240 | #include <__utility/swap.h> |
| 238 | 241 | #include <__variant/monostate.h> |
| 239 | #include <exception> | |
| 242 | #include <__verbose_abort> | |
| 240 | 243 | #include <initializer_list> |
| 241 | 244 | #include <limits> |
| 242 | 245 | #include <new> |
| ... | ... | @@ -257,7 +260,7 @@ _LIBCPP_PUSH_MACROS |
| 257 | 260 | |
| 258 | 261 | namespace std { // explicitly not using versioning namespace |
| 259 | 262 | |
| 260 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { | |
| 263 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { | |
| 261 | 264 | public: |
| 262 | 265 | const char* what() const _NOEXCEPT override; |
| 263 | 266 | }; |
| ... | ... | @@ -266,7 +269,7 @@ public: |
| 266 | 269 | |
| 267 | 270 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 268 | 271 | |
| 269 | #if _LIBCPP_STD_VER > 14 | |
| 272 | #if _LIBCPP_STD_VER >= 17 | |
| 270 | 273 | |
| 271 | 274 | // Light N-dimensional array of function pointers. Used in place of std::array to avoid |
| 272 | 275 | // adding a dependency. |
| ... | ... | @@ -285,10 +288,10 @@ _LIBCPP_NORETURN |
| 285 | 288 | inline _LIBCPP_HIDE_FROM_ABI |
| 286 | 289 | _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS |
| 287 | 290 | void __throw_bad_variant_access() { |
| 288 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 291 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 289 | 292 | throw bad_variant_access(); |
| 290 | 293 | #else |
| 291 | _VSTD::abort(); | |
| 294 | _LIBCPP_VERBOSE_ABORT("bad_variant_access was thrown in -fno-exceptions mode"); | |
| 292 | 295 | #endif |
| 293 | 296 | } |
| 294 | 297 | |
| ... | ... | @@ -547,7 +550,7 @@ private: |
| 547 | 550 | } |
| 548 | 551 | |
| 549 | 552 | template <class _Fp, class... _Fs> |
| 550 | static constexpr void __std_visit_visitor_return_type_check() { | |
| 553 | static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_visitor_return_type_check() { | |
| 551 | 554 | static_assert( |
| 552 | 555 | __all<is_same_v<_Fp, _Fs>...>::value, |
| 553 | 556 | "`std::visit` requires the visitor to have a single return type."); |
| ... | ... | @@ -594,9 +597,9 @@ private: |
| 594 | 597 | template <class _Fp, class _Vp, class... _Vs> |
| 595 | 598 | _LIBCPP_HIDE_FROM_ABI |
| 596 | 599 | static constexpr auto __make_fdiagonal() { |
| 597 | constexpr size_t _Np = __remove_cvref_t<_Vp>::__size(); | |
| 598 | static_assert(__all<(_Np == __remove_cvref_t<_Vs>::__size())...>::value); | |
| 599 | return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<_Np>{}); | |
| 600 | constexpr size_t __np = __remove_cvref_t<_Vp>::__size(); | |
| 601 | static_assert(__all<(__np == __remove_cvref_t<_Vs>::__size())...>::value); | |
| 602 | return __make_fdiagonal_impl<_Fp, _Vp, _Vs...>(make_index_sequence<__np>{}); | |
| 600 | 603 | } |
| 601 | 604 | |
| 602 | 605 | template <class _Fp, class... _Vs, size_t... _Is> |
| ... | ... | @@ -660,7 +663,7 @@ struct __variant { |
| 660 | 663 | _VSTD::forward<_Vs>(__vs)...); |
| 661 | 664 | } |
| 662 | 665 | |
| 663 | #if _LIBCPP_STD_VER > 17 | |
| 666 | #if _LIBCPP_STD_VER >= 20 | |
| 664 | 667 | template <class _Rp, class _Visitor, class... _Vs> |
| 665 | 668 | _LIBCPP_HIDE_FROM_ABI |
| 666 | 669 | static constexpr _Rp __visit_value(_Visitor&& __visitor, |
| ... | ... | @@ -673,7 +676,7 @@ struct __variant { |
| 673 | 676 | |
| 674 | 677 | private: |
| 675 | 678 | template <class _Visitor, class... _Values> |
| 676 | static constexpr void __std_visit_exhaustive_visitor_check() { | |
| 679 | static _LIBCPP_HIDE_FROM_ABI constexpr void __std_visit_exhaustive_visitor_check() { | |
| 677 | 680 | static_assert(is_invocable_v<_Visitor, _Values...>, |
| 678 | 681 | "`std::visit` requires the visitor to be exhaustive."); |
| 679 | 682 | } |
| ... | ... | @@ -692,7 +695,7 @@ private: |
| 692 | 695 | _Visitor&& __visitor; |
| 693 | 696 | }; |
| 694 | 697 | |
| 695 | #if _LIBCPP_STD_VER > 17 | |
| 698 | #if _LIBCPP_STD_VER >= 20 | |
| 696 | 699 | template <class _Rp, class _Visitor> |
| 697 | 700 | struct __value_visitor_return_type { |
| 698 | 701 | template <class... _Alts> |
| ... | ... | @@ -721,7 +724,7 @@ private: |
| 721 | 724 | return __value_visitor<_Visitor>{_VSTD::forward<_Visitor>(__visitor)}; |
| 722 | 725 | } |
| 723 | 726 | |
| 724 | #if _LIBCPP_STD_VER > 17 | |
| 727 | #if _LIBCPP_STD_VER >= 20 | |
| 725 | 728 | template <class _Rp, class _Visitor> |
| 726 | 729 | _LIBCPP_HIDE_FROM_ABI |
| 727 | 730 | static constexpr auto __make_value_visitor(_Visitor&& __visitor) { |
| ... | ... | @@ -1034,10 +1037,10 @@ protected: |
| 1034 | 1037 | __a.__value = _VSTD::forward<_Arg>(__arg); |
| 1035 | 1038 | } else { |
| 1036 | 1039 | struct { |
| 1037 | void operator()(true_type) const { | |
| 1040 | _LIBCPP_HIDE_FROM_ABI void operator()(true_type) const { | |
| 1038 | 1041 | __this->__emplace<_Ip>(_VSTD::forward<_Arg>(__arg)); |
| 1039 | 1042 | } |
| 1040 | void operator()(false_type) const { | |
| 1043 | _LIBCPP_HIDE_FROM_ABI void operator()(false_type) const { | |
| 1041 | 1044 | __this->__emplace<_Ip>(_Tp(_VSTD::forward<_Arg>(__arg))); |
| 1042 | 1045 | } |
| 1043 | 1046 | __assignment* __this; |
| ... | ... | @@ -1155,10 +1158,10 @@ class _LIBCPP_TEMPLATE_VIS __impl |
| 1155 | 1158 | |
| 1156 | 1159 | public: |
| 1157 | 1160 | using __base_type::__base_type; // get in_place_index_t constructor & friends |
| 1158 | __impl(__impl const&) = default; | |
| 1159 | __impl(__impl&&) = default; | |
| 1160 | __impl& operator=(__impl const&) = default; | |
| 1161 | __impl& operator=(__impl&&) = default; | |
| 1161 | _LIBCPP_HIDE_FROM_ABI __impl(__impl const&) = default; | |
| 1162 | _LIBCPP_HIDE_FROM_ABI __impl(__impl&&) = default; | |
| 1163 | _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl const&) = default; | |
| 1164 | _LIBCPP_HIDE_FROM_ABI __impl& operator=(__impl&&) = default; | |
| 1162 | 1165 | |
| 1163 | 1166 | template <size_t _Ip, class _Arg> |
| 1164 | 1167 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -1187,7 +1190,7 @@ public: |
| 1187 | 1190 | _VSTD::swap(__lhs, __rhs); |
| 1188 | 1191 | } |
| 1189 | 1192 | __impl __tmp(_VSTD::move(*__rhs)); |
| 1190 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1193 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1191 | 1194 | if constexpr (__all<is_nothrow_move_constructible_v<_Types>...>::value) { |
| 1192 | 1195 | this->__generic_construct(*__rhs, _VSTD::move(*__lhs)); |
| 1193 | 1196 | } else { |
| ... | ... | @@ -1271,7 +1274,7 @@ struct __all_overloads : _Bases... { |
| 1271 | 1274 | using _Bases::operator()...; |
| 1272 | 1275 | }; |
| 1273 | 1276 | |
| 1274 | template <class IdxSeq> | |
| 1277 | template <class _IdxSeq> | |
| 1275 | 1278 | struct __make_overloads_imp; |
| 1276 | 1279 | |
| 1277 | 1280 | template <size_t ..._Idx> |
| ... | ... | @@ -1291,7 +1294,7 @@ using __best_match_t = |
| 1291 | 1294 | } // namespace __variant_detail |
| 1292 | 1295 | |
| 1293 | 1296 | template <class... _Types> |
| 1294 | class _LIBCPP_TEMPLATE_VIS variant | |
| 1297 | class _LIBCPP_TEMPLATE_VIS _LIBCPP_DECLSPEC_EMPTY_BASES variant | |
| 1295 | 1298 | : private __sfinae_ctor_base< |
| 1296 | 1299 | __all<is_copy_constructible_v<_Types>...>::value, |
| 1297 | 1300 | __all<is_move_constructible_v<_Types>...>::value>, |
| ... | ... | @@ -1323,8 +1326,8 @@ public: |
| 1323 | 1326 | constexpr variant() noexcept(is_nothrow_default_constructible_v<__first_type>) |
| 1324 | 1327 | : __impl_(in_place_index<0>) {} |
| 1325 | 1328 | |
| 1326 | constexpr variant(const variant&) = default; | |
| 1327 | constexpr variant(variant&&) = default; | |
| 1329 | _LIBCPP_HIDE_FROM_ABI constexpr variant(const variant&) = default; | |
| 1330 | _LIBCPP_HIDE_FROM_ABI constexpr variant(variant&&) = default; | |
| 1328 | 1331 | |
| 1329 | 1332 | template < |
| 1330 | 1333 | class _Arg, |
| ... | ... | @@ -1393,10 +1396,10 @@ public: |
| 1393 | 1396 | is_nothrow_constructible_v<_Tp, initializer_list< _Up>&, _Args...>) |
| 1394 | 1397 | : __impl_(in_place_index<_Ip>, __il, _VSTD::forward<_Args>(__args)...) {} |
| 1395 | 1398 | |
| 1396 | ~variant() = default; | |
| 1399 | _LIBCPP_HIDE_FROM_ABI ~variant() = default; | |
| 1397 | 1400 | |
| 1398 | constexpr variant& operator=(const variant&) = default; | |
| 1399 | constexpr variant& operator=(variant&&) = default; | |
| 1401 | _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(const variant&) = default; | |
| 1402 | _LIBCPP_HIDE_FROM_ABI constexpr variant& operator=(variant&&) = default; | |
| 1400 | 1403 | |
| 1401 | 1404 | template < |
| 1402 | 1405 | class _Arg, |
| ... | ... | @@ -1652,7 +1655,7 @@ constexpr bool operator==(const variant<_Types...>& __lhs, |
| 1652 | 1655 | return __variant::__visit_value_at(__lhs.index(), __convert_to_bool<equal_to<>>{}, __lhs, __rhs); |
| 1653 | 1656 | } |
| 1654 | 1657 | |
| 1655 | # if _LIBCPP_STD_VER > 17 | |
| 1658 | # if _LIBCPP_STD_VER >= 20 | |
| 1656 | 1659 | |
| 1657 | 1660 | template <class... _Types> requires (three_way_comparable<_Types> && ...) |
| 1658 | 1661 | _LIBCPP_HIDE_FROM_ABI constexpr common_comparison_category_t<compare_three_way_result_t<_Types>...> |
| ... | ... | @@ -1671,7 +1674,7 @@ operator<=>(const variant<_Types...>& __lhs, const variant<_Types...>& __rhs) { |
| 1671 | 1674 | return __variant::__visit_value_at(__lhs.index(), __three_way, __lhs, __rhs); |
| 1672 | 1675 | } |
| 1673 | 1676 | |
| 1674 | # endif // _LIBCPP_STD_VER > 17 | |
| 1677 | # endif // _LIBCPP_STD_VER >= 20 | |
| 1675 | 1678 | |
| 1676 | 1679 | template <class... _Types> |
| 1677 | 1680 | _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -1757,7 +1760,7 @@ constexpr decltype(auto) visit(_Visitor&& __visitor, _Vs&&... __vs) { |
| 1757 | 1760 | _VSTD::forward<_Vs>(__vs)...); |
| 1758 | 1761 | } |
| 1759 | 1762 | |
| 1760 | #if _LIBCPP_STD_VER > 17 | |
| 1763 | #if _LIBCPP_STD_VER >= 20 | |
| 1761 | 1764 | template < |
| 1762 | 1765 | class _Rp, class _Visitor, class... _Vs, |
| 1763 | 1766 | typename = void_t<decltype(_VSTD::__as_variant(std::declval<_Vs>()))...> > |
| ... | ... | @@ -1824,13 +1827,14 @@ constexpr auto&& __unchecked_get(variant<_Types...>& __v) noexcept { |
| 1824 | 1827 | return std::__unchecked_get<__find_exactly_one_t<_Tp, _Types...>::value>(__v); |
| 1825 | 1828 | } |
| 1826 | 1829 | |
| 1827 | #endif // _LIBCPP_STD_VER > 14 | |
| 1830 | #endif // _LIBCPP_STD_VER >= 17 | |
| 1828 | 1831 | |
| 1829 | 1832 | _LIBCPP_END_NAMESPACE_STD |
| 1830 | 1833 | |
| 1831 | 1834 | _LIBCPP_POP_MACROS |
| 1832 | 1835 | |
| 1833 | 1836 | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
| 1837 | # include <exception> | |
| 1834 | 1838 | # include <type_traits> |
| 1835 | 1839 | # include <typeinfo> |
| 1836 | 1840 | # include <utility> |
lib/libcxx/include/vector+474-375| ... | ... | @@ -41,6 +41,8 @@ public: |
| 41 | 41 | vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); |
| 42 | 42 | template <class InputIterator> |
| 43 | 43 | vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); |
| 44 | template<container-compatible-range<T> R> | |
| 45 | constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); // C++23 | |
| 44 | 46 | vector(const vector& x); |
| 45 | 47 | vector(vector&& x) |
| 46 | 48 | noexcept(is_nothrow_move_constructible<allocator_type>::value); |
| ... | ... | @@ -55,6 +57,8 @@ public: |
| 55 | 57 | vector& operator=(initializer_list<value_type> il); |
| 56 | 58 | template <class InputIterator> |
| 57 | 59 | void assign(InputIterator first, InputIterator last); |
| 60 | template<container-compatible-range<T> R> | |
| 61 | constexpr void assign_range(R&& rg); // C++23 | |
| 58 | 62 | void assign(size_type n, const value_type& u); |
| 59 | 63 | void assign(initializer_list<value_type> il); |
| 60 | 64 | |
| ... | ... | @@ -99,6 +103,8 @@ public: |
| 99 | 103 | void push_back(value_type&& x); |
| 100 | 104 | template <class... Args> |
| 101 | 105 | reference emplace_back(Args&&... args); // reference in C++17 |
| 106 | template<container-compatible-range<T> R> | |
| 107 | constexpr void append_range(R&& rg); // C++23 | |
| 102 | 108 | void pop_back(); |
| 103 | 109 | |
| 104 | 110 | template <class... Args> iterator emplace(const_iterator position, Args&&... args); |
| ... | ... | @@ -107,6 +113,8 @@ public: |
| 107 | 113 | iterator insert(const_iterator position, size_type n, const value_type& x); |
| 108 | 114 | template <class InputIterator> |
| 109 | 115 | iterator insert(const_iterator position, InputIterator first, InputIterator last); |
| 116 | template<container-compatible-range<T> R> | |
| 117 | constexpr iterator insert_range(const_iterator position, R&& rg); // C++23 | |
| 110 | 118 | iterator insert(const_iterator position, initializer_list<value_type> il); |
| 111 | 119 | |
| 112 | 120 | iterator erase(const_iterator position); |
| ... | ... | @@ -165,6 +173,8 @@ public: |
| 165 | 173 | vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); |
| 166 | 174 | template <class InputIterator> |
| 167 | 175 | vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); |
| 176 | template<container-compatible-range<bool> R> | |
| 177 | constexpr vector(from_range_t, R&& rg, const Allocator& = Allocator()); | |
| 168 | 178 | vector(const vector& x); |
| 169 | 179 | vector(vector&& x) |
| 170 | 180 | noexcept(is_nothrow_move_constructible<allocator_type>::value); |
| ... | ... | @@ -179,6 +189,8 @@ public: |
| 179 | 189 | vector& operator=(initializer_list<value_type> il); |
| 180 | 190 | template <class InputIterator> |
| 181 | 191 | void assign(InputIterator first, InputIterator last); |
| 192 | template<container-compatible-range<T> R> | |
| 193 | constexpr void assign_range(R&& rg); // C++23 | |
| 182 | 194 | void assign(size_type n, const value_type& u); |
| 183 | 195 | void assign(initializer_list<value_type> il); |
| 184 | 196 | |
| ... | ... | @@ -218,6 +230,8 @@ public: |
| 218 | 230 | |
| 219 | 231 | void push_back(const value_type& x); |
| 220 | 232 | template <class... Args> reference emplace_back(Args&&... args); // C++14; reference in C++17 |
| 233 | template<container-compatible-range<T> R> | |
| 234 | constexpr void append_range(R&& rg); // C++23 | |
| 221 | 235 | void pop_back(); |
| 222 | 236 | |
| 223 | 237 | template <class... Args> iterator emplace(const_iterator position, Args&&... args); // C++14 |
| ... | ... | @@ -225,6 +239,8 @@ public: |
| 225 | 239 | iterator insert(const_iterator position, size_type n, const value_type& x); |
| 226 | 240 | template <class InputIterator> |
| 227 | 241 | iterator insert(const_iterator position, InputIterator first, InputIterator last); |
| 242 | template<container-compatible-range<T> R> | |
| 243 | constexpr iterator insert_range(const_iterator position, R&& rg); // C++23 | |
| 228 | 244 | iterator insert(const_iterator position, initializer_list<value_type> il); |
| 229 | 245 | |
| 230 | 246 | iterator erase(const_iterator position); |
| ... | ... | @@ -247,14 +263,21 @@ template <class InputIterator, class Allocator = allocator<typename iterator_tra |
| 247 | 263 | vector(InputIterator, InputIterator, Allocator = Allocator()) |
| 248 | 264 | -> vector<typename iterator_traits<InputIterator>::value_type, Allocator>; // C++17 |
| 249 | 265 | |
| 266 | template<ranges::input_range R, class Allocator = allocator<ranges::range_value_t<R>>> | |
| 267 | vector(from_range_t, R&&, Allocator = Allocator()) | |
| 268 | -> vector<ranges::range_value_t<R>, Allocator>; // C++23 | |
| 269 | ||
| 250 | 270 | template <class Allocator> struct hash<std::vector<bool, Allocator>>; |
| 251 | 271 | |
| 252 | template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 253 | template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 254 | template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 255 | template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 256 | template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 257 | template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); | |
| 272 | template <class T, class Allocator> bool operator==(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // constexpr since C++20 | |
| 273 | template <class T, class Allocator> bool operator!=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20 | |
| 274 | template <class T, class Allocator> bool operator< (const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20 | |
| 275 | template <class T, class Allocator> bool operator> (const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20 | |
| 276 | template <class T, class Allocator> bool operator>=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20 | |
| 277 | template <class T, class Allocator> bool operator<=(const vector<T,Allocator>& x, const vector<T,Allocator>& y); // removed in C++20 | |
| 278 | template <class T, class Allocator> constexpr | |
| 279 | constexpr synth-three-way-result<T> operator<=>(const vector<T, Allocator>& x, | |
| 280 | const vector<T, Allocator>& y); // since C++20 | |
| 258 | 281 | |
| 259 | 282 | template <class T, class Allocator> |
| 260 | 283 | void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) |
| ... | ... | @@ -262,10 +285,10 @@ void swap(vector<T,Allocator>& x, vector<T,Allocator>& y) |
| 262 | 285 | |
| 263 | 286 | template <class T, class Allocator, class U> |
| 264 | 287 | typename vector<T, Allocator>::size_type |
| 265 | erase(vector<T, Allocator>& c, const U& value); // C++20 | |
| 288 | erase(vector<T, Allocator>& c, const U& value); // since C++20 | |
| 266 | 289 | template <class T, class Allocator, class Predicate> |
| 267 | 290 | typename vector<T, Allocator>::size_type |
| 268 | erase_if(vector<T, Allocator>& c, Predicate pred); // C++20 | |
| 291 | erase_if(vector<T, Allocator>& c, Predicate pred); // since C++20 | |
| 269 | 292 | |
| 270 | 293 | |
| 271 | 294 | template<class T> |
| ... | ... | @@ -281,44 +304,57 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++ |
| 281 | 304 | #include <__algorithm/copy.h> |
| 282 | 305 | #include <__algorithm/equal.h> |
| 283 | 306 | #include <__algorithm/fill_n.h> |
| 307 | #include <__algorithm/iterator_operations.h> | |
| 284 | 308 | #include <__algorithm/lexicographical_compare.h> |
| 309 | #include <__algorithm/lexicographical_compare_three_way.h> | |
| 285 | 310 | #include <__algorithm/remove.h> |
| 286 | 311 | #include <__algorithm/remove_if.h> |
| 287 | 312 | #include <__algorithm/rotate.h> |
| 288 | 313 | #include <__algorithm/unwrap_iter.h> |
| 289 | 314 | #include <__assert> // all public C++ headers provide the assertion handler |
| 315 | #include <__availability> | |
| 290 | 316 | #include <__bit_reference> |
| 291 | 317 | #include <__concepts/same_as.h> |
| 292 | 318 | #include <__config> |
| 293 | #include <__debug> | |
| 294 | 319 | #include <__format/enable_insertable.h> |
| 295 | 320 | #include <__format/formatter.h> |
| 321 | #include <__format/formatter_bool.h> | |
| 296 | 322 | #include <__functional/hash.h> |
| 297 | 323 | #include <__functional/unary_function.h> |
| 298 | 324 | #include <__iterator/advance.h> |
| 325 | #include <__iterator/distance.h> | |
| 299 | 326 | #include <__iterator/iterator_traits.h> |
| 300 | 327 | #include <__iterator/reverse_iterator.h> |
| 301 | 328 | #include <__iterator/wrap_iter.h> |
| 329 | #include <__memory/addressof.h> | |
| 302 | 330 | #include <__memory/allocate_at_least.h> |
| 331 | #include <__memory/allocator_traits.h> | |
| 303 | 332 | #include <__memory/pointer_traits.h> |
| 304 | 333 | #include <__memory/swap_allocator.h> |
| 305 | 334 | #include <__memory/temp_value.h> |
| 306 | 335 | #include <__memory/uninitialized_algorithms.h> |
| 307 | 336 | #include <__memory_resource/polymorphic_allocator.h> |
| 337 | #include <__ranges/access.h> | |
| 338 | #include <__ranges/concepts.h> | |
| 339 | #include <__ranges/container_compatible_range.h> | |
| 340 | #include <__ranges/from_range.h> | |
| 341 | #include <__ranges/size.h> | |
| 308 | 342 | #include <__split_buffer> |
| 309 | 343 | #include <__type_traits/is_allocator.h> |
| 344 | #include <__type_traits/is_constructible.h> | |
| 345 | #include <__type_traits/is_nothrow_move_assignable.h> | |
| 310 | 346 | #include <__type_traits/noexcept_move_assign_container.h> |
| 347 | #include <__type_traits/type_identity.h> | |
| 311 | 348 | #include <__utility/exception_guard.h> |
| 312 | 349 | #include <__utility/forward.h> |
| 313 | 350 | #include <__utility/move.h> |
| 351 | #include <__utility/pair.h> | |
| 314 | 352 | #include <__utility/swap.h> |
| 315 | 353 | #include <climits> |
| 316 | #include <cstdlib> | |
| 317 | 354 | #include <cstring> |
| 318 | 355 | #include <iosfwd> // for forward declaration of vector |
| 319 | 356 | #include <limits> |
| 320 | 357 | #include <stdexcept> |
| 321 | #include <type_traits> | |
| 322 | 358 | #include <version> |
| 323 | 359 | |
| 324 | 360 | // standard-mandated includes |
| ... | ... | @@ -341,7 +377,6 @@ template<class T, class charT> requires is-vector-bool-reference<T> // Since C++ |
| 341 | 377 | _LIBCPP_PUSH_MACROS |
| 342 | 378 | #include <__undef_macros> |
| 343 | 379 | |
| 344 | ||
| 345 | 380 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 346 | 381 | |
| 347 | 382 | template <class _Tp, class _Allocator /* = allocator<_Tp> */> |
| ... | ... | @@ -376,7 +411,6 @@ public: |
| 376 | 411 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 377 | 412 | vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) |
| 378 | 413 | { |
| 379 | std::__debug_db_insert_c(this); | |
| 380 | 414 | } |
| 381 | 415 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(const allocator_type& __a) |
| 382 | 416 | #if _LIBCPP_STD_VER <= 14 |
| ... | ... | @@ -386,10 +420,9 @@ public: |
| 386 | 420 | #endif |
| 387 | 421 | : __end_cap_(nullptr, __a) |
| 388 | 422 | { |
| 389 | std::__debug_db_insert_c(this); | |
| 390 | 423 | } |
| 391 | 424 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n); |
| 392 | #if _LIBCPP_STD_VER > 11 | |
| 425 | #if _LIBCPP_STD_VER >= 14 | |
| 393 | 426 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a); |
| 394 | 427 | #endif |
| 395 | 428 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x); |
| ... | ... | @@ -399,7 +432,6 @@ public: |
| 399 | 432 | vector(size_type __n, const value_type& __x, const allocator_type& __a) |
| 400 | 433 | : __end_cap_(nullptr, __a) |
| 401 | 434 | { |
| 402 | std::__debug_db_insert_c(this); | |
| 403 | 435 | if (__n > 0) |
| 404 | 436 | { |
| 405 | 437 | __vallocate(__n); |
| ... | ... | @@ -408,12 +440,12 @@ public: |
| 408 | 440 | } |
| 409 | 441 | |
| 410 | 442 | template <class _InputIterator, |
| 411 | __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 443 | __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 412 | 444 | is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value, |
| 413 | 445 | int> = 0> |
| 414 | 446 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_InputIterator __first, _InputIterator __last); |
| 415 | 447 | template <class _InputIterator, |
| 416 | __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 448 | __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 417 | 449 | is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value, |
| 418 | 450 | int> = 0> |
| 419 | 451 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -421,29 +453,41 @@ public: |
| 421 | 453 | |
| 422 | 454 | template < |
| 423 | 455 | class _ForwardIterator, |
| 424 | __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 456 | __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 425 | 457 | is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 426 | 458 | int> = 0> |
| 427 | 459 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(_ForwardIterator __first, _ForwardIterator __last); |
| 428 | 460 | |
| 429 | 461 | template <class _ForwardIterator, |
| 430 | __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 462 | __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 431 | 463 | is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 432 | 464 | int> = 0> |
| 433 | 465 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 434 | 466 | vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a); |
| 435 | 467 | |
| 468 | #if _LIBCPP_STD_VER >= 23 | |
| 469 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 470 | _LIBCPP_HIDE_FROM_ABI constexpr vector(from_range_t, _Range&& __range, | |
| 471 | const allocator_type& __alloc = allocator_type()) : __end_cap_(nullptr, __alloc) { | |
| 472 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 473 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 474 | __init_with_size(ranges::begin(__range), ranges::end(__range), __n); | |
| 475 | ||
| 476 | } else { | |
| 477 | __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 478 | } | |
| 479 | } | |
| 480 | #endif | |
| 481 | ||
| 436 | 482 | private: |
| 437 | 483 | class __destroy_vector { |
| 438 | 484 | public: |
| 439 | _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {} | |
| 485 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {} | |
| 440 | 486 | |
| 441 | 487 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() { |
| 442 | __vec_.__annotate_delete(); | |
| 443 | std::__debug_db_erase_c(std::addressof(__vec_)); | |
| 444 | ||
| 445 | 488 | if (__vec_.__begin_ != nullptr) { |
| 446 | 489 | __vec_.__clear(); |
| 490 | __vec_.__annotate_delete(); | |
| 447 | 491 | __alloc_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.capacity()); |
| 448 | 492 | } |
| 449 | 493 | } |
| ... | ... | @@ -474,7 +518,7 @@ public: |
| 474 | 518 | |
| 475 | 519 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 476 | 520 | vector(vector&& __x) |
| 477 | #if _LIBCPP_STD_VER > 14 | |
| 521 | #if _LIBCPP_STD_VER >= 17 | |
| 478 | 522 | noexcept; |
| 479 | 523 | #else |
| 480 | 524 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); |
| ... | ... | @@ -487,17 +531,31 @@ public: |
| 487 | 531 | _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); |
| 488 | 532 | |
| 489 | 533 | template <class _InputIterator, |
| 490 | __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 534 | __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 491 | 535 | is_constructible<value_type, typename iterator_traits<_InputIterator>::reference>::value, |
| 492 | 536 | int> = 0> |
| 493 | 537 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_InputIterator __first, _InputIterator __last); |
| 494 | 538 | template < |
| 495 | 539 | class _ForwardIterator, |
| 496 | __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 540 | __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 497 | 541 | is_constructible<value_type, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 498 | 542 | int> = 0> |
| 499 | 543 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(_ForwardIterator __first, _ForwardIterator __last); |
| 500 | 544 | |
| 545 | #if _LIBCPP_STD_VER >= 23 | |
| 546 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 547 | _LIBCPP_HIDE_FROM_ABI | |
| 548 | constexpr void assign_range(_Range&& __range) { | |
| 549 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 550 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 551 | __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); | |
| 552 | ||
| 553 | } else { | |
| 554 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 555 | } | |
| 556 | } | |
| 557 | #endif | |
| 558 | ||
| 501 | 559 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void assign(size_type __n, const_reference __u); |
| 502 | 560 | |
| 503 | 561 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -561,22 +619,22 @@ public: |
| 561 | 619 | |
| 562 | 620 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() _NOEXCEPT |
| 563 | 621 | { |
| 564 | _LIBCPP_ASSERT(!empty(), "front() called on an empty vector"); | |
| 622 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector"); | |
| 565 | 623 | return *this->__begin_; |
| 566 | 624 | } |
| 567 | 625 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const _NOEXCEPT |
| 568 | 626 | { |
| 569 | _LIBCPP_ASSERT(!empty(), "front() called on an empty vector"); | |
| 627 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "front() called on an empty vector"); | |
| 570 | 628 | return *this->__begin_; |
| 571 | 629 | } |
| 572 | 630 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() _NOEXCEPT |
| 573 | 631 | { |
| 574 | _LIBCPP_ASSERT(!empty(), "back() called on an empty vector"); | |
| 632 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector"); | |
| 575 | 633 | return *(this->__end_ - 1); |
| 576 | 634 | } |
| 577 | 635 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const _NOEXCEPT |
| 578 | 636 | { |
| 579 | _LIBCPP_ASSERT(!empty(), "back() called on an empty vector"); | |
| 637 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "back() called on an empty vector"); | |
| 580 | 638 | return *(this->__end_ - 1); |
| 581 | 639 | } |
| 582 | 640 | |
| ... | ... | @@ -594,12 +652,20 @@ public: |
| 594 | 652 | |
| 595 | 653 | template <class... _Args> |
| 596 | 654 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 597 | #if _LIBCPP_STD_VER > 14 | |
| 655 | #if _LIBCPP_STD_VER >= 17 | |
| 598 | 656 | reference emplace_back(_Args&&... __args); |
| 599 | 657 | #else |
| 600 | 658 | void emplace_back(_Args&&... __args); |
| 601 | 659 | #endif |
| 602 | 660 | |
| 661 | #if _LIBCPP_STD_VER >= 23 | |
| 662 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 663 | _LIBCPP_HIDE_FROM_ABI | |
| 664 | constexpr void append_range(_Range&& __range) { | |
| 665 | insert_range(end(), std::forward<_Range>(__range)); | |
| 666 | } | |
| 667 | #endif | |
| 668 | ||
| 603 | 669 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 604 | 670 | void pop_back(); |
| 605 | 671 | |
| ... | ... | @@ -613,15 +679,29 @@ public: |
| 613 | 679 | iterator insert(const_iterator __position, size_type __n, const_reference __x); |
| 614 | 680 | |
| 615 | 681 | template <class _InputIterator, |
| 616 | __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 682 | __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 617 | 683 | is_constructible< value_type, typename iterator_traits<_InputIterator>::reference>::value, |
| 618 | 684 | int> = 0> |
| 619 | 685 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator |
| 620 | 686 | insert(const_iterator __position, _InputIterator __first, _InputIterator __last); |
| 621 | 687 | |
| 688 | #if _LIBCPP_STD_VER >= 23 | |
| 689 | template <_ContainerCompatibleRange<_Tp> _Range> | |
| 690 | _LIBCPP_HIDE_FROM_ABI | |
| 691 | constexpr iterator insert_range(const_iterator __position, _Range&& __range) { | |
| 692 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 693 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 694 | return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); | |
| 695 | ||
| 696 | } else { | |
| 697 | return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); | |
| 698 | } | |
| 699 | } | |
| 700 | #endif | |
| 701 | ||
| 622 | 702 | template < |
| 623 | 703 | class _ForwardIterator, |
| 624 | __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 704 | __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 625 | 705 | is_constructible< value_type, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 626 | 706 | int> = 0> |
| 627 | 707 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator |
| ... | ... | @@ -642,7 +722,6 @@ public: |
| 642 | 722 | size_type __old_size = size(); |
| 643 | 723 | __clear(); |
| 644 | 724 | __annotate_shrink(__old_size); |
| 645 | std::__debug_db_invalidate_all(this); | |
| 646 | 725 | } |
| 647 | 726 | |
| 648 | 727 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void resize(size_type __sz); |
| ... | ... | @@ -658,23 +737,12 @@ public: |
| 658 | 737 | |
| 659 | 738 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const; |
| 660 | 739 | |
| 661 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 662 | ||
| 663 | bool __dereferenceable(const const_iterator* __i) const; | |
| 664 | bool __decrementable(const const_iterator* __i) const; | |
| 665 | bool __addable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 666 | bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; | |
| 667 | ||
| 668 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 669 | ||
| 670 | 740 | private: |
| 671 | 741 | pointer __begin_ = nullptr; |
| 672 | 742 | pointer __end_ = nullptr; |
| 673 | 743 | __compressed_pair<pointer, allocator_type> __end_cap_ = |
| 674 | 744 | __compressed_pair<pointer, allocator_type>(nullptr, __default_init_tag()); |
| 675 | 745 | |
| 676 | _LIBCPP_HIDE_FROM_ABI void __invalidate_iterators_past(pointer __new_last); | |
| 677 | ||
| 678 | 746 | // Allocate space for __n objects |
| 679 | 747 | // throws length_error if __n > max_size() |
| 680 | 748 | // throws (probably bad_alloc) if memory run out |
| ... | ... | @@ -698,16 +766,56 @@ private: |
| 698 | 766 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 699 | 767 | void __construct_at_end(size_type __n, const_reference __x); |
| 700 | 768 | |
| 701 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> = 0> | |
| 702 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void | |
| 703 | __construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n); | |
| 769 | template <class _InputIterator, class _Sentinel> | |
| 770 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 771 | void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) { | |
| 772 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 773 | ||
| 774 | if (__n > 0) { | |
| 775 | __vallocate(__n); | |
| 776 | __construct_at_end(__first, __last, __n); | |
| 777 | } | |
| 778 | ||
| 779 | __guard.__complete(); | |
| 780 | } | |
| 781 | ||
| 782 | template <class _InputIterator, class _Sentinel> | |
| 783 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 784 | void __init_with_sentinel(_InputIterator __first, _Sentinel __last) { | |
| 785 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 786 | ||
| 787 | for (; __first != __last; ++__first) | |
| 788 | emplace_back(*__first); | |
| 789 | ||
| 790 | __guard.__complete(); | |
| 791 | } | |
| 792 | ||
| 793 | template <class _Iterator, class _Sentinel> | |
| 794 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 795 | void __assign_with_sentinel(_Iterator __first, _Sentinel __last); | |
| 796 | ||
| 797 | template <class _ForwardIterator, class _Sentinel> | |
| 798 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 799 | void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n); | |
| 800 | ||
| 801 | template <class _InputIterator, class _Sentinel> | |
| 802 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 803 | iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); | |
| 804 | ||
| 805 | template <class _Iterator, class _Sentinel> | |
| 806 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 807 | iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); | |
| 808 | ||
| 809 | template <class _InputIterator, class _Sentinel> | |
| 810 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 811 | void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); | |
| 704 | 812 | |
| 705 | 813 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n); |
| 706 | 814 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __append(size_type __n, const_reference __x); |
| 707 | 815 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 708 | iterator __make_iter(pointer __p) _NOEXCEPT { return iterator(this, __p); } | |
| 816 | iterator __make_iter(pointer __p) _NOEXCEPT { return iterator(__p); } | |
| 709 | 817 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 710 | const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(this, __p); } | |
| 818 | const_iterator __make_iter(const_pointer __p) const _NOEXCEPT { return const_iterator(__p); } | |
| 711 | 819 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v); |
| 712 | 820 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer __swap_out_circular_buffer(__split_buffer<value_type, allocator_type&>& __v, pointer __p); |
| 713 | 821 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_range(pointer __from_s, pointer __from_e, pointer __to); |
| ... | ... | @@ -718,8 +826,6 @@ private: |
| 718 | 826 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI |
| 719 | 827 | void __destruct_at_end(pointer __new_last) _NOEXCEPT |
| 720 | 828 | { |
| 721 | if (!__libcpp_is_constant_evaluated()) | |
| 722 | __invalidate_iterators_past(__new_last); | |
| 723 | 829 | size_type __old_size = size(); |
| 724 | 830 | __base_destruct_at_end(__new_last); |
| 725 | 831 | __annotate_shrink(__old_size); |
| ... | ... | @@ -734,17 +840,19 @@ private: |
| 734 | 840 | inline void __emplace_back_slow_path(_Args&&... __args); |
| 735 | 841 | |
| 736 | 842 | // The following functions are no-ops outside of AddressSanitizer mode. |
| 737 | // We call annotatations only for the default Allocator because other allocators | |
| 738 | // may not meet the AddressSanitizer alignment constraints. | |
| 739 | // See the documentation for __sanitizer_annotate_contiguous_container for more details. | |
| 843 | // We call annotations for every allocator, unless explicitly disabled. | |
| 844 | // | |
| 845 | // To disable annotations for a particular allocator, change value of | |
| 846 | // __asan_annotate_container_with_allocator to false. | |
| 847 | // For more details, see the "Using libc++" documentation page or | |
| 848 | // the documentation for __sanitizer_annotate_contiguous_container. | |
| 740 | 849 | #ifndef _LIBCPP_HAS_NO_ASAN |
| 741 | 850 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 742 | 851 | void __annotate_contiguous_container(const void *__beg, const void *__end, |
| 743 | 852 | const void *__old_mid, |
| 744 | 853 | const void *__new_mid) const |
| 745 | 854 | { |
| 746 | ||
| 747 | if (!__libcpp_is_constant_evaluated() && __beg && is_same<allocator_type, __default_allocator_type>::value) | |
| 855 | if (!__libcpp_is_constant_evaluated() && __beg != nullptr && __asan_annotate_container_with_allocator<_Allocator>::value) | |
| 748 | 856 | __sanitizer_annotate_contiguous_container(__beg, __end, __old_mid, __new_mid); |
| 749 | 857 | } |
| 750 | 858 | #else |
| ... | ... | @@ -866,6 +974,7 @@ private: |
| 866 | 974 | if (__alloc() != __c.__alloc()) |
| 867 | 975 | { |
| 868 | 976 | __clear(); |
| 977 | __annotate_delete(); | |
| 869 | 978 | __alloc_traits::deallocate(__alloc(), this->__begin_, capacity()); |
| 870 | 979 | this->__begin_ = this->__end_ = __end_cap() = nullptr; |
| 871 | 980 | } |
| ... | ... | @@ -892,7 +1001,7 @@ private: |
| 892 | 1001 | #if _LIBCPP_STD_VER >= 17 |
| 893 | 1002 | template<class _InputIterator, |
| 894 | 1003 | class _Alloc = allocator<__iter_value_type<_InputIterator>>, |
| 895 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1004 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 896 | 1005 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 897 | 1006 | > |
| 898 | 1007 | vector(_InputIterator, _InputIterator) |
| ... | ... | @@ -900,13 +1009,22 @@ vector(_InputIterator, _InputIterator) |
| 900 | 1009 | |
| 901 | 1010 | template<class _InputIterator, |
| 902 | 1011 | class _Alloc, |
| 903 | class = enable_if_t<__is_cpp17_input_iterator<_InputIterator>::value>, | |
| 1012 | class = enable_if_t<__has_input_iterator_category<_InputIterator>::value>, | |
| 904 | 1013 | class = enable_if_t<__is_allocator<_Alloc>::value> |
| 905 | 1014 | > |
| 906 | 1015 | vector(_InputIterator, _InputIterator, _Alloc) |
| 907 | 1016 | -> vector<__iter_value_type<_InputIterator>, _Alloc>; |
| 908 | 1017 | #endif |
| 909 | 1018 | |
| 1019 | #if _LIBCPP_STD_VER >= 23 | |
| 1020 | template <ranges::input_range _Range, | |
| 1021 | class _Alloc = allocator<ranges::range_value_t<_Range>>, | |
| 1022 | class = enable_if_t<__is_allocator<_Alloc>::value> | |
| 1023 | > | |
| 1024 | vector(from_range_t, _Range&&, _Alloc = _Alloc()) | |
| 1025 | -> vector<ranges::range_value_t<_Range>, _Alloc>; | |
| 1026 | #endif | |
| 1027 | ||
| 910 | 1028 | template <class _Tp, class _Allocator> |
| 911 | 1029 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 912 | 1030 | void |
| ... | ... | @@ -922,7 +1040,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a |
| 922 | 1040 | std::swap(this->__end_cap(), __v.__end_cap()); |
| 923 | 1041 | __v.__first_ = __v.__begin_; |
| 924 | 1042 | __annotate_new(size()); |
| 925 | std::__debug_db_invalidate_all(this); | |
| 926 | 1043 | } |
| 927 | 1044 | |
| 928 | 1045 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -942,7 +1059,6 @@ vector<_Tp, _Allocator>::__swap_out_circular_buffer(__split_buffer<value_type, a |
| 942 | 1059 | std::swap(this->__end_cap(), __v.__end_cap()); |
| 943 | 1060 | __v.__first_ = __v.__begin_; |
| 944 | 1061 | __annotate_new(size()); |
| 945 | std::__debug_db_invalidate_all(this); | |
| 946 | 1062 | return __r; |
| 947 | 1063 | } |
| 948 | 1064 | |
| ... | ... | @@ -954,6 +1070,7 @@ vector<_Tp, _Allocator>::__vdeallocate() _NOEXCEPT |
| 954 | 1070 | if (this->__begin_ != nullptr) |
| 955 | 1071 | { |
| 956 | 1072 | clear(); |
| 1073 | __annotate_delete(); | |
| 957 | 1074 | __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity()); |
| 958 | 1075 | this->__begin_ = this->__end_ = this->__end_cap() = nullptr; |
| 959 | 1076 | } |
| ... | ... | @@ -1021,10 +1138,9 @@ vector<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) |
| 1021 | 1138 | } |
| 1022 | 1139 | |
| 1023 | 1140 | template <class _Tp, class _Allocator> |
| 1024 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value, int> > | |
| 1141 | template <class _InputIterator, class _Sentinel> | |
| 1025 | 1142 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void |
| 1026 | vector<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last, size_type __n) | |
| 1027 | { | |
| 1143 | vector<_Tp, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { | |
| 1028 | 1144 | _ConstructTransaction __tx(*this, __n); |
| 1029 | 1145 | __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); |
| 1030 | 1146 | } |
| ... | ... | @@ -1074,7 +1190,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1074 | 1190 | vector<_Tp, _Allocator>::vector(size_type __n) |
| 1075 | 1191 | { |
| 1076 | 1192 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); |
| 1077 | std::__debug_db_insert_c(this); | |
| 1078 | 1193 | if (__n > 0) |
| 1079 | 1194 | { |
| 1080 | 1195 | __vallocate(__n); |
| ... | ... | @@ -1083,14 +1198,13 @@ vector<_Tp, _Allocator>::vector(size_type __n) |
| 1083 | 1198 | __guard.__complete(); |
| 1084 | 1199 | } |
| 1085 | 1200 | |
| 1086 | #if _LIBCPP_STD_VER > 11 | |
| 1201 | #if _LIBCPP_STD_VER >= 14 | |
| 1087 | 1202 | template <class _Tp, class _Allocator> |
| 1088 | 1203 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1089 | 1204 | vector<_Tp, _Allocator>::vector(size_type __n, const allocator_type& __a) |
| 1090 | 1205 | : __end_cap_(nullptr, __a) |
| 1091 | 1206 | { |
| 1092 | 1207 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); |
| 1093 | std::__debug_db_insert_c(this); | |
| 1094 | 1208 | if (__n > 0) |
| 1095 | 1209 | { |
| 1096 | 1210 | __vallocate(__n); |
| ... | ... | @@ -1105,7 +1219,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1105 | 1219 | vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) |
| 1106 | 1220 | { |
| 1107 | 1221 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); |
| 1108 | std::__debug_db_insert_c(this); | |
| 1109 | 1222 | if (__n > 0) |
| 1110 | 1223 | { |
| 1111 | 1224 | __vallocate(__n); |
| ... | ... | @@ -1115,69 +1228,47 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x) |
| 1115 | 1228 | } |
| 1116 | 1229 | |
| 1117 | 1230 | template <class _Tp, class _Allocator> |
| 1118 | template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 1231 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 1119 | 1232 | is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, |
| 1120 | 1233 | int> > |
| 1121 | 1234 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1122 | 1235 | vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last) |
| 1123 | 1236 | { |
| 1124 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1125 | std::__debug_db_insert_c(this); | |
| 1126 | for (; __first != __last; ++__first) | |
| 1127 | emplace_back(*__first); | |
| 1128 | __guard.__complete(); | |
| 1237 | __init_with_sentinel(__first, __last); | |
| 1129 | 1238 | } |
| 1130 | 1239 | |
| 1131 | 1240 | template <class _Tp, class _Allocator> |
| 1132 | template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 1241 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 1133 | 1242 | is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, |
| 1134 | 1243 | int> > |
| 1135 | 1244 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1136 | 1245 | vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a) |
| 1137 | 1246 | : __end_cap_(nullptr, __a) |
| 1138 | 1247 | { |
| 1139 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1140 | std::__debug_db_insert_c(this); | |
| 1141 | for (; __first != __last; ++__first) | |
| 1142 | emplace_back(*__first); | |
| 1143 | __guard.__complete(); | |
| 1248 | __init_with_sentinel(__first, __last); | |
| 1144 | 1249 | } |
| 1145 | 1250 | |
| 1146 | 1251 | template <class _Tp, class _Allocator> |
| 1147 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 1252 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 1148 | 1253 | is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 1149 | 1254 | int> > |
| 1150 | 1255 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1151 | 1256 | vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last) |
| 1152 | 1257 | { |
| 1153 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1154 | std::__debug_db_insert_c(this); | |
| 1155 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 1156 | if (__n > 0) | |
| 1157 | { | |
| 1158 | __vallocate(__n); | |
| 1159 | __construct_at_end(__first, __last, __n); | |
| 1160 | } | |
| 1161 | __guard.__complete(); | |
| 1258 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 1259 | __init_with_size(__first, __last, __n); | |
| 1162 | 1260 | } |
| 1163 | 1261 | |
| 1164 | 1262 | template <class _Tp, class _Allocator> |
| 1165 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 1263 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 1166 | 1264 | is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 1167 | 1265 | int> > |
| 1168 | 1266 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1169 | 1267 | vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a) |
| 1170 | 1268 | : __end_cap_(nullptr, __a) |
| 1171 | 1269 | { |
| 1172 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1173 | std::__debug_db_insert_c(this); | |
| 1174 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 1175 | if (__n > 0) | |
| 1176 | { | |
| 1177 | __vallocate(__n); | |
| 1178 | __construct_at_end(__first, __last, __n); | |
| 1179 | } | |
| 1180 | __guard.__complete(); | |
| 1270 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 1271 | __init_with_size(__first, __last, __n); | |
| 1181 | 1272 | } |
| 1182 | 1273 | |
| 1183 | 1274 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1185,15 +1276,7 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1185 | 1276 | vector<_Tp, _Allocator>::vector(const vector& __x) |
| 1186 | 1277 | : __end_cap_(nullptr, __alloc_traits::select_on_container_copy_construction(__x.__alloc())) |
| 1187 | 1278 | { |
| 1188 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1189 | std::__debug_db_insert_c(this); | |
| 1190 | size_type __n = __x.size(); | |
| 1191 | if (__n > 0) | |
| 1192 | { | |
| 1193 | __vallocate(__n); | |
| 1194 | __construct_at_end(__x.__begin_, __x.__end_, __n); | |
| 1195 | } | |
| 1196 | __guard.__complete(); | |
| 1279 | __init_with_size(__x.__begin_, __x.__end_, __x.size()); | |
| 1197 | 1280 | } |
| 1198 | 1281 | |
| 1199 | 1282 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1201,30 +1284,20 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1201 | 1284 | vector<_Tp, _Allocator>::vector(const vector& __x, const __type_identity_t<allocator_type>& __a) |
| 1202 | 1285 | : __end_cap_(nullptr, __a) |
| 1203 | 1286 | { |
| 1204 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 1205 | std::__debug_db_insert_c(this); | |
| 1206 | size_type __n = __x.size(); | |
| 1207 | if (__n > 0) | |
| 1208 | { | |
| 1209 | __vallocate(__n); | |
| 1210 | __construct_at_end(__x.__begin_, __x.__end_, __n); | |
| 1211 | } | |
| 1212 | __guard.__complete(); | |
| 1287 | __init_with_size(__x.__begin_, __x.__end_, __x.size()); | |
| 1213 | 1288 | } |
| 1214 | 1289 | |
| 1215 | 1290 | template <class _Tp, class _Allocator> |
| 1216 | 1291 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1217 | 1292 | inline _LIBCPP_HIDE_FROM_ABI |
| 1218 | 1293 | vector<_Tp, _Allocator>::vector(vector&& __x) |
| 1219 | #if _LIBCPP_STD_VER > 14 | |
| 1294 | #if _LIBCPP_STD_VER >= 17 | |
| 1220 | 1295 | noexcept |
| 1221 | 1296 | #else |
| 1222 | 1297 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) |
| 1223 | 1298 | #endif |
| 1224 | 1299 | : __end_cap_(nullptr, std::move(__x.__alloc())) |
| 1225 | 1300 | { |
| 1226 | std::__debug_db_insert_c(this); | |
| 1227 | std::__debug_db_swap(this, std::addressof(__x)); | |
| 1228 | 1301 | this->__begin_ = __x.__begin_; |
| 1229 | 1302 | this->__end_ = __x.__end_; |
| 1230 | 1303 | this->__end_cap() = __x.__end_cap(); |
| ... | ... | @@ -1237,14 +1310,12 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 1237 | 1310 | vector<_Tp, _Allocator>::vector(vector&& __x, const __type_identity_t<allocator_type>& __a) |
| 1238 | 1311 | : __end_cap_(nullptr, __a) |
| 1239 | 1312 | { |
| 1240 | std::__debug_db_insert_c(this); | |
| 1241 | 1313 | if (__a == __x.__alloc()) |
| 1242 | 1314 | { |
| 1243 | 1315 | this->__begin_ = __x.__begin_; |
| 1244 | 1316 | this->__end_ = __x.__end_; |
| 1245 | 1317 | this->__end_cap() = __x.__end_cap(); |
| 1246 | 1318 | __x.__begin_ = __x.__end_ = __x.__end_cap() = nullptr; |
| 1247 | std::__debug_db_swap(this, std::addressof(__x)); | |
| 1248 | 1319 | } |
| 1249 | 1320 | else |
| 1250 | 1321 | { |
| ... | ... | @@ -1263,7 +1334,6 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 1263 | 1334 | vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il) |
| 1264 | 1335 | { |
| 1265 | 1336 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); |
| 1266 | std::__debug_db_insert_c(this); | |
| 1267 | 1337 | if (__il.size() > 0) |
| 1268 | 1338 | { |
| 1269 | 1339 | __vallocate(__il.size()); |
| ... | ... | @@ -1279,7 +1349,6 @@ vector<_Tp, _Allocator>::vector(initializer_list<value_type> __il, const allocat |
| 1279 | 1349 | : __end_cap_(nullptr, __a) |
| 1280 | 1350 | { |
| 1281 | 1351 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); |
| 1282 | std::__debug_db_insert_c(this); | |
| 1283 | 1352 | if (__il.size() > 0) |
| 1284 | 1353 | { |
| 1285 | 1354 | __vallocate(__il.size()); |
| ... | ... | @@ -1329,7 +1398,6 @@ vector<_Tp, _Allocator>::__move_assign(vector& __c, true_type) |
| 1329 | 1398 | this->__end_ = __c.__end_; |
| 1330 | 1399 | this->__end_cap() = __c.__end_cap(); |
| 1331 | 1400 | __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; |
| 1332 | std::__debug_db_swap(this, std::addressof(__c)); | |
| 1333 | 1401 | } |
| 1334 | 1402 | |
| 1335 | 1403 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1347,40 +1415,52 @@ vector<_Tp, _Allocator>::operator=(const vector& __x) |
| 1347 | 1415 | } |
| 1348 | 1416 | |
| 1349 | 1417 | template <class _Tp, class _Allocator> |
| 1350 | template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 1418 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 1351 | 1419 | is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, |
| 1352 | 1420 | int> > |
| 1353 | 1421 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void |
| 1354 | 1422 | vector<_Tp, _Allocator>::assign(_InputIterator __first, _InputIterator __last) |
| 1355 | 1423 | { |
| 1424 | __assign_with_sentinel(__first, __last); | |
| 1425 | } | |
| 1426 | ||
| 1427 | template <class _Tp, class _Allocator> | |
| 1428 | template <class _Iterator, class _Sentinel> | |
| 1429 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1430 | void vector<_Tp, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) { | |
| 1356 | 1431 | clear(); |
| 1357 | 1432 | for (; __first != __last; ++__first) |
| 1358 | 1433 | emplace_back(*__first); |
| 1359 | 1434 | } |
| 1360 | 1435 | |
| 1361 | 1436 | template <class _Tp, class _Allocator> |
| 1362 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 1437 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 1363 | 1438 | is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 1364 | 1439 | int> > |
| 1365 | 1440 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void |
| 1366 | 1441 | vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) |
| 1367 | 1442 | { |
| 1368 | size_type __new_size = static_cast<size_type>(std::distance(__first, __last)); | |
| 1443 | __assign_with_size(__first, __last, std::distance(__first, __last)); | |
| 1444 | } | |
| 1445 | ||
| 1446 | template <class _Tp, class _Allocator> | |
| 1447 | template <class _ForwardIterator, class _Sentinel> | |
| 1448 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1449 | void vector<_Tp, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __n) { | |
| 1450 | size_type __new_size = static_cast<size_type>(__n); | |
| 1369 | 1451 | if (__new_size <= capacity()) |
| 1370 | 1452 | { |
| 1371 | _ForwardIterator __mid = __last; | |
| 1372 | bool __growing = false; | |
| 1373 | 1453 | if (__new_size > size()) |
| 1374 | 1454 | { |
| 1375 | __growing = true; | |
| 1376 | __mid = __first; | |
| 1377 | std::advance(__mid, size()); | |
| 1378 | } | |
| 1379 | pointer __m = std::copy(__first, __mid, this->__begin_); | |
| 1380 | if (__growing) | |
| 1455 | _ForwardIterator __mid = std::next(__first, size()); | |
| 1456 | std::copy(__first, __mid, this->__begin_); | |
| 1381 | 1457 | __construct_at_end(__mid, __last, __new_size - size()); |
| 1458 | } | |
| 1382 | 1459 | else |
| 1460 | { | |
| 1461 | pointer __m = std::__copy<_ClassicAlgPolicy>(__first, __last, this->__begin_).second; | |
| 1383 | 1462 | this->__destruct_at_end(__m); |
| 1463 | } | |
| 1384 | 1464 | } |
| 1385 | 1465 | else |
| 1386 | 1466 | { |
| ... | ... | @@ -1388,7 +1468,6 @@ vector<_Tp, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __las |
| 1388 | 1468 | __vallocate(__recommend(__new_size)); |
| 1389 | 1469 | __construct_at_end(__first, __last, __new_size); |
| 1390 | 1470 | } |
| 1391 | std::__debug_db_invalidate_all(this); | |
| 1392 | 1471 | } |
| 1393 | 1472 | |
| 1394 | 1473 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1411,7 +1490,6 @@ vector<_Tp, _Allocator>::assign(size_type __n, const_reference __u) |
| 1411 | 1490 | __vallocate(__recommend(static_cast<size_type>(__n))); |
| 1412 | 1491 | __construct_at_end(__n, __u); |
| 1413 | 1492 | } |
| 1414 | std::__debug_db_invalidate_all(this); | |
| 1415 | 1493 | } |
| 1416 | 1494 | |
| 1417 | 1495 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1456,7 +1534,7 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 1456 | 1534 | typename vector<_Tp, _Allocator>::reference |
| 1457 | 1535 | vector<_Tp, _Allocator>::operator[](size_type __n) _NOEXCEPT |
| 1458 | 1536 | { |
| 1459 | _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); | |
| 1537 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds"); | |
| 1460 | 1538 | return this->__begin_[__n]; |
| 1461 | 1539 | } |
| 1462 | 1540 | |
| ... | ... | @@ -1466,7 +1544,7 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 1466 | 1544 | typename vector<_Tp, _Allocator>::const_reference |
| 1467 | 1545 | vector<_Tp, _Allocator>::operator[](size_type __n) const _NOEXCEPT |
| 1468 | 1546 | { |
| 1469 | _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); | |
| 1547 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < size(), "vector[] index out of bounds"); | |
| 1470 | 1548 | return this->__begin_[__n]; |
| 1471 | 1549 | } |
| 1472 | 1550 | |
| ... | ... | @@ -1512,19 +1590,19 @@ vector<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT |
| 1512 | 1590 | { |
| 1513 | 1591 | if (capacity() > size()) |
| 1514 | 1592 | { |
| 1515 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1593 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1516 | 1594 | try |
| 1517 | 1595 | { |
| 1518 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1596 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1519 | 1597 | allocator_type& __a = this->__alloc(); |
| 1520 | 1598 | __split_buffer<value_type, allocator_type&> __v(size(), size(), __a); |
| 1521 | 1599 | __swap_out_circular_buffer(__v); |
| 1522 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1600 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1523 | 1601 | } |
| 1524 | 1602 | catch (...) |
| 1525 | 1603 | { |
| 1526 | 1604 | } |
| 1527 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1605 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1528 | 1606 | } |
| 1529 | 1607 | } |
| 1530 | 1608 | |
| ... | ... | @@ -1588,7 +1666,7 @@ template <class _Tp, class _Allocator> |
| 1588 | 1666 | template <class... _Args> |
| 1589 | 1667 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1590 | 1668 | inline |
| 1591 | #if _LIBCPP_STD_VER > 14 | |
| 1669 | #if _LIBCPP_STD_VER >= 17 | |
| 1592 | 1670 | typename vector<_Tp, _Allocator>::reference |
| 1593 | 1671 | #else |
| 1594 | 1672 | void |
| ... | ... | @@ -1601,7 +1679,7 @@ vector<_Tp, _Allocator>::emplace_back(_Args&&... __args) |
| 1601 | 1679 | } |
| 1602 | 1680 | else |
| 1603 | 1681 | __emplace_back_slow_path(std::forward<_Args>(__args)...); |
| 1604 | #if _LIBCPP_STD_VER > 14 | |
| 1682 | #if _LIBCPP_STD_VER >= 17 | |
| 1605 | 1683 | return this->back(); |
| 1606 | 1684 | #endif |
| 1607 | 1685 | } |
| ... | ... | @@ -1612,7 +1690,7 @@ inline |
| 1612 | 1690 | void |
| 1613 | 1691 | vector<_Tp, _Allocator>::pop_back() |
| 1614 | 1692 | { |
| 1615 | _LIBCPP_ASSERT(!empty(), "vector::pop_back called on an empty vector"); | |
| 1693 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "vector::pop_back called on an empty vector"); | |
| 1616 | 1694 | this->__destruct_at_end(this->__end_ - 1); |
| 1617 | 1695 | } |
| 1618 | 1696 | |
| ... | ... | @@ -1622,15 +1700,11 @@ inline _LIBCPP_HIDE_FROM_ABI |
| 1622 | 1700 | typename vector<_Tp, _Allocator>::iterator |
| 1623 | 1701 | vector<_Tp, _Allocator>::erase(const_iterator __position) |
| 1624 | 1702 | { |
| 1625 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1626 | "vector::erase(iterator) called with an iterator not referring to this vector"); | |
| 1627 | _LIBCPP_ASSERT(__position != end(), | |
| 1703 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__position != end(), | |
| 1628 | 1704 | "vector::erase(iterator) called with a non-dereferenceable iterator"); |
| 1629 | 1705 | difference_type __ps = __position - cbegin(); |
| 1630 | 1706 | pointer __p = this->__begin_ + __ps; |
| 1631 | 1707 | this->__destruct_at_end(std::move(__p + 1, this->__end_, __p)); |
| 1632 | if (!__libcpp_is_constant_evaluated()) | |
| 1633 | this->__invalidate_iterators_past(__p - 1); | |
| 1634 | 1708 | return __make_iter(__p); |
| 1635 | 1709 | } |
| 1636 | 1710 | |
| ... | ... | @@ -1639,17 +1713,10 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1639 | 1713 | typename vector<_Tp, _Allocator>::iterator |
| 1640 | 1714 | vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) |
| 1641 | 1715 | { |
| 1642 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__first)) == this, | |
| 1643 | "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); | |
| 1644 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__last)) == this, | |
| 1645 | "vector::erase(iterator, iterator) called with an iterator not referring to this vector"); | |
| 1646 | ||
| 1647 | _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); | |
| 1716 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "vector::erase(first, last) called with invalid range"); | |
| 1648 | 1717 | pointer __p = this->__begin_ + (__first - begin()); |
| 1649 | 1718 | if (__first != __last) { |
| 1650 | 1719 | this->__destruct_at_end(std::move(__p + (__last - __first), this->__end_, __p)); |
| 1651 | if (!__libcpp_is_constant_evaluated()) | |
| 1652 | this->__invalidate_iterators_past(__p - 1); | |
| 1653 | 1720 | } |
| 1654 | 1721 | return __make_iter(__p); |
| 1655 | 1722 | } |
| ... | ... | @@ -1679,8 +1746,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1679 | 1746 | typename vector<_Tp, _Allocator>::iterator |
| 1680 | 1747 | vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) |
| 1681 | 1748 | { |
| 1682 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1683 | "vector::insert(iterator, x) called with an iterator not referring to this vector"); | |
| 1684 | 1749 | pointer __p = this->__begin_ + (__position - begin()); |
| 1685 | 1750 | // We can't compare unrelated pointers inside constant expressions |
| 1686 | 1751 | if (!__libcpp_is_constant_evaluated() && this->__end_ < this->__end_cap()) |
| ... | ... | @@ -1713,8 +1778,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1713 | 1778 | typename vector<_Tp, _Allocator>::iterator |
| 1714 | 1779 | vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) |
| 1715 | 1780 | { |
| 1716 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1717 | "vector::insert(iterator, x) called with an iterator not referring to this vector"); | |
| 1718 | 1781 | pointer __p = this->__begin_ + (__position - begin()); |
| 1719 | 1782 | if (this->__end_ < this->__end_cap()) |
| 1720 | 1783 | { |
| ... | ... | @@ -1744,8 +1807,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1744 | 1807 | typename vector<_Tp, _Allocator>::iterator |
| 1745 | 1808 | vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) |
| 1746 | 1809 | { |
| 1747 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1748 | "vector::emplace(iterator, x) called with an iterator not referring to this vector"); | |
| 1749 | 1810 | pointer __p = this->__begin_ + (__position - begin()); |
| 1750 | 1811 | if (this->__end_ < this->__end_cap()) |
| 1751 | 1812 | { |
| ... | ... | @@ -1775,8 +1836,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 1775 | 1836 | typename vector<_Tp, _Allocator>::iterator |
| 1776 | 1837 | vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) |
| 1777 | 1838 | { |
| 1778 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1779 | "vector::insert(iterator, n, x) called with an iterator not referring to this vector"); | |
| 1780 | 1839 | pointer __p = this->__begin_ + (__position - begin()); |
| 1781 | 1840 | if (__n > 0) |
| 1782 | 1841 | { |
| ... | ... | @@ -1810,16 +1869,21 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_ |
| 1810 | 1869 | } |
| 1811 | 1870 | return __make_iter(__p); |
| 1812 | 1871 | } |
| 1813 | ||
| 1814 | 1872 | template <class _Tp, class _Allocator> |
| 1815 | template <class _InputIterator, __enable_if_t<__is_exactly_cpp17_input_iterator<_InputIterator>::value && | |
| 1873 | template <class _InputIterator, __enable_if_t<__has_exactly_input_iterator_category<_InputIterator>::value && | |
| 1816 | 1874 | is_constructible<_Tp, typename iterator_traits<_InputIterator>::reference>::value, |
| 1817 | 1875 | int> > |
| 1818 | 1876 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator |
| 1819 | 1877 | vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) |
| 1820 | 1878 | { |
| 1821 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1822 | "vector::insert(iterator, range) called with an iterator not referring to this vector"); | |
| 1879 | return __insert_with_sentinel(__position, __first, __last); | |
| 1880 | } | |
| 1881 | ||
| 1882 | template <class _Tp, class _Allocator> | |
| 1883 | template <class _InputIterator, class _Sentinel> | |
| 1884 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1885 | typename vector<_Tp, _Allocator>::iterator | |
| 1886 | vector<_Tp, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) { | |
| 1823 | 1887 | difference_type __off = __position - begin(); |
| 1824 | 1888 | pointer __p = this->__begin_ + __off; |
| 1825 | 1889 | allocator_type& __a = this->__alloc(); |
| ... | ... | @@ -1831,24 +1895,24 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs |
| 1831 | 1895 | __split_buffer<value_type, allocator_type&> __v(__a); |
| 1832 | 1896 | if (__first != __last) |
| 1833 | 1897 | { |
| 1834 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1898 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1835 | 1899 | try |
| 1836 | 1900 | { |
| 1837 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1838 | __v.__construct_at_end(__first, __last); | |
| 1901 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1902 | __v.__construct_at_end_with_sentinel(std::move(__first), std::move(__last)); | |
| 1839 | 1903 | difference_type __old_size = __old_last - this->__begin_; |
| 1840 | 1904 | difference_type __old_p = __p - this->__begin_; |
| 1841 | 1905 | reserve(__recommend(size() + __v.size())); |
| 1842 | 1906 | __p = this->__begin_ + __old_p; |
| 1843 | 1907 | __old_last = this->__begin_ + __old_size; |
| 1844 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 1908 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1845 | 1909 | } |
| 1846 | 1910 | catch (...) |
| 1847 | 1911 | { |
| 1848 | 1912 | erase(__make_iter(__old_last), end()); |
| 1849 | 1913 | throw; |
| 1850 | 1914 | } |
| 1851 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 1915 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 1852 | 1916 | } |
| 1853 | 1917 | __p = std::rotate(__p, __old_last, this->__end_); |
| 1854 | 1918 | insert(__make_iter(__p), std::make_move_iterator(__v.begin()), |
| ... | ... | @@ -1857,23 +1921,30 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __firs |
| 1857 | 1921 | } |
| 1858 | 1922 | |
| 1859 | 1923 | template <class _Tp, class _Allocator> |
| 1860 | template <class _ForwardIterator, __enable_if_t<__is_cpp17_forward_iterator<_ForwardIterator>::value && | |
| 1924 | template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value && | |
| 1861 | 1925 | is_constructible<_Tp, typename iterator_traits<_ForwardIterator>::reference>::value, |
| 1862 | 1926 | int> > |
| 1863 | 1927 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector<_Tp, _Allocator>::iterator |
| 1864 | 1928 | vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) |
| 1865 | 1929 | { |
| 1866 | _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__position)) == this, | |
| 1867 | "vector::insert(iterator, range) called with an iterator not referring to this vector"); | |
| 1930 | return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); | |
| 1931 | } | |
| 1932 | ||
| 1933 | template <class _Tp, class _Allocator> | |
| 1934 | template <class _Iterator, class _Sentinel> | |
| 1935 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 1936 | typename vector<_Tp, _Allocator>::iterator | |
| 1937 | vector<_Tp, _Allocator>::__insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, | |
| 1938 | difference_type __n) { | |
| 1939 | auto __insertion_size = __n; | |
| 1868 | 1940 | pointer __p = this->__begin_ + (__position - begin()); |
| 1869 | difference_type __n = std::distance(__first, __last); | |
| 1870 | 1941 | if (__n > 0) |
| 1871 | 1942 | { |
| 1872 | 1943 | if (__n <= this->__end_cap() - this->__end_) |
| 1873 | 1944 | { |
| 1874 | 1945 | size_type __old_n = __n; |
| 1875 | 1946 | pointer __old_last = this->__end_; |
| 1876 | _ForwardIterator __m = __last; | |
| 1947 | _Iterator __m = std::next(__first, __n); | |
| 1877 | 1948 | difference_type __dx = this->__end_ - __p; |
| 1878 | 1949 | if (__n > __dx) |
| 1879 | 1950 | { |
| ... | ... | @@ -1893,7 +1964,7 @@ vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __fi |
| 1893 | 1964 | { |
| 1894 | 1965 | allocator_type& __a = this->__alloc(); |
| 1895 | 1966 | __split_buffer<value_type, allocator_type&> __v(__recommend(size() + __n), __p - this->__begin_, __a); |
| 1896 | __v.__construct_at_end(__first, __last); | |
| 1967 | __v.__construct_at_end_with_size(__first, __insertion_size); | |
| 1897 | 1968 | __p = __swap_out_circular_buffer(__v, __p); |
| 1898 | 1969 | } |
| 1899 | 1970 | } |
| ... | ... | @@ -1935,16 +2006,15 @@ vector<_Tp, _Allocator>::swap(vector& __x) |
| 1935 | 2006 | __is_nothrow_swappable<allocator_type>::value) |
| 1936 | 2007 | #endif |
| 1937 | 2008 | { |
| 1938 | _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || | |
| 1939 | this->__alloc() == __x.__alloc(), | |
| 1940 | "vector::swap: Either propagate_on_container_swap must be true" | |
| 1941 | " or the allocators must compare equal"); | |
| 2009 | _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__alloc_traits::propagate_on_container_swap::value || | |
| 2010 | this->__alloc() == __x.__alloc(), | |
| 2011 | "vector::swap: Either propagate_on_container_swap must be true" | |
| 2012 | " or the allocators must compare equal"); | |
| 1942 | 2013 | std::swap(this->__begin_, __x.__begin_); |
| 1943 | 2014 | std::swap(this->__end_, __x.__end_); |
| 1944 | 2015 | std::swap(this->__end_cap(), __x.__end_cap()); |
| 1945 | 2016 | std::__swap_allocator(this->__alloc(), __x.__alloc(), |
| 1946 | 2017 | integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>()); |
| 1947 | std::__debug_db_swap(this, std::addressof(__x)); | |
| 1948 | 2018 | } |
| 1949 | 2019 | |
| 1950 | 2020 | template <class _Tp, class _Allocator> |
| ... | ... | @@ -1969,61 +2039,6 @@ vector<_Tp, _Allocator>::__invariants() const |
| 1969 | 2039 | return true; |
| 1970 | 2040 | } |
| 1971 | 2041 | |
| 1972 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 1973 | ||
| 1974 | template <class _Tp, class _Allocator> | |
| 1975 | bool | |
| 1976 | vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const | |
| 1977 | { | |
| 1978 | return this->__begin_ <= __i->base() && __i->base() < this->__end_; | |
| 1979 | } | |
| 1980 | ||
| 1981 | template <class _Tp, class _Allocator> | |
| 1982 | bool | |
| 1983 | vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const | |
| 1984 | { | |
| 1985 | return this->__begin_ < __i->base() && __i->base() <= this->__end_; | |
| 1986 | } | |
| 1987 | ||
| 1988 | template <class _Tp, class _Allocator> | |
| 1989 | bool | |
| 1990 | vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1991 | { | |
| 1992 | const_pointer __p = __i->base() + __n; | |
| 1993 | return this->__begin_ <= __p && __p <= this->__end_; | |
| 1994 | } | |
| 1995 | ||
| 1996 | template <class _Tp, class _Allocator> | |
| 1997 | bool | |
| 1998 | vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const | |
| 1999 | { | |
| 2000 | const_pointer __p = __i->base() + __n; | |
| 2001 | return this->__begin_ <= __p && __p < this->__end_; | |
| 2002 | } | |
| 2003 | ||
| 2004 | #endif // _LIBCPP_ENABLE_DEBUG_MODE | |
| 2005 | ||
| 2006 | template <class _Tp, class _Allocator> | |
| 2007 | inline _LIBCPP_HIDE_FROM_ABI | |
| 2008 | void | |
| 2009 | vector<_Tp, _Allocator>::__invalidate_iterators_past(pointer __new_last) { | |
| 2010 | #ifdef _LIBCPP_ENABLE_DEBUG_MODE | |
| 2011 | __c_node* __c = __get_db()->__find_c_and_lock(this); | |
| 2012 | for (__i_node** __p = __c->end_; __p != __c->beg_; ) { | |
| 2013 | --__p; | |
| 2014 | const_iterator* __i = static_cast<const_iterator*>((*__p)->__i_); | |
| 2015 | if (__i->base() > __new_last) { | |
| 2016 | (*__p)->__c_ = nullptr; | |
| 2017 | if (--__c->end_ != __p) | |
| 2018 | std::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); | |
| 2019 | } | |
| 2020 | } | |
| 2021 | __get_db()->unlock(); | |
| 2022 | #else | |
| 2023 | ((void)__new_last); | |
| 2024 | #endif | |
| 2025 | } | |
| 2026 | ||
| 2027 | 2042 | // vector<bool> |
| 2028 | 2043 | |
| 2029 | 2044 | template <class _Allocator> class vector<bool, _Allocator>; |
| ... | ... | @@ -2107,12 +2122,11 @@ public: |
| 2107 | 2122 | private: |
| 2108 | 2123 | class __destroy_vector { |
| 2109 | 2124 | public: |
| 2110 | _LIBCPP_CONSTEXPR __destroy_vector(vector& __vec) : __vec_(__vec) {} | |
| 2125 | _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI __destroy_vector(vector& __vec) : __vec_(__vec) {} | |
| 2111 | 2126 | |
| 2112 | 2127 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void operator()() { |
| 2113 | 2128 | if (__vec_.__begin_ != nullptr) |
| 2114 | 2129 | __storage_traits::deallocate(__vec_.__alloc(), __vec_.__begin_, __vec_.__cap()); |
| 2115 | std::__debug_db_invalidate_all(this); | |
| 2116 | 2130 | } |
| 2117 | 2131 | |
| 2118 | 2132 | private: |
| ... | ... | @@ -2123,23 +2137,40 @@ public: |
| 2123 | 2137 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector(*this)(); } |
| 2124 | 2138 | |
| 2125 | 2139 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n); |
| 2126 | #if _LIBCPP_STD_VER > 11 | |
| 2140 | #if _LIBCPP_STD_VER >= 14 | |
| 2127 | 2141 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a); |
| 2128 | 2142 | #endif |
| 2129 | 2143 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v); |
| 2130 | 2144 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a); |
| 2131 | 2145 | template <class _InputIterator> |
| 2132 | 2146 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, |
| 2133 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0); | |
| 2147 | typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0); | |
| 2134 | 2148 | template <class _InputIterator> |
| 2135 | 2149 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a, |
| 2136 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type* = 0); | |
| 2150 | typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type* = 0); | |
| 2137 | 2151 | template <class _ForwardIterator> |
| 2138 | 2152 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, |
| 2139 | typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); | |
| 2153 | typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0); | |
| 2140 | 2154 | template <class _ForwardIterator> |
| 2141 | 2155 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, |
| 2142 | typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type* = 0); | |
| 2156 | typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type* = 0); | |
| 2157 | ||
| 2158 | #if _LIBCPP_STD_VER >= 23 | |
| 2159 | template <_ContainerCompatibleRange<bool> _Range> | |
| 2160 | _LIBCPP_HIDE_FROM_ABI constexpr | |
| 2161 | vector(from_range_t, _Range&& __range, const allocator_type& __a = allocator_type()) | |
| 2162 | : __begin_(nullptr), | |
| 2163 | __size_(0), | |
| 2164 | __cap_alloc_(0, static_cast<__storage_allocator>(__a)) { | |
| 2165 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 2166 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 2167 | __init_with_size(ranges::begin(__range), ranges::end(__range), __n); | |
| 2168 | ||
| 2169 | } else { | |
| 2170 | __init_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 2171 | } | |
| 2172 | } | |
| 2173 | #endif | |
| 2143 | 2174 | |
| 2144 | 2175 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v); |
| 2145 | 2176 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(const vector& __v, const allocator_type& __a); |
| ... | ... | @@ -2157,7 +2188,7 @@ public: |
| 2157 | 2188 | |
| 2158 | 2189 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2159 | 2190 | vector(vector&& __v) |
| 2160 | #if _LIBCPP_STD_VER > 14 | |
| 2191 | #if _LIBCPP_STD_VER >= 17 | |
| 2161 | 2192 | noexcept; |
| 2162 | 2193 | #else |
| 2163 | 2194 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); |
| ... | ... | @@ -2168,18 +2199,32 @@ public: |
| 2168 | 2199 | _NOEXCEPT_((__noexcept_move_assign_container<_Allocator, __alloc_traits>::value)); |
| 2169 | 2200 | |
| 2170 | 2201 | template <class _InputIterator> |
| 2171 | typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 2202 | typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value, | |
| 2172 | 2203 | void |
| 2173 | 2204 | >::type |
| 2174 | 2205 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_InputIterator __first, _InputIterator __last); |
| 2175 | 2206 | template <class _ForwardIterator> |
| 2176 | 2207 | typename enable_if |
| 2177 | 2208 | < |
| 2178 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2209 | __has_forward_iterator_category<_ForwardIterator>::value, | |
| 2179 | 2210 | void |
| 2180 | 2211 | >::type |
| 2181 | 2212 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 assign(_ForwardIterator __first, _ForwardIterator __last); |
| 2182 | 2213 | |
| 2214 | #if _LIBCPP_STD_VER >= 23 | |
| 2215 | template <_ContainerCompatibleRange<bool> _Range> | |
| 2216 | _LIBCPP_HIDE_FROM_ABI | |
| 2217 | constexpr void assign_range(_Range&& __range) { | |
| 2218 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 2219 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 2220 | __assign_with_size(ranges::begin(__range), ranges::end(__range), __n); | |
| 2221 | ||
| 2222 | } else { | |
| 2223 | __assign_with_sentinel(ranges::begin(__range), ranges::end(__range)); | |
| 2224 | } | |
| 2225 | } | |
| 2226 | #endif | |
| 2227 | ||
| 2183 | 2228 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void assign(size_type __n, const value_type& __x); |
| 2184 | 2229 | |
| 2185 | 2230 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -2254,24 +2299,32 @@ public: |
| 2254 | 2299 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference back() const {return __make_ref(__size_ - 1);} |
| 2255 | 2300 | |
| 2256 | 2301 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void push_back(const value_type& __x); |
| 2257 | #if _LIBCPP_STD_VER > 11 | |
| 2302 | #if _LIBCPP_STD_VER >= 14 | |
| 2258 | 2303 | template <class... _Args> |
| 2259 | #if _LIBCPP_STD_VER > 14 | |
| 2304 | #if _LIBCPP_STD_VER >= 17 | |
| 2260 | 2305 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference emplace_back(_Args&&... __args) |
| 2261 | 2306 | #else |
| 2262 | 2307 | _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args) |
| 2263 | 2308 | #endif |
| 2264 | 2309 | { |
| 2265 | 2310 | push_back ( value_type ( std::forward<_Args>(__args)... )); |
| 2266 | #if _LIBCPP_STD_VER > 14 | |
| 2311 | #if _LIBCPP_STD_VER >= 17 | |
| 2267 | 2312 | return this->back(); |
| 2268 | 2313 | #endif |
| 2269 | 2314 | } |
| 2270 | 2315 | #endif |
| 2271 | 2316 | |
| 2317 | #if _LIBCPP_STD_VER >= 23 | |
| 2318 | template <_ContainerCompatibleRange<bool> _Range> | |
| 2319 | _LIBCPP_HIDE_FROM_ABI | |
| 2320 | constexpr void append_range(_Range&& __range) { | |
| 2321 | insert_range(end(), std::forward<_Range>(__range)); | |
| 2322 | } | |
| 2323 | #endif | |
| 2324 | ||
| 2272 | 2325 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void pop_back() {--__size_;} |
| 2273 | 2326 | |
| 2274 | #if _LIBCPP_STD_VER > 11 | |
| 2327 | #if _LIBCPP_STD_VER >= 14 | |
| 2275 | 2328 | template <class... _Args> |
| 2276 | 2329 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator emplace(const_iterator __position, _Args&&... __args) |
| 2277 | 2330 | { return insert ( __position, value_type ( std::forward<_Args>(__args)... )); } |
| ... | ... | @@ -2280,18 +2333,32 @@ public: |
| 2280 | 2333 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, const value_type& __x); |
| 2281 | 2334 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator __position, size_type __n, const value_type& __x); |
| 2282 | 2335 | template <class _InputIterator> |
| 2283 | typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 2336 | typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value, | |
| 2284 | 2337 | iterator |
| 2285 | 2338 | >::type |
| 2286 | 2339 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _InputIterator __first, _InputIterator __last); |
| 2287 | 2340 | template <class _ForwardIterator> |
| 2288 | 2341 | typename enable_if |
| 2289 | 2342 | < |
| 2290 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2343 | __has_forward_iterator_category<_ForwardIterator>::value, | |
| 2291 | 2344 | iterator |
| 2292 | 2345 | >::type |
| 2293 | 2346 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last); |
| 2294 | 2347 | |
| 2348 | #if _LIBCPP_STD_VER >= 23 | |
| 2349 | template <_ContainerCompatibleRange<bool> _Range> | |
| 2350 | _LIBCPP_HIDE_FROM_ABI | |
| 2351 | constexpr iterator insert_range(const_iterator __position, _Range&& __range) { | |
| 2352 | if constexpr (ranges::forward_range<_Range> || ranges::sized_range<_Range>) { | |
| 2353 | auto __n = static_cast<size_type>(ranges::distance(__range)); | |
| 2354 | return __insert_with_size(__position, ranges::begin(__range), ranges::end(__range), __n); | |
| 2355 | ||
| 2356 | } else { | |
| 2357 | return __insert_with_sentinel(__position, ranges::begin(__range), ranges::end(__range)); | |
| 2358 | } | |
| 2359 | } | |
| 2360 | #endif | |
| 2361 | ||
| 2295 | 2362 | #ifndef _LIBCPP_CXX03_LANG |
| 2296 | 2363 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2297 | 2364 | iterator insert(const_iterator __position, initializer_list<value_type> __il) |
| ... | ... | @@ -2304,7 +2371,7 @@ public: |
| 2304 | 2371 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2305 | 2372 | void clear() _NOEXCEPT {__size_ = 0;} |
| 2306 | 2373 | |
| 2307 | _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) | |
| 2374 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(vector&) | |
| 2308 | 2375 | #if _LIBCPP_STD_VER >= 14 |
| 2309 | 2376 | _NOEXCEPT; |
| 2310 | 2377 | #else |
| ... | ... | @@ -2329,6 +2396,52 @@ private: |
| 2329 | 2396 | std::__throw_out_of_range("vector"); |
| 2330 | 2397 | } |
| 2331 | 2398 | |
| 2399 | template <class _InputIterator, class _Sentinel> | |
| 2400 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2401 | void __init_with_size(_InputIterator __first, _Sentinel __last, size_type __n) { | |
| 2402 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 2403 | ||
| 2404 | if (__n > 0) { | |
| 2405 | __vallocate(__n); | |
| 2406 | __construct_at_end(std::move(__first), std::move(__last), __n); | |
| 2407 | } | |
| 2408 | ||
| 2409 | __guard.__complete(); | |
| 2410 | } | |
| 2411 | ||
| 2412 | template <class _InputIterator, class _Sentinel> | |
| 2413 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2414 | void __init_with_sentinel(_InputIterator __first, _Sentinel __last) { | |
| 2415 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2416 | try { | |
| 2417 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2418 | for (; __first != __last; ++__first) | |
| 2419 | push_back(*__first); | |
| 2420 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2421 | } catch (...) { | |
| 2422 | if (__begin_ != nullptr) | |
| 2423 | __storage_traits::deallocate(__alloc(), __begin_, __cap()); | |
| 2424 | throw; | |
| 2425 | } | |
| 2426 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2427 | } | |
| 2428 | ||
| 2429 | template <class _Iterator, class _Sentinel> | |
| 2430 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2431 | void __assign_with_sentinel(_Iterator __first, _Sentinel __last); | |
| 2432 | ||
| 2433 | template <class _ForwardIterator, class _Sentinel> | |
| 2434 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2435 | void __assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns); | |
| 2436 | ||
| 2437 | template <class _InputIterator, class _Sentinel> | |
| 2438 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2439 | iterator __insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last); | |
| 2440 | ||
| 2441 | template <class _Iterator, class _Sentinel> | |
| 2442 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2443 | iterator __insert_with_size(const_iterator __position, _Iterator __first, _Sentinel __last, difference_type __n); | |
| 2444 | ||
| 2332 | 2445 | // Allocate space for __n objects |
| 2333 | 2446 | // throws length_error if __n > max_size() |
| 2334 | 2447 | // throws (probably bad_alloc) if memory run out |
| ... | ... | @@ -2355,13 +2468,9 @@ private: |
| 2355 | 2468 | {return (__new_size + (__bits_per_word-1)) & ~((size_type)__bits_per_word-1);} |
| 2356 | 2469 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 size_type __recommend(size_type __new_size) const; |
| 2357 | 2470 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __construct_at_end(size_type __n, bool __x); |
| 2358 | template <class _ForwardIterator> | |
| 2359 | typename enable_if | |
| 2360 | < | |
| 2361 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2362 | void | |
| 2363 | >::type | |
| 2364 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); | |
| 2471 | template <class _InputIterator, class _Sentinel> | |
| 2472 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 2473 | void __construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n); | |
| 2365 | 2474 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __append(size_type __n, const_reference __x); |
| 2366 | 2475 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2367 | 2476 | reference __make_ref(size_type __pos) _NOEXCEPT |
| ... | ... | @@ -2436,7 +2545,6 @@ vector<bool, _Allocator>::__vdeallocate() _NOEXCEPT |
| 2436 | 2545 | if (this->__begin_ != nullptr) |
| 2437 | 2546 | { |
| 2438 | 2547 | __storage_traits::deallocate(this->__alloc(), this->__begin_, __cap()); |
| 2439 | std::__debug_db_invalidate_all(this); | |
| 2440 | 2548 | this->__begin_ = nullptr; |
| 2441 | 2549 | this->__size_ = this->__cap() = 0; |
| 2442 | 2550 | } |
| ... | ... | @@ -2491,17 +2599,11 @@ vector<bool, _Allocator>::__construct_at_end(size_type __n, bool __x) |
| 2491 | 2599 | } |
| 2492 | 2600 | |
| 2493 | 2601 | template <class _Allocator> |
| 2494 | template <class _ForwardIterator> | |
| 2602 | template <class _InputIterator, class _Sentinel> | |
| 2495 | 2603 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2496 | typename enable_if | |
| 2497 | < | |
| 2498 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2499 | void | |
| 2500 | >::type | |
| 2501 | vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) | |
| 2502 | { | |
| 2604 | void vector<bool, _Allocator>::__construct_at_end(_InputIterator __first, _Sentinel __last, size_type __n) { | |
| 2503 | 2605 | size_type __old_size = this->__size_; |
| 2504 | this->__size_ += std::distance(__first, __last); | |
| 2606 | this->__size_ += __n; | |
| 2505 | 2607 | if (__old_size == 0 || ((__old_size - 1) / __bits_per_word) != ((this->__size_ - 1) / __bits_per_word)) |
| 2506 | 2608 | { |
| 2507 | 2609 | if (this->__size_ <= __bits_per_word) |
| ... | ... | @@ -2509,7 +2611,7 @@ vector<bool, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardI |
| 2509 | 2611 | else |
| 2510 | 2612 | this->__begin_[(this->__size_ - 1) / __bits_per_word] = __storage_type(0); |
| 2511 | 2613 | } |
| 2512 | std::copy(__first, __last, __make_iter(__old_size)); | |
| 2614 | std::__copy<_ClassicAlgPolicy>(__first, __last, __make_iter(__old_size)); | |
| 2513 | 2615 | } |
| 2514 | 2616 | |
| 2515 | 2617 | template <class _Allocator> |
| ... | ... | @@ -2550,7 +2652,7 @@ vector<bool, _Allocator>::vector(size_type __n) |
| 2550 | 2652 | } |
| 2551 | 2653 | } |
| 2552 | 2654 | |
| 2553 | #if _LIBCPP_STD_VER > 11 | |
| 2655 | #if _LIBCPP_STD_VER >= 14 | |
| 2554 | 2656 | template <class _Allocator> |
| 2555 | 2657 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2556 | 2658 | vector<bool, _Allocator>::vector(size_type __n, const allocator_type& __a) |
| ... | ... | @@ -2598,92 +2700,50 @@ template <class _Allocator> |
| 2598 | 2700 | template <class _InputIterator> |
| 2599 | 2701 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2600 | 2702 | vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, |
| 2601 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*) | |
| 2703 | typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*) | |
| 2602 | 2704 | : __begin_(nullptr), |
| 2603 | 2705 | __size_(0), |
| 2604 | 2706 | __cap_alloc_(0, __default_init_tag()) |
| 2605 | 2707 | { |
| 2606 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2607 | try | |
| 2608 | { | |
| 2609 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2610 | for (; __first != __last; ++__first) | |
| 2611 | push_back(*__first); | |
| 2612 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2613 | } | |
| 2614 | catch (...) | |
| 2615 | { | |
| 2616 | if (__begin_ != nullptr) | |
| 2617 | __storage_traits::deallocate(__alloc(), __begin_, __cap()); | |
| 2618 | std::__debug_db_invalidate_all(this); | |
| 2619 | throw; | |
| 2620 | } | |
| 2621 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2708 | __init_with_sentinel(__first, __last); | |
| 2622 | 2709 | } |
| 2623 | 2710 | |
| 2624 | 2711 | template <class _Allocator> |
| 2625 | 2712 | template <class _InputIterator> |
| 2626 | 2713 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2627 | 2714 | vector<bool, _Allocator>::vector(_InputIterator __first, _InputIterator __last, const allocator_type& __a, |
| 2628 | typename enable_if<__is_exactly_cpp17_input_iterator<_InputIterator>::value>::type*) | |
| 2715 | typename enable_if<__has_exactly_input_iterator_category<_InputIterator>::value>::type*) | |
| 2629 | 2716 | : __begin_(nullptr), |
| 2630 | 2717 | __size_(0), |
| 2631 | 2718 | __cap_alloc_(0, static_cast<__storage_allocator>(__a)) |
| 2632 | 2719 | { |
| 2633 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2634 | try | |
| 2635 | { | |
| 2636 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2637 | for (; __first != __last; ++__first) | |
| 2638 | push_back(*__first); | |
| 2639 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2640 | } | |
| 2641 | catch (...) | |
| 2642 | { | |
| 2643 | if (__begin_ != nullptr) | |
| 2644 | __storage_traits::deallocate(__alloc(), __begin_, __cap()); | |
| 2645 | std::__debug_db_invalidate_all(this); | |
| 2646 | throw; | |
| 2647 | } | |
| 2648 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 2720 | __init_with_sentinel(__first, __last); | |
| 2649 | 2721 | } |
| 2650 | 2722 | |
| 2651 | 2723 | template <class _Allocator> |
| 2652 | 2724 | template <class _ForwardIterator> |
| 2653 | 2725 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2654 | 2726 | vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, |
| 2655 | typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*) | |
| 2727 | typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*) | |
| 2656 | 2728 | : __begin_(nullptr), |
| 2657 | 2729 | __size_(0), |
| 2658 | 2730 | __cap_alloc_(0, __default_init_tag()) |
| 2659 | 2731 | { |
| 2660 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 2661 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2662 | if (__n > 0) | |
| 2663 | { | |
| 2664 | __vallocate(__n); | |
| 2665 | __construct_at_end(__first, __last); | |
| 2666 | } | |
| 2667 | __guard.__complete(); | |
| 2732 | auto __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2733 | __init_with_size(__first, __last, __n); | |
| 2668 | 2734 | } |
| 2669 | 2735 | |
| 2670 | 2736 | template <class _Allocator> |
| 2671 | 2737 | template <class _ForwardIterator> |
| 2672 | 2738 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2673 | 2739 | vector<bool, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __last, const allocator_type& __a, |
| 2674 | typename enable_if<__is_cpp17_forward_iterator<_ForwardIterator>::value>::type*) | |
| 2740 | typename enable_if<__has_forward_iterator_category<_ForwardIterator>::value>::type*) | |
| 2675 | 2741 | : __begin_(nullptr), |
| 2676 | 2742 | __size_(0), |
| 2677 | 2743 | __cap_alloc_(0, static_cast<__storage_allocator>(__a)) |
| 2678 | 2744 | { |
| 2679 | auto __guard = std::__make_exception_guard(__destroy_vector(*this)); | |
| 2680 | size_type __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2681 | if (__n > 0) | |
| 2682 | { | |
| 2683 | __vallocate(__n); | |
| 2684 | __construct_at_end(__first, __last); | |
| 2685 | } | |
| 2686 | __guard.__complete(); | |
| 2745 | auto __n = static_cast<size_type>(std::distance(__first, __last)); | |
| 2746 | __init_with_size(__first, __last, __n); | |
| 2687 | 2747 | } |
| 2688 | 2748 | |
| 2689 | 2749 | #ifndef _LIBCPP_CXX03_LANG |
| ... | ... | @@ -2699,7 +2759,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il) |
| 2699 | 2759 | if (__n > 0) |
| 2700 | 2760 | { |
| 2701 | 2761 | __vallocate(__n); |
| 2702 | __construct_at_end(__il.begin(), __il.end()); | |
| 2762 | __construct_at_end(__il.begin(), __il.end(), __n); | |
| 2703 | 2763 | } |
| 2704 | 2764 | } |
| 2705 | 2765 | |
| ... | ... | @@ -2714,7 +2774,7 @@ vector<bool, _Allocator>::vector(initializer_list<value_type> __il, const alloca |
| 2714 | 2774 | if (__n > 0) |
| 2715 | 2775 | { |
| 2716 | 2776 | __vallocate(__n); |
| 2717 | __construct_at_end(__il.begin(), __il.end()); | |
| 2777 | __construct_at_end(__il.begin(), __il.end(), __n); | |
| 2718 | 2778 | } |
| 2719 | 2779 | } |
| 2720 | 2780 | |
| ... | ... | @@ -2730,7 +2790,7 @@ vector<bool, _Allocator>::vector(const vector& __v) |
| 2730 | 2790 | if (__v.size() > 0) |
| 2731 | 2791 | { |
| 2732 | 2792 | __vallocate(__v.size()); |
| 2733 | __construct_at_end(__v.begin(), __v.end()); | |
| 2793 | __construct_at_end(__v.begin(), __v.end(), __v.size()); | |
| 2734 | 2794 | } |
| 2735 | 2795 | } |
| 2736 | 2796 | |
| ... | ... | @@ -2744,7 +2804,7 @@ vector<bool, _Allocator>::vector(const vector& __v, const allocator_type& __a) |
| 2744 | 2804 | if (__v.size() > 0) |
| 2745 | 2805 | { |
| 2746 | 2806 | __vallocate(__v.size()); |
| 2747 | __construct_at_end(__v.begin(), __v.end()); | |
| 2807 | __construct_at_end(__v.begin(), __v.end(), __v.size()); | |
| 2748 | 2808 | } |
| 2749 | 2809 | } |
| 2750 | 2810 | |
| ... | ... | @@ -2772,7 +2832,7 @@ vector<bool, _Allocator>::operator=(const vector& __v) |
| 2772 | 2832 | |
| 2773 | 2833 | template <class _Allocator> |
| 2774 | 2834 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector<bool, _Allocator>::vector(vector&& __v) |
| 2775 | #if _LIBCPP_STD_VER > 14 | |
| 2835 | #if _LIBCPP_STD_VER >= 17 | |
| 2776 | 2836 | _NOEXCEPT |
| 2777 | 2837 | #else |
| 2778 | 2838 | _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) |
| ... | ... | @@ -2803,7 +2863,7 @@ vector<bool, _Allocator>::vector(vector&& __v, const __type_identity_t<allocator |
| 2803 | 2863 | else if (__v.size() > 0) |
| 2804 | 2864 | { |
| 2805 | 2865 | __vallocate(__v.size()); |
| 2806 | __construct_at_end(__v.begin(), __v.end()); | |
| 2866 | __construct_at_end(__v.begin(), __v.end(), __v.size()); | |
| 2807 | 2867 | } |
| 2808 | 2868 | } |
| 2809 | 2869 | |
| ... | ... | @@ -2861,16 +2921,22 @@ vector<bool, _Allocator>::assign(size_type __n, const value_type& __x) |
| 2861 | 2921 | } |
| 2862 | 2922 | std::fill_n(begin(), __n, __x); |
| 2863 | 2923 | } |
| 2864 | std::__debug_db_invalidate_all(this); | |
| 2865 | 2924 | } |
| 2866 | 2925 | |
| 2867 | 2926 | template <class _Allocator> |
| 2868 | 2927 | template <class _InputIterator> |
| 2869 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 2928 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value, | |
| 2870 | 2929 | void |
| 2871 | 2930 | >::type |
| 2872 | 2931 | vector<bool, _Allocator>::assign(_InputIterator __first, _InputIterator __last) |
| 2873 | 2932 | { |
| 2933 | __assign_with_sentinel(__first, __last); | |
| 2934 | } | |
| 2935 | ||
| 2936 | template <class _Allocator> | |
| 2937 | template <class _Iterator, class _Sentinel> | |
| 2938 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2939 | void vector<bool, _Allocator>::__assign_with_sentinel(_Iterator __first, _Sentinel __last) { | |
| 2874 | 2940 | clear(); |
| 2875 | 2941 | for (; __first != __last; ++__first) |
| 2876 | 2942 | push_back(*__first); |
| ... | ... | @@ -2881,14 +2947,22 @@ template <class _ForwardIterator> |
| 2881 | 2947 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 2882 | 2948 | typename enable_if |
| 2883 | 2949 | < |
| 2884 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 2950 | __has_forward_iterator_category<_ForwardIterator>::value, | |
| 2885 | 2951 | void |
| 2886 | 2952 | >::type |
| 2887 | 2953 | vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __last) |
| 2888 | 2954 | { |
| 2955 | __assign_with_size(__first, __last, std::distance(__first, __last)); | |
| 2956 | } | |
| 2957 | ||
| 2958 | template <class _Allocator> | |
| 2959 | template <class _ForwardIterator, class _Sentinel> | |
| 2960 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 2961 | void vector<bool, _Allocator>::__assign_with_size(_ForwardIterator __first, _Sentinel __last, difference_type __ns) { | |
| 2962 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(__ns >= 0, "invalid range specified"); | |
| 2963 | ||
| 2889 | 2964 | clear(); |
| 2890 | difference_type __ns = std::distance(__first, __last); | |
| 2891 | _LIBCPP_ASSERT(__ns >= 0, "invalid range specified"); | |
| 2965 | ||
| 2892 | 2966 | const size_t __n = static_cast<size_type>(__ns); |
| 2893 | 2967 | if (__n) |
| 2894 | 2968 | { |
| ... | ... | @@ -2897,7 +2971,7 @@ vector<bool, _Allocator>::assign(_ForwardIterator __first, _ForwardIterator __la |
| 2897 | 2971 | __vdeallocate(); |
| 2898 | 2972 | __vallocate(__n); |
| 2899 | 2973 | } |
| 2900 | __construct_at_end(__first, __last); | |
| 2974 | __construct_at_end(__first, __last, __n); | |
| 2901 | 2975 | } |
| 2902 | 2976 | } |
| 2903 | 2977 | |
| ... | ... | @@ -2911,9 +2985,8 @@ vector<bool, _Allocator>::reserve(size_type __n) |
| 2911 | 2985 | this->__throw_length_error(); |
| 2912 | 2986 | vector __v(this->get_allocator()); |
| 2913 | 2987 | __v.__vallocate(__n); |
| 2914 | __v.__construct_at_end(this->begin(), this->end()); | |
| 2988 | __v.__construct_at_end(this->begin(), this->end(), this->size()); | |
| 2915 | 2989 | swap(__v); |
| 2916 | std::__debug_db_invalidate_all(this); | |
| 2917 | 2990 | } |
| 2918 | 2991 | } |
| 2919 | 2992 | |
| ... | ... | @@ -2923,17 +2996,17 @@ vector<bool, _Allocator>::shrink_to_fit() _NOEXCEPT |
| 2923 | 2996 | { |
| 2924 | 2997 | if (__external_cap_to_internal(size()) > __cap()) |
| 2925 | 2998 | { |
| 2926 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 2999 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2927 | 3000 | try |
| 2928 | 3001 | { |
| 2929 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3002 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2930 | 3003 | vector(*this, allocator_type(__alloc())).swap(*this); |
| 2931 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3004 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2932 | 3005 | } |
| 2933 | 3006 | catch (...) |
| 2934 | 3007 | { |
| 2935 | 3008 | } |
| 2936 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3009 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 2937 | 3010 | } |
| 2938 | 3011 | } |
| 2939 | 3012 | |
| ... | ... | @@ -3018,11 +3091,19 @@ vector<bool, _Allocator>::insert(const_iterator __position, size_type __n, const |
| 3018 | 3091 | |
| 3019 | 3092 | template <class _Allocator> |
| 3020 | 3093 | template <class _InputIterator> |
| 3021 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__is_exactly_cpp17_input_iterator<_InputIterator>::value, | |
| 3094 | _LIBCPP_CONSTEXPR_SINCE_CXX20 typename enable_if <__has_exactly_input_iterator_category<_InputIterator>::value, | |
| 3022 | 3095 | typename vector<bool, _Allocator>::iterator |
| 3023 | 3096 | >::type |
| 3024 | 3097 | vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) |
| 3025 | 3098 | { |
| 3099 | return __insert_with_sentinel(__position, __first, __last); | |
| 3100 | } | |
| 3101 | ||
| 3102 | template <class _Allocator> | |
| 3103 | template <class _InputIterator, class _Sentinel> | |
| 3104 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 3105 | typename vector<bool, _Allocator>::iterator | |
| 3106 | vector<bool, _Allocator>::__insert_with_sentinel(const_iterator __position, _InputIterator __first, _Sentinel __last) { | |
| 3026 | 3107 | difference_type __off = __position - begin(); |
| 3027 | 3108 | iterator __p = __const_iterator_cast(__position); |
| 3028 | 3109 | iterator __old_end = end(); |
| ... | ... | @@ -3034,24 +3115,24 @@ vector<bool, _Allocator>::insert(const_iterator __position, _InputIterator __fir |
| 3034 | 3115 | vector __v(get_allocator()); |
| 3035 | 3116 | if (__first != __last) |
| 3036 | 3117 | { |
| 3037 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3118 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3038 | 3119 | try |
| 3039 | 3120 | { |
| 3040 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3041 | __v.assign(__first, __last); | |
| 3121 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3122 | __v.__assign_with_sentinel(std::move(__first), std::move(__last)); | |
| 3042 | 3123 | difference_type __old_size = static_cast<difference_type>(__old_end - begin()); |
| 3043 | 3124 | difference_type __old_p = __p - begin(); |
| 3044 | 3125 | reserve(__recommend(size() + __v.size())); |
| 3045 | 3126 | __p = begin() + __old_p; |
| 3046 | 3127 | __old_end = begin() + __old_size; |
| 3047 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 3128 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3048 | 3129 | } |
| 3049 | 3130 | catch (...) |
| 3050 | 3131 | { |
| 3051 | 3132 | erase(__old_end, end()); |
| 3052 | 3133 | throw; |
| 3053 | 3134 | } |
| 3054 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 3135 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 3055 | 3136 | } |
| 3056 | 3137 | __p = std::rotate(__p, __old_end, end()); |
| 3057 | 3138 | insert(__p, __v.begin(), __v.end()); |
| ... | ... | @@ -3063,13 +3144,21 @@ template <class _ForwardIterator> |
| 3063 | 3144 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3064 | 3145 | typename enable_if |
| 3065 | 3146 | < |
| 3066 | __is_cpp17_forward_iterator<_ForwardIterator>::value, | |
| 3147 | __has_forward_iterator_category<_ForwardIterator>::value, | |
| 3067 | 3148 | typename vector<bool, _Allocator>::iterator |
| 3068 | 3149 | >::type |
| 3069 | 3150 | vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) |
| 3070 | 3151 | { |
| 3071 | const difference_type __n_signed = std::distance(__first, __last); | |
| 3072 | _LIBCPP_ASSERT(__n_signed >= 0, "invalid range specified"); | |
| 3152 | return __insert_with_size(__position, __first, __last, std::distance(__first, __last)); | |
| 3153 | } | |
| 3154 | ||
| 3155 | template <class _Allocator> | |
| 3156 | template <class _ForwardIterator, class _Sentinel> | |
| 3157 | _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI | |
| 3158 | typename vector<bool, _Allocator>::iterator | |
| 3159 | vector<bool, _Allocator>::__insert_with_size(const_iterator __position, _ForwardIterator __first, _Sentinel __last, | |
| 3160 | difference_type __n_signed) { | |
| 3161 | _LIBCPP_ASSERT_VALID_INPUT_RANGE(__n_signed >= 0, "invalid range specified"); | |
| 3073 | 3162 | const size_type __n = static_cast<size_type>(__n_signed); |
| 3074 | 3163 | iterator __r; |
| 3075 | 3164 | size_type __c = capacity(); |
| ... | ... | @@ -3089,7 +3178,7 @@ vector<bool, _Allocator>::insert(const_iterator __position, _ForwardIterator __f |
| 3089 | 3178 | std::copy_backward(__position, cend(), __v.end()); |
| 3090 | 3179 | swap(__v); |
| 3091 | 3180 | } |
| 3092 | std::copy(__first, __last, __r); | |
| 3181 | std::__copy<_ClassicAlgPolicy>(__first, __last, __r); | |
| 3093 | 3182 | return __r; |
| 3094 | 3183 | } |
| 3095 | 3184 | |
| ... | ... | @@ -3238,8 +3327,9 @@ operator==(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3238 | 3327 | return __sz == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin()); |
| 3239 | 3328 | } |
| 3240 | 3329 | |
| 3330 | #if _LIBCPP_STD_VER <= 17 | |
| 3331 | ||
| 3241 | 3332 | template <class _Tp, class _Allocator> |
| 3242 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3243 | 3333 | inline _LIBCPP_HIDE_FROM_ABI |
| 3244 | 3334 | bool |
| 3245 | 3335 | operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) |
| ... | ... | @@ -3248,7 +3338,6 @@ operator!=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3248 | 3338 | } |
| 3249 | 3339 | |
| 3250 | 3340 | template <class _Tp, class _Allocator> |
| 3251 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3252 | 3341 | inline _LIBCPP_HIDE_FROM_ABI |
| 3253 | 3342 | bool |
| 3254 | 3343 | operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) |
| ... | ... | @@ -3257,7 +3346,6 @@ operator< (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3257 | 3346 | } |
| 3258 | 3347 | |
| 3259 | 3348 | template <class _Tp, class _Allocator> |
| 3260 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3261 | 3349 | inline _LIBCPP_HIDE_FROM_ABI |
| 3262 | 3350 | bool |
| 3263 | 3351 | operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) |
| ... | ... | @@ -3266,7 +3354,6 @@ operator> (const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3266 | 3354 | } |
| 3267 | 3355 | |
| 3268 | 3356 | template <class _Tp, class _Allocator> |
| 3269 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3270 | 3357 | inline _LIBCPP_HIDE_FROM_ABI |
| 3271 | 3358 | bool |
| 3272 | 3359 | operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) |
| ... | ... | @@ -3275,7 +3362,6 @@ operator>=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3275 | 3362 | } |
| 3276 | 3363 | |
| 3277 | 3364 | template <class _Tp, class _Allocator> |
| 3278 | _LIBCPP_CONSTEXPR_SINCE_CXX20 | |
| 3279 | 3365 | inline _LIBCPP_HIDE_FROM_ABI |
| 3280 | 3366 | bool |
| 3281 | 3367 | operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) |
| ... | ... | @@ -3283,6 +3369,17 @@ operator<=(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __ |
| 3283 | 3369 | return !(__y < __x); |
| 3284 | 3370 | } |
| 3285 | 3371 | |
| 3372 | #else // _LIBCPP_STD_VER <= 17 | |
| 3373 | ||
| 3374 | template <class _Tp, class _Allocator> | |
| 3375 | _LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp> | |
| 3376 | operator<=>(const vector<_Tp, _Allocator>& __x, const vector<_Tp, _Allocator>& __y) { | |
| 3377 | return std::lexicographical_compare_three_way( | |
| 3378 | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); | |
| 3379 | } | |
| 3380 | ||
| 3381 | #endif // _LIBCPP_STD_VER <= 17 | |
| 3382 | ||
| 3286 | 3383 | template <class _Tp, class _Allocator> |
| 3287 | 3384 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3288 | 3385 | inline _LIBCPP_HIDE_FROM_ABI |
| ... | ... | @@ -3293,7 +3390,7 @@ swap(vector<_Tp, _Allocator>& __x, vector<_Tp, _Allocator>& __y) |
| 3293 | 3390 | __x.swap(__y); |
| 3294 | 3391 | } |
| 3295 | 3392 | |
| 3296 | #if _LIBCPP_STD_VER > 17 | |
| 3393 | #if _LIBCPP_STD_VER >= 20 | |
| 3297 | 3394 | template <class _Tp, class _Allocator, class _Up> |
| 3298 | 3395 | _LIBCPP_CONSTEXPR_SINCE_CXX20 |
| 3299 | 3396 | inline _LIBCPP_HIDE_FROM_ABI typename vector<_Tp, _Allocator>::size_type |
| ... | ... | @@ -3319,15 +3416,15 @@ template <> |
| 3319 | 3416 | inline constexpr bool __format::__enable_insertable<vector<wchar_t>> = true; |
| 3320 | 3417 | #endif |
| 3321 | 3418 | |
| 3322 | #endif // _LIBCPP_STD_VER > 17 | |
| 3419 | #endif // _LIBCPP_STD_VER >= 20 | |
| 3323 | 3420 | |
| 3324 | #if _LIBCPP_STD_VER > 20 | |
| 3325 | template <class _Tp, class CharT> | |
| 3421 | #if _LIBCPP_STD_VER >= 23 | |
| 3422 | template <class _Tp, class _CharT> | |
| 3326 | 3423 | // Since is-vector-bool-reference is only used once it's inlined here. |
| 3327 | 3424 | requires same_as<typename _Tp::__container, vector<bool, typename _Tp::__container::allocator_type>> |
| 3328 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<_Tp, CharT> { | |
| 3425 | struct _LIBCPP_TEMPLATE_VIS formatter<_Tp, _CharT> { | |
| 3329 | 3426 | private: |
| 3330 | formatter<bool, CharT> __underlying_; | |
| 3427 | formatter<bool, _CharT> __underlying_; | |
| 3331 | 3428 | |
| 3332 | 3429 | public: |
| 3333 | 3430 | template <class _ParseContext> |
| ... | ... | @@ -3340,15 +3437,15 @@ public: |
| 3340 | 3437 | return __underlying_.format(__ref, __ctx); |
| 3341 | 3438 | } |
| 3342 | 3439 | }; |
| 3343 | #endif // _LIBCPP_STD_VER > 20 | |
| 3440 | #endif // _LIBCPP_STD_VER >= 23 | |
| 3344 | 3441 | |
| 3345 | 3442 | _LIBCPP_END_NAMESPACE_STD |
| 3346 | 3443 | |
| 3347 | #if _LIBCPP_STD_VER > 14 | |
| 3444 | #if _LIBCPP_STD_VER >= 17 | |
| 3348 | 3445 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 3349 | 3446 | namespace pmr { |
| 3350 | 3447 | template <class _ValueT> |
| 3351 | using vector = std::vector<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 3448 | using vector _LIBCPP_AVAILABILITY_PMR = std::vector<_ValueT, polymorphic_allocator<_ValueT>>; | |
| 3352 | 3449 | } // namespace pmr |
| 3353 | 3450 | _LIBCPP_END_NAMESPACE_STD |
| 3354 | 3451 | #endif |
| ... | ... | @@ -3359,6 +3456,8 @@ _LIBCPP_POP_MACROS |
| 3359 | 3456 | # include <algorithm> |
| 3360 | 3457 | # include <atomic> |
| 3361 | 3458 | # include <concepts> |
| 3459 | # include <cstdlib> | |
| 3460 | # include <type_traits> | |
| 3362 | 3461 | # include <typeinfo> |
| 3363 | 3462 | # include <utility> |
| 3364 | 3463 | #endif |
lib/libcxx/include/version+80-28| ... | ... | @@ -28,6 +28,8 @@ __cpp_lib_array_constexpr 201811L <array> <iterato |
| 28 | 28 | __cpp_lib_as_const 201510L <utility> |
| 29 | 29 | __cpp_lib_associative_heterogeneous_erasure 202110L <map> <set> <unordered_map> |
| 30 | 30 | <unordered_set> |
| 31 | __cpp_lib_associative_heterogeneous_insertion 202306L <map> <set> <unordered_map> | |
| 32 | <unordered_set> | |
| 31 | 33 | __cpp_lib_assume_aligned 201811L <memory> |
| 32 | 34 | __cpp_lib_atomic_flag_test 201907L <atomic> |
| 33 | 35 | __cpp_lib_atomic_float 201711L <atomic> |
| ... | ... | @@ -38,10 +40,13 @@ __cpp_lib_atomic_shared_ptr 201711L <atomic> |
| 38 | 40 | __cpp_lib_atomic_value_initialization 201911L <atomic> <memory> |
| 39 | 41 | __cpp_lib_atomic_wait 201907L <atomic> |
| 40 | 42 | __cpp_lib_barrier 201907L <barrier> |
| 41 | __cpp_lib_bind_back 202202L <functional> | |
| 42 | __cpp_lib_bind_front 201907L <functional> | |
| 43 | __cpp_lib_bind_back 202306L <functional> | |
| 44 | 202202L // C++23 | |
| 45 | __cpp_lib_bind_front 202306L <functional> | |
| 46 | 201907L // C++20 | |
| 43 | 47 | __cpp_lib_bit_cast 201806L <bit> |
| 44 | 48 | __cpp_lib_bitops 201907L <bit> |
| 49 | __cpp_lib_bitset 202306L <bitset> | |
| 45 | 50 | __cpp_lib_bool_constant 201505L <type_traits> |
| 46 | 51 | __cpp_lib_bounded_array_traits 201902L <type_traits> |
| 47 | 52 | __cpp_lib_boyer_moore_searcher 201603L <functional> |
| ... | ... | @@ -72,6 +77,7 @@ __cpp_lib_constexpr_tuple 201811L <tuple> |
| 72 | 77 | __cpp_lib_constexpr_typeinfo 202106L <typeinfo> |
| 73 | 78 | __cpp_lib_constexpr_utility 201811L <utility> |
| 74 | 79 | __cpp_lib_constexpr_vector 201907L <vector> |
| 80 | __cpp_lib_copyable_function 202306L <functional> | |
| 75 | 81 | __cpp_lib_coroutine 201902L <coroutine> |
| 76 | 82 | __cpp_lib_destroying_delete 201806L <new> |
| 77 | 83 | __cpp_lib_enable_shared_from_this 201603L <memory> |
| ... | ... | @@ -82,15 +88,20 @@ __cpp_lib_erase_if 202002L <deque> <forward |
| 82 | 88 | __cpp_lib_exchange_function 201304L <utility> |
| 83 | 89 | __cpp_lib_execution 201902L <execution> |
| 84 | 90 | 201603L // C++17 |
| 85 | __cpp_lib_expected 202202L <expected> | |
| 91 | __cpp_lib_expected 202211L <expected> | |
| 86 | 92 | __cpp_lib_filesystem 201703L <filesystem> |
| 87 | 93 | __cpp_lib_format 202106L <format> |
| 94 | __cpp_lib_format_ranges 202207L <format> | |
| 95 | __cpp_lib_formatters 202302L <stacktrace> <thread> | |
| 88 | 96 | __cpp_lib_forward_like 202207L <utility> |
| 97 | __cpp_lib_fstream_native_handle 202306L <fstream> | |
| 98 | __cpp_lib_function_ref 202306L <functional> | |
| 89 | 99 | __cpp_lib_gcd_lcm 201606L <numeric> |
| 90 | 100 | __cpp_lib_generic_associative_lookup 201304L <map> <set> |
| 91 | 101 | __cpp_lib_generic_unordered_lookup 201811L <unordered_map> <unordered_set> |
| 92 | 102 | __cpp_lib_hardware_interference_size 201703L <new> |
| 93 | 103 | __cpp_lib_has_unique_object_representations 201606L <type_traits> |
| 104 | __cpp_lib_hazard_pointer 202306L <hazard_pointer> | |
| 94 | 105 | __cpp_lib_hypot 201603L <cmath> |
| 95 | 106 | __cpp_lib_incomplete_container_elements 201505L <forward_list> <list> <vector> |
| 96 | 107 | __cpp_lib_int_pow2 202002L <bit> |
| ... | ... | @@ -121,7 +132,9 @@ __cpp_lib_make_unique 201304L <memory> |
| 121 | 132 | __cpp_lib_map_try_emplace 201411L <map> |
| 122 | 133 | __cpp_lib_math_constants 201907L <numbers> |
| 123 | 134 | __cpp_lib_math_special_functions 201603L <cmath> |
| 135 | __cpp_lib_mdspan 202207L <mdspan> | |
| 124 | 136 | __cpp_lib_memory_resource 201603L <memory_resource> |
| 137 | __cpp_lib_move_iterator_concept 202207L <iterator> | |
| 125 | 138 | __cpp_lib_move_only_function 202110L <functional> |
| 126 | 139 | __cpp_lib_node_extract 201606L <map> <set> <unordered_map> |
| 127 | 140 | <unordered_set> |
| ... | ... | @@ -136,22 +149,26 @@ __cpp_lib_optional 202110L <optional> |
| 136 | 149 | __cpp_lib_out_ptr 202106L <memory> |
| 137 | 150 | __cpp_lib_parallel_algorithm 201603L <algorithm> <numeric> |
| 138 | 151 | __cpp_lib_polymorphic_allocator 201902L <memory_resource> |
| 152 | __cpp_lib_print 202207L <ostream> <print> | |
| 139 | 153 | __cpp_lib_quoted_string_io 201304L <iomanip> |
| 140 | __cpp_lib_ranges 202106L <algorithm> <functional> <iterator> | |
| 154 | __cpp_lib_ranges 202207L <algorithm> <functional> <iterator> | |
| 141 | 155 | <memory> <ranges> |
| 142 | 156 | __cpp_lib_ranges_as_rvalue 202207L <ranges> |
| 143 | 157 | __cpp_lib_ranges_chunk 202202L <ranges> |
| 144 | 158 | __cpp_lib_ranges_chunk_by 202202L <ranges> |
| 145 | 159 | __cpp_lib_ranges_iota 202202L <numeric> |
| 146 | 160 | __cpp_lib_ranges_join_with 202202L <ranges> |
| 161 | __cpp_lib_ranges_repeat 202207L <ranges> | |
| 147 | 162 | __cpp_lib_ranges_slide 202202L <ranges> |
| 148 | 163 | __cpp_lib_ranges_starts_ends_with 202106L <algorithm> |
| 149 | 164 | __cpp_lib_ranges_to_container 202202L <deque> <forward_list> <list> |
| 150 | <map> <priority_queue> <queue> | |
| 165 | <map> <queue> <ranges> | |
| 151 | 166 | <set> <stack> <string> |
| 152 | 167 | <unordered_map> <unordered_set> <vector> |
| 153 | 168 | __cpp_lib_ranges_zip 202110L <ranges> <tuple> <utility> |
| 169 | __cpp_lib_ratio 202306L <ratio> | |
| 154 | 170 | __cpp_lib_raw_memory_algorithms 201606L <memory> |
| 171 | __cpp_lib_rcu 202306L <rcu> | |
| 155 | 172 | __cpp_lib_reference_from_temporary 202202L <type_traits> |
| 156 | 173 | __cpp_lib_remove_cvref 201711L <type_traits> |
| 157 | 174 | __cpp_lib_result_of_sfinae 201210L <functional> <type_traits> |
| ... | ... | @@ -166,10 +183,12 @@ __cpp_lib_shared_ptr_weak_type 201606L <memory> |
| 166 | 183 | __cpp_lib_shared_timed_mutex 201402L <shared_mutex> |
| 167 | 184 | __cpp_lib_shift 201806L <algorithm> |
| 168 | 185 | __cpp_lib_smart_ptr_for_overwrite 202002L <memory> |
| 186 | __cpp_lib_smart_ptr_owner_equality 202306L <memory> | |
| 169 | 187 | __cpp_lib_source_location 201907L <source_location> |
| 170 | 188 | __cpp_lib_span 202002L <span> |
| 171 | 189 | __cpp_lib_spanstream 202106L <spanstream> |
| 172 | 190 | __cpp_lib_ssize 201902L <iterator> |
| 191 | __cpp_lib_sstream_from_string_view 202306L <sstream> | |
| 173 | 192 | __cpp_lib_stacktrace 202011L <stacktrace> |
| 174 | 193 | __cpp_lib_starts_ends_with 201711L <string> <string_view> |
| 175 | 194 | __cpp_lib_stdatomic_h 202011L <stdatomic.h> |
| ... | ... | @@ -178,11 +197,14 @@ __cpp_lib_string_resize_and_overwrite 202110L <string> |
| 178 | 197 | __cpp_lib_string_udls 201304L <string> |
| 179 | 198 | __cpp_lib_string_view 201803L <string> <string_view> |
| 180 | 199 | 201606L // C++17 |
| 200 | __cpp_lib_submdspan 202306L <mdspan> | |
| 181 | 201 | __cpp_lib_syncbuf 201803L <syncstream> |
| 202 | __cpp_lib_text_encoding 202306L <text_encoding> | |
| 182 | 203 | __cpp_lib_three_way_comparison 201907L <compare> |
| 183 | 204 | __cpp_lib_to_address 201711L <memory> |
| 184 | 205 | __cpp_lib_to_array 201907L <array> |
| 185 | 206 | __cpp_lib_to_chars 201611L <charconv> |
| 207 | __cpp_lib_to_string 202306L <string> | |
| 186 | 208 | __cpp_lib_to_underlying 202102L <utility> |
| 187 | 209 | __cpp_lib_transformation_trait_aliases 201304L <type_traits> |
| 188 | 210 | __cpp_lib_transparent_operators 201510L <functional> <memory> |
| ... | ... | @@ -197,6 +219,7 @@ __cpp_lib_unreachable 202202L <utility> |
| 197 | 219 | __cpp_lib_unwrap_ref 201811L <functional> |
| 198 | 220 | __cpp_lib_variant 202102L <variant> |
| 199 | 221 | __cpp_lib_void_t 201411L <type_traits> |
| 222 | __cpp_lib_within_lifetime 202306L <type_traits> | |
| 200 | 223 | |
| 201 | 224 | */ |
| 202 | 225 | |
| ... | ... | @@ -209,7 +232,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 209 | 232 | |
| 210 | 233 | // clang-format off |
| 211 | 234 | |
| 212 | #if _LIBCPP_STD_VER > 11 | |
| 235 | #if _LIBCPP_STD_VER >= 14 | |
| 213 | 236 | # define __cpp_lib_chrono_udls 201304L |
| 214 | 237 | # define __cpp_lib_complex_udls 201309L |
| 215 | 238 | # define __cpp_lib_exchange_function 201304L |
| ... | ... | @@ -224,7 +247,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 224 | 247 | # define __cpp_lib_quoted_string_io 201304L |
| 225 | 248 | # define __cpp_lib_result_of_sfinae 201210L |
| 226 | 249 | # define __cpp_lib_robust_nonmodifying_seq_ops 201304L |
| 227 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_timed_mutex) | |
| 250 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX) | |
| 228 | 251 | # define __cpp_lib_shared_timed_mutex 201402L |
| 229 | 252 | # endif |
| 230 | 253 | # define __cpp_lib_string_udls 201304L |
| ... | ... | @@ -234,7 +257,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 234 | 257 | # define __cpp_lib_tuples_by_type 201304L |
| 235 | 258 | #endif |
| 236 | 259 | |
| 237 | #if _LIBCPP_STD_VER > 14 | |
| 260 | #if _LIBCPP_STD_VER >= 17 | |
| 238 | 261 | # define __cpp_lib_addressof_constexpr 201603L |
| 239 | 262 | # define __cpp_lib_allocator_traits_is_always_equal 201411L |
| 240 | 263 | # define __cpp_lib_any 201606L |
| ... | ... | @@ -249,7 +272,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 249 | 272 | # define __cpp_lib_clamp 201603L |
| 250 | 273 | # define __cpp_lib_enable_shared_from_this 201603L |
| 251 | 274 | // # define __cpp_lib_execution 201603L |
| 252 | # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_filesystem) | |
| 275 | # if !defined(_LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM_LIBRARY) | |
| 253 | 276 | # define __cpp_lib_filesystem 201703L |
| 254 | 277 | # endif |
| 255 | 278 | # define __cpp_lib_gcd_lcm 201606L |
| ... | ... | @@ -268,7 +291,9 @@ __cpp_lib_void_t 201411L <type_traits> |
| 268 | 291 | # define __cpp_lib_make_from_tuple 201606L |
| 269 | 292 | # define __cpp_lib_map_try_emplace 201411L |
| 270 | 293 | // # define __cpp_lib_math_special_functions 201603L |
| 271 | # define __cpp_lib_memory_resource 201603L | |
| 294 | # if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR) | |
| 295 | # define __cpp_lib_memory_resource 201603L | |
| 296 | # endif | |
| 272 | 297 | # define __cpp_lib_node_extract 201606L |
| 273 | 298 | # define __cpp_lib_nonmember_container_access 201411L |
| 274 | 299 | # define __cpp_lib_not_fn 201603L |
| ... | ... | @@ -277,7 +302,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 277 | 302 | # define __cpp_lib_raw_memory_algorithms 201606L |
| 278 | 303 | # define __cpp_lib_sample 201603L |
| 279 | 304 | # define __cpp_lib_scoped_lock 201703L |
| 280 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_shared_mutex) | |
| 305 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX) | |
| 281 | 306 | # define __cpp_lib_shared_mutex 201505L |
| 282 | 307 | # endif |
| 283 | 308 | # define __cpp_lib_shared_ptr_arrays 201611L |
| ... | ... | @@ -293,7 +318,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 293 | 318 | # define __cpp_lib_void_t 201411L |
| 294 | 319 | #endif |
| 295 | 320 | |
| 296 | #if _LIBCPP_STD_VER > 17 | |
| 321 | #if _LIBCPP_STD_VER >= 20 | |
| 297 | 322 | # undef __cpp_lib_array_constexpr |
| 298 | 323 | # define __cpp_lib_array_constexpr 201811L |
| 299 | 324 | # define __cpp_lib_assume_aligned 201811L |
| ... | ... | @@ -303,15 +328,15 @@ __cpp_lib_void_t 201411L <type_traits> |
| 303 | 328 | // # define __cpp_lib_atomic_ref 201806L |
| 304 | 329 | // # define __cpp_lib_atomic_shared_ptr 201711L |
| 305 | 330 | # define __cpp_lib_atomic_value_initialization 201911L |
| 306 | # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_atomic_wait) | |
| 331 | # if !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC) | |
| 307 | 332 | # define __cpp_lib_atomic_wait 201907L |
| 308 | 333 | # endif |
| 309 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_barrier) | |
| 334 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC) | |
| 310 | 335 | # define __cpp_lib_barrier 201907L |
| 311 | 336 | # endif |
| 312 | 337 | # define __cpp_lib_bind_front 201907L |
| 313 | 338 | # define __cpp_lib_bit_cast 201806L |
| 314 | // # define __cpp_lib_bitops 201907L | |
| 339 | # define __cpp_lib_bitops 201907L | |
| 315 | 340 | # define __cpp_lib_bounded_array_traits 201902L |
| 316 | 341 | # if !defined(_LIBCPP_HAS_NO_CHAR8_T) |
| 317 | 342 | # define __cpp_lib_char8_t 201907L |
| ... | ... | @@ -330,16 +355,14 @@ __cpp_lib_void_t 201411L <type_traits> |
| 330 | 355 | # define __cpp_lib_constexpr_utility 201811L |
| 331 | 356 | # define __cpp_lib_constexpr_vector 201907L |
| 332 | 357 | # define __cpp_lib_coroutine 201902L |
| 333 | # if _LIBCPP_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L | |
| 358 | # if _LIBCPP_STD_VER >= 20 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L | |
| 334 | 359 | # define __cpp_lib_destroying_delete 201806L |
| 335 | 360 | # endif |
| 336 | 361 | # define __cpp_lib_endian 201907L |
| 337 | 362 | # define __cpp_lib_erase_if 202002L |
| 338 | 363 | # undef __cpp_lib_execution |
| 339 | 364 | // # define __cpp_lib_execution 201902L |
| 340 | # if !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT) | |
| 341 | // # define __cpp_lib_format 202106L | |
| 342 | # endif | |
| 365 | // # define __cpp_lib_format 202106L | |
| 343 | 366 | # define __cpp_lib_generic_unordered_lookup 201811L |
| 344 | 367 | # define __cpp_lib_int_pow2 202002L |
| 345 | 368 | # define __cpp_lib_integer_comparison_functions 202002L |
| ... | ... | @@ -351,15 +374,18 @@ __cpp_lib_void_t 201411L <type_traits> |
| 351 | 374 | # if !defined(_LIBCPP_HAS_NO_THREADS) |
| 352 | 375 | // # define __cpp_lib_jthread 201911L |
| 353 | 376 | # endif |
| 354 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_latch) | |
| 377 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC) | |
| 355 | 378 | # define __cpp_lib_latch 201907L |
| 356 | 379 | # endif |
| 357 | 380 | # define __cpp_lib_list_remove_return_type 201806L |
| 358 | 381 | # define __cpp_lib_math_constants 201907L |
| 359 | # define __cpp_lib_polymorphic_allocator 201902L | |
| 360 | # define __cpp_lib_ranges 202106L | |
| 382 | # define __cpp_lib_move_iterator_concept 202207L | |
| 383 | # if !defined(_LIBCPP_AVAILABILITY_HAS_NO_PMR) | |
| 384 | # define __cpp_lib_polymorphic_allocator 201902L | |
| 385 | # endif | |
| 386 | # define __cpp_lib_ranges 202207L | |
| 361 | 387 | # define __cpp_lib_remove_cvref 201711L |
| 362 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_semaphore) | |
| 388 | # if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_AVAILABILITY_HAS_NO_SYNC) | |
| 363 | 389 | # define __cpp_lib_semaphore 201907L |
| 364 | 390 | # endif |
| 365 | 391 | # undef __cpp_lib_shared_ptr_arrays |
| ... | ... | @@ -382,7 +408,7 @@ __cpp_lib_void_t 201411L <type_traits> |
| 382 | 408 | # define __cpp_lib_unwrap_ref 201811L |
| 383 | 409 | #endif |
| 384 | 410 | |
| 385 | #if _LIBCPP_STD_VER > 20 | |
| 411 | #if _LIBCPP_STD_VER >= 23 | |
| 386 | 412 | # define __cpp_lib_adaptor_iterator_pair_constructor 202106L |
| 387 | 413 | # define __cpp_lib_allocate_at_least 202106L |
| 388 | 414 | // # define __cpp_lib_associative_heterogeneous_erasure 202110L |
| ... | ... | @@ -393,23 +419,28 @@ __cpp_lib_void_t 201411L <type_traits> |
| 393 | 419 | // # define __cpp_lib_constexpr_cmath 202202L |
| 394 | 420 | # undef __cpp_lib_constexpr_memory |
| 395 | 421 | # define __cpp_lib_constexpr_memory 202202L |
| 396 | // # define __cpp_lib_constexpr_typeinfo 202106L | |
| 397 | # define __cpp_lib_expected 202202L | |
| 422 | # define __cpp_lib_constexpr_typeinfo 202106L | |
| 423 | # define __cpp_lib_expected 202211L | |
| 424 | # define __cpp_lib_format_ranges 202207L | |
| 425 | // # define __cpp_lib_formatters 202302L | |
| 398 | 426 | # define __cpp_lib_forward_like 202207L |
| 399 | // # define __cpp_lib_invoke_r 202106L | |
| 427 | # define __cpp_lib_invoke_r 202106L | |
| 400 | 428 | # define __cpp_lib_is_scoped_enum 202011L |
| 429 | // # define __cpp_lib_mdspan 202207L | |
| 401 | 430 | // # define __cpp_lib_move_only_function 202110L |
| 402 | 431 | # undef __cpp_lib_optional |
| 403 | 432 | # define __cpp_lib_optional 202110L |
| 404 | 433 | // # define __cpp_lib_out_ptr 202106L |
| 434 | // # define __cpp_lib_print 202207L | |
| 405 | 435 | # define __cpp_lib_ranges_as_rvalue 202207L |
| 406 | 436 | // # define __cpp_lib_ranges_chunk 202202L |
| 407 | 437 | // # define __cpp_lib_ranges_chunk_by 202202L |
| 408 | 438 | // # define __cpp_lib_ranges_iota 202202L |
| 409 | 439 | // # define __cpp_lib_ranges_join_with 202202L |
| 440 | # define __cpp_lib_ranges_repeat 202207L | |
| 410 | 441 | // # define __cpp_lib_ranges_slide 202202L |
| 411 | 442 | // # define __cpp_lib_ranges_starts_ends_with 202106L |
| 412 | // # define __cpp_lib_ranges_to_container 202202L | |
| 443 | # define __cpp_lib_ranges_to_container 202202L | |
| 413 | 444 | // # define __cpp_lib_ranges_zip 202110L |
| 414 | 445 | // # define __cpp_lib_reference_from_temporary 202202L |
| 415 | 446 | // # define __cpp_lib_spanstream 202106L |
| ... | ... | @@ -417,10 +448,31 @@ __cpp_lib_void_t 201411L <type_traits> |
| 417 | 448 | # define __cpp_lib_stdatomic_h 202011L |
| 418 | 449 | # define __cpp_lib_string_contains 202011L |
| 419 | 450 | # define __cpp_lib_string_resize_and_overwrite 202110L |
| 451 | // # define __cpp_lib_to_string 202306L | |
| 420 | 452 | # define __cpp_lib_to_underlying 202102L |
| 421 | 453 | # define __cpp_lib_unreachable 202202L |
| 422 | 454 | #endif |
| 423 | 455 | |
| 456 | #if _LIBCPP_STD_VER >= 26 | |
| 457 | // # define __cpp_lib_associative_heterogeneous_insertion 202306L | |
| 458 | # undef __cpp_lib_bind_back | |
| 459 | // # define __cpp_lib_bind_back 202306L | |
| 460 | # undef __cpp_lib_bind_front | |
| 461 | # define __cpp_lib_bind_front 202306L | |
| 462 | // # define __cpp_lib_bitset 202306L | |
| 463 | // # define __cpp_lib_copyable_function 202306L | |
| 464 | // # define __cpp_lib_fstream_native_handle 202306L | |
| 465 | // # define __cpp_lib_function_ref 202306L | |
| 466 | // # define __cpp_lib_hazard_pointer 202306L | |
| 467 | # define __cpp_lib_ratio 202306L | |
| 468 | // # define __cpp_lib_rcu 202306L | |
| 469 | // # define __cpp_lib_smart_ptr_owner_equality 202306L | |
| 470 | // # define __cpp_lib_sstream_from_string_view 202306L | |
| 471 | // # define __cpp_lib_submdspan 202306L | |
| 472 | // # define __cpp_lib_text_encoding 202306L | |
| 473 | // # define __cpp_lib_within_lifetime 202306L | |
| 474 | #endif | |
| 475 | ||
| 424 | 476 | // clang-format on |
| 425 | 477 | |
| 426 | 478 | #endif // _LIBCPP_VERSIONH |
lib/libcxx/include/wchar.h+4| ... | ... | @@ -116,12 +116,16 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, |
| 116 | 116 | # pragma GCC system_header |
| 117 | 117 | #endif |
| 118 | 118 | |
| 119 | // We define this here to support older versions of glibc <wchar.h> that do | |
| 120 | // not define this for clang. | |
| 119 | 121 | #ifdef __cplusplus |
| 120 | 122 | #define __CORRECT_ISO_CPP_WCHAR_H_PROTO |
| 121 | 123 | #endif |
| 122 | 124 | |
| 123 | 125 | # if __has_include_next(<wchar.h>) |
| 124 | 126 | # include_next <wchar.h> |
| 127 | # else | |
| 128 | # include <__mbstate_t.h> // make sure we have mbstate_t regardless of the existence of <wchar.h> | |
| 125 | 129 | # endif |
| 126 | 130 | |
| 127 | 131 | // Determine whether we have const-correct overloads for wcschr and friends. |
lib/libcxx/src/algorithm.cpp+16-21| ... | ... | @@ -7,11 +7,25 @@ |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | 9 | #include <algorithm> |
| 10 | #include <bit> | |
| 10 | 11 | |
| 11 | 12 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 12 | 13 | |
| 13 | // TODO(varconst): this currently doesn't benefit `ranges::sort` because it uses `ranges::less` instead of `__less`. | |
| 14 | template <class Comp, class RandomAccessIterator> | |
| 15 | void __sort(RandomAccessIterator first, RandomAccessIterator last, Comp comp) { | |
| 16 | auto depth_limit = 2 * std::__bit_log2(static_cast<size_t>(last - first)); | |
| 14 | 17 | |
| 18 | // Only use bitset partitioning for arithmetic types. We should also check | |
| 19 | // that the default comparator is in use so that we are sure that there are no | |
| 20 | // branches in the comparator. | |
| 21 | std::__introsort<_ClassicAlgPolicy, | |
| 22 | ranges::less, | |
| 23 | RandomAccessIterator, | |
| 24 | __use_branchless_sort<ranges::less, RandomAccessIterator>::value>( | |
| 25 | first, last, ranges::less{}, depth_limit); | |
| 26 | } | |
| 27 | ||
| 28 | // clang-format off | |
| 15 | 29 | template void __sort<__less<char>&, char*>(char*, char*, __less<char>&); |
| 16 | 30 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 17 | 31 | template void __sort<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); |
| ... | ... | @@ -29,25 +43,6 @@ template void __sort<__less<unsigned long long>&, unsigned long long*>(unsigned |
| 29 | 43 | template void __sort<__less<float>&, float*>(float*, float*, __less<float>&); |
| 30 | 44 | template void __sort<__less<double>&, double*>(double*, double*, __less<double>&); |
| 31 | 45 | template void __sort<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); |
| 32 | ||
| 33 | template bool __insertion_sort_incomplete<__less<char>&, char*>(char*, char*, __less<char>&); | |
| 34 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 35 | template bool __insertion_sort_incomplete<__less<wchar_t>&, wchar_t*>(wchar_t*, wchar_t*, __less<wchar_t>&); | |
| 36 | #endif | |
| 37 | template bool __insertion_sort_incomplete<__less<signed char>&, signed char*>(signed char*, signed char*, __less<signed char>&); | |
| 38 | template bool __insertion_sort_incomplete<__less<unsigned char>&, unsigned char*>(unsigned char*, unsigned char*, __less<unsigned char>&); | |
| 39 | template bool __insertion_sort_incomplete<__less<short>&, short*>(short*, short*, __less<short>&); | |
| 40 | template bool __insertion_sort_incomplete<__less<unsigned short>&, unsigned short*>(unsigned short*, unsigned short*, __less<unsigned short>&); | |
| 41 | template bool __insertion_sort_incomplete<__less<int>&, int*>(int*, int*, __less<int>&); | |
| 42 | template bool __insertion_sort_incomplete<__less<unsigned>&, unsigned*>(unsigned*, unsigned*, __less<unsigned>&); | |
| 43 | template bool __insertion_sort_incomplete<__less<long>&, long*>(long*, long*, __less<long>&); | |
| 44 | template bool __insertion_sort_incomplete<__less<unsigned long>&, unsigned long*>(unsigned long*, unsigned long*, __less<unsigned long>&); | |
| 45 | template bool __insertion_sort_incomplete<__less<long long>&, long long*>(long long*, long long*, __less<long long>&); | |
| 46 | template bool __insertion_sort_incomplete<__less<unsigned long long>&, unsigned long long*>(unsigned long long*, unsigned long long*, __less<unsigned long long>&); | |
| 47 | template bool __insertion_sort_incomplete<__less<float>&, float*>(float*, float*, __less<float>&); | |
| 48 | template bool __insertion_sort_incomplete<__less<double>&, double*>(double*, double*, __less<double>&); | |
| 49 | template bool __insertion_sort_incomplete<__less<long double>&, long double*>(long double*, long double*, __less<long double>&); | |
| 50 | ||
| 51 | template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); | |
| 46 | // clang-format on | |
| 52 | 47 | |
| 53 | 48 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/any.cpp+1-1| ... | ... | @@ -21,7 +21,7 @@ const char* bad_any_cast::what() const noexcept { |
| 21 | 21 | // Even though it no longer exists in a header file |
| 22 | 22 | _LIBCPP_BEGIN_NAMESPACE_LFTS |
| 23 | 23 | |
| 24 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast | |
| 24 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast | |
| 25 | 25 | { |
| 26 | 26 | public: |
| 27 | 27 | virtual const char* what() const noexcept; |
lib/libcxx/src/atomic.cpp+11-3| ... | ... | @@ -9,11 +9,14 @@ |
| 9 | 9 | #include <__config> |
| 10 | 10 | #ifndef _LIBCPP_HAS_NO_THREADS |
| 11 | 11 | |
| 12 | #include <__thread/timed_backoff_policy.h> | |
| 12 | 13 | #include <atomic> |
| 13 | 14 | #include <climits> |
| 14 | 15 | #include <functional> |
| 15 | 16 | #include <thread> |
| 16 | 17 | |
| 18 | #include "include/apple_availability.h" | |
| 19 | ||
| 17 | 20 | #ifdef __linux__ |
| 18 | 21 | |
| 19 | 22 | #include <unistd.h> |
| ... | ... | @@ -77,20 +80,25 @@ static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const vo |
| 77 | 80 | const_cast<__cxx_atomic_contention_t*>(__ptr), 0); |
| 78 | 81 | } |
| 79 | 82 | |
| 80 | #elif defined(__FreeBSD__) | |
| 83 | #elif defined(__FreeBSD__) && __SIZEOF_LONG__ == 8 | |
| 84 | /* | |
| 85 | * Since __cxx_contention_t is int64_t even on 32bit FreeBSD | |
| 86 | * platforms, we have to use umtx ops that work on the long type, and | |
| 87 | * limit its use to architectures where long and int64_t are synonyms. | |
| 88 | */ | |
| 81 | 89 | |
| 82 | 90 | static void __libcpp_platform_wait_on_address(__cxx_atomic_contention_t const volatile* __ptr, |
| 83 | 91 | __cxx_contention_t __val) |
| 84 | 92 | { |
| 85 | 93 | _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), |
| 86 | UMTX_OP_WAIT_UINT_PRIVATE, __val, NULL, NULL); | |
| 94 | UMTX_OP_WAIT, __val, NULL, NULL); | |
| 87 | 95 | } |
| 88 | 96 | |
| 89 | 97 | static void __libcpp_platform_wake_by_address(__cxx_atomic_contention_t const volatile* __ptr, |
| 90 | 98 | bool __notify_one) |
| 91 | 99 | { |
| 92 | 100 | _umtx_op(const_cast<__cxx_atomic_contention_t*>(__ptr), |
| 93 | UMTX_OP_WAKE_PRIVATE, __notify_one ? 1 : INT_MAX, NULL, NULL); | |
| 101 | UMTX_OP_WAKE, __notify_one ? 1 : INT_MAX, NULL, NULL); | |
| 94 | 102 | } |
| 95 | 103 | |
| 96 | 104 | #else // <- Add other operating systems here |
lib/libcxx/src/charconv.cpp+2-2| ... | ... | @@ -18,13 +18,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 18 | 18 | namespace __itoa |
| 19 | 19 | { |
| 20 | 20 | |
| 21 | _LIBCPP_FUNC_VIS char* | |
| 21 | _LIBCPP_EXPORTED_FROM_ABI char* | |
| 22 | 22 | __u32toa(uint32_t value, char* buffer) noexcept |
| 23 | 23 | { |
| 24 | 24 | return __base_10_u32(buffer, value); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | _LIBCPP_FUNC_VIS char* | |
| 27 | _LIBCPP_EXPORTED_FROM_ABI char* | |
| 28 | 28 | __u64toa(uint64_t value, char* buffer) noexcept |
| 29 | 29 | { |
| 30 | 30 | return __base_10_u64(buffer, value); |
lib/libcxx/src/chrono.cpp+7-62| ... | ... | @@ -12,9 +12,9 @@ |
| 12 | 12 | #define _LARGE_TIME_API |
| 13 | 13 | #endif |
| 14 | 14 | |
| 15 | #include <cerrno> // errno | |
| 15 | #include <__system_error/system_error.h> | |
| 16 | #include <cerrno> // errno | |
| 16 | 17 | #include <chrono> |
| 17 | #include <system_error> // __throw_system_error | |
| 18 | 18 | |
| 19 | 19 | #if defined(__MVS__) |
| 20 | 20 | #include <__support/ibm/gettod_zos.h> // gettimeofdayMonotonic |
| ... | ... | @@ -24,15 +24,15 @@ |
| 24 | 24 | #include "include/apple_availability.h" |
| 25 | 25 | |
| 26 | 26 | #if __has_include(<unistd.h>) |
| 27 | # include <unistd.h> | |
| 27 | # include <unistd.h> // _POSIX_TIMERS | |
| 28 | 28 | #endif |
| 29 | 29 | |
| 30 | 30 | #if __has_include(<sys/time.h>) |
| 31 | 31 | # include <sys/time.h> // for gettimeofday and timeval |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | #if !defined(__APPLE__) && defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 | |
| 35 | # define _LIBCPP_USE_CLOCK_GETTIME | |
| 34 | #if defined(__APPLE__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) | |
| 35 | # define _LIBCPP_HAS_CLOCK_GETTIME | |
| 36 | 36 | #endif |
| 37 | 37 | |
| 38 | 38 | #if defined(_LIBCPP_WIN32API) |
| ... | ... | @@ -116,7 +116,7 @@ static system_clock::time_point __libcpp_system_clock_now() { |
| 116 | 116 | return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch)); |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | #elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME) | |
| 119 | #elif defined(_LIBCPP_HAS_CLOCK_GETTIME) | |
| 120 | 120 | |
| 121 | 121 | static system_clock::time_point __libcpp_system_clock_now() { |
| 122 | 122 | struct timespec tp; |
| ... | ... | @@ -167,59 +167,6 @@ system_clock::from_time_t(time_t t) noexcept |
| 167 | 167 | |
| 168 | 168 | #if defined(__APPLE__) |
| 169 | 169 | |
| 170 | // TODO(ldionne): | |
| 171 | // This old implementation of steady_clock is retained until Chrome drops supports | |
| 172 | // for macOS < 10.12. The issue is that they link libc++ statically into their | |
| 173 | // application, which means that libc++ must support being built for such deployment | |
| 174 | // targets. See https://llvm.org/D74489 for details. | |
| 175 | #if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ | |
| 176 | (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 177 | (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ | |
| 178 | (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) | |
| 179 | # define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME | |
| 180 | #endif | |
| 181 | ||
| 182 | #if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME) | |
| 183 | ||
| 184 | // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of | |
| 185 | // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom | |
| 186 | // are run time constants supplied by the OS. This clock has no relationship | |
| 187 | // to the Gregorian calendar. It's main use is as a high resolution timer. | |
| 188 | ||
| 189 | // MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize | |
| 190 | // for that case as an optimization. | |
| 191 | ||
| 192 | static steady_clock::rep steady_simplified() { | |
| 193 | return static_cast<steady_clock::rep>(mach_absolute_time()); | |
| 194 | } | |
| 195 | static double compute_steady_factor() { | |
| 196 | mach_timebase_info_data_t MachInfo; | |
| 197 | mach_timebase_info(&MachInfo); | |
| 198 | return static_cast<double>(MachInfo.numer) / MachInfo.denom; | |
| 199 | } | |
| 200 | ||
| 201 | static steady_clock::rep steady_full() { | |
| 202 | static const double factor = compute_steady_factor(); | |
| 203 | return static_cast<steady_clock::rep>(mach_absolute_time() * factor); | |
| 204 | } | |
| 205 | ||
| 206 | typedef steady_clock::rep (*FP)(); | |
| 207 | ||
| 208 | static FP init_steady_clock() { | |
| 209 | mach_timebase_info_data_t MachInfo; | |
| 210 | mach_timebase_info(&MachInfo); | |
| 211 | if (MachInfo.numer == MachInfo.denom) | |
| 212 | return &steady_simplified; | |
| 213 | return &steady_full; | |
| 214 | } | |
| 215 | ||
| 216 | static steady_clock::time_point __libcpp_steady_clock_now() { | |
| 217 | static FP fp = init_steady_clock(); | |
| 218 | return steady_clock::time_point(steady_clock::duration(fp())); | |
| 219 | } | |
| 220 | ||
| 221 | #else // vvvvv default behavior for Apple platforms vvvvv | |
| 222 | ||
| 223 | 170 | // On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or |
| 224 | 171 | // mach_absolute_time are able to time functions in the nanosecond range. |
| 225 | 172 | // Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it |
| ... | ... | @@ -232,8 +179,6 @@ static steady_clock::time_point __libcpp_steady_clock_now() { |
| 232 | 179 | return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec)); |
| 233 | 180 | } |
| 234 | 181 | |
| 235 | #endif | |
| 236 | ||
| 237 | 182 | #elif defined(_LIBCPP_WIN32API) |
| 238 | 183 | |
| 239 | 184 | // https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says: |
| ... | ... | @@ -281,7 +226,7 @@ static steady_clock::time_point __libcpp_steady_clock_now() noexcept { |
| 281 | 226 | return steady_clock::time_point(nanoseconds(_zx_clock_get_monotonic())); |
| 282 | 227 | } |
| 283 | 228 | |
| 284 | # elif defined(CLOCK_MONOTONIC) | |
| 229 | # elif defined(_LIBCPP_HAS_CLOCK_GETTIME) | |
| 285 | 230 | |
| 286 | 231 | static steady_clock::time_point __libcpp_steady_clock_now() { |
| 287 | 232 | struct timespec tp; |
lib/libcxx/src/condition_variable.cpp-1| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | |
| 13 | 13 | #include <condition_variable> |
| 14 | 14 | #include <thread> |
| 15 | #include <system_error> | |
| 16 | 15 | |
| 17 | 16 | #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) |
| 18 | 17 | # pragma comment(lib, "pthread") |
lib/libcxx/src/condition_variable_destructor.cpp+1-1| ... | ... | @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 24 | 24 | |
| 25 | 25 | #ifdef NEEDS_CONDVAR_DESTRUCTOR |
| 26 | 26 | |
| 27 | class _LIBCPP_TYPE_VIS condition_variable | |
| 27 | class _LIBCPP_EXPORTED_FROM_ABI condition_variable | |
| 28 | 28 | { |
| 29 | 29 | __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; |
| 30 | 30 | public: |
lib/libcxx/src/debug.cpp deleted-559| ... | ... | @@ -1,559 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__assert> | |
| 10 | #include <__config> | |
| 11 | #include <__debug> | |
| 12 | #include <__hash_table> | |
| 13 | #include <algorithm> | |
| 14 | #include <cstdio> | |
| 15 | #include <functional> | |
| 16 | #include <string> | |
| 17 | ||
| 18 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 19 | # include <mutex> | |
| 20 | # if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) | |
| 21 | # pragma comment(lib, "pthread") | |
| 22 | # endif | |
| 23 | #endif | |
| 24 | ||
| 25 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 26 | ||
| 27 | _LIBCPP_FUNC_VIS | |
| 28 | __libcpp_db* | |
| 29 | __get_db() | |
| 30 | { | |
| 31 | static _LIBCPP_NO_DESTROY __libcpp_db db; | |
| 32 | return &db; | |
| 33 | } | |
| 34 | ||
| 35 | _LIBCPP_FUNC_VIS | |
| 36 | const __libcpp_db* | |
| 37 | __get_const_db() | |
| 38 | { | |
| 39 | return __get_db(); | |
| 40 | } | |
| 41 | ||
| 42 | namespace | |
| 43 | { | |
| 44 | ||
| 45 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 46 | typedef mutex mutex_type; | |
| 47 | typedef lock_guard<mutex_type> WLock; | |
| 48 | typedef lock_guard<mutex_type> RLock; | |
| 49 | ||
| 50 | mutex_type& | |
| 51 | mut() | |
| 52 | { | |
| 53 | static _LIBCPP_NO_DESTROY mutex_type m; | |
| 54 | return m; | |
| 55 | } | |
| 56 | #endif // !_LIBCPP_HAS_NO_THREADS | |
| 57 | ||
| 58 | } // unnamed namespace | |
| 59 | ||
| 60 | __i_node::~__i_node() | |
| 61 | { | |
| 62 | if (__next_) | |
| 63 | { | |
| 64 | __next_->~__i_node(); | |
| 65 | free(__next_); | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 69 | __c_node::~__c_node() | |
| 70 | { | |
| 71 | free(beg_); | |
| 72 | if (__next_) | |
| 73 | { | |
| 74 | __next_->~__c_node(); | |
| 75 | free(__next_); | |
| 76 | } | |
| 77 | } | |
| 78 | ||
| 79 | __libcpp_db::__libcpp_db() | |
| 80 | : __cbeg_(nullptr), | |
| 81 | __cend_(nullptr), | |
| 82 | __csz_(0), | |
| 83 | __ibeg_(nullptr), | |
| 84 | __iend_(nullptr), | |
| 85 | __isz_(0) | |
| 86 | { | |
| 87 | } | |
| 88 | ||
| 89 | __libcpp_db::~__libcpp_db() | |
| 90 | { | |
| 91 | if (__cbeg_) | |
| 92 | { | |
| 93 | for (__c_node** p = __cbeg_; p != __cend_; ++p) | |
| 94 | { | |
| 95 | if (*p != nullptr) | |
| 96 | { | |
| 97 | (*p)->~__c_node(); | |
| 98 | free(*p); | |
| 99 | } | |
| 100 | } | |
| 101 | free(__cbeg_); | |
| 102 | } | |
| 103 | if (__ibeg_) | |
| 104 | { | |
| 105 | for (__i_node** p = __ibeg_; p != __iend_; ++p) | |
| 106 | { | |
| 107 | if (*p != nullptr) | |
| 108 | { | |
| 109 | (*p)->~__i_node(); | |
| 110 | free(*p); | |
| 111 | } | |
| 112 | } | |
| 113 | free(__ibeg_); | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | void* | |
| 118 | __libcpp_db::__find_c_from_i(void* __i) const | |
| 119 | { | |
| 120 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 121 | RLock _(mut()); | |
| 122 | #endif | |
| 123 | __i_node* i = __find_iterator(__i); | |
| 124 | _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database."); | |
| 125 | return i->__c_ != nullptr ? i->__c_->__c_ : nullptr; | |
| 126 | } | |
| 127 | ||
| 128 | void | |
| 129 | __libcpp_db::__insert_ic(void* __i, const void* __c) | |
| 130 | { | |
| 131 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 132 | WLock _(mut()); | |
| 133 | #endif | |
| 134 | if (__cbeg_ == __cend_) | |
| 135 | return; | |
| 136 | size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 137 | __c_node* c = __cbeg_[hc]; | |
| 138 | if (c == nullptr) | |
| 139 | return; | |
| 140 | while (c->__c_ != __c) | |
| 141 | { | |
| 142 | c = c->__next_; | |
| 143 | if (c == nullptr) | |
| 144 | return; | |
| 145 | } | |
| 146 | __i_node* i = __insert_iterator(__i); | |
| 147 | c->__add(i); | |
| 148 | i->__c_ = c; | |
| 149 | } | |
| 150 | ||
| 151 | void | |
| 152 | __libcpp_db::__insert_c(void* __c, __libcpp_db::_InsertConstruct *__fn) | |
| 153 | { | |
| 154 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 155 | WLock _(mut()); | |
| 156 | #endif | |
| 157 | if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_)) | |
| 158 | { | |
| 159 | size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1); | |
| 160 | __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(__c_node*))); | |
| 161 | if (cbeg == nullptr) | |
| 162 | __throw_bad_alloc(); | |
| 163 | ||
| 164 | for (__c_node** p = __cbeg_; p != __cend_; ++p) | |
| 165 | { | |
| 166 | __c_node* q = *p; | |
| 167 | while (q != nullptr) | |
| 168 | { | |
| 169 | size_t h = hash<void*>()(q->__c_) % nc; | |
| 170 | __c_node* r = q->__next_; | |
| 171 | q->__next_ = cbeg[h]; | |
| 172 | cbeg[h] = q; | |
| 173 | q = r; | |
| 174 | } | |
| 175 | } | |
| 176 | free(__cbeg_); | |
| 177 | __cbeg_ = cbeg; | |
| 178 | __cend_ = __cbeg_ + nc; | |
| 179 | } | |
| 180 | size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 181 | __c_node* p = __cbeg_[hc]; | |
| 182 | void *buf = malloc(sizeof(__c_node)); | |
| 183 | if (buf == nullptr) | |
| 184 | __throw_bad_alloc(); | |
| 185 | __cbeg_[hc] = __fn(buf, __c, p); | |
| 186 | ||
| 187 | ++__csz_; | |
| 188 | } | |
| 189 | ||
| 190 | void | |
| 191 | __libcpp_db::__erase_i(void* __i) | |
| 192 | { | |
| 193 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 194 | WLock _(mut()); | |
| 195 | #endif | |
| 196 | if (__ibeg_ != __iend_) | |
| 197 | { | |
| 198 | size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); | |
| 199 | __i_node* p = __ibeg_[hi]; | |
| 200 | if (p != nullptr) | |
| 201 | { | |
| 202 | __i_node* q = nullptr; | |
| 203 | while (p->__i_ != __i) | |
| 204 | { | |
| 205 | q = p; | |
| 206 | p = p->__next_; | |
| 207 | if (p == nullptr) | |
| 208 | return; | |
| 209 | } | |
| 210 | if (q == nullptr) | |
| 211 | __ibeg_[hi] = p->__next_; | |
| 212 | else | |
| 213 | q->__next_ = p->__next_; | |
| 214 | __c_node* c = p->__c_; | |
| 215 | --__isz_; | |
| 216 | if (c != nullptr) | |
| 217 | c->__remove(p); | |
| 218 | free(p); | |
| 219 | } | |
| 220 | } | |
| 221 | } | |
| 222 | ||
| 223 | void | |
| 224 | __libcpp_db::__invalidate_all(void* __c) | |
| 225 | { | |
| 226 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 227 | WLock _(mut()); | |
| 228 | #endif | |
| 229 | if (__cend_ != __cbeg_) | |
| 230 | { | |
| 231 | size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 232 | __c_node* p = __cbeg_[hc]; | |
| 233 | if (p == nullptr) | |
| 234 | return; | |
| 235 | while (p->__c_ != __c) | |
| 236 | { | |
| 237 | p = p->__next_; | |
| 238 | if (p == nullptr) | |
| 239 | return; | |
| 240 | } | |
| 241 | while (p->end_ != p->beg_) | |
| 242 | { | |
| 243 | --p->end_; | |
| 244 | (*p->end_)->__c_ = nullptr; | |
| 245 | } | |
| 246 | } | |
| 247 | } | |
| 248 | ||
| 249 | __c_node* | |
| 250 | __libcpp_db::__find_c_and_lock(void* __c) const | |
| 251 | { | |
| 252 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 253 | mut().lock(); | |
| 254 | #endif | |
| 255 | if (__cend_ == __cbeg_) | |
| 256 | { | |
| 257 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 258 | mut().unlock(); | |
| 259 | #endif | |
| 260 | return nullptr; | |
| 261 | } | |
| 262 | size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 263 | __c_node* p = __cbeg_[hc]; | |
| 264 | if (p == nullptr) | |
| 265 | { | |
| 266 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 267 | mut().unlock(); | |
| 268 | #endif | |
| 269 | return nullptr; | |
| 270 | } | |
| 271 | while (p->__c_ != __c) | |
| 272 | { | |
| 273 | p = p->__next_; | |
| 274 | if (p == nullptr) | |
| 275 | { | |
| 276 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 277 | mut().unlock(); | |
| 278 | #endif | |
| 279 | return nullptr; | |
| 280 | } | |
| 281 | } | |
| 282 | return p; | |
| 283 | } | |
| 284 | ||
| 285 | __c_node* | |
| 286 | __libcpp_db::__find_c(void* __c) const | |
| 287 | { | |
| 288 | size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 289 | __c_node* p = __cbeg_[hc]; | |
| 290 | _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A"); | |
| 291 | while (p->__c_ != __c) | |
| 292 | { | |
| 293 | p = p->__next_; | |
| 294 | _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B"); | |
| 295 | } | |
| 296 | return p; | |
| 297 | } | |
| 298 | ||
| 299 | void | |
| 300 | __libcpp_db::unlock() const | |
| 301 | { | |
| 302 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 303 | mut().unlock(); | |
| 304 | #endif | |
| 305 | } | |
| 306 | ||
| 307 | void | |
| 308 | __libcpp_db::__erase_c(void* __c) | |
| 309 | { | |
| 310 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 311 | WLock _(mut()); | |
| 312 | #endif | |
| 313 | if (__cend_ != __cbeg_) | |
| 314 | { | |
| 315 | size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 316 | __c_node* p = __cbeg_[hc]; | |
| 317 | if (p == nullptr) | |
| 318 | return; | |
| 319 | __c_node* q = nullptr; | |
| 320 | _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A"); | |
| 321 | while (p->__c_ != __c) | |
| 322 | { | |
| 323 | q = p; | |
| 324 | p = p->__next_; | |
| 325 | if (p == nullptr) | |
| 326 | return; | |
| 327 | _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B"); | |
| 328 | } | |
| 329 | if (q == nullptr) | |
| 330 | __cbeg_[hc] = p->__next_; | |
| 331 | else | |
| 332 | q->__next_ = p->__next_; | |
| 333 | while (p->end_ != p->beg_) | |
| 334 | { | |
| 335 | --p->end_; | |
| 336 | (*p->end_)->__c_ = nullptr; | |
| 337 | } | |
| 338 | free(p->beg_); | |
| 339 | free(p); | |
| 340 | --__csz_; | |
| 341 | } | |
| 342 | } | |
| 343 | ||
| 344 | void | |
| 345 | __libcpp_db::__iterator_copy(void* __i, const void* __i0) | |
| 346 | { | |
| 347 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 348 | WLock _(mut()); | |
| 349 | #endif | |
| 350 | __i_node* i = __find_iterator(__i); | |
| 351 | __i_node* i0 = __find_iterator(__i0); | |
| 352 | __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr; | |
| 353 | if (i == nullptr && i0 != nullptr) | |
| 354 | i = __insert_iterator(__i); | |
| 355 | __c_node* c = i != nullptr ? i->__c_ : nullptr; | |
| 356 | if (c != c0) | |
| 357 | { | |
| 358 | if (c != nullptr) | |
| 359 | c->__remove(i); | |
| 360 | if (i != nullptr) | |
| 361 | { | |
| 362 | i->__c_ = nullptr; | |
| 363 | if (c0 != nullptr) | |
| 364 | { | |
| 365 | i->__c_ = c0; | |
| 366 | i->__c_->__add(i); | |
| 367 | } | |
| 368 | } | |
| 369 | } | |
| 370 | } | |
| 371 | ||
| 372 | bool | |
| 373 | __libcpp_db::__dereferenceable(const void* __i) const | |
| 374 | { | |
| 375 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 376 | RLock _(mut()); | |
| 377 | #endif | |
| 378 | __i_node* i = __find_iterator(__i); | |
| 379 | return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i); | |
| 380 | } | |
| 381 | ||
| 382 | bool | |
| 383 | __libcpp_db::__decrementable(const void* __i) const | |
| 384 | { | |
| 385 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 386 | RLock _(mut()); | |
| 387 | #endif | |
| 388 | __i_node* i = __find_iterator(__i); | |
| 389 | return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i); | |
| 390 | } | |
| 391 | ||
| 392 | bool | |
| 393 | __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const | |
| 394 | { | |
| 395 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 396 | RLock _(mut()); | |
| 397 | #endif | |
| 398 | __i_node* i = __find_iterator(__i); | |
| 399 | return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n); | |
| 400 | } | |
| 401 | ||
| 402 | bool | |
| 403 | __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const | |
| 404 | { | |
| 405 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 406 | RLock _(mut()); | |
| 407 | #endif | |
| 408 | __i_node* i = __find_iterator(__i); | |
| 409 | return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n); | |
| 410 | } | |
| 411 | ||
| 412 | bool | |
| 413 | __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const | |
| 414 | { | |
| 415 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 416 | RLock _(mut()); | |
| 417 | #endif | |
| 418 | __i_node* i = __find_iterator(__i); | |
| 419 | __i_node* j = __find_iterator(__j); | |
| 420 | __c_node* ci = i != nullptr ? i->__c_ : nullptr; | |
| 421 | __c_node* cj = j != nullptr ? j->__c_ : nullptr; | |
| 422 | return ci == cj; | |
| 423 | } | |
| 424 | ||
| 425 | void | |
| 426 | __libcpp_db::swap(void* c1, void* c2) | |
| 427 | { | |
| 428 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 429 | WLock _(mut()); | |
| 430 | #endif | |
| 431 | size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 432 | __c_node* p1 = __cbeg_[hc]; | |
| 433 | _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A"); | |
| 434 | while (p1->__c_ != c1) | |
| 435 | { | |
| 436 | p1 = p1->__next_; | |
| 437 | _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B"); | |
| 438 | } | |
| 439 | hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_); | |
| 440 | __c_node* p2 = __cbeg_[hc]; | |
| 441 | _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C"); | |
| 442 | while (p2->__c_ != c2) | |
| 443 | { | |
| 444 | p2 = p2->__next_; | |
| 445 | _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D"); | |
| 446 | } | |
| 447 | std::swap(p1->beg_, p2->beg_); | |
| 448 | std::swap(p1->end_, p2->end_); | |
| 449 | std::swap(p1->cap_, p2->cap_); | |
| 450 | for (__i_node** p = p1->beg_; p != p1->end_; ++p) | |
| 451 | (*p)->__c_ = p1; | |
| 452 | for (__i_node** p = p2->beg_; p != p2->end_; ++p) | |
| 453 | (*p)->__c_ = p2; | |
| 454 | } | |
| 455 | ||
| 456 | void | |
| 457 | __libcpp_db::__insert_i(void* __i) | |
| 458 | { | |
| 459 | #ifndef _LIBCPP_HAS_NO_THREADS | |
| 460 | WLock _(mut()); | |
| 461 | #endif | |
| 462 | __insert_iterator(__i); | |
| 463 | } | |
| 464 | ||
| 465 | void | |
| 466 | __c_node::__add(__i_node* i) | |
| 467 | { | |
| 468 | if (end_ == cap_) | |
| 469 | { | |
| 470 | size_t nc = 2*static_cast<size_t>(cap_ - beg_); | |
| 471 | if (nc == 0) | |
| 472 | nc = 1; | |
| 473 | __i_node** beg = | |
| 474 | static_cast<__i_node**>(malloc(nc * sizeof(__i_node*))); | |
| 475 | if (beg == nullptr) | |
| 476 | __throw_bad_alloc(); | |
| 477 | ||
| 478 | if (nc > 1) | |
| 479 | memcpy(beg, beg_, nc/2*sizeof(__i_node*)); | |
| 480 | free(beg_); | |
| 481 | beg_ = beg; | |
| 482 | end_ = beg_ + nc/2; | |
| 483 | cap_ = beg_ + nc; | |
| 484 | } | |
| 485 | *end_++ = i; | |
| 486 | } | |
| 487 | ||
| 488 | // private api | |
| 489 | ||
| 490 | _LIBCPP_HIDDEN | |
| 491 | __i_node* | |
| 492 | __libcpp_db::__insert_iterator(void* __i) | |
| 493 | { | |
| 494 | if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_)) | |
| 495 | { | |
| 496 | size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1); | |
| 497 | __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(__i_node*))); | |
| 498 | if (ibeg == nullptr) | |
| 499 | __throw_bad_alloc(); | |
| 500 | ||
| 501 | for (__i_node** p = __ibeg_; p != __iend_; ++p) | |
| 502 | { | |
| 503 | __i_node* q = *p; | |
| 504 | while (q != nullptr) | |
| 505 | { | |
| 506 | size_t h = hash<void*>()(q->__i_) % nc; | |
| 507 | __i_node* r = q->__next_; | |
| 508 | q->__next_ = ibeg[h]; | |
| 509 | ibeg[h] = q; | |
| 510 | q = r; | |
| 511 | } | |
| 512 | } | |
| 513 | free(__ibeg_); | |
| 514 | __ibeg_ = ibeg; | |
| 515 | __iend_ = __ibeg_ + nc; | |
| 516 | } | |
| 517 | size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); | |
| 518 | __i_node* p = __ibeg_[hi]; | |
| 519 | __i_node* r = __ibeg_[hi] = | |
| 520 | static_cast<__i_node*>(malloc(sizeof(__i_node))); | |
| 521 | if (r == nullptr) | |
| 522 | __throw_bad_alloc(); | |
| 523 | ||
| 524 | ::new(r) __i_node(__i, p, nullptr); | |
| 525 | ++__isz_; | |
| 526 | return r; | |
| 527 | } | |
| 528 | ||
| 529 | _LIBCPP_HIDDEN | |
| 530 | __i_node* | |
| 531 | __libcpp_db::__find_iterator(const void* __i) const | |
| 532 | { | |
| 533 | __i_node* r = nullptr; | |
| 534 | if (__ibeg_ != __iend_) | |
| 535 | { | |
| 536 | size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); | |
| 537 | for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_) | |
| 538 | { | |
| 539 | if (nd->__i_ == __i) | |
| 540 | { | |
| 541 | r = nd; | |
| 542 | break; | |
| 543 | } | |
| 544 | } | |
| 545 | } | |
| 546 | return r; | |
| 547 | } | |
| 548 | ||
| 549 | _LIBCPP_HIDDEN | |
| 550 | void | |
| 551 | __c_node::__remove(__i_node* p) | |
| 552 | { | |
| 553 | __i_node** r = find(beg_, end_, p); | |
| 554 | _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove"); | |
| 555 | if (--end_ != r) | |
| 556 | memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*)); | |
| 557 | } | |
| 558 | ||
| 559 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/experimental/memory_resource.cpp+2-2| ... | ... | @@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_LFTS_PMR |
| 27 | 27 | |
| 28 | 28 | // new_delete_resource() |
| 29 | 29 | |
| 30 | class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp | |
| 30 | class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp | |
| 31 | 31 | : public memory_resource |
| 32 | 32 | { |
| 33 | 33 | void *do_allocate(size_t size, size_t align) override { |
| ... | ... | @@ -51,7 +51,7 @@ public: |
| 51 | 51 | |
| 52 | 52 | // null_memory_resource() |
| 53 | 53 | |
| 54 | class _LIBCPP_TYPE_VIS __null_memory_resource_imp | |
| 54 | class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp | |
| 55 | 55 | : public memory_resource |
| 56 | 56 | { |
| 57 | 57 | public: |
lib/libcxx/src/filesystem/directory_entry.cpp created+74| ... | ... | @@ -0,0 +1,74 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__config> | |
| 10 | #include <cstdint> | |
| 11 | #include <filesystem> | |
| 12 | #include <system_error> | |
| 13 | ||
| 14 | #include "file_descriptor.h" | |
| 15 | #include "posix_compat.h" | |
| 16 | #include "time_utils.h" | |
| 17 | ||
| 18 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 19 | ||
| 20 | error_code directory_entry::__do_refresh() noexcept { | |
| 21 | __data_.__reset(); | |
| 22 | error_code failure_ec; | |
| 23 | ||
| 24 | detail::StatT full_st; | |
| 25 | file_status st = detail::posix_lstat(__p_, full_st, &failure_ec); | |
| 26 | if (!status_known(st)) { | |
| 27 | __data_.__reset(); | |
| 28 | return failure_ec; | |
| 29 | } | |
| 30 | ||
| 31 | if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) { | |
| 32 | __data_.__cache_type_ = directory_entry::_RefreshNonSymlink; | |
| 33 | __data_.__type_ = st.type(); | |
| 34 | __data_.__non_sym_perms_ = st.permissions(); | |
| 35 | } else { // we have a symlink | |
| 36 | __data_.__sym_perms_ = st.permissions(); | |
| 37 | // Get the information about the linked entity. | |
| 38 | // Ignore errors from stat, since we don't want errors regarding symlink | |
| 39 | // resolution to be reported to the user. | |
| 40 | error_code ignored_ec; | |
| 41 | st = detail::posix_stat(__p_, full_st, &ignored_ec); | |
| 42 | ||
| 43 | __data_.__type_ = st.type(); | |
| 44 | __data_.__non_sym_perms_ = st.permissions(); | |
| 45 | ||
| 46 | // If we failed to resolve the link, then only partially populate the | |
| 47 | // cache. | |
| 48 | if (!status_known(st)) { | |
| 49 | __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved; | |
| 50 | return error_code{}; | |
| 51 | } | |
| 52 | // Otherwise, we resolved the link, potentially as not existing. | |
| 53 | // That's OK. | |
| 54 | __data_.__cache_type_ = directory_entry::_RefreshSymlink; | |
| 55 | } | |
| 56 | ||
| 57 | if (_VSTD_FS::is_regular_file(st)) | |
| 58 | __data_.__size_ = static_cast<uintmax_t>(full_st.st_size); | |
| 59 | ||
| 60 | if (_VSTD_FS::exists(st)) { | |
| 61 | __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink); | |
| 62 | ||
| 63 | // Attempt to extract the mtime, and fail if it's not representable using | |
| 64 | // file_time_type. For now we ignore the error, as we'll report it when | |
| 65 | // the value is actually used. | |
| 66 | error_code ignored_ec; | |
| 67 | __data_.__write_time_ = | |
| 68 | detail::__extract_last_write_time(__p_, full_st, &ignored_ec); | |
| 69 | } | |
| 70 | ||
| 71 | return failure_ec; | |
| 72 | } | |
| 73 | ||
| 74 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/directory_iterator.cpp+14-4| ... | ... | @@ -11,8 +11,18 @@ |
| 11 | 11 | #include <errno.h> |
| 12 | 12 | #include <filesystem> |
| 13 | 13 | #include <stack> |
| 14 | #include <utility> | |
| 14 | 15 | |
| 15 | #include "filesystem_common.h" | |
| 16 | #include "error.h" | |
| 17 | #include "file_descriptor.h" | |
| 18 | ||
| 19 | #if defined(_LIBCPP_WIN32API) | |
| 20 | # define WIN32_LEAN_AND_MEAN | |
| 21 | # define NOMINMAX | |
| 22 | # include <windows.h> | |
| 23 | #else | |
| 24 | # include <dirent.h> // for DIR & friends | |
| 25 | #endif | |
| 16 | 26 | |
| 17 | 27 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 18 | 28 | |
| ... | ... | @@ -182,7 +192,7 @@ directory_iterator::directory_iterator(const path& p, error_code* ec, |
| 182 | 192 | } |
| 183 | 193 | |
| 184 | 194 | directory_iterator& directory_iterator::__increment(error_code* ec) { |
| 185 | _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator"); | |
| 195 | _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to increment an invalid iterator"); | |
| 186 | 196 | ErrorHandler<void> err("directory_iterator::operator++()", ec); |
| 187 | 197 | |
| 188 | 198 | error_code m_ec; |
| ... | ... | @@ -196,7 +206,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) { |
| 196 | 206 | } |
| 197 | 207 | |
| 198 | 208 | directory_entry const& directory_iterator::__dereference() const { |
| 199 | _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator"); | |
| 209 | _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Attempting to dereference an invalid iterator"); | |
| 200 | 210 | return __imp_->__entry_; |
| 201 | 211 | } |
| 202 | 212 | |
| ... | ... | @@ -225,7 +235,7 @@ recursive_directory_iterator::recursive_directory_iterator( |
| 225 | 235 | } |
| 226 | 236 | |
| 227 | 237 | void recursive_directory_iterator::__pop(error_code* ec) { |
| 228 | _LIBCPP_ASSERT(__imp_, "Popping the end iterator"); | |
| 238 | _LIBCPP_ASSERT_UNCATEGORIZED(__imp_, "Popping the end iterator"); | |
| 229 | 239 | if (ec) |
| 230 | 240 | ec->clear(); |
| 231 | 241 | __imp_->__stack_.pop(); |
lib/libcxx/src/filesystem/error.h created+238| ... | ... | @@ -0,0 +1,238 @@ |
| 1 | //===----------------------------------------------------------------------===//// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===//// | |
| 8 | ||
| 9 | #ifndef FILESYSTEM_ERROR_H | |
| 10 | #define FILESYSTEM_ERROR_H | |
| 11 | ||
| 12 | #include <__assert> | |
| 13 | #include <__config> | |
| 14 | #include <cerrno> | |
| 15 | #include <cstdarg> | |
| 16 | #include <cstddef> | |
| 17 | #include <cstdint> | |
| 18 | #include <filesystem> | |
| 19 | #include <string> | |
| 20 | #include <system_error> | |
| 21 | #include <utility> // __libcpp_unreachable | |
| 22 | ||
| 23 | #include "format_string.h" | |
| 24 | ||
| 25 | #if defined(_LIBCPP_WIN32API) | |
| 26 | # define WIN32_LEAN_AND_MEAN | |
| 27 | # define NOMINMAX | |
| 28 | # include <windows.h> // ERROR_* macros | |
| 29 | #endif | |
| 30 | ||
| 31 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 32 | ||
| 33 | namespace detail { | |
| 34 | ||
| 35 | #if defined(_LIBCPP_WIN32API) | |
| 36 | ||
| 37 | inline errc __win_err_to_errc(int err) { | |
| 38 | constexpr struct { | |
| 39 | DWORD win; | |
| 40 | errc errc; | |
| 41 | } win_error_mapping[] = { | |
| 42 | {ERROR_ACCESS_DENIED, errc::permission_denied}, | |
| 43 | {ERROR_ALREADY_EXISTS, errc::file_exists}, | |
| 44 | {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, | |
| 45 | {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory}, | |
| 46 | {ERROR_BAD_UNIT, errc::no_such_device}, | |
| 47 | {ERROR_BROKEN_PIPE, errc::broken_pipe}, | |
| 48 | {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, | |
| 49 | {ERROR_BUSY, errc::device_or_resource_busy}, | |
| 50 | {ERROR_BUSY_DRIVE, errc::device_or_resource_busy}, | |
| 51 | {ERROR_CANNOT_MAKE, errc::permission_denied}, | |
| 52 | {ERROR_CANTOPEN, errc::io_error}, | |
| 53 | {ERROR_CANTREAD, errc::io_error}, | |
| 54 | {ERROR_CANTWRITE, errc::io_error}, | |
| 55 | {ERROR_CURRENT_DIRECTORY, errc::permission_denied}, | |
| 56 | {ERROR_DEV_NOT_EXIST, errc::no_such_device}, | |
| 57 | {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy}, | |
| 58 | {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty}, | |
| 59 | {ERROR_DIRECTORY, errc::invalid_argument}, | |
| 60 | {ERROR_DISK_FULL, errc::no_space_on_device}, | |
| 61 | {ERROR_FILE_EXISTS, errc::file_exists}, | |
| 62 | {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory}, | |
| 63 | {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device}, | |
| 64 | {ERROR_INVALID_ACCESS, errc::permission_denied}, | |
| 65 | {ERROR_INVALID_DRIVE, errc::no_such_device}, | |
| 66 | {ERROR_INVALID_FUNCTION, errc::function_not_supported}, | |
| 67 | {ERROR_INVALID_HANDLE, errc::invalid_argument}, | |
| 68 | {ERROR_INVALID_NAME, errc::no_such_file_or_directory}, | |
| 69 | {ERROR_INVALID_PARAMETER, errc::invalid_argument}, | |
| 70 | {ERROR_LOCK_VIOLATION, errc::no_lock_available}, | |
| 71 | {ERROR_LOCKED, errc::no_lock_available}, | |
| 72 | {ERROR_NEGATIVE_SEEK, errc::invalid_argument}, | |
| 73 | {ERROR_NOACCESS, errc::permission_denied}, | |
| 74 | {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory}, | |
| 75 | {ERROR_NOT_READY, errc::resource_unavailable_try_again}, | |
| 76 | {ERROR_NOT_SAME_DEVICE, errc::cross_device_link}, | |
| 77 | {ERROR_NOT_SUPPORTED, errc::not_supported}, | |
| 78 | {ERROR_OPEN_FAILED, errc::io_error}, | |
| 79 | {ERROR_OPEN_FILES, errc::device_or_resource_busy}, | |
| 80 | {ERROR_OPERATION_ABORTED, errc::operation_canceled}, | |
| 81 | {ERROR_OUTOFMEMORY, errc::not_enough_memory}, | |
| 82 | {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory}, | |
| 83 | {ERROR_READ_FAULT, errc::io_error}, | |
| 84 | {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument}, | |
| 85 | {ERROR_RETRY, errc::resource_unavailable_try_again}, | |
| 86 | {ERROR_SEEK, errc::io_error}, | |
| 87 | {ERROR_SHARING_VIOLATION, errc::permission_denied}, | |
| 88 | {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open}, | |
| 89 | {ERROR_WRITE_FAULT, errc::io_error}, | |
| 90 | {ERROR_WRITE_PROTECT, errc::permission_denied}, | |
| 91 | }; | |
| 92 | ||
| 93 | for (const auto &pair : win_error_mapping) | |
| 94 | if (pair.win == static_cast<DWORD>(err)) | |
| 95 | return pair.errc; | |
| 96 | return errc::invalid_argument; | |
| 97 | } | |
| 98 | ||
| 99 | #endif // _LIBCPP_WIN32API | |
| 100 | ||
| 101 | inline error_code capture_errno() { | |
| 102 | _LIBCPP_ASSERT_UNCATEGORIZED(errno != 0, "Expected errno to be non-zero"); | |
| 103 | return error_code(errno, generic_category()); | |
| 104 | } | |
| 105 | ||
| 106 | #if defined(_LIBCPP_WIN32API) | |
| 107 | inline error_code make_windows_error(int err) { | |
| 108 | return make_error_code(__win_err_to_errc(err)); | |
| 109 | } | |
| 110 | #endif | |
| 111 | ||
| 112 | template <class T> | |
| 113 | T error_value(); | |
| 114 | template <> | |
| 115 | inline _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {} | |
| 116 | template <> | |
| 117 | inline bool error_value<bool>() { | |
| 118 | return false; | |
| 119 | } | |
| 120 | #if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__ | |
| 121 | template <> | |
| 122 | inline size_t error_value<size_t>() { | |
| 123 | return size_t(-1); | |
| 124 | } | |
| 125 | #endif | |
| 126 | template <> | |
| 127 | inline uintmax_t error_value<uintmax_t>() { | |
| 128 | return uintmax_t(-1); | |
| 129 | } | |
| 130 | template <> | |
| 131 | inline _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() { | |
| 132 | return file_time_type::min(); | |
| 133 | } | |
| 134 | template <> | |
| 135 | inline path error_value<path>() { | |
| 136 | return {}; | |
| 137 | } | |
| 138 | ||
| 139 | template <class T> | |
| 140 | struct ErrorHandler { | |
| 141 | const char* func_name_; | |
| 142 | error_code* ec_ = nullptr; | |
| 143 | const path* p1_ = nullptr; | |
| 144 | const path* p2_ = nullptr; | |
| 145 | ||
| 146 | ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, | |
| 147 | const path* p2 = nullptr) | |
| 148 | : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) { | |
| 149 | if (ec_) | |
| 150 | ec_->clear(); | |
| 151 | } | |
| 152 | ||
| 153 | T report(const error_code& ec) const { | |
| 154 | if (ec_) { | |
| 155 | *ec_ = ec; | |
| 156 | return error_value<T>(); | |
| 157 | } | |
| 158 | string what = string("in ") + func_name_; | |
| 159 | switch (bool(p1_) + bool(p2_)) { | |
| 160 | case 0: | |
| 161 | __throw_filesystem_error(what, ec); | |
| 162 | case 1: | |
| 163 | __throw_filesystem_error(what, *p1_, ec); | |
| 164 | case 2: | |
| 165 | __throw_filesystem_error(what, *p1_, *p2_, ec); | |
| 166 | } | |
| 167 | __libcpp_unreachable(); | |
| 168 | } | |
| 169 | ||
| 170 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0) | |
| 171 | void report_impl(const error_code& ec, const char* msg, va_list ap) const { | |
| 172 | if (ec_) { | |
| 173 | *ec_ = ec; | |
| 174 | return; | |
| 175 | } | |
| 176 | string what = | |
| 177 | string("in ") + func_name_ + ": " + detail::vformat_string(msg, ap); | |
| 178 | switch (bool(p1_) + bool(p2_)) { | |
| 179 | case 0: | |
| 180 | __throw_filesystem_error(what, ec); | |
| 181 | case 1: | |
| 182 | __throw_filesystem_error(what, *p1_, ec); | |
| 183 | case 2: | |
| 184 | __throw_filesystem_error(what, *p1_, *p2_, ec); | |
| 185 | } | |
| 186 | __libcpp_unreachable(); | |
| 187 | } | |
| 188 | ||
| 189 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 190 | T report(const error_code& ec, const char* msg, ...) const { | |
| 191 | va_list ap; | |
| 192 | va_start(ap, msg); | |
| 193 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 194 | try { | |
| 195 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 196 | report_impl(ec, msg, ap); | |
| 197 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 198 | } catch (...) { | |
| 199 | va_end(ap); | |
| 200 | throw; | |
| 201 | } | |
| 202 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 203 | va_end(ap); | |
| 204 | return error_value<T>(); | |
| 205 | } | |
| 206 | ||
| 207 | T report(errc const& err) const { | |
| 208 | return report(make_error_code(err)); | |
| 209 | } | |
| 210 | ||
| 211 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 212 | T report(errc const& err, const char* msg, ...) const { | |
| 213 | va_list ap; | |
| 214 | va_start(ap, msg); | |
| 215 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 216 | try { | |
| 217 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 218 | report_impl(make_error_code(err), msg, ap); | |
| 219 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 220 | } catch (...) { | |
| 221 | va_end(ap); | |
| 222 | throw; | |
| 223 | } | |
| 224 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 225 | va_end(ap); | |
| 226 | return error_value<T>(); | |
| 227 | } | |
| 228 | ||
| 229 | private: | |
| 230 | ErrorHandler(ErrorHandler const&) = delete; | |
| 231 | ErrorHandler& operator=(ErrorHandler const&) = delete; | |
| 232 | }; | |
| 233 | ||
| 234 | } // end namespace detail | |
| 235 | ||
| 236 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 237 | ||
| 238 | #endif // FILESYSTEM_ERROR_H |
lib/libcxx/src/filesystem/file_descriptor.h created+298| ... | ... | @@ -0,0 +1,298 @@ |
| 1 | //===----------------------------------------------------------------------===//// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===//// | |
| 8 | ||
| 9 | #ifndef FILESYSTEM_FILE_DESCRIPTOR_H | |
| 10 | #define FILESYSTEM_FILE_DESCRIPTOR_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <cstdint> | |
| 14 | #include <filesystem> | |
| 15 | #include <string_view> | |
| 16 | #include <system_error> | |
| 17 | #include <utility> | |
| 18 | ||
| 19 | #include "error.h" | |
| 20 | #include "posix_compat.h" | |
| 21 | #include "time_utils.h" | |
| 22 | ||
| 23 | #if defined(_LIBCPP_WIN32API) | |
| 24 | # define WIN32_LEAN_AND_MEAN | |
| 25 | # define NOMINMAX | |
| 26 | # include <windows.h> | |
| 27 | #else | |
| 28 | # include <dirent.h> // for DIR & friends | |
| 29 | # include <fcntl.h> // values for fchmodat | |
| 30 | # include <sys/stat.h> | |
| 31 | # include <sys/statvfs.h> | |
| 32 | # include <unistd.h> | |
| 33 | #endif // defined(_LIBCPP_WIN32API) | |
| 34 | ||
| 35 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 36 | ||
| 37 | namespace detail { | |
| 38 | ||
| 39 | #if !defined(_LIBCPP_WIN32API) | |
| 40 | ||
| 41 | #if defined(DT_BLK) | |
| 42 | template <class DirEntT, class = decltype(DirEntT::d_type)> | |
| 43 | file_type get_file_type(DirEntT* ent, int) { | |
| 44 | switch (ent->d_type) { | |
| 45 | case DT_BLK: | |
| 46 | return file_type::block; | |
| 47 | case DT_CHR: | |
| 48 | return file_type::character; | |
| 49 | case DT_DIR: | |
| 50 | return file_type::directory; | |
| 51 | case DT_FIFO: | |
| 52 | return file_type::fifo; | |
| 53 | case DT_LNK: | |
| 54 | return file_type::symlink; | |
| 55 | case DT_REG: | |
| 56 | return file_type::regular; | |
| 57 | case DT_SOCK: | |
| 58 | return file_type::socket; | |
| 59 | // Unlike in lstat, hitting "unknown" here simply means that the underlying | |
| 60 | // filesystem doesn't support d_type. Report is as 'none' so we correctly | |
| 61 | // set the cache to empty. | |
| 62 | case DT_UNKNOWN: | |
| 63 | break; | |
| 64 | } | |
| 65 | return file_type::none; | |
| 66 | } | |
| 67 | #endif // defined(DT_BLK) | |
| 68 | ||
| 69 | template <class DirEntT> | |
| 70 | file_type get_file_type(DirEntT*, long) { | |
| 71 | return file_type::none; | |
| 72 | } | |
| 73 | ||
| 74 | inline pair<string_view, file_type> posix_readdir(DIR* dir_stream, | |
| 75 | error_code& ec) { | |
| 76 | struct dirent* dir_entry_ptr = nullptr; | |
| 77 | errno = 0; // zero errno in order to detect errors | |
| 78 | ec.clear(); | |
| 79 | if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { | |
| 80 | if (errno) | |
| 81 | ec = capture_errno(); | |
| 82 | return {}; | |
| 83 | } else { | |
| 84 | return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)}; | |
| 85 | } | |
| 86 | } | |
| 87 | ||
| 88 | #else // _LIBCPP_WIN32API | |
| 89 | ||
| 90 | inline file_type get_file_type(const WIN32_FIND_DATAW& data) { | |
| 91 | if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && | |
| 92 | data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) | |
| 93 | return file_type::symlink; | |
| 94 | if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
| 95 | return file_type::directory; | |
| 96 | return file_type::regular; | |
| 97 | } | |
| 98 | inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { | |
| 99 | return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow; | |
| 100 | } | |
| 101 | inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) { | |
| 102 | ULARGE_INTEGER tmp; | |
| 103 | const FILETIME& time = data.ftLastWriteTime; | |
| 104 | tmp.u.LowPart = time.dwLowDateTime; | |
| 105 | tmp.u.HighPart = time.dwHighDateTime; | |
| 106 | return file_time_type(file_time_type::duration(tmp.QuadPart)); | |
| 107 | } | |
| 108 | ||
| 109 | #endif // !_LIBCPP_WIN32API | |
| 110 | ||
| 111 | // POSIX HELPERS | |
| 112 | ||
| 113 | using value_type = path::value_type; | |
| 114 | using string_type = path::string_type; | |
| 115 | ||
| 116 | struct FileDescriptor { | |
| 117 | const path& name; | |
| 118 | int fd = -1; | |
| 119 | StatT m_stat; | |
| 120 | file_status m_status; | |
| 121 | ||
| 122 | template <class... Args> | |
| 123 | static FileDescriptor create(const path* p, error_code& ec, Args... args) { | |
| 124 | ec.clear(); | |
| 125 | int fd; | |
| 126 | #ifdef _LIBCPP_WIN32API | |
| 127 | // TODO: most of the filesystem implementation uses native Win32 calls | |
| 128 | // (mostly via posix_compat.h). However, here we use the C-runtime APIs to | |
| 129 | // open a file, because we subsequently pass the C-runtime fd to | |
| 130 | // `std::[io]fstream::__open(int fd)` in order to implement copy_file. | |
| 131 | // | |
| 132 | // Because we're calling the windows C-runtime, win32 error codes are | |
| 133 | // translated into C error numbers by the C runtime, and returned in errno, | |
| 134 | // rather than being accessible directly via GetLastError. | |
| 135 | // | |
| 136 | // Ideally copy_file should be calling the Win32 CopyFile2 function, which | |
| 137 | // works on paths, not open files -- at which point this FileDescriptor type | |
| 138 | // will no longer be needed on windows at all. | |
| 139 | fd = ::_wopen(p->c_str(), args...); | |
| 140 | #else | |
| 141 | fd = open(p->c_str(), args...); | |
| 142 | #endif | |
| 143 | ||
| 144 | if (fd == -1) { | |
| 145 | ec = capture_errno(); | |
| 146 | return FileDescriptor{p}; | |
| 147 | } | |
| 148 | return FileDescriptor(p, fd); | |
| 149 | } | |
| 150 | ||
| 151 | template <class... Args> | |
| 152 | static FileDescriptor create_with_status(const path* p, error_code& ec, | |
| 153 | Args... args) { | |
| 154 | FileDescriptor fd = create(p, ec, args...); | |
| 155 | if (!ec) | |
| 156 | fd.refresh_status(ec); | |
| 157 | ||
| 158 | return fd; | |
| 159 | } | |
| 160 | ||
| 161 | file_status get_status() const { return m_status; } | |
| 162 | StatT const& get_stat() const { return m_stat; } | |
| 163 | ||
| 164 | bool status_known() const { return _VSTD_FS::status_known(m_status); } | |
| 165 | ||
| 166 | file_status refresh_status(error_code& ec); | |
| 167 | ||
| 168 | void close() noexcept { | |
| 169 | if (fd != -1) { | |
| 170 | #ifdef _LIBCPP_WIN32API | |
| 171 | ::_close(fd); | |
| 172 | #else | |
| 173 | ::close(fd); | |
| 174 | #endif | |
| 175 | // FIXME: shouldn't this return an error_code? | |
| 176 | } | |
| 177 | fd = -1; | |
| 178 | } | |
| 179 | ||
| 180 | FileDescriptor(FileDescriptor&& other) | |
| 181 | : name(other.name), fd(other.fd), m_stat(other.m_stat), | |
| 182 | m_status(other.m_status) { | |
| 183 | other.fd = -1; | |
| 184 | other.m_status = file_status{}; | |
| 185 | } | |
| 186 | ||
| 187 | ~FileDescriptor() { close(); } | |
| 188 | ||
| 189 | FileDescriptor(FileDescriptor const&) = delete; | |
| 190 | FileDescriptor& operator=(FileDescriptor const&) = delete; | |
| 191 | ||
| 192 | private: | |
| 193 | explicit FileDescriptor(const path* p, int descriptor = -1) : name(*p), fd(descriptor) {} | |
| 194 | }; | |
| 195 | ||
| 196 | inline perms posix_get_perms(const StatT& st) noexcept { | |
| 197 | return static_cast<perms>(st.st_mode) & perms::mask; | |
| 198 | } | |
| 199 | ||
| 200 | inline file_status create_file_status(error_code& m_ec, path const& p, | |
| 201 | const StatT& path_stat, error_code* ec) { | |
| 202 | if (ec) | |
| 203 | *ec = m_ec; | |
| 204 | if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { | |
| 205 | return file_status(file_type::not_found); | |
| 206 | } else if (m_ec) { | |
| 207 | ErrorHandler<void> err("posix_stat", ec, &p); | |
| 208 | err.report(m_ec, "failed to determine attributes for the specified path"); | |
| 209 | return file_status(file_type::none); | |
| 210 | } | |
| 211 | // else | |
| 212 | ||
| 213 | file_status fs_tmp; | |
| 214 | auto const mode = path_stat.st_mode; | |
| 215 | if (S_ISLNK(mode)) | |
| 216 | fs_tmp.type(file_type::symlink); | |
| 217 | else if (S_ISREG(mode)) | |
| 218 | fs_tmp.type(file_type::regular); | |
| 219 | else if (S_ISDIR(mode)) | |
| 220 | fs_tmp.type(file_type::directory); | |
| 221 | else if (S_ISBLK(mode)) | |
| 222 | fs_tmp.type(file_type::block); | |
| 223 | else if (S_ISCHR(mode)) | |
| 224 | fs_tmp.type(file_type::character); | |
| 225 | else if (S_ISFIFO(mode)) | |
| 226 | fs_tmp.type(file_type::fifo); | |
| 227 | else if (S_ISSOCK(mode)) | |
| 228 | fs_tmp.type(file_type::socket); | |
| 229 | else | |
| 230 | fs_tmp.type(file_type::unknown); | |
| 231 | ||
| 232 | fs_tmp.permissions(detail::posix_get_perms(path_stat)); | |
| 233 | return fs_tmp; | |
| 234 | } | |
| 235 | ||
| 236 | inline file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { | |
| 237 | error_code m_ec; | |
| 238 | if (detail::stat(p.c_str(), &path_stat) == -1) | |
| 239 | m_ec = detail::capture_errno(); | |
| 240 | return create_file_status(m_ec, p, path_stat, ec); | |
| 241 | } | |
| 242 | ||
| 243 | inline file_status posix_stat(path const& p, error_code* ec) { | |
| 244 | StatT path_stat; | |
| 245 | return posix_stat(p, path_stat, ec); | |
| 246 | } | |
| 247 | ||
| 248 | inline file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { | |
| 249 | error_code m_ec; | |
| 250 | if (detail::lstat(p.c_str(), &path_stat) == -1) | |
| 251 | m_ec = detail::capture_errno(); | |
| 252 | return create_file_status(m_ec, p, path_stat, ec); | |
| 253 | } | |
| 254 | ||
| 255 | inline file_status posix_lstat(path const& p, error_code* ec) { | |
| 256 | StatT path_stat; | |
| 257 | return posix_lstat(p, path_stat, ec); | |
| 258 | } | |
| 259 | ||
| 260 | // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html | |
| 261 | inline bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { | |
| 262 | if (detail::ftruncate(fd.fd, to_size) == -1) { | |
| 263 | ec = capture_errno(); | |
| 264 | return true; | |
| 265 | } | |
| 266 | ec.clear(); | |
| 267 | return false; | |
| 268 | } | |
| 269 | ||
| 270 | inline bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { | |
| 271 | if (detail::fchmod(fd.fd, st.st_mode) == -1) { | |
| 272 | ec = capture_errno(); | |
| 273 | return true; | |
| 274 | } | |
| 275 | ec.clear(); | |
| 276 | return false; | |
| 277 | } | |
| 278 | ||
| 279 | inline bool stat_equivalent(const StatT& st1, const StatT& st2) { | |
| 280 | return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); | |
| 281 | } | |
| 282 | ||
| 283 | inline file_status FileDescriptor::refresh_status(error_code& ec) { | |
| 284 | // FD must be open and good. | |
| 285 | m_status = file_status{}; | |
| 286 | m_stat = {}; | |
| 287 | error_code m_ec; | |
| 288 | if (detail::fstat(fd, &m_stat) == -1) | |
| 289 | m_ec = capture_errno(); | |
| 290 | m_status = create_file_status(m_ec, name, m_stat, &ec); | |
| 291 | return m_status; | |
| 292 | } | |
| 293 | ||
| 294 | } // end namespace detail | |
| 295 | ||
| 296 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 297 | ||
| 298 | #endif // FILESYSTEM_FILE_DESCRIPTOR_H |
lib/libcxx/src/filesystem/filesystem_clock.cpp created+64| ... | ... | @@ -0,0 +1,64 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__config> | |
| 10 | #include <chrono> | |
| 11 | #include <filesystem> | |
| 12 | #include <time.h> | |
| 13 | ||
| 14 | #if defined(_LIBCPP_WIN32API) | |
| 15 | # include "time_utils.h" | |
| 16 | #endif | |
| 17 | ||
| 18 | #if defined(_LIBCPP_WIN32API) | |
| 19 | # define WIN32_LEAN_AND_MEAN | |
| 20 | # define NOMINMAX | |
| 21 | # include <windows.h> | |
| 22 | #endif | |
| 23 | ||
| 24 | #if __has_include(<unistd.h>) | |
| 25 | # include <unistd.h> // _POSIX_TIMERS | |
| 26 | #endif | |
| 27 | ||
| 28 | #if __has_include(<sys/time.h>) | |
| 29 | # include <sys/time.h> // for gettimeofday and timeval | |
| 30 | #endif | |
| 31 | ||
| 32 | #if defined(__APPLE__) || (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0) | |
| 33 | # define _LIBCPP_HAS_CLOCK_GETTIME | |
| 34 | #endif | |
| 35 | ||
| 36 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 37 | ||
| 38 | const bool _FilesystemClock::is_steady; | |
| 39 | ||
| 40 | _FilesystemClock::time_point _FilesystemClock::now() noexcept { | |
| 41 | typedef chrono::duration<rep> __secs; | |
| 42 | #if defined(_LIBCPP_WIN32API) | |
| 43 | typedef chrono::duration<rep, nano> __nsecs; | |
| 44 | FILETIME time; | |
| 45 | GetSystemTimeAsFileTime(&time); | |
| 46 | detail::TimeSpec tp = detail::filetime_to_timespec(time); | |
| 47 | return time_point(__secs(tp.tv_sec) + | |
| 48 | chrono::duration_cast<duration>(__nsecs(tp.tv_nsec))); | |
| 49 | #elif defined(_LIBCPP_HAS_CLOCK_GETTIME) | |
| 50 | typedef chrono::duration<rep, nano> __nsecs; | |
| 51 | struct timespec tp; | |
| 52 | if (0 != clock_gettime(CLOCK_REALTIME, &tp)) | |
| 53 | __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed"); | |
| 54 | return time_point(__secs(tp.tv_sec) + | |
| 55 | chrono::duration_cast<duration>(__nsecs(tp.tv_nsec))); | |
| 56 | #else | |
| 57 | typedef chrono::duration<rep, micro> __microsecs; | |
| 58 | timeval tv; | |
| 59 | gettimeofday(&tv, 0); | |
| 60 | return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec)); | |
| 61 | #endif | |
| 62 | } | |
| 63 | ||
| 64 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/filesystem_common.h deleted-613| ... | ... | @@ -1,613 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===//// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===//// | |
| 8 | ||
| 9 | #ifndef FILESYSTEM_COMMON_H | |
| 10 | #define FILESYSTEM_COMMON_H | |
| 11 | ||
| 12 | #include <__assert> | |
| 13 | #include <__config> | |
| 14 | #include <array> | |
| 15 | #include <chrono> | |
| 16 | #include <climits> | |
| 17 | #include <cstdarg> | |
| 18 | #include <ctime> | |
| 19 | #include <filesystem> | |
| 20 | #include <ratio> | |
| 21 | #include <system_error> | |
| 22 | #include <utility> | |
| 23 | ||
| 24 | #if defined(_LIBCPP_WIN32API) | |
| 25 | # define WIN32_LEAN_AND_MEAN | |
| 26 | # define NOMINMAX | |
| 27 | # include <windows.h> | |
| 28 | #else | |
| 29 | # include <dirent.h> // for DIR & friends | |
| 30 | # include <fcntl.h> /* values for fchmodat */ | |
| 31 | # include <sys/stat.h> | |
| 32 | # include <sys/statvfs.h> | |
| 33 | # include <sys/time.h> // for ::utimes as used in __last_write_time | |
| 34 | # include <unistd.h> | |
| 35 | #endif // defined(_LIBCPP_WIN32API) | |
| 36 | ||
| 37 | #include "../include/apple_availability.h" | |
| 38 | ||
| 39 | #if !defined(__APPLE__) | |
| 40 | // We can use the presence of UTIME_OMIT to detect platforms that provide | |
| 41 | // utimensat. | |
| 42 | #if defined(UTIME_OMIT) | |
| 43 | #define _LIBCPP_USE_UTIMENSAT | |
| 44 | #endif | |
| 45 | #endif | |
| 46 | ||
| 47 | _LIBCPP_DIAGNOSTIC_PUSH | |
| 48 | _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function") | |
| 49 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function") | |
| 50 | ||
| 51 | #if defined(_LIBCPP_WIN32API) | |
| 52 | # define PATHSTR(x) (L##x) | |
| 53 | # define PATH_CSTR_FMT "\"%ls\"" | |
| 54 | #else | |
| 55 | # define PATHSTR(x) (x) | |
| 56 | # define PATH_CSTR_FMT "\"%s\"" | |
| 57 | #endif | |
| 58 | ||
| 59 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 60 | ||
| 61 | namespace detail { | |
| 62 | ||
| 63 | #if defined(_LIBCPP_WIN32API) | |
| 64 | // Non anonymous, to allow access from two translation units. | |
| 65 | errc __win_err_to_errc(int err); | |
| 66 | #endif | |
| 67 | ||
| 68 | namespace { | |
| 69 | ||
| 70 | static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string | |
| 71 | format_string_impl(const char* msg, va_list ap) { | |
| 72 | array<char, 256> buf; | |
| 73 | ||
| 74 | va_list apcopy; | |
| 75 | va_copy(apcopy, ap); | |
| 76 | int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy); | |
| 77 | va_end(apcopy); | |
| 78 | ||
| 79 | string result; | |
| 80 | if (static_cast<size_t>(ret) < buf.size()) { | |
| 81 | result.assign(buf.data(), static_cast<size_t>(ret)); | |
| 82 | } else { | |
| 83 | // we did not provide a long enough buffer on our first attempt. The | |
| 84 | // return value is the number of bytes (excluding the null byte) that are | |
| 85 | // needed for formatting. | |
| 86 | size_t size_with_null = static_cast<size_t>(ret) + 1; | |
| 87 | result.__resize_default_init(size_with_null - 1); | |
| 88 | ret = ::vsnprintf(&result[0], size_with_null, msg, ap); | |
| 89 | _LIBCPP_ASSERT(static_cast<size_t>(ret) == (size_with_null - 1), "TODO"); | |
| 90 | } | |
| 91 | return result; | |
| 92 | } | |
| 93 | ||
| 94 | static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string | |
| 95 | format_string(const char* msg, ...) { | |
| 96 | string ret; | |
| 97 | va_list ap; | |
| 98 | va_start(ap, msg); | |
| 99 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 100 | try { | |
| 101 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 102 | ret = format_string_impl(msg, ap); | |
| 103 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 104 | } catch (...) { | |
| 105 | va_end(ap); | |
| 106 | throw; | |
| 107 | } | |
| 108 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 109 | va_end(ap); | |
| 110 | return ret; | |
| 111 | } | |
| 112 | ||
| 113 | error_code capture_errno() { | |
| 114 | _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero"); | |
| 115 | return error_code(errno, generic_category()); | |
| 116 | } | |
| 117 | ||
| 118 | #if defined(_LIBCPP_WIN32API) | |
| 119 | error_code make_windows_error(int err) { | |
| 120 | return make_error_code(__win_err_to_errc(err)); | |
| 121 | } | |
| 122 | #endif | |
| 123 | ||
| 124 | template <class T> | |
| 125 | T error_value(); | |
| 126 | template <> | |
| 127 | _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value<void>() {} | |
| 128 | template <> | |
| 129 | bool error_value<bool>() { | |
| 130 | return false; | |
| 131 | } | |
| 132 | #if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__ | |
| 133 | template <> | |
| 134 | size_t error_value<size_t>() { | |
| 135 | return size_t(-1); | |
| 136 | } | |
| 137 | #endif | |
| 138 | template <> | |
| 139 | uintmax_t error_value<uintmax_t>() { | |
| 140 | return uintmax_t(-1); | |
| 141 | } | |
| 142 | template <> | |
| 143 | _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value<file_time_type>() { | |
| 144 | return file_time_type::min(); | |
| 145 | } | |
| 146 | template <> | |
| 147 | path error_value<path>() { | |
| 148 | return {}; | |
| 149 | } | |
| 150 | ||
| 151 | template <class T> | |
| 152 | struct ErrorHandler { | |
| 153 | const char* func_name_; | |
| 154 | error_code* ec_ = nullptr; | |
| 155 | const path* p1_ = nullptr; | |
| 156 | const path* p2_ = nullptr; | |
| 157 | ||
| 158 | ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, | |
| 159 | const path* p2 = nullptr) | |
| 160 | : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) { | |
| 161 | if (ec_) | |
| 162 | ec_->clear(); | |
| 163 | } | |
| 164 | ||
| 165 | T report(const error_code& ec) const { | |
| 166 | if (ec_) { | |
| 167 | *ec_ = ec; | |
| 168 | return error_value<T>(); | |
| 169 | } | |
| 170 | string what = string("in ") + func_name_; | |
| 171 | switch (bool(p1_) + bool(p2_)) { | |
| 172 | case 0: | |
| 173 | __throw_filesystem_error(what, ec); | |
| 174 | case 1: | |
| 175 | __throw_filesystem_error(what, *p1_, ec); | |
| 176 | case 2: | |
| 177 | __throw_filesystem_error(what, *p1_, *p2_, ec); | |
| 178 | } | |
| 179 | __libcpp_unreachable(); | |
| 180 | } | |
| 181 | ||
| 182 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0) | |
| 183 | void report_impl(const error_code& ec, const char* msg, va_list ap) const { | |
| 184 | if (ec_) { | |
| 185 | *ec_ = ec; | |
| 186 | return; | |
| 187 | } | |
| 188 | string what = | |
| 189 | string("in ") + func_name_ + ": " + format_string_impl(msg, ap); | |
| 190 | switch (bool(p1_) + bool(p2_)) { | |
| 191 | case 0: | |
| 192 | __throw_filesystem_error(what, ec); | |
| 193 | case 1: | |
| 194 | __throw_filesystem_error(what, *p1_, ec); | |
| 195 | case 2: | |
| 196 | __throw_filesystem_error(what, *p1_, *p2_, ec); | |
| 197 | } | |
| 198 | __libcpp_unreachable(); | |
| 199 | } | |
| 200 | ||
| 201 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 202 | T report(const error_code& ec, const char* msg, ...) const { | |
| 203 | va_list ap; | |
| 204 | va_start(ap, msg); | |
| 205 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 206 | try { | |
| 207 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 208 | report_impl(ec, msg, ap); | |
| 209 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 210 | } catch (...) { | |
| 211 | va_end(ap); | |
| 212 | throw; | |
| 213 | } | |
| 214 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 215 | va_end(ap); | |
| 216 | return error_value<T>(); | |
| 217 | } | |
| 218 | ||
| 219 | T report(errc const& err) const { | |
| 220 | return report(make_error_code(err)); | |
| 221 | } | |
| 222 | ||
| 223 | _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) | |
| 224 | T report(errc const& err, const char* msg, ...) const { | |
| 225 | va_list ap; | |
| 226 | va_start(ap, msg); | |
| 227 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 228 | try { | |
| 229 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 230 | report_impl(make_error_code(err), msg, ap); | |
| 231 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 232 | } catch (...) { | |
| 233 | va_end(ap); | |
| 234 | throw; | |
| 235 | } | |
| 236 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 237 | va_end(ap); | |
| 238 | return error_value<T>(); | |
| 239 | } | |
| 240 | ||
| 241 | private: | |
| 242 | ErrorHandler(ErrorHandler const&) = delete; | |
| 243 | ErrorHandler& operator=(ErrorHandler const&) = delete; | |
| 244 | }; | |
| 245 | ||
| 246 | using chrono::duration; | |
| 247 | using chrono::duration_cast; | |
| 248 | ||
| 249 | #if defined(_LIBCPP_WIN32API) | |
| 250 | // Various C runtime versions (UCRT, or the legacy msvcrt.dll used by | |
| 251 | // some mingw toolchains) provide different stat function implementations, | |
| 252 | // with a number of limitations with respect to what we want from the | |
| 253 | // stat function. Instead provide our own (in the anonymous detail namespace | |
| 254 | // in posix_compat.h) which does exactly what we want, along with our own | |
| 255 | // stat structure and flag macros. | |
| 256 | ||
| 257 | struct TimeSpec { | |
| 258 | int64_t tv_sec; | |
| 259 | int64_t tv_nsec; | |
| 260 | }; | |
| 261 | struct StatT { | |
| 262 | unsigned st_mode; | |
| 263 | TimeSpec st_atim; | |
| 264 | TimeSpec st_mtim; | |
| 265 | uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber | |
| 266 | struct FileIdStruct { | |
| 267 | unsigned char id[16]; // FILE_ID_INFO::FileId | |
| 268 | bool operator==(const FileIdStruct &other) const { | |
| 269 | for (int i = 0; i < 16; i++) | |
| 270 | if (id[i] != other.id[i]) | |
| 271 | return false; | |
| 272 | return true; | |
| 273 | } | |
| 274 | } st_ino; | |
| 275 | uint32_t st_nlink; | |
| 276 | uintmax_t st_size; | |
| 277 | }; | |
| 278 | ||
| 279 | #else | |
| 280 | using TimeSpec = struct timespec; | |
| 281 | using TimeVal = struct timeval; | |
| 282 | using StatT = struct stat; | |
| 283 | #endif | |
| 284 | ||
| 285 | template <class FileTimeT, class TimeT, | |
| 286 | bool IsFloat = is_floating_point<typename FileTimeT::rep>::value> | |
| 287 | struct time_util_base { | |
| 288 | using rep = typename FileTimeT::rep; | |
| 289 | using fs_duration = typename FileTimeT::duration; | |
| 290 | using fs_seconds = duration<rep>; | |
| 291 | using fs_nanoseconds = duration<rep, nano>; | |
| 292 | using fs_microseconds = duration<rep, micro>; | |
| 293 | ||
| 294 | static constexpr rep max_seconds = | |
| 295 | duration_cast<fs_seconds>(FileTimeT::duration::max()).count(); | |
| 296 | ||
| 297 | static constexpr rep max_nsec = | |
| 298 | duration_cast<fs_nanoseconds>(FileTimeT::duration::max() - | |
| 299 | fs_seconds(max_seconds)) | |
| 300 | .count(); | |
| 301 | ||
| 302 | static constexpr rep min_seconds = | |
| 303 | duration_cast<fs_seconds>(FileTimeT::duration::min()).count(); | |
| 304 | ||
| 305 | static constexpr rep min_nsec_timespec = | |
| 306 | duration_cast<fs_nanoseconds>( | |
| 307 | (FileTimeT::duration::min() - fs_seconds(min_seconds)) + | |
| 308 | fs_seconds(1)) | |
| 309 | .count(); | |
| 310 | ||
| 311 | private: | |
| 312 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() { | |
| 313 | return duration_cast<fs_duration>( | |
| 314 | fs_nanoseconds(min_nsec_timespec) - | |
| 315 | duration_cast<fs_nanoseconds>(fs_seconds(1))); | |
| 316 | } | |
| 317 | // Static assert that these values properly round trip. | |
| 318 | static_assert(fs_seconds(min_seconds) + get_min_nsecs() == | |
| 319 | FileTimeT::duration::min(), | |
| 320 | "value doesn't roundtrip"); | |
| 321 | ||
| 322 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() { | |
| 323 | // This kinda sucks, but it's what happens when we don't have __int128_t. | |
| 324 | if (sizeof(TimeT) == sizeof(rep)) { | |
| 325 | typedef duration<long long, ratio<3600 * 24 * 365> > Years; | |
| 326 | return duration_cast<Years>(fs_seconds(max_seconds)) > Years(250) && | |
| 327 | duration_cast<Years>(fs_seconds(min_seconds)) < Years(-250); | |
| 328 | } | |
| 329 | return max_seconds >= numeric_limits<TimeT>::max() && | |
| 330 | min_seconds <= numeric_limits<TimeT>::min(); | |
| 331 | } | |
| 332 | static_assert(check_range(), "the representable range is unacceptable small"); | |
| 333 | }; | |
| 334 | ||
| 335 | template <class FileTimeT, class TimeT> | |
| 336 | struct time_util_base<FileTimeT, TimeT, true> { | |
| 337 | using rep = typename FileTimeT::rep; | |
| 338 | using fs_duration = typename FileTimeT::duration; | |
| 339 | using fs_seconds = duration<rep>; | |
| 340 | using fs_nanoseconds = duration<rep, nano>; | |
| 341 | using fs_microseconds = duration<rep, micro>; | |
| 342 | ||
| 343 | static const rep max_seconds; | |
| 344 | static const rep max_nsec; | |
| 345 | static const rep min_seconds; | |
| 346 | static const rep min_nsec_timespec; | |
| 347 | }; | |
| 348 | ||
| 349 | template <class FileTimeT, class TimeT> | |
| 350 | const typename FileTimeT::rep | |
| 351 | time_util_base<FileTimeT, TimeT, true>::max_seconds = | |
| 352 | duration_cast<fs_seconds>(FileTimeT::duration::max()).count(); | |
| 353 | ||
| 354 | template <class FileTimeT, class TimeT> | |
| 355 | const typename FileTimeT::rep time_util_base<FileTimeT, TimeT, true>::max_nsec = | |
| 356 | duration_cast<fs_nanoseconds>(FileTimeT::duration::max() - | |
| 357 | fs_seconds(max_seconds)) | |
| 358 | .count(); | |
| 359 | ||
| 360 | template <class FileTimeT, class TimeT> | |
| 361 | const typename FileTimeT::rep | |
| 362 | time_util_base<FileTimeT, TimeT, true>::min_seconds = | |
| 363 | duration_cast<fs_seconds>(FileTimeT::duration::min()).count(); | |
| 364 | ||
| 365 | template <class FileTimeT, class TimeT> | |
| 366 | const typename FileTimeT::rep | |
| 367 | time_util_base<FileTimeT, TimeT, true>::min_nsec_timespec = | |
| 368 | duration_cast<fs_nanoseconds>((FileTimeT::duration::min() - | |
| 369 | fs_seconds(min_seconds)) + | |
| 370 | fs_seconds(1)) | |
| 371 | .count(); | |
| 372 | ||
| 373 | template <class FileTimeT, class TimeT, class TimeSpecT> | |
| 374 | struct time_util : time_util_base<FileTimeT, TimeT> { | |
| 375 | using Base = time_util_base<FileTimeT, TimeT>; | |
| 376 | using Base::max_nsec; | |
| 377 | using Base::max_seconds; | |
| 378 | using Base::min_nsec_timespec; | |
| 379 | using Base::min_seconds; | |
| 380 | ||
| 381 | using typename Base::fs_duration; | |
| 382 | using typename Base::fs_microseconds; | |
| 383 | using typename Base::fs_nanoseconds; | |
| 384 | using typename Base::fs_seconds; | |
| 385 | ||
| 386 | public: | |
| 387 | template <class CType, class ChronoType> | |
| 388 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool checked_set(CType* out, | |
| 389 | ChronoType time) { | |
| 390 | using Lim = numeric_limits<CType>; | |
| 391 | if (time > Lim::max() || time < Lim::min()) | |
| 392 | return false; | |
| 393 | *out = static_cast<CType>(time); | |
| 394 | return true; | |
| 395 | } | |
| 396 | ||
| 397 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(TimeSpecT tm) { | |
| 398 | if (tm.tv_sec >= 0) { | |
| 399 | return tm.tv_sec < max_seconds || | |
| 400 | (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec); | |
| 401 | } else if (tm.tv_sec == (min_seconds - 1)) { | |
| 402 | return tm.tv_nsec >= min_nsec_timespec; | |
| 403 | } else { | |
| 404 | return tm.tv_sec >= min_seconds; | |
| 405 | } | |
| 406 | } | |
| 407 | ||
| 408 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(FileTimeT tm) { | |
| 409 | auto secs = duration_cast<fs_seconds>(tm.time_since_epoch()); | |
| 410 | auto nsecs = duration_cast<fs_nanoseconds>(tm.time_since_epoch() - secs); | |
| 411 | if (nsecs.count() < 0) { | |
| 412 | secs = secs + fs_seconds(1); | |
| 413 | nsecs = nsecs + fs_seconds(1); | |
| 414 | } | |
| 415 | using TLim = numeric_limits<TimeT>; | |
| 416 | if (secs.count() >= 0) | |
| 417 | return secs.count() <= TLim::max(); | |
| 418 | return secs.count() >= TLim::min(); | |
| 419 | } | |
| 420 | ||
| 421 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 FileTimeT | |
| 422 | convert_from_timespec(TimeSpecT tm) { | |
| 423 | if (tm.tv_sec >= 0 || tm.tv_nsec == 0) { | |
| 424 | return FileTimeT(fs_seconds(tm.tv_sec) + | |
| 425 | duration_cast<fs_duration>(fs_nanoseconds(tm.tv_nsec))); | |
| 426 | } else { // tm.tv_sec < 0 | |
| 427 | auto adj_subsec = duration_cast<fs_duration>(fs_seconds(1) - | |
| 428 | fs_nanoseconds(tm.tv_nsec)); | |
| 429 | auto Dur = fs_seconds(tm.tv_sec + 1) - adj_subsec; | |
| 430 | return FileTimeT(Dur); | |
| 431 | } | |
| 432 | } | |
| 433 | ||
| 434 | template <class SubSecT> | |
| 435 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool | |
| 436 | set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) { | |
| 437 | auto dur = tp.time_since_epoch(); | |
| 438 | auto sec_dur = duration_cast<fs_seconds>(dur); | |
| 439 | auto subsec_dur = duration_cast<fs_nanoseconds>(dur - sec_dur); | |
| 440 | // The tv_nsec and tv_usec fields must not be negative so adjust accordingly | |
| 441 | if (subsec_dur.count() < 0) { | |
| 442 | if (sec_dur.count() > min_seconds) { | |
| 443 | sec_dur = sec_dur - fs_seconds(1); | |
| 444 | subsec_dur = subsec_dur + fs_seconds(1); | |
| 445 | } else { | |
| 446 | subsec_dur = fs_nanoseconds::zero(); | |
| 447 | } | |
| 448 | } | |
| 449 | return checked_set(sec_out, sec_dur.count()) && | |
| 450 | checked_set(subsec_out, subsec_dur.count()); | |
| 451 | } | |
| 452 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool convert_to_timespec(TimeSpecT& dest, | |
| 453 | FileTimeT tp) { | |
| 454 | if (!is_representable(tp)) | |
| 455 | return false; | |
| 456 | return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp); | |
| 457 | } | |
| 458 | }; | |
| 459 | ||
| 460 | #if defined(_LIBCPP_WIN32API) | |
| 461 | using fs_time = time_util<file_time_type, int64_t, TimeSpec>; | |
| 462 | #else | |
| 463 | using fs_time = time_util<file_time_type, time_t, TimeSpec>; | |
| 464 | #endif | |
| 465 | ||
| 466 | #if defined(__APPLE__) | |
| 467 | inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } | |
| 468 | inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } | |
| 469 | #elif defined(__MVS__) | |
| 470 | inline TimeSpec extract_mtime(StatT const& st) { | |
| 471 | TimeSpec TS = {st.st_mtime, 0}; | |
| 472 | return TS; | |
| 473 | } | |
| 474 | inline TimeSpec extract_atime(StatT const& st) { | |
| 475 | TimeSpec TS = {st.st_atime, 0}; | |
| 476 | return TS; | |
| 477 | } | |
| 478 | #elif defined(_AIX) | |
| 479 | inline TimeSpec extract_mtime(StatT const& st) { | |
| 480 | TimeSpec TS = {st.st_mtime, st.st_mtime_n}; | |
| 481 | return TS; | |
| 482 | } | |
| 483 | inline TimeSpec extract_atime(StatT const& st) { | |
| 484 | TimeSpec TS = {st.st_atime, st.st_atime_n}; | |
| 485 | return TS; | |
| 486 | } | |
| 487 | #else | |
| 488 | inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } | |
| 489 | inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } | |
| 490 | #endif | |
| 491 | ||
| 492 | #if !defined(_LIBCPP_WIN32API) | |
| 493 | inline TimeVal make_timeval(TimeSpec const& ts) { | |
| 494 | using namespace chrono; | |
| 495 | auto Convert = [](long nsec) { | |
| 496 | using int_type = decltype(std::declval<TimeVal>().tv_usec); | |
| 497 | auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count(); | |
| 498 | return static_cast<int_type>(dur); | |
| 499 | }; | |
| 500 | TimeVal TV = {}; | |
| 501 | TV.tv_sec = ts.tv_sec; | |
| 502 | TV.tv_usec = Convert(ts.tv_nsec); | |
| 503 | return TV; | |
| 504 | } | |
| 505 | ||
| 506 | inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 507 | error_code& ec) { | |
| 508 | TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])}; | |
| 509 | if (::utimes(p.c_str(), ConvertedTS) == -1) { | |
| 510 | ec = capture_errno(); | |
| 511 | return true; | |
| 512 | } | |
| 513 | return false; | |
| 514 | } | |
| 515 | ||
| 516 | #if defined(_LIBCPP_USE_UTIMENSAT) | |
| 517 | bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 518 | error_code& ec) { | |
| 519 | if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) { | |
| 520 | ec = capture_errno(); | |
| 521 | return true; | |
| 522 | } | |
| 523 | return false; | |
| 524 | } | |
| 525 | #endif | |
| 526 | ||
| 527 | bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 528 | error_code& ec) { | |
| 529 | #if !defined(_LIBCPP_USE_UTIMENSAT) | |
| 530 | return posix_utimes(p, TS, ec); | |
| 531 | #else | |
| 532 | return posix_utimensat(p, TS, ec); | |
| 533 | #endif | |
| 534 | } | |
| 535 | ||
| 536 | #if defined(DT_BLK) | |
| 537 | template <class DirEntT, class = decltype(DirEntT::d_type)> | |
| 538 | static file_type get_file_type(DirEntT* ent, int) { | |
| 539 | switch (ent->d_type) { | |
| 540 | case DT_BLK: | |
| 541 | return file_type::block; | |
| 542 | case DT_CHR: | |
| 543 | return file_type::character; | |
| 544 | case DT_DIR: | |
| 545 | return file_type::directory; | |
| 546 | case DT_FIFO: | |
| 547 | return file_type::fifo; | |
| 548 | case DT_LNK: | |
| 549 | return file_type::symlink; | |
| 550 | case DT_REG: | |
| 551 | return file_type::regular; | |
| 552 | case DT_SOCK: | |
| 553 | return file_type::socket; | |
| 554 | // Unlike in lstat, hitting "unknown" here simply means that the underlying | |
| 555 | // filesystem doesn't support d_type. Report is as 'none' so we correctly | |
| 556 | // set the cache to empty. | |
| 557 | case DT_UNKNOWN: | |
| 558 | break; | |
| 559 | } | |
| 560 | return file_type::none; | |
| 561 | } | |
| 562 | #endif // defined(DT_BLK) | |
| 563 | ||
| 564 | template <class DirEntT> | |
| 565 | static file_type get_file_type(DirEntT*, long) { | |
| 566 | return file_type::none; | |
| 567 | } | |
| 568 | ||
| 569 | static pair<string_view, file_type> posix_readdir(DIR* dir_stream, | |
| 570 | error_code& ec) { | |
| 571 | struct dirent* dir_entry_ptr = nullptr; | |
| 572 | errno = 0; // zero errno in order to detect errors | |
| 573 | ec.clear(); | |
| 574 | if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { | |
| 575 | if (errno) | |
| 576 | ec = capture_errno(); | |
| 577 | return {}; | |
| 578 | } else { | |
| 579 | return {dir_entry_ptr->d_name, get_file_type(dir_entry_ptr, 0)}; | |
| 580 | } | |
| 581 | } | |
| 582 | ||
| 583 | #else // _LIBCPP_WIN32API | |
| 584 | ||
| 585 | static file_type get_file_type(const WIN32_FIND_DATAW& data) { | |
| 586 | if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && | |
| 587 | data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) | |
| 588 | return file_type::symlink; | |
| 589 | if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | |
| 590 | return file_type::directory; | |
| 591 | return file_type::regular; | |
| 592 | } | |
| 593 | static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { | |
| 594 | return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow; | |
| 595 | } | |
| 596 | static file_time_type get_write_time(const WIN32_FIND_DATAW& data) { | |
| 597 | ULARGE_INTEGER tmp; | |
| 598 | const FILETIME& time = data.ftLastWriteTime; | |
| 599 | tmp.u.LowPart = time.dwLowDateTime; | |
| 600 | tmp.u.HighPart = time.dwHighDateTime; | |
| 601 | return file_time_type(file_time_type::duration(tmp.QuadPart)); | |
| 602 | } | |
| 603 | ||
| 604 | #endif // !_LIBCPP_WIN32API | |
| 605 | ||
| 606 | } // namespace | |
| 607 | } // end namespace detail | |
| 608 | ||
| 609 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 610 | ||
| 611 | _LIBCPP_DIAGNOSTIC_POP | |
| 612 | ||
| 613 | #endif // FILESYSTEM_COMMON_H |
lib/libcxx/src/filesystem/filesystem_error.cpp created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__config> | |
| 10 | #include <__utility/unreachable.h> | |
| 11 | #include <filesystem> | |
| 12 | #include <system_error> | |
| 13 | ||
| 14 | #include "format_string.h" | |
| 15 | ||
| 16 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 17 | ||
| 18 | filesystem_error::~filesystem_error() {} | |
| 19 | ||
| 20 | void filesystem_error::__create_what(int __num_paths) { | |
| 21 | const char* derived_what = system_error::what(); | |
| 22 | __storage_->__what_ = [&]() -> string { | |
| 23 | switch (__num_paths) { | |
| 24 | case 0: | |
| 25 | return detail::format_string("filesystem error: %s", derived_what); | |
| 26 | case 1: | |
| 27 | return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]", | |
| 28 | derived_what, path1().c_str()); | |
| 29 | case 2: | |
| 30 | return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]", | |
| 31 | derived_what, path1().c_str(), path2().c_str()); | |
| 32 | } | |
| 33 | __libcpp_unreachable(); | |
| 34 | }(); | |
| 35 | } | |
| 36 | ||
| 37 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/format_string.h created+77| ... | ... | @@ -0,0 +1,77 @@ |
| 1 | //===----------------------------------------------------------------------===//// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===//// | |
| 8 | ||
| 9 | #ifndef FILESYSTEM_FORMAT_STRING_H | |
| 10 | #define FILESYSTEM_FORMAT_STRING_H | |
| 11 | ||
| 12 | #include <__assert> | |
| 13 | #include <__config> | |
| 14 | #include <array> | |
| 15 | #include <cstdarg> | |
| 16 | #include <cstddef> | |
| 17 | #include <cstdio> | |
| 18 | #include <string> | |
| 19 | ||
| 20 | #if defined(_LIBCPP_WIN32API) | |
| 21 | # define PATHSTR(x) (L##x) | |
| 22 | # define PATH_CSTR_FMT "\"%ls\"" | |
| 23 | #else | |
| 24 | # define PATHSTR(x) (x) | |
| 25 | # define PATH_CSTR_FMT "\"%s\"" | |
| 26 | #endif | |
| 27 | ||
| 28 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 29 | ||
| 30 | namespace detail { | |
| 31 | ||
| 32 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) { | |
| 33 | array<char, 256> buf; | |
| 34 | ||
| 35 | va_list apcopy; | |
| 36 | va_copy(apcopy, ap); | |
| 37 | int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy); | |
| 38 | va_end(apcopy); | |
| 39 | ||
| 40 | string result; | |
| 41 | if (static_cast<size_t>(ret) < buf.size()) { | |
| 42 | result.assign(buf.data(), static_cast<size_t>(ret)); | |
| 43 | } else { | |
| 44 | // we did not provide a long enough buffer on our first attempt. The | |
| 45 | // return value is the number of bytes (excluding the null byte) that are | |
| 46 | // needed for formatting. | |
| 47 | size_t size_with_null = static_cast<size_t>(ret) + 1; | |
| 48 | result.__resize_default_init(size_with_null - 1); | |
| 49 | ret = ::vsnprintf(&result[0], size_with_null, msg, ap); | |
| 50 | _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<size_t>(ret) == (size_with_null - 1), "TODO"); | |
| 51 | } | |
| 52 | return result; | |
| 53 | } | |
| 54 | ||
| 55 | inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) { | |
| 56 | string ret; | |
| 57 | va_list ap; | |
| 58 | va_start(ap, msg); | |
| 59 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 60 | try { | |
| 61 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 62 | ret = detail::vformat_string(msg, ap); | |
| 63 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 64 | } catch (...) { | |
| 65 | va_end(ap); | |
| 66 | throw; | |
| 67 | } | |
| 68 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 69 | va_end(ap); | |
| 70 | return ret; | |
| 71 | } | |
| 72 | ||
| 73 | } // end namespace detail | |
| 74 | ||
| 75 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 76 | ||
| 77 | #endif // FILESYSTEM_FORMAT_STRING_H |
lib/libcxx/src/filesystem/int128_builtins.cpp+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | |
| 19 | 19 | #if !defined(_LIBCPP_HAS_NO_INT128) |
| 20 | 20 | |
| 21 | extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_FUNC_VIS | |
| 21 | extern "C" __attribute__((no_sanitize("undefined"))) _LIBCPP_EXPORTED_FROM_ABI | |
| 22 | 22 | __int128_t __muloti4(__int128_t a, __int128_t b, int* overflow) { |
| 23 | 23 | const int N = (int)(sizeof(__int128_t) * CHAR_BIT); |
| 24 | 24 | const __int128_t MIN = (__int128_t)1 << (N - 1); |
lib/libcxx/src/filesystem/operations.cpp+17-1145| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | 9 | #include <__assert> |
| 10 | #include <__config> | |
| 10 | 11 | #include <__utility/unreachable.h> |
| 11 | 12 | #include <array> |
| 12 | 13 | #include <climits> |
| ... | ... | @@ -17,9 +18,11 @@ |
| 17 | 18 | #include <type_traits> |
| 18 | 19 | #include <vector> |
| 19 | 20 | |
| 20 | #include "filesystem_common.h" | |
| 21 | ||
| 21 | #include "error.h" | |
| 22 | #include "file_descriptor.h" | |
| 23 | #include "path_parser.h" | |
| 22 | 24 | #include "posix_compat.h" |
| 25 | #include "time_utils.h" | |
| 23 | 26 | |
| 24 | 27 | #if defined(_LIBCPP_WIN32API) |
| 25 | 28 | # define WIN32_LEAN_AND_MEAN |
| ... | ... | @@ -45,595 +48,12 @@ |
| 45 | 48 | # define _LIBCPP_FILESYSTEM_USE_FSTREAM |
| 46 | 49 | #endif |
| 47 | 50 | |
| 48 | #if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API) | |
| 49 | # include <sys/time.h> // for gettimeofday and timeval | |
| 50 | #endif | |
| 51 | ||
| 52 | 51 | #if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB) |
| 53 | 52 | # pragma comment(lib, "rt") |
| 54 | 53 | #endif |
| 55 | 54 | |
| 56 | 55 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 57 | 56 | |
| 58 | namespace { | |
| 59 | ||
| 60 | bool isSeparator(path::value_type C) { | |
| 61 | if (C == '/') | |
| 62 | return true; | |
| 63 | #if defined(_LIBCPP_WIN32API) | |
| 64 | if (C == '\\') | |
| 65 | return true; | |
| 66 | #endif | |
| 67 | return false; | |
| 68 | } | |
| 69 | ||
| 70 | bool isDriveLetter(path::value_type C) { | |
| 71 | return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z'); | |
| 72 | } | |
| 73 | ||
| 74 | namespace parser { | |
| 75 | ||
| 76 | using string_view_t = path::__string_view; | |
| 77 | using string_view_pair = pair<string_view_t, string_view_t>; | |
| 78 | using PosPtr = path::value_type const*; | |
| 79 | ||
| 80 | struct PathParser { | |
| 81 | enum ParserState : unsigned char { | |
| 82 | // Zero is a special sentinel value used by default constructed iterators. | |
| 83 | PS_BeforeBegin = path::iterator::_BeforeBegin, | |
| 84 | PS_InRootName = path::iterator::_InRootName, | |
| 85 | PS_InRootDir = path::iterator::_InRootDir, | |
| 86 | PS_InFilenames = path::iterator::_InFilenames, | |
| 87 | PS_InTrailingSep = path::iterator::_InTrailingSep, | |
| 88 | PS_AtEnd = path::iterator::_AtEnd | |
| 89 | }; | |
| 90 | ||
| 91 | const string_view_t Path; | |
| 92 | string_view_t RawEntry; | |
| 93 | ParserState State; | |
| 94 | ||
| 95 | private: | |
| 96 | PathParser(string_view_t P, ParserState State) noexcept : Path(P), | |
| 97 | State(State) {} | |
| 98 | ||
| 99 | public: | |
| 100 | PathParser(string_view_t P, string_view_t E, unsigned char S) | |
| 101 | : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) { | |
| 102 | // S cannot be '0' or PS_BeforeBegin. | |
| 103 | } | |
| 104 | ||
| 105 | static PathParser CreateBegin(string_view_t P) noexcept { | |
| 106 | PathParser PP(P, PS_BeforeBegin); | |
| 107 | PP.increment(); | |
| 108 | return PP; | |
| 109 | } | |
| 110 | ||
| 111 | static PathParser CreateEnd(string_view_t P) noexcept { | |
| 112 | PathParser PP(P, PS_AtEnd); | |
| 113 | return PP; | |
| 114 | } | |
| 115 | ||
| 116 | PosPtr peek() const noexcept { | |
| 117 | auto TkEnd = getNextTokenStartPos(); | |
| 118 | auto End = getAfterBack(); | |
| 119 | return TkEnd == End ? nullptr : TkEnd; | |
| 120 | } | |
| 121 | ||
| 122 | void increment() noexcept { | |
| 123 | const PosPtr End = getAfterBack(); | |
| 124 | const PosPtr Start = getNextTokenStartPos(); | |
| 125 | if (Start == End) | |
| 126 | return makeState(PS_AtEnd); | |
| 127 | ||
| 128 | switch (State) { | |
| 129 | case PS_BeforeBegin: { | |
| 130 | PosPtr TkEnd = consumeRootName(Start, End); | |
| 131 | if (TkEnd) | |
| 132 | return makeState(PS_InRootName, Start, TkEnd); | |
| 133 | } | |
| 134 | _LIBCPP_FALLTHROUGH(); | |
| 135 | case PS_InRootName: { | |
| 136 | PosPtr TkEnd = consumeAllSeparators(Start, End); | |
| 137 | if (TkEnd) | |
| 138 | return makeState(PS_InRootDir, Start, TkEnd); | |
| 139 | else | |
| 140 | return makeState(PS_InFilenames, Start, consumeName(Start, End)); | |
| 141 | } | |
| 142 | case PS_InRootDir: | |
| 143 | return makeState(PS_InFilenames, Start, consumeName(Start, End)); | |
| 144 | ||
| 145 | case PS_InFilenames: { | |
| 146 | PosPtr SepEnd = consumeAllSeparators(Start, End); | |
| 147 | if (SepEnd != End) { | |
| 148 | PosPtr TkEnd = consumeName(SepEnd, End); | |
| 149 | if (TkEnd) | |
| 150 | return makeState(PS_InFilenames, SepEnd, TkEnd); | |
| 151 | } | |
| 152 | return makeState(PS_InTrailingSep, Start, SepEnd); | |
| 153 | } | |
| 154 | ||
| 155 | case PS_InTrailingSep: | |
| 156 | return makeState(PS_AtEnd); | |
| 157 | ||
| 158 | case PS_AtEnd: | |
| 159 | __libcpp_unreachable(); | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | void decrement() noexcept { | |
| 164 | const PosPtr REnd = getBeforeFront(); | |
| 165 | const PosPtr RStart = getCurrentTokenStartPos() - 1; | |
| 166 | if (RStart == REnd) // we're decrementing the begin | |
| 167 | return makeState(PS_BeforeBegin); | |
| 168 | ||
| 169 | switch (State) { | |
| 170 | case PS_AtEnd: { | |
| 171 | // Try to consume a trailing separator or root directory first. | |
| 172 | if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) { | |
| 173 | if (SepEnd == REnd) | |
| 174 | return makeState(PS_InRootDir, Path.data(), RStart + 1); | |
| 175 | PosPtr TkStart = consumeRootName(SepEnd, REnd); | |
| 176 | if (TkStart == REnd) | |
| 177 | return makeState(PS_InRootDir, RStart, RStart + 1); | |
| 178 | return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1); | |
| 179 | } else { | |
| 180 | PosPtr TkStart = consumeRootName(RStart, REnd); | |
| 181 | if (TkStart == REnd) | |
| 182 | return makeState(PS_InRootName, TkStart + 1, RStart + 1); | |
| 183 | TkStart = consumeName(RStart, REnd); | |
| 184 | return makeState(PS_InFilenames, TkStart + 1, RStart + 1); | |
| 185 | } | |
| 186 | } | |
| 187 | case PS_InTrailingSep: | |
| 188 | return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, | |
| 189 | RStart + 1); | |
| 190 | case PS_InFilenames: { | |
| 191 | PosPtr SepEnd = consumeAllSeparators(RStart, REnd); | |
| 192 | if (SepEnd == REnd) | |
| 193 | return makeState(PS_InRootDir, Path.data(), RStart + 1); | |
| 194 | PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd); | |
| 195 | if (TkStart == REnd) { | |
| 196 | if (SepEnd) | |
| 197 | return makeState(PS_InRootDir, SepEnd + 1, RStart + 1); | |
| 198 | return makeState(PS_InRootName, TkStart + 1, RStart + 1); | |
| 199 | } | |
| 200 | TkStart = consumeName(SepEnd, REnd); | |
| 201 | return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1); | |
| 202 | } | |
| 203 | case PS_InRootDir: | |
| 204 | return makeState(PS_InRootName, Path.data(), RStart + 1); | |
| 205 | case PS_InRootName: | |
| 206 | case PS_BeforeBegin: | |
| 207 | __libcpp_unreachable(); | |
| 208 | } | |
| 209 | } | |
| 210 | ||
| 211 | /// \brief Return a view with the "preferred representation" of the current | |
| 212 | /// element. For example trailing separators are represented as a '.' | |
| 213 | string_view_t operator*() const noexcept { | |
| 214 | switch (State) { | |
| 215 | case PS_BeforeBegin: | |
| 216 | case PS_AtEnd: | |
| 217 | return PATHSTR(""); | |
| 218 | case PS_InRootDir: | |
| 219 | if (RawEntry[0] == '\\') | |
| 220 | return PATHSTR("\\"); | |
| 221 | else | |
| 222 | return PATHSTR("/"); | |
| 223 | case PS_InTrailingSep: | |
| 224 | return PATHSTR(""); | |
| 225 | case PS_InRootName: | |
| 226 | case PS_InFilenames: | |
| 227 | return RawEntry; | |
| 228 | } | |
| 229 | __libcpp_unreachable(); | |
| 230 | } | |
| 231 | ||
| 232 | explicit operator bool() const noexcept { | |
| 233 | return State != PS_BeforeBegin && State != PS_AtEnd; | |
| 234 | } | |
| 235 | ||
| 236 | PathParser& operator++() noexcept { | |
| 237 | increment(); | |
| 238 | return *this; | |
| 239 | } | |
| 240 | ||
| 241 | PathParser& operator--() noexcept { | |
| 242 | decrement(); | |
| 243 | return *this; | |
| 244 | } | |
| 245 | ||
| 246 | bool atEnd() const noexcept { | |
| 247 | return State == PS_AtEnd; | |
| 248 | } | |
| 249 | ||
| 250 | bool inRootDir() const noexcept { | |
| 251 | return State == PS_InRootDir; | |
| 252 | } | |
| 253 | ||
| 254 | bool inRootName() const noexcept { | |
| 255 | return State == PS_InRootName; | |
| 256 | } | |
| 257 | ||
| 258 | bool inRootPath() const noexcept { | |
| 259 | return inRootName() || inRootDir(); | |
| 260 | } | |
| 261 | ||
| 262 | private: | |
| 263 | void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept { | |
| 264 | State = NewState; | |
| 265 | RawEntry = string_view_t(Start, End - Start); | |
| 266 | } | |
| 267 | void makeState(ParserState NewState) noexcept { | |
| 268 | State = NewState; | |
| 269 | RawEntry = {}; | |
| 270 | } | |
| 271 | ||
| 272 | PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); } | |
| 273 | ||
| 274 | PosPtr getBeforeFront() const noexcept { return Path.data() - 1; } | |
| 275 | ||
| 276 | /// \brief Return a pointer to the first character after the currently | |
| 277 | /// lexed element. | |
| 278 | PosPtr getNextTokenStartPos() const noexcept { | |
| 279 | switch (State) { | |
| 280 | case PS_BeforeBegin: | |
| 281 | return Path.data(); | |
| 282 | case PS_InRootName: | |
| 283 | case PS_InRootDir: | |
| 284 | case PS_InFilenames: | |
| 285 | return &RawEntry.back() + 1; | |
| 286 | case PS_InTrailingSep: | |
| 287 | case PS_AtEnd: | |
| 288 | return getAfterBack(); | |
| 289 | } | |
| 290 | __libcpp_unreachable(); | |
| 291 | } | |
| 292 | ||
| 293 | /// \brief Return a pointer to the first character in the currently lexed | |
| 294 | /// element. | |
| 295 | PosPtr getCurrentTokenStartPos() const noexcept { | |
| 296 | switch (State) { | |
| 297 | case PS_BeforeBegin: | |
| 298 | case PS_InRootName: | |
| 299 | return &Path.front(); | |
| 300 | case PS_InRootDir: | |
| 301 | case PS_InFilenames: | |
| 302 | case PS_InTrailingSep: | |
| 303 | return &RawEntry.front(); | |
| 304 | case PS_AtEnd: | |
| 305 | return &Path.back() + 1; | |
| 306 | } | |
| 307 | __libcpp_unreachable(); | |
| 308 | } | |
| 309 | ||
| 310 | // Consume all consecutive separators. | |
| 311 | PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept { | |
| 312 | if (P == nullptr || P == End || !isSeparator(*P)) | |
| 313 | return nullptr; | |
| 314 | const int Inc = P < End ? 1 : -1; | |
| 315 | P += Inc; | |
| 316 | while (P != End && isSeparator(*P)) | |
| 317 | P += Inc; | |
| 318 | return P; | |
| 319 | } | |
| 320 | ||
| 321 | // Consume exactly N separators, or return nullptr. | |
| 322 | PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept { | |
| 323 | PosPtr Ret = consumeAllSeparators(P, End); | |
| 324 | if (Ret == nullptr) | |
| 325 | return nullptr; | |
| 326 | if (P < End) { | |
| 327 | if (Ret == P + N) | |
| 328 | return Ret; | |
| 329 | } else { | |
| 330 | if (Ret == P - N) | |
| 331 | return Ret; | |
| 332 | } | |
| 333 | return nullptr; | |
| 334 | } | |
| 335 | ||
| 336 | PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { | |
| 337 | PosPtr Start = P; | |
| 338 | if (P == nullptr || P == End || isSeparator(*P)) | |
| 339 | return nullptr; | |
| 340 | const int Inc = P < End ? 1 : -1; | |
| 341 | P += Inc; | |
| 342 | while (P != End && !isSeparator(*P)) | |
| 343 | P += Inc; | |
| 344 | if (P == End && Inc < 0) { | |
| 345 | // Iterating backwards and consumed all the rest of the input. | |
| 346 | // Check if the start of the string would have been considered | |
| 347 | // a root name. | |
| 348 | PosPtr RootEnd = consumeRootName(End + 1, Start); | |
| 349 | if (RootEnd) | |
| 350 | return RootEnd - 1; | |
| 351 | } | |
| 352 | return P; | |
| 353 | } | |
| 354 | ||
| 355 | PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept { | |
| 356 | if (P == End) | |
| 357 | return nullptr; | |
| 358 | if (P < End) { | |
| 359 | if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':') | |
| 360 | return nullptr; | |
| 361 | return P + 2; | |
| 362 | } else { | |
| 363 | if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':') | |
| 364 | return nullptr; | |
| 365 | return P - 2; | |
| 366 | } | |
| 367 | } | |
| 368 | ||
| 369 | PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept { | |
| 370 | if (P == End) | |
| 371 | return nullptr; | |
| 372 | if (P < End) | |
| 373 | return consumeName(consumeNSeparators(P, End, 2), End); | |
| 374 | else | |
| 375 | return consumeNSeparators(consumeName(P, End), End, 2); | |
| 376 | } | |
| 377 | ||
| 378 | PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept { | |
| 379 | #if defined(_LIBCPP_WIN32API) | |
| 380 | if (PosPtr Ret = consumeDriveLetter(P, End)) | |
| 381 | return Ret; | |
| 382 | if (PosPtr Ret = consumeNetworkRoot(P, End)) | |
| 383 | return Ret; | |
| 384 | #endif | |
| 385 | return nullptr; | |
| 386 | } | |
| 387 | }; | |
| 388 | ||
| 389 | string_view_pair separate_filename(string_view_t const& s) { | |
| 390 | if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty()) | |
| 391 | return string_view_pair{s, PATHSTR("")}; | |
| 392 | auto pos = s.find_last_of('.'); | |
| 393 | if (pos == string_view_t::npos || pos == 0) | |
| 394 | return string_view_pair{s, string_view_t{}}; | |
| 395 | return string_view_pair{s.substr(0, pos), s.substr(pos)}; | |
| 396 | } | |
| 397 | ||
| 398 | string_view_t createView(PosPtr S, PosPtr E) noexcept { | |
| 399 | return {S, static_cast<size_t>(E - S) + 1}; | |
| 400 | } | |
| 401 | ||
| 402 | } // namespace parser | |
| 403 | } // namespace | |
| 404 | ||
| 405 | // POSIX HELPERS | |
| 406 | ||
| 407 | #if defined(_LIBCPP_WIN32API) | |
| 408 | namespace detail { | |
| 409 | ||
| 410 | errc __win_err_to_errc(int err) { | |
| 411 | constexpr struct { | |
| 412 | DWORD win; | |
| 413 | errc errc; | |
| 414 | } win_error_mapping[] = { | |
| 415 | {ERROR_ACCESS_DENIED, errc::permission_denied}, | |
| 416 | {ERROR_ALREADY_EXISTS, errc::file_exists}, | |
| 417 | {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, | |
| 418 | {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory}, | |
| 419 | {ERROR_BAD_UNIT, errc::no_such_device}, | |
| 420 | {ERROR_BROKEN_PIPE, errc::broken_pipe}, | |
| 421 | {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, | |
| 422 | {ERROR_BUSY, errc::device_or_resource_busy}, | |
| 423 | {ERROR_BUSY_DRIVE, errc::device_or_resource_busy}, | |
| 424 | {ERROR_CANNOT_MAKE, errc::permission_denied}, | |
| 425 | {ERROR_CANTOPEN, errc::io_error}, | |
| 426 | {ERROR_CANTREAD, errc::io_error}, | |
| 427 | {ERROR_CANTWRITE, errc::io_error}, | |
| 428 | {ERROR_CURRENT_DIRECTORY, errc::permission_denied}, | |
| 429 | {ERROR_DEV_NOT_EXIST, errc::no_such_device}, | |
| 430 | {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy}, | |
| 431 | {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty}, | |
| 432 | {ERROR_DIRECTORY, errc::invalid_argument}, | |
| 433 | {ERROR_DISK_FULL, errc::no_space_on_device}, | |
| 434 | {ERROR_FILE_EXISTS, errc::file_exists}, | |
| 435 | {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory}, | |
| 436 | {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device}, | |
| 437 | {ERROR_INVALID_ACCESS, errc::permission_denied}, | |
| 438 | {ERROR_INVALID_DRIVE, errc::no_such_device}, | |
| 439 | {ERROR_INVALID_FUNCTION, errc::function_not_supported}, | |
| 440 | {ERROR_INVALID_HANDLE, errc::invalid_argument}, | |
| 441 | {ERROR_INVALID_NAME, errc::no_such_file_or_directory}, | |
| 442 | {ERROR_INVALID_PARAMETER, errc::invalid_argument}, | |
| 443 | {ERROR_LOCK_VIOLATION, errc::no_lock_available}, | |
| 444 | {ERROR_LOCKED, errc::no_lock_available}, | |
| 445 | {ERROR_NEGATIVE_SEEK, errc::invalid_argument}, | |
| 446 | {ERROR_NOACCESS, errc::permission_denied}, | |
| 447 | {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory}, | |
| 448 | {ERROR_NOT_READY, errc::resource_unavailable_try_again}, | |
| 449 | {ERROR_NOT_SAME_DEVICE, errc::cross_device_link}, | |
| 450 | {ERROR_NOT_SUPPORTED, errc::not_supported}, | |
| 451 | {ERROR_OPEN_FAILED, errc::io_error}, | |
| 452 | {ERROR_OPEN_FILES, errc::device_or_resource_busy}, | |
| 453 | {ERROR_OPERATION_ABORTED, errc::operation_canceled}, | |
| 454 | {ERROR_OUTOFMEMORY, errc::not_enough_memory}, | |
| 455 | {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory}, | |
| 456 | {ERROR_READ_FAULT, errc::io_error}, | |
| 457 | {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument}, | |
| 458 | {ERROR_RETRY, errc::resource_unavailable_try_again}, | |
| 459 | {ERROR_SEEK, errc::io_error}, | |
| 460 | {ERROR_SHARING_VIOLATION, errc::permission_denied}, | |
| 461 | {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open}, | |
| 462 | {ERROR_WRITE_FAULT, errc::io_error}, | |
| 463 | {ERROR_WRITE_PROTECT, errc::permission_denied}, | |
| 464 | }; | |
| 465 | ||
| 466 | for (const auto &pair : win_error_mapping) | |
| 467 | if (pair.win == static_cast<DWORD>(err)) | |
| 468 | return pair.errc; | |
| 469 | return errc::invalid_argument; | |
| 470 | } | |
| 471 | ||
| 472 | } // namespace detail | |
| 473 | #endif | |
| 474 | ||
| 475 | namespace detail { | |
| 476 | namespace { | |
| 477 | ||
| 478 | using value_type = path::value_type; | |
| 479 | using string_type = path::string_type; | |
| 480 | ||
| 481 | struct FileDescriptor { | |
| 482 | const path& name; | |
| 483 | int fd = -1; | |
| 484 | StatT m_stat; | |
| 485 | file_status m_status; | |
| 486 | ||
| 487 | template <class... Args> | |
| 488 | static FileDescriptor create(const path* p, error_code& ec, Args... args) { | |
| 489 | ec.clear(); | |
| 490 | int fd; | |
| 491 | if ((fd = detail::open(p->c_str(), args...)) == -1) { | |
| 492 | ec = capture_errno(); | |
| 493 | return FileDescriptor{p}; | |
| 494 | } | |
| 495 | return FileDescriptor(p, fd); | |
| 496 | } | |
| 497 | ||
| 498 | template <class... Args> | |
| 499 | static FileDescriptor create_with_status(const path* p, error_code& ec, | |
| 500 | Args... args) { | |
| 501 | FileDescriptor fd = create(p, ec, args...); | |
| 502 | if (!ec) | |
| 503 | fd.refresh_status(ec); | |
| 504 | ||
| 505 | return fd; | |
| 506 | } | |
| 507 | ||
| 508 | file_status get_status() const { return m_status; } | |
| 509 | StatT const& get_stat() const { return m_stat; } | |
| 510 | ||
| 511 | bool status_known() const { return _VSTD_FS::status_known(m_status); } | |
| 512 | ||
| 513 | file_status refresh_status(error_code& ec); | |
| 514 | ||
| 515 | void close() noexcept { | |
| 516 | if (fd != -1) | |
| 517 | detail::close(fd); | |
| 518 | fd = -1; | |
| 519 | } | |
| 520 | ||
| 521 | FileDescriptor(FileDescriptor&& other) | |
| 522 | : name(other.name), fd(other.fd), m_stat(other.m_stat), | |
| 523 | m_status(other.m_status) { | |
| 524 | other.fd = -1; | |
| 525 | other.m_status = file_status{}; | |
| 526 | } | |
| 527 | ||
| 528 | ~FileDescriptor() { close(); } | |
| 529 | ||
| 530 | FileDescriptor(FileDescriptor const&) = delete; | |
| 531 | FileDescriptor& operator=(FileDescriptor const&) = delete; | |
| 532 | ||
| 533 | private: | |
| 534 | explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {} | |
| 535 | }; | |
| 536 | ||
| 537 | perms posix_get_perms(const StatT& st) noexcept { | |
| 538 | return static_cast<perms>(st.st_mode) & perms::mask; | |
| 539 | } | |
| 540 | ||
| 541 | file_status create_file_status(error_code& m_ec, path const& p, | |
| 542 | const StatT& path_stat, error_code* ec) { | |
| 543 | if (ec) | |
| 544 | *ec = m_ec; | |
| 545 | if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { | |
| 546 | return file_status(file_type::not_found); | |
| 547 | } else if (m_ec) { | |
| 548 | ErrorHandler<void> err("posix_stat", ec, &p); | |
| 549 | err.report(m_ec, "failed to determine attributes for the specified path"); | |
| 550 | return file_status(file_type::none); | |
| 551 | } | |
| 552 | // else | |
| 553 | ||
| 554 | file_status fs_tmp; | |
| 555 | auto const mode = path_stat.st_mode; | |
| 556 | if (S_ISLNK(mode)) | |
| 557 | fs_tmp.type(file_type::symlink); | |
| 558 | else if (S_ISREG(mode)) | |
| 559 | fs_tmp.type(file_type::regular); | |
| 560 | else if (S_ISDIR(mode)) | |
| 561 | fs_tmp.type(file_type::directory); | |
| 562 | else if (S_ISBLK(mode)) | |
| 563 | fs_tmp.type(file_type::block); | |
| 564 | else if (S_ISCHR(mode)) | |
| 565 | fs_tmp.type(file_type::character); | |
| 566 | else if (S_ISFIFO(mode)) | |
| 567 | fs_tmp.type(file_type::fifo); | |
| 568 | else if (S_ISSOCK(mode)) | |
| 569 | fs_tmp.type(file_type::socket); | |
| 570 | else | |
| 571 | fs_tmp.type(file_type::unknown); | |
| 572 | ||
| 573 | fs_tmp.permissions(detail::posix_get_perms(path_stat)); | |
| 574 | return fs_tmp; | |
| 575 | } | |
| 576 | ||
| 577 | file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { | |
| 578 | error_code m_ec; | |
| 579 | if (detail::stat(p.c_str(), &path_stat) == -1) | |
| 580 | m_ec = detail::capture_errno(); | |
| 581 | return create_file_status(m_ec, p, path_stat, ec); | |
| 582 | } | |
| 583 | ||
| 584 | file_status posix_stat(path const& p, error_code* ec) { | |
| 585 | StatT path_stat; | |
| 586 | return posix_stat(p, path_stat, ec); | |
| 587 | } | |
| 588 | ||
| 589 | file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { | |
| 590 | error_code m_ec; | |
| 591 | if (detail::lstat(p.c_str(), &path_stat) == -1) | |
| 592 | m_ec = detail::capture_errno(); | |
| 593 | return create_file_status(m_ec, p, path_stat, ec); | |
| 594 | } | |
| 595 | ||
| 596 | file_status posix_lstat(path const& p, error_code* ec) { | |
| 597 | StatT path_stat; | |
| 598 | return posix_lstat(p, path_stat, ec); | |
| 599 | } | |
| 600 | ||
| 601 | // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html | |
| 602 | bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { | |
| 603 | if (detail::ftruncate(fd.fd, to_size) == -1) { | |
| 604 | ec = capture_errno(); | |
| 605 | return true; | |
| 606 | } | |
| 607 | ec.clear(); | |
| 608 | return false; | |
| 609 | } | |
| 610 | ||
| 611 | bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { | |
| 612 | if (detail::fchmod(fd.fd, st.st_mode) == -1) { | |
| 613 | ec = capture_errno(); | |
| 614 | return true; | |
| 615 | } | |
| 616 | ec.clear(); | |
| 617 | return false; | |
| 618 | } | |
| 619 | ||
| 620 | bool stat_equivalent(const StatT& st1, const StatT& st2) { | |
| 621 | return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); | |
| 622 | } | |
| 623 | ||
| 624 | file_status FileDescriptor::refresh_status(error_code& ec) { | |
| 625 | // FD must be open and good. | |
| 626 | m_status = file_status{}; | |
| 627 | m_stat = {}; | |
| 628 | error_code m_ec; | |
| 629 | if (detail::fstat(fd, &m_stat) == -1) | |
| 630 | m_ec = capture_errno(); | |
| 631 | m_status = create_file_status(m_ec, name, m_stat, &ec); | |
| 632 | return m_status; | |
| 633 | } | |
| 634 | } // namespace | |
| 635 | } // end namespace detail | |
| 636 | ||
| 637 | 57 | using detail::capture_errno; |
| 638 | 58 | using detail::ErrorHandler; |
| 639 | 59 | using detail::StatT; |
| ... | ... | @@ -642,51 +62,6 @@ using parser::createView; |
| 642 | 62 | using parser::PathParser; |
| 643 | 63 | using parser::string_view_t; |
| 644 | 64 | |
| 645 | const bool _FilesystemClock::is_steady; | |
| 646 | ||
| 647 | _FilesystemClock::time_point _FilesystemClock::now() noexcept { | |
| 648 | typedef chrono::duration<rep> __secs; | |
| 649 | #if defined(_LIBCPP_WIN32API) | |
| 650 | typedef chrono::duration<rep, nano> __nsecs; | |
| 651 | FILETIME time; | |
| 652 | GetSystemTimeAsFileTime(&time); | |
| 653 | TimeSpec tp = detail::filetime_to_timespec(time); | |
| 654 | return time_point(__secs(tp.tv_sec) + | |
| 655 | chrono::duration_cast<duration>(__nsecs(tp.tv_nsec))); | |
| 656 | #elif defined(CLOCK_REALTIME) | |
| 657 | typedef chrono::duration<rep, nano> __nsecs; | |
| 658 | struct timespec tp; | |
| 659 | if (0 != clock_gettime(CLOCK_REALTIME, &tp)) | |
| 660 | __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed"); | |
| 661 | return time_point(__secs(tp.tv_sec) + | |
| 662 | chrono::duration_cast<duration>(__nsecs(tp.tv_nsec))); | |
| 663 | #else | |
| 664 | typedef chrono::duration<rep, micro> __microsecs; | |
| 665 | timeval tv; | |
| 666 | gettimeofday(&tv, 0); | |
| 667 | return time_point(__secs(tv.tv_sec) + __microsecs(tv.tv_usec)); | |
| 668 | #endif // CLOCK_REALTIME | |
| 669 | } | |
| 670 | ||
| 671 | filesystem_error::~filesystem_error() {} | |
| 672 | ||
| 673 | void filesystem_error::__create_what(int __num_paths) { | |
| 674 | const char* derived_what = system_error::what(); | |
| 675 | __storage_->__what_ = [&]() -> string { | |
| 676 | switch (__num_paths) { | |
| 677 | case 0: | |
| 678 | return detail::format_string("filesystem error: %s", derived_what); | |
| 679 | case 1: | |
| 680 | return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]", | |
| 681 | derived_what, path1().c_str()); | |
| 682 | case 2: | |
| 683 | return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]", | |
| 684 | derived_what, path1().c_str(), path2().c_str()); | |
| 685 | } | |
| 686 | __libcpp_unreachable(); | |
| 687 | }(); | |
| 688 | } | |
| 689 | ||
| 690 | 65 | static path __do_absolute(const path& p, path* cwd, error_code* ec) { |
| 691 | 66 | if (ec) |
| 692 | 67 | ec->clear(); |
| ... | ... | @@ -975,7 +350,7 @@ bool __copy_file(const path& from, const path& to, copy_options options, |
| 975 | 350 | return err.report(m_ec); |
| 976 | 351 | } |
| 977 | 352 | |
| 978 | if (!copy_file_impl(from_fd, to_fd, m_ec)) { | |
| 353 | if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) { | |
| 979 | 354 | // FIXME: Remove the dest file if we failed, and it didn't exist previously. |
| 980 | 355 | return err.report(m_ec); |
| 981 | 356 | } |
| ... | ... | @@ -1104,7 +479,7 @@ path __current_path(error_code* ec) { |
| 1104 | 479 | Deleter deleter = &::free; |
| 1105 | 480 | #else |
| 1106 | 481 | auto size = ::pathconf(".", _PC_PATH_MAX); |
| 1107 | _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size"); | |
| 482 | _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size"); | |
| 1108 | 483 | |
| 1109 | 484 | auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]); |
| 1110 | 485 | path::value_type* ptr = buff.get(); |
| ... | ... | @@ -1193,18 +568,6 @@ bool __fs_is_empty(const path& p, error_code* ec) { |
| 1193 | 568 | __libcpp_unreachable(); |
| 1194 | 569 | } |
| 1195 | 570 | |
| 1196 | static file_time_type __extract_last_write_time(const path& p, const StatT& st, | |
| 1197 | error_code* ec) { | |
| 1198 | using detail::fs_time; | |
| 1199 | ErrorHandler<file_time_type> err("last_write_time", ec, &p); | |
| 1200 | ||
| 1201 | auto ts = detail::extract_mtime(st); | |
| 1202 | if (!fs_time::is_representable(ts)) | |
| 1203 | return err.report(errc::value_too_large); | |
| 1204 | ||
| 1205 | return fs_time::convert_from_timespec(ts); | |
| 1206 | } | |
| 1207 | ||
| 1208 | 571 | file_time_type __last_write_time(const path& p, error_code* ec) { |
| 1209 | 572 | using namespace chrono; |
| 1210 | 573 | ErrorHandler<file_time_type> err("last_write_time", ec, &p); |
| ... | ... | @@ -1214,7 +577,7 @@ file_time_type __last_write_time(const path& p, error_code* ec) { |
| 1214 | 577 | detail::posix_stat(p, st, &m_ec); |
| 1215 | 578 | if (m_ec) |
| 1216 | 579 | return err.report(m_ec); |
| 1217 | return __extract_last_write_time(p, st, ec); | |
| 580 | return detail::__extract_last_write_time(p, st, ec); | |
| 1218 | 581 | } |
| 1219 | 582 | |
| 1220 | 583 | void __last_write_time(const path& p, file_time_type new_time, error_code* ec) { |
| ... | ... | @@ -1264,7 +627,7 @@ void __permissions(const path& p, perms prms, perm_options opts, |
| 1264 | 627 | const bool resolve_symlinks = !has_opt(perm_options::nofollow); |
| 1265 | 628 | const bool add_perms = has_opt(perm_options::add); |
| 1266 | 629 | const bool remove_perms = has_opt(perm_options::remove); |
| 1267 | _LIBCPP_ASSERT( | |
| 630 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 1268 | 631 | (add_perms + remove_perms + has_opt(perm_options::replace)) == 1, |
| 1269 | 632 | "One and only one of the perm_options constants replace, add, or remove " |
| 1270 | 633 | "is present in opts"); |
| ... | ... | @@ -1278,7 +641,7 @@ void __permissions(const path& p, perms prms, perm_options opts, |
| 1278 | 641 | set_sym_perms = is_symlink(st); |
| 1279 | 642 | if (m_ec) |
| 1280 | 643 | return err.report(m_ec); |
| 1281 | _LIBCPP_ASSERT(st.permissions() != perms::unknown, | |
| 644 | _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown, | |
| 1282 | 645 | "Permissions unexpectedly unknown"); |
| 1283 | 646 | if (add_perms) |
| 1284 | 647 | prms |= st.permissions(); |
| ... | ... | @@ -1324,7 +687,7 @@ path __read_symlink(const path& p, error_code* ec) { |
| 1324 | 687 | detail::SSizeT ret; |
| 1325 | 688 | if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1) |
| 1326 | 689 | return err.report(capture_errno()); |
| 1327 | _LIBCPP_ASSERT(ret > 0, "TODO"); | |
| 690 | _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO"); | |
| 1328 | 691 | if (static_cast<size_t>(ret) >= size) |
| 1329 | 692 | return err.report(errc::value_too_large); |
| 1330 | 693 | buff[ret] = 0; |
| ... | ... | @@ -1550,8 +913,13 @@ path __temp_directory_path(error_code* ec) { |
| 1550 | 913 | for (auto& ep : env_paths) |
| 1551 | 914 | if ((ret = getenv(ep))) |
| 1552 | 915 | break; |
| 1553 | if (ret == nullptr) | |
| 916 | if (ret == nullptr) { | |
| 917 | #if defined(__ANDROID__) | |
| 918 | ret = "/data/local/tmp"; | |
| 919 | #else | |
| 1554 | 920 | ret = "/tmp"; |
| 921 | #endif | |
| 922 | } | |
| 1555 | 923 | |
| 1556 | 924 | path p(ret); |
| 1557 | 925 | #endif |
| ... | ... | @@ -1604,500 +972,4 @@ path __weakly_canonical(const path& p, error_code* ec) { |
| 1604 | 972 | return result.lexically_normal(); |
| 1605 | 973 | } |
| 1606 | 974 | |
| 1607 | /////////////////////////////////////////////////////////////////////////////// | |
| 1608 | // path definitions | |
| 1609 | /////////////////////////////////////////////////////////////////////////////// | |
| 1610 | ||
| 1611 | constexpr path::value_type path::preferred_separator; | |
| 1612 | ||
| 1613 | path& path::replace_extension(path const& replacement) { | |
| 1614 | path p = extension(); | |
| 1615 | if (not p.empty()) { | |
| 1616 | __pn_.erase(__pn_.size() - p.native().size()); | |
| 1617 | } | |
| 1618 | if (!replacement.empty()) { | |
| 1619 | if (replacement.native()[0] != '.') { | |
| 1620 | __pn_ += PATHSTR("."); | |
| 1621 | } | |
| 1622 | __pn_.append(replacement.__pn_); | |
| 1623 | } | |
| 1624 | return *this; | |
| 1625 | } | |
| 1626 | ||
| 1627 | /////////////////////////////////////////////////////////////////////////////// | |
| 1628 | // path.decompose | |
| 1629 | ||
| 1630 | string_view_t path::__root_name() const { | |
| 1631 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1632 | if (PP.State == PathParser::PS_InRootName) | |
| 1633 | return *PP; | |
| 1634 | return {}; | |
| 1635 | } | |
| 1636 | ||
| 1637 | string_view_t path::__root_directory() const { | |
| 1638 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1639 | if (PP.State == PathParser::PS_InRootName) | |
| 1640 | ++PP; | |
| 1641 | if (PP.State == PathParser::PS_InRootDir) | |
| 1642 | return *PP; | |
| 1643 | return {}; | |
| 1644 | } | |
| 1645 | ||
| 1646 | string_view_t path::__root_path_raw() const { | |
| 1647 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1648 | if (PP.State == PathParser::PS_InRootName) { | |
| 1649 | auto NextCh = PP.peek(); | |
| 1650 | if (NextCh && isSeparator(*NextCh)) { | |
| 1651 | ++PP; | |
| 1652 | return createView(__pn_.data(), &PP.RawEntry.back()); | |
| 1653 | } | |
| 1654 | return PP.RawEntry; | |
| 1655 | } | |
| 1656 | if (PP.State == PathParser::PS_InRootDir) | |
| 1657 | return *PP; | |
| 1658 | return {}; | |
| 1659 | } | |
| 1660 | ||
| 1661 | static bool ConsumeRootName(PathParser *PP) { | |
| 1662 | static_assert(PathParser::PS_BeforeBegin == 1 && | |
| 1663 | PathParser::PS_InRootName == 2, | |
| 1664 | "Values for enums are incorrect"); | |
| 1665 | while (PP->State <= PathParser::PS_InRootName) | |
| 1666 | ++(*PP); | |
| 1667 | return PP->State == PathParser::PS_AtEnd; | |
| 1668 | } | |
| 1669 | ||
| 1670 | static bool ConsumeRootDir(PathParser* PP) { | |
| 1671 | static_assert(PathParser::PS_BeforeBegin == 1 && | |
| 1672 | PathParser::PS_InRootName == 2 && | |
| 1673 | PathParser::PS_InRootDir == 3, "Values for enums are incorrect"); | |
| 1674 | while (PP->State <= PathParser::PS_InRootDir) | |
| 1675 | ++(*PP); | |
| 1676 | return PP->State == PathParser::PS_AtEnd; | |
| 1677 | } | |
| 1678 | ||
| 1679 | string_view_t path::__relative_path() const { | |
| 1680 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1681 | if (ConsumeRootDir(&PP)) | |
| 1682 | return {}; | |
| 1683 | return createView(PP.RawEntry.data(), &__pn_.back()); | |
| 1684 | } | |
| 1685 | ||
| 1686 | string_view_t path::__parent_path() const { | |
| 1687 | if (empty()) | |
| 1688 | return {}; | |
| 1689 | // Determine if we have a root path but not a relative path. In that case | |
| 1690 | // return *this. | |
| 1691 | { | |
| 1692 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1693 | if (ConsumeRootDir(&PP)) | |
| 1694 | return __pn_; | |
| 1695 | } | |
| 1696 | // Otherwise remove a single element from the end of the path, and return | |
| 1697 | // a string representing that path | |
| 1698 | { | |
| 1699 | auto PP = PathParser::CreateEnd(__pn_); | |
| 1700 | --PP; | |
| 1701 | if (PP.RawEntry.data() == __pn_.data()) | |
| 1702 | return {}; | |
| 1703 | --PP; | |
| 1704 | return createView(__pn_.data(), &PP.RawEntry.back()); | |
| 1705 | } | |
| 1706 | } | |
| 1707 | ||
| 1708 | string_view_t path::__filename() const { | |
| 1709 | if (empty()) | |
| 1710 | return {}; | |
| 1711 | { | |
| 1712 | PathParser PP = PathParser::CreateBegin(__pn_); | |
| 1713 | if (ConsumeRootDir(&PP)) | |
| 1714 | return {}; | |
| 1715 | } | |
| 1716 | return *(--PathParser::CreateEnd(__pn_)); | |
| 1717 | } | |
| 1718 | ||
| 1719 | string_view_t path::__stem() const { | |
| 1720 | return parser::separate_filename(__filename()).first; | |
| 1721 | } | |
| 1722 | ||
| 1723 | string_view_t path::__extension() const { | |
| 1724 | return parser::separate_filename(__filename()).second; | |
| 1725 | } | |
| 1726 | ||
| 1727 | //////////////////////////////////////////////////////////////////////////// | |
| 1728 | // path.gen | |
| 1729 | ||
| 1730 | enum PathPartKind : unsigned char { | |
| 1731 | PK_None, | |
| 1732 | PK_RootSep, | |
| 1733 | PK_Filename, | |
| 1734 | PK_Dot, | |
| 1735 | PK_DotDot, | |
| 1736 | PK_TrailingSep | |
| 1737 | }; | |
| 1738 | ||
| 1739 | static PathPartKind ClassifyPathPart(string_view_t Part) { | |
| 1740 | if (Part.empty()) | |
| 1741 | return PK_TrailingSep; | |
| 1742 | if (Part == PATHSTR(".")) | |
| 1743 | return PK_Dot; | |
| 1744 | if (Part == PATHSTR("..")) | |
| 1745 | return PK_DotDot; | |
| 1746 | if (Part == PATHSTR("/")) | |
| 1747 | return PK_RootSep; | |
| 1748 | #if defined(_LIBCPP_WIN32API) | |
| 1749 | if (Part == PATHSTR("\\")) | |
| 1750 | return PK_RootSep; | |
| 1751 | #endif | |
| 1752 | return PK_Filename; | |
| 1753 | } | |
| 1754 | ||
| 1755 | path path::lexically_normal() const { | |
| 1756 | if (__pn_.empty()) | |
| 1757 | return *this; | |
| 1758 | ||
| 1759 | using PartKindPair = pair<string_view_t, PathPartKind>; | |
| 1760 | vector<PartKindPair> Parts; | |
| 1761 | // Guess as to how many elements the path has to avoid reallocating. | |
| 1762 | Parts.reserve(32); | |
| 1763 | ||
| 1764 | // Track the total size of the parts as we collect them. This allows the | |
| 1765 | // resulting path to reserve the correct amount of memory. | |
| 1766 | size_t NewPathSize = 0; | |
| 1767 | auto AddPart = [&](PathPartKind K, string_view_t P) { | |
| 1768 | NewPathSize += P.size(); | |
| 1769 | Parts.emplace_back(P, K); | |
| 1770 | }; | |
| 1771 | auto LastPartKind = [&]() { | |
| 1772 | if (Parts.empty()) | |
| 1773 | return PK_None; | |
| 1774 | return Parts.back().second; | |
| 1775 | }; | |
| 1776 | ||
| 1777 | bool MaybeNeedTrailingSep = false; | |
| 1778 | // Build a stack containing the remaining elements of the path, popping off | |
| 1779 | // elements which occur before a '..' entry. | |
| 1780 | for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) { | |
| 1781 | auto Part = *PP; | |
| 1782 | PathPartKind Kind = ClassifyPathPart(Part); | |
| 1783 | switch (Kind) { | |
| 1784 | case PK_Filename: | |
| 1785 | case PK_RootSep: { | |
| 1786 | // Add all non-dot and non-dot-dot elements to the stack of elements. | |
| 1787 | AddPart(Kind, Part); | |
| 1788 | MaybeNeedTrailingSep = false; | |
| 1789 | break; | |
| 1790 | } | |
| 1791 | case PK_DotDot: { | |
| 1792 | // Only push a ".." element if there are no elements preceding the "..", | |
| 1793 | // or if the preceding element is itself "..". | |
| 1794 | auto LastKind = LastPartKind(); | |
| 1795 | if (LastKind == PK_Filename) { | |
| 1796 | NewPathSize -= Parts.back().first.size(); | |
| 1797 | Parts.pop_back(); | |
| 1798 | } else if (LastKind != PK_RootSep) | |
| 1799 | AddPart(PK_DotDot, PATHSTR("..")); | |
| 1800 | MaybeNeedTrailingSep = LastKind == PK_Filename; | |
| 1801 | break; | |
| 1802 | } | |
| 1803 | case PK_Dot: | |
| 1804 | case PK_TrailingSep: { | |
| 1805 | MaybeNeedTrailingSep = true; | |
| 1806 | break; | |
| 1807 | } | |
| 1808 | case PK_None: | |
| 1809 | __libcpp_unreachable(); | |
| 1810 | } | |
| 1811 | } | |
| 1812 | // [fs.path.generic]p6.8: If the path is empty, add a dot. | |
| 1813 | if (Parts.empty()) | |
| 1814 | return PATHSTR("."); | |
| 1815 | ||
| 1816 | // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any | |
| 1817 | // trailing directory-separator. | |
| 1818 | bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename; | |
| 1819 | ||
| 1820 | path Result; | |
| 1821 | Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep); | |
| 1822 | for (auto& PK : Parts) | |
| 1823 | Result /= PK.first; | |
| 1824 | ||
| 1825 | if (NeedTrailingSep) | |
| 1826 | Result /= PATHSTR(""); | |
| 1827 | ||
| 1828 | Result.make_preferred(); | |
| 1829 | return Result; | |
| 1830 | } | |
| 1831 | ||
| 1832 | static int DetermineLexicalElementCount(PathParser PP) { | |
| 1833 | int Count = 0; | |
| 1834 | for (; PP; ++PP) { | |
| 1835 | auto Elem = *PP; | |
| 1836 | if (Elem == PATHSTR("..")) | |
| 1837 | --Count; | |
| 1838 | else if (Elem != PATHSTR(".") && Elem != PATHSTR("")) | |
| 1839 | ++Count; | |
| 1840 | } | |
| 1841 | return Count; | |
| 1842 | } | |
| 1843 | ||
| 1844 | path path::lexically_relative(const path& base) const { | |
| 1845 | { // perform root-name/root-directory mismatch checks | |
| 1846 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1847 | auto PPBase = PathParser::CreateBegin(base.__pn_); | |
| 1848 | auto CheckIterMismatchAtBase = [&]() { | |
| 1849 | return PP.State != PPBase.State && | |
| 1850 | (PP.inRootPath() || PPBase.inRootPath()); | |
| 1851 | }; | |
| 1852 | if (PP.inRootName() && PPBase.inRootName()) { | |
| 1853 | if (*PP != *PPBase) | |
| 1854 | return {}; | |
| 1855 | } else if (CheckIterMismatchAtBase()) | |
| 1856 | return {}; | |
| 1857 | ||
| 1858 | if (PP.inRootPath()) | |
| 1859 | ++PP; | |
| 1860 | if (PPBase.inRootPath()) | |
| 1861 | ++PPBase; | |
| 1862 | if (CheckIterMismatchAtBase()) | |
| 1863 | return {}; | |
| 1864 | } | |
| 1865 | ||
| 1866 | // Find the first mismatching element | |
| 1867 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1868 | auto PPBase = PathParser::CreateBegin(base.__pn_); | |
| 1869 | while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) { | |
| 1870 | ++PP; | |
| 1871 | ++PPBase; | |
| 1872 | } | |
| 1873 | ||
| 1874 | // If there is no mismatch, return ".". | |
| 1875 | if (!PP && !PPBase) | |
| 1876 | return "."; | |
| 1877 | ||
| 1878 | // Otherwise, determine the number of elements, 'n', which are not dot or | |
| 1879 | // dot-dot minus the number of dot-dot elements. | |
| 1880 | int ElemCount = DetermineLexicalElementCount(PPBase); | |
| 1881 | if (ElemCount < 0) | |
| 1882 | return {}; | |
| 1883 | ||
| 1884 | // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise | |
| 1885 | if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR(""))) | |
| 1886 | return PATHSTR("."); | |
| 1887 | ||
| 1888 | // return a path constructed with 'n' dot-dot elements, followed by the | |
| 1889 | // elements of '*this' after the mismatch. | |
| 1890 | path Result; | |
| 1891 | // FIXME: Reserve enough room in Result that it won't have to re-allocate. | |
| 1892 | while (ElemCount--) | |
| 1893 | Result /= PATHSTR(".."); | |
| 1894 | for (; PP; ++PP) | |
| 1895 | Result /= *PP; | |
| 1896 | return Result; | |
| 1897 | } | |
| 1898 | ||
| 1899 | //////////////////////////////////////////////////////////////////////////// | |
| 1900 | // path.comparisons | |
| 1901 | static int CompareRootName(PathParser *LHS, PathParser *RHS) { | |
| 1902 | if (!LHS->inRootName() && !RHS->inRootName()) | |
| 1903 | return 0; | |
| 1904 | ||
| 1905 | auto GetRootName = [](PathParser *Parser) -> string_view_t { | |
| 1906 | return Parser->inRootName() ? **Parser : PATHSTR(""); | |
| 1907 | }; | |
| 1908 | int res = GetRootName(LHS).compare(GetRootName(RHS)); | |
| 1909 | ConsumeRootName(LHS); | |
| 1910 | ConsumeRootName(RHS); | |
| 1911 | return res; | |
| 1912 | } | |
| 1913 | ||
| 1914 | static int CompareRootDir(PathParser *LHS, PathParser *RHS) { | |
| 1915 | if (!LHS->inRootDir() && RHS->inRootDir()) | |
| 1916 | return -1; | |
| 1917 | else if (LHS->inRootDir() && !RHS->inRootDir()) | |
| 1918 | return 1; | |
| 1919 | else { | |
| 1920 | ConsumeRootDir(LHS); | |
| 1921 | ConsumeRootDir(RHS); | |
| 1922 | return 0; | |
| 1923 | } | |
| 1924 | } | |
| 1925 | ||
| 1926 | static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) { | |
| 1927 | auto &LHS = *LHSPtr; | |
| 1928 | auto &RHS = *RHSPtr; | |
| 1929 | ||
| 1930 | int res; | |
| 1931 | while (LHS && RHS) { | |
| 1932 | if ((res = (*LHS).compare(*RHS)) != 0) | |
| 1933 | return res; | |
| 1934 | ++LHS; | |
| 1935 | ++RHS; | |
| 1936 | } | |
| 1937 | return 0; | |
| 1938 | } | |
| 1939 | ||
| 1940 | static int CompareEndState(PathParser *LHS, PathParser *RHS) { | |
| 1941 | if (LHS->atEnd() && !RHS->atEnd()) | |
| 1942 | return -1; | |
| 1943 | else if (!LHS->atEnd() && RHS->atEnd()) | |
| 1944 | return 1; | |
| 1945 | return 0; | |
| 1946 | } | |
| 1947 | ||
| 1948 | int path::__compare(string_view_t __s) const { | |
| 1949 | auto LHS = PathParser::CreateBegin(__pn_); | |
| 1950 | auto RHS = PathParser::CreateBegin(__s); | |
| 1951 | int res; | |
| 1952 | ||
| 1953 | if ((res = CompareRootName(&LHS, &RHS)) != 0) | |
| 1954 | return res; | |
| 1955 | ||
| 1956 | if ((res = CompareRootDir(&LHS, &RHS)) != 0) | |
| 1957 | return res; | |
| 1958 | ||
| 1959 | if ((res = CompareRelative(&LHS, &RHS)) != 0) | |
| 1960 | return res; | |
| 1961 | ||
| 1962 | return CompareEndState(&LHS, &RHS); | |
| 1963 | } | |
| 1964 | ||
| 1965 | //////////////////////////////////////////////////////////////////////////// | |
| 1966 | // path.nonmembers | |
| 1967 | size_t hash_value(const path& __p) noexcept { | |
| 1968 | auto PP = PathParser::CreateBegin(__p.native()); | |
| 1969 | size_t hash_value = 0; | |
| 1970 | hash<string_view_t> hasher; | |
| 1971 | while (PP) { | |
| 1972 | hash_value = __hash_combine(hash_value, hasher(*PP)); | |
| 1973 | ++PP; | |
| 1974 | } | |
| 1975 | return hash_value; | |
| 1976 | } | |
| 1977 | ||
| 1978 | //////////////////////////////////////////////////////////////////////////// | |
| 1979 | // path.itr | |
| 1980 | path::iterator path::begin() const { | |
| 1981 | auto PP = PathParser::CreateBegin(__pn_); | |
| 1982 | iterator it; | |
| 1983 | it.__path_ptr_ = this; | |
| 1984 | it.__state_ = static_cast<path::iterator::_ParserState>(PP.State); | |
| 1985 | it.__entry_ = PP.RawEntry; | |
| 1986 | it.__stashed_elem_.__assign_view(*PP); | |
| 1987 | return it; | |
| 1988 | } | |
| 1989 | ||
| 1990 | path::iterator path::end() const { | |
| 1991 | iterator it{}; | |
| 1992 | it.__state_ = path::iterator::_AtEnd; | |
| 1993 | it.__path_ptr_ = this; | |
| 1994 | return it; | |
| 1995 | } | |
| 1996 | ||
| 1997 | path::iterator& path::iterator::__increment() { | |
| 1998 | PathParser PP(__path_ptr_->native(), __entry_, __state_); | |
| 1999 | ++PP; | |
| 2000 | __state_ = static_cast<_ParserState>(PP.State); | |
| 2001 | __entry_ = PP.RawEntry; | |
| 2002 | __stashed_elem_.__assign_view(*PP); | |
| 2003 | return *this; | |
| 2004 | } | |
| 2005 | ||
| 2006 | path::iterator& path::iterator::__decrement() { | |
| 2007 | PathParser PP(__path_ptr_->native(), __entry_, __state_); | |
| 2008 | --PP; | |
| 2009 | __state_ = static_cast<_ParserState>(PP.State); | |
| 2010 | __entry_ = PP.RawEntry; | |
| 2011 | __stashed_elem_.__assign_view(*PP); | |
| 2012 | return *this; | |
| 2013 | } | |
| 2014 | ||
| 2015 | #if defined(_LIBCPP_WIN32API) | |
| 2016 | //////////////////////////////////////////////////////////////////////////// | |
| 2017 | // Windows path conversions | |
| 2018 | size_t __wide_to_char(const wstring &str, char *out, size_t outlen) { | |
| 2019 | if (str.empty()) | |
| 2020 | return 0; | |
| 2021 | ErrorHandler<size_t> err("__wide_to_char", nullptr); | |
| 2022 | UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; | |
| 2023 | BOOL used_default = FALSE; | |
| 2024 | int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out, | |
| 2025 | outlen, nullptr, &used_default); | |
| 2026 | if (ret <= 0 || used_default) | |
| 2027 | return err.report(errc::illegal_byte_sequence); | |
| 2028 | return ret; | |
| 2029 | } | |
| 2030 | ||
| 2031 | size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) { | |
| 2032 | if (str.empty()) | |
| 2033 | return 0; | |
| 2034 | ErrorHandler<size_t> err("__char_to_wide", nullptr); | |
| 2035 | UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; | |
| 2036 | int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(), | |
| 2037 | str.size(), out, outlen); | |
| 2038 | if (ret <= 0) | |
| 2039 | return err.report(errc::illegal_byte_sequence); | |
| 2040 | return ret; | |
| 2041 | } | |
| 2042 | #endif | |
| 2043 | ||
| 2044 | ||
| 2045 | /////////////////////////////////////////////////////////////////////////////// | |
| 2046 | // directory entry definitions | |
| 2047 | /////////////////////////////////////////////////////////////////////////////// | |
| 2048 | ||
| 2049 | error_code directory_entry::__do_refresh() noexcept { | |
| 2050 | __data_.__reset(); | |
| 2051 | error_code failure_ec; | |
| 2052 | ||
| 2053 | StatT full_st; | |
| 2054 | file_status st = detail::posix_lstat(__p_, full_st, &failure_ec); | |
| 2055 | if (!status_known(st)) { | |
| 2056 | __data_.__reset(); | |
| 2057 | return failure_ec; | |
| 2058 | } | |
| 2059 | ||
| 2060 | if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) { | |
| 2061 | __data_.__cache_type_ = directory_entry::_RefreshNonSymlink; | |
| 2062 | __data_.__type_ = st.type(); | |
| 2063 | __data_.__non_sym_perms_ = st.permissions(); | |
| 2064 | } else { // we have a symlink | |
| 2065 | __data_.__sym_perms_ = st.permissions(); | |
| 2066 | // Get the information about the linked entity. | |
| 2067 | // Ignore errors from stat, since we don't want errors regarding symlink | |
| 2068 | // resolution to be reported to the user. | |
| 2069 | error_code ignored_ec; | |
| 2070 | st = detail::posix_stat(__p_, full_st, &ignored_ec); | |
| 2071 | ||
| 2072 | __data_.__type_ = st.type(); | |
| 2073 | __data_.__non_sym_perms_ = st.permissions(); | |
| 2074 | ||
| 2075 | // If we failed to resolve the link, then only partially populate the | |
| 2076 | // cache. | |
| 2077 | if (!status_known(st)) { | |
| 2078 | __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved; | |
| 2079 | return error_code{}; | |
| 2080 | } | |
| 2081 | // Otherwise, we resolved the link, potentially as not existing. | |
| 2082 | // That's OK. | |
| 2083 | __data_.__cache_type_ = directory_entry::_RefreshSymlink; | |
| 2084 | } | |
| 2085 | ||
| 2086 | if (_VSTD_FS::is_regular_file(st)) | |
| 2087 | __data_.__size_ = static_cast<uintmax_t>(full_st.st_size); | |
| 2088 | ||
| 2089 | if (_VSTD_FS::exists(st)) { | |
| 2090 | __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink); | |
| 2091 | ||
| 2092 | // Attempt to extract the mtime, and fail if it's not representable using | |
| 2093 | // file_time_type. For now we ignore the error, as we'll report it when | |
| 2094 | // the value is actually used. | |
| 2095 | error_code ignored_ec; | |
| 2096 | __data_.__write_time_ = | |
| 2097 | __extract_last_write_time(__p_, full_st, &ignored_ec); | |
| 2098 | } | |
| 2099 | ||
| 2100 | return failure_ec; | |
| 2101 | } | |
| 2102 | ||
| 2103 | 975 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/path.cpp created+460| ... | ... | @@ -0,0 +1,460 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__config> | |
| 10 | #include <filesystem> | |
| 11 | #include <vector> | |
| 12 | ||
| 13 | #include "error.h" | |
| 14 | #include "path_parser.h" | |
| 15 | ||
| 16 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 17 | ||
| 18 | using detail::ErrorHandler; | |
| 19 | using parser::createView; | |
| 20 | using parser::PathParser; | |
| 21 | using parser::string_view_t; | |
| 22 | ||
| 23 | /////////////////////////////////////////////////////////////////////////////// | |
| 24 | // path definitions | |
| 25 | /////////////////////////////////////////////////////////////////////////////// | |
| 26 | ||
| 27 | constexpr path::value_type path::preferred_separator; | |
| 28 | ||
| 29 | path& path::replace_extension(path const& replacement) { | |
| 30 | path p = extension(); | |
| 31 | if (not p.empty()) { | |
| 32 | __pn_.erase(__pn_.size() - p.native().size()); | |
| 33 | } | |
| 34 | if (!replacement.empty()) { | |
| 35 | if (replacement.native()[0] != '.') { | |
| 36 | __pn_ += PATHSTR("."); | |
| 37 | } | |
| 38 | __pn_.append(replacement.__pn_); | |
| 39 | } | |
| 40 | return *this; | |
| 41 | } | |
| 42 | ||
| 43 | /////////////////////////////////////////////////////////////////////////////// | |
| 44 | // path.decompose | |
| 45 | ||
| 46 | string_view_t path::__root_name() const { | |
| 47 | auto PP = PathParser::CreateBegin(__pn_); | |
| 48 | if (PP.State == PathParser::PS_InRootName) | |
| 49 | return *PP; | |
| 50 | return {}; | |
| 51 | } | |
| 52 | ||
| 53 | string_view_t path::__root_directory() const { | |
| 54 | auto PP = PathParser::CreateBegin(__pn_); | |
| 55 | if (PP.State == PathParser::PS_InRootName) | |
| 56 | ++PP; | |
| 57 | if (PP.State == PathParser::PS_InRootDir) | |
| 58 | return *PP; | |
| 59 | return {}; | |
| 60 | } | |
| 61 | ||
| 62 | string_view_t path::__root_path_raw() const { | |
| 63 | auto PP = PathParser::CreateBegin(__pn_); | |
| 64 | if (PP.State == PathParser::PS_InRootName) { | |
| 65 | auto NextCh = PP.peek(); | |
| 66 | if (NextCh && isSeparator(*NextCh)) { | |
| 67 | ++PP; | |
| 68 | return createView(__pn_.data(), &PP.RawEntry.back()); | |
| 69 | } | |
| 70 | return PP.RawEntry; | |
| 71 | } | |
| 72 | if (PP.State == PathParser::PS_InRootDir) | |
| 73 | return *PP; | |
| 74 | return {}; | |
| 75 | } | |
| 76 | ||
| 77 | static bool ConsumeRootName(PathParser *PP) { | |
| 78 | static_assert(PathParser::PS_BeforeBegin == 1 && | |
| 79 | PathParser::PS_InRootName == 2, | |
| 80 | "Values for enums are incorrect"); | |
| 81 | while (PP->State <= PathParser::PS_InRootName) | |
| 82 | ++(*PP); | |
| 83 | return PP->State == PathParser::PS_AtEnd; | |
| 84 | } | |
| 85 | ||
| 86 | static bool ConsumeRootDir(PathParser* PP) { | |
| 87 | static_assert(PathParser::PS_BeforeBegin == 1 && | |
| 88 | PathParser::PS_InRootName == 2 && | |
| 89 | PathParser::PS_InRootDir == 3, "Values for enums are incorrect"); | |
| 90 | while (PP->State <= PathParser::PS_InRootDir) | |
| 91 | ++(*PP); | |
| 92 | return PP->State == PathParser::PS_AtEnd; | |
| 93 | } | |
| 94 | ||
| 95 | string_view_t path::__relative_path() const { | |
| 96 | auto PP = PathParser::CreateBegin(__pn_); | |
| 97 | if (ConsumeRootDir(&PP)) | |
| 98 | return {}; | |
| 99 | return createView(PP.RawEntry.data(), &__pn_.back()); | |
| 100 | } | |
| 101 | ||
| 102 | string_view_t path::__parent_path() const { | |
| 103 | if (empty()) | |
| 104 | return {}; | |
| 105 | // Determine if we have a root path but not a relative path. In that case | |
| 106 | // return *this. | |
| 107 | { | |
| 108 | auto PP = PathParser::CreateBegin(__pn_); | |
| 109 | if (ConsumeRootDir(&PP)) | |
| 110 | return __pn_; | |
| 111 | } | |
| 112 | // Otherwise remove a single element from the end of the path, and return | |
| 113 | // a string representing that path | |
| 114 | { | |
| 115 | auto PP = PathParser::CreateEnd(__pn_); | |
| 116 | --PP; | |
| 117 | if (PP.RawEntry.data() == __pn_.data()) | |
| 118 | return {}; | |
| 119 | --PP; | |
| 120 | return createView(__pn_.data(), &PP.RawEntry.back()); | |
| 121 | } | |
| 122 | } | |
| 123 | ||
| 124 | string_view_t path::__filename() const { | |
| 125 | if (empty()) | |
| 126 | return {}; | |
| 127 | { | |
| 128 | PathParser PP = PathParser::CreateBegin(__pn_); | |
| 129 | if (ConsumeRootDir(&PP)) | |
| 130 | return {}; | |
| 131 | } | |
| 132 | return *(--PathParser::CreateEnd(__pn_)); | |
| 133 | } | |
| 134 | ||
| 135 | string_view_t path::__stem() const { | |
| 136 | return parser::separate_filename(__filename()).first; | |
| 137 | } | |
| 138 | ||
| 139 | string_view_t path::__extension() const { | |
| 140 | return parser::separate_filename(__filename()).second; | |
| 141 | } | |
| 142 | ||
| 143 | //////////////////////////////////////////////////////////////////////////// | |
| 144 | // path.gen | |
| 145 | ||
| 146 | enum PathPartKind : unsigned char { | |
| 147 | PK_None, | |
| 148 | PK_RootSep, | |
| 149 | PK_Filename, | |
| 150 | PK_Dot, | |
| 151 | PK_DotDot, | |
| 152 | PK_TrailingSep | |
| 153 | }; | |
| 154 | ||
| 155 | static PathPartKind ClassifyPathPart(string_view_t Part) { | |
| 156 | if (Part.empty()) | |
| 157 | return PK_TrailingSep; | |
| 158 | if (Part == PATHSTR(".")) | |
| 159 | return PK_Dot; | |
| 160 | if (Part == PATHSTR("..")) | |
| 161 | return PK_DotDot; | |
| 162 | if (Part == PATHSTR("/")) | |
| 163 | return PK_RootSep; | |
| 164 | #if defined(_LIBCPP_WIN32API) | |
| 165 | if (Part == PATHSTR("\\")) | |
| 166 | return PK_RootSep; | |
| 167 | #endif | |
| 168 | return PK_Filename; | |
| 169 | } | |
| 170 | ||
| 171 | path path::lexically_normal() const { | |
| 172 | if (__pn_.empty()) | |
| 173 | return *this; | |
| 174 | ||
| 175 | using PartKindPair = pair<string_view_t, PathPartKind>; | |
| 176 | vector<PartKindPair> Parts; | |
| 177 | // Guess as to how many elements the path has to avoid reallocating. | |
| 178 | Parts.reserve(32); | |
| 179 | ||
| 180 | // Track the total size of the parts as we collect them. This allows the | |
| 181 | // resulting path to reserve the correct amount of memory. | |
| 182 | size_t NewPathSize = 0; | |
| 183 | auto AddPart = [&](PathPartKind K, string_view_t P) { | |
| 184 | NewPathSize += P.size(); | |
| 185 | Parts.emplace_back(P, K); | |
| 186 | }; | |
| 187 | auto LastPartKind = [&]() { | |
| 188 | if (Parts.empty()) | |
| 189 | return PK_None; | |
| 190 | return Parts.back().second; | |
| 191 | }; | |
| 192 | ||
| 193 | bool MaybeNeedTrailingSep = false; | |
| 194 | // Build a stack containing the remaining elements of the path, popping off | |
| 195 | // elements which occur before a '..' entry. | |
| 196 | for (auto PP = PathParser::CreateBegin(__pn_); PP; ++PP) { | |
| 197 | auto Part = *PP; | |
| 198 | PathPartKind Kind = ClassifyPathPart(Part); | |
| 199 | switch (Kind) { | |
| 200 | case PK_Filename: | |
| 201 | case PK_RootSep: { | |
| 202 | // Add all non-dot and non-dot-dot elements to the stack of elements. | |
| 203 | AddPart(Kind, Part); | |
| 204 | MaybeNeedTrailingSep = false; | |
| 205 | break; | |
| 206 | } | |
| 207 | case PK_DotDot: { | |
| 208 | // Only push a ".." element if there are no elements preceding the "..", | |
| 209 | // or if the preceding element is itself "..". | |
| 210 | auto LastKind = LastPartKind(); | |
| 211 | if (LastKind == PK_Filename) { | |
| 212 | NewPathSize -= Parts.back().first.size(); | |
| 213 | Parts.pop_back(); | |
| 214 | } else if (LastKind != PK_RootSep) | |
| 215 | AddPart(PK_DotDot, PATHSTR("..")); | |
| 216 | MaybeNeedTrailingSep = LastKind == PK_Filename; | |
| 217 | break; | |
| 218 | } | |
| 219 | case PK_Dot: | |
| 220 | case PK_TrailingSep: { | |
| 221 | MaybeNeedTrailingSep = true; | |
| 222 | break; | |
| 223 | } | |
| 224 | case PK_None: | |
| 225 | __libcpp_unreachable(); | |
| 226 | } | |
| 227 | } | |
| 228 | // [fs.path.generic]p6.8: If the path is empty, add a dot. | |
| 229 | if (Parts.empty()) | |
| 230 | return PATHSTR("."); | |
| 231 | ||
| 232 | // [fs.path.generic]p6.7: If the last filename is dot-dot, remove any | |
| 233 | // trailing directory-separator. | |
| 234 | bool NeedTrailingSep = MaybeNeedTrailingSep && LastPartKind() == PK_Filename; | |
| 235 | ||
| 236 | path Result; | |
| 237 | Result.__pn_.reserve(Parts.size() + NewPathSize + NeedTrailingSep); | |
| 238 | for (auto& PK : Parts) | |
| 239 | Result /= PK.first; | |
| 240 | ||
| 241 | if (NeedTrailingSep) | |
| 242 | Result /= PATHSTR(""); | |
| 243 | ||
| 244 | Result.make_preferred(); | |
| 245 | return Result; | |
| 246 | } | |
| 247 | ||
| 248 | static int DetermineLexicalElementCount(PathParser PP) { | |
| 249 | int Count = 0; | |
| 250 | for (; PP; ++PP) { | |
| 251 | auto Elem = *PP; | |
| 252 | if (Elem == PATHSTR("..")) | |
| 253 | --Count; | |
| 254 | else if (Elem != PATHSTR(".") && Elem != PATHSTR("")) | |
| 255 | ++Count; | |
| 256 | } | |
| 257 | return Count; | |
| 258 | } | |
| 259 | ||
| 260 | path path::lexically_relative(const path& base) const { | |
| 261 | { // perform root-name/root-directory mismatch checks | |
| 262 | auto PP = PathParser::CreateBegin(__pn_); | |
| 263 | auto PPBase = PathParser::CreateBegin(base.__pn_); | |
| 264 | auto CheckIterMismatchAtBase = [&]() { | |
| 265 | return PP.State != PPBase.State && | |
| 266 | (PP.inRootPath() || PPBase.inRootPath()); | |
| 267 | }; | |
| 268 | if (PP.inRootName() && PPBase.inRootName()) { | |
| 269 | if (*PP != *PPBase) | |
| 270 | return {}; | |
| 271 | } else if (CheckIterMismatchAtBase()) | |
| 272 | return {}; | |
| 273 | ||
| 274 | if (PP.inRootPath()) | |
| 275 | ++PP; | |
| 276 | if (PPBase.inRootPath()) | |
| 277 | ++PPBase; | |
| 278 | if (CheckIterMismatchAtBase()) | |
| 279 | return {}; | |
| 280 | } | |
| 281 | ||
| 282 | // Find the first mismatching element | |
| 283 | auto PP = PathParser::CreateBegin(__pn_); | |
| 284 | auto PPBase = PathParser::CreateBegin(base.__pn_); | |
| 285 | while (PP && PPBase && PP.State == PPBase.State && *PP == *PPBase) { | |
| 286 | ++PP; | |
| 287 | ++PPBase; | |
| 288 | } | |
| 289 | ||
| 290 | // If there is no mismatch, return ".". | |
| 291 | if (!PP && !PPBase) | |
| 292 | return "."; | |
| 293 | ||
| 294 | // Otherwise, determine the number of elements, 'n', which are not dot or | |
| 295 | // dot-dot minus the number of dot-dot elements. | |
| 296 | int ElemCount = DetermineLexicalElementCount(PPBase); | |
| 297 | if (ElemCount < 0) | |
| 298 | return {}; | |
| 299 | ||
| 300 | // if n == 0 and (a == end() || a->empty()), returns path("."); otherwise | |
| 301 | if (ElemCount == 0 && (PP.atEnd() || *PP == PATHSTR(""))) | |
| 302 | return PATHSTR("."); | |
| 303 | ||
| 304 | // return a path constructed with 'n' dot-dot elements, followed by the | |
| 305 | // elements of '*this' after the mismatch. | |
| 306 | path Result; | |
| 307 | // FIXME: Reserve enough room in Result that it won't have to re-allocate. | |
| 308 | while (ElemCount--) | |
| 309 | Result /= PATHSTR(".."); | |
| 310 | for (; PP; ++PP) | |
| 311 | Result /= *PP; | |
| 312 | return Result; | |
| 313 | } | |
| 314 | ||
| 315 | //////////////////////////////////////////////////////////////////////////// | |
| 316 | // path.comparisons | |
| 317 | static int CompareRootName(PathParser *LHS, PathParser *RHS) { | |
| 318 | if (!LHS->inRootName() && !RHS->inRootName()) | |
| 319 | return 0; | |
| 320 | ||
| 321 | auto GetRootName = [](PathParser *Parser) -> string_view_t { | |
| 322 | return Parser->inRootName() ? **Parser : PATHSTR(""); | |
| 323 | }; | |
| 324 | int res = GetRootName(LHS).compare(GetRootName(RHS)); | |
| 325 | ConsumeRootName(LHS); | |
| 326 | ConsumeRootName(RHS); | |
| 327 | return res; | |
| 328 | } | |
| 329 | ||
| 330 | static int CompareRootDir(PathParser *LHS, PathParser *RHS) { | |
| 331 | if (!LHS->inRootDir() && RHS->inRootDir()) | |
| 332 | return -1; | |
| 333 | else if (LHS->inRootDir() && !RHS->inRootDir()) | |
| 334 | return 1; | |
| 335 | else { | |
| 336 | ConsumeRootDir(LHS); | |
| 337 | ConsumeRootDir(RHS); | |
| 338 | return 0; | |
| 339 | } | |
| 340 | } | |
| 341 | ||
| 342 | static int CompareRelative(PathParser *LHSPtr, PathParser *RHSPtr) { | |
| 343 | auto &LHS = *LHSPtr; | |
| 344 | auto &RHS = *RHSPtr; | |
| 345 | ||
| 346 | int res; | |
| 347 | while (LHS && RHS) { | |
| 348 | if ((res = (*LHS).compare(*RHS)) != 0) | |
| 349 | return res; | |
| 350 | ++LHS; | |
| 351 | ++RHS; | |
| 352 | } | |
| 353 | return 0; | |
| 354 | } | |
| 355 | ||
| 356 | static int CompareEndState(PathParser *LHS, PathParser *RHS) { | |
| 357 | if (LHS->atEnd() && !RHS->atEnd()) | |
| 358 | return -1; | |
| 359 | else if (!LHS->atEnd() && RHS->atEnd()) | |
| 360 | return 1; | |
| 361 | return 0; | |
| 362 | } | |
| 363 | ||
| 364 | int path::__compare(string_view_t __s) const { | |
| 365 | auto LHS = PathParser::CreateBegin(__pn_); | |
| 366 | auto RHS = PathParser::CreateBegin(__s); | |
| 367 | int res; | |
| 368 | ||
| 369 | if ((res = CompareRootName(&LHS, &RHS)) != 0) | |
| 370 | return res; | |
| 371 | ||
| 372 | if ((res = CompareRootDir(&LHS, &RHS)) != 0) | |
| 373 | return res; | |
| 374 | ||
| 375 | if ((res = CompareRelative(&LHS, &RHS)) != 0) | |
| 376 | return res; | |
| 377 | ||
| 378 | return CompareEndState(&LHS, &RHS); | |
| 379 | } | |
| 380 | ||
| 381 | //////////////////////////////////////////////////////////////////////////// | |
| 382 | // path.nonmembers | |
| 383 | size_t hash_value(const path& __p) noexcept { | |
| 384 | auto PP = PathParser::CreateBegin(__p.native()); | |
| 385 | size_t hash_value = 0; | |
| 386 | hash<string_view_t> hasher; | |
| 387 | while (PP) { | |
| 388 | hash_value = __hash_combine(hash_value, hasher(*PP)); | |
| 389 | ++PP; | |
| 390 | } | |
| 391 | return hash_value; | |
| 392 | } | |
| 393 | ||
| 394 | //////////////////////////////////////////////////////////////////////////// | |
| 395 | // path.itr | |
| 396 | path::iterator path::begin() const { | |
| 397 | auto PP = PathParser::CreateBegin(__pn_); | |
| 398 | iterator it; | |
| 399 | it.__path_ptr_ = this; | |
| 400 | it.__state_ = static_cast<path::iterator::_ParserState>(PP.State); | |
| 401 | it.__entry_ = PP.RawEntry; | |
| 402 | it.__stashed_elem_.__assign_view(*PP); | |
| 403 | return it; | |
| 404 | } | |
| 405 | ||
| 406 | path::iterator path::end() const { | |
| 407 | iterator it{}; | |
| 408 | it.__state_ = path::iterator::_AtEnd; | |
| 409 | it.__path_ptr_ = this; | |
| 410 | return it; | |
| 411 | } | |
| 412 | ||
| 413 | path::iterator& path::iterator::__increment() { | |
| 414 | PathParser PP(__path_ptr_->native(), __entry_, __state_); | |
| 415 | ++PP; | |
| 416 | __state_ = static_cast<_ParserState>(PP.State); | |
| 417 | __entry_ = PP.RawEntry; | |
| 418 | __stashed_elem_.__assign_view(*PP); | |
| 419 | return *this; | |
| 420 | } | |
| 421 | ||
| 422 | path::iterator& path::iterator::__decrement() { | |
| 423 | PathParser PP(__path_ptr_->native(), __entry_, __state_); | |
| 424 | --PP; | |
| 425 | __state_ = static_cast<_ParserState>(PP.State); | |
| 426 | __entry_ = PP.RawEntry; | |
| 427 | __stashed_elem_.__assign_view(*PP); | |
| 428 | return *this; | |
| 429 | } | |
| 430 | ||
| 431 | #if defined(_LIBCPP_WIN32API) | |
| 432 | //////////////////////////////////////////////////////////////////////////// | |
| 433 | // Windows path conversions | |
| 434 | size_t __wide_to_char(const wstring &str, char *out, size_t outlen) { | |
| 435 | if (str.empty()) | |
| 436 | return 0; | |
| 437 | ErrorHandler<size_t> err("__wide_to_char", nullptr); | |
| 438 | UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; | |
| 439 | BOOL used_default = FALSE; | |
| 440 | int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out, | |
| 441 | outlen, nullptr, &used_default); | |
| 442 | if (ret <= 0 || used_default) | |
| 443 | return err.report(errc::illegal_byte_sequence); | |
| 444 | return ret; | |
| 445 | } | |
| 446 | ||
| 447 | size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) { | |
| 448 | if (str.empty()) | |
| 449 | return 0; | |
| 450 | ErrorHandler<size_t> err("__char_to_wide", nullptr); | |
| 451 | UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; | |
| 452 | int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(), | |
| 453 | str.size(), out, outlen); | |
| 454 | if (ret <= 0) | |
| 455 | return err.report(errc::illegal_byte_sequence); | |
| 456 | return ret; | |
| 457 | } | |
| 458 | #endif | |
| 459 | ||
| 460 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/path_parser.h created+368| ... | ... | @@ -0,0 +1,368 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifndef PATH_PARSER_H | |
| 10 | #define PATH_PARSER_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <__utility/unreachable.h> | |
| 14 | #include <cstddef> | |
| 15 | #include <filesystem> | |
| 16 | #include <utility> | |
| 17 | ||
| 18 | #include "format_string.h" | |
| 19 | ||
| 20 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 21 | ||
| 22 | inline bool isSeparator(path::value_type C) { | |
| 23 | if (C == '/') | |
| 24 | return true; | |
| 25 | #if defined(_LIBCPP_WIN32API) | |
| 26 | if (C == '\\') | |
| 27 | return true; | |
| 28 | #endif | |
| 29 | return false; | |
| 30 | } | |
| 31 | ||
| 32 | inline bool isDriveLetter(path::value_type C) { | |
| 33 | return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z'); | |
| 34 | } | |
| 35 | ||
| 36 | namespace parser { | |
| 37 | ||
| 38 | using string_view_t = path::__string_view; | |
| 39 | using string_view_pair = pair<string_view_t, string_view_t>; | |
| 40 | using PosPtr = path::value_type const*; | |
| 41 | ||
| 42 | struct PathParser { | |
| 43 | enum ParserState : unsigned char { | |
| 44 | // Zero is a special sentinel value used by default constructed iterators. | |
| 45 | PS_BeforeBegin = path::iterator::_BeforeBegin, | |
| 46 | PS_InRootName = path::iterator::_InRootName, | |
| 47 | PS_InRootDir = path::iterator::_InRootDir, | |
| 48 | PS_InFilenames = path::iterator::_InFilenames, | |
| 49 | PS_InTrailingSep = path::iterator::_InTrailingSep, | |
| 50 | PS_AtEnd = path::iterator::_AtEnd | |
| 51 | }; | |
| 52 | ||
| 53 | const string_view_t Path; | |
| 54 | string_view_t RawEntry; | |
| 55 | ParserState State; | |
| 56 | ||
| 57 | private: | |
| 58 | PathParser(string_view_t P, ParserState State) noexcept : Path(P), | |
| 59 | State(State) {} | |
| 60 | ||
| 61 | public: | |
| 62 | PathParser(string_view_t P, string_view_t E, unsigned char S) | |
| 63 | : Path(P), RawEntry(E), State(static_cast<ParserState>(S)) { | |
| 64 | // S cannot be '0' or PS_BeforeBegin. | |
| 65 | } | |
| 66 | ||
| 67 | static PathParser CreateBegin(string_view_t P) noexcept { | |
| 68 | PathParser PP(P, PS_BeforeBegin); | |
| 69 | PP.increment(); | |
| 70 | return PP; | |
| 71 | } | |
| 72 | ||
| 73 | static PathParser CreateEnd(string_view_t P) noexcept { | |
| 74 | PathParser PP(P, PS_AtEnd); | |
| 75 | return PP; | |
| 76 | } | |
| 77 | ||
| 78 | PosPtr peek() const noexcept { | |
| 79 | auto TkEnd = getNextTokenStartPos(); | |
| 80 | auto End = getAfterBack(); | |
| 81 | return TkEnd == End ? nullptr : TkEnd; | |
| 82 | } | |
| 83 | ||
| 84 | void increment() noexcept { | |
| 85 | const PosPtr End = getAfterBack(); | |
| 86 | const PosPtr Start = getNextTokenStartPos(); | |
| 87 | if (Start == End) | |
| 88 | return makeState(PS_AtEnd); | |
| 89 | ||
| 90 | switch (State) { | |
| 91 | case PS_BeforeBegin: { | |
| 92 | PosPtr TkEnd = consumeRootName(Start, End); | |
| 93 | if (TkEnd) | |
| 94 | return makeState(PS_InRootName, Start, TkEnd); | |
| 95 | } | |
| 96 | _LIBCPP_FALLTHROUGH(); | |
| 97 | case PS_InRootName: { | |
| 98 | PosPtr TkEnd = consumeAllSeparators(Start, End); | |
| 99 | if (TkEnd) | |
| 100 | return makeState(PS_InRootDir, Start, TkEnd); | |
| 101 | else | |
| 102 | return makeState(PS_InFilenames, Start, consumeName(Start, End)); | |
| 103 | } | |
| 104 | case PS_InRootDir: | |
| 105 | return makeState(PS_InFilenames, Start, consumeName(Start, End)); | |
| 106 | ||
| 107 | case PS_InFilenames: { | |
| 108 | PosPtr SepEnd = consumeAllSeparators(Start, End); | |
| 109 | if (SepEnd != End) { | |
| 110 | PosPtr TkEnd = consumeName(SepEnd, End); | |
| 111 | if (TkEnd) | |
| 112 | return makeState(PS_InFilenames, SepEnd, TkEnd); | |
| 113 | } | |
| 114 | return makeState(PS_InTrailingSep, Start, SepEnd); | |
| 115 | } | |
| 116 | ||
| 117 | case PS_InTrailingSep: | |
| 118 | return makeState(PS_AtEnd); | |
| 119 | ||
| 120 | case PS_AtEnd: | |
| 121 | __libcpp_unreachable(); | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 125 | void decrement() noexcept { | |
| 126 | const PosPtr REnd = getBeforeFront(); | |
| 127 | const PosPtr RStart = getCurrentTokenStartPos() - 1; | |
| 128 | if (RStart == REnd) // we're decrementing the begin | |
| 129 | return makeState(PS_BeforeBegin); | |
| 130 | ||
| 131 | switch (State) { | |
| 132 | case PS_AtEnd: { | |
| 133 | // Try to consume a trailing separator or root directory first. | |
| 134 | if (PosPtr SepEnd = consumeAllSeparators(RStart, REnd)) { | |
| 135 | if (SepEnd == REnd) | |
| 136 | return makeState(PS_InRootDir, Path.data(), RStart + 1); | |
| 137 | PosPtr TkStart = consumeRootName(SepEnd, REnd); | |
| 138 | if (TkStart == REnd) | |
| 139 | return makeState(PS_InRootDir, RStart, RStart + 1); | |
| 140 | return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1); | |
| 141 | } else { | |
| 142 | PosPtr TkStart = consumeRootName(RStart, REnd); | |
| 143 | if (TkStart == REnd) | |
| 144 | return makeState(PS_InRootName, TkStart + 1, RStart + 1); | |
| 145 | TkStart = consumeName(RStart, REnd); | |
| 146 | return makeState(PS_InFilenames, TkStart + 1, RStart + 1); | |
| 147 | } | |
| 148 | } | |
| 149 | case PS_InTrailingSep: | |
| 150 | return makeState(PS_InFilenames, consumeName(RStart, REnd) + 1, | |
| 151 | RStart + 1); | |
| 152 | case PS_InFilenames: { | |
| 153 | PosPtr SepEnd = consumeAllSeparators(RStart, REnd); | |
| 154 | if (SepEnd == REnd) | |
| 155 | return makeState(PS_InRootDir, Path.data(), RStart + 1); | |
| 156 | PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd); | |
| 157 | if (TkStart == REnd) { | |
| 158 | if (SepEnd) | |
| 159 | return makeState(PS_InRootDir, SepEnd + 1, RStart + 1); | |
| 160 | return makeState(PS_InRootName, TkStart + 1, RStart + 1); | |
| 161 | } | |
| 162 | TkStart = consumeName(SepEnd, REnd); | |
| 163 | return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1); | |
| 164 | } | |
| 165 | case PS_InRootDir: | |
| 166 | return makeState(PS_InRootName, Path.data(), RStart + 1); | |
| 167 | case PS_InRootName: | |
| 168 | case PS_BeforeBegin: | |
| 169 | __libcpp_unreachable(); | |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 173 | /// \brief Return a view with the "preferred representation" of the current | |
| 174 | /// element. For example trailing separators are represented as a '.' | |
| 175 | string_view_t operator*() const noexcept { | |
| 176 | switch (State) { | |
| 177 | case PS_BeforeBegin: | |
| 178 | case PS_AtEnd: | |
| 179 | return PATHSTR(""); | |
| 180 | case PS_InRootDir: | |
| 181 | if (RawEntry[0] == '\\') | |
| 182 | return PATHSTR("\\"); | |
| 183 | else | |
| 184 | return PATHSTR("/"); | |
| 185 | case PS_InTrailingSep: | |
| 186 | return PATHSTR(""); | |
| 187 | case PS_InRootName: | |
| 188 | case PS_InFilenames: | |
| 189 | return RawEntry; | |
| 190 | } | |
| 191 | __libcpp_unreachable(); | |
| 192 | } | |
| 193 | ||
| 194 | explicit operator bool() const noexcept { | |
| 195 | return State != PS_BeforeBegin && State != PS_AtEnd; | |
| 196 | } | |
| 197 | ||
| 198 | PathParser& operator++() noexcept { | |
| 199 | increment(); | |
| 200 | return *this; | |
| 201 | } | |
| 202 | ||
| 203 | PathParser& operator--() noexcept { | |
| 204 | decrement(); | |
| 205 | return *this; | |
| 206 | } | |
| 207 | ||
| 208 | bool atEnd() const noexcept { | |
| 209 | return State == PS_AtEnd; | |
| 210 | } | |
| 211 | ||
| 212 | bool inRootDir() const noexcept { | |
| 213 | return State == PS_InRootDir; | |
| 214 | } | |
| 215 | ||
| 216 | bool inRootName() const noexcept { | |
| 217 | return State == PS_InRootName; | |
| 218 | } | |
| 219 | ||
| 220 | bool inRootPath() const noexcept { | |
| 221 | return inRootName() || inRootDir(); | |
| 222 | } | |
| 223 | ||
| 224 | private: | |
| 225 | void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept { | |
| 226 | State = NewState; | |
| 227 | RawEntry = string_view_t(Start, End - Start); | |
| 228 | } | |
| 229 | void makeState(ParserState NewState) noexcept { | |
| 230 | State = NewState; | |
| 231 | RawEntry = {}; | |
| 232 | } | |
| 233 | ||
| 234 | PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); } | |
| 235 | ||
| 236 | PosPtr getBeforeFront() const noexcept { return Path.data() - 1; } | |
| 237 | ||
| 238 | /// \brief Return a pointer to the first character after the currently | |
| 239 | /// lexed element. | |
| 240 | PosPtr getNextTokenStartPos() const noexcept { | |
| 241 | switch (State) { | |
| 242 | case PS_BeforeBegin: | |
| 243 | return Path.data(); | |
| 244 | case PS_InRootName: | |
| 245 | case PS_InRootDir: | |
| 246 | case PS_InFilenames: | |
| 247 | return &RawEntry.back() + 1; | |
| 248 | case PS_InTrailingSep: | |
| 249 | case PS_AtEnd: | |
| 250 | return getAfterBack(); | |
| 251 | } | |
| 252 | __libcpp_unreachable(); | |
| 253 | } | |
| 254 | ||
| 255 | /// \brief Return a pointer to the first character in the currently lexed | |
| 256 | /// element. | |
| 257 | PosPtr getCurrentTokenStartPos() const noexcept { | |
| 258 | switch (State) { | |
| 259 | case PS_BeforeBegin: | |
| 260 | case PS_InRootName: | |
| 261 | return &Path.front(); | |
| 262 | case PS_InRootDir: | |
| 263 | case PS_InFilenames: | |
| 264 | case PS_InTrailingSep: | |
| 265 | return &RawEntry.front(); | |
| 266 | case PS_AtEnd: | |
| 267 | return &Path.back() + 1; | |
| 268 | } | |
| 269 | __libcpp_unreachable(); | |
| 270 | } | |
| 271 | ||
| 272 | // Consume all consecutive separators. | |
| 273 | PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept { | |
| 274 | if (P == nullptr || P == End || !isSeparator(*P)) | |
| 275 | return nullptr; | |
| 276 | const int Inc = P < End ? 1 : -1; | |
| 277 | P += Inc; | |
| 278 | while (P != End && isSeparator(*P)) | |
| 279 | P += Inc; | |
| 280 | return P; | |
| 281 | } | |
| 282 | ||
| 283 | // Consume exactly N separators, or return nullptr. | |
| 284 | PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept { | |
| 285 | PosPtr Ret = consumeAllSeparators(P, End); | |
| 286 | if (Ret == nullptr) | |
| 287 | return nullptr; | |
| 288 | if (P < End) { | |
| 289 | if (Ret == P + N) | |
| 290 | return Ret; | |
| 291 | } else { | |
| 292 | if (Ret == P - N) | |
| 293 | return Ret; | |
| 294 | } | |
| 295 | return nullptr; | |
| 296 | } | |
| 297 | ||
| 298 | PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { | |
| 299 | PosPtr Start = P; | |
| 300 | if (P == nullptr || P == End || isSeparator(*P)) | |
| 301 | return nullptr; | |
| 302 | const int Inc = P < End ? 1 : -1; | |
| 303 | P += Inc; | |
| 304 | while (P != End && !isSeparator(*P)) | |
| 305 | P += Inc; | |
| 306 | if (P == End && Inc < 0) { | |
| 307 | // Iterating backwards and consumed all the rest of the input. | |
| 308 | // Check if the start of the string would have been considered | |
| 309 | // a root name. | |
| 310 | PosPtr RootEnd = consumeRootName(End + 1, Start); | |
| 311 | if (RootEnd) | |
| 312 | return RootEnd - 1; | |
| 313 | } | |
| 314 | return P; | |
| 315 | } | |
| 316 | ||
| 317 | PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept { | |
| 318 | if (P == End) | |
| 319 | return nullptr; | |
| 320 | if (P < End) { | |
| 321 | if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':') | |
| 322 | return nullptr; | |
| 323 | return P + 2; | |
| 324 | } else { | |
| 325 | if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':') | |
| 326 | return nullptr; | |
| 327 | return P - 2; | |
| 328 | } | |
| 329 | } | |
| 330 | ||
| 331 | PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept { | |
| 332 | if (P == End) | |
| 333 | return nullptr; | |
| 334 | if (P < End) | |
| 335 | return consumeName(consumeNSeparators(P, End, 2), End); | |
| 336 | else | |
| 337 | return consumeNSeparators(consumeName(P, End), End, 2); | |
| 338 | } | |
| 339 | ||
| 340 | PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept { | |
| 341 | #if defined(_LIBCPP_WIN32API) | |
| 342 | if (PosPtr Ret = consumeDriveLetter(P, End)) | |
| 343 | return Ret; | |
| 344 | if (PosPtr Ret = consumeNetworkRoot(P, End)) | |
| 345 | return Ret; | |
| 346 | #endif | |
| 347 | return nullptr; | |
| 348 | } | |
| 349 | }; | |
| 350 | ||
| 351 | inline string_view_pair separate_filename(string_view_t const& s) { | |
| 352 | if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty()) | |
| 353 | return string_view_pair{s, PATHSTR("")}; | |
| 354 | auto pos = s.find_last_of('.'); | |
| 355 | if (pos == string_view_t::npos || pos == 0) | |
| 356 | return string_view_pair{s, string_view_t{}}; | |
| 357 | return string_view_pair{s.substr(0, pos), s.substr(pos)}; | |
| 358 | } | |
| 359 | ||
| 360 | inline string_view_t createView(PosPtr S, PosPtr E) noexcept { | |
| 361 | return {S, static_cast<size_t>(E - S) + 1}; | |
| 362 | } | |
| 363 | ||
| 364 | } // namespace parser | |
| 365 | ||
| 366 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 367 | ||
| 368 | #endif // PATH_PARSER_H |
lib/libcxx/src/filesystem/posix_compat.h+58-66| ... | ... | @@ -24,9 +24,11 @@ |
| 24 | 24 | #define POSIX_COMPAT_H |
| 25 | 25 | |
| 26 | 26 | #include <__assert> |
| 27 | #include <__config> | |
| 27 | 28 | #include <filesystem> |
| 28 | 29 | |
| 29 | #include "filesystem_common.h" | |
| 30 | #include "error.h" | |
| 31 | #include "time_utils.h" | |
| 30 | 32 | |
| 31 | 33 | #if defined(_LIBCPP_WIN32API) |
| 32 | 34 | # define WIN32_LEAN_AND_MEAN |
| ... | ... | @@ -35,10 +37,13 @@ |
| 35 | 37 | # include <io.h> |
| 36 | 38 | # include <winioctl.h> |
| 37 | 39 | #else |
| 40 | # include <fcntl.h> | |
| 38 | 41 | # include <unistd.h> |
| 39 | 42 | # include <sys/stat.h> |
| 40 | 43 | # include <sys/statvfs.h> |
| 44 | # include <sys/time.h> | |
| 41 | 45 | #endif |
| 46 | #include <stdlib.h> | |
| 42 | 47 | #include <time.h> |
| 43 | 48 | |
| 44 | 49 | #if defined(_LIBCPP_WIN32API) |
| ... | ... | @@ -74,7 +79,6 @@ struct LIBCPP_REPARSE_DATA_BUFFER { |
| 74 | 79 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM |
| 75 | 80 | |
| 76 | 81 | namespace detail { |
| 77 | namespace { | |
| 78 | 82 | |
| 79 | 83 | #if defined(_LIBCPP_WIN32API) |
| 80 | 84 | |
| ... | ... | @@ -118,36 +122,7 @@ namespace { |
| 118 | 122 | |
| 119 | 123 | #define O_NONBLOCK 0 |
| 120 | 124 | |
| 121 | ||
| 122 | // There were 369 years and 89 leap days from the Windows epoch | |
| 123 | // (1601) to the Unix epoch (1970). | |
| 124 | #define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60)) | |
| 125 | ||
| 126 | TimeSpec filetime_to_timespec(LARGE_INTEGER li) { | |
| 127 | TimeSpec ret; | |
| 128 | ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS; | |
| 129 | ret.tv_nsec = (li.QuadPart % 10000000) * 100; | |
| 130 | return ret; | |
| 131 | } | |
| 132 | ||
| 133 | TimeSpec filetime_to_timespec(FILETIME ft) { | |
| 134 | LARGE_INTEGER li; | |
| 135 | li.LowPart = ft.dwLowDateTime; | |
| 136 | li.HighPart = ft.dwHighDateTime; | |
| 137 | return filetime_to_timespec(li); | |
| 138 | } | |
| 139 | ||
| 140 | FILETIME timespec_to_filetime(TimeSpec ts) { | |
| 141 | LARGE_INTEGER li; | |
| 142 | li.QuadPart = | |
| 143 | ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000; | |
| 144 | FILETIME ft; | |
| 145 | ft.dwLowDateTime = li.LowPart; | |
| 146 | ft.dwHighDateTime = li.HighPart; | |
| 147 | return ft; | |
| 148 | } | |
| 149 | ||
| 150 | int set_errno(int e = GetLastError()) { | |
| 125 | inline int set_errno(int e = GetLastError()) { | |
| 151 | 126 | errno = static_cast<int>(__win_err_to_errc(e)); |
| 152 | 127 | return -1; |
| 153 | 128 | } |
| ... | ... | @@ -170,7 +145,7 @@ private: |
| 170 | 145 | HANDLE h; |
| 171 | 146 | }; |
| 172 | 147 | |
| 173 | int stat_handle(HANDLE h, StatT *buf) { | |
| 148 | inline int stat_handle(HANDLE h, StatT *buf) { | |
| 174 | 149 | FILE_BASIC_INFO basic; |
| 175 | 150 | if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) |
| 176 | 151 | return set_errno(); |
| ... | ... | @@ -208,7 +183,7 @@ int stat_handle(HANDLE h, StatT *buf) { |
| 208 | 183 | return 0; |
| 209 | 184 | } |
| 210 | 185 | |
| 211 | int stat_file(const wchar_t *path, StatT *buf, DWORD flags) { | |
| 186 | inline int stat_file(const wchar_t *path, StatT *buf, DWORD flags) { | |
| 212 | 187 | WinHandle h(path, FILE_READ_ATTRIBUTES, flags); |
| 213 | 188 | if (!h) |
| 214 | 189 | return set_errno(); |
| ... | ... | @@ -216,24 +191,26 @@ int stat_file(const wchar_t *path, StatT *buf, DWORD flags) { |
| 216 | 191 | return ret; |
| 217 | 192 | } |
| 218 | 193 | |
| 219 | int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); } | |
| 194 | inline int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); } | |
| 220 | 195 | |
| 221 | int lstat(const wchar_t *path, StatT *buf) { | |
| 196 | inline int lstat(const wchar_t *path, StatT *buf) { | |
| 222 | 197 | return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT); |
| 223 | 198 | } |
| 224 | 199 | |
| 225 | int fstat(int fd, StatT *buf) { | |
| 200 | inline int fstat(int fd, StatT *buf) { | |
| 226 | 201 | HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); |
| 227 | 202 | return stat_handle(h, buf); |
| 228 | 203 | } |
| 229 | 204 | |
| 230 | int mkdir(const wchar_t *path, int permissions) { | |
| 205 | inline int mkdir(const wchar_t *path, int permissions) { | |
| 231 | 206 | (void)permissions; |
| 232 | return _wmkdir(path); | |
| 207 | if (!CreateDirectoryW(path, nullptr)) | |
| 208 | return set_errno(); | |
| 209 | return 0; | |
| 233 | 210 | } |
| 234 | 211 | |
| 235 | int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, | |
| 236 | bool is_dir) { | |
| 212 | inline int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, | |
| 213 | bool is_dir) { | |
| 237 | 214 | path dest(oldname); |
| 238 | 215 | dest.make_preferred(); |
| 239 | 216 | oldname = dest.c_str(); |
| ... | ... | @@ -249,21 +226,21 @@ int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, |
| 249 | 226 | return set_errno(); |
| 250 | 227 | } |
| 251 | 228 | |
| 252 | int symlink_file(const wchar_t *oldname, const wchar_t *newname) { | |
| 229 | inline int symlink_file(const wchar_t *oldname, const wchar_t *newname) { | |
| 253 | 230 | return symlink_file_dir(oldname, newname, false); |
| 254 | 231 | } |
| 255 | 232 | |
| 256 | int symlink_dir(const wchar_t *oldname, const wchar_t *newname) { | |
| 233 | inline int symlink_dir(const wchar_t *oldname, const wchar_t *newname) { | |
| 257 | 234 | return symlink_file_dir(oldname, newname, true); |
| 258 | 235 | } |
| 259 | 236 | |
| 260 | int link(const wchar_t *oldname, const wchar_t *newname) { | |
| 237 | inline int link(const wchar_t *oldname, const wchar_t *newname) { | |
| 261 | 238 | if (CreateHardLinkW(newname, oldname, nullptr)) |
| 262 | 239 | return 0; |
| 263 | 240 | return set_errno(); |
| 264 | 241 | } |
| 265 | 242 | |
| 266 | int remove(const wchar_t *path) { | |
| 243 | inline int remove(const wchar_t *path) { | |
| 267 | 244 | detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT); |
| 268 | 245 | if (!h) |
| 269 | 246 | return set_errno(); |
| ... | ... | @@ -274,7 +251,7 @@ int remove(const wchar_t *path) { |
| 274 | 251 | return 0; |
| 275 | 252 | } |
| 276 | 253 | |
| 277 | int truncate_handle(HANDLE h, off_t length) { | |
| 254 | inline int truncate_handle(HANDLE h, off_t length) { | |
| 278 | 255 | LARGE_INTEGER size_param; |
| 279 | 256 | size_param.QuadPart = length; |
| 280 | 257 | if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN)) |
| ... | ... | @@ -284,19 +261,19 @@ int truncate_handle(HANDLE h, off_t length) { |
| 284 | 261 | return 0; |
| 285 | 262 | } |
| 286 | 263 | |
| 287 | int ftruncate(int fd, off_t length) { | |
| 264 | inline int ftruncate(int fd, off_t length) { | |
| 288 | 265 | HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); |
| 289 | 266 | return truncate_handle(h, length); |
| 290 | 267 | } |
| 291 | 268 | |
| 292 | int truncate(const wchar_t *path, off_t length) { | |
| 269 | inline int truncate(const wchar_t *path, off_t length) { | |
| 293 | 270 | detail::WinHandle h(path, GENERIC_WRITE, 0); |
| 294 | 271 | if (!h) |
| 295 | 272 | return set_errno(); |
| 296 | 273 | return truncate_handle(h, length); |
| 297 | 274 | } |
| 298 | 275 | |
| 299 | int rename(const wchar_t *from, const wchar_t *to) { | |
| 276 | inline int rename(const wchar_t *from, const wchar_t *to) { | |
| 300 | 277 | if (!(MoveFileExW(from, to, |
| 301 | 278 | MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | |
| 302 | 279 | MOVEFILE_WRITE_THROUGH))) |
| ... | ... | @@ -304,11 +281,11 @@ int rename(const wchar_t *from, const wchar_t *to) { |
| 304 | 281 | return 0; |
| 305 | 282 | } |
| 306 | 283 | |
| 307 | template <class... Args> int open(const wchar_t *filename, Args... args) { | |
| 308 | return _wopen(filename, args...); | |
| 284 | inline int chdir(const wchar_t* path) { | |
| 285 | if (!SetCurrentDirectoryW(path)) | |
| 286 | return set_errno(); | |
| 287 | return 0; | |
| 309 | 288 | } |
| 310 | int close(int fd) { return _close(fd); } | |
| 311 | int chdir(const wchar_t *path) { return _wchdir(path); } | |
| 312 | 289 | |
| 313 | 290 | struct StatVFS { |
| 314 | 291 | uint64_t f_frsize; |
| ... | ... | @@ -317,7 +294,7 @@ struct StatVFS { |
| 317 | 294 | uint64_t f_bavail; |
| 318 | 295 | }; |
| 319 | 296 | |
| 320 | int statvfs(const wchar_t *p, StatVFS *buf) { | |
| 297 | inline int statvfs(const wchar_t *p, StatVFS *buf) { | |
| 321 | 298 | path dir = p; |
| 322 | 299 | while (true) { |
| 323 | 300 | error_code local_ec; |
| ... | ... | @@ -343,11 +320,29 @@ int statvfs(const wchar_t *p, StatVFS *buf) { |
| 343 | 320 | return 0; |
| 344 | 321 | } |
| 345 | 322 | |
| 346 | wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); } | |
| 323 | inline wchar_t* getcwd([[maybe_unused]] wchar_t* in_buf, [[maybe_unused]] size_t in_size) { | |
| 324 | // Only expected to be used with us allocating the buffer. | |
| 325 | _LIBCPP_ASSERT(in_buf == nullptr, "Windows getcwd() assumes in_buf==nullptr"); | |
| 326 | _LIBCPP_ASSERT(in_size == 0, "Windows getcwd() assumes in_size==0"); | |
| 327 | ||
| 328 | size_t buff_size = MAX_PATH + 10; | |
| 329 | std::unique_ptr<wchar_t, decltype(&::free)> buff(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t))), &::free); | |
| 330 | DWORD retval = GetCurrentDirectoryW(buff_size, buff.get()); | |
| 331 | if (retval > buff_size) { | |
| 332 | buff_size = retval; | |
| 333 | buff.reset(static_cast<wchar_t*>(malloc(buff_size * sizeof(wchar_t)))); | |
| 334 | retval = GetCurrentDirectoryW(buff_size, buff.get()); | |
| 335 | } | |
| 336 | if (!retval) { | |
| 337 | set_errno(); | |
| 338 | return nullptr; | |
| 339 | } | |
| 340 | return buff.release(); | |
| 341 | } | |
| 347 | 342 | |
| 348 | wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) { | |
| 343 | inline wchar_t *realpath(const wchar_t *path, [[maybe_unused]] wchar_t *resolved_name) { | |
| 349 | 344 | // Only expected to be used with us allocating the buffer. |
| 350 | _LIBCPP_ASSERT(resolved_name == nullptr, | |
| 345 | _LIBCPP_ASSERT_UNCATEGORIZED(resolved_name == nullptr, | |
| 351 | 346 | "Windows realpath() assumes a null resolved_name"); |
| 352 | 347 | |
| 353 | 348 | WinHandle h(path, FILE_READ_ATTRIBUTES, 0); |
| ... | ... | @@ -386,7 +381,7 @@ wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) { |
| 386 | 381 | #define AT_SYMLINK_NOFOLLOW 1 |
| 387 | 382 | using ModeT = int; |
| 388 | 383 | |
| 389 | int fchmod_handle(HANDLE h, int perms) { | |
| 384 | inline int fchmod_handle(HANDLE h, int perms) { | |
| 390 | 385 | FILE_BASIC_INFO basic; |
| 391 | 386 | if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) |
| 392 | 387 | return set_errno(); |
| ... | ... | @@ -400,7 +395,7 @@ int fchmod_handle(HANDLE h, int perms) { |
| 400 | 395 | return 0; |
| 401 | 396 | } |
| 402 | 397 | |
| 403 | int fchmodat(int fd, const wchar_t *path, int perms, int flag) { | |
| 398 | inline int fchmodat(int /*fd*/, const wchar_t *path, int perms, int flag) { | |
| 404 | 399 | DWORD attributes = GetFileAttributesW(path); |
| 405 | 400 | if (attributes == INVALID_FILE_ATTRIBUTES) |
| 406 | 401 | return set_errno(); |
| ... | ... | @@ -427,7 +422,7 @@ int fchmodat(int fd, const wchar_t *path, int perms, int flag) { |
| 427 | 422 | return 0; |
| 428 | 423 | } |
| 429 | 424 | |
| 430 | int fchmod(int fd, int perms) { | |
| 425 | inline int fchmod(int fd, int perms) { | |
| 431 | 426 | HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd)); |
| 432 | 427 | return fchmod_handle(h, perms); |
| 433 | 428 | } |
| ... | ... | @@ -435,7 +430,7 @@ int fchmod(int fd, int perms) { |
| 435 | 430 | #define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE |
| 436 | 431 | using SSizeT = ::int64_t; |
| 437 | 432 | |
| 438 | SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) { | |
| 433 | inline SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) { | |
| 439 | 434 | uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; |
| 440 | 435 | detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT); |
| 441 | 436 | if (!h) |
| ... | ... | @@ -479,14 +474,13 @@ SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) { |
| 479 | 474 | } |
| 480 | 475 | |
| 481 | 476 | #else |
| 482 | int symlink_file(const char *oldname, const char *newname) { | |
| 477 | inline int symlink_file(const char *oldname, const char *newname) { | |
| 483 | 478 | return ::symlink(oldname, newname); |
| 484 | 479 | } |
| 485 | int symlink_dir(const char *oldname, const char *newname) { | |
| 480 | inline int symlink_dir(const char *oldname, const char *newname) { | |
| 486 | 481 | return ::symlink(oldname, newname); |
| 487 | 482 | } |
| 488 | 483 | using ::chdir; |
| 489 | using ::close; | |
| 490 | 484 | using ::fchmod; |
| 491 | 485 | #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) |
| 492 | 486 | using ::fchmodat; |
| ... | ... | @@ -497,7 +491,6 @@ using ::getcwd; |
| 497 | 491 | using ::link; |
| 498 | 492 | using ::lstat; |
| 499 | 493 | using ::mkdir; |
| 500 | using ::open; | |
| 501 | 494 | using ::readlink; |
| 502 | 495 | using ::realpath; |
| 503 | 496 | using ::remove; |
| ... | ... | @@ -514,7 +507,6 @@ using SSizeT = ::ssize_t; |
| 514 | 507 | |
| 515 | 508 | #endif |
| 516 | 509 | |
| 517 | } // namespace | |
| 518 | 510 | } // end namespace detail |
| 519 | 511 | |
| 520 | 512 | _LIBCPP_END_NAMESPACE_FILESYSTEM |
lib/libcxx/src/filesystem/time_utils.h created+385| ... | ... | @@ -0,0 +1,385 @@ |
| 1 | //===----------------------------------------------------------------------===//// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===//// | |
| 8 | ||
| 9 | #ifndef FILESYSTEM_TIME_UTILS_H | |
| 10 | #define FILESYSTEM_TIME_UTILS_H | |
| 11 | ||
| 12 | #include <__config> | |
| 13 | #include <array> | |
| 14 | #include <chrono> | |
| 15 | #include <filesystem> | |
| 16 | #include <limits> | |
| 17 | #include <ratio> | |
| 18 | #include <system_error> | |
| 19 | #include <type_traits> | |
| 20 | #include <utility> | |
| 21 | ||
| 22 | #include "error.h" | |
| 23 | #include "format_string.h" | |
| 24 | ||
| 25 | #if defined(_LIBCPP_WIN32API) | |
| 26 | # define WIN32_LEAN_AND_MEAN | |
| 27 | # define NOMINMAX | |
| 28 | # include <windows.h> | |
| 29 | #else | |
| 30 | # include <fcntl.h> | |
| 31 | # include <sys/stat.h> | |
| 32 | # include <sys/time.h> // for ::utimes as used in __last_write_time | |
| 33 | #endif | |
| 34 | ||
| 35 | // We can use the presence of UTIME_OMIT to detect platforms that provide utimensat. | |
| 36 | #if defined(UTIME_OMIT) | |
| 37 | # define _LIBCPP_USE_UTIMENSAT | |
| 38 | #endif | |
| 39 | ||
| 40 | _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM | |
| 41 | ||
| 42 | namespace detail { | |
| 43 | ||
| 44 | #if defined(_LIBCPP_WIN32API) | |
| 45 | // Various C runtime versions (UCRT, or the legacy msvcrt.dll used by | |
| 46 | // some mingw toolchains) provide different stat function implementations, | |
| 47 | // with a number of limitations with respect to what we want from the | |
| 48 | // stat function. Instead provide our own which does exactly what we want, | |
| 49 | // along with our own stat structure and flag macros. | |
| 50 | ||
| 51 | struct TimeSpec { | |
| 52 | int64_t tv_sec; | |
| 53 | int64_t tv_nsec; | |
| 54 | }; | |
| 55 | struct StatT { | |
| 56 | unsigned st_mode; | |
| 57 | TimeSpec st_atim; | |
| 58 | TimeSpec st_mtim; | |
| 59 | uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber | |
| 60 | struct FileIdStruct { | |
| 61 | unsigned char id[16]; // FILE_ID_INFO::FileId | |
| 62 | bool operator==(const FileIdStruct &other) const { | |
| 63 | for (int i = 0; i < 16; i++) | |
| 64 | if (id[i] != other.id[i]) | |
| 65 | return false; | |
| 66 | return true; | |
| 67 | } | |
| 68 | } st_ino; | |
| 69 | uint32_t st_nlink; | |
| 70 | uintmax_t st_size; | |
| 71 | }; | |
| 72 | ||
| 73 | // There were 369 years and 89 leap days from the Windows epoch | |
| 74 | // (1601) to the Unix epoch (1970). | |
| 75 | #define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60)) | |
| 76 | ||
| 77 | inline TimeSpec filetime_to_timespec(LARGE_INTEGER li) { | |
| 78 | TimeSpec ret; | |
| 79 | ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS; | |
| 80 | ret.tv_nsec = (li.QuadPart % 10000000) * 100; | |
| 81 | return ret; | |
| 82 | } | |
| 83 | ||
| 84 | inline TimeSpec filetime_to_timespec(FILETIME ft) { | |
| 85 | LARGE_INTEGER li; | |
| 86 | li.LowPart = ft.dwLowDateTime; | |
| 87 | li.HighPart = ft.dwHighDateTime; | |
| 88 | return filetime_to_timespec(li); | |
| 89 | } | |
| 90 | ||
| 91 | inline FILETIME timespec_to_filetime(TimeSpec ts) { | |
| 92 | LARGE_INTEGER li; | |
| 93 | li.QuadPart = | |
| 94 | ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000; | |
| 95 | FILETIME ft; | |
| 96 | ft.dwLowDateTime = li.LowPart; | |
| 97 | ft.dwHighDateTime = li.HighPart; | |
| 98 | return ft; | |
| 99 | } | |
| 100 | ||
| 101 | #else | |
| 102 | using TimeSpec = struct timespec; | |
| 103 | using TimeVal = struct timeval; | |
| 104 | using StatT = struct stat; | |
| 105 | ||
| 106 | inline TimeVal make_timeval(TimeSpec const& ts) { | |
| 107 | using namespace chrono; | |
| 108 | auto Convert = [](long nsec) { | |
| 109 | using int_type = decltype(std::declval<TimeVal>().tv_usec); | |
| 110 | auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count(); | |
| 111 | return static_cast<int_type>(dur); | |
| 112 | }; | |
| 113 | TimeVal TV = {}; | |
| 114 | TV.tv_sec = ts.tv_sec; | |
| 115 | TV.tv_usec = Convert(ts.tv_nsec); | |
| 116 | return TV; | |
| 117 | } | |
| 118 | #endif | |
| 119 | ||
| 120 | using chrono::duration; | |
| 121 | using chrono::duration_cast; | |
| 122 | ||
| 123 | template <class FileTimeT, class TimeT, | |
| 124 | bool IsFloat = is_floating_point<typename FileTimeT::rep>::value> | |
| 125 | struct time_util_base { | |
| 126 | using rep = typename FileTimeT::rep; | |
| 127 | using fs_duration = typename FileTimeT::duration; | |
| 128 | using fs_seconds = duration<rep>; | |
| 129 | using fs_nanoseconds = duration<rep, nano>; | |
| 130 | using fs_microseconds = duration<rep, micro>; | |
| 131 | ||
| 132 | static constexpr rep max_seconds = | |
| 133 | duration_cast<fs_seconds>(FileTimeT::duration::max()).count(); | |
| 134 | ||
| 135 | static constexpr rep max_nsec = | |
| 136 | duration_cast<fs_nanoseconds>(FileTimeT::duration::max() - | |
| 137 | fs_seconds(max_seconds)) | |
| 138 | .count(); | |
| 139 | ||
| 140 | static constexpr rep min_seconds = | |
| 141 | duration_cast<fs_seconds>(FileTimeT::duration::min()).count(); | |
| 142 | ||
| 143 | static constexpr rep min_nsec_timespec = | |
| 144 | duration_cast<fs_nanoseconds>( | |
| 145 | (FileTimeT::duration::min() - fs_seconds(min_seconds)) + | |
| 146 | fs_seconds(1)) | |
| 147 | .count(); | |
| 148 | ||
| 149 | private: | |
| 150 | static _LIBCPP_CONSTEXPR fs_duration get_min_nsecs() { | |
| 151 | return duration_cast<fs_duration>( | |
| 152 | fs_nanoseconds(min_nsec_timespec) - | |
| 153 | duration_cast<fs_nanoseconds>(fs_seconds(1))); | |
| 154 | } | |
| 155 | // Static assert that these values properly round trip. | |
| 156 | static_assert(fs_seconds(min_seconds) + get_min_nsecs() == | |
| 157 | FileTimeT::duration::min(), | |
| 158 | "value doesn't roundtrip"); | |
| 159 | ||
| 160 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() { | |
| 161 | // This kinda sucks, but it's what happens when we don't have __int128_t. | |
| 162 | if (sizeof(TimeT) == sizeof(rep)) { | |
| 163 | typedef duration<long long, ratio<3600 * 24 * 365> > Years; | |
| 164 | return duration_cast<Years>(fs_seconds(max_seconds)) > Years(250) && | |
| 165 | duration_cast<Years>(fs_seconds(min_seconds)) < Years(-250); | |
| 166 | } | |
| 167 | return max_seconds >= numeric_limits<TimeT>::max() && | |
| 168 | min_seconds <= numeric_limits<TimeT>::min(); | |
| 169 | } | |
| 170 | #if _LIBCPP_STD_VER >= 14 | |
| 171 | static_assert(check_range(), "the representable range is unacceptable small"); | |
| 172 | #endif | |
| 173 | }; | |
| 174 | ||
| 175 | template <class FileTimeT, class TimeT> | |
| 176 | struct time_util_base<FileTimeT, TimeT, true> { | |
| 177 | using rep = typename FileTimeT::rep; | |
| 178 | using fs_duration = typename FileTimeT::duration; | |
| 179 | using fs_seconds = duration<rep>; | |
| 180 | using fs_nanoseconds = duration<rep, nano>; | |
| 181 | using fs_microseconds = duration<rep, micro>; | |
| 182 | ||
| 183 | static const rep max_seconds; | |
| 184 | static const rep max_nsec; | |
| 185 | static const rep min_seconds; | |
| 186 | static const rep min_nsec_timespec; | |
| 187 | }; | |
| 188 | ||
| 189 | template <class FileTimeT, class TimeT> | |
| 190 | const typename FileTimeT::rep | |
| 191 | time_util_base<FileTimeT, TimeT, true>::max_seconds = | |
| 192 | duration_cast<fs_seconds>(FileTimeT::duration::max()).count(); | |
| 193 | ||
| 194 | template <class FileTimeT, class TimeT> | |
| 195 | const typename FileTimeT::rep time_util_base<FileTimeT, TimeT, true>::max_nsec = | |
| 196 | duration_cast<fs_nanoseconds>(FileTimeT::duration::max() - | |
| 197 | fs_seconds(max_seconds)) | |
| 198 | .count(); | |
| 199 | ||
| 200 | template <class FileTimeT, class TimeT> | |
| 201 | const typename FileTimeT::rep | |
| 202 | time_util_base<FileTimeT, TimeT, true>::min_seconds = | |
| 203 | duration_cast<fs_seconds>(FileTimeT::duration::min()).count(); | |
| 204 | ||
| 205 | template <class FileTimeT, class TimeT> | |
| 206 | const typename FileTimeT::rep | |
| 207 | time_util_base<FileTimeT, TimeT, true>::min_nsec_timespec = | |
| 208 | duration_cast<fs_nanoseconds>((FileTimeT::duration::min() - | |
| 209 | fs_seconds(min_seconds)) + | |
| 210 | fs_seconds(1)) | |
| 211 | .count(); | |
| 212 | ||
| 213 | template <class FileTimeT, class TimeT, class TimeSpecT> | |
| 214 | struct time_util : time_util_base<FileTimeT, TimeT> { | |
| 215 | using Base = time_util_base<FileTimeT, TimeT>; | |
| 216 | using Base::max_nsec; | |
| 217 | using Base::max_seconds; | |
| 218 | using Base::min_nsec_timespec; | |
| 219 | using Base::min_seconds; | |
| 220 | ||
| 221 | using typename Base::fs_duration; | |
| 222 | using typename Base::fs_microseconds; | |
| 223 | using typename Base::fs_nanoseconds; | |
| 224 | using typename Base::fs_seconds; | |
| 225 | ||
| 226 | public: | |
| 227 | template <class CType, class ChronoType> | |
| 228 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool checked_set(CType* out, | |
| 229 | ChronoType time) { | |
| 230 | using Lim = numeric_limits<CType>; | |
| 231 | if (time > Lim::max() || time < Lim::min()) | |
| 232 | return false; | |
| 233 | *out = static_cast<CType>(time); | |
| 234 | return true; | |
| 235 | } | |
| 236 | ||
| 237 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(TimeSpecT tm) { | |
| 238 | if (tm.tv_sec >= 0) { | |
| 239 | return tm.tv_sec < max_seconds || | |
| 240 | (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec); | |
| 241 | } else if (tm.tv_sec == (min_seconds - 1)) { | |
| 242 | return tm.tv_nsec >= min_nsec_timespec; | |
| 243 | } else { | |
| 244 | return tm.tv_sec >= min_seconds; | |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(FileTimeT tm) { | |
| 249 | auto secs = duration_cast<fs_seconds>(tm.time_since_epoch()); | |
| 250 | auto nsecs = duration_cast<fs_nanoseconds>(tm.time_since_epoch() - secs); | |
| 251 | if (nsecs.count() < 0) { | |
| 252 | secs = secs + fs_seconds(1); | |
| 253 | nsecs = nsecs + fs_seconds(1); | |
| 254 | } | |
| 255 | using TLim = numeric_limits<TimeT>; | |
| 256 | if (secs.count() >= 0) | |
| 257 | return secs.count() <= TLim::max(); | |
| 258 | return secs.count() >= TLim::min(); | |
| 259 | } | |
| 260 | ||
| 261 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 FileTimeT | |
| 262 | convert_from_timespec(TimeSpecT tm) { | |
| 263 | if (tm.tv_sec >= 0 || tm.tv_nsec == 0) { | |
| 264 | return FileTimeT(fs_seconds(tm.tv_sec) + | |
| 265 | duration_cast<fs_duration>(fs_nanoseconds(tm.tv_nsec))); | |
| 266 | } else { // tm.tv_sec < 0 | |
| 267 | auto adj_subsec = duration_cast<fs_duration>(fs_seconds(1) - | |
| 268 | fs_nanoseconds(tm.tv_nsec)); | |
| 269 | auto Dur = fs_seconds(tm.tv_sec + 1) - adj_subsec; | |
| 270 | return FileTimeT(Dur); | |
| 271 | } | |
| 272 | } | |
| 273 | ||
| 274 | template <class SubSecT> | |
| 275 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool | |
| 276 | set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) { | |
| 277 | auto dur = tp.time_since_epoch(); | |
| 278 | auto sec_dur = duration_cast<fs_seconds>(dur); | |
| 279 | auto subsec_dur = duration_cast<fs_nanoseconds>(dur - sec_dur); | |
| 280 | // The tv_nsec and tv_usec fields must not be negative so adjust accordingly | |
| 281 | if (subsec_dur.count() < 0) { | |
| 282 | if (sec_dur.count() > min_seconds) { | |
| 283 | sec_dur = sec_dur - fs_seconds(1); | |
| 284 | subsec_dur = subsec_dur + fs_seconds(1); | |
| 285 | } else { | |
| 286 | subsec_dur = fs_nanoseconds::zero(); | |
| 287 | } | |
| 288 | } | |
| 289 | return checked_set(sec_out, sec_dur.count()) && | |
| 290 | checked_set(subsec_out, subsec_dur.count()); | |
| 291 | } | |
| 292 | static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool convert_to_timespec(TimeSpecT& dest, | |
| 293 | FileTimeT tp) { | |
| 294 | if (!is_representable(tp)) | |
| 295 | return false; | |
| 296 | return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp); | |
| 297 | } | |
| 298 | }; | |
| 299 | ||
| 300 | #if defined(_LIBCPP_WIN32API) | |
| 301 | using fs_time = time_util<file_time_type, int64_t, TimeSpec>; | |
| 302 | #else | |
| 303 | using fs_time = time_util<file_time_type, time_t, TimeSpec>; | |
| 304 | #endif | |
| 305 | ||
| 306 | #if defined(__APPLE__) | |
| 307 | inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } | |
| 308 | inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } | |
| 309 | #elif defined(__MVS__) | |
| 310 | inline TimeSpec extract_mtime(StatT const& st) { | |
| 311 | TimeSpec TS = {st.st_mtime, 0}; | |
| 312 | return TS; | |
| 313 | } | |
| 314 | inline TimeSpec extract_atime(StatT const& st) { | |
| 315 | TimeSpec TS = {st.st_atime, 0}; | |
| 316 | return TS; | |
| 317 | } | |
| 318 | #elif defined(_AIX) | |
| 319 | inline TimeSpec extract_mtime(StatT const& st) { | |
| 320 | TimeSpec TS = {st.st_mtime, st.st_mtime_n}; | |
| 321 | return TS; | |
| 322 | } | |
| 323 | inline TimeSpec extract_atime(StatT const& st) { | |
| 324 | TimeSpec TS = {st.st_atime, st.st_atime_n}; | |
| 325 | return TS; | |
| 326 | } | |
| 327 | #else | |
| 328 | inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } | |
| 329 | inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } | |
| 330 | #endif | |
| 331 | ||
| 332 | #ifndef _LIBCPP_HAS_NO_FILESYSTEM | |
| 333 | ||
| 334 | #if !defined(_LIBCPP_WIN32API) | |
| 335 | inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 336 | error_code& ec) { | |
| 337 | TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])}; | |
| 338 | if (::utimes(p.c_str(), ConvertedTS) == -1) { | |
| 339 | ec = capture_errno(); | |
| 340 | return true; | |
| 341 | } | |
| 342 | return false; | |
| 343 | } | |
| 344 | ||
| 345 | #if defined(_LIBCPP_USE_UTIMENSAT) | |
| 346 | inline bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 347 | error_code& ec) { | |
| 348 | if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) { | |
| 349 | ec = capture_errno(); | |
| 350 | return true; | |
| 351 | } | |
| 352 | return false; | |
| 353 | } | |
| 354 | #endif | |
| 355 | ||
| 356 | inline bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS, | |
| 357 | error_code& ec) { | |
| 358 | #if !defined(_LIBCPP_USE_UTIMENSAT) | |
| 359 | return posix_utimes(p, TS, ec); | |
| 360 | #else | |
| 361 | return posix_utimensat(p, TS, ec); | |
| 362 | #endif | |
| 363 | } | |
| 364 | ||
| 365 | #endif // !_LIBCPP_WIN32API | |
| 366 | ||
| 367 | inline file_time_type __extract_last_write_time(const path& p, const StatT& st, | |
| 368 | error_code* ec) { | |
| 369 | using detail::fs_time; | |
| 370 | ErrorHandler<file_time_type> err("last_write_time", ec, &p); | |
| 371 | ||
| 372 | auto ts = detail::extract_mtime(st); | |
| 373 | if (!fs_time::is_representable(ts)) | |
| 374 | return err.report(errc::value_too_large); | |
| 375 | ||
| 376 | return fs_time::convert_from_timespec(ts); | |
| 377 | } | |
| 378 | ||
| 379 | #endif // !_LIBCPP_HAS_NO_FILESYSTEM | |
| 380 | ||
| 381 | } // end namespace detail | |
| 382 | ||
| 383 | _LIBCPP_END_NAMESPACE_FILESYSTEM | |
| 384 | ||
| 385 | #endif // FILESYSTEM_TIME_UTILS_H |
lib/libcxx/src/format.cpp deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <format> | |
| 10 | ||
| 11 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 12 | ||
| 13 | #ifndef _LIBCPP_INLINE_FORMAT_ERROR_DTOR | |
| 14 | format_error::~format_error() noexcept = default; | |
| 15 | #endif | |
| 16 | ||
| 17 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/future.cpp+2-2| ... | ... | @@ -197,12 +197,12 @@ promise<void>::~promise() |
| 197 | 197 | { |
| 198 | 198 | if (__state_) |
| 199 | 199 | { |
| 200 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 200 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 201 | 201 | if (!__state_->__has_value() && __state_->use_count() > 1) |
| 202 | 202 | __state_->set_exception(make_exception_ptr( |
| 203 | 203 | future_error(make_error_code(future_errc::broken_promise)) |
| 204 | 204 | )); |
| 205 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 205 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 206 | 206 | __state_->__release_shared(); |
| 207 | 207 | } |
| 208 | 208 | } |
lib/libcxx/src/include/apple_availability.h-18| ... | ... | @@ -11,24 +11,6 @@ |
| 11 | 11 | |
| 12 | 12 | #if defined(__APPLE__) |
| 13 | 13 | |
| 14 | #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) | |
| 15 | #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101300 | |
| 16 | #define _LIBCPP_USE_UTIMENSAT | |
| 17 | #endif | |
| 18 | #elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) | |
| 19 | #if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 110000 | |
| 20 | #define _LIBCPP_USE_UTIMENSAT | |
| 21 | #endif | |
| 22 | #elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) | |
| 23 | #if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 110000 | |
| 24 | #define _LIBCPP_USE_UTIMENSAT | |
| 25 | #endif | |
| 26 | #elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) | |
| 27 | #if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 40000 | |
| 28 | #define _LIBCPP_USE_UTIMENSAT | |
| 29 | #endif | |
| 30 | #endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__ | |
| 31 | ||
| 32 | 14 | #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) |
| 33 | 15 | #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101500 |
| 34 | 16 | #define _LIBCPP_USE_ULOCK |
lib/libcxx/src/include/config_elast.h-2| ... | ... | @@ -35,8 +35,6 @@ |
| 35 | 35 | #define _LIBCPP_ELAST 4095 |
| 36 | 36 | #elif defined(__APPLE__) |
| 37 | 37 | // No _LIBCPP_ELAST needed on Apple |
| 38 | #elif defined(__sun__) | |
| 39 | #define _LIBCPP_ELAST ESTALE | |
| 40 | 38 | #elif defined(__MVS__) |
| 41 | 39 | #define _LIBCPP_ELAST 1160 |
| 42 | 40 | #elif defined(_LIBCPP_MSVCRT_LIKE) |
lib/libcxx/src/include/ryu/common.h+11-10| ... | ... | @@ -43,7 +43,8 @@ |
| 43 | 43 | // clang-format off |
| 44 | 44 | |
| 45 | 45 | #include <__assert> |
| 46 | #include "__config" | |
| 46 | #include <__config> | |
| 47 | #include <cstring> | |
| 47 | 48 | |
| 48 | 49 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 49 | 50 | |
| ... | ... | @@ -51,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 51 | 52 | // Function precondition: __v is not a 10-digit number. |
| 52 | 53 | // (f2s: 9 digits are sufficient for round-tripping.) |
| 53 | 54 | // (d2fixed: We print 9-digit blocks.) |
| 54 | _LIBCPP_ASSERT(__v < 1000000000, ""); | |
| 55 | _LIBCPP_ASSERT_UNCATEGORIZED(__v < 1000000000, ""); | |
| 55 | 56 | if (__v >= 100000000) { return 9; } |
| 56 | 57 | if (__v >= 10000000) { return 8; } |
| 57 | 58 | if (__v >= 1000000) { return 7; } |
| ... | ... | @@ -68,36 +69,36 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 68 | 69 | // This approximation works up to the point that the multiplication overflows at __e = 3529. |
| 69 | 70 | // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater |
| 70 | 71 | // than 2^9297. |
| 71 | _LIBCPP_ASSERT(__e >= 0, ""); | |
| 72 | _LIBCPP_ASSERT(__e <= 3528, ""); | |
| 72 | _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, ""); | |
| 73 | _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 3528, ""); | |
| 73 | 74 | return static_cast<int32_t>(((static_cast<uint32_t>(__e) * 1217359) >> 19) + 1); |
| 74 | 75 | } |
| 75 | 76 | |
| 76 | 77 | // Returns floor(log_10(2^__e)). |
| 77 | 78 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow2(const int32_t __e) { |
| 78 | 79 | // The first value this approximation fails for is 2^1651 which is just greater than 10^297. |
| 79 | _LIBCPP_ASSERT(__e >= 0, ""); | |
| 80 | _LIBCPP_ASSERT(__e <= 1650, ""); | |
| 80 | _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, ""); | |
| 81 | _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 1650, ""); | |
| 81 | 82 | return (static_cast<uint32_t>(__e) * 78913) >> 18; |
| 82 | 83 | } |
| 83 | 84 | |
| 84 | 85 | // Returns floor(log_10(5^__e)). |
| 85 | 86 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __log10Pow5(const int32_t __e) { |
| 86 | 87 | // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. |
| 87 | _LIBCPP_ASSERT(__e >= 0, ""); | |
| 88 | _LIBCPP_ASSERT(__e <= 2620, ""); | |
| 88 | _LIBCPP_ASSERT_UNCATEGORIZED(__e >= 0, ""); | |
| 89 | _LIBCPP_ASSERT_UNCATEGORIZED(__e <= 2620, ""); | |
| 89 | 90 | return (static_cast<uint32_t>(__e) * 732923) >> 20; |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | 93 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __float_to_bits(const float __f) { |
| 93 | 94 | uint32_t __bits = 0; |
| 94 | _VSTD::memcpy(&__bits, &__f, sizeof(float)); | |
| 95 | std::memcpy(&__bits, &__f, sizeof(float)); | |
| 95 | 96 | return __bits; |
| 96 | 97 | } |
| 97 | 98 | |
| 98 | 99 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __double_to_bits(const double __d) { |
| 99 | 100 | uint64_t __bits = 0; |
| 100 | _VSTD::memcpy(&__bits, &__d, sizeof(double)); | |
| 101 | std::memcpy(&__bits, &__d, sizeof(double)); | |
| 101 | 102 | return __bits; |
| 102 | 103 | } |
| 103 | 104 |
lib/libcxx/src/include/ryu/d2s_intrinsics.h+8-8| ... | ... | @@ -63,7 +63,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 63 | 63 | // (The shift value is in the range [49, 58].) |
| 64 | 64 | // Check this here in case a future change requires larger shift |
| 65 | 65 | // values. In this case this function needs to be adjusted. |
| 66 | _LIBCPP_ASSERT(__dist < 64, ""); | |
| 66 | _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, ""); | |
| 67 | 67 | return __shiftright128(__lo, __hi, static_cast<unsigned char>(__dist)); |
| 68 | 68 | } |
| 69 | 69 | |
| ... | ... | @@ -85,7 +85,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 85 | 85 | // (The shift value is in the range [49, 58].) |
| 86 | 86 | // Check this here in case a future change requires larger shift |
| 87 | 87 | // values. In this case this function needs to be adjusted. |
| 88 | _LIBCPP_ASSERT(__dist < 64, ""); | |
| 88 | _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, ""); | |
| 89 | 89 | auto __temp = __lo | ((unsigned __int128)__hi << 64); |
| 90 | 90 | // For x64 128-bit shfits using the `shrd` instruction and two 64-bit |
| 91 | 91 | // registers, the shift value is modulo 64. Thus the `& 63` is free. |
| ... | ... | @@ -126,13 +126,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 126 | 126 | |
| 127 | 127 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64_t __hi, const uint32_t __dist) { |
| 128 | 128 | // We don't need to handle the case __dist >= 64 here (see above). |
| 129 | _LIBCPP_ASSERT(__dist < 64, ""); | |
| 129 | _LIBCPP_ASSERT_UNCATEGORIZED(__dist < 64, ""); | |
| 130 | 130 | #ifdef _LIBCPP_64_BIT |
| 131 | _LIBCPP_ASSERT(__dist > 0, ""); | |
| 131 | _LIBCPP_ASSERT_UNCATEGORIZED(__dist > 0, ""); | |
| 132 | 132 | return (__hi << (64 - __dist)) | (__lo >> __dist); |
| 133 | 133 | #else // ^^^ 64-bit ^^^ / vvv 32-bit vvv |
| 134 | 134 | // Avoid a 64-bit shift by taking advantage of the range of shift values. |
| 135 | _LIBCPP_ASSERT(__dist >= 32, ""); | |
| 135 | _LIBCPP_ASSERT_UNCATEGORIZED(__dist >= 32, ""); | |
| 136 | 136 | return (__hi << (64 - __dist)) | (static_cast<uint32_t>(__lo >> 32) >> (__dist - 32)); |
| 137 | 137 | #endif // ^^^ 32-bit ^^^ |
| 138 | 138 | } |
| ... | ... | @@ -227,7 +227,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 227 | 227 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint64_t __value) { |
| 228 | 228 | uint32_t __count = 0; |
| 229 | 229 | for (;;) { |
| 230 | _LIBCPP_ASSERT(__value != 0, ""); | |
| 230 | _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, ""); | |
| 231 | 231 | const uint64_t __q = __div5(__value); |
| 232 | 232 | const uint32_t __r = static_cast<uint32_t>(__value) - 5 * static_cast<uint32_t>(__q); |
| 233 | 233 | if (__r != 0) { |
| ... | ... | @@ -247,8 +247,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 247 | 247 | |
| 248 | 248 | // Returns true if __value is divisible by 2^__p. |
| 249 | 249 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint64_t __value, const uint32_t __p) { |
| 250 | _LIBCPP_ASSERT(__value != 0, ""); | |
| 251 | _LIBCPP_ASSERT(__p < 64, ""); | |
| 250 | _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, ""); | |
| 251 | _LIBCPP_ASSERT_UNCATEGORIZED(__p < 64, ""); | |
| 252 | 252 | // __builtin_ctzll doesn't appear to be faster here. |
| 253 | 253 | return (__value & ((1ull << __p) - 1)) == 0; |
| 254 | 254 | } |
lib/libcxx/src/include/ryu/ryu.h+1-2| ... | ... | @@ -47,8 +47,7 @@ |
| 47 | 47 | #include <__charconv/chars_format.h> |
| 48 | 48 | #include <__charconv/to_chars_result.h> |
| 49 | 49 | #include <__config> |
| 50 | #include <__debug> | |
| 51 | #include <__errc> | |
| 50 | #include <__system_error/errc.h> | |
| 52 | 51 | #include <cstdint> |
| 53 | 52 | #include <cstring> |
| 54 | 53 | #include <type_traits> |
lib/libcxx/src/include/to_chars_floating_point.h+12-12| ... | ... | @@ -269,7 +269,7 @@ to_chars_result _Floating_to_chars_hex_precision( |
| 269 | 269 | // * Print the leading hexit, then mask it away. |
| 270 | 270 | { |
| 271 | 271 | const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Adjusted_explicit_bits); |
| 272 | _LIBCPP_ASSERT(_Nibble < 3, ""); | |
| 272 | _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 3, ""); | |
| 273 | 273 | const char _Leading_hexit = static_cast<char>('0' + _Nibble); |
| 274 | 274 | |
| 275 | 275 | *_First++ = _Leading_hexit; |
| ... | ... | @@ -288,12 +288,12 @@ to_chars_result _Floating_to_chars_hex_precision( |
| 288 | 288 | int32_t _Number_of_bits_remaining = _Adjusted_explicit_bits; // 24 for float, 52 for double |
| 289 | 289 | |
| 290 | 290 | for (;;) { |
| 291 | _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, ""); | |
| 292 | _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, ""); | |
| 291 | _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, ""); | |
| 292 | _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, ""); | |
| 293 | 293 | _Number_of_bits_remaining -= 4; |
| 294 | 294 | |
| 295 | 295 | const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining); |
| 296 | _LIBCPP_ASSERT(_Nibble < 16, ""); | |
| 296 | _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, ""); | |
| 297 | 297 | const char _Hexit = __itoa::_Charconv_digits[_Nibble]; |
| 298 | 298 | |
| 299 | 299 | *_First++ = _Hexit; |
| ... | ... | @@ -415,12 +415,12 @@ to_chars_result _Floating_to_chars_hex_shortest( |
| 415 | 415 | // '0' hexits, the same condition works (as we print the final hexit and mask it away); we don't need to test |
| 416 | 416 | // _Number_of_bits_remaining. |
| 417 | 417 | do { |
| 418 | _LIBCPP_ASSERT(_Number_of_bits_remaining >= 4, ""); | |
| 419 | _LIBCPP_ASSERT(_Number_of_bits_remaining % 4 == 0, ""); | |
| 418 | _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining >= 4, ""); | |
| 419 | _LIBCPP_ASSERT_UNCATEGORIZED(_Number_of_bits_remaining % 4 == 0, ""); | |
| 420 | 420 | _Number_of_bits_remaining -= 4; |
| 421 | 421 | |
| 422 | 422 | const uint32_t _Nibble = static_cast<uint32_t>(_Adjusted_mantissa >> _Number_of_bits_remaining); |
| 423 | _LIBCPP_ASSERT(_Nibble < 16, ""); | |
| 423 | _LIBCPP_ASSERT_UNCATEGORIZED(_Nibble < 16, ""); | |
| 424 | 424 | const char _Hexit = __itoa::_Charconv_digits[_Nibble]; |
| 425 | 425 | |
| 426 | 426 | if (_First == _Last) { |
| ... | ... | @@ -940,13 +940,13 @@ to_chars_result _Floating_to_chars_general_precision( |
| 940 | 940 | _Effective_precision = _VSTD::min(_Precision - (_Scientific_exponent_X + 1), _Max_fixed_precision); |
| 941 | 941 | const to_chars_result _Buf_result = |
| 942 | 942 | _Floating_to_chars_fixed_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision); |
| 943 | _LIBCPP_ASSERT(_Buf_result.ec == errc{}, ""); | |
| 943 | _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, ""); | |
| 944 | 944 | _Significand_last = _Buf_result.ptr; |
| 945 | 945 | } else { |
| 946 | 946 | _Effective_precision = _VSTD::min(_Precision - 1, _Max_scientific_precision); |
| 947 | 947 | const to_chars_result _Buf_result = |
| 948 | 948 | _Floating_to_chars_scientific_precision(_Buffer, _VSTD::end(_Buffer), _Value, _Effective_precision); |
| 949 | _LIBCPP_ASSERT(_Buf_result.ec == errc{}, ""); | |
| 949 | _LIBCPP_ASSERT_UNCATEGORIZED(_Buf_result.ec == errc{}, ""); | |
| 950 | 950 | _Significand_last = _VSTD::find(_Buffer, _Buf_result.ptr, 'e'); |
| 951 | 951 | _Exponent_first = _Significand_last; |
| 952 | 952 | _Exponent_last = _Buf_result.ptr; |
| ... | ... | @@ -992,10 +992,10 @@ to_chars_result _Floating_to_chars( |
| 992 | 992 | char* _First, char* const _Last, _Floating _Value, const chars_format _Fmt, const int _Precision) noexcept { |
| 993 | 993 | |
| 994 | 994 | if constexpr (_Overload == _Floating_to_chars_overload::_Plain) { |
| 995 | _LIBCPP_ASSERT(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally | |
| 995 | _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format{}, ""); // plain overload must pass chars_format{} internally | |
| 996 | 996 | } else { |
| 997 | _LIBCPP_ASSERT(_Fmt == chars_format::general || _Fmt == chars_format::scientific || _Fmt == chars_format::fixed | |
| 998 | || _Fmt == chars_format::hex, | |
| 997 | _LIBCPP_ASSERT_UNCATEGORIZED(_Fmt == chars_format::general || _Fmt == chars_format::scientific | |
| 998 | || _Fmt == chars_format::fixed || _Fmt == chars_format::hex, | |
| 999 | 999 | "invalid format in to_chars()"); |
| 1000 | 1000 | } |
| 1001 | 1001 |
lib/libcxx/src/ios.cpp+4-4| ... | ... | @@ -413,20 +413,20 @@ void |
| 413 | 413 | ios_base::__set_badbit_and_consider_rethrow() |
| 414 | 414 | { |
| 415 | 415 | __rdstate_ |= badbit; |
| 416 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 416 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 417 | 417 | if (__exceptions_ & badbit) |
| 418 | 418 | throw; |
| 419 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 419 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 420 | 420 | } |
| 421 | 421 | |
| 422 | 422 | void |
| 423 | 423 | ios_base::__set_failbit_and_consider_rethrow() |
| 424 | 424 | { |
| 425 | 425 | __rdstate_ |= failbit; |
| 426 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 426 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 427 | 427 | if (__exceptions_ & failbit) |
| 428 | 428 | throw; |
| 429 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 429 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 430 | 430 | } |
| 431 | 431 | |
| 432 | 432 | bool |
lib/libcxx/src/ios.instantiations.cpp+1-1| ... | ... | @@ -37,7 +37,7 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char> |
| 37 | 37 | template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>; |
| 38 | 38 | template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>; |
| 39 | 39 | |
| 40 | #ifndef _LIBCPP_HAS_NO_FSTREAM | |
| 40 | #ifndef _LIBCPP_HAS_NO_FILESYSTEM | |
| 41 | 41 | template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>; |
| 42 | 42 | template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>; |
| 43 | 43 | template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>; |
lib/libcxx/src/iostream.cpp+13-9| ... | ... | @@ -7,17 +7,21 @@ |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | 9 | #include <__locale> |
| 10 | #include <__std_stream> | |
| 10 | #include "std_stream.h" | |
| 11 | 11 | #include <new> |
| 12 | 12 | #include <string> |
| 13 | 13 | |
| 14 | #ifdef _LIBCPP_MSVCRT_LIKE | |
| 15 | # include <__locale_dir/locale_base_api/locale_guard.h> | |
| 16 | #endif | |
| 17 | ||
| 14 | 18 | #define _str(s) #s |
| 15 | 19 | #define str(s) _str(s) |
| 16 | 20 | #define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE) |
| 17 | 21 | |
| 18 | 22 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 23 | |
| 20 | _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] | |
| 24 | _ALIGNAS_TYPE (istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)] | |
| 21 | 25 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 22 | 26 | __asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 23 | 27 | #endif |
| ... | ... | @@ -26,7 +30,7 @@ _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)]; |
| 26 | 30 | static mbstate_t mb_cin; |
| 27 | 31 | |
| 28 | 32 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 29 | _ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)] | |
| 33 | _ALIGNAS_TYPE (wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)] | |
| 30 | 34 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 31 | 35 | __asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 32 | 36 | #endif |
| ... | ... | @@ -35,7 +39,7 @@ _ALIGNAS_TYPE (__stdinbuf<wchar_t> ) static char __wcin[sizeof(__stdinbuf <wchar |
| 35 | 39 | static mbstate_t mb_wcin; |
| 36 | 40 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 37 | 41 | |
| 38 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)] | |
| 42 | _ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)] | |
| 39 | 43 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 40 | 44 | __asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 41 | 45 | #endif |
| ... | ... | @@ -44,7 +48,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; |
| 44 | 48 | static mbstate_t mb_cout; |
| 45 | 49 | |
| 46 | 50 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 47 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)] | |
| 51 | _ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)] | |
| 48 | 52 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 49 | 53 | __asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 50 | 54 | #endif |
| ... | ... | @@ -53,7 +57,7 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wcha |
| 53 | 57 | static mbstate_t mb_wcout; |
| 54 | 58 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 55 | 59 | |
| 56 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)] | |
| 60 | _ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)] | |
| 57 | 61 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 58 | 62 | __asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 59 | 63 | #endif |
| ... | ... | @@ -62,7 +66,7 @@ _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; |
| 62 | 66 | static mbstate_t mb_cerr; |
| 63 | 67 | |
| 64 | 68 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 65 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)] | |
| 69 | _ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)] | |
| 66 | 70 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 67 | 71 | __asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 68 | 72 | #endif |
| ... | ... | @@ -71,14 +75,14 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wcha |
| 71 | 75 | static mbstate_t mb_wcerr; |
| 72 | 76 | #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 73 | 77 | |
| 74 | _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)] | |
| 78 | _ALIGNAS_TYPE (ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)] | |
| 75 | 79 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 76 | 80 | __asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 77 | 81 | #endif |
| 78 | 82 | ; |
| 79 | 83 | |
| 80 | 84 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 81 | _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)] | |
| 85 | _ALIGNAS_TYPE (wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)] | |
| 82 | 86 | #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) |
| 83 | 87 | __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") |
| 84 | 88 | #endif |
lib/libcxx/src/legacy_pointer_safety.cpp+4-4| ... | ... | @@ -15,9 +15,9 @@ |
| 15 | 15 | |
| 16 | 16 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 17 | 17 | |
| 18 | _LIBCPP_FUNC_VIS void declare_reachable(void*) {} | |
| 19 | _LIBCPP_FUNC_VIS void declare_no_pointers(char*, size_t) {} | |
| 20 | _LIBCPP_FUNC_VIS void undeclare_no_pointers(char*, size_t) {} | |
| 21 | _LIBCPP_FUNC_VIS void* __undeclare_reachable(void* p) { return p; } | |
| 18 | _LIBCPP_EXPORTED_FROM_ABI void declare_reachable(void*) {} | |
| 19 | _LIBCPP_EXPORTED_FROM_ABI void declare_no_pointers(char*, size_t) {} | |
| 20 | _LIBCPP_EXPORTED_FROM_ABI void undeclare_no_pointers(char*, size_t) {} | |
| 21 | _LIBCPP_EXPORTED_FROM_ABI void* __undeclare_reachable(void* p) { return p; } | |
| 22 | 22 | |
| 23 | 23 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/locale.cpp+31-32| ... | ... | @@ -6,13 +6,8 @@ |
| 6 | 6 | // |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | // On Solaris, we need to define something to make the C99 parts of localeconv | |
| 10 | // visible. | |
| 11 | #ifdef __sun__ | |
| 12 | #define _LCONV_C99 | |
| 13 | #endif | |
| 14 | ||
| 15 | 9 | #include <__utility/unreachable.h> |
| 10 | #include <__verbose_abort> | |
| 16 | 11 | #include <algorithm> |
| 17 | 12 | #include <clocale> |
| 18 | 13 | #include <codecvt> |
| ... | ... | @@ -118,16 +113,27 @@ countof(const T * const begin, const T * const end) |
| 118 | 113 | |
| 119 | 114 | _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg) |
| 120 | 115 | { |
| 121 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 116 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 122 | 117 | throw runtime_error(msg); |
| 123 | 118 | #else |
| 124 | (void)msg; | |
| 125 | _VSTD::abort(); | |
| 119 | _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg.c_str()); | |
| 126 | 120 | #endif |
| 127 | 121 | } |
| 128 | 122 | |
| 129 | 123 | } |
| 130 | 124 | |
| 125 | string | |
| 126 | build_name(const string& other, const string& one, locale::category c) { | |
| 127 | if (other == "*" || one == "*") | |
| 128 | return "*"; | |
| 129 | if (c == locale::none || other == one) | |
| 130 | return other; | |
| 131 | ||
| 132 | // FIXME: Handle the more complicated cases, such as when the locale has | |
| 133 | // different names for different categories. | |
| 134 | return "*"; | |
| 135 | } | |
| 136 | ||
| 131 | 137 | const locale::category locale::none; |
| 132 | 138 | const locale::category locale::collate; |
| 133 | 139 | const locale::category locale::ctype; |
| ... | ... | @@ -236,10 +242,10 @@ locale::__imp::__imp(const string& name, size_t refs) |
| 236 | 242 | facets_(N), |
| 237 | 243 | name_(name) |
| 238 | 244 | { |
| 239 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 245 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 240 | 246 | try |
| 241 | 247 | { |
| 242 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 248 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 243 | 249 | facets_ = locale::classic().__locale_->facets_; |
| 244 | 250 | for (unsigned i = 0; i < facets_.size(); ++i) |
| 245 | 251 | if (facets_[i]) |
| ... | ... | @@ -286,7 +292,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 286 | 292 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| 287 | 293 | install(new messages_byname<wchar_t>(name_)); |
| 288 | 294 | #endif |
| 289 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 295 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 290 | 296 | } |
| 291 | 297 | catch (...) |
| 292 | 298 | { |
| ... | ... | @@ -295,7 +301,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 295 | 301 | facets_[i]->__release_shared(); |
| 296 | 302 | throw; |
| 297 | 303 | } |
| 298 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 304 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 299 | 305 | } |
| 300 | 306 | |
| 301 | 307 | locale::__imp::__imp(const __imp& other) |
| ... | ... | @@ -309,17 +315,16 @@ locale::__imp::__imp(const __imp& other) |
| 309 | 315 | } |
| 310 | 316 | |
| 311 | 317 | locale::__imp::__imp(const __imp& other, const string& name, locale::category c) |
| 312 | : facets_(N), | |
| 313 | name_("*") | |
| 318 | : facets_(N), name_(build_name(other.name_, name, c)) | |
| 314 | 319 | { |
| 315 | 320 | facets_ = other.facets_; |
| 316 | 321 | for (unsigned i = 0; i < facets_.size(); ++i) |
| 317 | 322 | if (facets_[i]) |
| 318 | 323 | facets_[i]->__add_shared(); |
| 319 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 324 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 320 | 325 | try |
| 321 | 326 | { |
| 322 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 327 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 323 | 328 | if (c & locale::collate) |
| 324 | 329 | { |
| 325 | 330 | install(new collate_byname<char>(name)); |
| ... | ... | @@ -380,7 +385,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 380 | 385 | install(new messages_byname<wchar_t>(name)); |
| 381 | 386 | #endif |
| 382 | 387 | } |
| 383 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 388 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 384 | 389 | } |
| 385 | 390 | catch (...) |
| 386 | 391 | { |
| ... | ... | @@ -389,7 +394,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 389 | 394 | facets_[i]->__release_shared(); |
| 390 | 395 | throw; |
| 391 | 396 | } |
| 392 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 397 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 393 | 398 | } |
| 394 | 399 | |
| 395 | 400 | template<class F> |
| ... | ... | @@ -402,17 +407,16 @@ locale::__imp::install_from(const locale::__imp& one) |
| 402 | 407 | } |
| 403 | 408 | |
| 404 | 409 | locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c) |
| 405 | : facets_(N), | |
| 406 | name_("*") | |
| 410 | : facets_(N), name_(build_name(other.name_, one.name_, c)) | |
| 407 | 411 | { |
| 408 | 412 | facets_ = other.facets_; |
| 409 | 413 | for (unsigned i = 0; i < facets_.size(); ++i) |
| 410 | 414 | if (facets_[i]) |
| 411 | 415 | facets_[i]->__add_shared(); |
| 412 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 416 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 413 | 417 | try |
| 414 | 418 | { |
| 415 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 419 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 416 | 420 | if (c & locale::collate) |
| 417 | 421 | { |
| 418 | 422 | install_from<_VSTD::collate<char> >(one); |
| ... | ... | @@ -489,7 +493,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 489 | 493 | install_from<_VSTD::messages<wchar_t> >(one); |
| 490 | 494 | #endif |
| 491 | 495 | } |
| 492 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 496 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 493 | 497 | } |
| 494 | 498 | catch (...) |
| 495 | 499 | { |
| ... | ... | @@ -498,7 +502,7 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP |
| 498 | 502 | facets_[i]->__release_shared(); |
| 499 | 503 | throw; |
| 500 | 504 | } |
| 501 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 505 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 502 | 506 | } |
| 503 | 507 | |
| 504 | 508 | locale::__imp::__imp(const __imp& other, facet* f, long id) |
| ... | ... | @@ -1189,8 +1193,6 @@ ctype<char>::classic_table() noexcept |
| 1189 | 1193 | return _C_ctype_tab_ + 1; |
| 1190 | 1194 | #elif defined(__GLIBC__) |
| 1191 | 1195 | return _LIBCPP_GET_C_LOCALE->__ctype_b; |
| 1192 | #elif defined(__sun__) | |
| 1193 | return __ctype_mask; | |
| 1194 | 1196 | #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) |
| 1195 | 1197 | return __pctype_func(); |
| 1196 | 1198 | #elif defined(__EMSCRIPTEN__) |
| ... | ... | @@ -1411,10 +1413,8 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* |
| 1411 | 1413 | if (iswxdigit_l(ch, __l_)) |
| 1412 | 1414 | *vec |= xdigit; |
| 1413 | 1415 | #endif |
| 1414 | #if !defined(__sun__) | |
| 1415 | 1416 | if (iswblank_l(ch, __l_)) |
| 1416 | 1417 | *vec |= blank; |
| 1417 | #endif | |
| 1418 | 1418 | } |
| 1419 | 1419 | } |
| 1420 | 1420 | return low; |
| ... | ... | @@ -6529,11 +6529,10 @@ void __do_nothing(void*) {} |
| 6529 | 6529 | |
| 6530 | 6530 | void __throw_runtime_error(const char* msg) |
| 6531 | 6531 | { |
| 6532 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 6532 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 6533 | 6533 | throw runtime_error(msg); |
| 6534 | 6534 | #else |
| 6535 | (void)msg; | |
| 6536 | _VSTD::abort(); | |
| 6535 | _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg); | |
| 6537 | 6536 | #endif |
| 6538 | 6537 | } |
| 6539 | 6538 |
lib/libcxx/src/memory.cpp-2| ... | ... | @@ -25,8 +25,6 @@ |
| 25 | 25 | |
| 26 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 27 | 27 | |
| 28 | const allocator_arg_t allocator_arg = allocator_arg_t(); | |
| 29 | ||
| 30 | 28 | bad_weak_ptr::~bad_weak_ptr() noexcept {} |
| 31 | 29 | |
| 32 | 30 | const char* |
lib/libcxx/src/memory_resource.cpp+8-7| ... | ... | @@ -37,7 +37,7 @@ static bool is_aligned_to(void* ptr, size_t align) { |
| 37 | 37 | } |
| 38 | 38 | #endif |
| 39 | 39 | |
| 40 | class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource { | |
| 40 | class _LIBCPP_EXPORTED_FROM_ABI __new_delete_memory_resource_imp : public memory_resource { | |
| 41 | 41 | void* do_allocate(size_t bytes, size_t align) override { |
| 42 | 42 | #ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION |
| 43 | 43 | return std::__libcpp_allocate(bytes, align); |
| ... | ... | @@ -60,7 +60,7 @@ class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp : public memory_resource |
| 60 | 60 | |
| 61 | 61 | // null_memory_resource() |
| 62 | 62 | |
| 63 | class _LIBCPP_TYPE_VIS __null_memory_resource_imp : public memory_resource { | |
| 63 | class _LIBCPP_EXPORTED_FROM_ABI __null_memory_resource_imp : public memory_resource { | |
| 64 | 64 | void* do_allocate(size_t, size_t) override { __throw_bad_alloc(); } |
| 65 | 65 | void do_deallocate(void*, size_t, size_t) override {} |
| 66 | 66 | bool do_is_equal(const memory_resource& other) const noexcept override { return &other == this; } |
| ... | ... | @@ -107,7 +107,7 @@ static memory_resource* __default_memory_resource(bool set = false, memory_resou |
| 107 | 107 | new_res = new_res ? new_res : new_delete_resource(); |
| 108 | 108 | lock_guard<mutex> guard(res_lock); |
| 109 | 109 | memory_resource* old_res = res; |
| 110 | res = new_res; | |
| 110 | res = new_res; | |
| 111 | 111 | return old_res; |
| 112 | 112 | } else { |
| 113 | 113 | lock_guard<mutex> guard(res_lock); |
| ... | ... | @@ -175,7 +175,7 @@ void* unsynchronized_pool_resource::__adhoc_pool::__do_allocate(memory_resource* |
| 175 | 175 | |
| 176 | 176 | void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate( |
| 177 | 177 | memory_resource* upstream, void* p, size_t bytes, size_t align) { |
| 178 | _LIBCPP_ASSERT(__first_ != nullptr, "deallocating a block that was not allocated with this allocator"); | |
| 178 | _LIBCPP_ASSERT_UNCATEGORIZED(__first_ != nullptr, "deallocating a block that was not allocated with this allocator"); | |
| 179 | 179 | if (__first_->__start_ == p) { |
| 180 | 180 | __chunk_footer* next = __first_->__next_; |
| 181 | 181 | upstream->deallocate(p, __first_->__allocation_size(), __first_->__align_); |
| ... | ... | @@ -189,7 +189,7 @@ void unsynchronized_pool_resource::__adhoc_pool::__do_deallocate( |
| 189 | 189 | return; |
| 190 | 190 | } |
| 191 | 191 | } |
| 192 | _LIBCPP_ASSERT(false, "deallocating a block that was not allocated with this allocator"); | |
| 192 | _LIBCPP_ASSERT_UNCATEGORIZED(false, "deallocating a block that was not allocated with this allocator"); | |
| 193 | 193 | } |
| 194 | 194 | } |
| 195 | 195 | |
| ... | ... | @@ -230,7 +230,7 @@ public: |
| 230 | 230 | } |
| 231 | 231 | |
| 232 | 232 | void* __allocate_in_new_chunk(memory_resource* upstream, size_t block_size, size_t chunk_size) { |
| 233 | _LIBCPP_ASSERT(chunk_size % block_size == 0, ""); | |
| 233 | _LIBCPP_ASSERT_UNCATEGORIZED(chunk_size % block_size == 0, ""); | |
| 234 | 234 | static_assert(__default_alignment >= alignof(std::max_align_t), ""); |
| 235 | 235 | static_assert(__default_alignment >= alignof(__chunk_footer), ""); |
| 236 | 236 | static_assert(__default_alignment >= alignof(__vacancy_header), ""); |
| ... | ... | @@ -401,7 +401,8 @@ void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t a |
| 401 | 401 | if (i == __num_fixed_pools_) |
| 402 | 402 | return __adhoc_pool_.__do_deallocate(__res_, p, bytes, align); |
| 403 | 403 | else { |
| 404 | _LIBCPP_ASSERT(__fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator"); | |
| 404 | _LIBCPP_ASSERT_UNCATEGORIZED( | |
| 405 | __fixed_pools_ != nullptr, "deallocating a block that was not allocated with this allocator"); | |
| 405 | 406 | __fixed_pools_[i].__evacuate(p); |
| 406 | 407 | } |
| 407 | 408 | } |
lib/libcxx/src/mutex.cpp+12-16| ... | ... | @@ -7,9 +7,9 @@ |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | 9 | #include <__assert> |
| 10 | #include <__thread/id.h> | |
| 10 | 11 | #include <limits> |
| 11 | 12 | #include <mutex> |
| 12 | #include <system_error> | |
| 13 | 13 | |
| 14 | 14 | #include "include/atomic_support.h" |
| 15 | 15 | |
| ... | ... | @@ -26,10 +26,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 26 | 26 | |
| 27 | 27 | #ifndef _LIBCPP_HAS_NO_THREADS |
| 28 | 28 | |
| 29 | const defer_lock_t defer_lock{}; | |
| 30 | const try_to_lock_t try_to_lock{}; | |
| 31 | const adopt_lock_t adopt_lock{}; | |
| 32 | ||
| 33 | 29 | // ~mutex is defined elsewhere |
| 34 | 30 | |
| 35 | 31 | void |
| ... | ... | @@ -51,7 +47,7 @@ mutex::unlock() noexcept |
| 51 | 47 | { |
| 52 | 48 | int ec = __libcpp_mutex_unlock(&__m_); |
| 53 | 49 | (void)ec; |
| 54 | _LIBCPP_ASSERT(ec == 0, "call to mutex::unlock failed"); | |
| 50 | _LIBCPP_ASSERT_UNCATEGORIZED(ec == 0, "call to mutex::unlock failed"); | |
| 55 | 51 | } |
| 56 | 52 | |
| 57 | 53 | // recursive_mutex |
| ... | ... | @@ -67,7 +63,7 @@ recursive_mutex::~recursive_mutex() |
| 67 | 63 | { |
| 68 | 64 | int e = __libcpp_recursive_mutex_destroy(&__m_); |
| 69 | 65 | (void)e; |
| 70 | _LIBCPP_ASSERT(e == 0, "call to ~recursive_mutex() failed"); | |
| 66 | _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to ~recursive_mutex() failed"); | |
| 71 | 67 | } |
| 72 | 68 | |
| 73 | 69 | void |
| ... | ... | @@ -83,7 +79,7 @@ recursive_mutex::unlock() noexcept |
| 83 | 79 | { |
| 84 | 80 | int e = __libcpp_recursive_mutex_unlock(&__m_); |
| 85 | 81 | (void)e; |
| 86 | _LIBCPP_ASSERT(e == 0, "call to recursive_mutex::unlock() failed"); | |
| 82 | _LIBCPP_ASSERT_UNCATEGORIZED(e == 0, "call to recursive_mutex::unlock() failed"); | |
| 87 | 83 | } |
| 88 | 84 | |
| 89 | 85 | bool |
| ... | ... | @@ -211,21 +207,21 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, |
| 211 | 207 | #if defined(_LIBCPP_HAS_NO_THREADS) |
| 212 | 208 | if (flag == 0) |
| 213 | 209 | { |
| 214 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 210 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 215 | 211 | try |
| 216 | 212 | { |
| 217 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 213 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 218 | 214 | flag = 1; |
| 219 | 215 | func(arg); |
| 220 | 216 | flag = ~once_flag::_State_type(0); |
| 221 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 217 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 222 | 218 | } |
| 223 | 219 | catch (...) |
| 224 | 220 | { |
| 225 | 221 | flag = 0; |
| 226 | 222 | throw; |
| 227 | 223 | } |
| 228 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 224 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 229 | 225 | } |
| 230 | 226 | #else // !_LIBCPP_HAS_NO_THREADS |
| 231 | 227 | __libcpp_mutex_lock(&mut); |
| ... | ... | @@ -233,10 +229,10 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, |
| 233 | 229 | __libcpp_condvar_wait(&cv, &mut); |
| 234 | 230 | if (flag == 0) |
| 235 | 231 | { |
| 236 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 232 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 237 | 233 | try |
| 238 | 234 | { |
| 239 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 235 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 240 | 236 | __libcpp_relaxed_store(&flag, once_flag::_State_type(1)); |
| 241 | 237 | __libcpp_mutex_unlock(&mut); |
| 242 | 238 | func(arg); |
| ... | ... | @@ -245,7 +241,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, |
| 245 | 241 | _AO_Release); |
| 246 | 242 | __libcpp_mutex_unlock(&mut); |
| 247 | 243 | __libcpp_condvar_broadcast(&cv); |
| 248 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 244 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 249 | 245 | } |
| 250 | 246 | catch (...) |
| 251 | 247 | { |
| ... | ... | @@ -255,7 +251,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg, |
| 255 | 251 | __libcpp_condvar_broadcast(&cv); |
| 256 | 252 | throw; |
| 257 | 253 | } |
| 258 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 254 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 259 | 255 | } |
| 260 | 256 | else |
| 261 | 257 | __libcpp_mutex_unlock(&mut); |
lib/libcxx/src/mutex_destructor.cpp+1-1| ... | ... | @@ -28,7 +28,7 @@ |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 29 | 29 | |
| 30 | 30 | #ifdef NEEDS_MUTEX_DESTRUCTOR |
| 31 | class _LIBCPP_TYPE_VIS mutex | |
| 31 | class _LIBCPP_EXPORTED_FROM_ABI mutex | |
| 32 | 32 | { |
| 33 | 33 | __libcpp_mutex_t __m_ = _LIBCPP_MUTEX_INITIALIZER; |
| 34 | 34 |
lib/libcxx/src/new.cpp+29-64| ... | ... | @@ -6,53 +6,16 @@ |
| 6 | 6 | // |
| 7 | 7 | //===----------------------------------------------------------------------===// |
| 8 | 8 | |
| 9 | #include <__memory/aligned_alloc.h> | |
| 10 | #include <cstdlib> | |
| 9 | 11 | #include <new> |
| 10 | #include <stdlib.h> | |
| 11 | 12 | |
| 12 | #include "include/atomic_support.h" | |
| 13 | #if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME) | |
| 13 | 14 | |
| 14 | #if defined(_LIBCPP_ABI_MICROSOFT) | |
| 15 | # if !defined(_LIBCPP_ABI_VCRUNTIME) | |
| 16 | # include "support/runtime/new_handler_fallback.ipp" | |
| 17 | # endif | |
| 18 | #elif defined(LIBCXX_BUILDING_LIBCXXABI) | |
| 19 | # include <cxxabi.h> | |
| 20 | #elif defined(LIBCXXRT) | |
| 21 | # include <cxxabi.h> | |
| 22 | # include "support/runtime/new_handler_fallback.ipp" | |
| 23 | #elif defined(__GLIBCXX__) | |
| 24 | // nothing to do | |
| 25 | #else | |
| 26 | # include "support/runtime/new_handler_fallback.ipp" | |
| 27 | #endif | |
| 28 | ||
| 29 | namespace std | |
| 30 | { | |
| 31 | ||
| 32 | #ifndef __GLIBCXX__ | |
| 33 | const nothrow_t nothrow{}; | |
| 34 | #endif | |
| 35 | ||
| 36 | #ifndef LIBSTDCXX | |
| 37 | ||
| 38 | void | |
| 39 | __throw_bad_alloc() | |
| 40 | { | |
| 41 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 42 | throw bad_alloc(); | |
| 43 | #else | |
| 44 | _VSTD::abort(); | |
| 45 | #endif | |
| 46 | } | |
| 47 | ||
| 48 | #endif // !LIBSTDCXX | |
| 49 | ||
| 50 | } // std | |
| 51 | ||
| 52 | #if !defined(__GLIBCXX__) && \ | |
| 53 | !defined(_LIBCPP_ABI_VCRUNTIME) && \ | |
| 54 | !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) | |
| 15 | // The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp | |
| 16 | // file. The version in this file is the canonical one. | |
| 55 | 17 | |
| 18 | // ------------------ BEGIN COPY ------------------ | |
| 56 | 19 | // Implement all new and delete operators as weak definitions |
| 57 | 20 | // in this shared library, so that they can be overridden by programs |
| 58 | 21 | // that define non-weak copies of the functions. |
| ... | ... | @@ -64,7 +27,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC |
| 64 | 27 | if (size == 0) |
| 65 | 28 | size = 1; |
| 66 | 29 | void* p; |
| 67 | while ((p = ::malloc(size)) == nullptr) | |
| 30 | while ((p = std::malloc(size)) == nullptr) | |
| 68 | 31 | { |
| 69 | 32 | // If malloc fails and there is a new_handler, |
| 70 | 33 | // call it to try free up memory. |
| ... | ... | @@ -72,7 +35,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC |
| 72 | 35 | if (nh) |
| 73 | 36 | nh(); |
| 74 | 37 | else |
| 75 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 38 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 76 | 39 | throw std::bad_alloc(); |
| 77 | 40 | #else |
| 78 | 41 | break; |
| ... | ... | @@ -86,17 +49,17 @@ void* |
| 86 | 49 | operator new(size_t size, const std::nothrow_t&) noexcept |
| 87 | 50 | { |
| 88 | 51 | void* p = nullptr; |
| 89 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 52 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 90 | 53 | try |
| 91 | 54 | { |
| 92 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 55 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 93 | 56 | p = ::operator new(size); |
| 94 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 57 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 95 | 58 | } |
| 96 | 59 | catch (...) |
| 97 | 60 | { |
| 98 | 61 | } |
| 99 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 62 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 100 | 63 | return p; |
| 101 | 64 | } |
| 102 | 65 | |
| ... | ... | @@ -112,17 +75,17 @@ void* |
| 112 | 75 | operator new[](size_t size, const std::nothrow_t&) noexcept |
| 113 | 76 | { |
| 114 | 77 | void* p = nullptr; |
| 115 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 78 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 116 | 79 | try |
| 117 | 80 | { |
| 118 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 81 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 119 | 82 | p = ::operator new[](size); |
| 120 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 83 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 121 | 84 | } |
| 122 | 85 | catch (...) |
| 123 | 86 | { |
| 124 | 87 | } |
| 125 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 88 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 126 | 89 | return p; |
| 127 | 90 | } |
| 128 | 91 | |
| ... | ... | @@ -130,7 +93,7 @@ _LIBCPP_WEAK |
| 130 | 93 | void |
| 131 | 94 | operator delete(void* ptr) noexcept |
| 132 | 95 | { |
| 133 | ::free(ptr); | |
| 96 | std::free(ptr); | |
| 134 | 97 | } |
| 135 | 98 | |
| 136 | 99 | _LIBCPP_WEAK |
| ... | ... | @@ -192,7 +155,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC |
| 192 | 155 | if (nh) |
| 193 | 156 | nh(); |
| 194 | 157 | else { |
| 195 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 158 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 196 | 159 | throw std::bad_alloc(); |
| 197 | 160 | #else |
| 198 | 161 | break; |
| ... | ... | @@ -207,17 +170,17 @@ void* |
| 207 | 170 | operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 208 | 171 | { |
| 209 | 172 | void* p = nullptr; |
| 210 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 173 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 211 | 174 | try |
| 212 | 175 | { |
| 213 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 176 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 214 | 177 | p = ::operator new(size, alignment); |
| 215 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 178 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 216 | 179 | } |
| 217 | 180 | catch (...) |
| 218 | 181 | { |
| 219 | 182 | } |
| 220 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 183 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 221 | 184 | return p; |
| 222 | 185 | } |
| 223 | 186 | |
| ... | ... | @@ -233,17 +196,17 @@ void* |
| 233 | 196 | operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept |
| 234 | 197 | { |
| 235 | 198 | void* p = nullptr; |
| 236 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 199 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 237 | 200 | try |
| 238 | 201 | { |
| 239 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 202 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 240 | 203 | p = ::operator new[](size, alignment); |
| 241 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 204 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 242 | 205 | } |
| 243 | 206 | catch (...) |
| 244 | 207 | { |
| 245 | 208 | } |
| 246 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 209 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 247 | 210 | return p; |
| 248 | 211 | } |
| 249 | 212 | |
| ... | ... | @@ -290,4 +253,6 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) noexcept |
| 290 | 253 | } |
| 291 | 254 | |
| 292 | 255 | #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION |
| 293 | #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS | |
| 256 | // ------------------ END COPY ------------------ | |
| 257 | ||
| 258 | #endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME |
lib/libcxx/src/new_handler.cpp created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <new> | |
| 10 | ||
| 11 | #include "include/atomic_support.h" | |
| 12 | ||
| 13 | #if defined(_LIBCPP_ABI_MICROSOFT) | |
| 14 | # if !defined(_LIBCPP_ABI_VCRUNTIME) | |
| 15 | # define _LIBPCPP_DEFINE_NEW_HANDLER | |
| 16 | # endif | |
| 17 | #elif defined(LIBCXX_BUILDING_LIBCXXABI) | |
| 18 | // nothing to do, we use the one from libc++abi | |
| 19 | #elif defined(LIBCXXRT) | |
| 20 | # define _LIBPCPP_DEFINE_NEW_HANDLER | |
| 21 | #elif defined(__GLIBCXX__) | |
| 22 | // nothing to do, we use the one from libstdc++/libsupc++ | |
| 23 | #else | |
| 24 | # define _LIBPCPP_DEFINE_NEW_HANDLER | |
| 25 | #endif | |
| 26 | ||
| 27 | #if defined(_LIBPCPP_DEFINE_NEW_HANDLER) | |
| 28 | ||
| 29 | namespace std { // purposefully not versioned | |
| 30 | ||
| 31 | static constinit std::new_handler __new_handler = nullptr; | |
| 32 | ||
| 33 | new_handler set_new_handler(new_handler handler) noexcept { return __libcpp_atomic_exchange(&__new_handler, handler); } | |
| 34 | ||
| 35 | new_handler get_new_handler() noexcept { return __libcpp_atomic_load(&__new_handler); } | |
| 36 | ||
| 37 | } // namespace std | |
| 38 | ||
| 39 | #endif // _LIBPCPP_DEFINE_NEW_HANDLER |
lib/libcxx/src/new_helpers.cpp created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <cstdlib> | |
| 10 | #include <new> | |
| 11 | ||
| 12 | namespace std { // purposefully not versioned | |
| 13 | ||
| 14 | #ifndef __GLIBCXX__ | |
| 15 | const nothrow_t nothrow{}; | |
| 16 | #endif | |
| 17 | ||
| 18 | #ifndef LIBSTDCXX | |
| 19 | ||
| 20 | void __throw_bad_alloc() { | |
| 21 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 22 | throw bad_alloc(); | |
| 23 | # else | |
| 24 | std::abort(); | |
| 25 | # endif | |
| 26 | } | |
| 27 | ||
| 28 | #endif // !LIBSTDCXX | |
| 29 | ||
| 30 | } // namespace std |
lib/libcxx/src/optional.cpp+1-1| ... | ... | @@ -27,7 +27,7 @@ const char* bad_optional_access::what() const noexcept { |
| 27 | 27 | // Even though it no longer exists in a header file |
| 28 | 28 | _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL |
| 29 | 29 | |
| 30 | class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access | |
| 30 | class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access | |
| 31 | 31 | : public std::logic_error |
| 32 | 32 | { |
| 33 | 33 | public: |
lib/libcxx/src/print.cpp created+62| ... | ... | @@ -0,0 +1,62 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__config> | |
| 10 | #include <cstdlib> | |
| 11 | #include <print> | |
| 12 | ||
| 13 | #if defined(_LIBCPP_WIN32API) | |
| 14 | # define WIN32_LEAN_AND_MEAN | |
| 15 | # define NOMINMAX | |
| 16 | # include <io.h> | |
| 17 | # include <windows.h> | |
| 18 | ||
| 19 | # include <__system_error/system_error.h> | |
| 20 | ||
| 21 | # include "filesystem/error.h" | |
| 22 | #endif | |
| 23 | ||
| 24 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 25 | ||
| 26 | #ifdef _WIN32 | |
| 27 | _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream) { | |
| 28 | // Note the Standard does this in one call, but it's unclear whether | |
| 29 | // an invalid handle is allowed when calling GetConsoleMode. | |
| 30 | // | |
| 31 | // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle?view=msvc-170 | |
| 32 | // https://learn.microsoft.com/en-us/windows/console/getconsolemode | |
| 33 | intptr_t __handle = _get_osfhandle(fileno(__stream)); | |
| 34 | if (__handle == -1) | |
| 35 | return false; | |
| 36 | ||
| 37 | unsigned long __mode; | |
| 38 | return GetConsoleMode(reinterpret_cast<void*>(__handle), &__mode); | |
| 39 | } | |
| 40 | ||
| 41 | # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 42 | _LIBCPP_EXPORTED_FROM_ABI void | |
| 43 | __write_to_windows_console([[maybe_unused]] FILE* __stream, [[maybe_unused]] wstring_view __view) { | |
| 44 | // https://learn.microsoft.com/en-us/windows/console/writeconsole | |
| 45 | if (WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fileno(__stream))), // clang-format aid | |
| 46 | __view.data(), | |
| 47 | __view.size(), | |
| 48 | nullptr, | |
| 49 | nullptr) == 0) { | |
| 50 | # ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 51 | // There is no __throw_system_error overload that takes an error code. | |
| 52 | throw system_error{filesystem::detail::make_windows_error(GetLastError()), "failed to write formatted output"}; | |
| 53 | # else // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 54 | std::abort(); | |
| 55 | # endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 56 | } | |
| 57 | } | |
| 58 | # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 59 | ||
| 60 | #endif // _WIN32 | |
| 61 | ||
| 62 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/pstl/libdispatch.cpp created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <__algorithm/min.h> | |
| 10 | #include <__algorithm/pstl_backends/cpu_backends/libdispatch.h> | |
| 11 | #include <__config> | |
| 12 | #include <dispatch/dispatch.h> | |
| 13 | #include <thread> | |
| 14 | ||
| 15 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 16 | ||
| 17 | namespace __par_backend::inline __libdispatch { | |
| 18 | ||
| 19 | ||
| 20 | void __dispatch_apply(size_t chunk_count, void* context, void (*func)(void* context, size_t chunk)) noexcept { | |
| 21 | ::dispatch_apply_f(chunk_count, DISPATCH_APPLY_AUTO, context, func); | |
| 22 | } | |
| 23 | ||
| 24 | __chunk_partitions __partition_chunks(ptrdiff_t element_count) { | |
| 25 | if (element_count == 0) { | |
| 26 | return __chunk_partitions{1, 0, 0}; | |
| 27 | } else if (element_count == 1) { | |
| 28 | return __chunk_partitions{1, 0, 1}; | |
| 29 | } | |
| 30 | ||
| 31 | __chunk_partitions partitions; | |
| 32 | partitions.__chunk_count_ = [&] { | |
| 33 | ptrdiff_t cores = std::max(1u, thread::hardware_concurrency()); | |
| 34 | ||
| 35 | auto medium = [&](ptrdiff_t n) { return cores + ((n - cores) / cores); }; | |
| 36 | ||
| 37 | // This is an approximation of `log(1.01, sqrt(n))` which seemes to be reasonable for `n` larger than 500 and tops | |
| 38 | // at 800 tasks for n ~ 8 million | |
| 39 | auto large = [](ptrdiff_t n) { return static_cast<ptrdiff_t>(100.499 * std::log(std::sqrt(n))); }; | |
| 40 | ||
| 41 | if (element_count < cores) | |
| 42 | return element_count; | |
| 43 | else if (element_count < 500) | |
| 44 | return medium(element_count); | |
| 45 | else | |
| 46 | return std::min(medium(element_count), large(element_count)); // provide a "smooth" transition | |
| 47 | }(); | |
| 48 | partitions.__chunk_size_ = element_count / partitions.__chunk_count_; | |
| 49 | partitions.__first_chunk_size_ = partitions.__chunk_size_; | |
| 50 | ||
| 51 | const ptrdiff_t leftover_item_count = element_count - (partitions.__chunk_count_ * partitions.__chunk_size_); | |
| 52 | ||
| 53 | if (leftover_item_count == 0) | |
| 54 | return partitions; | |
| 55 | ||
| 56 | if (leftover_item_count == partitions.__chunk_size_) { | |
| 57 | partitions.__chunk_count_ += 1; | |
| 58 | return partitions; | |
| 59 | } | |
| 60 | ||
| 61 | const ptrdiff_t n_extra_items_per_chunk = leftover_item_count / partitions.__chunk_count_; | |
| 62 | const ptrdiff_t n_final_leftover_items = leftover_item_count - (n_extra_items_per_chunk * partitions.__chunk_count_); | |
| 63 | ||
| 64 | partitions.__chunk_size_ += n_extra_items_per_chunk; | |
| 65 | partitions.__first_chunk_size_ = partitions.__chunk_size_ + n_final_leftover_items; | |
| 66 | return partitions; | |
| 67 | } | |
| 68 | ||
| 69 | // NOLINTNEXTLINE(llvm-namespace-comment) // This is https://llvm.org/PR56804 | |
| 70 | } // namespace __par_backend::inline __libdispatch | |
| 71 | ||
| 72 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/random.cpp+1-5| ... | ... | @@ -13,13 +13,9 @@ |
| 13 | 13 | # define _CRT_RAND_S |
| 14 | 14 | #endif // defined(_LIBCPP_USING_WIN32_RANDOM) |
| 15 | 15 | |
| 16 | #include <__system_error/system_error.h> | |
| 16 | 17 | #include <limits> |
| 17 | 18 | #include <random> |
| 18 | #include <system_error> | |
| 19 | ||
| 20 | #if defined(__sun__) | |
| 21 | # define rename solaris_headers_are_broken | |
| 22 | #endif // defined(__sun__) | |
| 23 | 19 | |
| 24 | 20 | #include <errno.h> |
| 25 | 21 | #include <stdio.h> |
lib/libcxx/src/ryu/d2fixed.cpp+23-24| ... | ... | @@ -43,7 +43,6 @@ |
| 43 | 43 | #include <__config> |
| 44 | 44 | #include <charconv> |
| 45 | 45 | #include <cstring> |
| 46 | #include <system_error> | |
| 47 | 46 | |
| 48 | 47 | #include "include/ryu/common.h" |
| 49 | 48 | #include "include/ryu/d2fixed.h" |
| ... | ... | @@ -103,8 +102,8 @@ inline constexpr int __POW10_ADDITIONAL_BITS = 120; |
| 103 | 102 | const uint64_t __s1low = __low2 + __high1 + __c1; // 128 |
| 104 | 103 | const uint32_t __c2 = __s1low < __low2; // __high1 + __c1 can't overflow, so compare against __low2 |
| 105 | 104 | const uint64_t __s1high = __high2 + __c2; // 192 |
| 106 | _LIBCPP_ASSERT(__j >= 128, ""); | |
| 107 | _LIBCPP_ASSERT(__j <= 180, ""); | |
| 105 | _LIBCPP_ASSERT_UNCATEGORIZED(__j >= 128, ""); | |
| 106 | _LIBCPP_ASSERT_UNCATEGORIZED(__j <= 180, ""); | |
| 108 | 107 | #ifdef _LIBCPP_INTRINSIC128 |
| 109 | 108 | const uint32_t __dist = static_cast<uint32_t>(__j - 128); // __dist: [0, 52] |
| 110 | 109 | const uint64_t __shiftedhigh = __s1high >> __dist; |
| ... | ... | @@ -135,19 +134,19 @@ void __append_n_digits(const uint32_t __olength, uint32_t __digits, char* const |
| 135 | 134 | __digits /= 10000; |
| 136 | 135 | const uint32_t __c0 = (__c % 100) << 1; |
| 137 | 136 | const uint32_t __c1 = (__c / 100) << 1; |
| 138 | _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2); | |
| 139 | _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2); | |
| 137 | std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2); | |
| 138 | std::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2); | |
| 140 | 139 | __i += 4; |
| 141 | 140 | } |
| 142 | 141 | if (__digits >= 100) { |
| 143 | 142 | const uint32_t __c = (__digits % 100) << 1; |
| 144 | 143 | __digits /= 100; |
| 145 | _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 144 | std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 146 | 145 | __i += 2; |
| 147 | 146 | } |
| 148 | 147 | if (__digits >= 10) { |
| 149 | 148 | const uint32_t __c = __digits << 1; |
| 150 | _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 149 | std::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 151 | 150 | } else { |
| 152 | 151 | __result[0] = static_cast<char>('0' + __digits); |
| 153 | 152 | } |
| ... | ... | @@ -164,14 +163,14 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_d_digits(const uint32_t __olength, ui |
| 164 | 163 | __digits /= 10000; |
| 165 | 164 | const uint32_t __c0 = (__c % 100) << 1; |
| 166 | 165 | const uint32_t __c1 = (__c / 100) << 1; |
| 167 | _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2); | |
| 168 | _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2); | |
| 166 | std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2); | |
| 167 | std::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2); | |
| 169 | 168 | __i += 4; |
| 170 | 169 | } |
| 171 | 170 | if (__digits >= 100) { |
| 172 | 171 | const uint32_t __c = (__digits % 100) << 1; |
| 173 | 172 | __digits /= 100; |
| 174 | _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 173 | std::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 175 | 174 | __i += 2; |
| 176 | 175 | } |
| 177 | 176 | if (__digits >= 10) { |
| ... | ... | @@ -190,7 +189,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint |
| 190 | 189 | for (; __i < __count - 1; __i += 2) { |
| 191 | 190 | const uint32_t __c = (__digits % 100) << 1; |
| 192 | 191 | __digits /= 100; |
| 193 | _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 192 | std::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2); | |
| 194 | 193 | } |
| 195 | 194 | if (__i < __count) { |
| 196 | 195 | const char __c = static_cast<char>('0' + (__digits % 10)); |
| ... | ... | @@ -200,7 +199,7 @@ _LIBCPP_HIDE_FROM_ABI inline void __append_c_digits(const uint32_t __count, uint |
| 200 | 199 | |
| 201 | 200 | void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 202 | 201 | if (__digits == 0) { |
| 203 | _VSTD::memset(__result, '0', 9); | |
| 202 | std::memset(__result, '0', 9); | |
| 204 | 203 | return; |
| 205 | 204 | } |
| 206 | 205 | |
| ... | ... | @@ -213,8 +212,8 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 213 | 212 | __digits /= 10000; |
| 214 | 213 | const uint32_t __c0 = (__c % 100) << 1; |
| 215 | 214 | const uint32_t __c1 = (__c / 100) << 1; |
| 216 | _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2); | |
| 217 | _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2); | |
| 215 | std::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2); | |
| 216 | std::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2); | |
| 218 | 217 | } |
| 219 | 218 | __result[0] = static_cast<char>('0' + __digits); |
| 220 | 219 | } |
| ... | ... | @@ -251,7 +250,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 251 | 250 | *_First++ = '0'; |
| 252 | 251 | if (__precision > 0) { |
| 253 | 252 | *_First++ = '.'; |
| 254 | _VSTD::memset(_First, '0', __precision); | |
| 253 | std::memset(_First, '0', __precision); | |
| 255 | 254 | _First += __precision; |
| 256 | 255 | } |
| 257 | 256 | return { _First, errc{} }; |
| ... | ... | @@ -322,14 +321,14 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 322 | 321 | if (_Last - _First < static_cast<ptrdiff_t>(__precision)) { |
| 323 | 322 | return { _Last, errc::value_too_large }; |
| 324 | 323 | } |
| 325 | _VSTD::memset(_First, '0', __precision); | |
| 324 | std::memset(_First, '0', __precision); | |
| 326 | 325 | _First += __precision; |
| 327 | 326 | } else if (__i < __MIN_BLOCK_2[__idx]) { |
| 328 | 327 | __i = __MIN_BLOCK_2[__idx]; |
| 329 | 328 | if (_Last - _First < static_cast<ptrdiff_t>(9 * __i)) { |
| 330 | 329 | return { _Last, errc::value_too_large }; |
| 331 | 330 | } |
| 332 | _VSTD::memset(_First, '0', 9 * __i); | |
| 331 | std::memset(_First, '0', 9 * __i); | |
| 333 | 332 | _First += 9 * __i; |
| 334 | 333 | } |
| 335 | 334 | for (; __i < __blocks; ++__i) { |
| ... | ... | @@ -342,7 +341,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 342 | 341 | if (_Last - _First < static_cast<ptrdiff_t>(__fill)) { |
| 343 | 342 | return { _Last, errc::value_too_large }; |
| 344 | 343 | } |
| 345 | _VSTD::memset(_First, '0', __fill); | |
| 344 | std::memset(_First, '0', __fill); | |
| 346 | 345 | _First += __fill; |
| 347 | 346 | break; |
| 348 | 347 | } |
| ... | ... | @@ -416,7 +415,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 416 | 415 | if (_Last - _First < static_cast<ptrdiff_t>(__precision)) { |
| 417 | 416 | return { _Last, errc::value_too_large }; |
| 418 | 417 | } |
| 419 | _VSTD::memset(_First, '0', __precision); | |
| 418 | std::memset(_First, '0', __precision); | |
| 420 | 419 | _First += __precision; |
| 421 | 420 | } |
| 422 | 421 | return { _First, errc{} }; |
| ... | ... | @@ -440,10 +439,10 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 440 | 439 | *_First++ = '0'; |
| 441 | 440 | if (__precision > 0) { |
| 442 | 441 | *_First++ = '.'; |
| 443 | _VSTD::memset(_First, '0', __precision); | |
| 442 | std::memset(_First, '0', __precision); | |
| 444 | 443 | _First += __precision; |
| 445 | 444 | } |
| 446 | _VSTD::memcpy(_First, "e+00", 4); | |
| 445 | std::memcpy(_First, "e+00", 4); | |
| 447 | 446 | _First += 4; |
| 448 | 447 | return { _First, errc{} }; |
| 449 | 448 | } |
| ... | ... | @@ -589,7 +588,7 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 589 | 588 | return { _Last, errc::value_too_large }; |
| 590 | 589 | } |
| 591 | 590 | if (__digits == 0) { |
| 592 | _VSTD::memset(_First, '0', __maximum); | |
| 591 | std::memset(_First, '0', __maximum); | |
| 593 | 592 | } else { |
| 594 | 593 | __append_c_digits(__maximum, __digits, _First); |
| 595 | 594 | } |
| ... | ... | @@ -654,11 +653,11 @@ void __append_nine_digits(uint32_t __digits, char* const __result) { |
| 654 | 653 | |
| 655 | 654 | if (__exp >= 100) { |
| 656 | 655 | const int32_t __c = __exp % 10; |
| 657 | _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2); | |
| 656 | std::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2); | |
| 658 | 657 | _First[2] = static_cast<char>('0' + __c); |
| 659 | 658 | _First += 3; |
| 660 | 659 | } else { |
| 661 | _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2); | |
| 660 | std::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2); | |
| 662 | 661 | _First += 2; |
| 663 | 662 | } |
| 664 | 663 |
lib/libcxx/src/ryu/d2s.cpp+22-22| ... | ... | @@ -154,7 +154,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 154 | 154 | // The average output length is 16.38 digits, so we check high-to-low. |
| 155 | 155 | // Function precondition: __v is not an 18, 19, or 20-digit number. |
| 156 | 156 | // (17 digits are sufficient for round-tripping.) |
| 157 | _LIBCPP_ASSERT(__v < 100000000000000000u, ""); | |
| 157 | _LIBCPP_ASSERT_UNCATEGORIZED(__v < 100000000000000000u, ""); | |
| 158 | 158 | if (__v >= 10000000000000000u) { return 17; } |
| 159 | 159 | if (__v >= 1000000000000000u) { return 16; } |
| 160 | 160 | if (__v >= 100000000000000u) { return 15; } |
| ... | ... | @@ -527,10 +527,10 @@ struct __floating_decimal_64 { |
| 527 | 527 | const uint32_t __d0 = (__d % 100) << 1; |
| 528 | 528 | const uint32_t __d1 = (__d / 100) << 1; |
| 529 | 529 | |
| 530 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 531 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 532 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2); | |
| 533 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2); | |
| 530 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 531 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 532 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2); | |
| 533 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2); | |
| 534 | 534 | } |
| 535 | 535 | uint32_t __output2 = static_cast<uint32_t>(_Output); |
| 536 | 536 | while (__output2 >= 10000) { |
| ... | ... | @@ -542,35 +542,35 @@ struct __floating_decimal_64 { |
| 542 | 542 | __output2 /= 10000; |
| 543 | 543 | const uint32_t __c0 = (__c % 100) << 1; |
| 544 | 544 | const uint32_t __c1 = (__c / 100) << 1; |
| 545 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 546 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 545 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 546 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 547 | 547 | } |
| 548 | 548 | if (__output2 >= 100) { |
| 549 | 549 | const uint32_t __c = (__output2 % 100) << 1; |
| 550 | 550 | __output2 /= 100; |
| 551 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 551 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 552 | 552 | } |
| 553 | 553 | if (__output2 >= 10) { |
| 554 | 554 | const uint32_t __c = __output2 << 1; |
| 555 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 555 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 556 | 556 | } else { |
| 557 | 557 | *--_Mid = static_cast<char>('0' + __output2); |
| 558 | 558 | } |
| 559 | 559 | |
| 560 | 560 | if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu |
| 561 | 561 | // Performance note: it might be more efficient to do this immediately after setting _Mid. |
| 562 | _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent)); | |
| 562 | std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent)); | |
| 563 | 563 | } else if (_Ryu_exponent == 0) { // case "1729" |
| 564 | 564 | // Done! |
| 565 | 565 | } else if (_Whole_digits > 0) { // case "17.29" |
| 566 | 566 | // Performance note: moving digits might not be optimal. |
| 567 | _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits)); | |
| 567 | std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits)); | |
| 568 | 568 | _First[_Whole_digits] = '.'; |
| 569 | 569 | } else { // case "0.001729" |
| 570 | 570 | // Performance note: a larger memset() followed by overwriting '.' might be more efficient. |
| 571 | 571 | _First[0] = '0'; |
| 572 | 572 | _First[1] = '.'; |
| 573 | _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits)); | |
| 573 | std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits)); | |
| 574 | 574 | } |
| 575 | 575 | |
| 576 | 576 | return { _First + _Total_fixed_length, errc{} }; |
| ... | ... | @@ -602,10 +602,10 @@ struct __floating_decimal_64 { |
| 602 | 602 | const uint32_t __c1 = (__c / 100) << 1; |
| 603 | 603 | const uint32_t __d0 = (__d % 100) << 1; |
| 604 | 604 | const uint32_t __d1 = (__d / 100) << 1; |
| 605 | _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 606 | _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 607 | _VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2); | |
| 608 | _VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2); | |
| 605 | std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 606 | std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 607 | std::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2); | |
| 608 | std::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2); | |
| 609 | 609 | __i += 8; |
| 610 | 610 | } |
| 611 | 611 | uint32_t __output2 = static_cast<uint32_t>(_Output); |
| ... | ... | @@ -618,14 +618,14 @@ struct __floating_decimal_64 { |
| 618 | 618 | __output2 /= 10000; |
| 619 | 619 | const uint32_t __c0 = (__c % 100) << 1; |
| 620 | 620 | const uint32_t __c1 = (__c / 100) << 1; |
| 621 | _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 622 | _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 621 | std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 622 | std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 623 | 623 | __i += 4; |
| 624 | 624 | } |
| 625 | 625 | if (__output2 >= 100) { |
| 626 | 626 | const uint32_t __c = (__output2 % 100) << 1; |
| 627 | 627 | __output2 /= 100; |
| 628 | _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); | |
| 628 | std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); | |
| 629 | 629 | __i += 2; |
| 630 | 630 | } |
| 631 | 631 | if (__output2 >= 10) { |
| ... | ... | @@ -657,11 +657,11 @@ struct __floating_decimal_64 { |
| 657 | 657 | |
| 658 | 658 | if (_Scientific_exponent >= 100) { |
| 659 | 659 | const int32_t __c = _Scientific_exponent % 10; |
| 660 | _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2); | |
| 660 | std::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2); | |
| 661 | 661 | __result[__index + 2] = static_cast<char>('0' + __c); |
| 662 | 662 | __index += 3; |
| 663 | 663 | } else { |
| 664 | _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); | |
| 664 | std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); | |
| 665 | 665 | __index += 2; |
| 666 | 666 | } |
| 667 | 667 | |
| ... | ... | @@ -713,7 +713,7 @@ struct __floating_decimal_64 { |
| 713 | 713 | return { _Last, errc::value_too_large }; |
| 714 | 714 | } |
| 715 | 715 | |
| 716 | _VSTD::memcpy(_First, "0e+00", 5); | |
| 716 | std::memcpy(_First, "0e+00", 5); | |
| 717 | 717 | |
| 718 | 718 | return { _First + 5, errc{} }; |
| 719 | 719 | } |
lib/libcxx/src/ryu/f2s.cpp+22-22| ... | ... | @@ -86,7 +86,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = { |
| 86 | 86 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __pow5Factor(uint32_t __value) { |
| 87 | 87 | uint32_t __count = 0; |
| 88 | 88 | for (;;) { |
| 89 | _LIBCPP_ASSERT(__value != 0, ""); | |
| 89 | _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, ""); | |
| 90 | 90 | const uint32_t __q = __value / 5; |
| 91 | 91 | const uint32_t __r = __value % 5; |
| 92 | 92 | if (__r != 0) { |
| ... | ... | @@ -105,14 +105,14 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = { |
| 105 | 105 | |
| 106 | 106 | // Returns true if __value is divisible by 2^__p. |
| 107 | 107 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline bool __multipleOfPowerOf2(const uint32_t __value, const uint32_t __p) { |
| 108 | _LIBCPP_ASSERT(__value != 0, ""); | |
| 109 | _LIBCPP_ASSERT(__p < 32, ""); | |
| 108 | _LIBCPP_ASSERT_UNCATEGORIZED(__value != 0, ""); | |
| 109 | _LIBCPP_ASSERT_UNCATEGORIZED(__p < 32, ""); | |
| 110 | 110 | // __builtin_ctz doesn't appear to be faster here. |
| 111 | 111 | return (__value & ((1u << __p) - 1)) == 0; |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | [[nodiscard]] _LIBCPP_HIDE_FROM_ABI inline uint32_t __mulShift(const uint32_t __m, const uint64_t __factor, const int32_t __shift) { |
| 115 | _LIBCPP_ASSERT(__shift > 32, ""); | |
| 115 | _LIBCPP_ASSERT_UNCATEGORIZED(__shift > 32, ""); | |
| 116 | 116 | |
| 117 | 117 | // The casts here help MSVC to avoid calls to the __allmul library |
| 118 | 118 | // function. |
| ... | ... | @@ -134,7 +134,7 @@ inline constexpr uint64_t __FLOAT_POW5_SPLIT[47] = { |
| 134 | 134 | #else // ^^^ 32-bit ^^^ / vvv 64-bit vvv |
| 135 | 135 | const uint64_t __sum = (__bits0 >> 32) + __bits1; |
| 136 | 136 | const uint64_t __shiftedSum = __sum >> (__shift - 32); |
| 137 | _LIBCPP_ASSERT(__shiftedSum <= UINT32_MAX, ""); | |
| 137 | _LIBCPP_ASSERT_UNCATEGORIZED(__shiftedSum <= UINT32_MAX, ""); | |
| 138 | 138 | return static_cast<uint32_t>(__shiftedSum); |
| 139 | 139 | #endif // ^^^ 64-bit ^^^ |
| 140 | 140 | } |
| ... | ... | @@ -309,8 +309,8 @@ struct __floating_decimal_32 { |
| 309 | 309 | // Performance note: Long division appears to be faster than losslessly widening float to double and calling |
| 310 | 310 | // __d2fixed_buffered_n(). If __f2fixed_buffered_n() is implemented, it might be faster than long division. |
| 311 | 311 | |
| 312 | _LIBCPP_ASSERT(_Exponent2 > 0, ""); | |
| 313 | _LIBCPP_ASSERT(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254 | |
| 312 | _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 > 0, ""); | |
| 313 | _LIBCPP_ASSERT_UNCATEGORIZED(_Exponent2 <= 104, ""); // because __ieeeExponent <= 254 | |
| 314 | 314 | |
| 315 | 315 | // Manually represent _Mantissa2 * 2^_Exponent2 as a large integer. _Mantissa2 is always 24 bits |
| 316 | 316 | // (due to the implicit bit), while _Exponent2 indicates a shift of at most 104 bits. |
| ... | ... | @@ -328,7 +328,7 @@ struct __floating_decimal_32 { |
| 328 | 328 | |
| 329 | 329 | // _Maxidx is the index of the most significant nonzero element. |
| 330 | 330 | uint32_t _Maxidx = ((24 + static_cast<uint32_t>(_Exponent2) + 31) / 32) - 1; |
| 331 | _LIBCPP_ASSERT(_Maxidx < _Data_size, ""); | |
| 331 | _LIBCPP_ASSERT_UNCATEGORIZED(_Maxidx < _Data_size, ""); | |
| 332 | 332 | |
| 333 | 333 | const uint32_t _Bit_shift = static_cast<uint32_t>(_Exponent2) % 32; |
| 334 | 334 | if (_Bit_shift <= 8) { // _Mantissa2's 24 bits don't cross an element boundary |
| ... | ... | @@ -388,9 +388,9 @@ struct __floating_decimal_32 { |
| 388 | 388 | } |
| 389 | 389 | } |
| 390 | 390 | |
| 391 | _LIBCPP_ASSERT(_Data[0] != 0, ""); | |
| 391 | _LIBCPP_ASSERT_UNCATEGORIZED(_Data[0] != 0, ""); | |
| 392 | 392 | for (uint32_t _Idx = 1; _Idx < _Data_size; ++_Idx) { |
| 393 | _LIBCPP_ASSERT(_Data[_Idx] == 0, ""); | |
| 393 | _LIBCPP_ASSERT_UNCATEGORIZED(_Data[_Idx] == 0, ""); | |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | 396 | const uint32_t _Data_olength = _Data[0] >= 1000000000 ? 10 : __decimalLength9(_Data[0]); |
| ... | ... | @@ -565,35 +565,35 @@ struct __floating_decimal_32 { |
| 565 | 565 | _Output /= 10000; |
| 566 | 566 | const uint32_t __c0 = (__c % 100) << 1; |
| 567 | 567 | const uint32_t __c1 = (__c / 100) << 1; |
| 568 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 569 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 568 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); | |
| 569 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); | |
| 570 | 570 | } |
| 571 | 571 | if (_Output >= 100) { |
| 572 | 572 | const uint32_t __c = (_Output % 100) << 1; |
| 573 | 573 | _Output /= 100; |
| 574 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 574 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 575 | 575 | } |
| 576 | 576 | if (_Output >= 10) { |
| 577 | 577 | const uint32_t __c = _Output << 1; |
| 578 | _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 578 | std::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); | |
| 579 | 579 | } else { |
| 580 | 580 | *--_Mid = static_cast<char>('0' + _Output); |
| 581 | 581 | } |
| 582 | 582 | |
| 583 | 583 | if (_Ryu_exponent > 0) { // case "172900" with _Can_use_ryu |
| 584 | 584 | // Performance note: it might be more efficient to do this immediately after setting _Mid. |
| 585 | _VSTD::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent)); | |
| 585 | std::memset(_First + __olength, '0', static_cast<size_t>(_Ryu_exponent)); | |
| 586 | 586 | } else if (_Ryu_exponent == 0) { // case "1729" |
| 587 | 587 | // Done! |
| 588 | 588 | } else if (_Whole_digits > 0) { // case "17.29" |
| 589 | 589 | // Performance note: moving digits might not be optimal. |
| 590 | _VSTD::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits)); | |
| 590 | std::memmove(_First, _First + 1, static_cast<size_t>(_Whole_digits)); | |
| 591 | 591 | _First[_Whole_digits] = '.'; |
| 592 | 592 | } else { // case "0.001729" |
| 593 | 593 | // Performance note: a larger memset() followed by overwriting '.' might be more efficient. |
| 594 | 594 | _First[0] = '0'; |
| 595 | 595 | _First[1] = '.'; |
| 596 | _VSTD::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits)); | |
| 596 | std::memset(_First + 2, '0', static_cast<size_t>(-_Whole_digits)); | |
| 597 | 597 | } |
| 598 | 598 | |
| 599 | 599 | return { _First + _Total_fixed_length, errc{} }; |
| ... | ... | @@ -617,14 +617,14 @@ struct __floating_decimal_32 { |
| 617 | 617 | _Output /= 10000; |
| 618 | 618 | const uint32_t __c0 = (__c % 100) << 1; |
| 619 | 619 | const uint32_t __c1 = (__c / 100) << 1; |
| 620 | _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 621 | _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 620 | std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); | |
| 621 | std::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); | |
| 622 | 622 | __i += 4; |
| 623 | 623 | } |
| 624 | 624 | if (_Output >= 100) { |
| 625 | 625 | const uint32_t __c = (_Output % 100) << 1; |
| 626 | 626 | _Output /= 100; |
| 627 | _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); | |
| 627 | std::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); | |
| 628 | 628 | __i += 2; |
| 629 | 629 | } |
| 630 | 630 | if (_Output >= 10) { |
| ... | ... | @@ -654,7 +654,7 @@ struct __floating_decimal_32 { |
| 654 | 654 | __result[__index++] = '+'; |
| 655 | 655 | } |
| 656 | 656 | |
| 657 | _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); | |
| 657 | std::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); | |
| 658 | 658 | __index += 2; |
| 659 | 659 | |
| 660 | 660 | return { _First + _Total_scientific_length, errc{} }; |
| ... | ... | @@ -673,7 +673,7 @@ struct __floating_decimal_32 { |
| 673 | 673 | return { _Last, errc::value_too_large }; |
| 674 | 674 | } |
| 675 | 675 | |
| 676 | _VSTD::memcpy(_First, "0e+00", 5); | |
| 676 | std::memcpy(_First, "0e+00", 5); | |
| 677 | 677 | |
| 678 | 678 | return { _First + 5, errc{} }; |
| 679 | 679 | } |
lib/libcxx/src/shared_mutex.cpp+54-74| ... | ... | @@ -10,106 +10,86 @@ |
| 10 | 10 | |
| 11 | 11 | #ifndef _LIBCPP_HAS_NO_THREADS |
| 12 | 12 | |
| 13 | #include <shared_mutex> | |
| 14 | #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) | |
| 15 | # pragma comment(lib, "pthread") | |
| 16 | #endif | |
| 13 | # include <mutex> | |
| 14 | # include <shared_mutex> | |
| 15 | # if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) | |
| 16 | # pragma comment(lib, "pthread") | |
| 17 | # endif | |
| 17 | 18 | |
| 18 | 19 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 19 | 20 | |
| 20 | 21 | // Shared Mutex Base |
| 21 | __shared_mutex_base::__shared_mutex_base() | |
| 22 | : __state_(0) | |
| 23 | { | |
| 24 | } | |
| 22 | __shared_mutex_base::__shared_mutex_base() : __state_(0) {} | |
| 25 | 23 | |
| 26 | 24 | // Exclusive ownership |
| 27 | 25 | |
| 28 | void | |
| 29 | __shared_mutex_base::lock() | |
| 30 | { | |
| 31 | unique_lock<mutex> lk(__mut_); | |
| 32 | while (__state_ & __write_entered_) | |
| 33 | __gate1_.wait(lk); | |
| 34 | __state_ |= __write_entered_; | |
| 35 | while (__state_ & __n_readers_) | |
| 36 | __gate2_.wait(lk); | |
| 26 | void __shared_mutex_base::lock() { | |
| 27 | unique_lock<mutex> lk(__mut_); | |
| 28 | while (__state_ & __write_entered_) | |
| 29 | __gate1_.wait(lk); | |
| 30 | __state_ |= __write_entered_; | |
| 31 | while (__state_ & __n_readers_) | |
| 32 | __gate2_.wait(lk); | |
| 37 | 33 | } |
| 38 | 34 | |
| 39 | bool | |
| 40 | __shared_mutex_base::try_lock() | |
| 41 | { | |
| 42 | unique_lock<mutex> lk(__mut_); | |
| 43 | if (__state_ == 0) | |
| 44 | { | |
| 45 | __state_ = __write_entered_; | |
| 46 | return true; | |
| 47 | } | |
| 48 | return false; | |
| 35 | bool __shared_mutex_base::try_lock() { | |
| 36 | unique_lock<mutex> lk(__mut_); | |
| 37 | if (__state_ == 0) { | |
| 38 | __state_ = __write_entered_; | |
| 39 | return true; | |
| 40 | } | |
| 41 | return false; | |
| 49 | 42 | } |
| 50 | 43 | |
| 51 | void | |
| 52 | __shared_mutex_base::unlock() | |
| 53 | { | |
| 54 | lock_guard<mutex> _(__mut_); | |
| 55 | __state_ = 0; | |
| 56 | __gate1_.notify_all(); | |
| 44 | void __shared_mutex_base::unlock() { | |
| 45 | lock_guard<mutex> _(__mut_); | |
| 46 | __state_ = 0; | |
| 47 | __gate1_.notify_all(); | |
| 57 | 48 | } |
| 58 | 49 | |
| 59 | 50 | // Shared ownership |
| 60 | 51 | |
| 61 | void | |
| 62 | __shared_mutex_base::lock_shared() | |
| 63 | { | |
| 64 | unique_lock<mutex> lk(__mut_); | |
| 65 | while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) | |
| 66 | __gate1_.wait(lk); | |
| 67 | unsigned num_readers = (__state_ & __n_readers_) + 1; | |
| 68 | __state_ &= ~__n_readers_; | |
| 69 | __state_ |= num_readers; | |
| 70 | } | |
| 71 | ||
| 72 | bool | |
| 73 | __shared_mutex_base::try_lock_shared() | |
| 74 | { | |
| 75 | unique_lock<mutex> lk(__mut_); | |
| 76 | unsigned num_readers = __state_ & __n_readers_; | |
| 77 | if (!(__state_ & __write_entered_) && num_readers != __n_readers_) | |
| 78 | { | |
| 79 | ++num_readers; | |
| 80 | __state_ &= ~__n_readers_; | |
| 81 | __state_ |= num_readers; | |
| 82 | return true; | |
| 83 | } | |
| 84 | return false; | |
| 52 | void __shared_mutex_base::lock_shared() { | |
| 53 | unique_lock<mutex> lk(__mut_); | |
| 54 | while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) | |
| 55 | __gate1_.wait(lk); | |
| 56 | unsigned num_readers = (__state_ & __n_readers_) + 1; | |
| 57 | __state_ &= ~__n_readers_; | |
| 58 | __state_ |= num_readers; | |
| 85 | 59 | } |
| 86 | 60 | |
| 87 | void | |
| 88 | __shared_mutex_base::unlock_shared() | |
| 89 | { | |
| 90 | lock_guard<mutex> _(__mut_); | |
| 91 | unsigned num_readers = (__state_ & __n_readers_) - 1; | |
| 61 | bool __shared_mutex_base::try_lock_shared() { | |
| 62 | unique_lock<mutex> lk(__mut_); | |
| 63 | unsigned num_readers = __state_ & __n_readers_; | |
| 64 | if (!(__state_ & __write_entered_) && num_readers != __n_readers_) { | |
| 65 | ++num_readers; | |
| 92 | 66 | __state_ &= ~__n_readers_; |
| 93 | 67 | __state_ |= num_readers; |
| 94 | if (__state_ & __write_entered_) | |
| 95 | { | |
| 96 | if (num_readers == 0) | |
| 97 | __gate2_.notify_one(); | |
| 98 | } | |
| 99 | else | |
| 100 | { | |
| 101 | if (num_readers == __n_readers_ - 1) | |
| 102 | __gate1_.notify_one(); | |
| 103 | } | |
| 68 | return true; | |
| 69 | } | |
| 70 | return false; | |
| 104 | 71 | } |
| 105 | 72 | |
| 73 | void __shared_mutex_base::unlock_shared() { | |
| 74 | lock_guard<mutex> _(__mut_); | |
| 75 | unsigned num_readers = (__state_ & __n_readers_) - 1; | |
| 76 | __state_ &= ~__n_readers_; | |
| 77 | __state_ |= num_readers; | |
| 78 | if (__state_ & __write_entered_) { | |
| 79 | if (num_readers == 0) | |
| 80 | __gate2_.notify_one(); | |
| 81 | } else { | |
| 82 | if (num_readers == __n_readers_ - 1) | |
| 83 | __gate1_.notify_one(); | |
| 84 | } | |
| 85 | } | |
| 106 | 86 | |
| 107 | 87 | // Shared Timed Mutex |
| 108 | 88 | // These routines are here for ABI stability |
| 109 | 89 | shared_timed_mutex::shared_timed_mutex() : __base_() {} |
| 110 | void shared_timed_mutex::lock() { return __base_.lock(); } | |
| 90 | void shared_timed_mutex::lock() { return __base_.lock(); } | |
| 111 | 91 | bool shared_timed_mutex::try_lock() { return __base_.try_lock(); } |
| 112 | void shared_timed_mutex::unlock() { return __base_.unlock(); } | |
| 92 | void shared_timed_mutex::unlock() { return __base_.unlock(); } | |
| 113 | 93 | void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); } |
| 114 | 94 | bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); } |
| 115 | 95 | void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); } |
lib/libcxx/src/std_stream.h created+447| ... | ... | @@ -0,0 +1,447 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | #ifndef _LIBCPP_STD_STREAM_H | |
| 11 | #define _LIBCPP_STD_STREAM_H | |
| 12 | ||
| 13 | #include <__config> | |
| 14 | #include <__locale> | |
| 15 | #include <cstdio> | |
| 16 | #include <istream> | |
| 17 | #include <ostream> | |
| 18 | ||
| 19 | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
| 20 | # pragma GCC system_header | |
| 21 | #endif | |
| 22 | ||
| 23 | _LIBCPP_PUSH_MACROS | |
| 24 | #include <__undef_macros> | |
| 25 | ||
| 26 | ||
| 27 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 28 | ||
| 29 | static const int __limit = 8; | |
| 30 | ||
| 31 | // __stdinbuf | |
| 32 | ||
| 33 | template <class _CharT> | |
| 34 | class _LIBCPP_HIDDEN __stdinbuf | |
| 35 | : public basic_streambuf<_CharT, char_traits<_CharT> > | |
| 36 | { | |
| 37 | public: | |
| 38 | typedef _CharT char_type; | |
| 39 | typedef char_traits<char_type> traits_type; | |
| 40 | typedef typename traits_type::int_type int_type; | |
| 41 | typedef typename traits_type::pos_type pos_type; | |
| 42 | typedef typename traits_type::off_type off_type; | |
| 43 | typedef typename traits_type::state_type state_type; | |
| 44 | ||
| 45 | __stdinbuf(FILE* __fp, state_type* __st); | |
| 46 | ||
| 47 | protected: | |
| 48 | virtual int_type underflow(); | |
| 49 | virtual int_type uflow(); | |
| 50 | virtual int_type pbackfail(int_type __c = traits_type::eof()); | |
| 51 | virtual void imbue(const locale& __loc); | |
| 52 | ||
| 53 | private: | |
| 54 | ||
| 55 | FILE* __file_; | |
| 56 | const codecvt<char_type, char, state_type>* __cv_; | |
| 57 | state_type* __st_; | |
| 58 | int __encoding_; | |
| 59 | int_type __last_consumed_; | |
| 60 | bool __last_consumed_is_next_; | |
| 61 | bool __always_noconv_; | |
| 62 | ||
| 63 | #if defined(_LIBCPP_WIN32API) | |
| 64 | static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>; | |
| 65 | #else | |
| 66 | static constexpr bool __is_win32api_wide_char = false; | |
| 67 | #endif | |
| 68 | ||
| 69 | __stdinbuf(const __stdinbuf&); | |
| 70 | __stdinbuf& operator=(const __stdinbuf&); | |
| 71 | ||
| 72 | int_type __getchar(bool __consume); | |
| 73 | }; | |
| 74 | ||
| 75 | template <class _CharT> | |
| 76 | __stdinbuf<_CharT>::__stdinbuf(FILE* __fp, state_type* __st) | |
| 77 | : __file_(__fp), | |
| 78 | __st_(__st), | |
| 79 | __last_consumed_(traits_type::eof()), | |
| 80 | __last_consumed_is_next_(false) | |
| 81 | { | |
| 82 | imbue(this->getloc()); | |
| 83 | // On Windows, in wchar_t mode, ignore the codecvt from the locale by | |
| 84 | // default and assume noconv; this passes wchar_t through unmodified from | |
| 85 | // getwc. If the user sets a custom locale with imbue(), that gets honored, | |
| 86 | // the IO is done with getc() and converted with the provided codecvt. | |
| 87 | if constexpr (__is_win32api_wide_char) | |
| 88 | __always_noconv_ = true; | |
| 89 | } | |
| 90 | ||
| 91 | template <class _CharT> | |
| 92 | void | |
| 93 | __stdinbuf<_CharT>::imbue(const locale& __loc) | |
| 94 | { | |
| 95 | __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc); | |
| 96 | __encoding_ = __cv_->encoding(); | |
| 97 | __always_noconv_ = __cv_->always_noconv(); | |
| 98 | if (__encoding_ > __limit) | |
| 99 | __throw_runtime_error("unsupported locale for standard input"); | |
| 100 | } | |
| 101 | ||
| 102 | template <class _CharT> | |
| 103 | typename __stdinbuf<_CharT>::int_type | |
| 104 | __stdinbuf<_CharT>::underflow() | |
| 105 | { | |
| 106 | return __getchar(false); | |
| 107 | } | |
| 108 | ||
| 109 | template <class _CharT> | |
| 110 | typename __stdinbuf<_CharT>::int_type | |
| 111 | __stdinbuf<_CharT>::uflow() | |
| 112 | { | |
| 113 | return __getchar(true); | |
| 114 | } | |
| 115 | ||
| 116 | static bool __do_getc(FILE *__fp, char *__pbuf) { | |
| 117 | int __c = getc(__fp); | |
| 118 | if (__c == EOF) | |
| 119 | return false; | |
| 120 | *__pbuf = static_cast<char>(__c); | |
| 121 | return true; | |
| 122 | } | |
| 123 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 124 | static bool __do_getc(FILE *__fp, wchar_t *__pbuf) { | |
| 125 | wint_t __c = getwc(__fp); | |
| 126 | if (__c == WEOF) | |
| 127 | return false; | |
| 128 | *__pbuf = static_cast<wchar_t>(__c); | |
| 129 | return true; | |
| 130 | } | |
| 131 | #endif | |
| 132 | ||
| 133 | static bool __do_ungetc(int __c, FILE *__fp, char __dummy) { | |
| 134 | if (ungetc(__c, __fp) == EOF) | |
| 135 | return false; | |
| 136 | return true; | |
| 137 | } | |
| 138 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 139 | static bool __do_ungetc(std::wint_t __c, FILE *__fp, wchar_t __dummy) { | |
| 140 | if (ungetwc(__c, __fp) == WEOF) | |
| 141 | return false; | |
| 142 | return true; | |
| 143 | } | |
| 144 | #endif | |
| 145 | ||
| 146 | template <class _CharT> | |
| 147 | typename __stdinbuf<_CharT>::int_type | |
| 148 | __stdinbuf<_CharT>::__getchar(bool __consume) | |
| 149 | { | |
| 150 | if (__last_consumed_is_next_) | |
| 151 | { | |
| 152 | int_type __result = __last_consumed_; | |
| 153 | if (__consume) | |
| 154 | { | |
| 155 | __last_consumed_ = traits_type::eof(); | |
| 156 | __last_consumed_is_next_ = false; | |
| 157 | } | |
| 158 | return __result; | |
| 159 | } | |
| 160 | if (__always_noconv_) { | |
| 161 | char_type __1buf; | |
| 162 | if (!__do_getc(__file_, &__1buf)) | |
| 163 | return traits_type::eof(); | |
| 164 | if (!__consume) | |
| 165 | { | |
| 166 | if (!__do_ungetc(traits_type::to_int_type(__1buf), __file_, __1buf)) | |
| 167 | return traits_type::eof(); | |
| 168 | } | |
| 169 | else | |
| 170 | __last_consumed_ = traits_type::to_int_type(__1buf); | |
| 171 | return traits_type::to_int_type(__1buf); | |
| 172 | } | |
| 173 | ||
| 174 | char __extbuf[__limit]; | |
| 175 | int __nread = _VSTD::max(1, __encoding_); | |
| 176 | for (int __i = 0; __i < __nread; ++__i) | |
| 177 | { | |
| 178 | int __c = getc(__file_); | |
| 179 | if (__c == EOF) | |
| 180 | return traits_type::eof(); | |
| 181 | __extbuf[__i] = static_cast<char>(__c); | |
| 182 | } | |
| 183 | char_type __1buf; | |
| 184 | const char* __enxt; | |
| 185 | char_type* __inxt; | |
| 186 | codecvt_base::result __r; | |
| 187 | do | |
| 188 | { | |
| 189 | state_type __sv_st = *__st_; | |
| 190 | __r = __cv_->in(*__st_, __extbuf, __extbuf + __nread, __enxt, | |
| 191 | &__1buf, &__1buf + 1, __inxt); | |
| 192 | switch (__r) | |
| 193 | { | |
| 194 | case _VSTD::codecvt_base::ok: | |
| 195 | break; | |
| 196 | case codecvt_base::partial: | |
| 197 | *__st_ = __sv_st; | |
| 198 | if (__nread == sizeof(__extbuf)) | |
| 199 | return traits_type::eof(); | |
| 200 | { | |
| 201 | int __c = getc(__file_); | |
| 202 | if (__c == EOF) | |
| 203 | return traits_type::eof(); | |
| 204 | __extbuf[__nread] = static_cast<char>(__c); | |
| 205 | } | |
| 206 | ++__nread; | |
| 207 | break; | |
| 208 | case codecvt_base::error: | |
| 209 | return traits_type::eof(); | |
| 210 | case _VSTD::codecvt_base::noconv: | |
| 211 | __1buf = static_cast<char_type>(__extbuf[0]); | |
| 212 | break; | |
| 213 | } | |
| 214 | } while (__r == _VSTD::codecvt_base::partial); | |
| 215 | if (!__consume) | |
| 216 | { | |
| 217 | for (int __i = __nread; __i > 0;) | |
| 218 | { | |
| 219 | if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF) | |
| 220 | return traits_type::eof(); | |
| 221 | } | |
| 222 | } | |
| 223 | else | |
| 224 | __last_consumed_ = traits_type::to_int_type(__1buf); | |
| 225 | return traits_type::to_int_type(__1buf); | |
| 226 | } | |
| 227 | ||
| 228 | template <class _CharT> | |
| 229 | typename __stdinbuf<_CharT>::int_type | |
| 230 | __stdinbuf<_CharT>::pbackfail(int_type __c) | |
| 231 | { | |
| 232 | if (traits_type::eq_int_type(__c, traits_type::eof())) | |
| 233 | { | |
| 234 | if (!__last_consumed_is_next_) | |
| 235 | { | |
| 236 | __c = __last_consumed_; | |
| 237 | __last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_, | |
| 238 | traits_type::eof()); | |
| 239 | } | |
| 240 | return __c; | |
| 241 | } | |
| 242 | if (__always_noconv_ && __last_consumed_is_next_) { | |
| 243 | if (!__do_ungetc(__last_consumed_, __file_, | |
| 244 | traits_type::to_char_type(__last_consumed_))) | |
| 245 | return traits_type::eof(); | |
| 246 | } else if (__last_consumed_is_next_) { | |
| 247 | char __extbuf[__limit]; | |
| 248 | char* __enxt; | |
| 249 | const char_type __ci = traits_type::to_char_type(__last_consumed_); | |
| 250 | const char_type* __inxt; | |
| 251 | switch (__cv_->out(*__st_, &__ci, &__ci + 1, __inxt, | |
| 252 | __extbuf, __extbuf + sizeof(__extbuf), __enxt)) | |
| 253 | { | |
| 254 | case _VSTD::codecvt_base::ok: | |
| 255 | break; | |
| 256 | case _VSTD::codecvt_base::noconv: | |
| 257 | __extbuf[0] = static_cast<char>(__last_consumed_); | |
| 258 | __enxt = __extbuf + 1; | |
| 259 | break; | |
| 260 | case codecvt_base::partial: | |
| 261 | case codecvt_base::error: | |
| 262 | return traits_type::eof(); | |
| 263 | } | |
| 264 | while (__enxt > __extbuf) | |
| 265 | if (ungetc(*--__enxt, __file_) == EOF) | |
| 266 | return traits_type::eof(); | |
| 267 | } | |
| 268 | __last_consumed_ = __c; | |
| 269 | __last_consumed_is_next_ = true; | |
| 270 | return __c; | |
| 271 | } | |
| 272 | ||
| 273 | // __stdoutbuf | |
| 274 | ||
| 275 | template <class _CharT> | |
| 276 | class _LIBCPP_HIDDEN __stdoutbuf | |
| 277 | : public basic_streambuf<_CharT, char_traits<_CharT> > | |
| 278 | { | |
| 279 | public: | |
| 280 | typedef _CharT char_type; | |
| 281 | typedef char_traits<char_type> traits_type; | |
| 282 | typedef typename traits_type::int_type int_type; | |
| 283 | typedef typename traits_type::pos_type pos_type; | |
| 284 | typedef typename traits_type::off_type off_type; | |
| 285 | typedef typename traits_type::state_type state_type; | |
| 286 | ||
| 287 | __stdoutbuf(FILE* __fp, state_type* __st); | |
| 288 | ||
| 289 | protected: | |
| 290 | virtual int_type overflow (int_type __c = traits_type::eof()); | |
| 291 | virtual streamsize xsputn(const char_type* __s, streamsize __n); | |
| 292 | virtual int sync(); | |
| 293 | virtual void imbue(const locale& __loc); | |
| 294 | ||
| 295 | private: | |
| 296 | FILE* __file_; | |
| 297 | const codecvt<char_type, char, state_type>* __cv_; | |
| 298 | state_type* __st_; | |
| 299 | bool __always_noconv_; | |
| 300 | ||
| 301 | #if defined(_LIBCPP_WIN32API) | |
| 302 | static constexpr bool __is_win32api_wide_char = !is_same_v<_CharT, char>; | |
| 303 | #else | |
| 304 | static constexpr bool __is_win32api_wide_char = false; | |
| 305 | #endif | |
| 306 | ||
| 307 | __stdoutbuf(const __stdoutbuf&); | |
| 308 | __stdoutbuf& operator=(const __stdoutbuf&); | |
| 309 | }; | |
| 310 | ||
| 311 | template <class _CharT> | |
| 312 | __stdoutbuf<_CharT>::__stdoutbuf(FILE* __fp, state_type* __st) | |
| 313 | : __file_(__fp), | |
| 314 | __cv_(&use_facet<codecvt<char_type, char, state_type> >(this->getloc())), | |
| 315 | __st_(__st), | |
| 316 | __always_noconv_(__cv_->always_noconv()) | |
| 317 | { | |
| 318 | // On Windows, in wchar_t mode, ignore the codecvt from the locale by | |
| 319 | // default and assume noconv; this passes wchar_t through unmodified to | |
| 320 | // fputwc, which handles it correctly depending on the actual mode of the | |
| 321 | // output stream. If the user sets a custom locale with imbue(), that | |
| 322 | // gets honored. | |
| 323 | if constexpr (__is_win32api_wide_char) | |
| 324 | __always_noconv_ = true; | |
| 325 | } | |
| 326 | ||
| 327 | static bool __do_fputc(char __c, FILE* __fp) { | |
| 328 | if (fwrite(&__c, sizeof(__c), 1, __fp) != 1) | |
| 329 | return false; | |
| 330 | return true; | |
| 331 | } | |
| 332 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS | |
| 333 | static bool __do_fputc(wchar_t __c, FILE* __fp) { | |
| 334 | // fputwc works regardless of wide/narrow mode of stdout, while | |
| 335 | // fwrite of wchar_t only works if the stream actually has been set | |
| 336 | // into wide mode. | |
| 337 | if (fputwc(__c, __fp) == WEOF) | |
| 338 | return false; | |
| 339 | return true; | |
| 340 | } | |
| 341 | #endif | |
| 342 | ||
| 343 | template <class _CharT> | |
| 344 | typename __stdoutbuf<_CharT>::int_type | |
| 345 | __stdoutbuf<_CharT>::overflow(int_type __c) | |
| 346 | { | |
| 347 | char __extbuf[__limit]; | |
| 348 | char_type __1buf; | |
| 349 | if (!traits_type::eq_int_type(__c, traits_type::eof())) | |
| 350 | { | |
| 351 | __1buf = traits_type::to_char_type(__c); | |
| 352 | if (__always_noconv_) | |
| 353 | { | |
| 354 | if (!__do_fputc(__1buf, __file_)) | |
| 355 | return traits_type::eof(); | |
| 356 | } | |
| 357 | else | |
| 358 | { | |
| 359 | char* __extbe = __extbuf; | |
| 360 | codecvt_base::result __r; | |
| 361 | char_type* pbase = &__1buf; | |
| 362 | char_type* pptr = pbase + 1; | |
| 363 | do | |
| 364 | { | |
| 365 | const char_type* __e; | |
| 366 | __r = __cv_->out(*__st_, pbase, pptr, __e, | |
| 367 | __extbuf, | |
| 368 | __extbuf + sizeof(__extbuf), | |
| 369 | __extbe); | |
| 370 | if (__e == pbase) | |
| 371 | return traits_type::eof(); | |
| 372 | if (__r == codecvt_base::noconv) | |
| 373 | { | |
| 374 | if (fwrite(pbase, 1, 1, __file_) != 1) | |
| 375 | return traits_type::eof(); | |
| 376 | } | |
| 377 | else if (__r == codecvt_base::ok || __r == codecvt_base::partial) | |
| 378 | { | |
| 379 | size_t __nmemb = static_cast<size_t>(__extbe - __extbuf); | |
| 380 | if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) | |
| 381 | return traits_type::eof(); | |
| 382 | if (__r == codecvt_base::partial) | |
| 383 | { | |
| 384 | pbase = const_cast<char_type*>(__e); | |
| 385 | } | |
| 386 | } | |
| 387 | else | |
| 388 | return traits_type::eof(); | |
| 389 | } while (__r == codecvt_base::partial); | |
| 390 | } | |
| 391 | } | |
| 392 | return traits_type::not_eof(__c); | |
| 393 | } | |
| 394 | ||
| 395 | template <class _CharT> | |
| 396 | streamsize | |
| 397 | __stdoutbuf<_CharT>::xsputn(const char_type* __s, streamsize __n) | |
| 398 | { | |
| 399 | // For wchar_t on Windows, don't call fwrite(), but write characters one | |
| 400 | // at a time with fputwc(); that works both when stdout is in the default | |
| 401 | // mode and when it is set to Unicode mode. | |
| 402 | if (__always_noconv_ && !__is_win32api_wide_char) | |
| 403 | return fwrite(__s, sizeof(char_type), __n, __file_); | |
| 404 | streamsize __i = 0; | |
| 405 | for (; __i < __n; ++__i, ++__s) | |
| 406 | if (overflow(traits_type::to_int_type(*__s)) == traits_type::eof()) | |
| 407 | break; | |
| 408 | return __i; | |
| 409 | } | |
| 410 | ||
| 411 | template <class _CharT> | |
| 412 | int | |
| 413 | __stdoutbuf<_CharT>::sync() | |
| 414 | { | |
| 415 | char __extbuf[__limit]; | |
| 416 | codecvt_base::result __r; | |
| 417 | do | |
| 418 | { | |
| 419 | char* __extbe; | |
| 420 | __r = __cv_->unshift(*__st_, __extbuf, | |
| 421 | __extbuf + sizeof(__extbuf), | |
| 422 | __extbe); | |
| 423 | size_t __nmemb = static_cast<size_t>(__extbe - __extbuf); | |
| 424 | if (fwrite(__extbuf, 1, __nmemb, __file_) != __nmemb) | |
| 425 | return -1; | |
| 426 | } while (__r == codecvt_base::partial); | |
| 427 | if (__r == codecvt_base::error) | |
| 428 | return -1; | |
| 429 | if (fflush(__file_)) | |
| 430 | return -1; | |
| 431 | return 0; | |
| 432 | } | |
| 433 | ||
| 434 | template <class _CharT> | |
| 435 | void | |
| 436 | __stdoutbuf<_CharT>::imbue(const locale& __loc) | |
| 437 | { | |
| 438 | sync(); | |
| 439 | __cv_ = &use_facet<codecvt<char_type, char, state_type> >(__loc); | |
| 440 | __always_noconv_ = __cv_->always_noconv(); | |
| 441 | } | |
| 442 | ||
| 443 | _LIBCPP_END_NAMESPACE_STD | |
| 444 | ||
| 445 | _LIBCPP_POP_MACROS | |
| 446 | ||
| 447 | #endif // _LIBCPP_STD_STREAM_H |
lib/libcxx/src/stdexcept.cpp-1| ... | ... | @@ -9,7 +9,6 @@ |
| 9 | 9 | #include <new> |
| 10 | 10 | #include <stdexcept> |
| 11 | 11 | #include <string> |
| 12 | #include <system_error> | |
| 13 | 12 | |
| 14 | 13 | #ifdef _LIBCPP_ABI_VCRUNTIME |
| 15 | 14 | #include "support/runtime/stdexcept_vcruntime.ipp" |
lib/libcxx/src/string.cpp+3-14| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include <cstdlib> |
| 13 | 13 | #include <limits> |
| 14 | 14 | #include <stdexcept> |
| 15 | #include <stdio.h> | |
| 16 | 15 | #include <string> |
| 17 | 16 | |
| 18 | 17 | #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS |
| ... | ... | @@ -61,22 +60,12 @@ template string operator+<char, char_traits<char>, allocator<char>>(char const*, |
| 61 | 60 | namespace |
| 62 | 61 | { |
| 63 | 62 | |
| 64 | template<typename T> | |
| 65 | inline void throw_helper(const string& msg) { | |
| 66 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 67 | throw T(msg); | |
| 68 | #else | |
| 69 | fprintf(stderr, "%s\n", msg.c_str()); | |
| 70 | _VSTD::abort(); | |
| 71 | #endif | |
| 72 | } | |
| 73 | ||
| 74 | 63 | inline void throw_from_string_out_of_range(const string& func) { |
| 75 | throw_helper<out_of_range>(func + ": out of range"); | |
| 64 | std::__throw_out_of_range((func + ": out of range").c_str()); | |
| 76 | 65 | } |
| 77 | 66 | |
| 78 | 67 | inline void throw_from_string_invalid_arg(const string& func) { |
| 79 | throw_helper<invalid_argument>(func + ": no conversion"); | |
| 68 | std::__throw_invalid_argument((func + ": no conversion").c_str()); | |
| 80 | 69 | } |
| 81 | 70 | |
| 82 | 71 | // as_integer |
| ... | ... | @@ -357,7 +346,7 @@ S i_to_string(V v) { |
| 357 | 346 | constexpr size_t bufsize = numeric_limits<V>::digits10 + 2; // +1 for minus, +1 for digits10 |
| 358 | 347 | char buf[bufsize]; |
| 359 | 348 | const auto res = to_chars(buf, buf + bufsize, v); |
| 360 | _LIBCPP_ASSERT(res.ec == errc(), "bufsize must be large enough to accomodate the value"); | |
| 349 | _LIBCPP_ASSERT_INTERNAL(res.ec == errc(), "bufsize must be large enough to accomodate the value"); | |
| 361 | 350 | return S(buf, res.ptr); |
| 362 | 351 | } |
| 363 | 352 |
lib/libcxx/src/strstream.cpp+1-1| ... | ... | @@ -173,7 +173,7 @@ strstreambuf::overflow(int_type __c) |
| 173 | 173 | if (buf == nullptr) |
| 174 | 174 | return int_type(EOF); |
| 175 | 175 | if (old_size != 0) { |
| 176 | _LIBCPP_ASSERT(eback(), "overflow copying from NULL"); | |
| 176 | _LIBCPP_ASSERT_UNCATEGORIZED(eback(), "overflow copying from NULL"); | |
| 177 | 177 | memcpy(buf, eback(), static_cast<size_t>(old_size)); |
| 178 | 178 | } |
| 179 | 179 | ptrdiff_t ninp = gptr() - eback(); |
lib/libcxx/src/support/ibm/mbsnrtowcs.cpp+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | // Returns (size_t) -1 when an invalid sequence is encountered. |
| 19 | 19 | // Leaves *`src` pointing to the next character to convert or NULL |
| 20 | 20 | // if a null character was converted from *`src`. |
| 21 | _LIBCPP_FUNC_VIS | |
| 21 | _LIBCPP_EXPORTED_FROM_ABI | |
| 22 | 22 | size_t mbsnrtowcs(wchar_t *__restrict dst, const char **__restrict src, |
| 23 | 23 | size_t src_size_bytes, size_t max_dest_chars, |
| 24 | 24 | mbstate_t *__restrict ps) { |
lib/libcxx/src/support/ibm/wcsnrtombs.cpp+1-1| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | // converted from *src, excluding the null terminator. |
| 18 | 18 | // Returns (size_t) -1 if an error occurs and sets errno. |
| 19 | 19 | // If `dst` is NULL, `dst_size_bytes` is ignored and no bytes are copied to `dst`. |
| 20 | _LIBCPP_FUNC_VIS | |
| 20 | _LIBCPP_EXPORTED_FROM_ABI | |
| 21 | 21 | size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src, |
| 22 | 22 | size_t max_source_chars, size_t dst_size_bytes, |
| 23 | 23 | mbstate_t *__restrict ps) { |
lib/libcxx/src/support/ibm/xlocale_zos.cpp+1-1| ... | ... | @@ -111,7 +111,7 @@ locale_t uselocale(locale_t newloc) { |
| 111 | 111 | tokenized.push_back(s); |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | _LIBCPP_ASSERT(tokenized.size() >= _NCAT, "locale-name list is too short"); | |
| 114 | _LIBCPP_ASSERT_UNCATEGORIZED(tokenized.size() >= _NCAT, "locale-name list is too short"); | |
| 115 | 115 | |
| 116 | 116 | previous_loc->lc_collate = tokenized[LC_COLLATE]; |
| 117 | 117 | previous_loc->lc_ctype = tokenized[LC_CTYPE]; |
lib/libcxx/src/support/runtime/exception_fallback.ipp+4-4| ... | ... | @@ -51,15 +51,15 @@ _LIBCPP_NORETURN |
| 51 | 51 | void |
| 52 | 52 | terminate() noexcept |
| 53 | 53 | { |
| 54 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 54 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 55 | 55 | try |
| 56 | 56 | { |
| 57 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 57 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 58 | 58 | (*get_terminate())(); |
| 59 | 59 | // handler should not return |
| 60 | 60 | fprintf(stderr, "terminate_handler unexpectedly returned\n"); |
| 61 | 61 | ::abort(); |
| 62 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 62 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 63 | 63 | } |
| 64 | 64 | catch (...) |
| 65 | 65 | { |
| ... | ... | @@ -67,7 +67,7 @@ terminate() noexcept |
| 67 | 67 | fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); |
| 68 | 68 | ::abort(); |
| 69 | 69 | } |
| 70 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 70 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; } |
lib/libcxx/src/support/runtime/exception_msvc.ipp+4-4| ... | ... | @@ -57,15 +57,15 @@ terminate_handler get_terminate() noexcept { |
| 57 | 57 | _LIBCPP_NORETURN |
| 58 | 58 | void terminate() noexcept |
| 59 | 59 | { |
| 60 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 60 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 61 | 61 | try |
| 62 | 62 | { |
| 63 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 63 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 64 | 64 | (*get_terminate())(); |
| 65 | 65 | // handler should not return |
| 66 | 66 | fprintf(stderr, "terminate_handler unexpectedly returned\n"); |
| 67 | 67 | ::abort(); |
| 68 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 68 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 69 | 69 | } |
| 70 | 70 | catch (...) |
| 71 | 71 | { |
| ... | ... | @@ -73,7 +73,7 @@ void terminate() noexcept |
| 73 | 73 | fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); |
| 74 | 74 | ::abort(); |
| 75 | 75 | } |
| 76 | #endif // _LIBCPP_NO_EXCEPTIONS | |
| 76 | #endif // _LIBCPP_HAS_NO_EXCEPTIONS | |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | bool uncaught_exception() noexcept { return uncaught_exceptions() > 0; } |
lib/libcxx/src/support/runtime/new_handler_fallback.ipp deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | // -*- C++ -*- | |
| 2 | //===----------------------------------------------------------------------===// | |
| 3 | // | |
| 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 5 | // See https://llvm.org/LICENSE.txt for license information. | |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 7 | // | |
| 8 | //===----------------------------------------------------------------------===// | |
| 9 | ||
| 10 | namespace std { | |
| 11 | ||
| 12 | static constinit std::new_handler __new_handler = nullptr; | |
| 13 | ||
| 14 | new_handler | |
| 15 | set_new_handler(new_handler handler) noexcept | |
| 16 | { | |
| 17 | return __libcpp_atomic_exchange(&__new_handler, handler); | |
| 18 | } | |
| 19 | ||
| 20 | new_handler | |
| 21 | get_new_handler() noexcept | |
| 22 | { | |
| 23 | return __libcpp_atomic_load(&__new_handler); | |
| 24 | } | |
| 25 | ||
| 26 | } // namespace std |
lib/libcxx/src/support/solaris/mbsnrtowcs.inc deleted-76| ... | ... | @@ -1,76 +0,0 @@ |
| 1 | ||
| 2 | ||
| 3 | /*- | |
| 4 | * As noted in the source, some portions of this implementation are copied from | |
| 5 | * FreeBSD libc. These are covered by the following copyright: | |
| 6 | * | |
| 7 | * Copyright (c) 2002-2004 Tim J. Robbins. | |
| 8 | * | |
| 9 | * Redistribution and use in source and binary forms, with or without | |
| 10 | * modification, are permitted provided that the following conditions | |
| 11 | * are met: | |
| 12 | * 1. Redistributions of source code must retain the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer. | |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 15 | * notice, this list of conditions and the following disclaimer in the | |
| 16 | * documentation and/or other materials provided with the distribution. | |
| 17 | * | |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 28 | * SUCH DAMAGE. | |
| 29 | */ | |
| 30 | ||
| 31 | size_t | |
| 32 | mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src, | |
| 33 | size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc) | |
| 34 | { | |
| 35 | const char *s; | |
| 36 | size_t nchr; | |
| 37 | wchar_t wc; | |
| 38 | size_t nb; | |
| 39 | FIX_LOCALE(loc); | |
| 40 | ||
| 41 | s = *src; | |
| 42 | nchr = 0; | |
| 43 | ||
| 44 | if (dst == NULL) { | |
| 45 | for (;;) { | |
| 46 | if ((nb = mbrtowc_l(&wc, s, nms, ps, loc)) == (size_t)-1) | |
| 47 | /* Invalid sequence - mbrtowc() sets errno. */ | |
| 48 | return ((size_t)-1); | |
| 49 | else if (nb == 0 || nb == (size_t)-2) | |
| 50 | return (nchr); | |
| 51 | s += nb; | |
| 52 | nms -= nb; | |
| 53 | nchr++; | |
| 54 | } | |
| 55 | /*NOTREACHED*/ | |
| 56 | } | |
| 57 | ||
| 58 | while (len-- > 0) { | |
| 59 | if ((nb = mbrtowc_l(dst, s, nms, ps, loc)) == (size_t)-1) { | |
| 60 | *src = s; | |
| 61 | return ((size_t)-1); | |
| 62 | } else if (nb == (size_t)-2) { | |
| 63 | *src = s + nms; | |
| 64 | return (nchr); | |
| 65 | } else if (nb == 0) { | |
| 66 | *src = NULL; | |
| 67 | return (nchr); | |
| 68 | } | |
| 69 | s += nb; | |
| 70 | nms -= nb; | |
| 71 | nchr++; | |
| 72 | dst++; | |
| 73 | } | |
| 74 | *src = s; | |
| 75 | return (nchr); | |
| 76 | } |
lib/libcxx/src/support/solaris/wcsnrtombs.inc deleted-92| ... | ... | @@ -1,92 +0,0 @@ |
| 1 | /*- | |
| 2 | * Copyright (c) 2002-2004 Tim J. Robbins. | |
| 3 | * | |
| 4 | * Redistribution and use in source and binary forms, with or without | |
| 5 | * modification, are permitted provided that the following conditions | |
| 6 | * are met: | |
| 7 | * 1. Redistributions of source code must retain the above copyright | |
| 8 | * notice, this list of conditions and the following disclaimer. | |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 | * notice, this list of conditions and the following disclaimer in the | |
| 11 | * documentation and/or other materials provided with the distribution. | |
| 12 | * | |
| 13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 23 | * SUCH DAMAGE. | |
| 24 | */ | |
| 25 | ||
| 26 | ||
| 27 | size_t | |
| 28 | wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src, | |
| 29 | size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc) | |
| 30 | { | |
| 31 | FIX_LOCALE(loc); | |
| 32 | mbstate_t mbsbak; | |
| 33 | char buf[MB_CUR_MAX_L(loc)]; | |
| 34 | const wchar_t *s; | |
| 35 | size_t nbytes; | |
| 36 | size_t nb; | |
| 37 | ||
| 38 | s = *src; | |
| 39 | nbytes = 0; | |
| 40 | ||
| 41 | if (dst == NULL) { | |
| 42 | while (nwc-- > 0) { | |
| 43 | if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) | |
| 44 | /* Invalid character - wcrtomb() sets errno. */ | |
| 45 | return ((size_t)-1); | |
| 46 | else if (*s == L'\0') | |
| 47 | return (nbytes + nb - 1); | |
| 48 | s++; | |
| 49 | nbytes += nb; | |
| 50 | } | |
| 51 | return (nbytes); | |
| 52 | } | |
| 53 | ||
| 54 | while (len > 0 && nwc-- > 0) { | |
| 55 | if (len > (size_t)MB_CUR_MAX_L(loc)) { | |
| 56 | /* Enough space to translate in-place. */ | |
| 57 | if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) { | |
| 58 | *src = s; | |
| 59 | return ((size_t)-1); | |
| 60 | } | |
| 61 | } else { | |
| 62 | /* | |
| 63 | * May not be enough space; use temp. buffer. | |
| 64 | * | |
| 65 | * We need to save a copy of the conversion state | |
| 66 | * here so we can restore it if the multibyte | |
| 67 | * character is too long for the buffer. | |
| 68 | */ | |
| 69 | mbsbak = *ps; | |
| 70 | if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) { | |
| 71 | *src = s; | |
| 72 | return ((size_t)-1); | |
| 73 | } | |
| 74 | if (nb > (int)len) { | |
| 75 | /* MB sequence for character won't fit. */ | |
| 76 | *ps = mbsbak; | |
| 77 | break; | |
| 78 | } | |
| 79 | memcpy(dst, buf, nb); | |
| 80 | } | |
| 81 | if (*s == L'\0') { | |
| 82 | *src = NULL; | |
| 83 | return (nbytes + nb - 1); | |
| 84 | } | |
| 85 | s++; | |
| 86 | dst += nb; | |
| 87 | len -= nb; | |
| 88 | nbytes += nb; | |
| 89 | } | |
| 90 | *src = s; | |
| 91 | return (nbytes); | |
| 92 | } |
lib/libcxx/src/support/solaris/xlocale.cpp deleted-68| ... | ... | @@ -1,68 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #ifdef __sun__ | |
| 10 | ||
| 11 | #include "__support/solaris/xlocale.h" | |
| 12 | #include <stdarg.h> | |
| 13 | #include <stdio.h> | |
| 14 | #include <sys/localedef.h> | |
| 15 | ||
| 16 | extern "C" { | |
| 17 | ||
| 18 | int isxdigit_l(int __c, locale_t __l) { | |
| 19 | return isxdigit(__c); | |
| 20 | } | |
| 21 | ||
| 22 | int iswxdigit_l(wint_t __c, locale_t __l) { | |
| 23 | return isxdigit(__c); | |
| 24 | } | |
| 25 | ||
| 26 | // FIXME: This disregards the locale, which is Very Wrong | |
| 27 | #define vsnprintf_l(__s, __n, __l, __format, __va) \ | |
| 28 | vsnprintf(__s, __n, __format, __va) | |
| 29 | ||
| 30 | int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) | |
| 31 | { | |
| 32 | va_list __va; | |
| 33 | va_start(__va, __format); | |
| 34 | int __res = vsnprintf_l(__s, __n , __l, __format, __va); | |
| 35 | va_end(__va); | |
| 36 | return __res; | |
| 37 | } | |
| 38 | ||
| 39 | int asprintf_l(char **__s, locale_t __l, const char *__format, ...) { | |
| 40 | va_list __va; | |
| 41 | va_start(__va, __format); | |
| 42 | // FIXME: | |
| 43 | int __res = vasprintf(__s, __format, __va); | |
| 44 | va_end(__va); | |
| 45 | return __res; | |
| 46 | } | |
| 47 | ||
| 48 | int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { | |
| 49 | va_list __va; | |
| 50 | va_start(__va, __format); | |
| 51 | // FIXME: | |
| 52 | int __res = vsscanf(__s, __format, __va); | |
| 53 | va_end(__va); | |
| 54 | return __res; | |
| 55 | } | |
| 56 | ||
| 57 | size_t mbrtowc_l(wchar_t *__pwc, const char *__pmb, | |
| 58 | size_t __max, mbstate_t *__ps, locale_t __loc) { | |
| 59 | return mbrtowc(__pwc, __pmb, __max, __ps); | |
| 60 | } | |
| 61 | ||
| 62 | struct lconv *localeconv_l(locale_t __l) { | |
| 63 | return localeconv(); | |
| 64 | } | |
| 65 | ||
| 66 | }; | |
| 67 | ||
| 68 | #endif // __sun__ |
lib/libcxx/src/support/win32/locale_win32.cpp+2| ... | ... | @@ -11,6 +11,8 @@ |
| 11 | 11 | #include <memory> |
| 12 | 12 | #include <type_traits> |
| 13 | 13 | |
| 14 | #include <__locale_dir/locale_base_api/locale_guard.h> | |
| 15 | ||
| 14 | 16 | int __libcpp_vasprintf(char **sptr, const char *__restrict fmt, va_list ap); |
| 15 | 17 | |
| 16 | 18 | using std::__libcpp_locale_guard; |
lib/libcxx/src/system_error.cpp+4-5| ... | ... | @@ -12,6 +12,7 @@ |
| 12 | 12 | #endif |
| 13 | 13 | |
| 14 | 14 | #include <__assert> |
| 15 | #include <__verbose_abort> | |
| 15 | 16 | #include <cerrno> |
| 16 | 17 | #include <cstdio> |
| 17 | 18 | #include <cstdlib> |
| ... | ... | @@ -103,7 +104,7 @@ handle_strerror_r_return(int strerror_return, char *buffer) { |
| 103 | 104 | if (new_errno == EINVAL) |
| 104 | 105 | return ""; |
| 105 | 106 | |
| 106 | _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerror_r"); | |
| 107 | _LIBCPP_ASSERT_UNCATEGORIZED(new_errno == ERANGE, "unexpected error from ::strerror_r"); | |
| 107 | 108 | // FIXME maybe? 'strerror_buff_size' is likely to exceed the |
| 108 | 109 | // maximum error size so ERANGE shouldn't be returned. |
| 109 | 110 | std::abort(); |
| ... | ... | @@ -286,12 +287,10 @@ system_error::~system_error() noexcept |
| 286 | 287 | void |
| 287 | 288 | __throw_system_error(int ev, const char* what_arg) |
| 288 | 289 | { |
| 289 | #ifndef _LIBCPP_NO_EXCEPTIONS | |
| 290 | #ifndef _LIBCPP_HAS_NO_EXCEPTIONS | |
| 290 | 291 | throw system_error(error_code(ev, system_category()), what_arg); |
| 291 | 292 | #else |
| 292 | (void)ev; | |
| 293 | (void)what_arg; | |
| 294 | _VSTD::abort(); | |
| 293 | _LIBCPP_VERBOSE_ABORT("system_error was thrown in -fno-exceptions mode with error %i and message \"%s\"", ev, what_arg); | |
| 295 | 294 | #endif |
| 296 | 295 | } |
| 297 | 296 |
lib/libcxx/src/thread.cpp+2| ... | ... | @@ -10,6 +10,8 @@ |
| 10 | 10 | |
| 11 | 11 | #ifndef _LIBCPP_HAS_NO_THREADS |
| 12 | 12 | |
| 13 | #include <__thread/poll_with_backoff.h> | |
| 14 | #include <__thread/timed_backoff_policy.h> | |
| 13 | 15 | #include <exception> |
| 14 | 16 | #include <future> |
| 15 | 17 | #include <limits> |
lib/libcxx/src/utility.cpp deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | //===----------------------------------------------------------------------===// | |
| 2 | // | |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| 4 | // See https://llvm.org/LICENSE.txt for license information. | |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| 6 | // | |
| 7 | //===----------------------------------------------------------------------===// | |
| 8 | ||
| 9 | #include <utility> | |
| 10 | ||
| 11 | _LIBCPP_BEGIN_NAMESPACE_STD | |
| 12 | ||
| 13 | const piecewise_construct_t piecewise_construct{}; | |
| 14 | ||
| 15 | _LIBCPP_END_NAMESPACE_STD |
lib/libcxx/src/valarray.cpp+2-2| ... | ... | @@ -12,8 +12,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD |
| 12 | 12 | |
| 13 | 13 | // These two symbols are part of the v1 ABI but not part of the >=v2 ABI. |
| 14 | 14 | #if _LIBCPP_ABI_VERSION == 1 |
| 15 | template _LIBCPP_FUNC_VIS valarray<size_t>::valarray(size_t); | |
| 16 | template _LIBCPP_FUNC_VIS valarray<size_t>::~valarray(); | |
| 15 | template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::valarray(size_t); | |
| 16 | template _LIBCPP_EXPORTED_FROM_ABI valarray<size_t>::~valarray(); | |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | 19 | template void valarray<size_t>::resize(size_t, size_t); |
src/Compilation.zig+3| ... | ... | @@ -4318,6 +4318,9 @@ pub fn addCCArgs( |
| 4318 | 4318 | try argv.append("-D_LIBCPP_HAS_NO_THREADS"); |
| 4319 | 4319 | } |
| 4320 | 4320 | |
| 4321 | // See the comment in libcxx.zig for more details about this. | |
| 4322 | try argv.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL"); | |
| 4323 | ||
| 4321 | 4324 | try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ |
| 4322 | 4325 | @intFromEnum(comp.libcxx_abi_version), |
| 4323 | 4326 | })); |
src/libcxx.zig+17-4| ... | ... | @@ -46,15 +46,17 @@ const libcxx_files = [_][]const u8{ |
| 46 | 46 | "src/chrono.cpp", |
| 47 | 47 | "src/condition_variable.cpp", |
| 48 | 48 | "src/condition_variable_destructor.cpp", |
| 49 | "src/debug.cpp", | |
| 50 | 49 | "src/exception.cpp", |
| 51 | 50 | "src/experimental/memory_resource.cpp", |
| 51 | "src/filesystem/directory_entry.cpp", | |
| 52 | 52 | "src/filesystem/directory_iterator.cpp", |
| 53 | "src/filesystem/filesystem_clock.cpp", | |
| 54 | "src/filesystem/filesystem_error.cpp", | |
| 53 | 55 | // omit int128_builtins.cpp because it provides __muloti4 which is already provided |
| 54 | 56 | // by compiler_rt and crashes on Windows x86_64: https://github.com/ziglang/zig/issues/10719 |
| 55 | 57 | //"src/filesystem/int128_builtins.cpp", |
| 56 | 58 | "src/filesystem/operations.cpp", |
| 57 | "src/format.cpp", | |
| 59 | "src/filesystem/path.cpp", | |
| 58 | 60 | "src/functional.cpp", |
| 59 | 61 | "src/future.cpp", |
| 60 | 62 | "src/hash.cpp", |
| ... | ... | @@ -65,10 +67,14 @@ const libcxx_files = [_][]const u8{ |
| 65 | 67 | "src/legacy_pointer_safety.cpp", |
| 66 | 68 | "src/locale.cpp", |
| 67 | 69 | "src/memory.cpp", |
| 70 | "src/memory_resource.cpp", | |
| 68 | 71 | "src/mutex.cpp", |
| 69 | 72 | "src/mutex_destructor.cpp", |
| 70 | 73 | "src/new.cpp", |
| 74 | "src/new_handler.cpp", | |
| 75 | "src/new_helpers.cpp", | |
| 71 | 76 | "src/optional.cpp", |
| 77 | "src/print.cpp", | |
| 72 | 78 | "src/random.cpp", |
| 73 | 79 | "src/random_shuffle.cpp", |
| 74 | 80 | "src/regex.cpp", |
| ... | ... | @@ -82,14 +88,12 @@ const libcxx_files = [_][]const u8{ |
| 82 | 88 | "src/support/ibm/mbsnrtowcs.cpp", |
| 83 | 89 | "src/support/ibm/wcsnrtombs.cpp", |
| 84 | 90 | "src/support/ibm/xlocale_zos.cpp", |
| 85 | "src/support/solaris/xlocale.cpp", | |
| 86 | 91 | "src/support/win32/locale_win32.cpp", |
| 87 | 92 | "src/support/win32/support.cpp", |
| 88 | 93 | "src/support/win32/thread_win32.cpp", |
| 89 | 94 | "src/system_error.cpp", |
| 90 | 95 | "src/thread.cpp", |
| 91 | 96 | "src/typeinfo.cpp", |
| 92 | "src/utility.cpp", | |
| 93 | 97 | "src/valarray.cpp", |
| 94 | 98 | "src/variant.cpp", |
| 95 | 99 | "src/vector.cpp", |
| ... | ... | @@ -166,6 +170,13 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 166 | 170 | try cflags.append("-D_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS"); |
| 167 | 171 | try cflags.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); |
| 168 | 172 | |
| 173 | // See libcxx/include/__algorithm/pstl_backends/cpu_backends/backend.h | |
| 174 | // for potentially enabling some fancy features here, which would | |
| 175 | // require corresponding changes in libcxx.zig, as well as | |
| 176 | // Compilation.addCCArgs. This option makes it use serial backend which | |
| 177 | // is simple and works everywhere. | |
| 178 | try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL"); | |
| 179 | ||
| 169 | 180 | try cflags.append(abi_version_arg); |
| 170 | 181 | try cflags.append(abi_namespace_arg); |
| 171 | 182 | |
| ... | ... | @@ -336,6 +347,8 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 336 | 347 | try cflags.append("-D_LIBCXXABI_BUILDING_LIBRARY"); |
| 337 | 348 | try cflags.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 338 | 349 | try cflags.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); |
| 350 | // This must be coordinated with the same flag in libcxx | |
| 351 | try cflags.append("-D_LIBCPP_PSTL_CPU_BACKEND_SERIAL"); | |
| 339 | 352 | |
| 340 | 353 | try cflags.append(abi_version_arg); |
| 341 | 354 | try cflags.append(abi_namespace_arg); |