From 6fb835e6f64894201f8810b461327019b1737f90 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 2 May 2025 00:49:40 +0800 Subject: [PATCH] Workaround for CWG-2369 in deduction guides Also make `_Valid_compare_for_container` stricter per [container.adaptors.general]/6.2. --- stl/inc/flat_map | 25 +++++++++++++++++-------- tests/libcxx/expected_results.txt | 8 ++++---- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 4f417832f4d..ec993207511 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -29,8 +29,9 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN template -concept _Valid_compare_for_container = is_invocable_v; +concept _Valid_compare_for_container = _Not_allocator_for_container<_Compare> + && is_invocable_v; template struct _Flat_map_value_compare_provider { @@ -1378,8 +1379,9 @@ flat_map(sorted_unique_t, _InputIterator, _InputIterator, _Compare = _Compare()) -> flat_map<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; #ifdef __cpp_lib_byte +// TRANSITION, CWG-2369, should just use constrained template parameters. template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare = less<_Range_key_type<_Rng>>, - _Allocator_for_container _Allocator = allocator> + class _Allocator = allocator, enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_map(from_range_t, _Rng&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, @@ -1389,13 +1391,16 @@ template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare = less flat_map(from_range_t, _Rng&&, _Compare = _Compare()) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; -template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare, _Allocator_for_container _Allocator> +// TRANSITION, CWG-2369, should just use constrained template parameters. +template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare, class _Allocator, + enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_map(from_range_t, _Rng&&, _Compare, _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #endif // ^^^ !defined(__cpp_lib_byte) ^^^ -template <_RANGES input_range _Rng, _Allocator_for_container _Allocator> +// TRANSITION, CWG-2369, should just use constrained template parameters. +template <_RANGES input_range _Rng, class _Allocator, enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_map(from_range_t, _Rng&&, _Allocator) -> flat_map<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; @@ -1543,8 +1548,9 @@ flat_multimap(sorted_equivalent_t, _InputIterator, _InputIterator, _Compare = _C -> flat_multimap<_Guide_key_t<_InputIterator>, _Guide_val_t<_InputIterator>, _Compare>; #ifdef __cpp_lib_byte +// TRANSITION, CWG-2369, should just use constrained template parameters. template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare = less<_Range_key_type<_Rng>>, - _Allocator_for_container _Allocator = allocator> + class _Allocator = allocator, enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_multimap(from_range_t, _Rng&&, _Compare = _Compare(), _Allocator = _Allocator()) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, @@ -1554,14 +1560,17 @@ template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare = less flat_multimap(from_range_t, _Rng&&, _Compare = _Compare()) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>>, vector<_Range_mapped_type<_Rng>>>; -template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare, _Allocator_for_container _Allocator> +// TRANSITION, CWG-2369, should just use constrained template parameters. +template <_RANGES input_range _Rng, _Not_allocator_for_container _Compare, class _Allocator, + enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_multimap(from_range_t, _Rng&&, _Compare, _Allocator) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, _Compare, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; #endif // ^^^ !defined(__cpp_lib_byte) ^^^ -template <_RANGES input_range _Rng, _Allocator_for_container _Allocator> +// TRANSITION, CWG-2369, should just use constrained template parameters. +template <_RANGES input_range _Rng, class _Allocator, enable_if_t<_Allocator_for_container<_Allocator>, int> = 0> flat_multimap(from_range_t, _Rng&&, _Allocator) -> flat_multimap<_Range_key_type<_Rng>, _Range_mapped_type<_Rng>, less<_Range_key_type<_Rng>>, vector<_Range_key_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_key_type<_Rng>>>, vector<_Range_mapped_type<_Rng>, _Rebind_alloc_t<_Allocator, _Range_mapped_type<_Rng>>>>; diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 53cbe6b72d7..c8647ca92b3 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -232,10 +232,6 @@ std/strings/c.strings/cuchar.compile.pass.cpp FAIL # P0429R9 -# FIXME! error: no type named 'value_type' in 'std::greater' -std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp FAIL -std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp FAIL - # FIXME! Assertion failed: m.keys().size() == m.values().size() # [flat.map.defn] doesn't declare a move constructor, which seems to imply that moving from a flat_map should behave # as if the move constructor were implicitly defined, i.e. it can't restore the invariants @@ -259,6 +255,8 @@ std/containers/container.adaptors/flat.multimap/flat.multimap.cons/move.pass.cpp # FIXME! warning C4242: 'initializing': conversion from '_Ty' to '_Ty2', possible loss of data std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp:0 FAIL std/containers/container.adaptors/flat.map/flat.map.cons/copy_assign.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.map/flat.map.cons/deduct.pass.cpp:1 FAIL std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp:0 FAIL std/containers/container.adaptors/flat.map/flat.map.cons/deduct_pmr.pass.cpp:1 FAIL std/containers/container.adaptors/flat.map/flat.map.cons/initializer_list.pass.cpp:0 FAIL @@ -283,6 +281,8 @@ std/containers/container.adaptors/flat.multimap/flat.multimap.cons/containers.pa std/containers/container.adaptors/flat.multimap/flat.multimap.cons/containers.pass.cpp:1 FAIL std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp:0 FAIL std/containers/container.adaptors/flat.multimap/flat.multimap.cons/copy_assign.pass.cpp:1 FAIL +std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp:0 FAIL +std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct.pass.cpp:1 FAIL std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp:0 FAIL std/containers/container.adaptors/flat.multimap/flat.multimap.cons/deduct_pmr.pass.cpp:1 FAIL std/containers/container.adaptors/flat.multimap/flat.multimap.cons/initializer_list.pass.cpp:0 FAIL