From 442029c6fa37f1b6f9203357de09672d5704077c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 18 Jan 2024 21:21:30 -0800 Subject: [PATCH 01/20] ``: `__umulh` is already an intrinsic for `_M_HYBRID_X86_ARM64` (#4330) --- stl/inc/xcharconv_ryu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stl/inc/xcharconv_ryu.h b/stl/inc/xcharconv_ryu.h index d2f8db8dd62..4b944ff380c 100644 --- a/stl/inc/xcharconv_ryu.h +++ b/stl/inc/xcharconv_ryu.h @@ -211,6 +211,7 @@ _NODISCARD inline uint64_t __ryu_shiftright128(const uint64_t __lo, const uint64 #ifndef _WIN64 +#if !defined(_M_HYBRID_X86_ARM64) // Returns the high 64 bits of the 128-bit product of __a and __b. _NODISCARD inline uint64_t __umulh(const uint64_t __a, const uint64_t __b) { // Reuse the __ryu_umul128 implementation. @@ -220,6 +221,7 @@ _NODISCARD inline uint64_t __umulh(const uint64_t __a, const uint64_t __b) { (void) __ryu_umul128(__a, __b, &__hi); return __hi; } +#endif // ^^^ !defined(_M_HYBRID_X86_ARM64) ^^^ // On 32-bit platforms, compilers typically generate calls to library // functions for 64-bit divisions, even if the divisor is a constant. From 264413871a99dbb8299342e3983c743298d88887 Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 25 Jan 2024 06:31:45 +0700 Subject: [PATCH 02/20] `iter_value_t` should always use direct-initialization (#4233) Co-authored-by: A. Jiang Co-authored-by: Stephan T. Lavavej --- stl/inc/algorithm | 28 +- stl/inc/numeric | 8 +- stl/inc/random | 2 +- tests/std/test.lst | 1 + .../Dev11_0253803_debug_pointer/test.cpp | 2 +- .../env.lst | 4 + .../test.compile.pass.cpp | 561 ++++++++++++++++++ .../tests/P0896R4_common_iterator/test.cpp | 2 +- 8 files changed, 587 insertions(+), 21 deletions(-) create mode 100644 tests/std/tests/GH_004109_iter_value_t_direct_initialization/env.lst create mode 100644 tests/std/tests/GH_004109_iter_value_t_direct_initialization/test.compile.pass.cpp diff --git a/stl/inc/algorithm b/stl/inc/algorithm index c2d974151b3..e793f01a441 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -4529,7 +4529,7 @@ _CONSTEXPR20 _OutIt unique_copy(_InIt _First, _InIt _Last, _OutIt _Dest, _Pr _Pr ++_UDest; } else { // can't reread source or dest, construct a temporary - _Iter_value_t<_InIt> _Val = *_UFirst; + _Iter_value_t<_InIt> _Val(*_UFirst); *_UDest = _Val; ++_UDest; @@ -4656,7 +4656,7 @@ namespace ranges { } } else { // Neither _First nor _Result can be reread, construct temporary - iter_value_t<_It> _Val = *_First; + iter_value_t<_It> _Val(*_First); while (++_First != _Last) { if (!_STD invoke(_Pred, _STD invoke(_Proj, _Val), _STD invoke(_Proj, *_First))) { @@ -6322,7 +6322,7 @@ _CONSTEXPR20 void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { using _Diff = _Iter_diff_t<_RanIt>; _Diff _Count = _ULast - _UFirst; if (2 <= _Count) { - _Iter_value_t<_RanIt> _Val = _STD move(*--_ULast); + _Iter_value_t<_RanIt> _Val(_STD move(*--_ULast)); _STD _Push_heap_by_index(_UFirst, --_Count, _Diff(0), _STD move(_Val), _Pass_fn(_Pred)); } } @@ -6393,7 +6393,7 @@ namespace ranges { } --_Last; - iter_value_t<_It> _Val = _RANGES iter_move(_Last); + iter_value_t<_It> _Val(_RANGES iter_move(_Last)); // NB: if _Proj is a _Ref_fn, this aliases the _Proj1 and _Proj2 parameters of _Push_heap_by_index _RANGES _Push_heap_by_index(_STD move(_First), _Count - 1, 0, _STD move(_Val), _Pred, _Proj, _Proj); } @@ -6449,7 +6449,7 @@ _CONSTEXPR20 void _Pop_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { // pop *_First to *(_Last - 1) and reheap if (2 <= _Last - _First) { --_Last; - _Iter_value_t<_RanIt> _Val = _STD move(*_Last); + _Iter_value_t<_RanIt> _Val(_STD move(*_Last)); _STD _Pop_heap_hole_unchecked(_First, _Last, _Last, _STD move(_Val), _Pred); } } @@ -6527,7 +6527,7 @@ namespace ranges { } --_Last; - iter_value_t<_It> _Val = _RANGES iter_move(_Last); + iter_value_t<_It> _Val(_RANGES iter_move(_Last)); // NB: if _Proj is a _Ref_fn, this aliases the _Proj1 and _Proj2 parameters of _Pop_heap_hole_unchecked _RANGES _Pop_heap_hole_unchecked(_STD move(_First), _Last, _Last, _STD move(_Val), _Pred, _Proj, _Proj); } @@ -6571,7 +6571,7 @@ _CONSTEXPR20 void _Make_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { for (_Diff _Hole = _Bottom >> 1; _Hole > 0;) { // shift for codegen // reheap top half, bottom to top --_Hole; - _Iter_value_t<_RanIt> _Val = _STD move(*(_First + _Hole)); + _Iter_value_t<_RanIt> _Val(_STD move(*(_First + _Hole))); _STD _Pop_heap_hole_by_index(_First, _Hole, _Bottom, _STD move(_Val), _Pred); } } @@ -6598,7 +6598,7 @@ namespace ranges { for (_Diff _Hole = _Bottom >> 1; _Hole > 0;) { // shift for codegen // reheap top half, bottom to top --_Hole; - iter_value_t<_It> _Val = _RANGES iter_move(_First + _Hole); + iter_value_t<_It> _Val(_RANGES iter_move(_First + _Hole)); // NB: if _Proj is a _Ref_fn, this aliases the _Proj1 and _Proj2 parameters of _Pop_heap_hole_by_index _RANGES _Pop_heap_hole_by_index(_First, _Hole, _Bottom, _STD move(_Val), _Pred, _Proj, _Proj); } @@ -7862,8 +7862,8 @@ _CONSTEXPR20 _BidIt _Insertion_sort_unchecked(const _BidIt _First, const _BidIt // insertion sort [_First, _Last) if (_First != _Last) { for (_BidIt _Mid = _First; ++_Mid != _Last;) { // order next element - _BidIt _Hole = _Mid; - _Iter_value_t<_BidIt> _Val = _STD move(*_Mid); + _BidIt _Hole = _Mid; + _Iter_value_t<_BidIt> _Val(_STD move(*_Mid)); if (_DEBUG_LT_PRED(_Pred, _Val, *_First)) { // found new earliest element, move to front _Move_backward_unchecked(_First, _Mid, ++_Hole); @@ -8051,8 +8051,8 @@ namespace ranges { } for (auto _Mid = _First; ++_Mid != _Last;) { // order next element - iter_value_t<_It> _Val = _RANGES iter_move(_Mid); - auto _Hole = _Mid; + iter_value_t<_It> _Val(_RANGES iter_move(_Mid)); + auto _Hole = _Mid; for (auto _Prev = _Hole;;) { --_Prev; @@ -8713,7 +8713,7 @@ _CONSTEXPR20 void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last, _Pr _Pr _Make_heap_unchecked(_UFirst, _UMid, _Pass_fn(_Pred)); for (auto _UNext = _UMid; _UNext < _ULast; ++_UNext) { if (_DEBUG_LT_PRED(_Pred, *_UNext, *_UFirst)) { // replace top with new largest - _Iter_value_t<_RanIt> _Val = _STD move(*_UNext); + _Iter_value_t<_RanIt> _Val(_STD move(*_UNext)); _STD _Pop_heap_hole_unchecked(_UFirst, _UMid, _UNext, _STD move(_Val), _Pass_fn(_Pred)); } } @@ -8803,7 +8803,7 @@ namespace ranges { for (auto _Next = _Mid; _Next != _Last; ++_Next) { if (_STD invoke(_Pred, _STD invoke(_Proj, *_Next), _STD invoke(_Proj, *_First))) { // replace top with new largest - iter_value_t<_It> _Val = _RANGES iter_move(_Next); + iter_value_t<_It> _Val(_RANGES iter_move(_Next)); _RANGES _Pop_heap_hole_unchecked(_First, _Mid, _Next, _STD move(_Val), _Pred, _Proj, _Proj); } } diff --git a/stl/inc/numeric b/stl/inc/numeric index e3c2cdc7276..c9ffb26b598 100644 --- a/stl/inc/numeric +++ b/stl/inc/numeric @@ -343,7 +343,7 @@ _CONSTEXPR20 _OutIt inclusive_scan(const _InIt _First, const _InIt _Last, _OutIt const auto _ULast = _Get_unwrapped(_Last); auto _UDest = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast)); if (_UFirst != _ULast) { - _Iter_value_t<_InIt> _Val = *_UFirst; // Requirement missing from N4950 + _Iter_value_t<_InIt> _Val(*_UFirst); // Requirement missing from N4950 for (;;) { *_UDest = _Val; ++_UDest; @@ -476,10 +476,10 @@ _CONSTEXPR20 _OutIt adjacent_difference(const _InIt _First, const _InIt _Last, _ const auto _ULast = _Get_unwrapped(_Last); auto _UDest = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast)); if (_UFirst != _ULast) { - _Iter_value_t<_InIt> _Val = *_UFirst; - *_UDest = _Val; + _Iter_value_t<_InIt> _Val(*_UFirst); + *_UDest = _Val; while (++_UFirst != _ULast) { // compute another difference - _Iter_value_t<_InIt> _Tmp = *_UFirst; + _Iter_value_t<_InIt> _Tmp(*_UFirst); #if _HAS_CXX20 *++_UDest = _Func(_Tmp, _STD move(_Val)); #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv diff --git a/stl/inc/random b/stl/inc/random index 372f965c9da..fbac0b707c3 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -191,7 +191,7 @@ public: const size_t _Mx = _Nx <= _Sx ? _Sx + 1 : _Nx; size_t _Kx; - _Iter_value_t<_RanIt> _Mask = _Iter_value_t<_RanIt>(1) << 31; + _Iter_value_t<_RanIt> _Mask(_Iter_value_t<_RanIt>(1) << 31); _Mask <<= 1; // build 32-bit mask safely _Mask -= 1; diff --git a/tests/std/test.lst b/tests/std/test.lst index 1cb0e33f917..5d33546ab75 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -234,6 +234,7 @@ tests\GH_003840_tellg_when_reading_lf_file_in_text_mode tests\GH_003867_output_nan tests\GH_004023_mdspan_fwd_prod_overflow tests\GH_004040_container_nonmember_functions +tests\GH_004109_iter_value_t_direct_initialization tests\GH_004201_chrono_formatter tests\GH_004275_seeking_fancy_iterators tests\LWG2381_num_get_floating_point diff --git a/tests/std/tests/Dev11_0253803_debug_pointer/test.cpp b/tests/std/tests/Dev11_0253803_debug_pointer/test.cpp index a9b67d75561..530f709ebcd 100644 --- a/tests/std/tests/Dev11_0253803_debug_pointer/test.cpp +++ b/tests/std/tests/Dev11_0253803_debug_pointer/test.cpp @@ -13,6 +13,7 @@ #ifdef __cpp_lib_execution #include +using std::execution::par; #endif // __cpp_lib_execution using namespace std; @@ -272,7 +273,6 @@ int main() { uninitialized_fill_n(nil, zero, 1729); #ifdef __cpp_lib_execution - using namespace std::execution; (void) all_of(par, nil, nil, pred); (void) any_of(par, nil, nil, pred); (void) none_of(par, nil, nil, pred); diff --git a/tests/std/tests/GH_004109_iter_value_t_direct_initialization/env.lst b/tests/std/tests/GH_004109_iter_value_t_direct_initialization/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_004109_iter_value_t_direct_initialization/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_004109_iter_value_t_direct_initialization/test.compile.pass.cpp b/tests/std/tests/GH_004109_iter_value_t_direct_initialization/test.compile.pass.cpp new file mode 100644 index 00000000000..08520f59bf5 --- /dev/null +++ b/tests/std/tests/GH_004109_iter_value_t_direct_initialization/test.compile.pass.cpp @@ -0,0 +1,561 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include +#include + +#ifdef __cpp_lib_execution +#include +using std::execution::par; +#endif // __cpp_lib_execution + +using namespace std; + +struct Val; + +struct RRef { + RRef(const Val&); +}; + +struct Val { + using difference_type = int; + explicit Val(const RRef&); + Val& operator=(const RRef&); + bool operator==(const Val&) const; +#if _HAS_CXX20 + strong_ordering operator<=>(const Val&) const; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + bool operator!=(const Val&) const; + bool operator<(const Val&) const; + bool operator<=(const Val&) const; + bool operator>(const Val&) const; + bool operator>=(const Val&) const; +#endif // ^^^ !_HAS_CXX20 ^^^ + Val& operator++(); + Val operator++(int); +}; + +struct I { + using iterator_category = random_access_iterator_tag; + using pointer = Val*; + using value_type = Val; + using reference = Val&; + using difference_type = int; + Val& operator*() const; + Val& operator[](int) const; + I& operator++(); + I operator++(int); + I& operator--(); + I operator--(int); + I& operator+=(int); + I& operator-=(int); + friend bool operator==(const I&, const I&); + friend bool operator!=(const I&, const I&); + friend bool operator<(const I&, const I&); + friend bool operator<=(const I&, const I&); + friend bool operator>(const I&, const I&); + friend bool operator>=(const I&, const I&); + friend int operator-(I, I); + friend I operator+(I, int); + friend I operator-(I, int); + friend I operator+(int, I); + friend RRef iter_move(const I&); + +#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-1941943 + int dummy{0}; +#endif // ^^^ workaround ^^^ +}; + +#ifdef __cpp_lib_concepts +static_assert(random_access_iterator); +static_assert(sortable); +#endif // __cpp_lib_concepts + +extern Val val; +extern mt19937 urbg; // UniformRandomBitGenerator +const int zero = 0; +// GH-4109: : iter_value_t should always use direct-initialization +void test_gh_4109() { + I nil{}; + + bool (*pred)(Val) = nullptr; + bool (*pred2)(Val, Val) = nullptr; + bool (*comp)(Val, Val) = nullptr; + Val (*gen)() = nullptr; +#if _HAS_AUTO_PTR_ETC + int (*rng)(int) = nullptr; +#endif // _HAS_AUTO_PTR_ETC + Val (*unop)(Val) = nullptr; + Val (*binop)(Val, Val) = nullptr; +#ifdef __cpp_lib_concepts + strong_ordering (*comp_three_way)(Val, Val) = nullptr; +#endif // __cpp_lib_concepts + + (void) all_of(nil, nil, pred); + (void) any_of(nil, nil, pred); + (void) none_of(nil, nil, pred); + for_each(nil, nil, pred); +#if _HAS_CXX17 + for_each_n(nil, zero, pred); +#endif // _HAS_CXX17 + (void) find(nil, nil, val); + (void) find_if(nil, nil, pred); + (void) find_if_not(nil, nil, pred); + (void) find_end(nil, nil, nil, nil); + (void) find_end(nil, nil, nil, nil, pred2); + (void) find_first_of(nil, nil, nil, nil); + (void) find_first_of(nil, nil, nil, nil, pred2); + (void) adjacent_find(nil, nil); + (void) adjacent_find(nil, nil, pred2); + (void) count(nil, nil, val); + (void) count_if(nil, nil, pred); + (void) mismatch(nil, nil, nil); + (void) mismatch(nil, nil, nil, pred2); + (void) mismatch(nil, nil, nil, nil); + (void) mismatch(nil, nil, nil, nil, pred2); + (void) equal(nil, nil, nil); + (void) equal(nil, nil, nil, pred2); + (void) equal(nil, nil, nil, nil); + (void) equal(nil, nil, nil, nil, pred2); + (void) is_permutation(nil, nil, nil); + (void) is_permutation(nil, nil, nil, pred2); + (void) is_permutation(nil, nil, nil, nil); + (void) is_permutation(nil, nil, nil, nil, pred2); + (void) search(nil, nil, nil, nil); + (void) search(nil, nil, nil, nil, pred2); + (void) search_n(nil, nil, zero, val); + (void) search_n(nil, nil, zero, val, pred2); + copy(nil, nil, nil); + copy_n(nil, zero, nil); + copy_if(nil, nil, nil, pred); + copy_backward(nil, nil, nil); + move(nil, nil, nil); + move_backward(nil, nil, nil); + swap_ranges(nil, nil, nil); + transform(nil, nil, nil, unop); + transform(nil, nil, nil, nil, binop); + replace(nil, nil, val, val); + replace_if(nil, nil, pred, val); + replace_copy(nil, nil, nil, val, val); + replace_copy_if(nil, nil, nil, pred, val); + fill(nil, nil, val); + fill_n(nil, zero, val); + generate(nil, nil, gen); + generate_n(nil, zero, gen); + (void) remove(nil, nil, val); + (void) remove_if(nil, nil, pred); + remove_copy(nil, nil, nil, val); + remove_copy_if(nil, nil, nil, pred); + (void) unique(nil, nil); + (void) unique(nil, nil, pred2); + unique_copy(nil, nil, nil); + unique_copy(nil, nil, nil, pred2); + reverse(nil, nil); + reverse_copy(nil, nil, nil); + rotate(nil, nil, nil); + rotate_copy(nil, nil, nil, nil); +#if _HAS_AUTO_PTR_ETC + random_shuffle(nil, nil); + random_shuffle(nil, nil, rng); +#endif // _HAS_AUTO_PTR_ETC +#if _HAS_CXX17 + sample(nil, nil, nil, zero, urbg); +#endif // _HAS_CXX17 + shuffle(nil, nil, urbg); +#if _HAS_CXX20 + shift_left(nil, nil, 1729); + shift_right(nil, nil, 1729); +#endif // _HAS_CXX20 + sort(nil, nil); + sort(nil, nil, comp); + stable_sort(nil, nil); + stable_sort(nil, nil, comp); + partial_sort(nil, nil, nil); + partial_sort(nil, nil, nil, comp); + partial_sort_copy(nil, nil, nil, nil); + partial_sort_copy(nil, nil, nil, nil, comp); + (void) is_sorted(nil, nil); + (void) is_sorted(nil, nil, comp); + (void) is_sorted_until(nil, nil); + (void) is_sorted_until(nil, nil, comp); + nth_element(nil, nil, nil); + nth_element(nil, nil, nil, comp); + (void) lower_bound(nil, nil, val); + (void) lower_bound(nil, nil, val, comp); + (void) upper_bound(nil, nil, val); + (void) upper_bound(nil, nil, val, comp); + (void) equal_range(nil, nil, val); + (void) equal_range(nil, nil, val, comp); + (void) binary_search(nil, nil, val); + (void) binary_search(nil, nil, val, comp); + (void) is_partitioned(nil, nil, pred); + partition(nil, nil, pred); + stable_partition(nil, nil, pred); + partition_copy(nil, nil, nil, nil, pred); + (void) partition_point(nil, nil, pred); + merge(nil, nil, nil, nil, nil); + merge(nil, nil, nil, nil, nil, comp); + inplace_merge(nil, nil, nil); + inplace_merge(nil, nil, nil, comp); + (void) includes(nil, nil, nil, nil); + (void) includes(nil, nil, nil, nil, comp); + set_union(nil, nil, nil, nil, nil); + set_union(nil, nil, nil, nil, nil, comp); + set_intersection(nil, nil, nil, nil, nil); + set_intersection(nil, nil, nil, nil, nil, comp); + set_difference(nil, nil, nil, nil, nil); + set_difference(nil, nil, nil, nil, nil, comp); + set_symmetric_difference(nil, nil, nil, nil, nil); + set_symmetric_difference(nil, nil, nil, nil, nil, comp); + push_heap(nil, nil); + push_heap(nil, nil, comp); + pop_heap(nil, nil); + pop_heap(nil, nil, comp); + make_heap(nil, nil); + make_heap(nil, nil, comp); + sort_heap(nil, nil); + sort_heap(nil, nil, comp); + (void) is_heap(nil, nil); + (void) is_heap(nil, nil, comp); + (void) is_heap_until(nil, nil); + (void) is_heap_until(nil, nil, comp); + (void) min_element(nil, nil); + (void) min_element(nil, nil, comp); + (void) max_element(nil, nil); + (void) max_element(nil, nil, comp); + (void) minmax_element(nil, nil); + (void) minmax_element(nil, nil, comp); + (void) lexicographical_compare(nil, nil, nil, nil); + (void) lexicographical_compare(nil, nil, nil, nil, comp); +#ifdef __cpp_lib_concepts + (void) lexicographical_compare_three_way(nil, nil, nil, nil); + (void) lexicographical_compare_three_way(nil, nil, nil, nil, comp_three_way); +#endif // __cpp_lib_concepts + next_permutation(nil, nil); + next_permutation(nil, nil, comp); + prev_permutation(nil, nil); + prev_permutation(nil, nil, comp); + + (void) accumulate(nil, nil, val, binop); +#if _HAS_CXX17 + (void) reduce(nil, nil, val, binop); +#endif // _HAS_CXX17 + (void) inner_product(nil, nil, nil, val, binop, binop); +#if _HAS_CXX17 + (void) transform_reduce(nil, nil, nil, val, binop, binop); + (void) transform_reduce(nil, nil, val, binop, unop); +#endif // _HAS_CXX17 + partial_sum(nil, nil, nil, binop); +#if _HAS_CXX17 + exclusive_scan(nil, nil, nil, val, binop); + inclusive_scan(nil, nil, nil, binop); + inclusive_scan(nil, nil, nil, binop, val); + transform_exclusive_scan(nil, nil, nil, val, binop, unop); + transform_inclusive_scan(nil, nil, nil, binop, unop); + transform_inclusive_scan(nil, nil, nil, binop, unop, val); +#endif // _HAS_CXX17 + adjacent_difference(nil, nil, nil, binop); + iota(nil, nil, val); + + uninitialized_copy(nil, nil, nil); + uninitialized_copy_n(nil, zero, nil); +#if _HAS_CXX17 + uninitialized_move(nil, nil, nil); + uninitialized_move_n(nil, zero, nil); +#endif // _HAS_CXX17 + uninitialized_fill(nil, nil, val); + uninitialized_fill_n(nil, zero, val); + +#ifdef __cpp_lib_execution + (void) all_of(par, nil, nil, pred); + (void) any_of(par, nil, nil, pred); + (void) none_of(par, nil, nil, pred); + for_each(par, nil, nil, pred); + for_each_n(par, nil, zero, pred); + (void) find(par, nil, nil, val); + (void) find_if(par, nil, nil, pred); + (void) find_if_not(par, nil, nil, pred); +#ifndef _M_CEE // TRANSITION, VSO-1946395 + (void) find_end(par, nil, nil, nil, nil); + (void) find_end(par, nil, nil, nil, nil, pred2); +#endif // ^^^ no workaround ^^^ + (void) find_first_of(par, nil, nil, nil, nil); + (void) find_first_of(par, nil, nil, nil, nil, pred2); + (void) adjacent_find(par, nil, nil); + (void) adjacent_find(par, nil, nil, pred2); + (void) count(par, nil, nil, val); + (void) count_if(par, nil, nil, pred); + (void) mismatch(par, nil, nil, nil); + (void) mismatch(par, nil, nil, nil, pred2); + (void) mismatch(par, nil, nil, nil, nil); + (void) mismatch(par, nil, nil, nil, nil, pred2); + (void) equal(par, nil, nil, nil); + (void) equal(par, nil, nil, nil, pred2); + (void) equal(par, nil, nil, nil, nil); + (void) equal(par, nil, nil, nil, nil, pred2); + (void) search(par, nil, nil, nil, nil); + (void) search(par, nil, nil, nil, nil, pred2); + (void) search_n(par, nil, nil, zero, val); + (void) search_n(par, nil, nil, zero, val, pred2); + copy(par, nil, nil, nil); + copy_n(par, nil, zero, nil); + copy_if(par, nil, nil, nil, pred); + move(par, nil, nil, nil); + swap_ranges(par, nil, nil, nil); + transform(par, nil, nil, nil, unop); + transform(par, nil, nil, nil, nil, binop); + replace(par, nil, nil, val, val); + replace_if(par, nil, nil, pred, val); + replace_copy(par, nil, nil, nil, val, val); + replace_copy_if(par, nil, nil, nil, pred, val); + fill(par, nil, nil, val); + fill_n(par, nil, zero, val); + generate(par, nil, nil, gen); + generate_n(par, nil, zero, gen); + (void) remove(par, nil, nil, val); + (void) remove_if(par, nil, nil, pred); + remove_copy(par, nil, nil, nil, val); + remove_copy_if(par, nil, nil, nil, pred); + (void) unique(par, nil, nil); + (void) unique(par, nil, nil, pred2); + unique_copy(par, nil, nil, nil); + unique_copy(par, nil, nil, nil, pred2); + reverse(par, nil, nil); + reverse_copy(par, nil, nil, nil); + rotate(par, nil, nil, nil); + rotate_copy(par, nil, nil, nil, nil); +#if _HAS_CXX20 + shift_left(par, nil, nil, 1729); + shift_right(par, nil, nil, 1729); +#endif // _HAS_CXX20 + sort(par, nil, nil); + sort(par, nil, nil, comp); + stable_sort(par, nil, nil); + stable_sort(par, nil, nil, comp); + partial_sort(par, nil, nil, nil); + partial_sort(par, nil, nil, nil, comp); + partial_sort_copy(par, nil, nil, nil, nil); + partial_sort_copy(par, nil, nil, nil, nil, comp); + (void) is_sorted(par, nil, nil); + (void) is_sorted(par, nil, nil, comp); + (void) is_sorted_until(par, nil, nil); + (void) is_sorted_until(par, nil, nil, comp); + nth_element(par, nil, nil, nil); + nth_element(par, nil, nil, nil, comp); + (void) is_partitioned(par, nil, nil, pred); + partition(par, nil, nil, pred); + stable_partition(par, nil, nil, pred); + partition_copy(par, nil, nil, nil, nil, pred); + merge(par, nil, nil, nil, nil, nil); + merge(par, nil, nil, nil, nil, nil, comp); + inplace_merge(par, nil, nil, nil); + inplace_merge(par, nil, nil, nil, comp); + (void) includes(par, nil, nil, nil, nil); + (void) includes(par, nil, nil, nil, nil, comp); + set_union(par, nil, nil, nil, nil, nil); + set_union(par, nil, nil, nil, nil, nil, comp); + set_intersection(par, nil, nil, nil, nil, nil); + set_intersection(par, nil, nil, nil, nil, nil, comp); + set_difference(par, nil, nil, nil, nil, nil); + set_difference(par, nil, nil, nil, nil, nil, comp); + set_symmetric_difference(par, nil, nil, nil, nil, nil); + set_symmetric_difference(par, nil, nil, nil, nil, nil, comp); + (void) is_heap(par, nil, nil); + (void) is_heap(par, nil, nil, comp); + (void) is_heap_until(par, nil, nil); + (void) is_heap_until(par, nil, nil, comp); + (void) min_element(par, nil, nil); + (void) min_element(par, nil, nil, comp); + (void) max_element(par, nil, nil); + (void) max_element(par, nil, nil, comp); + (void) minmax_element(par, nil, nil); + (void) minmax_element(par, nil, nil, comp); + (void) lexicographical_compare(par, nil, nil, nil, nil); + (void) lexicographical_compare(par, nil, nil, nil, nil, comp); + + (void) reduce(par, nil, nil, val, binop); + (void) transform_reduce(par, nil, nil, nil, val, binop, binop); + (void) transform_reduce(par, nil, nil, val, binop, unop); + exclusive_scan(par, nil, nil, nil, val, binop); + inclusive_scan(par, nil, nil, nil, binop); + inclusive_scan(par, nil, nil, nil, binop, val); + transform_exclusive_scan(par, nil, nil, nil, val, binop, unop); + transform_inclusive_scan(par, nil, nil, nil, binop, unop); + transform_inclusive_scan(par, nil, nil, nil, binop, unop, val); + adjacent_difference(par, nil, nil, nil, binop); + + uninitialized_copy(par, nil, nil, nil); + uninitialized_copy_n(par, nil, zero, nil); + uninitialized_move(par, nil, nil, nil); + uninitialized_move_n(par, nil, zero, nil); + uninitialized_fill(par, nil, nil, val); + uninitialized_fill_n(par, nil, zero, val); +#endif // __cpp_lib_execution + +#ifdef __cpp_lib_concepts + // Non-modifying sequence operations + (void) ranges::all_of(nil, nil, pred); + (void) ranges::any_of(nil, nil, pred); + (void) ranges::none_of(nil, nil, pred); +#if _HAS_CXX23 + (void) ranges::contains(nil, nil, val); + (void) ranges::contains_subrange(nil, nil, nil, nil); +#endif // _HAS_CXX23 + ranges::for_each(nil, nil, pred); + ranges::for_each_n(nil, zero, pred); + (void) ranges::find(nil, nil, val); + (void) ranges::find_if(nil, nil, pred); + (void) ranges::find_if_not(nil, nil, pred); +#if _HAS_CXX23 + (void) ranges::find_last(nil, nil, val); + (void) ranges::find_last_if(nil, nil, pred); + (void) ranges::find_last_if_not(nil, nil, pred); +#endif // _HAS_CXX23 + (void) ranges::find_end(nil, nil, nil, nil); + (void) ranges::find_end(nil, nil, nil, nil, pred2); + (void) ranges::find_first_of(nil, nil, nil, nil); + (void) ranges::find_first_of(nil, nil, nil, nil, pred2); + (void) ranges::adjacent_find(nil, nil); + (void) ranges::adjacent_find(nil, nil, pred2); + (void) ranges::count(nil, nil, val); + (void) ranges::count_if(nil, nil, pred); + (void) ranges::mismatch(nil, nil, nil, nil); + (void) ranges::mismatch(nil, nil, nil, nil, pred2); + (void) ranges::equal(nil, nil, nil, nil); + (void) ranges::equal(nil, nil, nil, nil, pred2); + (void) ranges::is_permutation(nil, nil, nil, nil); + (void) ranges::is_permutation(nil, nil, nil, nil, pred2); + (void) ranges::search(nil, nil, nil, nil); + (void) ranges::search(nil, nil, nil, nil, pred2); + (void) ranges::search_n(nil, nil, zero, val); + (void) ranges::search_n(nil, nil, zero, val, pred2); +#if _HAS_CXX23 + (void) ranges::starts_with(nil, nil, nil, nil); + (void) ranges::starts_with(nil, nil, nil, nil, pred2); + (void) ranges::ends_with(nil, nil, nil, nil); + (void) ranges::ends_with(nil, nil, nil, nil, pred2); + (void) ranges::fold_left(nil, nil, val, binop); + (void) ranges::fold_left_first(nil, nil, binop); + (void) ranges::fold_right(nil, nil, val, binop); + (void) ranges::fold_right_last(nil, nil, binop); + (void) ranges::fold_left_with_iter(nil, nil, val, binop); + (void) ranges::fold_left_first_with_iter(nil, nil, binop); +#endif // _HAS_CXX23 + ranges::copy(nil, nil, nil); + ranges::copy_n(nil, zero, nil); + ranges::copy_if(nil, nil, nil, pred); + ranges::copy_backward(nil, nil, nil); + ranges::move(nil, nil, nil); + ranges::move_backward(nil, nil, nil); + ranges::swap_ranges(nil, nil, nil, nil); + ranges::transform(nil, nil, nil, unop); + ranges::transform(nil, nil, nil, nil, nil, binop); + ranges::replace(nil, nil, val, val); + ranges::replace_if(nil, nil, pred, val); + ranges::replace_copy(nil, nil, nil, val, val); + ranges::replace_copy_if(nil, nil, nil, pred, val); + ranges::fill(nil, nil, val); + ranges::fill_n(nil, zero, val); + ranges::generate(nil, nil, gen); + ranges::generate_n(nil, zero, gen); + (void) ranges::remove(nil, nil, val); + (void) ranges::remove_if(nil, nil, pred); + ranges::remove_copy(nil, nil, nil, val); + ranges::remove_copy_if(nil, nil, nil, pred); + (void) ranges::unique(nil, nil); + (void) ranges::unique(nil, nil, pred2); + ranges::unique_copy(nil, nil, nil); + ranges::unique_copy(nil, nil, nil, pred2); + ranges::reverse(nil, nil); + ranges::reverse_copy(nil, nil, nil); + ranges::rotate(nil, nil, nil); + ranges::rotate_copy(nil, nil, nil, nil); + ranges::sample(nil, nil, nil, zero, urbg); + ranges::shuffle(nil, nil, urbg); +#if _HAS_CXX23 + ranges::shift_left(nil, nil, 1729); + ranges::shift_right(nil, nil, 1729); +#endif // _HAS_CXX23 + ranges::sort(nil, nil); + ranges::sort(nil, nil, comp); + ranges::stable_sort(nil, nil); + ranges::stable_sort(nil, nil, comp); + ranges::partial_sort(nil, nil, nil); + ranges::partial_sort(nil, nil, nil, comp); + ranges::partial_sort_copy(nil, nil, nil, nil); + ranges::partial_sort_copy(nil, nil, nil, nil, comp); + (void) ranges::is_sorted(nil, nil); + (void) ranges::is_sorted(nil, nil, comp); + (void) ranges::is_sorted_until(nil, nil); + (void) ranges::is_sorted_until(nil, nil, comp); + ranges::nth_element(nil, nil, nil); + ranges::nth_element(nil, nil, nil, comp); + (void) ranges::lower_bound(nil, nil, val); + (void) ranges::lower_bound(nil, nil, val, comp); + (void) ranges::upper_bound(nil, nil, val); + (void) ranges::upper_bound(nil, nil, val, comp); + (void) ranges::equal_range(nil, nil, val); + (void) ranges::equal_range(nil, nil, val, comp); + (void) ranges::binary_search(nil, nil, val); + (void) ranges::binary_search(nil, nil, val, comp); + (void) ranges::is_partitioned(nil, nil, pred); + ranges::partition(nil, nil, pred); + ranges::stable_partition(nil, nil, pred); + ranges::partition_copy(nil, nil, nil, nil, pred); + (void) ranges::partition_point(nil, nil, pred); + ranges::merge(nil, nil, nil, nil, nil); + ranges::merge(nil, nil, nil, nil, nil, comp); + ranges::inplace_merge(nil, nil, nil); + ranges::inplace_merge(nil, nil, nil, comp); + (void) ranges::includes(nil, nil, nil, nil); + (void) ranges::includes(nil, nil, nil, nil, comp); + ranges::set_union(nil, nil, nil, nil, nil); + ranges::set_union(nil, nil, nil, nil, nil, comp); + ranges::set_intersection(nil, nil, nil, nil, nil); + ranges::set_intersection(nil, nil, nil, nil, nil, comp); + ranges::set_difference(nil, nil, nil, nil, nil); + ranges::set_difference(nil, nil, nil, nil, nil, comp); + ranges::set_symmetric_difference(nil, nil, nil, nil, nil); + ranges::set_symmetric_difference(nil, nil, nil, nil, nil, comp); + ranges::push_heap(nil, nil); + ranges::push_heap(nil, nil, comp); + ranges::pop_heap(nil, nil); + ranges::pop_heap(nil, nil, comp); + ranges::make_heap(nil, nil); + ranges::make_heap(nil, nil, comp); + ranges::sort_heap(nil, nil); + ranges::sort_heap(nil, nil, comp); + (void) ranges::is_heap(nil, nil); + (void) ranges::is_heap(nil, nil, comp); + (void) ranges::is_heap_until(nil, nil); + (void) ranges::is_heap_until(nil, nil, comp); + (void) ranges::min_element(nil, nil); + (void) ranges::min_element(nil, nil, comp); + (void) ranges::max_element(nil, nil); + (void) ranges::max_element(nil, nil, comp); + (void) ranges::minmax_element(nil, nil); + (void) ranges::minmax_element(nil, nil, comp); + (void) ranges::lexicographical_compare(nil, nil, nil, nil); + (void) ranges::lexicographical_compare(nil, nil, nil, nil, comp); + ranges::next_permutation(nil, nil); + ranges::next_permutation(nil, nil, comp); + ranges::prev_permutation(nil, nil); + ranges::prev_permutation(nil, nil, comp); + + // Constrained numeric operations +#if _HAS_CXX23 + ranges::iota(nil, nil, val); +#endif // _HAS_CXX23 + + // Constrained uninitialized memory algorithms + ranges::uninitialized_copy(nil, nil, nil, nil); + ranges::uninitialized_copy_n(nil, zero, nil, nil); + ranges::uninitialized_move(nil, nil, nil, nil); + ranges::uninitialized_move_n(nil, zero, nil, nil); + ranges::uninitialized_fill(nil, nil, val); + ranges::uninitialized_fill_n(nil, zero, val); +#endif // __cpp_lib_concepts +} diff --git a/tests/std/tests/P0896R4_common_iterator/test.cpp b/tests/std/tests/P0896R4_common_iterator/test.cpp index c4e6784c8ec..c4691a7c6e3 100644 --- a/tests/std/tests/P0896R4_common_iterator/test.cpp +++ b/tests/std/tests/P0896R4_common_iterator/test.cpp @@ -161,7 +161,7 @@ struct instantiator { if constexpr (input_iterator) { // iter_move Cit iter1{Iter{input}}; - const same_as> auto element1 = ranges::iter_move(iter1); + const same_as> auto element1(ranges::iter_move(iter1)); assert(element1 == P(0, 1)); } From 63aeb77ce1c5e389819bb6c0b83fcbd7dd8efe4b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 25 Jan 2024 07:55:46 +0800 Subject: [PATCH 03/20] ``: Don't swap `basic_stringbuf`s in move assignment and allocator-extended construction (#4239) Co-authored-by: Stephan T. Lavavej --- stl/inc/sstream | 134 ++++++++++++------ tests/libcxx/expected_results.txt | 3 - .../GH_001858_iostream_exception/test.cpp | 25 ++++ .../test.cpp | 17 +++ 4 files changed, 136 insertions(+), 43 deletions(-) diff --git a/stl/inc/sstream b/stl/inc/sstream index 59f0e6b6c05..2a0ae5136d9 100644 --- a/stl/inc/sstream +++ b/stl/inc/sstream @@ -66,24 +66,87 @@ public: const basic_string<_Elem, _Traits, _Alloc2>& _Str, ios_base::openmode _Mode = ios_base::in | ios_base::out) : basic_stringbuf(_Str, _Mode, _Alloc{}) {} - basic_stringbuf(basic_stringbuf&& _Right, const _Alloc& _Al_) : _Mystate(0), _Al(_Al_) { - _Assign_rv(_STD move(_Right)); + basic_stringbuf(basic_stringbuf&& _Right, const _Alloc& _Al_) : _Seekhigh(nullptr), _Mystate(0), _Al(_Al_) { + if constexpr (!allocator_traits<_Alloc>::is_always_equal::value) { + if (_Al != _Right._Al) { + _Copy_into_self_and_tidy(_STD move(_Right)); + return; + } + } + + _Take_contents(_STD move(_Right)); } #endif // _HAS_CXX20 - basic_stringbuf(basic_stringbuf&& _Right) : _Mystate(0) { - _Assign_rv(_STD move(_Right)); + basic_stringbuf(basic_stringbuf&& _Right) + : _Seekhigh(_STD exchange(_Right._Seekhigh, nullptr)), _Mystate(_STD exchange(_Right._Mystate, 0)), + _Al(_Right._Al) { + _Mysb::swap(_Right); } - basic_stringbuf& operator=(basic_stringbuf&& _Right) noexcept /* strengthened */ { - _Assign_rv(_STD move(_Right)); + basic_stringbuf& operator=(basic_stringbuf&& _Right) noexcept( + _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ { + if (this != _STD addressof(_Right)) { + _Assign_rv_no_alias(_STD move(_Right)); + } return *this; } - void _Assign_rv(basic_stringbuf&& _Right) noexcept { - if (this != _STD addressof(_Right)) { - _Tidy(); - this->swap(_Right); + void _Take_contents(basic_stringbuf&& _Right) noexcept { + // pre: *this holds no dynamic buffer and _Al == _Right._Al + _Seekhigh = _STD exchange(_Right._Seekhigh, nullptr); + _Mystate = _STD exchange(_Right._Mystate, 0); + _Mysb::swap(_Right); + } + + void _Copy_into_self_and_tidy(basic_stringbuf&& _Right) { + // pre: *this holds no dynamic buffer and _Al != _Right._Al + if ((_Right._Mystate & _Allocated) == 0) { + return; + } + + const auto _Right_data = _Right._Mysb::eback(); + const auto _Right_capacity = static_cast::size_type>( + (_Right._Mysb::pptr() ? _Right._Mysb::epptr() : _Right._Mysb::egptr()) - _Right_data); + + auto _New_capacity = _Right_capacity; + const auto _New_data = _STD _Unfancy(_STD _Allocate_at_least_helper(_Al, _New_capacity)); + + _Mysb::setg(_New_data, _New_data + (_Right._Mysb::gptr() - _Right_data), + _New_data + (_Right._Mysb::egptr() - _Right_data)); + if (_Right._Mysb::pbase() != nullptr) { + const auto _Pbase_diff = _Right._Mysb::pbase() - _Right_data; + const auto _Pptr_diff = _Right._Mysb::pptr() - _Right_data; + const auto _Epptr_diff = _Right._Mysb::epptr() - _Right_data; + _Mysb::setp(_New_data + _Pbase_diff, _New_data + _Pptr_diff, _New_data + _Epptr_diff); + } else { + _Mysb::setp(nullptr, nullptr, nullptr); + } + + const auto _Right_view = _Right._Get_buffer_view(); + if (_Right_view._Ptr != nullptr) { + _Traits::copy(_New_data + (_Right_view._Ptr - _Right_data), _Right_view._Ptr, _Right_view._Size); + } + + _Seekhigh = _New_data + _New_capacity; + _Mystate = _Right._Mystate; + + _Right._Tidy(); + } + + void _Assign_rv_no_alias(basic_stringbuf&& _Right) noexcept( + _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) { + // pre: this != std::addressof(_Right) + _Tidy(); + if constexpr (_Choose_pocma_v<_Alloc> == _Pocma_values::_No_propagate_allocators) { + if (_Al == _Right._Al) { + _Take_contents(_STD move(_Right)); + } else { + _Copy_into_self_and_tidy(_STD move(_Right)); + } + } else { + _Pocma(_Al, _Right._Al); + _Take_contents(_STD move(_Right)); } } @@ -584,20 +647,17 @@ public: : _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::in) {} #endif // _HAS_CXX20 - basic_istringstream(basic_istringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) { - _Assign_rv(_STD move(_Right)); - } + basic_istringstream(basic_istringstream&& _Right) + : _Mybase(_STD addressof(_Stringbuffer)), + _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) {} - basic_istringstream& operator=(basic_istringstream&& _Right) noexcept /* strengthened */ { - _Assign_rv(_STD move(_Right)); - return *this; - } - - void _Assign_rv(basic_istringstream&& _Right) noexcept { + basic_istringstream& operator=(basic_istringstream&& _Right) noexcept( + _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ { if (this != _STD addressof(_Right)) { _Mybase::swap(_Right); - _Stringbuffer._Assign_rv(_STD move(_Right._Stringbuffer)); + _Stringbuffer._Assign_rv_no_alias(_STD move(_Right._Stringbuffer)); } + return *this; } void swap(basic_istringstream& _Right) noexcept /* strengthened */ { @@ -704,20 +764,17 @@ public: : _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode | ios_base::out) {} #endif // _HAS_CXX20 - basic_ostringstream(basic_ostringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) { - _Assign_rv(_STD move(_Right)); - } + basic_ostringstream(basic_ostringstream&& _Right) + : _Mybase(_STD addressof(_Stringbuffer)), + _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) {} - basic_ostringstream& operator=(basic_ostringstream&& _Right) noexcept /* strengthened */ { - _Assign_rv(_STD move(_Right)); - return *this; - } - - void _Assign_rv(basic_ostringstream&& _Right) noexcept { + basic_ostringstream& operator=(basic_ostringstream&& _Right) noexcept( + _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ { if (this != _STD addressof(_Right)) { _Mybase::swap(_Right); - _Stringbuffer._Assign_rv(_STD move(_Right._Stringbuffer)); + _Stringbuffer._Assign_rv_no_alias(_STD move(_Right._Stringbuffer)); } + return *this; } void swap(basic_ostringstream& _Right) noexcept /* strengthened */ { @@ -830,20 +887,17 @@ public: : _Mybase(_STD addressof(_Stringbuffer)), _Stringbuffer(_Str, _Mode) {} #endif // _HAS_CXX20 - basic_stringstream(basic_stringstream&& _Right) : _Mybase(_STD addressof(_Stringbuffer)) { - _Assign_rv(_STD move(_Right)); - } + basic_stringstream(basic_stringstream&& _Right) + : _Mybase(_STD addressof(_Stringbuffer)), + _Stringbuffer((_Mybase::swap(_Right), _STD move(_Right._Stringbuffer))) {} - basic_stringstream& operator=(basic_stringstream&& _Right) noexcept /* strengthened */ { - _Assign_rv(_STD move(_Right)); - return *this; - } - - void _Assign_rv(basic_stringstream&& _Right) noexcept { + basic_stringstream& operator=(basic_stringstream&& _Right) noexcept( + _Choose_pocma_v<_Alloc> != _Pocma_values::_No_propagate_allocators) /* strengthened */ { if (this != _STD addressof(_Right)) { _Mybase::swap(_Right); - _Stringbuffer._Assign_rv(_STD move(_Right._Stringbuffer)); + _Stringbuffer._Assign_rv_no_alias(_STD move(_Right._Stringbuffer)); } + return *this; } void swap(basic_stringstream& _Right) noexcept /* strengthened */ { diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 615c255e33c..ed3fcb49521 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -513,9 +513,6 @@ std/algorithms/robust_against_adl.compile.pass.cpp FAIL # GH-3100: etc.: ADL should be avoided when calling _Construct_in_place and its friends std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp FAIL -# GH-4232: : basic_stringbuf shouldn't implement moving with swapping -std/input.output/string.streams/stringbuf/stringbuf.cons/move.alloc.pass.cpp FAIL - # GH-4238: : file_clock::to_utc() overflows for file_time # This test also has a bogus assumption about the file_time epoch, and file_time is doomed on Windows. std/time/time.clock/time.clock.file/ostream.pass.cpp FAIL diff --git a/tests/std/tests/GH_001858_iostream_exception/test.cpp b/tests/std/tests/GH_001858_iostream_exception/test.cpp index 5ddb356a1e5..9b9bc47ef29 100644 --- a/tests/std/tests/GH_001858_iostream_exception/test.cpp +++ b/tests/std/tests/GH_001858_iostream_exception/test.cpp @@ -15,6 +15,10 @@ #include #include +#if _HAS_CXX17 +#include +#endif // _HAS_CXX17 + #if _HAS_CXX20 #include #endif // _HAS_CXX20 @@ -322,6 +326,27 @@ STATIC_ASSERT(is_nothrow_move_assignable_v); STATIC_ASSERT(is_nothrow_move_assignable_v); STATIC_ASSERT(is_nothrow_move_assignable_v); +// GH-4232: : basic_stringbuf shouldn't implement moving with swapping +// These operations need to be able to throw exceptions when the source and target allocators are unequal. +#if _HAS_CXX17 +STATIC_ASSERT( + !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); +STATIC_ASSERT( + !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); +STATIC_ASSERT( + !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); +STATIC_ASSERT(!is_nothrow_move_assignable_v< + basic_istringstream, pmr::polymorphic_allocator>>); +STATIC_ASSERT( + !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); +STATIC_ASSERT(!is_nothrow_move_assignable_v< + basic_ostringstream, pmr::polymorphic_allocator>>); +STATIC_ASSERT( + !is_nothrow_move_assignable_v, pmr::polymorphic_allocator>>); +STATIC_ASSERT(!is_nothrow_move_assignable_v< + basic_stringstream, pmr::polymorphic_allocator>>); +#endif // _HAS_CXX17 + STATIC_ASSERT(is_nothrow_std_swappable); STATIC_ASSERT(is_nothrow_std_swappable); STATIC_ASSERT(is_nothrow_std_swappable); diff --git a/tests/std/tests/P0408R7_efficient_access_to_stringbuf_buffer/test.cpp b/tests/std/tests/P0408R7_efficient_access_to_stringbuf_buffer/test.cpp index 421f9ec0f90..a4fc8a0bb36 100644 --- a/tests/std/tests/P0408R7_efficient_access_to_stringbuf_buffer/test.cpp +++ b/tests/std/tests/P0408R7_efficient_access_to_stringbuf_buffer/test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,22 @@ struct test_pmr_allocator { } Stream stream2{init_value, init_value.get_allocator()}; assert(stream2.rdbuf()->get_allocator() == init_value.get_allocator()); + + // GH-4232: : basic_stringbuf shouldn't implement moving with swapping + + // Move to another stream buffer with different allocators + using SBuf = remove_pointer_t; + SBuf& sbuf = *stream.rdbuf(); + SBuf sbuf2{move(sbuf), init_value.get_allocator()}; + assert(sbuf2.get_allocator() != sbuf.get_allocator()); + assert(stream.view().empty()); + assert(sbuf2.view() == init_value); + + // Move assignment between different memory resources + sbuf = move(sbuf2); + assert(sbuf2.get_allocator() != sbuf.get_allocator()); + assert(sbuf2.view().empty()); + assert(stream.view() == init_value); } }; From 065e5ffc9aa4db4a3f4da6a22c6ede165a861128 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 25 Jan 2024 08:04:34 +0800 Subject: [PATCH 04/20] ``: Make copy/move assignment operators of `expected` propagate triviality (#4271) Co-authored-by: Stephan T. Lavavej --- stl/inc/expected | 60 +++++++- tests/std/tests/P0323R12_expected/test.cpp | 167 +++++++++++++++++++++ 2 files changed, 219 insertions(+), 8 deletions(-) diff --git a/stl/inc/expected b/stl/inc/expected index 69bee016bb0..9a72b37f8e1 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -182,6 +182,28 @@ struct _Check_expected_argument : true_type { "T must not be a (possibly cv-qualified) specialization of unexpected. (N4950 [expected.object.general]/2)"); }; +template +concept _Expected_binary_copy_assignable = + is_copy_assignable_v<_Ty> && is_copy_constructible_v<_Ty> // + && is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err> + && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>); + +template +concept _Expected_binary_move_assignable = + is_move_assignable_v<_Ty> && is_move_constructible_v<_Ty> // + && is_move_assignable_v<_Err> && is_move_constructible_v<_Err> + && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>); + +template // used with both _Ty and _Err +concept _Trivially_copy_constructible_assignable_destructible = + is_trivially_copy_constructible_v<_Type> && is_trivially_copy_assignable_v<_Type> + && is_trivially_destructible_v<_Type>; + +template // used with both _Ty and _Err +concept _Trivially_move_constructible_assignable_destructible = + is_trivially_move_constructible_v<_Type> && is_trivially_move_assignable_v<_Type> + && is_trivially_destructible_v<_Type>; + _EXPORT_STD template class expected { private: @@ -390,9 +412,7 @@ public: constexpr expected& operator=(const expected& _Other) noexcept( is_nothrow_copy_constructible_v<_Ty> && is_nothrow_copy_constructible_v<_Err> && is_nothrow_copy_assignable_v<_Ty> && is_nothrow_copy_assignable_v<_Err>) // strengthened - requires is_copy_assignable_v<_Ty> && is_copy_constructible_v<_Ty> // - && is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err> - && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>) + requires _Expected_binary_copy_assignable<_Ty, _Err> { if (_Has_value && _Other._Has_value) { _Value = _Other._Value; @@ -408,12 +428,16 @@ public: return *this; } + expected& operator=(const expected&) + requires _Expected_binary_copy_assignable<_Ty, _Err> + && _Trivially_copy_constructible_assignable_destructible<_Ty> + && _Trivially_copy_constructible_assignable_destructible<_Err> + = default; + constexpr expected& operator=(expected&& _Other) noexcept( is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_constructible_v<_Err> && is_nothrow_move_assignable_v<_Ty> && is_nothrow_move_assignable_v<_Err>) - requires is_move_assignable_v<_Ty> && is_move_constructible_v<_Ty> // - && is_move_assignable_v<_Err> && is_move_constructible_v<_Err> - && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>) + requires _Expected_binary_move_assignable<_Ty, _Err> { if (_Has_value && _Other._Has_value) { _Value = _STD move(_Other._Value); @@ -429,6 +453,12 @@ public: return *this; } + expected& operator=(expected&&) + requires _Expected_binary_move_assignable<_Ty, _Err> + && _Trivially_move_constructible_assignable_destructible<_Ty> + && _Trivially_move_constructible_assignable_destructible<_Err> + = default; + template requires (!is_same_v, expected> && !_Is_specialization_v, unexpected> && is_constructible_v<_Ty, _Uty> && is_assignable_v<_Ty&, _Uty> @@ -1162,6 +1192,12 @@ private: bool _Has_value; }; +template +concept _Expected_unary_copy_assignable = is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>; + +template +concept _Expected_unary_move_assignable = is_move_assignable_v<_Err> && is_move_constructible_v<_Err>; + template requires is_void_v<_Ty> class expected<_Ty, _Err> { @@ -1278,7 +1314,7 @@ public: // [expected.void.assign] constexpr expected& operator=(const expected& _Other) noexcept( is_nothrow_copy_constructible_v<_Err> && is_nothrow_copy_assignable_v<_Err>) // strengthened - requires is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err> + requires _Expected_unary_copy_assignable<_Err> { if (_Has_value && _Other._Has_value) { // nothing to do @@ -1297,9 +1333,13 @@ public: return *this; } + expected& operator=(const expected&) + requires _Expected_unary_copy_assignable<_Err> && _Trivially_copy_constructible_assignable_destructible<_Err> + = default; + constexpr expected& operator=(expected&& _Other) noexcept( is_nothrow_move_constructible_v<_Err> && is_nothrow_move_assignable_v<_Err>) - requires is_move_assignable_v<_Err> && is_move_constructible_v<_Err> + requires _Expected_unary_move_assignable<_Err> { if (_Has_value && _Other._Has_value) { // nothing to do @@ -1318,6 +1358,10 @@ public: return *this; } + expected& operator=(expected&&) + requires _Expected_unary_move_assignable<_Err> && _Trivially_move_constructible_assignable_destructible<_Err> + = default; + template requires is_constructible_v<_Err, const _UErr&> && is_assignable_v<_Err&, const _UErr&> constexpr expected& operator=(const unexpected<_UErr>& _Other) noexcept( diff --git a/tests/std/tests/P0323R12_expected/test.cpp b/tests/std/tests/P0323R12_expected/test.cpp index d6f69d5d589..82a748e357c 100644 --- a/tests/std/tests/P0323R12_expected/test.cpp +++ b/tests/std/tests/P0323R12_expected/test.cpp @@ -17,6 +17,8 @@ using namespace std; enum class IsDefaultConstructible : bool { Not, Yes }; enum class IsTriviallyCopyConstructible : bool { Not, Yes }; enum class IsTriviallyMoveConstructible : bool { Not, Yes }; +enum class IsTriviallyCopyAssignable : bool { Not, Yes }; +enum class IsTriviallyMoveAssignable : bool { Not, Yes }; enum class IsTriviallyDestructible : bool { Not, Yes }; enum class IsNothrowConstructible : bool { Not, Yes }; @@ -1186,6 +1188,170 @@ namespace test_expected { test_assignment(); } + // Only test the triviality scenarios that occur in practice. + template + struct TrivialityScenario { + static constexpr auto CopyCtorTriviality = CC; + static constexpr auto MoveCtorTriviality = MC; + static constexpr auto CopyAssignTriviality = CA; + static constexpr auto MoveAssignTriviality = MA; + static constexpr auto DtorTriviality = D; + }; + + // No operations are trivial. + using TrivialityScenario1 = TrivialityScenario; + + // Only destruction is trivial. + using TrivialityScenario2 = TrivialityScenario; + + // Only destruction and move construction are trivial. + using TrivialityScenario3 = TrivialityScenario; + + // Only destruction and move construction/assignment are trivial. + using TrivialityScenario4 = TrivialityScenario; + + // Only destruction and copy/move construction are trivial. + using TrivialityScenario5 = TrivialityScenario; + + // All operations are trivial. + using TrivialityScenario6 = TrivialityScenario; + + // per LWG-4026, see also LLVM-74768 + template + struct TrivialityTester { + PODType val{}; + + TrivialityTester() = default; + + constexpr explicit TrivialityTester(PODType v) noexcept : val{v} {} + + constexpr TrivialityTester(const TrivialityTester& other) noexcept : val{other.val} {} + constexpr TrivialityTester(const TrivialityTester&) + requires (Scenario::CopyCtorTriviality == IsTriviallyCopyConstructible::Yes) + = default; + + constexpr TrivialityTester(TrivialityTester&& other) noexcept : val{other.val} {} + TrivialityTester(TrivialityTester&&) + requires (Scenario::MoveCtorTriviality == IsTriviallyMoveConstructible::Yes) + = default; + + constexpr TrivialityTester& operator=(const TrivialityTester& other) noexcept { + val = other.val; + return *this; + } + TrivialityTester& operator=(const TrivialityTester&) + requires (Scenario::CopyAssignTriviality == IsTriviallyCopyAssignable::Yes) + = default; + + constexpr TrivialityTester& operator=(TrivialityTester&& other) noexcept { + val = other.val; + return *this; + } + TrivialityTester& operator=(TrivialityTester&&) + requires (Scenario::MoveAssignTriviality == IsTriviallyMoveAssignable::Yes) + = default; + + constexpr ~TrivialityTester() {} + ~TrivialityTester() + requires (Scenario::DtorTriviality == IsTriviallyDestructible::Yes) + = default; + }; + + template + constexpr void test_triviality_of_assignment_binary() { + using Val2 = TrivialityTester; + using E = expected; + + static_assert(is_trivially_copy_assignable_v + == (is_trivially_copy_constructible_v && is_trivially_copy_assignable_v + && is_trivially_destructible_v && is_trivially_copy_constructible_v + && is_trivially_copy_assignable_v && is_trivially_destructible_v) ); + static_assert(is_trivially_move_assignable_v + == (is_trivially_move_constructible_v && is_trivially_move_assignable_v + && is_trivially_destructible_v && is_trivially_move_constructible_v + && is_trivially_move_assignable_v && is_trivially_destructible_v) ); + + { + E e1{Val1{42}}; + E e2{unexpect, Val2{'^'}}; + e1 = e2; + assert(!e1.has_value()); + assert(e1.error().val == '^'); + } + { + E e1{Val1{42}}; + E e2{unexpect, Val2{'^'}}; + e1 = move(e2); + assert(!e1.has_value()); + assert(e1.error().val == '^'); + } + { + E e1{Val1{42}}; + E e2{unexpect, Val2{'^'}}; + e2 = e1; + assert(e2.has_value()); + assert(e2.value().val == 42); + } + { + E e1{Val1{42}}; + E e2{unexpect, Val2{'^'}}; + e2 = move(e1); + assert(e2.has_value()); + assert(e2.value().val == 42); + } + } + + template + constexpr void test_triviality_of_assignment() { + using Val = TrivialityTester; + using E = expected; + + static_assert(is_trivially_copy_assignable_v + == (is_trivially_copy_constructible_v && is_trivially_copy_assignable_v + && is_trivially_destructible_v) ); + static_assert(is_trivially_move_assignable_v + == (is_trivially_move_constructible_v && is_trivially_move_assignable_v + && is_trivially_destructible_v) ); + + { + E e1{}; + E e2{unexpect, Val{42}}; + e1 = e2; + assert(!e1.has_value()); + assert(e1.error().val == 42); + } + { + E e1{}; + E e2{unexpect, Val{42}}; + e1 = move(e2); + assert(!e1.has_value()); + assert(e1.error().val == 42); + } + + test_triviality_of_assignment_binary(); + test_triviality_of_assignment_binary(); + test_triviality_of_assignment_binary(); + test_triviality_of_assignment_binary(); + test_triviality_of_assignment_binary(); + test_triviality_of_assignment_binary(); + } + + constexpr void test_triviality_of_assignment_all() { + test_triviality_of_assignment(); + test_triviality_of_assignment(); + test_triviality_of_assignment(); + test_triviality_of_assignment(); + test_triviality_of_assignment(); + test_triviality_of_assignment(); + } + constexpr void test_emplace() noexcept { struct payload_emplace { constexpr payload_emplace(bool& destructor_called) noexcept : _destructor_called(destructor_called) {} @@ -2020,6 +2186,7 @@ namespace test_expected { test_special_members(); test_constructors(); test_assignment(); + test_triviality_of_assignment_all(); // per LWG-4026, see also LLVM-74768 test_emplace(); test_swap(); test_access(); From c1e42b9bb8af9ef8a4df7f8c3a622d4998809968 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 25 Jan 2024 08:24:06 +0800 Subject: [PATCH 05/20] ``: Deprecate TR1 components in the `std` namespace (#4284) Co-authored-by: Stephan T. Lavavej --- stl/inc/random | 232 ++++++++++++++++-- stl/inc/yvals_core.h | 12 +- .../test.compile.pass.cpp | 2 - tests/tr1/tests/random1/test.cpp | 16 +- tests/tr1/tests/random6/test.cpp | 2 + 5 files changed, 240 insertions(+), 24 deletions(-) diff --git a/stl/inc/random b/stl/inc/random index fbac0b707c3..646bcecd35c 100644 --- a/stl/inc/random +++ b/stl/inc/random @@ -534,7 +534,7 @@ private: }; template -class linear_congruential { // linear congruential random engine +class _DEPRECATE_TR1_RANDOM linear_congruential { // linear congruential random engine public: _RNG_REQUIRE_UINTTYPE(linear_congruential, _Uint); @@ -898,7 +898,7 @@ struct _Swc_traits { // traits for subtract_with_carry generator }; template -class subtract_with_carry +class _DEPRECATE_TR1_RANDOM subtract_with_carry : public _Swc_base<_Ty, _Sx, _Rx, _Swc_traits<_Ty, _Mx, _Rx>> { // subtract_with_carry generator public: using _Mybase = _Swc_base<_Ty, _Sx, _Rx, _Swc_traits<_Ty, _Mx, _Rx>>; @@ -915,9 +915,10 @@ public: subtract_with_carry(_Gen& _Gx) : _Mybase(_Gx) {} }; +_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template class subtract_with_carry_engine - : public subtract_with_carry<_Ty, static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1), _Sx, _Rx> { + : private subtract_with_carry<_Ty, static_cast<_Ty>((_Ty{1} << (_Wx - 1)) << 1), _Sx, _Rx> { // subtract_with_carry generator public: _RNG_REQUIRE_UINTTYPE(subtract_with_carry_engine, _Ty); @@ -981,6 +982,26 @@ public: return _Mx - 1; } + _NODISCARD_FRIEND bool operator==( + const subtract_with_carry_engine& _Left, const subtract_with_carry_engine& _Right) noexcept /* strengthened */ { + return static_cast(_Left) == static_cast(_Right); + } + +#if !_HAS_CXX20 + _NODISCARD_FRIEND bool operator!=( + const subtract_with_carry_engine& _Left, const subtract_with_carry_engine& _Right) noexcept /* strengthened */ { + return static_cast(_Left) != static_cast(_Right); + } +#endif // !_HAS_CXX20 + + _NODISCARD result_type operator()() { + return _Mybase::operator()(); + } + + void discard(unsigned long long _Nskip) { + _Mybase::discard(_Nskip); + } + template friend basic_ostream<_Elem, _Traits>& operator<<( basic_ostream<_Elem, _Traits>& _Ostr, const subtract_with_carry_engine& _Eng) { @@ -1019,6 +1040,7 @@ public: return _Istr; } }; +_STL_RESTORE_DEPRECATED_WARNING #if _HAS_TR1_NAMESPACE constexpr double _Cx_exp2(const int _Exp) noexcept { @@ -1108,7 +1130,7 @@ public: #endif // _HAS_TR1_NAMESPACE template -class mersenne_twister : public _Circ_buf<_Ty, _Nx> { // mersenne twister generator +class _DEPRECATE_TR1_RANDOM mersenne_twister : public _Circ_buf<_Ty, _Nx> { // mersenne twister generator public: using result_type = _Ty; @@ -1278,9 +1300,10 @@ protected: static constexpr int _M_mod_n = _Mx % _Nx; }; +_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class mersenne_twister_engine : public mersenne_twister<_Ty, _Wx, _Nx, _Mx, _Rx, _Px, _Ux, _Sx, _Bx, _Tx, _Cx, _Lx> { +class mersenne_twister_engine : private mersenne_twister<_Ty, _Wx, _Nx, _Mx, _Rx, _Px, _Ux, _Sx, _Bx, _Tx, _Cx, _Lx> { public: static constexpr unsigned long long _Max = (((1ULL << (_Wx - 1)) - 1) << 1) + 1; @@ -1360,10 +1383,43 @@ public: _NODISCARD static constexpr result_type(max)() noexcept /* strengthened */ { return _Mybase::_WMSK; } + + _NODISCARD_FRIEND bool operator==( + const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { + return static_cast(_Left) == static_cast(_Right); + } + +#if !_HAS_CXX20 + _NODISCARD_FRIEND bool operator!=( + const mersenne_twister_engine& _Left, const mersenne_twister_engine& _Right) noexcept /* strengthened */ { + return static_cast(_Left) != static_cast(_Right); + } +#endif // !_HAS_CXX20 + + template + friend basic_istream<_Elem, _S_Traits>& operator>>( + basic_istream<_Elem, _S_Traits>& _Istr, mersenne_twister_engine& _Eng) { + return _Istr >> static_cast<_Mybase&>(_Eng); + } + + template + friend basic_ostream<_Elem, _S_Traits>& operator<<( + basic_ostream<_Elem, _S_Traits>& _Ostr, const mersenne_twister_engine& _Eng) { + return _Ostr << static_cast(_Eng); + } + + _NODISCARD result_type operator()() { + return _Mybase::operator()(); + } + + void discard(unsigned long long _Nskip) { + _Mybase::discard(_Nskip); + } }; +_STL_RESTORE_DEPRECATED_WARNING template -class discard_block { // discard_block compound engine +class _DEPRECATE_TR1_RANDOM discard_block { // discard_block compound engine public: #if _HAS_TR1_NAMESPACE using base_type _DEPRECATE_TR1_NAMESPACE = _Engine; // TR1-only typedef @@ -1539,9 +1595,10 @@ private: size_t _Nx; }; +_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template class discard_block_engine // discard_block_engine compound engine - : public conditional_t<_Px <= INT_MAX, discard_block<_Engine, static_cast(_Px), static_cast(_Rx)>, + : private conditional_t<_Px <= INT_MAX, discard_block<_Engine, static_cast(_Px), static_cast(_Rx)>, _Discard_block_base<_Engine, _Px, _Rx>> { public: static_assert(0 < _Rx && _Rx <= _Px, "invalid template argument for discard_block_engine"); @@ -1564,6 +1621,31 @@ public: template = 0> explicit discard_block_engine(_Seed_seq& _Seq) : _Mybase(_Seq) {} + void seed() { + _Mybase::seed(); + } + + void seed(result_type _Xx0) { + _Mybase::seed(_Xx0); + } + + template = 0> + void seed(_Seed_seq& _Seq) { + _Mybase::seed(_Seq); + } + + _NODISCARD const _Engine& base() const noexcept { + return _Mybase::base(); + } + + _NODISCARD result_type operator()() { + return _Mybase::operator()(); + } + + void discard(unsigned long long _Nskip) { + _Mybase::discard(_Nskip); + } + _NODISCARD static constexpr result_type(min)() noexcept /* strengthened */ { return (_Engine::min)(); } @@ -1571,7 +1653,29 @@ public: _NODISCARD static constexpr result_type(max)() noexcept /* strengthened */ { return (_Engine::max)(); } + + _NODISCARD_FRIEND bool operator==(const discard_block_engine& _Left, const discard_block_engine& _Right) { + return static_cast(_Left) == static_cast(_Right); + } + +#if !_HAS_CXX20 + _NODISCARD_FRIEND bool operator!=(const discard_block_engine& _Left, const discard_block_engine& _Right) { + return static_cast(_Left) != static_cast(_Right); + } +#endif // !_HAS_CXX20 + + template + friend basic_istream<_Elem, _Traits>& operator>>(basic_istream<_Elem, _Traits>& _Istr, discard_block_engine& _Eng) { + return _Istr >> static_cast<_Mybase&>(_Eng); + } + + template + friend basic_ostream<_Elem, _Traits>& operator<<( + basic_ostream<_Elem, _Traits>& _Ostr, const discard_block_engine& _Eng) { + return _Ostr << static_cast(_Eng); + } }; +_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD template class independent_bits_engine { // independent_bits_engine compound engine @@ -1969,7 +2073,7 @@ private: }; template -class uniform_int { // uniform integer distribution +class _DEPRECATE_TR1_RANDOM uniform_int { // uniform integer distribution public: using result_type = _Ty; @@ -2112,8 +2216,9 @@ private: param_type _Par; }; +_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class uniform_int_distribution : public uniform_int<_Ty> { // uniform integer distribution +class uniform_int_distribution : private uniform_int<_Ty> { // uniform integer distribution public: _RNG_REQUIRE_INTTYPE(uniform_int_distribution, _Ty); @@ -2143,6 +2248,54 @@ public: explicit uniform_int_distribution(const param_type& _Par0) noexcept // strengthened : _Mybase(_Par0) {} + _NODISCARD result_type a() const noexcept /* strengthened */ { + return _Mybase::a(); + } + + _NODISCARD result_type b() const noexcept /* strengthened */ { + return _Mybase::b(); + } + + _NODISCARD param_type param() const noexcept /* strengthened */ { + return _Mybase::param(); + } + + void param(const param_type& _Par0) noexcept /* strengthened */ { + _Mybase::param(_Par0); + } + + _NODISCARD result_type(min)() const noexcept /* strengthened */ { + return (_Mybase::min)(); + } + + _NODISCARD result_type(max)() const noexcept /* strengthened */ { + return (_Mybase::max)(); + } + + void reset() noexcept /* strengthened */ {} + + template + _NODISCARD result_type operator()(_Engine& _Eng) _DISTRIBUTION_CONST { + return _Mybase::operator()(_Eng); + } + + template + _NODISCARD result_type operator()(_Engine& _Eng, const param_type& _Par0) _DISTRIBUTION_CONST { + return _Mybase::operator()(_Eng, _Par0); + } + + template + friend basic_istream<_Elem, _Traits>& operator>>( + basic_istream<_Elem, _Traits>& _Istr, uniform_int_distribution& _Dist) { + return _Istr >> static_cast<_Mybase&>(_Dist); + } + + template + friend basic_ostream<_Elem, _Traits>& operator<<( + basic_ostream<_Elem, _Traits>& _Ostr, const uniform_int_distribution& _Dist) { + return _Ostr << static_cast(_Dist); + } + _NODISCARD_FRIEND bool operator==( const uniform_int_distribution& _Left, const uniform_int_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); @@ -2155,6 +2308,7 @@ public: } #endif // !_HAS_CXX20 }; +_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD class bernoulli_distribution { // class for bernoulli distribution public: @@ -2828,7 +2982,7 @@ private: }; template -class uniform_real { // uniform real distribution +class _DEPRECATE_TR1_RANDOM uniform_real { // uniform real distribution public: using result_type = _Ty; @@ -2954,8 +3108,9 @@ private: param_type _Par; }; +_STL_DISABLE_DEPRECATED_WARNING _EXPORT_STD template -class uniform_real_distribution : public uniform_real<_Ty> { // uniform real distribution +class uniform_real_distribution : private uniform_real<_Ty> { // uniform real distribution public: _RNG_REQUIRE_REALTYPE(uniform_real_distribution, _Ty); @@ -2984,6 +3139,54 @@ public: explicit uniform_real_distribution(const param_type& _Par0) noexcept // strengthened : _Mybase(_Par0) {} + _NODISCARD result_type a() const noexcept /* strengthened */ { + return _Mybase::a(); + } + + _NODISCARD result_type b() const noexcept /* strengthened */ { + return _Mybase::b(); + } + + _NODISCARD param_type param() const noexcept /* strengthened */ { + return _Mybase::param(); + } + + void param(const param_type& _Par0) noexcept /* strengthened */ { + _Mybase::param(_Par0); + } + + _NODISCARD result_type(min)() const noexcept /* strengthened */ { + return (_Mybase::min)(); + } + + _NODISCARD result_type(max)() const noexcept /* strengthened */ { + return (_Mybase::max)(); + } + + void reset() noexcept /* strengthened */ {} + + template + _NODISCARD result_type operator()(_Engine& _Eng) _DISTRIBUTION_CONST { + return _Mybase::operator()(_Eng); + } + + template + _NODISCARD result_type operator()(_Engine& _Eng, const param_type& _Par0) _DISTRIBUTION_CONST { + return _Mybase::operator()(_Eng, _Par0); + } + + template + friend basic_istream<_Elem, _Traits>& operator>>( + basic_istream<_Elem, _Traits>& _Istr, uniform_real_distribution& _Dist) { + return _Istr >> static_cast<_Mybase&>(_Dist); + } + + template + friend basic_ostream<_Elem, _Traits>& operator<<( + basic_ostream<_Elem, _Traits>& _Ostr, const uniform_real_distribution& _Dist) { + return _Ostr << static_cast(_Dist); + } + _NODISCARD_FRIEND bool operator==( const uniform_real_distribution& _Left, const uniform_real_distribution& _Right) noexcept /* strengthened */ { return _Left.param() == _Right.param(); @@ -2996,6 +3199,7 @@ public: } #endif // !_HAS_CXX20 }; +_STL_RESTORE_DEPRECATED_WARNING _EXPORT_STD template class exponential_distribution { // exponential distribution @@ -4485,7 +4689,7 @@ private: _Ty _Vx2; _Ty _Rx0; _Ty _Rs; - uniform_real<_Ty> _Dist(-1, 1); + uniform_real_distribution<_Ty> _Dist(-1, 1); for (;;) { // get a point inside unit circle _Vx1 = _Dist(_Eng); _Vx2 = _Dist(_Eng); @@ -5020,7 +5224,7 @@ public: template result_type _Eval(_Engine& _Eng, const param_type& _Par0) _DISTRIBUTION_CONST { size_t _Px = _Mybase::operator()(_Eng, _Par0); - uniform_real<_Ty> _Dist(_Par0._Bvec[_Px], _Par0._Bvec[_Px + 1]); + uniform_real_distribution<_Ty> _Dist(_Par0._Bvec[_Px], _Par0._Bvec[_Px + 1]); return _Dist(_Eng); } @@ -5247,7 +5451,7 @@ public: size_t _Px = _Mybase::operator()(_Eng, _Par0); double _Px0 = _Par0._Pvec[_Px]; double _Px1 = _Par0._Pvec[_Px + 1]; - uniform_real<_Ty> _Dist; + uniform_real_distribution<_Ty> _Dist; result_type _Xx0 = _Dist(_Eng); if (_Px0 != _Px1) { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 922a71948d8..b18f335ac48 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1527,7 +1527,17 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define _DEPRECATE_IO_PFX_SFX #endif // ^^^ warning disabled ^^^ -// next warning number: STL4046 +#if _HAS_CXX17 && !defined(_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) \ + && !defined(_SILENCE_TR1_RANDOM_DEPRECATION_WARNING) && !defined(_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS) +#define _DEPRECATE_TR1_RANDOM \ + [[deprecated("warning STL4046: Non-Standard TR1 components in are deprecated and will be REMOVED. You " \ + "can define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING, _SILENCE_TR1_RANDOM_DEPRECATION_WARNING, or " \ + "_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS to suppress this warning.")]] +#else // ^^^ warning enabled / warning disabled vvv +#define _DEPRECATE_TR1_RANDOM +#endif // ^^^ warning disabled ^^^ + +// next warning number: STL4047 // next error number: STL1006 diff --git a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp index 690dd4be34a..fd092034744 100644 --- a/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0000000_instantiate_iterators_misc/test.compile.pass.cpp @@ -1162,8 +1162,6 @@ void random_test() { distribution_test_impl(piece_line_d1); distribution_test_impl(piece_line_d2); distribution_test_impl(piece_line_d3); - - (void) uni_int_d(gen, uni_int_d(gen)); } void ratio_test() { diff --git a/tests/tr1/tests/random1/test.cpp b/tests/tr1/tests/random1/test.cpp index 90eb1e90e4e..1a3af256c8b 100644 --- a/tests/tr1/tests/random1/test.cpp +++ b/tests/tr1/tests/random1/test.cpp @@ -224,13 +224,15 @@ static void tmt19937() { CHECK_INT(rng_t::state_size, 624); CHECK_INT(rng_t::shift_size, 397); CHECK_INT(rng_t::mask_bits, 31); - CHECK_INT((int) rng_t::parameter_a, (int) 0x9908b0df); - CHECK_INT(rng_t::output_u, 11); - CHECK_INT(rng_t::output_s, 7); - CHECK_INT((int) rng_t::output_b, (int) 0x9d2c5680); - CHECK_INT(rng_t::output_t, 15); - CHECK_INT((int) rng_t::output_c, (int) 0xefc60000); - CHECK_INT(rng_t::output_l, 18); + CHECK_INT((int) rng_t::xor_mask, (int) 0x9908b0df); + CHECK_INT(rng_t::tempering_u, 11); + CHECK_INT((int) rng_t::tempering_d, (int) 0xffffffff); + CHECK_INT(rng_t::tempering_s, 7); + CHECK_INT((int) rng_t::tempering_b, (int) 0x9d2c5680); + CHECK_INT(rng_t::tempering_t, 15); + CHECK_INT((int) rng_t::tempering_c, (int) 0xefc60000); + CHECK_INT(rng_t::tempering_l, 18); + CHECK_INT(rng_t::initialization_multiplier, 1812433253); rng_t rng; Int32 res = 0; for (int i = 0; i < 10000; ++i) { diff --git a/tests/tr1/tests/random6/test.cpp b/tests/tr1/tests/random6/test.cpp index 8bccb27c211..04e9a519888 100644 --- a/tests/tr1/tests/random6/test.cpp +++ b/tests/tr1/tests/random6/test.cpp @@ -4,6 +4,8 @@ // test C++11 header, part 6 #define TEST_NAME ", part 6" +#define _SILENCE_TR1_RANDOM_DEPRECATION_WARNING + #include #define FLOAT_TYPE IS_DOUBLE #include "tdefs.h" From cdf609646c360f5560e47ee76d50de4b3be7a46c Mon Sep 17 00:00:00 2001 From: Igor Zhukov Date: Thu, 25 Jan 2024 07:51:48 +0700 Subject: [PATCH 06/20] fix formatting floating-point values without type and precision provided (#4327) --- stl/inc/format | 10 +++++++++- .../tests/P0645R10_text_formatting_formatting/test.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/stl/inc/format b/stl/inc/format index b0b97ca0575..d5e6de99b86 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2967,6 +2967,7 @@ _NODISCARD _OutputIt _Fmt_write( auto _Format = chars_format::general; auto _Exponent = 'e'; auto _Precision = _Specs._Precision; + auto _None_type = false; switch (_Specs._Type) { case 'A': @@ -3003,6 +3004,9 @@ _NODISCARD _OutputIt _Fmt_write( } _Format = chars_format::general; break; + default: + _None_type = true; + break; } // Consider the powers of 2 in decimal: @@ -3043,7 +3047,11 @@ _NODISCARD _OutputIt _Fmt_write( _Result.ptr += 3; } else { if (_Precision == -1) { - _Result = _STD to_chars(_Buffer, _STD end(_Buffer), _Value, _Format); + if (_None_type) { + _Result = _STD to_chars(_Buffer, _STD end(_Buffer), _Value); + } else { + _Result = _STD to_chars(_Buffer, _STD end(_Buffer), _Value, _Format); + } } else { _Result = _STD to_chars(_Buffer, _STD end(_Buffer), _Value, _Format, _Precision); } diff --git a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp index 7dea640f249..f516e4735e7 100644 --- a/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_formatting/test.cpp @@ -1506,6 +1506,12 @@ constexpr bool test_format_string() { return true; } +// Also test GH-4319: incorrect output for some floating-point values +template +void test_gh_4319() { + assert(format(STR("{:}"), 12345678.0) == STR("12345678")); +} + void test() { test_simple_formatting(); test_simple_formatting(); @@ -1582,6 +1588,9 @@ void test() { test_localized_char(); test_localized_char(); test_localized_char(); + + test_gh_4319(); + test_gh_4319(); } int main() { From ee6bdb9a311ea117dee0bf97aeabe990276dbfa1 Mon Sep 17 00:00:00 2001 From: "S. B. Tam" Date: Thu, 25 Jan 2024 09:24:47 +0800 Subject: [PATCH 07/20] Skip libc++'s non-Standard `ascii` tests, reported upstream (#4328) Co-authored-by: Stephan T. Lavavej --- tests/libcxx/expected_results.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index ed3fcb49521..8914643f218 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -37,6 +37,11 @@ std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_mov # LLVM-75611: [libc++] views::take behaves incorrectly for iota_view std/ranges/range.adaptors/range.take/adaptor.pass.cpp FAIL +# LLVM-78661: [libc++][test] Move format.functions ASCII tests to libcxx/test/libcxx +# These test libc++'s non-standard "ascii" mode. +std/utilities/format/format.functions/ascii.pass.cpp SKIPPED +std/utilities/format/format.functions/escaped_output.ascii.pass.cpp SKIPPED + # Non-Standard regex behavior. # "It seems likely that the test is still non-conforming due to how libc++ handles the 'w' character class." std/re/re.traits/lookup_classname.pass.cpp FAIL @@ -944,9 +949,6 @@ std/algorithms/alg.modifying.operations/alg.unique/ranges_unique.pass.cpp:1 SKIP std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_long_double.hex.pass.cpp SKIPPED std/localization/locale.categories/category.numeric/locale.nm.put/facet.num.put.members/put_double.hex.pass.cpp SKIPPED -# Not analyzed. These tests use characters that cannot be represented in legacy character encodings -std/utilities/format/format.functions/ascii.pass.cpp FAIL - # Not analyzed. Failing assert(swaps <= expected). std/algorithms/alg.modifying.operations/alg.rotate/ranges_rotate.pass.cpp FAIL @@ -1026,7 +1028,6 @@ std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/iter_swap.pass std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp FAIL # Not analyzed. MSVC emits truncation warnings, Clang fails a runtime assertion. -std/utilities/format/format.functions/escaped_output.ascii.pass.cpp FAIL std/utilities/format/format.functions/locale-specific_form.pass.cpp FAIL # Not analyzed. From ce257fca4131c5bbec01d007bebb415fc2f72c75 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 25 Jan 2024 09:30:49 +0800 Subject: [PATCH 08/20] Make implicit conversion to `bool` ADL-proof (except for views) (#4334) Co-authored-by: Stephan T. Lavavej --- stl/inc/expected | 6 +- stl/inc/optional | 36 +-- stl/inc/type_traits | 2 +- stl/inc/xutility | 106 ++++--- tests/std/test.lst | 1 + .../GH_000140_adl_proof_comparison/env.lst | 4 + .../test.compile.pass.cpp | 291 ++++++++++++++++++ .../P0896R4_ranges_range_machinery/test.cpp | 136 ++++++++ 8 files changed, 509 insertions(+), 73 deletions(-) create mode 100644 tests/std/tests/GH_000140_adl_proof_comparison/env.lst create mode 100644 tests/std/tests/GH_000140_adl_proof_comparison/test.compile.pass.cpp diff --git a/stl/inc/expected b/stl/inc/expected index 9a72b37f8e1..8a17025e66d 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -95,7 +95,7 @@ public: // [expected.un.eq] template _NODISCARD_FRIEND constexpr bool operator==(const unexpected& _Left, const unexpected<_UErr>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { return _Left._Unexpected == _Right.error(); } @@ -1126,8 +1126,8 @@ public: template requires (!is_void_v<_Uty>) _NODISCARD_FRIEND constexpr bool operator==(const expected& _Left, const expected<_Uty, _UErr>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Value == *_Right)) && noexcept( - _Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left._Value == *_Right)) && noexcept( + _STD _Fake_copy_init(_Left._Unexpected == _Right.error()))) /* strengthened */ { if (_Left._Has_value != _Right.has_value()) { return false; } else if (_Left._Has_value) { diff --git a/stl/inc/optional b/stl/inc/optional index b18ca175333..47fe2d98365 100644 --- a/stl/inc/optional +++ b/stl/inc/optional @@ -623,7 +623,7 @@ optional(_Ty) -> optional<_Ty>; _EXPORT_STD template _NODISCARD constexpr bool operator==(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left == *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left == *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left == *_Right } -> _Implicitly_convertible_to; @@ -640,7 +640,7 @@ _NODISCARD constexpr bool operator==(const optional<_Ty1>& _Left, const optional _EXPORT_STD template _NODISCARD constexpr bool operator!=(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left != *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left != *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left != *_Right } -> _Implicitly_convertible_to; @@ -657,7 +657,7 @@ _NODISCARD constexpr bool operator!=(const optional<_Ty1>& _Left, const optional _EXPORT_STD template _NODISCARD constexpr bool operator<(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left < *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left < *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left < *_Right } -> _Implicitly_convertible_to; @@ -674,7 +674,7 @@ _NODISCARD constexpr bool operator<(const optional<_Ty1>& _Left, const optional< _EXPORT_STD template _NODISCARD constexpr bool operator>(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left > *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left > *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left > *_Right } -> _Implicitly_convertible_to; @@ -691,7 +691,7 @@ _NODISCARD constexpr bool operator>(const optional<_Ty1>& _Left, const optional< _EXPORT_STD template _NODISCARD constexpr bool operator<=(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left <= *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left <= *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left <= *_Right } -> _Implicitly_convertible_to; @@ -708,7 +708,7 @@ _NODISCARD constexpr bool operator<=(const optional<_Ty1>& _Left, const optional _EXPORT_STD template _NODISCARD constexpr bool operator>=(const optional<_Ty1>& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left >= *_Right))) /* strengthened */ + noexcept(_STD _Fake_copy_init(*_Left >= *_Right))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { *_Left >= *_Right } -> _Implicitly_convertible_to; @@ -828,7 +828,7 @@ using _Enable_if_comparable_with_greater_equal = _EXPORT_STD template = 0> _NODISCARD constexpr bool operator==(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left == _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left == _Right))) /* strengthened */ { if (_Left) { return *_Left == _Right; } @@ -837,7 +837,7 @@ _NODISCARD constexpr bool operator==(const optional<_Ty1>& _Left, const _Ty2& _R _EXPORT_STD template = 0> _NODISCARD constexpr bool operator==(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left == *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left == *_Right))) /* strengthened */ { if (_Right) { return _Left == *_Right; } @@ -846,7 +846,7 @@ _NODISCARD constexpr bool operator==(const _Ty1& _Left, const optional<_Ty2>& _R _EXPORT_STD template = 0> _NODISCARD constexpr bool operator!=(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left != _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left != _Right))) /* strengthened */ { if (_Left) { return *_Left != _Right; } @@ -854,7 +854,7 @@ _NODISCARD constexpr bool operator!=(const optional<_Ty1>& _Left, const _Ty2& _R } _EXPORT_STD template = 0> _NODISCARD constexpr bool operator!=(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left != *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left != *_Right))) /* strengthened */ { if (_Right) { return _Left != *_Right; } @@ -863,7 +863,7 @@ _NODISCARD constexpr bool operator!=(const _Ty1& _Left, const optional<_Ty2>& _R _EXPORT_STD template = 0> _NODISCARD constexpr bool operator<(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left < _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left < _Right))) /* strengthened */ { if (_Left) { return *_Left < _Right; } @@ -871,7 +871,7 @@ _NODISCARD constexpr bool operator<(const optional<_Ty1>& _Left, const _Ty2& _Ri } _EXPORT_STD template = 0> _NODISCARD constexpr bool operator<(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left < *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left < *_Right))) /* strengthened */ { if (_Right) { return _Left < *_Right; } @@ -880,7 +880,7 @@ _NODISCARD constexpr bool operator<(const _Ty1& _Left, const optional<_Ty2>& _Ri _EXPORT_STD template = 0> _NODISCARD constexpr bool operator>(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left > _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left > _Right))) /* strengthened */ { if (_Left) { return *_Left > _Right; } @@ -888,7 +888,7 @@ _NODISCARD constexpr bool operator>(const optional<_Ty1>& _Left, const _Ty2& _Ri } _EXPORT_STD template = 0> _NODISCARD constexpr bool operator>(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left > *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left > *_Right))) /* strengthened */ { if (_Right) { return _Left > *_Right; } @@ -897,7 +897,7 @@ _NODISCARD constexpr bool operator>(const _Ty1& _Left, const optional<_Ty2>& _Ri _EXPORT_STD template = 0> _NODISCARD constexpr bool operator<=(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left <= _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left <= _Right))) /* strengthened */ { if (_Left) { return *_Left <= _Right; } @@ -905,7 +905,7 @@ _NODISCARD constexpr bool operator<=(const optional<_Ty1>& _Left, const _Ty2& _R } _EXPORT_STD template = 0> _NODISCARD constexpr bool operator<=(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left <= *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left <= *_Right))) /* strengthened */ { if (_Right) { return _Left <= *_Right; } @@ -914,7 +914,7 @@ _NODISCARD constexpr bool operator<=(const _Ty1& _Left, const optional<_Ty2>& _R _EXPORT_STD template = 0> _NODISCARD constexpr bool operator>=(const optional<_Ty1>& _Left, const _Ty2& _Right) noexcept( - noexcept(_Fake_copy_init(*_Left >= _Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(*_Left >= _Right))) /* strengthened */ { if (_Left) { return *_Left >= _Right; } @@ -922,7 +922,7 @@ _NODISCARD constexpr bool operator>=(const optional<_Ty1>& _Left, const _Ty2& _R } _EXPORT_STD template = 0> _NODISCARD constexpr bool operator>=(const _Ty1& _Left, const optional<_Ty2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left >= *_Right))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left >= *_Right))) /* strengthened */ { if (_Right) { return _Left >= *_Right; } diff --git a/stl/inc/type_traits b/stl/inc/type_traits index d1a88f9c28b..0d121913bf4 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -2441,7 +2441,7 @@ struct less { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left < _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left < _Right))) /* strengthened */ { return _Left < _Right; } }; diff --git a/stl/inc/xutility b/stl/inc/xutility index 7a65a8d66fd..20cdaefd7e5 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -391,7 +391,7 @@ struct equal_to { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left == _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left == _Right))) /* strengthened */ { return _Left == _Right; } }; @@ -403,7 +403,7 @@ struct not_equal_to { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left != _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left != _Right))) /* strengthened */ { return _Left != _Right; } }; @@ -415,7 +415,7 @@ struct greater { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left > _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left > _Right))) /* strengthened */ { return _Left > _Right; } }; @@ -427,7 +427,7 @@ struct greater_equal { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left >= _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left >= _Right))) /* strengthened */ { return _Left >= _Right; } }; @@ -439,7 +439,7 @@ struct less_equal { using _RESULT_TYPE_NAME _CXX17_DEPRECATE_ADAPTOR_TYPEDEFS = bool; _NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const - noexcept(noexcept(_Fake_copy_init(_Left <= _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Left <= _Right))) /* strengthened */ { return _Left <= _Right; } }; @@ -1491,7 +1491,7 @@ _INLINE_VAR constexpr bool _Has_nothrow_operator_arrow = _Is_nothrow_convertible template _INLINE_VAR constexpr bool _Has_nothrow_operator_arrow<_Iter, _Pointer, false> = - noexcept(_Fake_copy_init<_Pointer>(_STD declval<_Iter>().operator->())); + noexcept(_STD _Fake_copy_init<_Pointer>(_STD declval<_Iter>().operator->())); _EXPORT_STD template class reverse_iterator { @@ -1614,7 +1614,7 @@ public: } _NODISCARD _CONSTEXPR17 reference operator[](const difference_type _Off) const - noexcept(noexcept(_Fake_copy_init(current[_Off]))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(current[_Off]))) /* strengthened */ { return current[static_cast(-_Off - 1)]; } @@ -1683,7 +1683,7 @@ protected: _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator==(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() == _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() == _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() == _Right._Get_current() } -> _Implicitly_convertible_to; @@ -1696,7 +1696,7 @@ _NODISCARD _CONSTEXPR17 bool _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator!=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() != _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() != _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() != _Right._Get_current() } -> _Implicitly_convertible_to; @@ -1709,7 +1709,7 @@ _NODISCARD _CONSTEXPR17 bool _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator<(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() > _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() > _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() > _Right._Get_current() } -> _Implicitly_convertible_to; @@ -1722,7 +1722,7 @@ _NODISCARD _CONSTEXPR17 bool _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator>(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() < _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() < _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() < _Right._Get_current() } -> _Implicitly_convertible_to; @@ -1735,7 +1735,7 @@ _NODISCARD _CONSTEXPR17 bool _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator<=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() >= _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() >= _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() >= _Right._Get_current() } -> _Implicitly_convertible_to; @@ -1748,7 +1748,7 @@ _NODISCARD _CONSTEXPR17 bool _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator>=(const reverse_iterator<_BidIt1>& _Left, const reverse_iterator<_BidIt2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Get_current() <= _Right._Get_current()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left._Get_current() <= _Right._Get_current()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left._Get_current() <= _Right._Get_current() } -> _Implicitly_convertible_to; @@ -2132,7 +2132,7 @@ public: template _Sent> _NODISCARD constexpr bool operator==(const _Sent& _Se) const - noexcept(noexcept(_Fake_copy_init(_Current == _Se))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Current == _Se))) /* strengthened */ { return _Current == _Se; } @@ -2150,28 +2150,28 @@ public: } _NODISCARD constexpr bool operator<(const basic_const_iterator& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current < _Right._Current))) // strengthened + noexcept(noexcept(_STD _Fake_copy_init(_Current < _Right._Current))) // strengthened requires random_access_iterator<_Iter> { return _Current < _Right._Current; } _NODISCARD constexpr bool operator>(const basic_const_iterator& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current > _Right._Current))) // strengthened + noexcept(noexcept(_STD _Fake_copy_init(_Current > _Right._Current))) // strengthened requires random_access_iterator<_Iter> { return _Current > _Right._Current; } _NODISCARD constexpr bool operator<=(const basic_const_iterator& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current <= _Right._Current))) // strengthened + noexcept(noexcept(_STD _Fake_copy_init(_Current <= _Right._Current))) // strengthened requires random_access_iterator<_Iter> { return _Current <= _Right._Current; } _NODISCARD constexpr bool operator>=(const basic_const_iterator& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current >= _Right._Current))) // strengthened + noexcept(noexcept(_STD _Fake_copy_init(_Current >= _Right._Current))) // strengthened requires random_access_iterator<_Iter> { return _Current >= _Right._Current; @@ -2187,28 +2187,28 @@ public: template <_Different_from _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD constexpr bool operator<(const _Other& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current < _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Current < _Right))) /* strengthened */ { return _Current < _Right; } template <_Different_from _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD constexpr bool operator>(const _Other& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current > _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Current > _Right))) /* strengthened */ { return _Current > _Right; } template <_Different_from _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD constexpr bool operator<=(const _Other& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current <= _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Current <= _Right))) /* strengthened */ { return _Current <= _Right; } template <_Different_from _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD constexpr bool operator>=(const _Other& _Right) const - noexcept(noexcept(_Fake_copy_init(_Current >= _Right))) /* strengthened */ { + noexcept(noexcept(_STD _Fake_copy_init(_Current >= _Right))) /* strengthened */ { return _Current >= _Right; } @@ -2223,28 +2223,28 @@ public: template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD_FRIEND constexpr bool operator<(const _Other& _Left, const basic_const_iterator& _Right) noexcept( - noexcept(_Fake_copy_init(_Left < _Right._Current))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left < _Right._Current))) /* strengthened */ { return _Left < _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD_FRIEND constexpr bool operator>(const _Other& _Left, const basic_const_iterator& _Right) noexcept( - noexcept(_Fake_copy_init(_Left > _Right._Current))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left > _Right._Current))) /* strengthened */ { return _Left > _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD_FRIEND constexpr bool operator<=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( - noexcept(_Fake_copy_init(_Left <= _Right._Current))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left <= _Right._Current))) /* strengthened */ { return _Left <= _Right._Current; } template <_Not_a_const_iterator _Other> requires random_access_iterator<_Iter> && totally_ordered_with<_Iter, _Other> _NODISCARD_FRIEND constexpr bool operator>=(const _Other& _Left, const basic_const_iterator& _Right) noexcept( - noexcept(_Fake_copy_init(_Left >= _Right._Current))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left >= _Right._Current))) /* strengthened */ { return _Left >= _Right._Current; } @@ -2342,12 +2342,12 @@ namespace ranges { template concept _Has_member = requires(_Ty __t) { - { _Fake_copy_init(__t.begin()) } -> input_or_output_iterator; + { _STD _Fake_copy_init(__t.begin()) } -> input_or_output_iterator; }; template concept _Has_ADL = _Has_class_or_enum_type<_Ty> && requires(_Ty __t) { - { _Fake_copy_init(begin(__t)) } -> input_or_output_iterator; // intentional ADL + { _STD _Fake_copy_init(begin(__t)) } -> input_or_output_iterator; // intentional ADL }; class _Cpo { @@ -2364,9 +2364,10 @@ namespace ranges { "and std::ranges::data do not accept arrays with incomplete element types."); return {_St::_Array, true}; } else if constexpr (_Has_member<_Ty>) { - return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>().begin()))}; + return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>().begin()))}; } else if constexpr (_Has_ADL<_Ty>) { - return {_St::_Non_member, noexcept(_Fake_copy_init(begin(_STD declval<_Ty>())))}; // intentional ADL + return {_St::_Non_member, + noexcept(_STD _Fake_copy_init(begin(_STD declval<_Ty>())))}; // intentional ADL } else { return {_St::_None}; } @@ -2410,12 +2411,12 @@ namespace ranges { template concept _Has_member = requires(_Ty __t) { - { _Fake_copy_init(__t.end()) } -> sentinel_for>; + { _STD _Fake_copy_init(__t.end()) } -> sentinel_for>; }; template concept _Has_ADL = _Has_class_or_enum_type<_Ty> && requires(_Ty __t) { - { _Fake_copy_init(end(__t)) } -> sentinel_for>; // intentional ADL + { _STD _Fake_copy_init(end(__t)) } -> sentinel_for>; // intentional ADL }; class _Cpo { @@ -2438,9 +2439,10 @@ namespace ranges { return {_St::_None}; } } else if constexpr (_Has_member<_Ty>) { - return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>().end()))}; + return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>().end()))}; } else if constexpr (_Has_ADL<_Ty>) { - return {_St::_Non_member, noexcept(_Fake_copy_init(end(_STD declval<_Ty>())))}; // intentional ADL + return { + _St::_Non_member, noexcept(_STD _Fake_copy_init(end(_STD declval<_Ty>())))}; // intentional ADL } else { return {_St::_None}; } @@ -2764,12 +2766,12 @@ namespace ranges { template concept _Has_member = requires(_Ty __t) { - { _Fake_copy_init(__t.rbegin()) } -> input_or_output_iterator; + { _STD _Fake_copy_init(__t.rbegin()) } -> input_or_output_iterator; }; template concept _Has_ADL = _Has_class_or_enum_type<_Ty> && requires(_Ty __t) { - { _Fake_copy_init(rbegin(__t)) } -> input_or_output_iterator; // intentional ADL + { _STD _Fake_copy_init(rbegin(__t)) } -> input_or_output_iterator; // intentional ADL }; template @@ -2786,10 +2788,10 @@ namespace ranges { _NODISCARD static consteval _Choice_t<_St> _Choose() noexcept { _STL_INTERNAL_STATIC_ASSERT(is_lvalue_reference_v<_Ty>); if constexpr (_Has_member<_Ty>) { - return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>().rbegin()))}; + return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>().rbegin()))}; } else if constexpr (_Has_ADL<_Ty>) { - return { - _St::_Non_member, noexcept(_Fake_copy_init(rbegin(_STD declval<_Ty>())))}; // intentional ADL + return {_St::_Non_member, + noexcept(_STD _Fake_copy_init(rbegin(_STD declval<_Ty>())))}; // intentional ADL } else if constexpr (_Can_make_reverse<_Ty>) { return {_St::_Make_reverse, noexcept(_STD make_reverse_iterator(_RANGES end(_STD declval<_Ty>())))}; } else { @@ -2832,13 +2834,13 @@ namespace ranges { template concept _Has_member = requires(_Ty __t) { - { _Fake_copy_init(__t.rend()) } -> sentinel_for; + { _STD _Fake_copy_init(__t.rend()) } -> sentinel_for; }; template concept _Has_ADL = _Has_class_or_enum_type<_Ty> && requires(_Ty __t) { // intentional ADL - { _Fake_copy_init(rend(__t)) } -> sentinel_for; + { _STD _Fake_copy_init(rend(__t)) } -> sentinel_for; }; template @@ -2855,9 +2857,10 @@ namespace ranges { _NODISCARD static consteval _Choice_t<_St> _Choose() noexcept { _STL_INTERNAL_STATIC_ASSERT(is_lvalue_reference_v<_Ty>); if constexpr (_Has_member<_Ty>) { - return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>().rend()))}; + return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>().rend()))}; } else if constexpr (_Has_ADL<_Ty>) { - return {_St::_Non_member, noexcept(_Fake_copy_init(rend(_STD declval<_Ty>())))}; // intentional ADL + return { + _St::_Non_member, noexcept(_STD _Fake_copy_init(rend(_STD declval<_Ty>())))}; // intentional ADL } else if constexpr (_Can_make_reverse<_Ty>) { return { _St::_Make_reverse, noexcept(_STD make_reverse_iterator(_RANGES begin(_STD declval<_Ty>())))}; @@ -2964,12 +2967,12 @@ namespace ranges { template concept _Has_member = !disable_sized_range<_UnCV> && requires(_Ty __t) { - { _Fake_copy_init(__t.size()) } -> _Integer_like; + { _STD _Fake_copy_init(__t.size()) } -> _Integer_like; }; template concept _Has_ADL = _Has_class_or_enum_type<_Ty> && !disable_sized_range<_UnCV> && requires(_Ty __t) { - { _Fake_copy_init(size(__t)) } -> _Integer_like; // intentional ADL + { _STD _Fake_copy_init(size(__t)) } -> _Integer_like; // intentional ADL }; template @@ -2994,9 +2997,10 @@ namespace ranges { return {_St::_None}; } } else if constexpr (_Has_member<_Ty, _UnCV>) { - return {_St::_Member, noexcept(_Fake_copy_init(_STD declval<_Ty>().size()))}; + return {_St::_Member, noexcept(_STD _Fake_copy_init(_STD declval<_Ty>().size()))}; } else if constexpr (_Has_ADL<_Ty, _UnCV>) { - return {_St::_Non_member, noexcept(_Fake_copy_init(size(_STD declval<_Ty>())))}; // intentional ADL + return { + _St::_Non_member, noexcept(_STD _Fake_copy_init(size(_STD declval<_Ty>())))}; // intentional ADL } else if constexpr (_Can_difference<_Ty>) { return {_St::_Subtract, noexcept(_RANGES end(_STD declval<_Ty>()) - _RANGES begin(_STD declval<_Ty>()))}; @@ -3102,7 +3106,7 @@ namespace ranges { template concept _Has_member = requires(_Ty __t) { - { _Fake_copy_init(__t.data()) } -> _Points_to_object; + { _STD _Fake_copy_init(__t.data()) } -> _Points_to_object; }; template @@ -4132,7 +4136,7 @@ public: template _Sent> _NODISCARD_FRIEND constexpr bool operator==(const move_iterator& _Left, const move_sentinel<_Sent>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left._Current == _Right._Get_last()))) /* strengthened */ { + noexcept(_STD _Fake_copy_init(_Left._Current == _Right._Get_last()))) /* strengthened */ { return _Left._Current == _Right._Get_last(); } @@ -4215,7 +4219,7 @@ private: _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator==(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left.base() == _Right.base()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left.base() == _Right.base()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left.base() == _Right.base() } -> _Implicitly_convertible_to; @@ -4236,7 +4240,7 @@ _NODISCARD _CONSTEXPR17 bool operator!=(const move_iterator<_Iter1>& _Left, _EXPORT_STD template _NODISCARD _CONSTEXPR17 bool operator<(const move_iterator<_Iter1>& _Left, const move_iterator<_Iter2>& _Right) noexcept( - noexcept(_Fake_copy_init(_Left.base() < _Right.base()))) /* strengthened */ + noexcept(_STD _Fake_copy_init(_Left.base() < _Right.base()))) /* strengthened */ #ifdef __cpp_lib_concepts requires requires { { _Left.base() < _Right.base() } -> _Implicitly_convertible_to; diff --git a/tests/std/test.lst b/tests/std/test.lst index 5d33546ab75..23a3ac90014 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -155,6 +155,7 @@ tests\Dev11_1140665_unique_ptr_array_conversions tests\Dev11_1150223_shared_mutex tests\Dev11_1158803_regex_thread_safety tests\Dev11_1180290_filesystem_error_code +tests\GH_000140_adl_proof_comparison tests\GH_000177_forbidden_aliasing tests\GH_000178_uniform_int tests\GH_000342_filebuf_close diff --git a/tests/std/tests/GH_000140_adl_proof_comparison/env.lst b/tests/std/tests/GH_000140_adl_proof_comparison/env.lst new file mode 100644 index 00000000000..19f025bd0e6 --- /dev/null +++ b/tests/std/tests/GH_000140_adl_proof_comparison/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/GH_000140_adl_proof_comparison/test.compile.pass.cpp b/tests/std/tests/GH_000140_adl_proof_comparison/test.compile.pass.cpp new file mode 100644 index 00000000000..003d16eadae --- /dev/null +++ b/tests/std/tests/GH_000140_adl_proof_comparison/test.compile.pass.cpp @@ -0,0 +1,291 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef _M_CEE // TRANSITION, VSO-1659496 +#include +#include +#include +#include +#include + +#if _HAS_CXX17 +#include +#endif // _HAS_CXX17 + +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 +#include +#endif // _HAS_CXX20 && defined(__cpp_lib_concepts) + +#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 +#include +#endif // _HAS_CXX23 && defined(__cpp_lib_concepts) + +using namespace std; + +template +struct tagged_bool_like { + bool val_; + constexpr operator bool() const noexcept { + return val_; + } +}; + +template +struct holder { + T t; +}; + +struct incomplete; + +using validating_bool_like = tagged_bool_like>; + +constexpr holder* placeholder = nullptr; +constexpr holder* const* placeholder_addr = &placeholder; + +struct test_comparable { + friend constexpr validating_bool_like operator==(const test_comparable&, const test_comparable&) noexcept { + return {true}; + } + friend constexpr validating_bool_like operator!=(const test_comparable&, const test_comparable&) noexcept { + return {false}; + } + friend constexpr validating_bool_like operator<(const test_comparable&, const test_comparable&) noexcept { + return {false}; + } + friend constexpr validating_bool_like operator>(const test_comparable&, const test_comparable&) noexcept { + return {false}; + } + friend constexpr validating_bool_like operator<=(const test_comparable&, const test_comparable&) noexcept { + return {true}; + } + friend constexpr validating_bool_like operator>=(const test_comparable&, const test_comparable&) noexcept { + return {true}; + } +}; + +template +struct validating_iterator_provider { + struct iterator; +}; + +template +constexpr bool is_validating_iterator = false; +template +constexpr bool is_validating_iterator> = + is_same_v>::iterator>; + +template +struct validating_iterator_provider::iterator { + using value_type = remove_cv_t; + using pointer = T*; + using reference = T&; + using difference_type = ptrdiff_t; + using iterator_category = random_access_iterator_tag; +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 + using iterator_concept = contiguous_iterator_tag; +#endif // _HAS_CXX20 && defined(__cpp_lib_concepts) + + constexpr T& operator*() const noexcept { + return *ptr_; + } + + constexpr T* operator->() const noexcept { + return ptr_; + } + + constexpr T& operator[](const ptrdiff_t n) const noexcept { + return ptr_[n]; + } + + constexpr iterator& operator++() noexcept { + ++ptr_; + return *this; + } + constexpr iterator operator++(int) noexcept { + auto old = *this; + ++*this; + return old; + } + + constexpr iterator& operator--() noexcept { + --ptr_; + return *this; + } + constexpr iterator operator--(int) noexcept { + auto old = *this; + --*this; + return old; + } + + constexpr iterator& operator+=(const ptrdiff_t n) noexcept { + ptr_ += n; + return *this; + } + + constexpr iterator& operator-=(const ptrdiff_t n) noexcept { + ptr_ -= n; + return *this; + } + + friend constexpr iterator operator+(const iterator i, const ptrdiff_t n) noexcept { + return {i.ptr_ + n}; + } + friend constexpr iterator operator+(const ptrdiff_t n, const iterator i) noexcept { + return {i.ptr_ + n}; + } + + friend constexpr ptrdiff_t operator-(const iterator i, const iterator j) noexcept { + return i.ptr_ - j.ptr_; + } + friend constexpr iterator operator-(const iterator i, const ptrdiff_t n) noexcept { + return iterator{i.ptr_ - n}; + } + + template , int> = 0> + friend constexpr auto operator==(iterator i, OtherIter j) noexcept + -> decltype(pointer{} == typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() == j.operator->() ? placeholder_addr : nullptr; + } + template , int> = 0> + friend constexpr auto operator!=(iterator i, OtherIter j) noexcept + -> decltype(pointer{} != typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() != j.operator->() ? placeholder_addr : nullptr; + } + + template , int> = 0> + friend constexpr auto operator<(iterator i, OtherIter j) noexcept + -> decltype(pointer{} < typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() < j.operator->() ? placeholder_addr : nullptr; + } + template , int> = 0> + friend constexpr auto operator>(iterator i, OtherIter j) noexcept + -> decltype(pointer{} > typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() > j.operator->() ? placeholder_addr : nullptr; + } + template , int> = 0> + friend constexpr auto operator<=(iterator i, OtherIter j) noexcept + -> decltype(pointer{} <= typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() <= j.operator->() ? placeholder_addr : nullptr; + } + template , int> = 0> + friend constexpr auto operator>=(iterator i, OtherIter j) noexcept + -> decltype(pointer{} >= typename OtherIter::pointer{} ? placeholder_addr : nullptr) { + return i.operator->() >= j.operator->() ? placeholder_addr : nullptr; + } + + template // + && is_validating_iterator // + && is_convertible_v, + int> = 0> + constexpr operator OtherIter() const noexcept { + return {ptr_}; + } + + T* ptr_; +}; + +void test_adl_proof_legacy_comparison_functors() { + (void) equal_to{}(test_comparable{}, test_comparable{}); + (void) not_equal_to{}(test_comparable{}, test_comparable{}); + (void) less{}(test_comparable{}, test_comparable{}); + (void) greater{}(test_comparable{}, test_comparable{}); + (void) less_equal{}(test_comparable{}, test_comparable{}); + (void) greater_equal{}(test_comparable{}, test_comparable{}); +} + +template +void test_adl_proof_comparison() { + L l{}; + R r{}; + + (void) (l == r); + (void) (l != r); + (void) (l < r); + (void) (l > r); + (void) (l <= r); + (void) (l >= r); +} + +void test_adl_proof_reverse_iterator_comparison() { + using validating_iter = validating_iterator_provider*>::iterator; + holder* p{}; + + reverse_iterator rit{validating_iter{&p + 1}}; + (void) rit.operator->(); + (void) rit[0]; + + using I = reverse_iterator::iterator>; + using J = reverse_iterator::iterator>; + + test_adl_proof_comparison(); + test_adl_proof_comparison(); +} + +void test_adl_proof_move_iterator_comparison() { + using I = move_iterator::iterator>; + using J = move_iterator::iterator>; + + test_adl_proof_comparison(); + test_adl_proof_comparison(); + +#if _HAS_CXX20 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 + I i{}; + move_sentinel::iterator> s{}; + + (void) (i == s); + (void) (i != s); +#endif // _HAS_CXX20 && defined(__cpp_lib_concepts) +} + +#if _HAS_CXX17 +void test_adl_proof_optional_comparison() { + using V = test_comparable; + using O = optional; + + test_adl_proof_comparison(); + test_adl_proof_comparison(); + test_adl_proof_comparison(); +} +#endif // _HAS_CXX17 + +#if _HAS_CXX23 && defined(__cpp_lib_concepts) // TRANSITION, GH-395 +void test_adl_proof_expected_comparison() { + expected ex; + (void) (ex == ex); + (void) (ex != ex); + + expected vex; + (void) (vex == vex); + (void) (vex != vex); + + unexpected unex{test_comparable{}}; + (void) (unex == unex); + (void) (unex != unex); +} + +void test_adl_proof_basic_const_iterator_comparison() { + using I = validating_iterator_provider::iterator; + using J = validating_iterator_provider::iterator; + + using CI = basic_const_iterator::iterator>; + using CJ = basic_const_iterator::iterator>; + + test_adl_proof_comparison(); + test_adl_proof_comparison(); + test_adl_proof_comparison(); + test_adl_proof_comparison(); + + test_adl_proof_comparison(); + test_adl_proof_comparison(); + test_adl_proof_comparison(); + test_adl_proof_comparison(); + + test_adl_proof_comparison(); + test_adl_proof_comparison(); + + test_adl_proof_comparison(); + test_adl_proof_comparison(); +} +#endif // _HAS_CXX23 && defined(__cpp_lib_concepts) + +#endif // _M_CEE diff --git a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp index 86b2371cec1..2b7d02ff42e 100644 --- a/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp +++ b/tests/std/tests/P0896R4_ranges_range_machinery/test.cpp @@ -2001,6 +2001,142 @@ namespace poison_pill_test { STATIC_ASSERT(CanSize); } // namespace poison_pill_test +#ifndef _M_CEE // TRANSITION, VSO-1659496 +// N.B. reverse_iterator*> can't be made ADL-proof and doesn't model bidirectional_iterator, +// so the rbegin()/rend() member functions return the same iterators as begin()/end(). +namespace adl_proof_test { + struct validating_member_range { + value_holder* elems_[1]; + + constexpr value_holder** begin() noexcept { + return elems_; + } + constexpr value_holder* const* begin() const noexcept { + return elems_; + } + + constexpr value_holder** end() noexcept { + return elems_ + 1; + } + constexpr value_holder* const* end() const noexcept { + return elems_ + 1; + } + + constexpr value_holder** rbegin() noexcept { + return elems_; + } + constexpr value_holder* const* rbegin() const noexcept { + return elems_; + } + + constexpr value_holder** rend() noexcept { + return elems_ + 1; + } + constexpr value_holder* const* rend() const noexcept { + return elems_ + 1; + } + + constexpr value_holder** data() noexcept { + return elems_; + } + constexpr value_holder* const* data() const noexcept { + return elems_; + } + }; + + STATIC_ASSERT(CanBegin); + STATIC_ASSERT(CanBegin); + STATIC_ASSERT(CanCBegin); + STATIC_ASSERT(CanCBegin); + + STATIC_ASSERT(CanEnd); + STATIC_ASSERT(CanEnd); + STATIC_ASSERT(CanCEnd); + STATIC_ASSERT(CanCEnd); + + STATIC_ASSERT(CanRBegin); + STATIC_ASSERT(CanRBegin); + STATIC_ASSERT(CanCRBegin); + STATIC_ASSERT(CanCRBegin); + + STATIC_ASSERT(CanREnd); + STATIC_ASSERT(CanREnd); + STATIC_ASSERT(CanCREnd); + STATIC_ASSERT(CanCREnd); + + STATIC_ASSERT(CanData); + STATIC_ASSERT(CanData); + STATIC_ASSERT(CanCData); + STATIC_ASSERT(CanCData); + + struct validating_nonmember_range { + value_holder* elems_[1]; + + friend constexpr value_holder** begin(validating_nonmember_range& r) noexcept { + return r.elems_; + } + friend constexpr value_holder* const* begin(const validating_nonmember_range& r) noexcept { + return r.elems_; + } + + friend constexpr value_holder** end(validating_nonmember_range& r) noexcept { + return r.elems_ + 1; + } + friend constexpr value_holder* const* end(const validating_nonmember_range& r) noexcept { + return r.elems_ + 1; + } + + friend constexpr value_holder** rbegin(validating_nonmember_range& r) noexcept { + return r.elems_; + } + friend constexpr value_holder* const* rbegin(const validating_nonmember_range& r) noexcept { + return r.elems_; + } + + friend constexpr value_holder** rend(validating_nonmember_range& r) noexcept { + return r.elems_ + 1; + } + friend constexpr value_holder* const* rend(const validating_nonmember_range& r) noexcept { + return r.elems_ + 1; + } + }; + + STATIC_ASSERT(CanBegin); + STATIC_ASSERT(CanBegin); + STATIC_ASSERT(CanCBegin); + STATIC_ASSERT(CanCBegin); + + STATIC_ASSERT(CanEnd); + STATIC_ASSERT(CanEnd); + STATIC_ASSERT(CanCEnd); + STATIC_ASSERT(CanCEnd); + + STATIC_ASSERT(CanRBegin); + STATIC_ASSERT(CanRBegin); + STATIC_ASSERT(CanCRBegin); + STATIC_ASSERT(CanCRBegin); + + STATIC_ASSERT(CanREnd); + STATIC_ASSERT(CanREnd); + STATIC_ASSERT(CanCREnd); + STATIC_ASSERT(CanCREnd); + + struct nonsizable_type { + constexpr value_holder* size() const noexcept { + return nullptr; + } + + friend constexpr value_holder* size(nonsizable_type) noexcept { + return nullptr; + } + }; + + STATIC_ASSERT(CanSize); + STATIC_ASSERT(CanSize); + STATIC_ASSERT(!CanSize); +} // namespace adl_proof_test +#endif // _M_CEE + namespace unwrapped_begin_end { // Validate the iterator-unwrapping range access CPOs ranges::_Ubegin and ranges::_Uend using test::CanCompare, test::CanDifference, test::Common, test::ProxyRef, test::Sized, test::WrappedState; From d2d7fccb47273d033c38c27ebb3d3246618656dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Thu, 25 Jan 2024 02:33:46 +0100 Subject: [PATCH 09/20] Run CTest tests serially to avoid oversubscribing cores (#4335) --- tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2cb6e24e969..811886ce5be 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -41,3 +41,4 @@ list(APPEND STLASAN_LIT_COMMAND "${STL_LIT_OUTPUT}" add_test(NAME stl COMMAND ${Python_EXECUTABLE} ${STL_LIT_COMMAND} COMMAND_EXPAND_LISTS) add_test(NAME stlasan COMMAND ${Python_EXECUTABLE} ${STLASAN_LIT_COMMAND} COMMAND_EXPAND_LISTS) +set_tests_properties(stl stlasan PROPERTIES RUN_SERIAL ON) From 223e297e809d190694fc49f7d994f6f46d0a2053 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 24 Jan 2024 17:37:35 -0800 Subject: [PATCH 10/20] Clarify some ASan-related libcxx FAILs (#4336) --- tests/libcxx/expected_results.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 8914643f218..b5780ecd5ed 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -196,17 +196,17 @@ std/modules/std.pass.cpp FAIL # *** ASAN FAILURES *** -# ASAN runtime warns about an overlarge allocation and panics when it should throw bad_alloc instead -# (VSO-1854252, VSO-1854240, VSO-1854255, VSO-1854247, VSO-1854256) +# Even with `allocator_may_return_null=1`, ASan kills oversized allocations instead of throwing `bad_alloc`. +# (https://github.com/google/sanitizers/issues/295) +std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp:1 FAIL +std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp:1 FAIL +std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp:1 FAIL +std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp:1 FAIL std/strings/basic.string/string.capacity/max_size.pass.cpp:1 FAIL -# ASAN runtime warns about an overlarge allocation and doesn't call new_handler (VSO-1854235, VSO-1854568, VSO-1854400, VSO-1854248) -std/language.support/support.dynamic/new.delete/new.delete.array/new.size.pass.cpp:1 FAIL -std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align.pass.cpp:1 FAIL +# Even with `allocator_may_return_null=1`, ASan doesn't call `new_handler` on allocation failure. (LLVM-15544) std/language.support/support.dynamic/new.delete/new.delete.array/new.size_align_nothrow.pass.cpp:1 FAIL std/language.support/support.dynamic/new.delete/new.delete.array/new.size_nothrow.pass.cpp:1 FAIL -std/language.support/support.dynamic/new.delete/new.delete.single/new.size.pass.cpp:1 FAIL -std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align.pass.cpp:1 FAIL std/language.support/support.dynamic/new.delete/new.delete.single/new.size_align_nothrow.pass.cpp:1 FAIL std/language.support/support.dynamic/new.delete/new.delete.single/new.size_nothrow.pass.cpp:1 FAIL From 4aad4b84d69e033d47215ff7d35bdee3e3b66b62 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 24 Jan 2024 17:39:41 -0800 Subject: [PATCH 11/20] Revert "Make the constexpr mutex constructor opt-in (#4000)" (#4339) Co-authored-by: Stephan T. Lavavej --- stl/inc/mutex | 12 ++++++------ tests/std/tests/VSO_0226079_mutex/env.lst | 2 +- tests/std/tests/VSO_0226079_mutex/test.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/stl/inc/mutex b/stl/inc/mutex index ce4c809f6a1..415aa79286e 100644 --- a/stl/inc/mutex +++ b/stl/inc/mutex @@ -32,18 +32,18 @@ _EXPORT_STD class condition_variable_any; class _Mutex_base { // base class for all mutex types public: -#ifdef _ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR +#ifdef _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR + _Mutex_base(int _Flags = 0) noexcept { + _Mtx_init_in_situ(_Mymtx(), _Flags | _Mtx_try); + } +#else // ^^^ defined(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) / !defined(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) vvv constexpr _Mutex_base(int _Flags = 0) noexcept { _Mtx_storage._Critical_section = {}; _Mtx_storage._Thread_id = -1; _Mtx_storage._Type = _Flags | _Mtx_try; _Mtx_storage._Count = 0; } -#else // ^^^ _ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR / !_ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR vvv - _Mutex_base(int _Flags = 0) noexcept { - _Mtx_init_in_situ(_Mymtx(), _Flags | _Mtx_try); - } -#endif // ^^^ !_ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR ^^^ +#endif // ^^^ !defined(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) ^^^ ~_Mutex_base() noexcept { _Mtx_destroy_in_situ(_Mymtx()); diff --git a/tests/std/tests/VSO_0226079_mutex/env.lst b/tests/std/tests/VSO_0226079_mutex/env.lst index de7171f19ca..d2b91697b4b 100644 --- a/tests/std/tests/VSO_0226079_mutex/env.lst +++ b/tests/std/tests/VSO_0226079_mutex/env.lst @@ -3,5 +3,5 @@ RUNALL_INCLUDE ..\impure_matrix.lst RUNALL_CROSSLIST -* PM_CL="/D_ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR" +* PM_CL="/D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR" * PM_CL="" diff --git a/tests/std/tests/VSO_0226079_mutex/test.cpp b/tests/std/tests/VSO_0226079_mutex/test.cpp index dd84dd39d93..584b3e982ea 100644 --- a/tests/std/tests/VSO_0226079_mutex/test.cpp +++ b/tests/std/tests/VSO_0226079_mutex/test.cpp @@ -468,7 +468,7 @@ void test_vso_1253916() { do_shared_locked_things(shared_lock{mtx}); } -#ifdef _ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR +#ifndef _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR struct test_constexpr_ctor { constexpr test_constexpr_ctor() {} mutex mtx; @@ -478,7 +478,7 @@ test_constexpr_ctor obj; #if _HAS_CXX20 && !defined(_M_CEE) constinit test_constexpr_ctor obj2; #endif // _HAS_CXX20 && !defined(_M_CEE) -#endif // _ENABLE_CONSTEXPR_MUTEX_CONSTRUCTOR +#endif // !defined(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) int main() { { From fef3c3d523d2622dd02d8b1016bcbd812276b129 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 24 Jan 2024 17:48:39 -0800 Subject: [PATCH 12/20] Remove a `/clr` workaround in test code (#4340) --- tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp index 9ee387fae6c..c5ea48f6893 100644 --- a/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp +++ b/tests/std/tests/Dev11_0535636_functional_overhaul/test.cpp @@ -1063,13 +1063,11 @@ constexpr bool test_invoke_constexpr() { #endif // _HAS_CXX20 assert(&invoke(&Thing::m_x, p) == &p->m_x); -#ifndef _M_CEE // TRANSITION, DevCom-939490 assert(invoke(&Thing::sum, *p, 3) == 1023); #if _HAS_CXX20 assert(invoke(&Thing::sum, ref(*p), 4) == 1024); #endif // _HAS_CXX20 assert(invoke(&Thing::sum, p, 5) == 1025); -#endif // _M_CEE assert(invoke(square_constexpr, 6) == 36); assert(invoke(&cube_constexpr, 7) == 343); From 32e65ac3e54a7150202cc9b3cc4de7330d58d24e Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Sat, 27 Jan 2024 02:24:31 -0800 Subject: [PATCH 13/20] ARM64 test improvements (#4341) --- .../tests/Dev09_056375_locale_cleanup/custombuild.pl | 7 +++++-- .../tests/GH_002030_asan_annotate_string/notarget.lst | 5 +++++ .../tests/GH_002030_asan_annotate_vector/notarget.lst | 5 +++++ .../std/tests/P0226R1_math_special_functions/test.cpp | 4 ++-- tests/std/tests/P0881R7_stacktrace/test.cpp | 2 ++ tests/std/tests/usual_17_matrix.lst | 10 +++++----- tests/std/tests/usual_20_matrix.lst | 6 +++--- tests/std/tests/usual_latest_matrix.lst | 6 +++--- tests/std/tests/usual_matrix.lst | 11 ++++++----- 9 files changed, 36 insertions(+), 20 deletions(-) create mode 100644 tests/std/tests/GH_002030_asan_annotate_string/notarget.lst create mode 100644 tests/std/tests/GH_002030_asan_annotate_vector/notarget.lst diff --git a/tests/std/tests/Dev09_056375_locale_cleanup/custombuild.pl b/tests/std/tests/Dev09_056375_locale_cleanup/custombuild.pl index 74863cccb12..263b73f4931 100644 --- a/tests/std/tests/Dev09_056375_locale_cleanup/custombuild.pl +++ b/tests/std/tests/Dev09_056375_locale_cleanup/custombuild.pl @@ -6,7 +6,10 @@ sub CustomBuildHook() { my $cwd = Run::GetCWDName(); - Run::ExecuteCL("TestDll.cpp /FeTestDll.DLL /link /DLL"); - Run::ExecuteCL("Test.cpp /Fe$cwd.exe"); + my $machine = $ENV{'TARGET_ARCHITECTURE'}; + Run::ExecuteCL("TestDll.cpp /c"); + Run::ExecuteLink("/machine:$machine /out:TestDll.DLL /DLL TestDll.obj"); + Run::ExecuteCL("Test.cpp /c"); + Run::ExecuteLink("/machine:$machine /out:$cwd.exe Test.obj"); } 1 diff --git a/tests/std/tests/GH_002030_asan_annotate_string/notarget.lst b/tests/std/tests/GH_002030_asan_annotate_string/notarget.lst new file mode 100644 index 00000000000..0027fd085c1 --- /dev/null +++ b/tests/std/tests/GH_002030_asan_annotate_string/notarget.lst @@ -0,0 +1,5 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +## TRANSITION, VSO-1938218 ASAN is not yet supported on arm64 +arm64 diff --git a/tests/std/tests/GH_002030_asan_annotate_vector/notarget.lst b/tests/std/tests/GH_002030_asan_annotate_vector/notarget.lst new file mode 100644 index 00000000000..0027fd085c1 --- /dev/null +++ b/tests/std/tests/GH_002030_asan_annotate_vector/notarget.lst @@ -0,0 +1,5 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +## TRANSITION, VSO-1938218 ASAN is not yet supported on arm64 +arm64 diff --git a/tests/std/tests/P0226R1_math_special_functions/test.cpp b/tests/std/tests/P0226R1_math_special_functions/test.cpp index aa0993a7f54..ca2280ad60e 100644 --- a/tests/std/tests/P0226R1_math_special_functions/test.cpp +++ b/tests/std/tests/P0226R1_math_special_functions/test.cpp @@ -261,9 +261,9 @@ void test_cyl_neumann() { assert(isclose(cyl_neumannl(0.5L, 0.333L), -1.30'671'255'810'072'199L, 2)); } { - assert(isclose(cyl_neumann(0.5, 0.666), -0.768'760'134'281'402'040)); + assert(isclose(cyl_neumann(0.5, 0.666), -0.768'760'134'281'402'040, 2)); assert(isclose(cyl_neumannf(0.5f, 0.666f), -0.768'760'134'281'402'040f)); - assert(isclose(cyl_neumannl(0.5L, 0.666L), -0.768'760'134'281'402'040L)); + assert(isclose(cyl_neumannl(0.5L, 0.666L), -0.768'760'134'281'402'040L, 2)); } } diff --git a/tests/std/tests/P0881R7_stacktrace/test.cpp b/tests/std/tests/P0881R7_stacktrace/test.cpp index 17cf3864e2d..09ae2968ec6 100644 --- a/tests/std/tests/P0881R7_stacktrace/test.cpp +++ b/tests/std/tests/P0881R7_stacktrace/test.cpp @@ -311,6 +311,8 @@ void test_impl() { } int main() { +#if !(defined(__clang__) && defined(_M_ARM64)) // TRANSITION, LLVM-74530 jthread t{test_impl}; test_impl(); +#endif } diff --git a/tests/std/tests/usual_17_matrix.lst b/tests/std/tests/usual_17_matrix.lst index 517a5d38ae8..13bb00d662b 100644 --- a/tests/std/tests/usual_17_matrix.lst +++ b/tests/std/tests/usual_17_matrix.lst @@ -47,8 +47,8 @@ PM_CL="/BE /c /EHsc /MD /std:c++latest /permissive-" PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive-" PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive-" PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MDd /std:c++17" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MTd /std:c++latest /permissive- /fp:strict" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++latest /permissive- --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MDd /std:c++17 --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive- --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MTd /std:c++latest /permissive- /fp:strict --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined --start-no-unused-arguments" diff --git a/tests/std/tests/usual_20_matrix.lst b/tests/std/tests/usual_20_matrix.lst index be4602dcfbe..8964140309b 100644 --- a/tests/std/tests/usual_20_matrix.lst +++ b/tests/std/tests/usual_20_matrix.lst @@ -35,6 +35,6 @@ PM_CL="/clr /MD /std:c++20" PM_CL="/clr /MDd /std:c++20" PM_CL="/BE /c /EHsc /MD /std:c++20 /permissive-" PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++20 /permissive- /MD" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++latest /permissive- /MTd /fp:strict" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++latest /permissive- /MT /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++20 /permissive- /MD --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++latest /permissive- /MTd /fp:strict --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /std:c++latest /permissive- /MT /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined --start-no-unused-arguments" diff --git a/tests/std/tests/usual_latest_matrix.lst b/tests/std/tests/usual_latest_matrix.lst index 20dbef6af61..1e3d4da8cd9 100644 --- a/tests/std/tests/usual_latest_matrix.lst +++ b/tests/std/tests/usual_latest_matrix.lst @@ -33,6 +33,6 @@ PM_CL="/MTd /D_ITERATOR_DEBUG_LEVEL=2 /permissive- /analyze:only /analyze:autolo ASAN PM_CL="/MTd /permissive- /analyze:only /analyze:autolog- -fsanitize=address /Zi" PM_LINK="/debug" PM_CL="/BE /c /MD /permissive-" PM_CL="/BE /c /MTd /permissive-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MD" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MTd /fp:strict" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MT /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MD --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MTd /fp:strict --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /permissive- /MT /fp:strict -fsanitize=undefined -fno-sanitize-recover=undefined --start-no-unused-arguments" diff --git a/tests/std/tests/usual_matrix.lst b/tests/std/tests/usual_matrix.lst index 97f067fd5d6..b8200e3ad22 100644 --- a/tests/std/tests/usual_matrix.lst +++ b/tests/std/tests/usual_matrix.lst @@ -49,8 +49,9 @@ PM_CL="/BE /c /EHsc /MD /std:c++14 /w14640 /Zc:threadSafeInit-" PM_CL="/BE /c /EHsc /MDd /std:c++17 /permissive- /w14640 /Zc:threadSafeInit-" PM_CL="/BE /c /EHsc /MT /std:c++20 /permissive- /w14640 /Zc:threadSafeInit-" PM_CL="/BE /c /EHsc /MTd /std:c++latest /permissive- /w14640 /Zc:threadSafeInit-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14 /w14640 /Zc:threadSafeInit-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MDd /std:c++17 /w14640 /Zc:threadSafeInit-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive- /w14640 /Zc:threadSafeInit-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MTd /std:c++latest /permissive- /fp:strict /w14640 /Zc:threadSafeInit-" -PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict /w14640 /Zc:threadSafeInit- -fsanitize=undefined -fno-sanitize-recover=undefined" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MD /std:c++14 /w14640 /Zc:threadSafeInit- --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MDd /std:c++17 /w14640 /Zc:threadSafeInit- --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++20 /permissive- /w14640 /Zc:threadSafeInit- --start-no-unused-arguments" +PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MTd /std:c++latest /permissive- /fp:strict /w14640 /Zc:threadSafeInit- --start-no-unused-arguments" +# TRANSITION, GH-3568 +# PM_COMPILER="clang-cl" PM_CL="-fno-ms-compatibility -fno-delayed-template-parsing -Wno-unqualified-std-cast-call /EHsc /MT /std:c++latest /permissive- /fp:strict /w14640 /Zc:threadSafeInit- -fsanitize=undefined -fno-sanitize-recover=undefined --start-no-unused-arguments" From 63e4c2f59f55d210c91edd8cce0abf0a570c5f96 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 30 Jan 2024 22:06:45 +0200 Subject: [PATCH 14/20] SSE2 vectorization for `bitset::to_string` (#3960) Co-authored-by: Alcaro Co-authored-by: Stephan T. Lavavej --- stl/inc/bitset | 26 +++++ stl/src/vector_algorithms.cpp | 110 ++++++++++++++++++ .../VSO_0000000_vector_algorithms/test.cpp | 73 ++++++++++++ 3 files changed, 209 insertions(+) diff --git a/stl/inc/bitset b/stl/inc/bitset index 826752bd49e..627bf330601 100644 --- a/stl/inc/bitset +++ b/stl/inc/bitset @@ -18,6 +18,15 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +#if _USE_STD_VECTOR_ALGORITHMS +extern "C" { +__declspec(noalias) void __stdcall __std_bitset_to_string_1( + char* _Dest, const void* _Src, size_t _Size_bits, char _Elem0, char _Elem1) noexcept; +__declspec(noalias) void __stdcall __std_bitset_to_string_2( + wchar_t* _Dest, const void* _Src, size_t _Size_bits, wchar_t _Elem0, wchar_t _Elem1) noexcept; +} // extern "C" +#endif // _USE_STD_VECTOR_ALGORITHMS + _STD_BEGIN _EXPORT_STD template class bitset { // store fixed-length sequence of Boolean elements @@ -348,6 +357,23 @@ public: // convert bitset to string basic_string<_Elem, _Tr, _Alloc> _Str; _Str._Resize_and_overwrite(_Bits, [this, _Elem0, _Elem1](_Elem* _Buf, size_t _Len) { +#if _USE_STD_VECTOR_ALGORITHMS + constexpr size_t _Bitset_vector_threshold = 32; + if constexpr (_Bits >= _Bitset_vector_threshold && is_integral_v<_Elem> && sizeof(_Elem) <= 2) { + if (!_Is_constant_evaluated()) { + if constexpr (sizeof(_Elem) == 1) { + __std_bitset_to_string_1(reinterpret_cast(_Buf), _Array, _Len, static_cast(_Elem0), + static_cast(_Elem1)); + } else { + _STL_INTERNAL_STATIC_ASSERT(sizeof(_Elem) == 2); + __std_bitset_to_string_2(reinterpret_cast(_Buf), _Array, _Len, + static_cast(_Elem0), static_cast(_Elem1)); + } + return _Len; + } + } +#endif // _USE_STD_VECTOR_ALGORITHMS + for (size_t _Pos = 0; _Pos < _Len; ++_Pos) { _Buf[_Pos] = _Subscript(_Len - 1 - _Pos) ? _Elem1 : _Elem0; } diff --git a/stl/src/vector_algorithms.cpp b/stl/src/vector_algorithms.cpp index d18b740304e..70a4e5b45aa 100644 --- a/stl/src/vector_algorithms.cpp +++ b/stl/src/vector_algorithms.cpp @@ -7,6 +7,7 @@ #if defined(_M_IX86) || defined(_M_X64) // NB: includes _M_ARM64EC #include +#include #ifndef _M_ARM64EC #include #include @@ -1563,5 +1564,114 @@ __declspec(noalias) size_t return __std_count_trivial_impl<_Find_traits_8>(_First, _Last, _Val); } +} // extern "C" + +#ifndef _M_ARM64EC +namespace { + __m128i __forceinline _Bitset_to_string_1_step(const uint16_t _Val, const __m128i _Px0, const __m128i _Px1) { + const __m128i _Vx0 = _mm_cvtsi32_si128(_Val); + const __m128i _Vx1 = _mm_unpacklo_epi8(_Vx0, _Vx0); + const __m128i _Vx2 = _mm_unpacklo_epi8(_Vx1, _Vx1); + const __m128i _Vx3 = _mm_shuffle_epi32(_Vx2, _MM_SHUFFLE(0, 0, 1, 1)); + const __m128i _Msk = _mm_and_si128(_Vx3, _mm_set1_epi64x(0x0102040810204080)); + const __m128i _Ex0 = _mm_cmpeq_epi8(_Msk, _mm_setzero_si128()); + const __m128i _Ex1 = _mm_xor_si128(_mm_and_si128(_Ex0, _Px0), _Px1); + return _Ex1; + } + + __m128i __forceinline _Bitset_to_string_2_step(const uint8_t _Val, const __m128i _Px0, const __m128i _Px1) { + const __m128i _Vx = _mm_set1_epi16(_Val); + const __m128i _Msk = _mm_and_si128(_Vx, _mm_set_epi64x(0x0001000200040008, 0x0010002000400080)); + const __m128i _Ex0 = _mm_cmpeq_epi16(_Msk, _mm_setzero_si128()); + const __m128i _Ex1 = _mm_xor_si128(_mm_and_si128(_Ex0, _Px0), _Px1); + return _Ex1; + } +} // unnamed namespace +#endif // !defined(_M_ARM64EC) + +extern "C" { + +__declspec(noalias) void __stdcall __std_bitset_to_string_1( + char* const _Dest, const void* _Src, size_t _Size_bits, const char _Elem0, const char _Elem1) noexcept { +#ifndef _M_ARM64EC + if (_Use_sse2()) { + const __m128i _Px0 = _mm_set1_epi8(_Elem0 ^ _Elem1); + const __m128i _Px1 = _mm_set1_epi8(_Elem1); + if (_Size_bits >= 16) { + char* _Pos = _Dest + _Size_bits; + _Size_bits &= 0xF; + char* const _Stop_at = _Dest + _Size_bits; + do { + uint16_t _Val; + memcpy(&_Val, _Src, 2); + const __m128i _Elems = _Bitset_to_string_1_step(_Val, _Px0, _Px1); + _Pos -= 16; + _mm_storeu_si128(reinterpret_cast<__m128i*>(_Pos), _Elems); + _Advance_bytes(_Src, 2); + } while (_Pos != _Stop_at); + } + + if (_Size_bits > 0) { + __assume(_Size_bits < 16); + uint16_t _Val; + if (_Size_bits > 8) { + memcpy(&_Val, _Src, 2); + } else { + _Val = *reinterpret_cast(_Src); + } + const __m128i _Elems = _Bitset_to_string_1_step(_Val, _Px0, _Px1); + char _Tmp[16]; + _mm_storeu_si128(reinterpret_cast<__m128i*>(_Tmp), _Elems); + const char* const _Tmpd = _Tmp + (16 - _Size_bits); + for (size_t _Ix = 0; _Ix < _Size_bits; ++_Ix) { + _Dest[_Ix] = _Tmpd[_Ix]; + } + } + } +#endif // !defined(_M_ARM64EC) + const auto _Arr = reinterpret_cast(_Src); + for (size_t _Ix = 0; _Ix < _Size_bits; ++_Ix) { + _Dest[_Size_bits - 1 - _Ix] = ((_Arr[_Ix >> 3] >> (_Ix & 7)) & 1) != 0 ? _Elem1 : _Elem0; + } +} + +__declspec(noalias) void __stdcall __std_bitset_to_string_2( + wchar_t* const _Dest, const void* _Src, size_t _Size_bits, const wchar_t _Elem0, const wchar_t _Elem1) noexcept { +#ifndef _M_ARM64EC + if (_Use_sse2()) { + const __m128i _Px0 = _mm_set1_epi16(_Elem0 ^ _Elem1); + const __m128i _Px1 = _mm_set1_epi16(_Elem1); + if (_Size_bits >= 8) { + wchar_t* _Pos = _Dest + _Size_bits; + _Size_bits &= 0x7; + wchar_t* const _Stop_at = _Dest + _Size_bits; + do { + const uint8_t _Val = *reinterpret_cast(_Src); + const __m128i _Elems = _Bitset_to_string_2_step(_Val, _Px0, _Px1); + _Pos -= 8; + _mm_storeu_si128(reinterpret_cast<__m128i*>(_Pos), _Elems); + _Advance_bytes(_Src, 1); + } while (_Pos != _Stop_at); + } + + if (_Size_bits > 0) { + __assume(_Size_bits < 8); + const uint8_t _Val = *reinterpret_cast(_Src); + const __m128i _Elems = _Bitset_to_string_2_step(_Val, _Px0, _Px1); + wchar_t _Tmp[8]; + _mm_storeu_si128(reinterpret_cast<__m128i*>(_Tmp), _Elems); + const wchar_t* const _Tmpd = _Tmp + (8 - _Size_bits); + for (size_t _Ix = 0; _Ix < _Size_bits; ++_Ix) { + _Dest[_Ix] = _Tmpd[_Ix]; + } + } + } +#endif // !defined(_M_ARM64EC) + const auto _Arr = reinterpret_cast(_Src); + for (size_t _Ix = 0; _Ix < _Size_bits; ++_Ix) { + _Dest[_Size_bits - 1 - _Ix] = ((_Arr[_Ix >> 3] >> (_Ix & 7)) & 1) != 0 ? _Elem1 : _Elem0; + } +} + } // extern "C" #endif // defined(_M_IX86) || defined(_M_X64) diff --git a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp index 383a9120b74..a0ad56a434c 100644 --- a/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp +++ b/tests/std/tests/VSO_0000000_vector_algorithms/test.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#include #include #include #include @@ -12,6 +13,7 @@ #include #include #include +#include #include #include @@ -443,6 +445,73 @@ void test_one_container() { test_two_containers>(); } +void test_bitset(mt19937_64& gen) { + assert(bitset<0>(0x0ULL).to_string() == ""); + assert(bitset<0>(0xFEDCBA9876543210ULL).to_string() == ""); + assert(bitset<15>(0x6789ULL).to_string() == "110011110001001"); + assert(bitset<15>(0xFEDCBA9876543210ULL).to_string() == "011001000010000"); + assert(bitset<32>(0xABCD1234ULL).to_string() == "10101011110011010001001000110100"); + assert(bitset<32>(0xFEDCBA9876543210ULL).to_string() == "01110110010101000011001000010000"); + assert(bitset<45>(0x1701D1729FFFULL).to_string() == "101110000000111010001011100101001111111111111"); + assert(bitset<45>(0xFEDCBA9876543210ULL).to_string() == "110101001100001110110010101000011001000010000"); + assert(bitset<64>(0xFEDCBA9876543210ULL).to_string() + == "1111111011011100101110101001100001110110010101000011001000010000"); + assert(bitset<75>(0xFEDCBA9876543210ULL).to_string() + == "000000000001111111011011100101110101001100001110110010101000011001000010000"); + + assert(bitset<0>(0x0ULL).to_string() == L""); + assert(bitset<0>(0xFEDCBA9876543210ULL).to_string() == L""); + assert(bitset<15>(0x6789ULL).to_string() == L"110011110001001"); + assert(bitset<15>(0xFEDCBA9876543210ULL).to_string() == L"011001000010000"); + assert(bitset<32>(0xABCD1234ULL).to_string() == L"10101011110011010001001000110100"); + assert(bitset<32>(0xFEDCBA9876543210ULL).to_string() == L"01110110010101000011001000010000"); + assert(bitset<45>(0x1701D1729FFFULL).to_string() == L"101110000000111010001011100101001111111111111"); + assert(bitset<45>(0xFEDCBA9876543210ULL).to_string() == L"110101001100001110110010101000011001000010000"); + assert(bitset<64>(0xFEDCBA9876543210ULL).to_string() + == L"1111111011011100101110101001100001110110010101000011001000010000"); + assert(bitset<75>(0xFEDCBA9876543210ULL).to_string() + == L"000000000001111111011011100101110101001100001110110010101000011001000010000"); + + assert(bitset<64>(0xFEDCBA9876543210ULL).to_string('o', 'x') + == "xxxxxxxoxxoxxxooxoxxxoxoxooxxooooxxxoxxooxoxoxooooxxooxooooxoooo"); + assert(bitset<64>(0xFEDCBA9876543210ULL).to_string(L'o', L'x') + == L"xxxxxxxoxxoxxxooxoxxxoxoxooxxooooxxxoxxooxoxoxooooxxooxooooxoooo"); + +#ifdef __cpp_lib_char8_t + assert(bitset<75>(0xFEDCBA9876543210ULL).to_string() + == u8"000000000001111111011011100101110101001100001110110010101000011001000010000"); +#endif // __cpp_lib_char8_t + assert(bitset<75>(0xFEDCBA9876543210ULL).to_string() + == u"000000000001111111011011100101110101001100001110110010101000011001000010000"); + assert(bitset<75>(0xFEDCBA9876543210ULL).to_string() + == U"000000000001111111011011100101110101001100001110110010101000011001000010000"); // not vectorized + + { + constexpr size_t N = 2048; + + string str; + wstring wstr; + str.reserve(N); + wstr.reserve(N); + + while (str.size() != N) { + uint64_t random_value = gen(); + + for (int bits = 0; bits < 64; ++bits) { + const auto character = '0' + (random_value & 1); + str.push_back(static_cast(character)); + wstr.push_back(static_cast(character)); + random_value >>= 1; + } + } + + const bitset b(str); + + assert(b.to_string() == str); + assert(b.to_string() == wstr); + } +} + void test_various_containers() { test_one_container>(); // contiguous, vectorizable test_one_container>(); // random-access, not vectorizable @@ -524,20 +593,24 @@ int main() { test_vector_algorithms(gen); test_various_containers(); + test_bitset(gen); #ifndef _M_CEE_PURE #if defined(_M_IX86) || defined(_M_X64) disable_instructions(__ISA_AVAILABLE_AVX2); test_vector_algorithms(gen); test_various_containers(); + test_bitset(gen); disable_instructions(__ISA_AVAILABLE_SSE42); test_vector_algorithms(gen); test_various_containers(); + test_bitset(gen); #endif // defined(_M_IX86) || defined(_M_X64) #if defined(_M_IX86) disable_instructions(__ISA_AVAILABLE_SSE2); test_vector_algorithms(gen); test_various_containers(); + test_bitset(gen); #endif // defined(_M_IX86) #endif // _M_CEE_PURE } From 46402aa2d7f76b60767ed09ecc63d47300e95b19 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 31 Jan 2024 04:10:15 +0800 Subject: [PATCH 15/20] ``: Make `deque::shrink_to_fit` never relocate elements (#4091) Co-authored-by: achabense <60953653+achabense@users.noreply.github.com> Co-authored-by: Stephan T. Lavavej --- stl/inc/deque | 105 ++++++++++++++---- .../test.cpp | 45 ++++++++ .../test.cpp | 2 +- 3 files changed, 131 insertions(+), 21 deletions(-) diff --git a/stl/inc/deque b/stl/inc/deque index 3ce93fd2e3f..ba0794eb243 100644 --- a/stl/inc/deque +++ b/stl/inc/deque @@ -989,19 +989,74 @@ public: } void shrink_to_fit() { - size_type _Oldcapacity = _Block_size * _Mapsize(); - size_type _Newcapacity = _Oldcapacity / 2; + if (empty()) { + if (_Map() != nullptr) { + _Reset_map(); + } + return; + } + + const auto _Mask = static_cast(_Mapsize() - 1); + + const auto _First_used_block_idx = static_cast(_Myoff() / _Block_size); + + // (_Myoff() + _Mysize() - 1) is for the last element, i.e. the back() of the deque. + // Divide by _Block_size to get the unmasked index of the last used block. + // Add 1 to get the unmasked index of the first unused block. + const auto _Unmasked_first_unused_block_idx = + static_cast(((_Myoff() + _Mysize() - 1) / _Block_size) + 1); + + const auto _First_unused_block_idx = static_cast(_Unmasked_first_unused_block_idx & _Mask); + + // deallocate unused blocks, traversing over the circular buffer until the first used block index + for (auto _Block_idx = _First_unused_block_idx; _Block_idx != _First_used_block_idx; + _Block_idx = static_cast((_Block_idx + 1) & _Mask)) { + auto& _Block_ptr = _Map()[static_cast<_Map_difference_type>(_Block_idx)]; + if (_Block_ptr != nullptr) { + _Getal().deallocate(_Block_ptr, _Block_size); + _Block_ptr = nullptr; + } + } + + const auto _Used_block_count = static_cast(_Unmasked_first_unused_block_idx - _First_used_block_idx); + + size_type _New_block_count = _Minimum_map_size; // should be power of 2 + + while (_New_block_count < _Used_block_count) { + _New_block_count *= 2; + } + + if (_New_block_count >= _Mapsize()) { + return; + } + + // worth shrinking the internal map, do it + + _Alpty _Almap(_Getal()); + const auto _New_map = _Almap.allocate(_New_block_count); - if (_Newcapacity < _Block_size * _Minimum_map_size) { - _Newcapacity = _Block_size * _Minimum_map_size; + _Orphan_all(); // the map can be shrunk, invalidate all iterators + + // transfer the ownership of blocks to pointers in the new map + for (size_type _Block = 0; _Block != _Used_block_count; ++_Block) { + const auto _New_block_idx = static_cast<_Map_difference_type>(_Block); + const auto _Old_block_idx = static_cast<_Map_difference_type>((_First_used_block_idx + _Block) & _Mask); + _STD _Construct_in_place(_New_map[_New_block_idx], _Map()[_Old_block_idx]); } - if ((empty() && _Mapsize() > 0) - || (!empty() && size() <= _Newcapacity && _Newcapacity < _Oldcapacity)) { // worth shrinking, do it - deque _Tmp( - _STD make_move_iterator(_Unchecked_begin()), _STD make_move_iterator(_Unchecked_end()), _Getal()); - swap(_Tmp); + // null out the rest of the new map + _STD _Uninitialized_value_construct_n_unchecked1( + _New_map + static_cast<_Map_difference_type>(_Used_block_count), _New_block_count - _Used_block_count); + + for (auto _Block = _Map_distance(); _Block > 0;) { + --_Block; + _STD _Destroy_in_place(_Map()[_Block]); // destroy pointer to block } + _Almap.deallocate(_Map(), _Mapsize()); // free storage for map + + _Map() = _New_map; + _Mapsize() = _New_block_count; + _Myoff() %= _Block_size; // the first element is within block index 0 of the new map } _NODISCARD const_reference operator[](size_type _Pos) const noexcept /* strengthened */ { @@ -1591,27 +1646,37 @@ private: _Mapsize() += _Count; } + void _Reset_map() noexcept { + // pre: each block pointer is either null or pointing to a block without constructed elements + + for (auto _Block = _Map_distance(); _Block > 0;) { // free storage for a block and destroy pointer + --_Block; + auto& _Block_ptr = _Map()[_Block]; + if (_Block_ptr) { // free block + _Getal().deallocate(_Block_ptr, _Block_size); + } + _STD _Destroy_in_place(_Block_ptr); // destroy pointer to block + } + + _Alpty _Almap(_Getal()); + _Almap.deallocate(_Map(), _Mapsize()); // free storage for map + + _Map() = nullptr; + _Mapsize() = 0; + } + void _Tidy() noexcept { // free all storage _Orphan_all(); - _Alpty _Almap(_Getal()); while (!empty()) { pop_back(); } if (_Map() != nullptr) { - for (auto _Block = _Map_distance(); _Block > 0;) { // free storage for a block and destroy pointer - if (_Map()[--_Block]) { // free block - _Getal().deallocate(_Map()[_Block], _Block_size); - } - _Destroy_in_place(_Map()[_Block]); // destroy pointer to block - } - - _Almap.deallocate(_Map(), _Mapsize()); // free storage for map + _Reset_map(); } - _Mapsize() = 0; - _Map() = nullptr; + _STL_INTERNAL_CHECK(_Mapsize() == 0); // null map should always be paired with zero mapsize } #if _ITERATOR_DEBUG_LEVEL == 2 diff --git a/tests/std/tests/Dev10_860421_deque_push_back_pop_front/test.cpp b/tests/std/tests/Dev10_860421_deque_push_back_pop_front/test.cpp index 4e21193d429..fd362b915da 100644 --- a/tests/std/tests/Dev10_860421_deque_push_back_pop_front/test.cpp +++ b/tests/std/tests/Dev10_860421_deque_push_back_pop_front/test.cpp @@ -259,6 +259,49 @@ void test_exception_safety_for_throwing_movable() { assert(d == d_orig); } +// Also test GH-4072: : shrink_to_fit() should follow the Standard +void test_gh_4072() { + { + constexpr int removed_count = 768; + + deque d; + for (int i = 0; i < 1729; ++i) { + d.emplace_back(i); + } + + for (int i = 0; i < removed_count; ++i) { + d.pop_front(); + d.pop_back(); + } + + deque d2; + for (int i = removed_count; i < 1729 - removed_count; ++i) { + d2.emplace_back(i); + } + + d.shrink_to_fit(); // ensures that no constructor or assignment operator of the element type is called + assert(d == d2); + } + + // ensure that the circular buffer is correctly handled + { + deque deq(128); + deq.pop_back(); + deq.emplace_front(0); + deq.shrink_to_fit(); + } + { + deque deq(128); + for (int i = 0; i < 120; ++i) { + deq.pop_back(); + } + for (int i = 0; i < 5; ++i) { + deq.emplace_front(0); + } + deq.shrink_to_fit(); + } +} + int main() { test_push_back_pop_front(); @@ -266,4 +309,6 @@ int main() { test_exception_safety_for_nonswappable_movable(); test_exception_safety_for_throwing_movable(); + + test_gh_4072(); } diff --git a/tests/std/tests/VSO_0000000_allocator_propagation/test.cpp b/tests/std/tests/VSO_0000000_allocator_propagation/test.cpp index 7622338207b..c0e775c77f0 100644 --- a/tests/std/tests/VSO_0000000_allocator_propagation/test.cpp +++ b/tests/std/tests/VSO_0000000_allocator_propagation/test.cpp @@ -501,7 +501,7 @@ void test_deque_shrink_to_fit_per_alloc() { } } -void test_deque_shrink_to_fit() { // MSVC STL's deque::shrink_to_fit relies on swap +void test_deque_shrink_to_fit() { // regression test: MSVC STL's deque::shrink_to_fit used to rely on swap test_deque_shrink_to_fit_per_alloc>(); test_deque_shrink_to_fit_per_alloc>(); test_deque_shrink_to_fit_per_alloc>(); From 9c10c1a23299f8b0e314cc3be8eae0571aca066e Mon Sep 17 00:00:00 2001 From: Tomasz Konojacki Date: Tue, 30 Jan 2024 21:16:20 +0100 Subject: [PATCH 16/20] ``: Preallocate memory in `path::operator/` (#4136) Co-authored-by: Stephan T. Lavavej Co-authored-by: Casey Carter --- stl/inc/filesystem | 29 +++++++++++++++++++++ tests/std/tests/P0218R1_filesystem/test.cpp | 22 ++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/stl/inc/filesystem b/stl/inc/filesystem index 4b2ad4ce9b8..a08e435d4cc 100644 --- a/stl/inc/filesystem +++ b/stl/inc/filesystem @@ -1377,6 +1377,35 @@ namespace filesystem { #endif // ^^^ !_HAS_CXX20 ^^^ _NODISCARD_FRIEND path operator/(const path& _Left, const path& _Right) { // append a pair of paths together + const auto _Right_size = _Right._Text.size(); + const auto _Right_first = _Right._Text.data(); + const auto _Right_last = _Right_first + _Right_size; + + // Handle the most common case: !has_root_name(_Right) && !has_root_directory(_Right) + if (_Right_size != 0 && !_Has_drive_letter_prefix(_Right_first, _Right_last) && !_Is_slash(*_Right_first)) { + const auto _Left_size = _Left._Text.size(); + const auto _Left_first = _Left._Text.data(); + const auto _Left_last = _Left_first + _Left_size; + + // Appending a slash to "X:" would make it an absolute path + const bool _Left_is_just_drive = _Left_size == 2 && _Is_drive_prefix(_Left_first); + const bool _Is_slash_needed = _Left_size != 0 && !_Left_is_just_drive && !_Is_slash(_Left_last[-1]); + + const auto _Total_size = _Left_size + static_cast(_Is_slash_needed) + _Right_size; + + path _Tmp; + _Tmp._Text._Resize_and_overwrite(_Total_size, [=](wchar_t* _Ptr, const size_t _Size) { + _CSTD memcpy(_Ptr, _Left_first, _Left_size * sizeof(wchar_t)); + _Ptr += _Left_size; + if (_Is_slash_needed) { + *_Ptr++ = preferred_separator; + } + _CSTD memcpy(_Ptr, _Right_first, _Right_size * sizeof(wchar_t)); + return _Size; + }); + return _Tmp; + } + path _Tmp = _Left; _Tmp /= _Right; return _Tmp; diff --git a/tests/std/tests/P0218R1_filesystem/test.cpp b/tests/std/tests/P0218R1_filesystem/test.cpp index d3ea57bbbc8..e2d66ba01b2 100644 --- a/tests/std/tests/P0218R1_filesystem/test.cpp +++ b/tests/std/tests/P0218R1_filesystem/test.cpp @@ -544,6 +544,7 @@ struct slash_test_case { }; constexpr slash_test_case slashTestCases[] = { + {L""sv, L""sv, L""sv}, {L"relative"sv, L"other"sv, LR"(relative\other)"sv}, {L"//server"sv, L"share"sv, LR"(//server\share)"sv}, {L"//server/"sv, L"share"sv, LR"(//server/share)"sv}, @@ -555,6 +556,7 @@ constexpr slash_test_case slashTestCases[] = { {L""sv, L"cat"sv, L"cat"sv}, {L"./"sv, L"cat"sv, L"./cat"sv}, // original test case catching a bug in the above {L"c:"sv, L""sv, L"c:"sv}, + {L"c:"sv, L"dog"sv, L"c:dog"sv}, {L"c:cat"sv, L"/dog"sv, L"c:/dog"sv}, {L"c:/cat"sv, L"/dog"sv, L"c:/dog"sv}, {L"c:cat"sv, L"c:dog"sv, LR"(c:cat\dog)"sv}, @@ -568,13 +570,23 @@ constexpr slash_test_case slashTestCases[] = { bool run_slash_test_case(const slash_test_case& testCase) { path p(testCase.a); p /= testCase.b; - if (p.native() == testCase.expected) { - return true; + + if (p.native() != testCase.expected) { + wcerr << L"With operator/=, expected " << testCase.a << L" / " << testCase.b << L" to be " << testCase.expected + << L" but it was " << p.native() << L"\n"; + return false; } - wcerr << L"Expected " << testCase.a << L" / " << testCase.b << L" to be " << testCase.expected << L" but it was " - << p.native() << L"\n"; - return false; + // Also test operator/, which was optimized by GH-4136. + p = path{testCase.a} / path{testCase.b}; + + if (p.native() != testCase.expected) { + wcerr << L"With operator/, expected " << testCase.a << L" / " << testCase.b << L" to be " << testCase.expected + << L" but it was " << p.native() << L"\n"; + return false; + } + + return true; } void test_iterators() { From c0da2af3d28e521e69bc3afd1e1418246ca074cf Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 31 Jan 2024 04:25:25 +0800 Subject: [PATCH 17/20] ``: Add different control block types for `allocate_shared_for_overwrite` (#4274) Co-authored-by: Stephan T. Lavavej --- stl/debugger/STL.natvis | 104 ++++++++++++++++ stl/inc/memory | 198 +++++++++++++++++++++++++----- tests/libcxx/expected_results.txt | 3 - 3 files changed, 272 insertions(+), 33 deletions(-) diff --git a/stl/debugger/STL.natvis b/stl/debugger/STL.natvis index a3047ef51d3..01e8dd606b6 100644 --- a/stl/debugger/STL.natvis +++ b/stl/debugger/STL.natvis @@ -362,6 +362,35 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + + + make_shared<T[N]> + + _Storage._Value + + + + + + + + make_shared<T[]> + + + size() + data() + + + + + + + make_shared<T[]> + + _Storage._Value + + + allocate_shared @@ -386,6 +415,81 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + + + + + + + allocate_shared<T[N]> + + _Storage._Value + allocator() + + + + + + + + + + + + allocate_shared<T[]> + + allocator() + + size() + data() + + + + + + + + + + + allocate_shared_for_overwrite + + ($T1 *) &_Storage + allocator() + + + + + + + + + + allocate_shared_for_overwrite<T[N]> + + _Storage._Value + allocator() + + + + + + + + + + + + allocate_shared_for_overwrite<T[]> + + allocator() + + size() + data() + + + + custom deleter diff --git a/stl/inc/memory b/stl/inc/memory index 8b528752403..8ad20eb7cde 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -1821,7 +1821,7 @@ private: template friend shared_ptr<_Ty0> _Make_shared_unbounded_array(size_t _Count, const _ArgTypes&... _Args); - template + template friend shared_ptr<_Ty0> _Allocate_shared_unbounded_array( const _Alloc& _Al, size_t _Count, const _ArgTypes&... _Args); #else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv @@ -2461,16 +2461,14 @@ public: template explicit _Ref_count_obj_alloc3(const _Alloc& _Al_arg, _Types&&... _Args) : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base() { -#if _HAS_CXX20 - if constexpr (sizeof...(_Types) == 1 && (is_same_v<_For_overwrite_tag, remove_cvref_t<_Types>> && ...)) { - _Default_construct_in_place(_Storage._Value); - ((void) _Args, ...); - } else -#endif // _HAS_CXX20 - { - allocator_traits<_Rebound>::construct( - this->_Get_val(), _STD addressof(_Storage._Value), _STD forward<_Types>(_Args)...); +#if _HAS_CXX20 && defined(_ENABLE_STL_INTERNAL_CHECK) + if constexpr (sizeof...(_Types) == 1) { + // allocate_shared_for_overwrite should use another type for the control block + _STL_INTERNAL_STATIC_ASSERT(!(is_same_v<_For_overwrite_tag, remove_cvref_t<_Types>> && ...)); } +#endif // _HAS_CXX20 && defined(_ENABLE_STL_INTERNAL_CHECK) + allocator_traits<_Rebound>::construct( + this->_Get_val(), _STD addressof(_Storage._Value), _STD forward<_Types>(_Args)...); } union { @@ -2496,6 +2494,44 @@ private: }; #if _HAS_CXX20 +template +class _Ref_count_obj_alloc_for_overwrite : public _Ebco_base<_Rebind_alloc_t<_Alloc, _Ty>>, public _Ref_count_base { + // handle reference counting for object in control block, allocator + // initialize and destroy objects by the default mechanism +private: + static_assert(is_same_v<_Ty, remove_cv_t<_Ty>>, "allocate_shared_for_overwrite should remove_cv_t"); + + using _Rebound = _Rebind_alloc_t<_Alloc, _Ty>; + +public: + template + explicit _Ref_count_obj_alloc_for_overwrite(const _Alloc& _Al_arg) + : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base() { + _Default_construct_in_place(_Storage._Value); + } + + union { + _Wrap<_Ty> _Storage; + }; + +private: + ~_Ref_count_obj_alloc_for_overwrite() noexcept override { // TRANSITION, should be non-virtual + // nothing to do; _Storage._Value already destroyed by _Destroy() + + // See N4964 [class.dtor]/7. + } + + void _Destroy() noexcept override { // destroy managed resource + _Destroy_in_place(_Storage._Value); // use the default mechanism per LWG-4024 + } + + void _Delete_this() noexcept override { // destroy self + _Rebind_alloc_t<_Alloc, _Ref_count_obj_alloc_for_overwrite> _Al(this->_Get_val()); + this->~_Ref_count_obj_alloc_for_overwrite(); + _Deallocate_plain(_Al, this); + } +}; + template class _NODISCARD _Uninitialized_rev_destroying_backout_al { // class to undo partially constructed ranges in _Uninitialized_xxx_al algorithms @@ -2647,11 +2683,10 @@ public: template explicit _Ref_count_unbounded_array_alloc(const _Alloc& _Al_arg, const size_t _Count, const _Arg& _Val) : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base(), _Size(_Count) { - if constexpr (is_same_v<_For_overwrite_tag, _Arg>) { - _Uninitialized_default_construct_multidimensional_n(_Get_ptr(), _Size); // the allocator isn't needed - } else { - _Uninitialized_fill_multidimensional_n_al(_Get_ptr(), _Size, _Val, this->_Get_val()); - } + // allocate_shared_for_overwrite should use another type for the control block + _STL_INTERNAL_STATIC_ASSERT(!is_same_v<_For_overwrite_tag, _Arg>); + + _Uninitialized_fill_multidimensional_n_al(_Get_ptr(), _Size, _Val, this->_Get_val()); } _NODISCARD auto _Get_ptr() noexcept { @@ -2694,6 +2729,65 @@ private: } }; +template +class _Ref_count_unbounded_array_alloc_for_overwrite + : public _Ebco_base<_Rebind_alloc_t<_Alloc, remove_all_extents_t<_Ty>>>, + public _Ref_count_base { + // handle reference counting for unbounded array in control block, allocator + // initialize and destroy objects by the default mechanism +private: + static_assert(is_unbounded_array_v<_Ty>); + static_assert(is_same_v<_Ty, remove_cv_t<_Ty>>, "allocate_shared_for_overwrite should remove_cv_t"); + + using _Item = remove_all_extents_t<_Ty>; + using _Rebound = _Rebind_alloc_t<_Alloc, _Item>; + +public: + using _Element_type = remove_extent_t<_Ty>; + + explicit _Ref_count_unbounded_array_alloc_for_overwrite(const _Alloc& _Al_arg, const size_t _Count) + : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base(), _Size(_Count) { + _Uninitialized_default_construct_multidimensional_n(_Get_ptr(), _Size); // the allocator isn't needed + } + + _NODISCARD auto _Get_ptr() noexcept { + return _STD addressof(_Storage._Value); + } + +private: + size_t _Size; + + union { + _Wrap<_Element_type> _Storage; // flexible array must be last member + }; + + ~_Ref_count_unbounded_array_alloc_for_overwrite() noexcept override { // TRANSITION, should be non-virtual + // nothing to do; _Storage._Value already destroyed by _Destroy() + + // See N4964 [class.dtor]/7. + } + + void _Destroy() noexcept override { // destroy managed resource + _Reverse_destroy_multidimensional_n(_Get_ptr(), _Size); // use the default mechanism per LWG-4024 + } + + void _Delete_this() noexcept override { // destroy self + constexpr size_t _Align = alignof(_Ref_count_unbounded_array_alloc_for_overwrite); + using _Storage = _Alignas_storage_unit<_Align>; + using _Rebound_alloc = _Rebind_alloc_t<_Alloc, _Storage>; + + _Rebound_alloc _Al(this->_Get_val()); + const size_t _Bytes = _Calculate_bytes_for_flexible_array< // + _Ref_count_unbounded_array_alloc_for_overwrite, _Check_overflow::_Nope>(_Size); + const size_t _Storage_units = _Bytes / sizeof(_Storage); + + this->~_Ref_count_unbounded_array_alloc_for_overwrite(); + + _Al.deallocate(_STD _Refancy<_Alloc_ptr_t<_Rebound_alloc>>(reinterpret_cast<_Storage*>(this)), + static_cast<_Alloc_size_t<_Rebound_alloc>>(_Storage_units)); + } +}; + template class _Ref_count_bounded_array_alloc : public _Ebco_base<_Rebind_alloc_t<_Alloc, remove_all_extents_t<_Ty>>>, public _Ref_count_base { @@ -2714,12 +2808,10 @@ public: template explicit _Ref_count_bounded_array_alloc(const _Alloc& _Al_arg, const _Arg& _Val) : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base() { // don't value-initialize _Storage - if constexpr (is_same_v<_For_overwrite_tag, _Arg>) { - _Uninitialized_default_construct_multidimensional_n( - _Storage._Value, extent_v<_Ty>); // the allocator isn't needed - } else { - _Uninitialized_fill_multidimensional_n_al(_Storage._Value, extent_v<_Ty>, _Val, this->_Get_val()); - } + // allocate_shared_for_overwrite should use another type for the control block + _STL_INTERNAL_STATIC_ASSERT(!is_same_v<_For_overwrite_tag, _Arg>); + + _Uninitialized_fill_multidimensional_n_al(_Storage._Value, extent_v<_Ty>, _Val, this->_Get_val()); } union { @@ -2745,6 +2837,50 @@ private: _Deallocate_plain(_Al, this); } }; + +template +class _Ref_count_bounded_array_alloc_for_overwrite + : public _Ebco_base<_Rebind_alloc_t<_Alloc, remove_all_extents_t<_Ty>>>, + public _Ref_count_base { + // handle reference counting for bounded array in control block, allocator + // initialize and destroy objects by the default mechanism +private: + static_assert(is_bounded_array_v<_Ty>); + static_assert(is_same_v<_Ty, remove_cv_t<_Ty>>, "allocate_shared_for_overwrite should remove_cv_t"); + + using _Item = remove_all_extents_t<_Ty>; + using _Rebound = _Rebind_alloc_t<_Alloc, _Item>; + +public: + explicit _Ref_count_bounded_array_alloc_for_overwrite(const _Alloc& _Al_arg) + : _Ebco_base<_Rebound>(_Al_arg), _Ref_count_base() { // don't value-initialize _Storage + _Uninitialized_default_construct_multidimensional_n( + _Storage._Value, extent_v<_Ty>); // the allocator isn't needed + } + + union { + _Wrap<_Ty> _Storage; + }; + +private: + ~_Ref_count_bounded_array_alloc_for_overwrite() noexcept override { // TRANSITION, should be non-virtual + // nothing to do; _Storage._Value already destroyed by _Destroy() + + // See N4964 [class.dtor]/7. + } + + void _Destroy() noexcept override { // destroy managed resource + // not _Storage._Value as _Ty is an array type (not a class type or a scalar type), + // and thus cannot be used as a pseudo-destructor (N4964 [expr.prim.id.dtor]). + _Destroy_in_place(_Storage); // use the default mechanism per LWG-4024 + } + + void _Delete_this() noexcept override { // destroy self + _Rebind_alloc_t<_Alloc, _Ref_count_bounded_array_alloc_for_overwrite> _Al(this->_Get_val()); + this->~_Ref_count_bounded_array_alloc_for_overwrite(); + _Deallocate_plain(_Al, this); + } +}; #endif // _HAS_CXX20 _EXPORT_STD template @@ -2884,12 +3020,14 @@ struct _Allocate_n_ptr { _Allocate_n_ptr& operator=(const _Allocate_n_ptr&) = delete; }; -_EXPORT_STD /* TRANSITION, VSO-1538698 */ template +_EXPORT_STD /* TRANSITION, VSO-1538698 */ template _NODISCARD shared_ptr<_Ty> _Allocate_shared_unbounded_array( const _Alloc& _Al, const size_t _Count, const _ArgTypes&... _Args) { // make a shared_ptr to an unbounded array static_assert(is_unbounded_array_v<_Ty>); - using _Refc = _Ref_count_unbounded_array_alloc, _Alloc>; + using _Refc = conditional_t<_IsForOverwrite, // + _Ref_count_unbounded_array_alloc_for_overwrite, _Alloc>, + _Ref_count_unbounded_array_alloc, _Alloc>>; constexpr size_t _Align = alignof(_Refc); using _Storage = _Alignas_storage_unit<_Align>; _Rebind_alloc_t<_Alloc, _Storage> _Rebound(_Al); @@ -2907,13 +3045,13 @@ _NODISCARD shared_ptr<_Ty> _Allocate_shared_unbounded_array( _EXPORT_STD template _NODISCARD_SMART_PTR_ALLOC enable_if_t, shared_ptr<_Ty>> allocate_shared( const _Alloc& _Al, const size_t _Count) { - return _Allocate_shared_unbounded_array<_Ty>(_Al, _Count); + return _Allocate_shared_unbounded_array(_Al, _Count); } _EXPORT_STD template _NODISCARD_SMART_PTR_ALLOC enable_if_t, shared_ptr<_Ty>> allocate_shared( const _Alloc& _Al, const size_t _Count, const remove_extent_t<_Ty>& _Val) { - return _Allocate_shared_unbounded_array<_Ty>(_Al, _Count, _Val); + return _Allocate_shared_unbounded_array(_Al, _Count, _Val); } _EXPORT_STD template @@ -2953,22 +3091,22 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t, shared_ptr<_T shared_ptr<_Ty> _Ret; if constexpr (is_array_v<_Ty>) { // make a shared_ptr to a bounded array - using _Refc = _Ref_count_bounded_array_alloc, _Alloc>; + using _Refc = _Ref_count_bounded_array_alloc_for_overwrite, _Alloc>; using _Alblock = _Rebind_alloc_t<_Alloc, _Refc>; _Alblock _Rebound(_Al); _Alloc_construct_ptr _Constructor{_Rebound}; _Constructor._Allocate(); - ::new (_STD _Voidify_unfancy(_Constructor._Ptr)) _Refc(_Al, _For_overwrite_tag{}); + ::new (_STD _Voidify_unfancy(_Constructor._Ptr)) _Refc(_Al); const auto _Ptr = static_cast*>(_Constructor._Ptr->_Storage._Value); _Ret._Set_ptr_rep_and_enable_shared(_Ptr, _STD _Unfancy(_Constructor._Release())); } else { // make a shared_ptr to non-array object - using _Refoa = _Ref_count_obj_alloc3, _Alloc>; + using _Refoa = _Ref_count_obj_alloc_for_overwrite, _Alloc>; using _Alblock = _Rebind_alloc_t<_Alloc, _Refoa>; _Alblock _Rebound(_Al); _Alloc_construct_ptr<_Alblock> _Constructor{_Rebound}; _Constructor._Allocate(); - _STD _Construct_in_place(*_Constructor._Ptr, _Al, _For_overwrite_tag{}); + _STD _Construct_in_place(*_Constructor._Ptr, _Al); const auto _Ptr = reinterpret_cast<_Ty*>(_STD addressof(_Constructor._Ptr->_Storage._Value)); _Ret._Set_ptr_rep_and_enable_shared(_Ptr, _STD _Unfancy(_Constructor._Release())); } @@ -2979,7 +3117,7 @@ _NODISCARD_SMART_PTR_ALLOC enable_if_t, shared_ptr<_T _EXPORT_STD template _NODISCARD_SMART_PTR_ALLOC enable_if_t, shared_ptr<_Ty>> allocate_shared_for_overwrite( const _Alloc& _Al, const size_t _Count) { - return _Allocate_shared_unbounded_array<_Ty>(_Al, _Count, _For_overwrite_tag{}); + return _Allocate_shared_unbounded_array(_Al, _Count); } #endif // _HAS_CXX20 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index b5780ecd5ed..248dd417440 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -1155,9 +1155,6 @@ std/localization/locales/locale/locale.cons/name_construction.pass.cpp FAIL # Not analyzed. After LLVM-74630 fixes LLVM-74214, will be blocked by our ctype_base deriving from locale::facet. std/localization/locale.categories/category.numeric/locale.num.get/user_defined_char_type.pass.cpp FAIL -# Not analyzed. Assertion failed: alloc_stats.destroy_count == 0 -std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared_for_overwrite.pass.cpp FAIL - # Not analyzed. Assertion failed: res == cvt.ok std/localization/codecvt_unicode.pass.cpp FAIL From c5e9583748acdbcc77223d1f0007e20d6bc28ef6 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 31 Jan 2024 04:30:32 +0800 Subject: [PATCH 18/20] ``: Remove non-conforming extension `ios_base::hexfloat` (#4345) --- stl/inc/ios | 4 ++-- stl/inc/xiosbase | 2 -- stl/inc/xlocnum | 6 +++--- tests/tr1/tests/ios/test.cpp | 18 ++++++++---------- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/stl/inc/ios b/stl/inc/ios index 881c292ba29..24353546712 100644 --- a/stl/inc/ios +++ b/stl/inc/ios @@ -206,8 +206,8 @@ _EXPORT_STD inline ios_base& __CLRCALL_OR_CDECL hex(ios_base& _Iosbase) { // set return _Iosbase; } -_EXPORT_STD inline ios_base& __CLRCALL_OR_CDECL hexfloat(ios_base& _Iosbase) { // set floatfield to hexfloat - _Iosbase.setf(ios_base::hexfloat, ios_base::floatfield); +_EXPORT_STD inline ios_base& __CLRCALL_OR_CDECL hexfloat(ios_base& _Iosbase) { // set floatfield to (scientific | fixed) + _Iosbase.setf(ios_base::scientific | ios_base::fixed, ios_base::floatfield); return _Iosbase; } diff --git a/stl/inc/xiosbase b/stl/inc/xiosbase index a1b5ff24ae3..af192b61692 100644 --- a/stl/inc/xiosbase +++ b/stl/inc/xiosbase @@ -42,8 +42,6 @@ public: static constexpr int scientific = 0x1000; static constexpr int fixed = 0x2000; - static constexpr int hexfloat = 0x3000; // TRANSITION, ABI, GH-3296 - static constexpr int boolalpha = 0x4000; static constexpr int adjustfield = left | right | internal; static constexpr int basefield = dec | oct | hex; diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index cb0ddec7575..619596ea9d1 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -1441,7 +1441,7 @@ private: if (_Flags & ios_base::uppercase) { if (_Ffl == ios_base::fixed) { _Ch = 'f'; - } else if (_Ffl == ios_base::hexfloat) { + } else if (_Ffl == (ios_base::scientific | ios_base::fixed)) { _Ch = 'A'; // added with TR1 } else if (_Ffl == ios_base::scientific) { _Ch = 'E'; @@ -1451,7 +1451,7 @@ private: } else { if (_Ffl == ios_base::fixed) { _Ch = 'f'; - } else if (_Ffl == ios_base::hexfloat) { + } else if (_Ffl == (ios_base::scientific | ios_base::fixed)) { _Ch = 'a'; // added with TR1 } else if (_Ffl == ios_base::scientific) { _Ch = 'e'; @@ -1475,7 +1475,7 @@ private: bool _Is_finite_val) const { // put formatted floating-point to _Dest auto _Prefix = static_cast(0 < _Count && (*_Buf == '+' || *_Buf == '-')); const char* _Exps; - if ((_Iosbase.flags() & ios_base::floatfield) != ios_base::hexfloat) { + if ((_Iosbase.flags() & ios_base::floatfield) != (ios_base::scientific | ios_base::fixed)) { _Exps = "eE"; } else { // correct for hexadecimal floating-point _Exps = "pP"; diff --git a/tests/tr1/tests/ios/test.cpp b/tests/tr1/tests/ios/test.cpp index 43cb33b11be..f425e7e7ba1 100644 --- a/tests/tr1/tests/ios/test.cpp +++ b/tests/tr1/tests/ios/test.cpp @@ -12,11 +12,11 @@ #include // static data -static const STD ios_base::fmtflags ffl[] = {STD ios_base::hexfloat, STD ios_base::dec, STD ios_base::fixed, - STD ios_base::hex, STD ios_base::internal, STD ios_base::left, STD ios_base::oct, STD ios_base::right, - STD ios_base::scientific, STD ios_base::showbase, STD ios_base::showpoint, STD ios_base::showpos, - STD ios_base::skipws, STD ios_base::unitbuf, STD ios_base::uppercase, STD ios_base::boolalpha, - STD ios_base::adjustfield, STD ios_base::basefield, STD ios_base::floatfield}; +static const STD ios_base::fmtflags ffl[] = {STD ios_base::dec, STD ios_base::fixed, STD ios_base::hex, + STD ios_base::internal, STD ios_base::left, STD ios_base::oct, STD ios_base::right, STD ios_base::scientific, + STD ios_base::showbase, STD ios_base::showpoint, STD ios_base::showpos, STD ios_base::skipws, STD ios_base::unitbuf, + STD ios_base::uppercase, STD ios_base::boolalpha, STD ios_base::adjustfield, STD ios_base::basefield, + STD ios_base::floatfield}; static const STD ios_base::iostate ifl[] = { STD ios_base::badbit, STD ios_base::eofbit, STD ios_base::failbit, STD ios_base::goodbit}; @@ -86,8 +86,6 @@ void test_main() { // test basic workings of ios definitions CHECK_INT(STD ios_base::dec | STD ios_base::oct | STD ios_base::hex, STD ios_base::basefield); CHECK_INT(STD ios_base::scientific | STD ios_base::fixed, STD ios_base::floatfield); - CHECK_INT(STD ios_base::scientific | STD ios_base::fixed, STD ios_base::hexfloat); - // test assignment and control functions CHECK(x && true); CHECK(!x == 0); @@ -170,7 +168,7 @@ void test_main() { // test basic workings of ios definitions CHECK_INT(x.flags(), STD ios_base::scientific | STD ios_base::unitbuf); x.clear(STD ios_base::floatfield); - x.setf(STD ios_base::hexfloat); + x.setf(STD ios_base::scientific | STD ios_base::fixed); CHECK_INT(x.flags(), STD ios_base::scientific | STD ios_base::fixed | STD ios_base::unitbuf); CHECK_INT(x.precision(INT_MIN), 6); @@ -216,13 +214,13 @@ void test_main() { // test basic workings of ios definitions CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right | STD ios_base::scientific); STD hexfloat(*po); - CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right | STD ios_base::hexfloat); + CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right | STD ios_base::scientific | STD ios_base::fixed); STD defaultfloat(*po); CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right); STD hexfloat(*po); - CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right | STD ios_base::hexfloat); + CHECK_INT(po->flags(), STD ios_base::oct | STD ios_base::right | STD ios_base::scientific | STD ios_base::fixed); STD error_code ec1 = STD make_error_code(STD io_errc::stream); CHECK(ec1.value() == (int) STD io_errc::stream); From b89a78038285c852b52633e65d304a4f2cceea2d Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Wed, 31 Jan 2024 04:48:52 +0800 Subject: [PATCH 19/20] ADL-proof implementation of [alg.merge], [alg.set.operations], [alg.heap.operations], and [alg.permutation.generators] (#4347) Co-authored-by: Stephan T. Lavavej --- stl/inc/algorithm | 546 +++++++++--------- stl/inc/execution | 68 +-- stl/inc/xmemory | 22 +- stl/inc/xutility | 20 +- .../test.compile.pass.cpp | 78 +++ .../test.compile.pass.cpp | 78 +++ 6 files changed, 491 insertions(+), 321 deletions(-) diff --git a/stl/inc/algorithm b/stl/inc/algorithm index e793f01a441..47f957d9ed2 100644 --- a/stl/inc/algorithm +++ b/stl/inc/algorithm @@ -150,7 +150,7 @@ struct _Optimistic_temporary_buffer { // temporary storage with _alloca-like att } // less heap space than stack space, give up and use stack instead - _Return_temporary_buffer(_Raw.first); + _STD _Return_temporary_buffer(_Raw.first); _Data = reinterpret_cast<_Ty*>(&_Stack_space[0]); _Capacity = _Optimistic_count; } @@ -160,7 +160,7 @@ struct _Optimistic_temporary_buffer { // temporary storage with _alloca-like att ~_Optimistic_temporary_buffer() noexcept { if (static_cast(_Capacity) > _Optimistic_count) { - _Return_temporary_buffer(_Data); + _STD _Return_temporary_buffer(_Data); } } @@ -5956,7 +5956,7 @@ _BidIt _Buffered_rotate_unchecked(const _BidIt _First, const _BidIt _Mid, const if (_Count2 <= _Capacity) { // buffer right range, then copy parts _Uninitialized_backout<_Iter_value_t<_BidIt>*> _Backout{ _Temp_ptr, _STD _Uninitialized_move_unchecked(_Mid, _Last, _Temp_ptr)}; - _Move_backward_unchecked(_First, _Mid, _Last); + _STD _Move_backward_unchecked(_First, _Mid, _Last); return _STD _Move_unchecked(_Backout._First, _Backout._Last, _First); // ditto _Backout destroys elements } @@ -6316,14 +6316,14 @@ _CONSTEXPR20 void _Push_heap_by_index( _EXPORT_STD template _CONSTEXPR20 void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // push *(_Last - 1) onto heap at [_First, _Last - 1) - _Adl_verify_range(_First, _Last); - const auto _UFirst = _Get_unwrapped(_First); - auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Last); + const auto _UFirst = _STD _Get_unwrapped(_First); + auto _ULast = _STD _Get_unwrapped(_Last); using _Diff = _Iter_diff_t<_RanIt>; _Diff _Count = _ULast - _UFirst; if (2 <= _Count) { _Iter_value_t<_RanIt> _Val(_STD move(*--_ULast)); - _STD _Push_heap_by_index(_UFirst, --_Count, _Diff(0), _STD move(_Val), _Pass_fn(_Pred)); + _STD _Push_heap_by_index(_UFirst, --_Count, _Diff(0), _STD move(_Val), _STD _Pass_fn(_Pred)); } } @@ -6360,11 +6360,11 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - _Push_heap_unchecked(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + _Push_heap_unchecked(_STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -6372,12 +6372,12 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { if constexpr (common_range<_Rng>) { - _Push_heap_unchecked(_Ubegin(_Range), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _Push_heap_unchecked(_Ubegin(_Range), _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _RANGES end(_Range); } else { - auto _ULast = _Get_final_iterator_unwrapped(_Range); - _Push_heap_unchecked(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return _Rewrap_iterator(_Range, _STD move(_ULast)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped(_Range); + _Push_heap_unchecked(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return _RANGES _Rewrap_iterator(_Range, _STD move(_ULast)); } } @@ -6457,8 +6457,8 @@ _CONSTEXPR20 void _Pop_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { _EXPORT_STD template _CONSTEXPR20 void pop_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // pop *_First to *(_Last - 1) and reheap - _Adl_verify_range(_First, _Last); - _STD _Pop_heap_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred)); + _STD _Adl_verify_range(_First, _Last); + _STD _Pop_heap_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred)); } _EXPORT_STD template @@ -6537,11 +6537,12 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - _RANGES _Pop_heap_unchecked(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + _RANGES _Pop_heap_unchecked( + _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -6549,11 +6550,11 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { if constexpr (common_range<_Rng>) { - _RANGES _Pop_heap_unchecked(_Ubegin(_Range), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Pop_heap_unchecked(_Ubegin(_Range), _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _RANGES end(_Range); } else { auto _ULast = _Get_final_iterator_unwrapped(_Range); - _RANGES _Pop_heap_unchecked(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Pop_heap_unchecked(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _Rewrap_iterator(_Range, _STD move(_ULast)); } } @@ -6578,8 +6579,8 @@ _CONSTEXPR20 void _Make_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { _EXPORT_STD template _CONSTEXPR20 void make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // make [_First, _Last) into a heap - _Adl_verify_range(_First, _Last); - _Make_heap_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred)); + _STD _Adl_verify_range(_First, _Last); + _STD _Make_heap_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred)); } _EXPORT_STD template @@ -6609,11 +6610,12 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - _Make_heap_common(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + _RANGES _Make_heap_common( + _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -6621,12 +6623,12 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { if constexpr (common_range<_Rng>) { - _Make_heap_common(_Ubegin(_Range), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Make_heap_common(_Ubegin(_Range), _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _RANGES end(_Range); } else { - auto _ULast = _Get_final_iterator_unwrapped(_Range); - _Make_heap_common(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return _Rewrap_iterator(_Range, _STD move(_ULast)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped(_Range); + _RANGES _Make_heap_common(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return _RANGES _Rewrap_iterator(_Range, _STD move(_ULast)); } } }; @@ -6652,19 +6654,19 @@ _CONSTEXPR20 _RanIt _Is_heap_until_unchecked(_RanIt _First, _RanIt _Last, _Pr _P _EXPORT_STD template _NODISCARD _CONSTEXPR20 _RanIt is_heap_until(_RanIt _First, _RanIt _Last, _Pr _Pred) { // find extent of range that is a heap - _Adl_verify_range(_First, _Last); - _Seek_wrapped( - _First, _STD _Is_heap_until_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last), _Pass_fn(_Pred))); + _STD _Adl_verify_range(_First, _Last); + _STD _Seek_wrapped(_First, + _STD _Is_heap_until_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred))); return _First; } _EXPORT_STD template _NODISCARD _CONSTEXPR20 bool is_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // test if range is a heap - _Adl_verify_range(_First, _Last); - const auto _UFirst = _Get_unwrapped(_First); - const auto _ULast = _Get_unwrapped(_Last); - return _STD _Is_heap_until_unchecked(_UFirst, _ULast, _Pass_fn(_Pred)) == _ULast; + _STD _Adl_verify_range(_First, _Last); + const auto _UFirst = _STD _Get_unwrapped(_First); + const auto _ULast = _STD _Get_unwrapped(_Last); + return _STD _Is_heap_until_unchecked(_UFirst, _ULast, _STD _Pass_fn(_Pred)) == _ULast; } _EXPORT_STD template @@ -6685,7 +6687,7 @@ _NODISCARD _RanIt is_heap_until(_ExPo&& _Exec, _RanIt _First, _RanIt _Last, _Pr _EXPORT_STD template = 0> _NODISCARD bool is_heap(_ExPo&& _Exec, _RanIt _First, _RanIt _Last, _Pr _Pred) noexcept /* terminates */ { // test if range is a heap - return _STD is_heap_until(_STD forward<_ExPo>(_Exec), _First, _Last, _Pass_fn(_Pred)) == _Last; + return _STD is_heap_until(_STD forward<_ExPo>(_Exec), _First, _Last, _STD _Pass_fn(_Pred)) == _Last; } _EXPORT_STD template = 0> @@ -6731,12 +6733,12 @@ namespace ranges { template _Se, class _Pj = identity, indirect_strict_weak_order> _Pr = ranges::less> _NODISCARD constexpr bool operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - const auto _ULast = _Unwrap_sent<_It>(_STD move(_Last)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + const auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last)); const auto _Size = _RANGES distance(_UFirst, _ULast); const auto _UResult = - _RANGES _Is_heap_until_unchecked(_STD move(_UFirst), _Size, _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Is_heap_until_unchecked(_STD move(_UFirst), _Size, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _UResult == _ULast; } @@ -6745,7 +6747,7 @@ namespace ranges { _NODISCARD constexpr bool operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { const auto _Size = _RANGES distance(_Range); const auto _UResult = - _RANGES _Is_heap_until_unchecked(_Ubegin(_Range), _Size, _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Is_heap_until_unchecked(_Ubegin(_Range), _Size, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _UResult == _Uend(_Range); } }; @@ -6757,12 +6759,12 @@ namespace ranges { template _Se, class _Pj = identity, indirect_strict_weak_order> _Pr = ranges::less> _NODISCARD constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - const auto _Size = _RANGES distance(_UFirst, _Unwrap_sent<_It>(_STD move(_Last))); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + const auto _Size = _RANGES distance(_UFirst, _RANGES _Unwrap_sent<_It>(_STD move(_Last))); auto _UResult = - _RANGES _Is_heap_until_unchecked(_STD move(_UFirst), _Size, _Pass_fn(_Pred), _Pass_fn(_Proj)); - _Seek_wrapped(_First, _STD move(_UResult)); + _RANGES _Is_heap_until_unchecked(_STD move(_UFirst), _Size, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + _STD _Seek_wrapped(_First, _STD move(_UResult)); return _First; } @@ -6770,8 +6772,9 @@ namespace ranges { indirect_strict_weak_order, _Pj>> _Pr = ranges::less> _NODISCARD constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { const auto _Size = _RANGES distance(_Range); - auto _UResult = _RANGES _Is_heap_until_unchecked(_Ubegin(_Range), _Size, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return _Rewrap_iterator(_Range, _STD move(_UResult)); + auto _UResult = + _RANGES _Is_heap_until_unchecked(_Ubegin(_Range), _Size, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return _RANGES _Rewrap_iterator(_Range, _STD move(_UResult)); } }; @@ -6790,16 +6793,16 @@ _CONSTEXPR20 void _Sort_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { _EXPORT_STD template _CONSTEXPR20 void sort_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // order heap by repeatedly popping - _Adl_verify_range(_First, _Last); - const auto _UFirst = _Get_unwrapped(_First); - const auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Last); + const auto _UFirst = _STD _Get_unwrapped(_First); + const auto _ULast = _STD _Get_unwrapped(_Last); #if _ITERATOR_DEBUG_LEVEL == 2 - const auto _Counterexample = _STD _Is_heap_until_unchecked(_UFirst, _ULast, _Pass_fn(_Pred)); + const auto _Counterexample = _STD _Is_heap_until_unchecked(_UFirst, _ULast, _STD _Pass_fn(_Pred)); if (_Counterexample != _ULast) { _STL_REPORT_ERROR("invalid heap in sort_heap()"); } #endif // _ITERATOR_DEBUG_LEVEL == 2 - _Sort_heap_unchecked(_UFirst, _ULast, _Pass_fn(_Pred)); + _STD _Sort_heap_unchecked(_UFirst, _ULast, _STD _Pass_fn(_Pred)); } _EXPORT_STD template @@ -6823,11 +6826,12 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr _It operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - _Sort_heap_common(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + _RANGES _Sort_heap_common( + _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -6835,12 +6839,12 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr borrowed_iterator_t<_Rng> operator()(_Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { if constexpr (common_range<_Rng>) { - _Sort_heap_common(_Ubegin(_Range), _Uend(_Range), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _RANGES _Sort_heap_common(_Ubegin(_Range), _Uend(_Range), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _RANGES end(_Range); } else { - auto _ULast = _Get_final_iterator_unwrapped(_Range); - _Sort_heap_common(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return _Rewrap_iterator(_Range, _STD move(_ULast)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped(_Range); + _RANGES _Sort_heap_common(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return _RANGES _Rewrap_iterator(_Range, _STD move(_ULast)); } } }; @@ -7124,17 +7128,17 @@ _NODISCARD constexpr auto _Idl_dist_add(_Diff1 _Lhs, _Diff2 _Rhs) { _EXPORT_STD template _CONSTEXPR20 _OutIt merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // copy merging ranges - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); - const auto _Count1 = _Idl_distance<_InIt1>(_UFirst1, _ULast1); - const auto _Count2 = _Idl_distance<_InIt2>(_UFirst2, _ULast2); - auto _UDest = _Get_unwrapped_n(_Dest, _Idl_dist_add(_Count1, _Count2)); + const auto _Count1 = _STD _Idl_distance<_InIt1>(_UFirst1, _ULast1); + const auto _Count2 = _STD _Idl_distance<_InIt2>(_UFirst2, _ULast2); + auto _UDest = _STD _Get_unwrapped_n(_Dest, _Idl_dist_add(_Count1, _Count2)); if (_UFirst1 != _ULast1 && _UFirst2 != _ULast2) { for (;;) { if (_DEBUG_LT_PRED(_Pred, *_UFirst2, *_UFirst1)) { @@ -7158,7 +7162,7 @@ _CONSTEXPR20 _OutIt merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 } _UDest = _STD _Copy_unchecked(_UFirst1, _ULast1, _UDest); // copy any tail - _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); + _STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); return _Dest; } @@ -7178,7 +7182,7 @@ _FwdIt3 merge(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _FwdIt2 _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3); - return _STD merge(_First1, _Last1, _First2, _Last2, _Dest, _Pass_fn(_Pred)); + return _STD merge(_First1, _Last1, _First2, _Last2, _Dest, _STD _Pass_fn(_Pred)); } _EXPORT_STD template constexpr merge_result<_It1, _It2, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UResult = - _Merge_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), _Unwrap_sent<_It1>(_STD move(_Last1)), - _Unwrap_iter<_Se2>(_STD move(_First2)), _Unwrap_sent<_It2>(_STD move(_Last2)), _STD move(_Result), - _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UResult = _Merge_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD move(_Result), _STD _Pass_fn(_Pred), + _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); return {_STD move(_First1), _STD move(_First2), _STD move(_UResult.out)}; } @@ -7223,11 +7227,11 @@ namespace ranges { _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); auto _First2 = _RANGES begin(_Range2); - auto _UResult = _Merge_unchecked(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), - _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), _STD move(_Result), _Pass_fn(_Pred), - _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); + auto _UResult = _Merge_unchecked(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), + _RANGES _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), _STD move(_Result), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); return {_STD move(_First1), _STD move(_First2), _STD move(_UResult.out)}; } @@ -7284,7 +7288,7 @@ void _Rotate_one_right(_BidIt _First, _BidIt _Mid, _BidIt _Last) { // exchanges the range [_First, _Mid) with [_Mid, _Last) // pre: distance(_Mid, _Last) is 1 _Iter_value_t<_BidIt> _Temp(_STD move(*_Mid)); - _Move_backward_unchecked(_First, _Mid, _Last); + _STD _Move_backward_unchecked(_First, _Mid, _Last); *_First = _STD move(_Temp); } @@ -7346,7 +7350,7 @@ void _Inplace_merge_buffer_right( *--_Last = _STD move(*_Mid); if (_First == _Mid) { *--_Last = _STD move(*_Right_last); // to make [_Right_first, _Right_last) a half-open range - _Move_backward_unchecked(_Right_first, _Right_last, _Last); // move any head (and lowest element) + _STD _Move_backward_unchecked(_Right_first, _Right_last, _Last); // move any head (and lowest element) return; } @@ -7356,7 +7360,7 @@ void _Inplace_merge_buffer_right( --_Right_last; if (_Right_first == _Right_last) { // we can't compare with *_Right_first, but we know it is lowest *--_Last = _STD move(*_Mid); // restore half-open range [_First, _Mid) - _Move_backward_unchecked(_First, _Mid, _Last); + _STD _Move_backward_unchecked(_First, _Mid, _Last); *_First = _STD move(*_Right_first); return; } @@ -7374,11 +7378,11 @@ void _Buffered_inplace_merge_divide_and_conquer2(_BidIt _First, _BidIt _Mid, _Bi _BidIt _Firstn, _BidIt _Lastn, _Iter_diff_t<_BidIt> _Count1n, _Iter_diff_t<_BidIt> _Count2n) { // common block of _Buffered_inplace_merge_divide_and_conquer, below using _Diff = _Iter_diff_t<_BidIt>; - _BidIt _Midn = _Buffered_rotate_unchecked(_Firstn, _Mid, _Lastn, static_cast<_Diff>(_Count1 - _Count1n), _Count2n, - _Temp_ptr, _Capacity); // rearrange middle - _Buffered_inplace_merge_unchecked( + _BidIt _Midn = _STD _Buffered_rotate_unchecked(_Firstn, _Mid, _Lastn, static_cast<_Diff>(_Count1 - _Count1n), + _Count2n, _Temp_ptr, _Capacity); // rearrange middle + _STD _Buffered_inplace_merge_unchecked( _First, _Firstn, _Midn, _Count1n, _Count2n, _Temp_ptr, _Capacity, _Pred); // merge each new part - _Buffered_inplace_merge_unchecked(_Midn, _Lastn, _Last, static_cast<_Diff>(_Count1 - _Count1n), + _STD _Buffered_inplace_merge_unchecked(_Midn, _Lastn, _Last, static_cast<_Diff>(_Count1 - _Count1n), static_cast<_Diff>(_Count2 - _Count2n), _Temp_ptr, _Capacity, _Pred); } @@ -7441,7 +7445,7 @@ void _Buffered_inplace_merge_unchecked(_BidIt _First, _BidIt _Mid, _BidIt _Last, --_Count1; } - const auto _Highest = _Prev_iter(_Mid); + const auto _Highest = _STD _Prev_iter(_Mid); do { --_Last; --_Count2; @@ -7459,17 +7463,17 @@ void _Buffered_inplace_merge_unchecked(_BidIt _First, _BidIt _Mid, _BidIt _Last, return; } - _Buffered_inplace_merge_unchecked_impl(_First, _Mid, _Last, _Count1, _Count2, _Temp_ptr, _Capacity, _Pred); + _STD _Buffered_inplace_merge_unchecked_impl(_First, _Mid, _Last, _Count1, _Count2, _Temp_ptr, _Capacity, _Pred); } _EXPORT_STD template void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) { // merge [_First, _Mid) with [_Mid, _Last) - _Adl_verify_range(_First, _Mid); - _Adl_verify_range(_Mid, _Last); - auto _UFirst = _Get_unwrapped(_First); - auto _UMid = _Get_unwrapped(_Mid); - auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Mid); + _STD _Adl_verify_range(_Mid, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + auto _UMid = _STD _Get_unwrapped(_Mid); + auto _ULast = _STD _Get_unwrapped(_Last); _DEBUG_ORDER_UNWRAPPED(_UFirst, _UMid, _Pred); // establish the usual invariants: @@ -7489,7 +7493,7 @@ void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) { ++_UFirst; } - const auto _Highest = _Prev_iter(_UMid); + const auto _Highest = _STD _Prev_iter(_UMid); do { --_ULast; if (_UMid == _ULast) { // rotate only element remaining in right partition to the beginning, without allocating @@ -7509,8 +7513,8 @@ void inplace_merge(_BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) { const _Diff _Count2 = _STD distance(_UMid, _ULast); _Optimistic_temporary_buffer<_Iter_value_t<_BidIt>> _Temp_buf{(_STD min)(_Count1, _Count2)}; - _Buffered_inplace_merge_unchecked_impl( - _UFirst, _UMid, _ULast, _Count1, _Count2, _Temp_buf._Data, _Temp_buf._Capacity, _Pass_fn(_Pred)); + _STD _Buffered_inplace_merge_unchecked_impl( + _UFirst, _UMid, _ULast, _Count1, _Count2, _Temp_buf._Data, _Temp_buf._Capacity, _STD _Pass_fn(_Pred)); } _EXPORT_STD template @@ -7525,7 +7529,7 @@ void inplace_merge(_ExPo&&, _BidIt _First, _BidIt _Mid, _BidIt _Last, _Pr _Pred) // merge [_First, _Mid) with [_Mid, _Last) // not parallelized at present, parallelism expected to be feasible in a future release _REQUIRE_CPP17_MUTABLE_BIDIRECTIONAL_ITERATOR(_BidIt); - _STD inplace_merge(_First, _Mid, _Last, _Pass_fn(_Pred)); + _STD inplace_merge(_First, _Mid, _Last, _STD _Pass_fn(_Pred)); } _EXPORT_STD template = 0> @@ -7760,15 +7764,15 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> _It operator()(_It _First, _It _Mid, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Mid); - _Adl_verify_range(_Mid, _Last); + _STD _Adl_verify_range(_First, _Mid); + _STD _Adl_verify_range(_Mid, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); - _Inplace_merge_common(_STD move(_UFirst), _Unwrap_iter<_Se>(_STD move(_Mid)), _STD move(_ULast), - _Pass_fn(_Pred), _Pass_fn(_Proj)); + _Inplace_merge_common(_STD move(_UFirst), _RANGES _Unwrap_iter<_Se>(_STD move(_Mid)), _STD move(_ULast), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -7779,15 +7783,15 @@ namespace ranges { auto _First = _RANGES begin(_Range); auto _Last = _RANGES end(_Range); - _Adl_verify_range(_First, _Mid); - _Adl_verify_range(_Mid, _Last); + _STD _Adl_verify_range(_First, _Mid); + _STD _Adl_verify_range(_Mid, _Last); - auto _UFirst = _Unwrap_range_iter<_Rng>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); + auto _UFirst = _RANGES _Unwrap_range_iter<_Rng>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); - _Inplace_merge_common(_STD move(_UFirst), _Unwrap_range_iter<_Rng>(_STD move(_Mid)), _STD move(_ULast), - _Pass_fn(_Pred), _Pass_fn(_Proj)); + _Inplace_merge_common(_STD move(_UFirst), _RANGES _Unwrap_range_iter<_Rng>(_STD move(_Mid)), + _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return _First; } @@ -9088,12 +9092,12 @@ namespace ranges { _EXPORT_STD template _NODISCARD _CONSTEXPR20 bool includes(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _Pr _Pred) { // test if every element in sorted [_First2, _Last2) is in sorted [_First1, _Last1) - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); for (; _UFirst1 != _ULast1 && _UFirst2 != _ULast2; ++_UFirst1) { @@ -9123,7 +9127,7 @@ _NODISCARD bool includes(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Firs // not parallelized at present, parallelism expected to be feasible in a future release _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); - return _STD includes(_First1, _Last1, _First2, _Last2, _Pass_fn(_Pred)); + return _STD includes(_First1, _Last1, _First2, _Last2, _STD _Pass_fn(_Pred)); } _EXPORT_STD template = 0> @@ -9145,11 +9149,12 @@ namespace ranges { indirect_strict_weak_order, projected<_It2, _Pj2>> _Pr = ranges::less> _NODISCARD constexpr bool operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - return _Includes_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), _Unwrap_sent<_It1>(_STD move(_Last1)), - _Unwrap_iter<_Se2>(_STD move(_First2)), _Unwrap_sent<_It2>(_STD move(_Last2)), _Pass_fn(_Pred), - _Pass_fn(_Proj1), _Pass_fn(_Proj2)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + return _Includes_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), + _STD _Pass_fn(_Proj2)); } template _CONSTEXPR20 _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // OR sets [_First1, _Last1) and [_First2, _Last2) - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); - auto _UDest = _Get_unwrapped_unverified(_Dest); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); for (; _UFirst1 != _ULast1 && _UFirst2 != _ULast2; ++_UDest) { if (_DEBUG_LT_PRED(_Pred, *_UFirst1, *_UFirst2)) { // copy first *_UDest = *_UFirst1; @@ -9234,7 +9239,7 @@ _CONSTEXPR20 _OutIt set_union(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _In } _UDest = _STD _Copy_unchecked(_UFirst1, _ULast1, _UDest); - _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); + _STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); return _Dest; } @@ -9254,7 +9259,7 @@ _FwdIt3 set_union(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2, _Fw _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3); - return _STD set_union(_First1, _Last1, _First2, _Last2, _Dest, _Pass_fn(_Pred)); + return _STD set_union(_First1, _Last1, _First2, _Last2, _Dest, _STD _Pass_fn(_Pred)); } _EXPORT_STD template constexpr set_union_result<_It1, _It2, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UResult = - _Set_union_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), _Unwrap_sent<_It1>(_STD move(_Last1)), - _Unwrap_iter<_Se2>(_STD move(_First2)), _Unwrap_sent<_It2>(_STD move(_Last2)), - _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UResult = _Set_union_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Get_unwrapped_unverified(_STD move(_Result)), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -9300,12 +9305,13 @@ namespace ranges { _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); auto _First2 = _RANGES begin(_Range2); - auto _UResult = _Set_union_unchecked(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), - _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), - _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + auto _UResult = _Set_union_unchecked(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), + _RANGES _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), + _STD _Get_unwrapped_unverified(_STD move(_Result)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), + _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -9348,15 +9354,15 @@ _EXPORT_STD template _CONSTEXPR20 _OutIt set_intersection( _InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // AND sets [_First1, _Last1) and [_First2, _Last2) - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); - auto _UDest = _Get_unwrapped_unverified(_Dest); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); while (_UFirst1 != _ULast1 && _UFirst2 != _ULast2) { if (_DEBUG_LT_PRED(_Pred, *_UFirst1, *_UFirst2)) { ++_UFirst1; @@ -9370,7 +9376,7 @@ _CONSTEXPR20 _OutIt set_intersection( } } - _Seek_wrapped(_Dest, _UDest); + _STD _Seek_wrapped(_Dest, _UDest); return _Dest; } @@ -9406,15 +9412,15 @@ namespace ranges { requires mergeable<_It1, _It2, _Out, _Pr, _Pj1, _Pj2> constexpr set_intersection_result<_It1, _It2, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UResult = _Set_intersection_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), - _Unwrap_sent<_It1>(_STD move(_Last1)), _Unwrap_iter<_Se2>(_STD move(_First2)), - _Unwrap_sent<_It2>(_STD move(_Last2)), _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), - _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UResult = _Set_intersection_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Get_unwrapped_unverified(_STD move(_Result)), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -9425,12 +9431,13 @@ namespace ranges { _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); auto _First2 = _RANGES begin(_Range2); - auto _UResult = _Set_intersection_unchecked(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), - _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), - _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + auto _UResult = _Set_intersection_unchecked(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)), + _Uend(_Range1), _RANGES _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), + _STD _Get_unwrapped_unverified(_STD move(_Result)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), + _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -9479,15 +9486,15 @@ _EXPORT_STD template _CONSTEXPR20 _OutIt set_difference( _InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // take set [_First2, _Last2) from [_First1, _Last1) - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); - auto _UDest = _Get_unwrapped_unverified(_Dest); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); while (_UFirst1 != _ULast1 && _UFirst2 != _ULast2) { if (_DEBUG_LT_PRED(_Pred, *_UFirst1, *_UFirst2)) { // copy first *_UDest = *_UFirst1; @@ -9502,7 +9509,7 @@ _CONSTEXPR20 _OutIt set_difference( } } - _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst1, _ULast1, _UDest)); + _STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst1, _ULast1, _UDest)); return _Dest; } @@ -9538,14 +9545,14 @@ namespace ranges { requires mergeable<_It1, _It2, _Out, _Pr, _Pj1, _Pj2> constexpr set_difference_result<_It1, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UResult = - _Set_difference_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), _Unwrap_sent<_It1>(_STD move(_Last1)), - _Unwrap_iter<_Se2>(_STD move(_First2)), _Unwrap_sent<_It2>(_STD move(_Last2)), - _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UResult = _Set_difference_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Get_unwrapped_unverified(_STD move(_Result)), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_Result)}; } @@ -9555,11 +9562,11 @@ namespace ranges { constexpr set_difference_result, _Out> operator()( _Rng1&& _Range1, _Rng2&& _Range2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); - auto _UResult = _Set_difference_unchecked(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), _Uend(_Range1), - _Ubegin(_Range2), _Uend(_Range2), _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), - _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + auto _UResult = _Set_difference_unchecked(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)), + _Uend(_Range1), _Ubegin(_Range2), _Uend(_Range2), _STD _Get_unwrapped_unverified(_STD move(_Result)), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_Result)}; } @@ -9607,15 +9614,15 @@ _EXPORT_STD template _CONSTEXPR20 _OutIt set_symmetric_difference( _InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest, _Pr _Pred) { // XOR sets [_First1, _Last1) and [_First2, _Last2) - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); _DEBUG_ORDER_SET_UNWRAPPED(_InIt2, _UFirst1, _ULast1, _Pred); _DEBUG_ORDER_SET_UNWRAPPED(_InIt1, _UFirst2, _ULast2, _Pred); - auto _UDest = _Get_unwrapped_unverified(_Dest); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); while (_UFirst1 != _ULast1 && _UFirst2 != _ULast2) { if (_DEBUG_LT_PRED(_Pred, *_UFirst1, *_UFirst2)) { // copy first *_UDest = *_UFirst1; @@ -9632,7 +9639,7 @@ _CONSTEXPR20 _OutIt set_symmetric_difference( } _UDest = _STD _Copy_unchecked(_UFirst1, _ULast1, _UDest); - _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); + _STD _Seek_wrapped(_Dest, _STD _Copy_unchecked(_UFirst2, _ULast2, _UDest)); return _Dest; } @@ -9653,7 +9660,7 @@ _FwdIt3 set_symmetric_difference(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdI _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3); - return _STD set_symmetric_difference(_First1, _Last1, _First2, _Last2, _Dest, _Pass_fn(_Pred)); + return _STD set_symmetric_difference(_First1, _Last1, _First2, _Last2, _Dest, _STD _Pass_fn(_Pred)); } _EXPORT_STD template constexpr set_symmetric_difference_result<_It1, _It2, _Out> operator()(_It1 _First1, _Se1 _Last1, _It2 _First2, _Se2 _Last2, _Out _Result, _Pr _Pred = {}, _Pj1 _Proj1 = {}, _Pj2 _Proj2 = {}) const { - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UResult = _Set_symmetric_difference_unchecked(_Unwrap_iter<_Se1>(_STD move(_First1)), - _Unwrap_sent<_It1>(_STD move(_Last1)), _Unwrap_iter<_Se2>(_STD move(_First2)), - _Unwrap_sent<_It2>(_STD move(_Last2)), _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), - _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UResult = _Set_symmetric_difference_unchecked(_RANGES _Unwrap_iter<_Se1>(_STD move(_First1)), + _RANGES _Unwrap_sent<_It1>(_STD move(_Last1)), _RANGES _Unwrap_iter<_Se2>(_STD move(_First2)), + _RANGES _Unwrap_sent<_It2>(_STD move(_Last2)), _STD _Get_unwrapped_unverified(_STD move(_Result)), + _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -9700,12 +9707,13 @@ namespace ranges { _Pj2 _Proj2 = {}) const { auto _First1 = _RANGES begin(_Range1); auto _First2 = _RANGES begin(_Range2); - auto _UResult = _Set_symmetric_difference_unchecked(_Unwrap_range_iter<_Rng1>(_STD move(_First1)), - _Uend(_Range1), _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), - _Get_unwrapped_unverified(_STD move(_Result)), _Pass_fn(_Pred), _Pass_fn(_Proj1), _Pass_fn(_Proj2)); - _Seek_wrapped(_First1, _STD move(_UResult.in1)); - _Seek_wrapped(_First2, _STD move(_UResult.in2)); - _Seek_wrapped(_Result, _STD move(_UResult.out)); + auto _UResult = _Set_symmetric_difference_unchecked(_RANGES _Unwrap_range_iter<_Rng1>(_STD move(_First1)), + _Uend(_Range1), _RANGES _Unwrap_range_iter<_Rng2>(_STD move(_First2)), _Uend(_Range2), + _STD _Get_unwrapped_unverified(_STD move(_Result)), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj1), + _STD _Pass_fn(_Proj2)); + _STD _Seek_wrapped(_First1, _STD move(_UResult.in1)); + _STD _Seek_wrapped(_First2, _STD move(_UResult.in2)); + _STD _Seek_wrapped(_Result, _STD move(_UResult.out)); return {_STD move(_First1), _STD move(_First2), _STD move(_Result)}; } @@ -10147,9 +10155,9 @@ namespace ranges { _EXPORT_STD template _CONSTEXPR20 bool next_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) { // permute and test for pure ascending - _Adl_verify_range(_First, _Last); - auto _UFirst = _Get_unwrapped(_First); - const auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + const auto _ULast = _STD _Get_unwrapped(_Last); auto _UNext = _ULast; if (_UFirst == _ULast || _UFirst == --_UNext) { return false; @@ -10191,12 +10199,12 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr next_permutation_result<_It> operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - const bool _Found = - _Next_permutation_common(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + const bool _Found = _Next_permutation_common( + _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return {_STD move(_First), _Found}; } @@ -10204,9 +10212,10 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr next_permutation_result> operator()( _Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { - auto _ULast = _Get_final_iterator_unwrapped(_Range); - const bool _Found = _Next_permutation_common(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return {_Rewrap_iterator(_Range, _STD move(_ULast)), _Found}; + auto _ULast = _RANGES _Get_final_iterator_unwrapped(_Range); + const bool _Found = + _Next_permutation_common(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return {_RANGES _Rewrap_iterator(_Range, _STD move(_ULast)), _Found}; } private: @@ -10230,12 +10239,12 @@ namespace ranges { } while (!_STD invoke(_Pred, _STD invoke(_Proj, *_Next), _STD invoke(_Proj, *_Mid))); _RANGES iter_swap(_Next, _Mid); - _Reverse_common(_STD move(_Next1), _STD move(_Last)); + _RANGES _Reverse_common(_STD move(_Next1), _STD move(_Last)); return true; } if (_Next == _First) { // pure descending, flip all - _Reverse_common(_STD move(_First), _STD move(_Last)); + _RANGES _Reverse_common(_STD move(_First), _STD move(_Last)); return false; } } @@ -10249,9 +10258,9 @@ namespace ranges { _EXPORT_STD template _CONSTEXPR20 bool prev_permutation(_BidIt _First, _BidIt _Last, _Pr _Pred) { // reverse permute and test for pure descending - _Adl_verify_range(_First, _Last); - auto _UFirst = _Get_unwrapped(_First); - const auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + const auto _ULast = _STD _Get_unwrapped(_Last); auto _UNext = _ULast; if (_UFirst == _ULast || _UFirst == --_UNext) { return false; @@ -10293,12 +10302,12 @@ namespace ranges { template _Se, class _Pr = ranges::less, class _Pj = identity> requires sortable<_It, _Pr, _Pj> constexpr prev_permutation_result<_It> operator()(_It _First, _Se _Last, _Pr _Pred = {}, _Pj _Proj = {}) const { - _Adl_verify_range(_First, _Last); - auto _UFirst = _Unwrap_iter<_Se>(_STD move(_First)); - auto _ULast = _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); - _Seek_wrapped(_First, _ULast); - const bool _Found = - _Prev_permutation_common(_STD move(_UFirst), _STD move(_ULast), _Pass_fn(_Pred), _Pass_fn(_Proj)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First)); + auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last)); + _STD _Seek_wrapped(_First, _ULast); + const bool _Found = _Prev_permutation_common( + _STD move(_UFirst), _STD move(_ULast), _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); return {_STD move(_First), _Found}; } @@ -10306,9 +10315,10 @@ namespace ranges { requires sortable, _Pr, _Pj> constexpr prev_permutation_result> operator()( _Rng&& _Range, _Pr _Pred = {}, _Pj _Proj = {}) const { - auto _ULast = _Get_final_iterator_unwrapped(_Range); - const bool _Found = _Prev_permutation_common(_Ubegin(_Range), _ULast, _Pass_fn(_Pred), _Pass_fn(_Proj)); - return {_Rewrap_iterator(_Range, _STD move(_ULast)), _Found}; + auto _ULast = _RANGES _Get_final_iterator_unwrapped(_Range); + const bool _Found = + _Prev_permutation_common(_Ubegin(_Range), _ULast, _STD _Pass_fn(_Pred), _STD _Pass_fn(_Proj)); + return {_RANGES _Rewrap_iterator(_Range, _STD move(_ULast)), _Found}; } private: @@ -10332,12 +10342,12 @@ namespace ranges { } while (!_STD invoke(_Pred, _STD invoke(_Proj, *_Mid), _STD invoke(_Proj, *_Next))); _RANGES iter_swap(_Next, _Mid); - _Reverse_common(_STD move(_Next1), _STD move(_Last)); + _RANGES _Reverse_common(_STD move(_Next1), _STD move(_Last)); return true; } if (_Next == _First) { // pure ascending, flip all - _Reverse_common(_STD move(_First), _STD move(_Last)); + _RANGES _Reverse_common(_STD move(_First), _STD move(_Last)); return false; } } @@ -10351,9 +10361,9 @@ namespace ranges { _EXPORT_STD template _NODISCARD _CONSTEXPR20 _FwdIt is_sorted_until(const _FwdIt _First, _FwdIt _Last, _Pr _Pred) { // find extent of range that is ordered by predicate - _Adl_verify_range(_First, _Last); - auto _UFirst = _Get_unwrapped(_First); - auto _ULast = _Get_unwrapped(_Last); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + auto _ULast = _STD _Get_unwrapped(_Last); if (_UFirst != _ULast) { for (auto _UNext = _UFirst; ++_UNext != _ULast; ++_UFirst) { if (_DEBUG_LT_PRED(_Pred, *_UNext, *_UFirst)) { @@ -10363,17 +10373,17 @@ _NODISCARD _CONSTEXPR20 _FwdIt is_sorted_until(const _FwdIt _First, _FwdIt _Last } } - _Seek_wrapped(_Last, _ULast); + _STD _Seek_wrapped(_Last, _ULast); return _Last; } _EXPORT_STD template _NODISCARD _CONSTEXPR20 bool is_sorted(_FwdIt _First, _FwdIt _Last, _Pr _Pred) { // test if range is ordered by predicate - _Adl_verify_range(_First, _Last); - const auto _UFirst = _Get_unwrapped(_First); - const auto _ULast = _Get_unwrapped(_Last); - return _STD is_sorted_until(_UFirst, _ULast, _Pass_fn(_Pred)) == _ULast; + _STD _Adl_verify_range(_First, _Last); + const auto _UFirst = _STD _Get_unwrapped(_First); + const auto _ULast = _STD _Get_unwrapped(_Last); + return _STD is_sorted_until(_UFirst, _ULast, _STD _Pass_fn(_Pred)) == _ULast; } _EXPORT_STD template @@ -10394,7 +10404,7 @@ _NODISCARD _FwdIt is_sorted_until(_ExPo&&, _FwdIt _First, _FwdIt _Last, _Pr _Pre _EXPORT_STD template = 0> _NODISCARD bool is_sorted(_ExPo&& _Exec, _FwdIt _First, _FwdIt _Last, _Pr _Pred) noexcept /* terminates */ { // test if range is ordered by predicate - return _STD is_sorted_until(_STD forward<_ExPo>(_Exec), _First, _Last, _Pass_fn(_Pred)) == _Last; + return _STD is_sorted_until(_STD forward<_ExPo>(_Exec), _First, _Last, _STD _Pass_fn(_Pred)) == _Last; } _EXPORT_STD template = 0> diff --git a/stl/inc/execution b/stl/inc/execution index c40636af786..6daa8a156ad 100644 --- a/stl/inc/execution +++ b/stl/inc/execution @@ -3286,7 +3286,7 @@ struct _Static_partitioned_is_heap_until2 { static void __stdcall _Threadpool_callback( __std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ { - _Run_available_chunked_work(*static_cast<_Static_partitioned_is_heap_until2*>(_Context)); + _STD _Run_available_chunked_work(*static_cast<_Static_partitioned_is_heap_until2*>(_Context)); } }; @@ -3294,18 +3294,19 @@ _EXPORT_STD template ::_Parallelize) { const size_t _Hw_threads = __std_parallel_algorithms_hw_threads(); if (_Hw_threads > 1) { // parallelize on multiprocessor machines const auto _Count = _ULast - _UFirst; if (_Count >= 3) { // ... with at least 3 elements _TRY_BEGIN - _Static_partitioned_is_heap_until2 _Operation{_UFirst, _ULast, _Hw_threads, _Count, _Pass_fn(_Pred)}; - _Run_chunked_parallel_work(_Hw_threads, _Operation); - _Seek_wrapped(_First, _Operation._Results._Get_result()); + _Static_partitioned_is_heap_until2 _Operation{ + _UFirst, _ULast, _Hw_threads, _Count, _STD _Pass_fn(_Pred)}; + _STD _Run_chunked_parallel_work(_Hw_threads, _Operation); + _STD _Seek_wrapped(_First, _Operation._Results._Get_result()); return _First; _CATCH(const _Parallelism_resources_exhausted&) // fall through to serial case below @@ -3314,7 +3315,7 @@ _NODISCARD _RanIt is_heap_until(_ExPo&&, _RanIt _First, _RanIt _Last, _Pr _Pred) } } - _Seek_wrapped(_First, _STD is_heap_until(_UFirst, _ULast, _Pass_fn(_Pred))); + _STD _Seek_wrapped(_First, _STD is_heap_until(_UFirst, _ULast, _STD _Pass_fn(_Pred))); return _First; } @@ -3765,7 +3766,7 @@ struct _Static_partitioned_set_subtraction { // Get chunk in _Range2 that corresponds to our current chunk from _Range1 auto _Range2_chunk_first = _STD lower_bound(_Range2._First, _Range2._Last, *_Range1_chunk_first, _Pred); auto _Range2_chunk_last = - _STD upper_bound(_Range2_chunk_first, _Range2._Last, *_Prev_iter(_Range1_chunk_last), _Pred); + _STD upper_bound(_Range2_chunk_first, _Range2._Last, *_STD _Prev_iter(_Range1_chunk_last), _Pred); // Publish results to rest of chunks. if (_Chunk_number == 0) { @@ -3816,14 +3817,14 @@ struct _Static_partitioned_set_subtraction { // Place elements from _Range1 in _Dest according to the offsets previously calculated. auto _Chunk_specific_dest = _Dest + static_cast<_Iter_diff_t<_RanIt3>>(_Prev_chunk_sum); - _Place_elements_from_indices( + _STD _Place_elements_from_indices( _Range1_chunk_first, _Chunk_specific_dest, _Index_chunk_first, static_cast(_Num_results)); return _Cancellation_status::_Running; } static void __stdcall _Threadpool_callback( __std_PTP_CALLBACK_INSTANCE, void* const _Context, __std_PTP_WORK) noexcept /* terminates */ { - _Run_available_chunked_work(*static_cast<_Static_partitioned_set_subtraction*>(_Context)); + _STD _Run_available_chunked_work(*static_cast<_Static_partitioned_set_subtraction*>(_Context)); } }; @@ -3877,13 +3878,13 @@ _FwdIt3 set_intersection(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Firs _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3); - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); - auto _UDest = _Get_unwrapped_unverified(_Dest); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); using _Diff = _Common_diff_t<_FwdIt1, _FwdIt2, _FwdIt3>; if constexpr (remove_reference_t<_ExPo>::_Parallelize && _Is_ranges_random_iter_v<_FwdIt1> && _Is_ranges_random_iter_v<_FwdIt2> && _Is_cpp17_random_iter_v<_FwdIt3>) { @@ -3895,10 +3896,10 @@ _FwdIt3 set_intersection(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Firs if (_Count1 >= 2 && _Count2 >= 2) { // ... with each range containing at least 2 elements _TRY_BEGIN _Static_partitioned_set_subtraction _Operation(_Hw_threads, _Count1, _UFirst1, _UFirst2, _ULast2, - _UDest, _Pass_fn(_Pred), _Set_intersection_per_chunk()); - _Run_chunked_parallel_work(_Hw_threads, _Operation); + _UDest, _STD _Pass_fn(_Pred), _Set_intersection_per_chunk()); + _STD _Run_chunked_parallel_work(_Hw_threads, _Operation); _UDest += static_cast<_Iter_diff_t<_FwdIt3>>(_Operation._Lookback.back()._Sum._Ref()); - _Seek_wrapped(_Dest, _UDest); + _STD _Seek_wrapped(_Dest, _UDest); return _Dest; _CATCH(const _Parallelism_resources_exhausted&) // fall through to serial case below @@ -3907,7 +3908,8 @@ _FwdIt3 set_intersection(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _Firs } } - _Seek_wrapped(_Dest, _STD set_intersection(_UFirst1, _ULast1, _UFirst2, _ULast2, _UDest, _Pass_fn(_Pred))); + _STD _Seek_wrapped( + _Dest, _STD set_intersection(_UFirst1, _ULast1, _UFirst2, _ULast2, _UDest, _STD _Pass_fn(_Pred))); return _Dest; } @@ -3967,13 +3969,13 @@ _FwdIt3 set_difference(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2 _REQUIRE_PARALLEL_ITERATOR(_FwdIt1); _REQUIRE_PARALLEL_ITERATOR(_FwdIt2); _REQUIRE_CPP17_MUTABLE_ITERATOR(_FwdIt3); - _Adl_verify_range(_First1, _Last1); - _Adl_verify_range(_First2, _Last2); - auto _UFirst1 = _Get_unwrapped(_First1); - const auto _ULast1 = _Get_unwrapped(_Last1); - auto _UFirst2 = _Get_unwrapped(_First2); - const auto _ULast2 = _Get_unwrapped(_Last2); - auto _UDest = _Get_unwrapped_unverified(_Dest); + _STD _Adl_verify_range(_First1, _Last1); + _STD _Adl_verify_range(_First2, _Last2); + auto _UFirst1 = _STD _Get_unwrapped(_First1); + const auto _ULast1 = _STD _Get_unwrapped(_Last1); + auto _UFirst2 = _STD _Get_unwrapped(_First2); + const auto _ULast2 = _STD _Get_unwrapped(_Last2); + auto _UDest = _STD _Get_unwrapped_unverified(_Dest); using _Diff = _Common_diff_t<_FwdIt1, _FwdIt2, _FwdIt3>; if constexpr (remove_reference_t<_ExPo>::_Parallelize && _Is_ranges_random_iter_v<_FwdIt1> && _Is_ranges_random_iter_v<_FwdIt2> && _Is_cpp17_random_iter_v<_FwdIt3>) { @@ -3984,10 +3986,10 @@ _FwdIt3 set_difference(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2 if (_Count >= 2) { // ... with at least 2 elements in [_First1, _Last1) _TRY_BEGIN _Static_partitioned_set_subtraction _Operation(_Hw_threads, _Count, _UFirst1, _UFirst2, _ULast2, _UDest, - _Pass_fn(_Pred), _Set_difference_per_chunk()); - _Run_chunked_parallel_work(_Hw_threads, _Operation); + _STD _Pass_fn(_Pred), _Set_difference_per_chunk()); + _STD _Run_chunked_parallel_work(_Hw_threads, _Operation); _UDest += static_cast<_Iter_diff_t<_FwdIt3>>(_Operation._Lookback.back()._Sum._Ref()); - _Seek_wrapped(_Dest, _UDest); + _STD _Seek_wrapped(_Dest, _UDest); return _Dest; _CATCH(const _Parallelism_resources_exhausted&) // fall through to serial case below @@ -3996,7 +3998,7 @@ _FwdIt3 set_difference(_ExPo&&, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First2 } } - _Seek_wrapped(_Dest, _STD set_difference(_UFirst1, _ULast1, _UFirst2, _ULast2, _UDest, _Pass_fn(_Pred))); + _STD _Seek_wrapped(_Dest, _STD set_difference(_UFirst1, _ULast1, _UFirst2, _ULast2, _UDest, _STD _Pass_fn(_Pred))); return _Dest; } diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 7d709382ebd..2839843709c 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -1636,13 +1636,13 @@ struct _NODISCARD _Uninitialized_backout { _Uninitialized_backout& operator=(const _Uninitialized_backout&) = delete; _CONSTEXPR20 ~_Uninitialized_backout() { - _Destroy_range(_First, _Last); + _STD _Destroy_range(_First, _Last); } template _CONSTEXPR20 void _Emplace_back(_Types&&... _Vals) { // construct a new element at *_Last and increment - _Construct_in_place(*_Last, _STD forward<_Types>(_Vals)...); + _STD _Construct_in_place(*_Last, _STD forward<_Types>(_Vals)...); ++_Last; } @@ -1660,7 +1660,7 @@ _CONSTEXPR20 _NoThrowFwdIt _Uninitialized_move_unchecked(_InIt _First, const _In if (!_STD is_constant_evaluated()) #endif // _HAS_CXX20 { - return _Copy_memmove(_First, _Last, _Dest); + return _STD _Copy_memmove(_First, _Last, _Dest); } } _Uninitialized_backout<_NoThrowFwdIt> _Backout{_Dest}; @@ -1746,10 +1746,10 @@ namespace ranges { template in_out_result<_InIt, _OutIt> _Copy_memcpy_common( _InIt _IFirst, _InIt _ILast, _OutIt _OFirst, _OutIt _OLast) noexcept { - const auto _IFirstPtr = _To_address(_IFirst); - const auto _ILastPtr = _To_address(_ILast); - const auto _OFirstPtr = _To_address(_OFirst); - const auto _OLastPtr = _To_address(_OLast); + const auto _IFirstPtr = _STD _To_address(_IFirst); + const auto _ILastPtr = _STD _To_address(_ILast); + const auto _OFirstPtr = _STD _To_address(_OFirst); + const auto _OLastPtr = _STD _To_address(_OLast); const auto _IFirst_ch = const_cast(reinterpret_cast(_IFirstPtr)); const auto _ILast_ch = const_cast(reinterpret_cast(_ILastPtr)); const auto _OFirst_ch = const_cast(reinterpret_cast(_OFirstPtr)); @@ -1783,12 +1783,14 @@ namespace ranges { if constexpr (_Iter_move_cat<_It, _Out>::_Bitcopy_constructible && _Sized_or_unreachable_sentinel_for<_Se, _It> && _Sized_or_unreachable_sentinel_for<_OSe, _Out>) { if constexpr (_Is_sized1 && _Is_sized2) { - return _Copy_memcpy_common(_IFirst, _RANGES next(_IFirst, _STD move(_ILast)), _OFirst, + return _RANGES _Copy_memcpy_common(_IFirst, _RANGES next(_IFirst, _STD move(_ILast)), _OFirst, _RANGES next(_OFirst, _STD move(_OLast))); } else if constexpr (_Is_sized1) { - return _Copy_memcpy_distance(_IFirst, _OFirst, _IFirst, _RANGES next(_IFirst, _STD move(_ILast))); + return _RANGES _Copy_memcpy_distance( + _IFirst, _OFirst, _IFirst, _RANGES next(_IFirst, _STD move(_ILast))); } else if constexpr (_Is_sized2) { - return _Copy_memcpy_distance(_IFirst, _OFirst, _OFirst, _RANGES next(_OFirst, _STD move(_OLast))); + return _RANGES _Copy_memcpy_distance( + _IFirst, _OFirst, _OFirst, _RANGES next(_OFirst, _STD move(_OLast))); } else { _STL_ASSERT(false, "Tried to uninitialized_move two ranges with unreachable sentinels"); } diff --git a/stl/inc/xutility b/stl/inc/xutility index 20cdaefd7e5..b8a1b6995ef 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -6978,22 +6978,22 @@ namespace ranges { _EXPORT_STD template _NODISCARD _CONSTEXPR20 _FwdIt lower_bound(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // find first element not before _Val - _Adl_verify_range(_First, _Last); - auto _UFirst = _Get_unwrapped(_First); - _Iter_diff_t<_FwdIt> _Count = _STD distance(_UFirst, _Get_unwrapped(_Last)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + _Iter_diff_t<_FwdIt> _Count = _STD distance(_UFirst, _STD _Get_unwrapped(_Last)); while (0 < _Count) { // divide and conquer, find half that contains answer const _Iter_diff_t<_FwdIt> _Count2 = _Count / 2; const auto _UMid = _STD next(_UFirst, _Count2); if (_Pred(*_UMid, _Val)) { // try top half - _UFirst = _Next_iter(_UMid); + _UFirst = _STD _Next_iter(_UMid); _Count -= _Count2 + 1; } else { _Count = _Count2; } } - _Seek_wrapped(_First, _UFirst); + _STD _Seek_wrapped(_First, _UFirst); return _First; } @@ -7006,9 +7006,9 @@ _NODISCARD _CONSTEXPR20 _FwdIt lower_bound(_FwdIt _First, _FwdIt _Last, const _T _EXPORT_STD template _NODISCARD _CONSTEXPR20 _FwdIt upper_bound(_FwdIt _First, _FwdIt _Last, const _Ty& _Val, _Pr _Pred) { // find first element that _Val is before - _Adl_verify_range(_First, _Last); - auto _UFirst = _Get_unwrapped(_First); - _Iter_diff_t<_FwdIt> _Count = _STD distance(_UFirst, _Get_unwrapped(_Last)); + _STD _Adl_verify_range(_First, _Last); + auto _UFirst = _STD _Get_unwrapped(_First); + _Iter_diff_t<_FwdIt> _Count = _STD distance(_UFirst, _STD _Get_unwrapped(_Last)); while (0 < _Count) { // divide and conquer, find half that contains answer _Iter_diff_t<_FwdIt> _Count2 = _Count / 2; @@ -7016,12 +7016,12 @@ _NODISCARD _CONSTEXPR20 _FwdIt upper_bound(_FwdIt _First, _FwdIt _Last, const _T if (_Pred(_Val, *_UMid)) { _Count = _Count2; } else { // try top half - _UFirst = _Next_iter(_UMid); + _UFirst = _STD _Next_iter(_UMid); _Count -= _Count2 + 1; } } - _Seek_wrapped(_First, _UFirst); + _STD _Seek_wrapped(_First, _UFirst); return _First; } diff --git a/tests/std/tests/GH_001596_adl_proof_algorithms/test.compile.pass.cpp b/tests/std/tests/GH_001596_adl_proof_algorithms/test.compile.pass.cpp index 248f6473289..12a478f4185 100644 --- a/tests/std/tests/GH_001596_adl_proof_algorithms/test.compile.pass.cpp +++ b/tests/std/tests/GH_001596_adl_proof_algorithms/test.compile.pass.cpp @@ -263,6 +263,48 @@ void test_algorithms() { // (void) std::shift_right(varr, varr, 0); // requires Cpp17ValueSwappable #endif // _HAS_CXX20 + int iarr3[1]{}; + validator varr3[1]{}; + + (void) std::merge(varr, varr, varr2, varr2, varr3); + (void) std::merge(iarr, iarr, iarr2, iarr2, iarr3, validating_less{}); + + // std::inplace_merge(varr, varr, varr); // requires Cpp17ValueSwappable + std::inplace_merge(iarr, iarr, iarr, validating_less{}); + + (void) std::includes(varr, varr, varr, varr); + (void) std::includes(iarr, iarr, iarr, iarr, validating_less{}); + + (void) std::set_union(varr, varr, varr, varr, varr3); + (void) std::set_union(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_intersection(varr, varr, varr, varr, varr3); + (void) std::set_intersection(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_difference(varr, varr, varr, varr, varr3); + (void) std::set_difference(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_symmetric_difference(varr, varr, varr, varr, varr3); + (void) std::set_symmetric_difference(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + std::push_heap(varr3, varr3 + 1); // requires Cpp17ValueSwappable + std::push_heap(iarr3, iarr3 + 1, validating_less{}); + + std::pop_heap(varr3, varr3 + 1); // requires Cpp17ValueSwappable + std::pop_heap(iarr3, iarr3 + 1, validating_less{}); + + std::make_heap(varr3, varr3 + 1); // requires Cpp17ValueSwappable + std::make_heap(iarr3, iarr3 + 1, validating_less{}); + + std::sort_heap(varr3, varr3 + 1); // requires Cpp17ValueSwappable + std::sort_heap(iarr3, iarr3 + 1, validating_less{}); + + (void) std::is_heap(varr3, varr3 + 1); + (void) std::is_heap(iarr3, iarr3 + 1, validating_less{}); + + (void) std::is_heap_until(varr3, varr3 + 1); + (void) std::is_heap_until(iarr3, iarr3 + 1, validating_less{}); + (void) std::min(+varr, +varr); (void) std::min(+iarr, +iarr, validating_less{}); (void) std::min({+varr, +varr}); @@ -299,6 +341,12 @@ void test_algorithms() { (void) std::lexicographical_compare_three_way(varr, varr, varr, varr); (void) std::lexicographical_compare_three_way(iarr, iarr, iarr, iarr, validating_compare_three_way{}); #endif // _HAS_CXX20 && defined(__cpp_lib_concepts) + + // (void) std::next_permutation(varr, varr); // requires Cpp17ValueSwappable + (void) std::next_permutation(iarr, iarr, validating_less{}); + + // (void) std::prev_permutation(varr, varr); // requires Cpp17ValueSwappable + (void) std::prev_permutation(iarr, iarr, validating_less{}); } #if _HAS_CXX17 @@ -431,6 +479,36 @@ void test_per_execution_policy() { // (void) std::shift_right(ExecutionPolicy, varr, varr, 0); // requires Cpp17ValueSwappable #endif // _HAS_CXX20 + int iarr3[2]{}; + validator varr3[2]{}; + + (void) std::merge(ExecutionPolicy, varr, varr, varr2, varr2, varr3); + (void) std::merge(ExecutionPolicy, iarr, iarr, iarr2, iarr2, iarr3, validating_less{}); + + // std::inplace_merge(ExecutionPolicy, varr, varr, varr); // requires Cpp17ValueSwappable + std::inplace_merge(ExecutionPolicy, iarr, iarr, iarr, validating_less{}); + + (void) std::includes(ExecutionPolicy, varr, varr, varr, varr); + (void) std::includes(ExecutionPolicy, iarr, iarr, iarr, iarr, validating_less{}); + + (void) std::set_union(ExecutionPolicy, varr, varr, varr, varr, varr3); + (void) std::set_union(ExecutionPolicy, iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_intersection(ExecutionPolicy, varr, varr, varr, varr, varr3); + (void) std::set_intersection(ExecutionPolicy, iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_difference(ExecutionPolicy, varr, varr, varr, varr, varr3); + (void) std::set_difference(ExecutionPolicy, iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::set_symmetric_difference(ExecutionPolicy, varr, varr, varr, varr, varr3); + (void) std::set_symmetric_difference(ExecutionPolicy, iarr, iarr, iarr, iarr, iarr3, validating_less{}); + + (void) std::is_heap(ExecutionPolicy, varr3, varr3 + 1); + (void) std::is_heap(ExecutionPolicy, iarr3, iarr3 + 1, validating_less{}); + + (void) std::is_heap_until(ExecutionPolicy, varr3, varr3 + 1); + (void) std::is_heap_until(ExecutionPolicy, iarr3, iarr3 + 1, validating_less{}); + (void) std::min_element(ExecutionPolicy, varr, varr + 1); (void) std::min_element(ExecutionPolicy, iarr, iarr + 1, validating_less{}); diff --git a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp index ccd04fec14e..c9ec1c4ae15 100644 --- a/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp +++ b/tests/std/tests/P2538R1_adl_proof_std_projected/test.compile.pass.cpp @@ -279,6 +279,74 @@ void test_ranges_algorithms() { (void) unique_copy(iarr, iarr, iarr2, {}, validating_identity{}); (void) unique_copy(iarr, iarr2, {}, validating_identity{}); + int iarr3[2]{}; + validator varr3[2]{}; + + (void) merge(varr, varr, varr2, varr2, varr3); + (void) merge(varr, varr2, varr3); + (void) merge(iarr, iarr, iarr2, iarr2, iarr3, validating_less{}); + (void) merge(iarr, iarr2, iarr3, validating_less{}); + + (void) inplace_merge(varr, varr, varr); + (void) inplace_merge(varr, varr); + (void) inplace_merge(iarr, iarr, iarr, validating_less{}); + (void) inplace_merge(iarr, iarr, {}, validating_identity{}); + + (void) includes(varr, varr, varr, varr); + (void) includes(varr, varr); + (void) includes(iarr, iarr, iarr, iarr, validating_less{}); + (void) includes(iarr, iarr, validating_less{}); + + (void) set_union(varr, varr, varr, varr, varr3); + (void) set_union(varr, varr, varr3); + (void) set_union(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + (void) set_union(iarr, iarr, iarr3, validating_less{}); + + (void) set_intersection(varr, varr, varr, varr, varr3); + (void) set_intersection(varr, varr, varr3); + (void) set_intersection(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + (void) set_intersection(iarr, iarr, iarr3, validating_less{}); + + (void) set_difference(varr, varr, varr, varr, varr3); + (void) set_difference(varr, varr, varr3); + (void) set_difference(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + (void) set_difference(iarr, iarr, iarr3, validating_less{}); + + (void) set_symmetric_difference(varr, varr, varr, varr, varr3); + (void) set_symmetric_difference(varr, varr, varr3); + (void) set_symmetric_difference(iarr, iarr, iarr, iarr, iarr3, validating_less{}); + (void) set_symmetric_difference(iarr, iarr, iarr3, validating_less{}); + + (void) push_heap(varr3, varr3 + 1); + (void) push_heap(varr3); + (void) push_heap(iarr3, iarr3 + 1, validating_less{}); + (void) push_heap(iarr3, {}, validating_identity{}); + + (void) pop_heap(varr3, varr3 + 1); + (void) pop_heap(varr3); + (void) pop_heap(iarr3, iarr3 + 1, validating_less{}); + (void) pop_heap(iarr3, {}, validating_identity{}); + + (void) make_heap(varr3, varr3 + 1); + (void) make_heap(varr3); + (void) make_heap(iarr3, iarr3 + 1, validating_less{}); + (void) make_heap(iarr3, {}, validating_identity{}); + + (void) sort_heap(varr3, varr3 + 1); + (void) sort_heap(varr3); + (void) sort_heap(iarr3, iarr3 + 1, validating_less{}); + (void) sort_heap(iarr3, {}, validating_identity{}); + + (void) is_heap(varr3, varr3 + 1); + (void) is_heap(varr3); + (void) is_heap(iarr3, iarr3 + 1, validating_less{}); + (void) is_heap(iarr3, {}, validating_identity{}); + + (void) is_heap_until(varr3, varr3 + 1); + (void) is_heap_until(varr3); + (void) is_heap_until(iarr3, iarr3 + 1, validating_less{}); + (void) is_heap_until(iarr3, {}, validating_identity{}); + (void) min(+varr, +varr); (void) min({+varr, +varr}); (void) min(varr); @@ -322,6 +390,16 @@ void test_ranges_algorithms() { (void) lexicographical_compare(varr, varr); (void) lexicographical_compare(iarr, iarr, iarr, iarr, validating_less{}); (void) lexicographical_compare(iarr, iarr, validating_less{}); + + (void) next_permutation(varr, varr); + (void) next_permutation(varr); + (void) next_permutation(iarr, iarr, validating_less{}); + (void) next_permutation(iarr, {}, validating_identity{}); + + (void) prev_permutation(varr, varr); + (void) prev_permutation(varr); + (void) prev_permutation(iarr, iarr, validating_less{}); + (void) prev_permutation(iarr, {}, validating_identity{}); } // Separated test for ranges::count and equality From 202e3820d6390505855ce9a58a4bcee4f28feacd Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 30 Jan 2024 12:55:19 -0800 Subject: [PATCH 20/20] llvm-project Mini-Update (#4348) --- llvm-project | 2 +- tests/libcxx/expected_results.txt | 108 +++++++++++++++++++--------- tools/scripts/check_libcxx_paths.py | 40 +++++++++++ 3 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 tools/scripts/check_libcxx_paths.py diff --git a/llvm-project b/llvm-project index 57f42a8765c..2e2b6b53f5f 160000 --- a/llvm-project +++ b/llvm-project @@ -1 +1 @@ -Subproject commit 57f42a8765cd3d878be4fb59ad44c85f8a7ca223 +Subproject commit 2e2b6b53f5f63179b52168ee156df7c76b90bc71 diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 248dd417440..4b413af66aa 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -22,10 +22,6 @@ std/time/time.syn/formatter.year_month_day_last.pass.cpp:1 FAIL std/time/time.syn/formatter.year_month_weekday.pass.cpp:0 FAIL std/time/time.syn/formatter.year_month_weekday.pass.cpp:1 FAIL -# LLVM-73849: [libc++][test] Streaming out floating-point sys_time and local_time is bogus -std/time/time.clock/time.clock.local/ostream.pass.cpp FAIL -std/time/time.clock/time.clock.system/ostream.pass.cpp FAIL - # LLVM-74221: [libc++][test] nasty_char_traits::move is incompatible with constexpr std/strings/basic.string/string.modifiers/string_append/initializer_list.pass.cpp:2 FAIL std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp:2 FAIL @@ -34,13 +30,8 @@ std/strings/basic.string/string.modifiers/string_assign/string.pass.cpp:2 FAIL std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp FAIL std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp FAIL -# LLVM-75611: [libc++] views::take behaves incorrectly for iota_view -std/ranges/range.adaptors/range.take/adaptor.pass.cpp FAIL - -# LLVM-78661: [libc++][test] Move format.functions ASCII tests to libcxx/test/libcxx -# These test libc++'s non-standard "ascii" mode. -std/utilities/format/format.functions/ascii.pass.cpp SKIPPED -std/utilities/format/format.functions/escaped_output.ascii.pass.cpp SKIPPED +# LLVM-79783: [libc++][test] array/size_and_alignment.compile.pass.cpp includes non-Standard <__type_traits/datasizeof.h> +std/containers/sequences/array/size_and_alignment.compile.pass.cpp FAIL # Non-Standard regex behavior. # "It seems likely that the test is still non-conforming due to how libc++ handles the 'w' character class." @@ -62,8 +53,6 @@ std/iterators/iterator.primitives/iterator.operations/prev.pass.cpp FAIL # The SKIPPED tests contain `XFAIL: msvc`, which is not well understood by the test harness. std/language.support/support.exception/except.nested/rethrow_if_nested.pass.cpp SKIPPED std/language.support/support.exception/propagation/current_exception.pass.cpp SKIPPED -std/language.support/support.exception/propagation/make_exception_ptr.pass.cpp FAIL -std/language.support/support.exception/propagation/rethrow_exception.pass.cpp FAIL # Testing nonstandard behavior std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp FAIL @@ -171,9 +160,6 @@ std/utilities/memory/specialized.algorithms/uninitialized.fill.n/ranges_uninitia std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move.pass.cpp FAIL std/utilities/memory/specialized.algorithms/uninitialized.move/ranges_uninitialized_move_n.pass.cpp FAIL -# libc++ doesn't implement LWG-3940 -std/utilities/expected/expected.void/observers/value.pass.cpp FAIL - # If any feature-test macro test is failing, this consolidated test will also fail. std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp FAIL @@ -229,7 +215,28 @@ std/strings/c.strings/cuchar.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/cmath.version.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/cstdlib.version.compile.pass.cpp FAIL +# P0543R3 Saturation Arithmetic +std/language.support/support.limits/support.limits.general/numeric.version.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/add_sat.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/add_sat.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/div_sat.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/div_sat.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/mul_sat.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/mul_sat.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/saturate_cast.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/saturate_cast.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/sub_sat.compile.pass.cpp FAIL +std/numerics/numeric.ops/numeric.ops.sat/sub_sat.pass.cpp FAIL + # P1759R6 Native Handles And File Streams +std/input.output/file.streams/fstreams/filebuf.members/native_handle.pass.cpp FAIL +std/input.output/file.streams/fstreams/filebuf/types.pass.cpp FAIL +std/input.output/file.streams/fstreams/fstream.members/native_handle.pass.cpp FAIL +std/input.output/file.streams/fstreams/fstream/types.pass.cpp FAIL +std/input.output/file.streams/fstreams/ifstream.members/native_handle.pass.cpp FAIL +std/input.output/file.streams/fstreams/ifstream/types.pass.cpp FAIL +std/input.output/file.streams/fstreams/ofstream.members/native_handle.pass.cpp FAIL +std/input.output/file.streams/fstreams/ofstream/types.pass.cpp FAIL std/language.support/support.limits/support.limits.general/fstream.version.compile.pass.cpp FAIL # P2255R2 "Type Traits To Detect References Binding To Temporaries" @@ -245,6 +252,7 @@ std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.format.pas std/containers/sequences/vector.bool/vector.bool.fmt/format.functions.vformat.pass.cpp FAIL std/containers/sequences/vector.bool/vector.bool.fmt/format.pass.cpp FAIL std/containers/sequences/vector.bool/vector.bool.fmt/parse.pass.cpp FAIL +std/input.output/iostream.format/print.fun/includes.compile.pass.cpp FAIL std/utilities/format/format.formattable/concept.formattable.compile.pass.cpp FAIL std/utilities/format/format.range/format.range.fmtdef/format.pass.cpp FAIL std/utilities/format/format.range/format.range.fmtdef/parse.pass.cpp FAIL @@ -289,6 +297,7 @@ std/language.support/support.limits/support.limits.general/optional.version.comp std/language.support/support.limits/support.limits.general/string_view.version.compile.pass.cpp FAIL # P2447R6 Constructing span From initializer_list +std/containers/views/views.span/span.cons/initializer_list.pass.cpp FAIL std/language.support/support.limits/support.limits.general/span.version.compile.pass.cpp FAIL # P2495R3 Interfacing stringstreams With string_view @@ -302,6 +311,11 @@ std/utilities/charconv/charconv.syn/to_chars_result.operator_bool.pass.cpp FAIL # P2587R3 Redefining to_string To Use to_chars std/language.support/support.limits/support.limits.general/string.version.compile.pass.cpp FAIL +# P2637R3 Member visit +std/utilities/variant/variant.visit.member/robust_against_adl.pass.cpp FAIL +std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp FAIL +std/utilities/variant/variant.visit.member/visit.pass.cpp FAIL + # P2697R1 Interfacing bitset With string_view std/language.support/support.limits/support.limits.general/bitset.version.compile.pass.cpp FAIL std/utilities/template.bitset/bitset.cons/string_view_ctor.pass.cpp FAIL @@ -313,6 +327,9 @@ std/language.support/support.limits/support.limits.general/ratio.version.compile std/language.support/support.limits/support.limits.general/tuple.version.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/utility.version.compile.pass.cpp FAIL +# P2821R5 span::at() +std/containers/views/views.span/span.elem/at.pass.cpp FAIL + # P2833R2 Freestanding Library: inout expected span std/language.support/support.limits/support.limits.general/expected.version.compile.pass.cpp FAIL std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp FAIL @@ -342,6 +359,7 @@ std/depr/depr.c.headers/stdlib_h.pass.cpp FAIL # LWG-2503 "multiline option should be added to syntax_option_type" std/re/re.const/re.matchflag/match_multiline.pass.cpp FAIL +std/re/re.const/re.matchflag/match_not_eol.pass.cpp FAIL # LWG-2532 "Satisfying a promise at thread exit" (Open) # WCFB02 implements the proposed resolution for this issue @@ -412,6 +430,11 @@ std/containers/views/mdspan/mdspan/ctor.dh_integers.pass.cpp:1 FAIL std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp:0 FAIL std/concepts/concepts.compare/concept.equalitycomparable/equality_comparable_with.compile.pass.cpp:1 FAIL +# DevCom-10439137 VSO-1869865: Discarded id-expression causes unnecessary reading +# Also: LLVM-79793 [libc++][test] Fix MSVC warning C4127 in array.cons/initialization.pass.cpp +std/containers/sequences/array/array.cons/initialization.pass.cpp:0 FAIL +std/containers/sequences/array/array.cons/initialization.pass.cpp:1 FAIL + # VSO-1923988: constexpr evaluation performs an assignment with a derived type when it should use a base type std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp:0 FAIL std/algorithms/alg.modifying.operations/alg.copy/copy_backward.pass.cpp:1 FAIL @@ -532,6 +555,10 @@ std/input.output/string.streams/stringbuf/stringbuf.members/view.pass.cpp FAIL std/input.output/syncstream/syncbuf/syncstream.syncbuf.cons/dtor.pass.cpp FAIL std/input.output/syncstream/syncbuf/syncstream.syncbuf.members/emit.pass.cpp FAIL +# GH-4316: : The width of output is miscalculated when formatting a floating-point number in the locale-specific form +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp FAIL +std/utilities/format/format.functions/locale-specific_form.pass.cpp FAIL + # *** VCRUNTIME BUGS *** # DevCom-10373274 VSO-1824997 "vcruntime nothrow array operator new falls back on the wrong function" @@ -631,9 +658,6 @@ std/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.c std/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp SKIPPED # Not analyzed, likely bogus tests. Various assertions, probably POSIX assumptions. -std/diagnostics/syserr/syserr.compare/eq_error_code_error_code.pass.cpp FAIL -std/diagnostics/syserr/syserr.errcat/syserr.errcat.derived/message.pass.cpp FAIL -std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp FAIL std/diagnostics/syserr/syserr.syserr/syserr.syserr.members/ctor_error_code_const_char_pointer.pass.cpp FAIL std/diagnostics/syserr/syserr.syserr/syserr.syserr.members/ctor_error_code_string.pass.cpp FAIL std/diagnostics/syserr/syserr.syserr/syserr.syserr.members/ctor_error_code.pass.cpp FAIL @@ -705,9 +729,6 @@ std/localization/locale.categories/category.numeric/locale.num.get/facet.num.get # This test is bogus according to the wording that was ultimately accepted for C++23. std/strings/basic.string/string.capacity/resize_and_overwrite.pass.cpp FAIL -# This test assumes that array is not const-default-constructible. -std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp FAIL - # contiguous_iterator requires to_address() which calls operator->(), but this bogus test uses an iterator that lacks operator->(). std/iterators/iterator.requirements/iterator.concepts/iterator.concept.random.access/contiguous_iterator.compile.pass.cpp FAIL @@ -966,9 +987,6 @@ std/algorithms/algorithms.results/min_max_result.pass.cpp:1 FAIL # Not analyzed. std/algorithms/robust_against_proxy_iterators_lifetime_bugs.pass.cpp FAIL -# Not analyzed. MSVC doesn't define __SIZE_WIDTH__. Clang does, but this is inspecting sizeof(deque) which is non-portable. -std/containers/sequences/deque/abi.compile.pass.cpp FAIL - # Not analyzed. Possible MSVC constexpr bug. # note: failure was caused by a read of a variable outside its lifetime std/containers/sequences/vector.bool/construct_iter_iter.pass.cpp:0 FAIL @@ -1027,9 +1045,6 @@ std/ranges/range.adaptors/range.lazy.split/range.lazy.split.inner/iter_swap.pass # Not analyzed. Checking whether packaged_task is constructible from an allocator and a packaged_task of a different type. std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp FAIL -# Not analyzed. MSVC emits truncation warnings, Clang fails a runtime assertion. -std/utilities/format/format.functions/locale-specific_form.pass.cpp FAIL - # Not analyzed. # MSVC warning C4305: 'specialization': truncation from 'const int' to 'bool' # Clang error: non-type template argument evaluates to -1, which cannot be narrowed to type 'bool' [-Wc++11-narrowing] @@ -1331,6 +1346,16 @@ std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pas std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp SKIPPED std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical.pass.cpp SKIPPED +# Not analyzed. +# MSVC error C2719: '_Fun_': formal parameter with requested alignment of 128 won't be aligned +# Clang error: unknown attribute 'no_unique_address' ignored [-Werror,-Wunknown-attributes] +std/ranges/ranges_robust_against_no_unique_address.pass.cpp FAIL + +# Not analyzed. Runtime assertion, we appear to be ignoring stream width. +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp FAIL +std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp FAIL + # *** XFAILs WHICH PASS *** # These tests contain `// XFAIL: msvc` comments, which accurately describe runtime failures for x86 and x64. @@ -1346,6 +1371,8 @@ std/input.output/filesystems/fs.op.funcs/fs.op.weakly_canonical/weakly_canonical # because we don't run :1 (ASAN) for ARM and ARM64. std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp:0 SKIPPED std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/ostream.pass.cpp:2 SKIPPED +std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp:0 SKIPPED +std/time/time.clock/time.clock.system/sys_date.ostream.pass.cpp:2 SKIPPED std/time/time.syn/formatter.day.pass.cpp:0 SKIPPED std/time/time.syn/formatter.day.pass.cpp:2 SKIPPED std/time/time.syn/formatter.month_day.pass.cpp:0 SKIPPED @@ -1367,10 +1394,12 @@ std/algorithms/alg.modifying.operations/alg.replace/ranges.replace.pass.cpp:9 SK std/algorithms/alg.nonmodifying/alg.equal/equal.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/find.pass.cpp:9 SKIPPED std/algorithms/alg.nonmodifying/alg.find/ranges.find.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.fold/left_folds.pass.cpp:9 SKIPPED std/depr/depr.c.headers/setjmp_h.compile.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ifstream.members/buffered_reads.pass.cpp:9 SKIPPED std/input.output/file.streams/fstreams/ofstream.members/buffered_writes.pass.cpp:9 SKIPPED std/language.support/support.runtime/csetjmp.pass.cpp:9 SKIPPED +std/numerics/numeric.ops/numeric.ops.midpoint/midpoint.pointer.pass.cpp:9 SKIPPED std/ranges/range.adaptors/range.lazy.split/constraints.compile.pass.cpp:9 SKIPPED std/ranges/range.utility/range.utility.conv/to.pass.cpp:9 SKIPPED std/thread/thread.jthread/assign.move.pass.cpp:9 SKIPPED @@ -1394,8 +1423,23 @@ std/input.output/string.streams/stringstream/stringstream.members/gcount.pass.cp # Similarly, this test is marked as `REQUIRES: 32-bit-pointer`. std/iterators/iterator.container/ssize.LWG3207.compile.pass.cpp:9 SKIPPED -# LLVM-75577 [libc++][test] support.limits.general/.version.compile.pass.cpp is malformed -std/language.support/support.limits/support.limits.general/.version.compile.pass.cpp:9 SKIPPED - -# x86chk ICE not yet reported. Assertion failed: isIndirection() +# VSO-1948221 x86chk ICE with constexpr type_info: Assertion failed: isIndirection() std/language.support/support.rtti/type.info/type_info.equal.pass.cpp:9 SKIPPED + +# These tests are marked as "UNSUPPORTED: !has-unix-headers" with comments saying: +# "`check_assertion.h` requires Unix headers". +std/algorithms/alg.modifying.operations/alg.fill/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.modifying.operations/alg.move/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.modifying.operations/alg.replace/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.modifying.operations/alg.rotate/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.modifying.operations/alg.transform/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.all_of/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.any_of/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.equal/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.find/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.foreach/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.nonmodifying/alg.none_of/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.sorting/alg.merge/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/alg.sorting/alg.sort/stable.sort/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/numeric.ops/reduce/pstl.exception_handling.pass.cpp:9 SKIPPED +std/algorithms/numeric.ops/transform.reduce/pstl.exception_handling.pass.cpp:9 SKIPPED diff --git a/tools/scripts/check_libcxx_paths.py b/tools/scripts/check_libcxx_paths.py new file mode 100644 index 00000000000..93a4f34b351 --- /dev/null +++ b/tools/scripts/check_libcxx_paths.py @@ -0,0 +1,40 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# This script checks tests/libcxx/expected_results.txt for nonexistent test paths. + +from pathlib import Path +import re +import sys + +if __name__ == "__main__": + if len(sys.argv) != 1: + sys.exit(f"Usage: python {sys.argv[0]}") + + # Use the location of this script to find the base of the repo. + absolute_repo_path = Path(sys.argv[0]).absolute().parents[2] + + # Tests can be mentioned multiple times for different configurations. + # Build up a unique set before checking for existence. + unique_tests = set() + + with open(absolute_repo_path / "tests/libcxx/expected_results.txt") as file: + for line in map(lambda x: x.strip(), file): + if line and not line.startswith("#"): # Ignore empty lines and comments. + unique_tests.add(re.sub(r"(:\d+)? (FAIL|SKIPPED)$", "", line)) + + # Build up a list of nonexistent tests so they can be printed in sorted order. + nonexistent_tests = [] + + for str in unique_tests: + if not (absolute_repo_path / "llvm-project/libcxx/test" / str).is_file(): + nonexistent_tests.append(str) + + if nonexistent_tests: + print(f"Failure, found {len(nonexistent_tests)} nonexistent test paths:") + nonexistent_tests.sort() + for str in nonexistent_tests: + print(f"{str}") + sys.exit(1) + + print("Success, all test paths exist.")