diff --git a/stl/inc/xmemory b/stl/inc/xmemory index 1640e5dc614..54bdc1445d1 100644 --- a/stl/inc/xmemory +++ b/stl/inc/xmemory @@ -2681,14 +2681,13 @@ concept _Container_compatible_range = (_RANGES input_range<_Rng>) && convertible_to<_RANGES range_reference_t<_Rng>, _Elem>; template <_RANGES input_range _Rng> -using _Range_key_type = remove_const_t::first_type>; +using _Range_key_type = remove_cvref_t>>; template <_RANGES input_range _Rng> -using _Range_mapped_type = _RANGES range_value_t<_Rng>::second_type; +using _Range_mapped_type = remove_cvref_t>>; template <_RANGES input_range _Rng> -using _Range_to_alloc_type = - pair::first_type, typename _RANGES range_value_t<_Rng>::second_type>; +using _Range_to_alloc_type = pair, _Range_mapped_type<_Rng>>; #endif // _HAS_CXX23 template using _Guide_key_t = #if _HAS_CXX23 - remove_const_t::value_type>>; + remove_cvref_t::value_type>>; #else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv - remove_const_t::value_type::first_type>; + _Remove_cvref_t::value_type::first_type>; #endif // ^^^ !_HAS_CXX23 ^^^ template using _Guide_val_t = #if _HAS_CXX23 - tuple_element_t<1, typename iterator_traits<_Iter>::value_type>; + remove_cvref_t::value_type>>; #else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv - typename iterator_traits<_Iter>::value_type::second_type; + _Remove_cvref_t::value_type::second_type>; #endif // ^^^ !_HAS_CXX23 ^^^ template -using _Guide_pair_t = -#if _HAS_CXX23 - pair::value_type>>, - tuple_element_t<1, typename iterator_traits<_Iter>::value_type>>; -#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv - pair::value_type::first_type>, - typename iterator_traits<_Iter>::value_type::second_type>; -#endif // ^^^ !_HAS_CXX23 ^^^ +using _Guide_pair_t = pair, _Guide_val_t<_Iter>>; _EXPORT_STD template struct _NO_SPECIALIZATIONS_CITING("N5014 [execpol.type]/3") is_execution_policy : false_type {}; diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index ca4a2989ef7..60d81c88af1 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -155,14 +155,11 @@ class MyAllocator { template struct almost_pair { - using first_type = T; - using second_type = U; + T first_; // to test LWG-4223, this member name is not `first` to avoid accidental relying + U second_; // to test LWG-4223, this member name is not `second` to avoid accidental relying - T first; - U second; - - constexpr operator pair() const { - return {first, second}; + constexpr operator pair, remove_cvref_t>() const { + return {first_, second_}; } }; @@ -502,6 +499,33 @@ void test_construction() { assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); } + + almost_pair alter_pairs[]{ + {value_types[0].first_, value_types[0].second_}, + {value_types[1].first_, value_types[1].second_}, + {value_types[2].first_, value_types[2].second_}, + {value_types[3].first_, value_types[3].second_}, + {value_types[4].first_, value_types[4].second_}, + {value_types[5].first_, value_types[5].second_}, + }; + + // Test LWG-4223 + { + flat_map fmap{ranges::begin(alter_pairs), ranges::end(alter_pairs)}; + flat_map fmap1{ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}}; + + assert(check_key_content(fmap, {0, 1, 2, 3, 4})); + assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); + assert(fmap == fmap1); + } + { + flat_multimap fmmap{ranges::begin(alter_pairs), ranges::end(alter_pairs)}; + flat_multimap fmmap1{ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}}; + + assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); + assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); + assert(fmmap == fmmap1); + } } { // Test flat_map(iter, iter, const key_comp&, const alloc&) @@ -531,6 +555,41 @@ void test_construction() { assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); } + + almost_pair alter_pairs[]{ + {value_types[0].first_, value_types[0].second_}, + {value_types[1].first_, value_types[1].second_}, + {value_types[2].first_, value_types[2].second_}, + {value_types[3].first_, value_types[3].second_}, + {value_types[4].first_, value_types[4].second_}, + {value_types[5].first_, value_types[5].second_}, + }; + + // Test LWG-4223 + { + MyAllocatorCounter allocation_counter; + flat_map_my_allocator fmap{ranges::begin(alter_pairs), ranges::end(alter_pairs), MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + flat_map_my_allocator fmap1{ + ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + + assert(check_key_content(fmap, {0, 1, 2, 3, 4})); + assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); + assert(fmap == fmap1); + } + { + MyAllocatorCounter allocation_counter; + flat_multimap_my_allocator fmmap{ranges::begin(alter_pairs), ranges::end(alter_pairs), MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + flat_multimap_my_allocator fmmap1{ + ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + + assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); + assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); + assert(fmmap == fmmap1); + } } { // Test flat_map(from_range_t, _Rng &&, const key_compare&) @@ -553,6 +612,33 @@ void test_construction() { assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); } + + almost_pair alter_pairs[]{ + {value_types[0].first_, move(value_types[0].second_)}, + {value_types[1].first_, move(value_types[1].second_)}, + {value_types[2].first_, move(value_types[2].second_)}, + {value_types[3].first_, move(value_types[3].second_)}, + {value_types[4].first_, move(value_types[4].second_)}, + {value_types[5].first_, move(value_types[5].second_)}, + }; + + // Test LWG-4223 + { + flat_map fmap{from_range, alter_pairs}; + flat_map fmap1{from_range, alter_pairs, less{}}; + + assert(check_key_content(fmap, {0, 1, 2, 3, 4})); + assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); + assert(fmap == fmap1); + } + { + flat_multimap fmmap{from_range, alter_pairs}; + flat_multimap fmmap1{from_range, alter_pairs, less{}}; + + assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); + assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); + assert(fmmap == fmmap1); + } } { // Test flat_map(from_range_t, _Rng &&, const key_compare&, const alloc&) @@ -582,6 +668,39 @@ void test_construction() { assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); } + + almost_pair alter_pairs[]{ + {move(value_types[0].first_), value_types[0].second_}, + {move(value_types[1].first_), value_types[1].second_}, + {move(value_types[2].first_), value_types[2].second_}, + {move(value_types[3].first_), value_types[3].second_}, + {move(value_types[4].first_), value_types[4].second_}, + {move(value_types[5].first_), value_types[5].second_}, + }; + + // Test LWG-4223 + { + MyAllocatorCounter allocation_counter; + flat_map fmap{from_range, alter_pairs, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + flat_map fmap1{from_range, alter_pairs, less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + + assert(check_key_content(fmap, {0, 1, 2, 3, 4})); + assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); + assert(fmap == fmap1); + } + { + MyAllocatorCounter allocation_counter; + flat_multimap fmmap{from_range, alter_pairs, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + flat_multimap fmmap1{from_range, alter_pairs, less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + + assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); + assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); + assert(fmmap == fmmap1); + } } { // Test flat_map(_Sorted_t, iter, iter, comp = key_comp()) @@ -594,6 +713,17 @@ void test_construction() { assert(check_key_content(fmap, {0, 1, 2, 3, 4})); assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); assert(fmap == fmap1); + + almost_pair alter_pairs[]{ + {move(value_types[0].first_), value_types[0].second_}, + {move(value_types[1].first_), value_types[1].second_}, + {move(value_types[2].first_), value_types[2].second_}, + {move(value_types[3].first_), value_types[3].second_}, + {move(value_types[4].first_), value_types[4].second_}, + }; + // Test LWG-4223 + flat_map fmap2{sorted_unique, ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}}; + assert(fmap2 == fmap); } { almost_pair value_types[]{{0, 44}, {1, 2324}, {2, 635462}, {2, 7}, {3, 433}, {4, 5}}; @@ -604,6 +734,18 @@ void test_construction() { assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); + + almost_pair alter_pairs[]{ + {move(value_types[0].first_), move(value_types[0].second_)}, + {move(value_types[1].first_), move(value_types[1].second_)}, + {move(value_types[2].first_), move(value_types[2].second_)}, + {move(value_types[3].first_), move(value_types[3].second_)}, + {move(value_types[4].first_), move(value_types[4].second_)}, + {move(value_types[5].first_), move(value_types[5].second_)}, + }; + // Test LWG-4223 + flat_multimap fmmap2{sorted_equivalent, ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}}; + assert(fmmap2 == fmmap); } } { @@ -623,6 +765,19 @@ void test_construction() { assert(check_key_content(fmap, {0, 1, 2, 3, 4})); assert(check_value_content(fmap, {44, 2324, 635462, 433, 5})); assert(fmap == fmap1); + + almost_pair alter_pairs[]{ + {move(value_types[0].first_), value_types[0].second_}, + {move(value_types[1].first_), value_types[1].second_}, + {move(value_types[2].first_), value_types[2].second_}, + {move(value_types[3].first_), value_types[3].second_}, + {move(value_types[4].first_), value_types[4].second_}, + }; + // Test LWG-4223 + flat_map_my_allocator fmap2{ + sorted_unique, ranges::begin(alter_pairs), ranges::end(alter_pairs), less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + assert(fmap == fmap2); } { almost_pair value_types[]{{0, 44}, {1, 2324}, {2, 635462}, {2, 7}, {3, 433}, {4, 5}}; @@ -638,6 +793,20 @@ void test_construction() { assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); assert(check_value_content(fmmap, {44, 2324, 635462, 7, 433, 5})); assert(fmmap == fmmap1); + + almost_pair alter_pairs[]{ + {move(value_types[0].first_), move(value_types[0].second_)}, + {move(value_types[1].first_), move(value_types[1].second_)}, + {move(value_types[2].first_), move(value_types[2].second_)}, + {move(value_types[3].first_), move(value_types[3].second_)}, + {move(value_types[4].first_), move(value_types[4].second_)}, + {move(value_types[5].first_), move(value_types[5].second_)}, + }; + // Test LWG-4223 + flat_multimap_my_allocator fmmap2{sorted_equivalent, ranges::begin(alter_pairs), ranges::end(alter_pairs), + less{}, MyAllocator{}}; + assert(allocation_counter.check_then_reset()); + assert(fmmap == fmmap2); } } { diff --git a/tests/std/tests/P0433R2_deduction_guides/test.cpp b/tests/std/tests/P0433R2_deduction_guides/test.cpp index 7b9cf044006..7d2ff24dc79 100644 --- a/tests/std/tests/P0433R2_deduction_guides/test.cpp +++ b/tests/std/tests/P0433R2_deduction_guides/test.cpp @@ -637,6 +637,22 @@ void test_map_or_multimap() { static_assert(is_same_v>>); static_assert(is_same_v, MyAlloc>>); + using PairIter = pair*; + static_assert(is_same_v>); + + using PairIter2 = pair*; + static_assert(is_same_v>); + + // Verify fixes from LWG-4223 + using PairIter3 = pair*; + static_assert(is_same_v>); + + using PairIter4 = pair*; + static_assert(is_same_v>); + + using PairIter5 = pair*; + static_assert(is_same_v>); + #if _HAS_CXX23 M m14(from_range, first); M m15(from_range, first, gt); @@ -648,19 +664,43 @@ void test_map_or_multimap() { static_assert(is_same_v>>); static_assert(is_same_v, MyAlloc>>); - { // Verify changes from P2165R4 - using TupleIter = tuple*; - static_assert(is_same_v>); + // Verify fixes from LWG-4223 + static_assert(is_same_v*>{}}), M>); + static_assert(is_same_v*>{}, gt}), + M>); + static_assert(is_same_v*>{}, gt, myal}), + M>>); + static_assert(is_same_v*>{}}), M>); + static_assert(is_same_v*>{}, gt}), + M>); + static_assert(is_same_v*>{}, gt, myal}), + M>>); - using PairIter = pair*; - static_assert(is_same_v>); + static_assert(is_same_v*>{}}), M>); + static_assert(is_same_v*>{}, gt}), + M>); - using ArrayIter = array*; - static_assert(is_same_v>); + // Verify changes from P2165R4 as fixed by LWG-4223 + using TupleIter = tuple*; + static_assert(is_same_v>); - using SubrangeIter = ranges::subrange*; - static_assert(is_same_v>); - } + using TupleIter2 = tuple*; + static_assert(is_same_v>); + + using TupleIter3 = tuple*; + static_assert(is_same_v>); + + using TupleIter4 = tuple*; + static_assert(is_same_v>); + + using TupleIter5 = tuple*; + static_assert(is_same_v>); + + using ArrayIter = array*; + static_assert(is_same_v>); + + using SubrangeIter = ranges::subrange*; + static_assert(is_same_v>); #endif // _HAS_CXX23 } @@ -755,6 +795,16 @@ void test_unordered_map_or_unordered_multimap() { static_assert(is_same_v, equal_to, MyAlloc>>); static_assert(is_same_v, MyAlloc>>); + // Verify fixes from LWG-4223 + using PairIter1 = pair*; + static_assert(is_same_v>); + + using PairIter2 = pair*; + static_assert(is_same_v>); + + using PairIter3 = pair*; + static_assert(is_same_v>); + #if _HAS_CXX23 UM um26(from_range, first); UM um27(from_range, first, 7); @@ -773,6 +823,28 @@ void test_unordered_map_or_unordered_multimap() { static_assert(is_same_v, equal_to, MyAlloc>>); static_assert(is_same_v, equal_to, MyAlloc>>); static_assert(is_same_v, MyAlloc>>); + + // Verify fixes from LWG-4223 + using TupleIter1 = tuple*; + static_assert(is_same_v>); + static_assert(is_same_v{}}), UM>); + + using TupleIter2 = tuple*; + static_assert(is_same_v>); + static_assert(is_same_v{}, 42, hf}), UM>); + + using TupleIter3 = tuple*; + static_assert(is_same_v>); + static_assert(is_same_v{}, 42, hf, eq}), + UM>); + + using ArrayIter = const array*; + static_assert(is_same_v>); + static_assert(is_same_v{}}), UM>); + + using SubrangeIter = ranges::subrange*; + static_assert(is_same_v>); + static_assert(is_same_v{}}), UM>); #endif // _HAS_CXX23 }