diff options
7 files changed, 158 insertions, 14 deletions
diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index c9687c2..13bfbb3 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -41,6 +41,10 @@ #include <bits/max_size_type.h> #include <bits/version.h> +#if __glibcxx_ranges_to_container // C++ >= 23 +# include <bits/utility.h> // for tuple_element_t +#endif + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" // __int128 @@ -1093,13 +1097,15 @@ namespace __detail = ranges::input_range<_Rg> && convertible_to<ranges::range_reference_t<_Rg>, _Tp>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4223. Deduction guides for maps are mishandling tuples and references template<ranges::input_range _Range> using __range_key_type - = remove_const_t<typename ranges::range_value_t<_Range>::first_type>; + = remove_const_t<tuple_element_t<0, ranges::range_value_t<_Range>>>; template<ranges::input_range _Range> using __range_mapped_type - = typename ranges::range_value_t<_Range>::second_type; + = tuple_element_t<1, ranges::range_value_t<_Range>>; // The allocator's value_type for map-like containers. template<ranges::input_range _Range> diff --git a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc index 00254dc..d9d88c4 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_map/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_map/1.cc @@ -11,6 +11,67 @@ #include <vector> #include <testsuite_allocator.h> #include <testsuite_hooks.h> +#include <testsuite_iterators.h> +#include <tuple> + +struct Gt { + template<typename T, typename U> + bool operator()(T const& l, U const & r) const + { return l > r; } +}; + +void +test_deduction_guide() +{ + __gnu_test::test_input_range<std::pair<long, float>> r(0, 0); + std::flat_map it1(r.begin(), r.begin()); + static_assert(std::is_same_v<decltype(it1), std::flat_map<long, float>>); + std::flat_map fr1(std::from_range, r); + static_assert(std::is_same_v<decltype(fr1), std::flat_map<long, float>>); + + Gt cmp; + std::flat_map it2(r.begin(), r.begin(), cmp); + static_assert(std::is_same_v<decltype(it2), std::flat_map<long, float, Gt>>); + std::flat_map fr2(std::from_range, r, cmp); + static_assert(std::is_same_v<decltype(fr2), std::flat_map<long, float, Gt>>); + + using Alloc = __gnu_test::SimpleAllocator<std::pair<const long, float>>; + Alloc alloc; + // No matching deduction guide + // std::flat_map it3(r.begin(), r.begin(), alloc); + std::flat_map fr3(std::from_range, r, alloc); + static_assert(std::is_same_v< + decltype(fr3), + std::flat_map<long, float, std::less<long>, + std::vector<long, __gnu_test::SimpleAllocator<long>>, + std::vector<float, __gnu_test::SimpleAllocator<float>>>>); + + // No matching deduction guide + // std::flat_map it4(r.begin(), r.begin(), cmp, alloc); + std::flat_map fr4(std::from_range, r, cmp, alloc); + static_assert(std::is_same_v< + decltype(fr4), + std::flat_map<long, float, Gt, + std::vector<long, __gnu_test::SimpleAllocator<long>>, + std::vector<float, __gnu_test::SimpleAllocator<float>>>>); + + // LWG4223: deduces flat_map<long, float const>, which in turn instantiates + // std::vector<cosnt float> that is ill-formed. + // __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0); + // std::flat_map it5(r2.begin(), r2.begin()); + // std::flat_map fr5(std::from_range, r2); + + // LWG4223: deduces flat_map<const long&, float&> + //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); + // std::flat_map it6(r3.begin(), r3.begin()); + // std::flat_map fr6(std::from_range, r3); + + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::flat_map it7(r4.begin(), r4.begin()); + static_assert(std::is_same_v<decltype(it7), std::flat_map<long, float>>); + std::flat_map fr7(std::from_range, r4); + static_assert(std::is_same_v<decltype(fr7), std::flat_map<long, float>>); +} template<template<typename> class KeyContainer, template<typename> class MappedContainer> void diff --git a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc index 38650a8..ff180bf 100644 --- a/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc +++ b/libstdc++-v3/testsuite/23_containers/flat_multimap/1.cc @@ -5,6 +5,71 @@ #include <vector> #include <testsuite_allocator.h> #include <testsuite_hooks.h> +#include <testsuite_iterators.h> +#include <tuple> + +struct Gt { + template<typename T, typename U> + bool operator()(T const& l, U const & r) const + { return l > r; } +}; + +void +test_deduction_guide() +{ + __gnu_test::test_input_range<std::pair<long, float>> r(0, 0); + std::flat_multimap it1(r.begin(), r.begin()); + static_assert(std::is_same_v<decltype(it1), std::flat_multimap<long, float>>); + std::flat_multimap fr1(std::from_range, r); + static_assert(std::is_same_v<decltype(fr1), std::flat_multimap<long, float>>); + + Gt cmp; + std::flat_multimap it2(r.begin(), r.begin(), cmp); + static_assert(std::is_same_v< + decltype(it2), + std::flat_multimap<long, float, Gt>>); + std::flat_multimap fr2(std::from_range, r, cmp); + static_assert(std::is_same_v< + decltype(fr2), + std::flat_multimap<long, float, Gt>>); + + using Alloc = __gnu_test::SimpleAllocator<std::pair<const long, float>>; + Alloc alloc; + // No matching deduction guide + // std::flat_multimap it3(r.begin(), r.begin(), alloc); + std::flat_multimap fr3(std::from_range, r, alloc); + static_assert(std::is_same_v< + decltype(fr3), + std::flat_multimap<long, float, std::less<long>, + std::vector<long, __gnu_test::SimpleAllocator<long>>, + std::vector<float, __gnu_test::SimpleAllocator<float>>>>); + + // No matching deduction guide + // std::flat_multimap it4(r.begin(), r.begin(), cmp, alloc); + std::flat_multimap fr4(std::from_range, r, cmp, alloc); + static_assert(std::is_same_v< + decltype(fr4), + std::flat_multimap<long, float, Gt, + std::vector<long, __gnu_test::SimpleAllocator<long>>, + std::vector<float, __gnu_test::SimpleAllocator<float>>>>); + + // LWG4223: deduces flat_multimap<long, float const>, which in turn instantiates + // std::vector<cosnt float> that is ill-formed. + // __gnu_test::test_input_range<std::pair<const long, const float>> r2(0, 0); + // std::flat_multimap it5(r2.begin(), r2.begin()); + // std::flat_multimap fr5(std::from_range, r2); + + // LWG4223: deduces flat_multimap<const long&, float&> + //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); + // std::flat_multimap it6(r3.begin(), r3.begin()); + // std::flat_multimap fr6(std::from_range, r3); + + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::flat_multimap it7(r4.begin(), r4.begin()); + static_assert(std::is_same_v<decltype(it7), std::flat_multimap<long, float>>); + std::flat_multimap fr7(std::from_range, r4); + static_assert(std::is_same_v<decltype(fr7), std::flat_multimap<long, float>>); +} template<template<typename> class KeyContainer, template<typename> class MappedContainer> void diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/map/cons/from_range.cc index 01e426f..c740471 100644 --- a/libstdc++-v3/testsuite/23_containers/map/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/map/cons/from_range.cc @@ -44,9 +44,11 @@ test_deduction_guide() //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); // std::map m6(std::from_range, r3); - // LWG4223: no deduction guide - // __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); - // std::map m7(std::from_range, r4); + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::map m7(std::from_range, r4); + static_assert(std::is_same_v<decltype(m7), std::map<long, float>>); + std::map it7(r4.begin(), r4.begin()); + static_assert(std::is_same_v<decltype(it7), std::map<long, float>>); } template<typename T, typename U> diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/from_range.cc index e0052e4..3e456f5 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/cons/from_range.cc @@ -44,9 +44,11 @@ test_deduction_guide() //__gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); // std::multimap m6(std::from_range, r3); - // LWG4223: no deduction guide - // __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); - // std::multimap m7(std::from_range, r4); + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::multimap m7(std::from_range, r4); + static_assert(std::is_same_v<decltype(m7), std::multimap<long, float>>); + std::multimap it7(r4.begin(), r4.begin()); + static_assert(std::is_same_v<decltype(it7), std::multimap<long, float>>); } template<typename T, typename U> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/from_range.cc index 51f8538..6d1da5b 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/from_range.cc @@ -81,9 +81,11 @@ test_deduction_guide() // __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); // std::unordered_map m10(std::from_range, r3); - // LWG4223: no deduction guide - // __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); - // std::unordered_map m11(std::from_range, r4); + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::unordered_map m11(std::from_range, r4); + static_assert(std::is_same_v<decltype(m11), std::unordered_map<long, float>>); + std::unordered_map it11(r4.begin(), r4.begin()); + static_assert(std::is_same_v<decltype(it11), std::unordered_map<long, float>>); } template<typename T, typename U> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/from_range.cc index 1baf730..2ca93d3 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/from_range.cc @@ -87,9 +87,15 @@ test_deduction_guide() // __gnu_test::test_input_range<std::pair<const long&, float&>> r3(0, 0); // std::unordered_multimap m10(std::from_range, r3); - // LWG4223: no deduction guide - // __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); - // std::unordered_multimap m11(std::from_range, r4); + __gnu_test::test_input_range<std::tuple<long, float>> r4(0, 0); + std::unordered_multimap m11(std::from_range, r4); + static_assert(std::is_same_v< + decltype(m11), + std::unordered_multimap<long, float>>); + std::unordered_multimap it11(r4.begin(), r4.begin()); + static_assert(std::is_same_v< + decltype(it11), + std::unordered_multimap<long, float>>); } template<typename T, typename U> |