This patch implements LWG2713 by adding missing allocator aware version of unordered associative containers constructors accepting only "range" (pair of iterators, initializer_list, or from_range), and corresponding deduction guides.
In addition the std::ranges::to<std::unordered_set>(alloc) is well-formed, likewise for rest of unordered containers. libstdc++-v3/ChangeLog: * include/bits/unordered_map.h (unordered_map): Define constructors accepting: (_InputIterator, _InputIterator, const allocator_type&), (initializer_list<value_type>, const allocator_type&), (from_range_t, _Rg&&, const allocator_type&) (unordered_multimap): Likewise. * include/bits/unordered_set.h (unordered_set): Define constructors and deduction guide accepting: (_InputIterator, _InputIterator, const allocator_type&), (initializer_list<value_type>, const allocator_type&). Define constructor (from_range_t, _Rg&&, const allocator_type&). (unordered_multiset): Likewise. * testsuite/23_containers/unordered_map/cons/66055.cc: New tests. * testsuite/23_containers/unordered_map/cons/deduction.cc: New tests. * testsuite/23_containers/unordered_map/cons/from_range.cc: New tests. * testsuite/23_containers/unordered_multimap/cons/66055.cc: New tests. * testsuite/23_containers/unordered_multimap/cons/deduction.cc: New tests. * testsuite/23_containers/unordered_multimap/cons/from_range.cc: New tests. * testsuite/23_containers/unordered_multiset/cons/66055.cc: New tests. * testsuite/23_containers/unordered_multiset/cons/deduction.cc: New tests. * testsuite/23_containers/unordered_multiset/cons/from_range.cc: New tests. * testsuite/23_containers/unordered_set/cons/66055.cc: New tests. * testsuite/23_containers/unordered_set/cons/deduction.cc: New tests. * testsuite/23_containers/unordered_set/cons/from_range.cc: New tests. * testsuite/std/ranges/conv/1.cc: New tests. --- I have added ranges::to test, as they provide additional motivation. Tested on x86_64-linux. OK for trunk? libstdc++-v3/include/bits/unordered_map.h | 44 ++++++++++ libstdc++-v3/include/bits/unordered_set.h | 86 +++++++++++++++++++ .../23_containers/unordered_map/cons/66055.cc | 11 ++- .../unordered_map/cons/deduction.cc | 29 +++++++ .../unordered_map/cons/from_range.cc | 24 +++--- .../unordered_multimap/cons/66055.cc | 10 ++- .../unordered_multimap/cons/deduction.cc | 34 ++++++++ .../unordered_multimap/cons/from_range.cc | 24 +++--- .../unordered_multiset/cons/66055.cc | 10 ++- .../unordered_multiset/cons/deduction.cc | 28 ++++++ .../unordered_multiset/cons/from_range.cc | 22 +++-- .../23_containers/unordered_set/cons/66055.cc | 10 ++- .../unordered_set/cons/deduction.cc | 28 ++++++ libstdc++-v3/testsuite/std/ranges/conv/1.cc | 22 +++++ 14 files changed, 328 insertions(+), 54 deletions(-) diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 5c930487190..2d85da3f29d 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -251,6 +251,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_map(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<typename _InputIterator> + unordered_map(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_map(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_map(_InputIterator __first, _InputIterator __last, size_type __n, @@ -271,6 +279,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_map(__l, __n, hasher(), key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + unordered_map(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_map(__l, 0, hasher(), key_equal(), __a) + { } + unordered_map(initializer_list<value_type> __l, size_type __n, const hasher& __hf, const allocator_type& __a) @@ -300,6 +315,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_h(__n, __hf, __eql, __a) { insert_range(std::forward<_Rg>(__rg)); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<__detail::__container_compatible_range<value_type> _Rg> + unordered_map(from_range_t, _Rg&& __rg, const allocator_type& __a) + : _M_h(0, hasher(), key_equal(), __a) + { insert_range(std::forward<_Rg>(__rg)); } + template<__detail::__container_compatible_range<value_type> _Rg> unordered_map(from_range_t, _Rg&& __rg, size_type __n, const allocator_type& __a) @@ -1497,6 +1519,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multimap(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<typename _InputIterator> + unordered_multimap(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multimap(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_multimap(_InputIterator __first, _InputIterator __last, size_type __n, @@ -1511,6 +1541,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + unordered_multimap(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multimap(__l, 0, hasher(), key_equal(), __a) + { } + unordered_multimap(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -1546,6 +1583,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_h(__n, __hf, __eql, __a) { insert_range(std::forward<_Rg>(__rg)); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered containers + template<__detail::__container_compatible_range<value_type> _Rg> + unordered_multimap(from_range_t, _Rg&& __rg, const allocator_type& __a) + : _M_h(0, hasher(), key_equal(), __a) + { insert_range(std::forward<_Rg>(__rg)); } + template<__detail::__container_compatible_range<value_type> _Rg> unordered_multimap(from_range_t, _Rg&& __rg, size_type __n, const allocator_type& __a) diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 21ffdaf50a0..d81e66065f0 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -245,6 +245,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_set(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator> + unordered_set(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_set(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, @@ -259,6 +267,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_set(__first, __last, __n, __hf, key_equal(), __a) { } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + unordered_set(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_set(__l, 0, hasher(), key_equal(), __a) + { } + unordered_set(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -294,6 +310,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_h(__n, __hf, __eql, __a) { insert_range(std::forward<_Rg>(__rg)); } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<__detail::__container_compatible_range<_Value> _Rg> + unordered_set(from_range_t, _Rg&& __rg, const allocator_type& __a) + : _M_h(0, hasher(), key_equal(), __a) + { insert_range(std::forward<_Rg>(__rg)); } + template<__detail::__container_compatible_range<_Value> _Rg> unordered_set(from_range_t, _Rg&& __rg, size_type __n, const allocator_type& __a) @@ -980,6 +1003,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER typename iterator_traits<_InputIterator>::value_type>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_set(_InputIterator, _InputIterator, _Allocator) + -> unordered_set<typename iterator_traits<_InputIterator>::value_type, + hash< + typename iterator_traits<_InputIterator>::value_type>, + equal_to< + typename iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -999,6 +1035,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_set<int>::size_type, _Allocator) -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_set(initializer_list<_Tp>, _Allocator) + -> unordered_set<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> @@ -1216,6 +1259,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multiset(__n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator> + unordered_multiset(_InputIterator __first, _InputIterator __last, + const allocator_type& __a) + : unordered_multiset(__first, __last, 0, hasher(), key_equal(), __a) + { } + template<typename _InputIterator> unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, @@ -1230,6 +1281,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) { } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + unordered_multiset(initializer_list<value_type> __l, + const allocator_type& __a) + : unordered_multiset(__l, 0, hasher(), key_equal(), __a) + { } + unordered_multiset(initializer_list<value_type> __l, size_type __n, const allocator_type& __a) @@ -1265,6 +1323,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_h(__n, __hf, __eql, __a) { insert_range(std::forward<_Rg>(__rg)); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<__detail::__container_compatible_range<_Value> _Rg> + unordered_multiset(from_range_t, _Rg&& __rg, const allocator_type& __a) + : _M_h(0, hasher(), key_equal(), __a) + { insert_range(std::forward<_Rg>(__rg)); } + template<__detail::__container_compatible_range<_Value> _Rg> unordered_multiset(from_range_t, _Rg&& __rg, size_type __n, const allocator_type& __a) @@ -1934,6 +2000,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER iterator_traits<_InputIterator>::value_type>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(_InputIterator, _InputIterator, _Allocator) + -> unordered_multiset<typename iterator_traits<_InputIterator>::value_type, + hash<typename + iterator_traits<_InputIterator>::value_type>, + equal_to<typename + iterator_traits<_InputIterator>::value_type>, + _Allocator>; + template<typename _InputIterator, typename _Hash, typename _Allocator, typename = _RequireInputIter<_InputIterator>, typename = _RequireNotAllocatorOrIntegral<_Hash>, @@ -1955,6 +2034,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER unordered_multiset<int>::size_type, _Allocator) -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2713. More missing allocator-extended constructors for unordered container + template<typename _Tp, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + unordered_multiset(initializer_list<_Tp>, _Allocator) + -> unordered_multiset<_Tp, hash<_Tp>, equal_to<_Tp>, _Allocator>; + template<typename _Tp, typename _Hash, typename _Allocator, typename = _RequireNotAllocatorOrIntegral<_Hash>, typename = _RequireAllocator<_Allocator>> diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/66055.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/66055.cc index c7a12c14425..0f959760713 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/66055.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/66055.cc @@ -27,7 +27,10 @@ using alloc_type = test_type::allocator_type; test_type h1(10, alloc_type()); test_type h2(10, hasher_type(), alloc_type()); -test_type h3(h1.begin(), h1.end(), 10, alloc_type()); -test_type h4(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); -test_type h5({ { 1, 1 } }, 10, alloc_type()); -test_type h6({ { 1, 1 } }, 10, hasher_type(), alloc_type()); +test_type h3(h1.begin(), h1.end(), alloc_type()); +test_type h4(h1.begin(), h1.end(), 10, alloc_type()); +test_type h5(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); +test_type h6({ { 1, 1 } }, alloc_type()); +test_type h7({ { 1, 1 } }, 10, alloc_type()); +test_type h8({ { 1, 1 } }, 10, hasher_type(), alloc_type()); + diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc index 8b69af896a2..61ef71330bb 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc @@ -15,12 +15,28 @@ static_assert(std::is_same_v< {2, 3.0}, {3, 4.0}}}), std::unordered_map<int, double>>); +static_assert(std::is_same_v< + decltype(std::unordered_map{{std::pair{1, 2.0}, + {2, 3.0}, {3, 4.0}}, + SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_map<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< decltype(std::unordered_map{ {std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, 1}), std::unordered_map<int, double>>); +static_assert(std::is_same_v< + decltype(std::unordered_map{ + {std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, + 1, SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_map<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< decltype(std::unordered_map{{std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, @@ -96,12 +112,25 @@ void f() std::equal_to<int>, SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< + decltype(std::unordered_map{x.begin(), x.end(), + std::allocator<std::pair<const int, double>>{}}), + std::unordered_map<int, double>>); + + static_assert(std::is_same_v< + decltype(std::unordered_map{x.begin(), x.end(), + SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_map<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< decltype(std::unordered_map{x.begin(), x.end(), 1, std::hash<int>{}, std::allocator<std::pair<const int, double>>{}}), std::unordered_map<int, double>>); + static_assert(std::is_same_v< decltype(std::unordered_map{x.begin(), x.end(), 1, std::hash<int>{}, 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 b3cbb2e6062..51f8538669a 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 @@ -49,12 +49,11 @@ test_deduction_guide() using Alloc = __gnu_test::SimpleAllocator<std::pair<const long, float>>; Alloc alloc; - // LWG2713: there is no matching constructor - // std::unordered_map m5(std::from_range, r, alloc); - // static_assert(std::is_same_v< - // decltype(m5), - // std::unordered_map<long, float, - // std::hash<long>, std::equal_to<long>, Alloc>>); + std::unordered_map m5(std::from_range, r, alloc); + static_assert(std::is_same_v< + decltype(m5), + std::unordered_map<long, float, + std::hash<long>, std::equal_to<long>, Alloc>>); std::unordered_map m6(std::from_range, r, 0, alloc); static_assert(std::is_same_v< @@ -154,13 +153,12 @@ do_test(Alloc alloc, Hash hf, Equal eqf) VERIFY( is_equal(m9.hash_function(), hf) ); VERIFY( is_equal(m9.key_eq(), eqf) ); - // LWG2713: there is no matching constructor - // std::unordered_map<K, V, Hash, Equal, Alloc> - // ma1(std::from_range, Range(a, a+14), alloc); - // VERIFY( eq(ma1, {a, 9}) ); - // VERIFY( is_equal(ma1.hash_function(), Hash()) ); - // VERIFY( is_equal(ma1.key_eq(), Equal()) ); - // VERIFY( ma1.get_allocator() == alloc ); + std::unordered_map<K, V, Hash, Equal, Alloc> + ma1(std::from_range, Range(a, a+14), alloc); + VERIFY( eq(ma1, {a, 9}) ); + VERIFY( is_equal(ma1.hash_function(), Hash()) ); + VERIFY( is_equal(ma1.key_eq(), Equal()) ); + VERIFY( ma1.get_allocator() == alloc ); std::unordered_map<K, V, Hash, Equal, Alloc> ma2(std::from_range, Range(a, a+14), 2, alloc); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/66055.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/66055.cc index dc0a65196c8..eecc60024fe 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/66055.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/66055.cc @@ -27,7 +27,9 @@ using alloc_type = test_type::allocator_type; test_type h1(10, alloc_type()); test_type h2(10, hasher_type(), alloc_type()); -test_type h3(h1.begin(), h1.end(), 10, alloc_type()); -test_type h4(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); -test_type h5({ { 1, 1 } }, 10, alloc_type()); -test_type h6({ { 1, 1 } }, 10, hasher_type(), alloc_type()); +test_type h3(h1.begin(), h1.end(), alloc_type()); +test_type h4(h1.begin(), h1.end(), 10, alloc_type()); +test_type h5(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); +test_type h6({ { 1, 1 } }, alloc_type()); +test_type h7({ { 1, 1 } }, 10, alloc_type()); +test_type h8({ { 1, 1 } }, 10, hasher_type(), alloc_type()); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc index e7e535b527a..4de23fe3e79 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc @@ -15,6 +15,28 @@ static_assert(std::is_same_v< {2, 3.0}, {3, 4.0}}}), std::unordered_multimap<int, double>>); +static_assert(std::is_same_v< + decltype(std::unordered_multimap{ + {std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, + SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_multimap<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + +static_assert(std::is_same_v< + decltype(std::unordered_multimap{ + {std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, + 1}), + std::unordered_multimap<int, double>>); + +static_assert(std::is_same_v< + decltype(std::unordered_multimap{ + {std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, + 1, SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_multimap<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< decltype(std::unordered_multimap{{std::pair{1, 2.0}, {2, 3.0}, {3, 4.0}}, @@ -105,6 +127,18 @@ void f() std::equal_to<int>, SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< + decltype(std::unordered_multimap{x.begin(), x.end(), + std::allocator<std::pair<const int, double>>{}}), + std::unordered_multimap<int, double>>); + + static_assert(std::is_same_v< + decltype(std::unordered_multimap{x.begin(), x.end(), + SimpleAllocator<std::pair<const int, double>>{}}), + std::unordered_multimap<int, double, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<std::pair<const int, double>>>>); + static_assert(std::is_same_v< decltype(std::unordered_multimap{x.begin(), x.end(), 1, std::hash<int>{}, 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 9273ef0d57a..2e26cd2d201 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 @@ -53,12 +53,11 @@ test_deduction_guide() using Alloc = __gnu_test::SimpleAllocator<std::pair<const long, float>>; Alloc alloc; - // LWG2713: there is no matching constructor - // std::unordered_multimap m5(std::from_range, r, alloc); - // static_assert(std::is_same_v< - // decltype(m5), - // std::unordered_multimap<long, float, - // std::hash<long>, std::equal_to<long>, Alloc>>); + std::unordered_multimap m5(std::from_range, r, alloc); + static_assert(std::is_same_v< + decltype(m5), + std::unordered_multimap<long, float, + std::hash<long>, std::equal_to<long>, Alloc>>); std::unordered_multimap m6(std::from_range, r, 0, alloc); static_assert(std::is_same_v< @@ -159,13 +158,12 @@ do_test(Alloc alloc, Hash hf, Equal eqf) VERIFY( is_equal(m9.hash_function(), hf) ); VERIFY( is_equal(m9.key_eq(), eqf) ); - // LWG2713: there is no matching constructor - // std::unordered_multimap<K, V, Hash, Equal, Alloc> - // ma1(std::from_range, Range(a, a+14), alloc); - // VERIFY( eq(ma1, {a, 14}) ); - // VERIFY( is_equal(ma1.hash_function(), Hash()) ); - // VERIFY( is_equal(ma1.key_eq(), Equal()) ); - // VERIFY( ma1.get_allocator() == alloc ); + std::unordered_multimap<K, V, Hash, Equal, Alloc> + ma1(std::from_range, Range(a, a+14), alloc); + VERIFY( eq(ma1, {a, 14}) ); + VERIFY( is_equal(ma1.hash_function(), Hash()) ); + VERIFY( is_equal(ma1.key_eq(), Equal()) ); + VERIFY( ma1.get_allocator() == alloc ); std::unordered_multimap<K, V, Hash, Equal, Alloc> ma2(std::from_range, Range(a, a+14), 2, alloc); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/66055.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/66055.cc index 5c34b94c00d..3ba609fc449 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/66055.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/66055.cc @@ -27,7 +27,9 @@ using alloc_type = test_type::allocator_type; test_type h1(10, alloc_type()); test_type h2(10, hasher_type(), alloc_type()); -test_type h3(h1.begin(), h1.end(), 10, alloc_type()); -test_type h4(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); -test_type h5({ 1, 1 }, 10, alloc_type()); -test_type h6({ 1, 1 }, 10, hasher_type(), alloc_type()); +test_type h3(h1.begin(), h1.end(), alloc_type()); +test_type h4(h1.begin(), h1.end(), 10, alloc_type()); +test_type h5(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); +test_type h6({ 1, 1 }, alloc_type()); +test_type h7({ 1, 1 }, 10, alloc_type()); +test_type h9({ 1, 1 }, 10, hasher_type(), alloc_type()); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc index 22b729749e2..46cd2105acc 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc @@ -19,6 +19,22 @@ static_assert(std::is_same_v< 0, std::hash<int>{}, std::allocator<int>{}}), std::unordered_multiset<int>>); +static_assert(std::is_same_v< + decltype(std::unordered_multiset{{1, 2, 3}}), + std::unordered_multiset<int>>); + +static_assert(std::is_same_v< + decltype(std::unordered_multiset{{1, 2, 3}, + std::allocator<int>{}}), + std::unordered_multiset<int>>); + +static_assert(std::is_same_v< + decltype(std::unordered_multiset{{1, 2, 3}, + SimpleAllocator<int>{}}), + std::unordered_multiset<int, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<int>>>); + static_assert(std::is_same_v< decltype(std::unordered_multiset{{1, 2, 3}, {}}), @@ -86,6 +102,18 @@ void f() {}, std::hash<int>{}, std::equal_to<int>{}}), std::unordered_multiset<int>>); + static_assert(std::is_same_v< + decltype(std::unordered_multiset{x.begin(), x.end(), + std::allocator<int>{}}), + std::unordered_multiset<int>>); + + static_assert(std::is_same_v< + decltype(std::unordered_multiset{x.begin(), x.end(), + SimpleAllocator<int>{}}), + std::unordered_multiset<int, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<int>>>); + static_assert(std::is_same_v< decltype(std::unordered_multiset{x.begin(), x.end(), {}, std::hash<int>{}, std::allocator<int>{}}), diff --git a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/from_range.cc index fb388764423..ddbc7ff822f 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/from_range.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/from_range.cc @@ -49,11 +49,10 @@ test_deduction_guide(long* p) using Alloc = __gnu_test::SimpleAllocator<long>; Alloc alloc; - // LWG2713: there is no matching constructor - // std::unordered_multiset s5(std::from_range, r, alloc); - // static_assert(std::is_same_v< - // decltype(s5), - // std::unordered_multiset<long, std::hash<long>, std::equal_to<long>, Alloc>>); + std::unordered_multiset s5(std::from_range, r, alloc); + static_assert(std::is_same_v< + decltype(s5), + std::unordered_multiset<long, std::hash<long>, std::equal_to<long>, Alloc>>); std::unordered_multiset s6(std::from_range, r, 0, alloc); static_assert(std::is_same_v< @@ -136,13 +135,12 @@ do_test(Alloc alloc, Hash hf, Equal eqf) VERIFY( is_equal(s9.hash_function(), hf) ); VERIFY( is_equal(s9.key_eq(), eqf) ); - // LWG2713: there is no matching constructor - // std::unordered_multiset<V, Hash, Equal, Alloc> - // sa(std::from_range, Range(a, a+14), alloc); - // VERIFY( eq(sa1, {a, 14}) ); - // VERIFY( is_equal(sa1.hash_function(), Hash()) ); - // VERIFY( is_equal(sa1.key_eq(), Equal()) ); - // VERIFY( sa1.get_allocator() == alloc ); + std::unordered_multiset<V, Hash, Equal, Alloc> + sa1(std::from_range, Range(a, a+14), alloc); + VERIFY( eq(sa1, {a, 14}) ); + VERIFY( is_equal(sa1.hash_function(), Hash()) ); + VERIFY( is_equal(sa1.key_eq(), Equal()) ); + VERIFY( sa1.get_allocator() == alloc ); std::unordered_multiset<V, Hash, Equal, Alloc> sa2(std::from_range, Range(a, a+14), 2, alloc); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/66055.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/66055.cc index 0d318a04b2b..96c0ca3be53 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/66055.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/66055.cc @@ -27,7 +27,9 @@ using alloc_type = test_type::allocator_type; test_type h1(10, alloc_type()); test_type h2(10, hasher_type(), alloc_type()); -test_type h3(h1.begin(), h1.end(), 10, alloc_type()); -test_type h4(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); -test_type h5({ 1, 1 }, 10, alloc_type()); -test_type h6({ 1, 1 }, 10, hasher_type(), alloc_type()); +test_type h3(h1.begin(), h1.end(), alloc_type()); +test_type h4(h1.begin(), h1.end(), 10, alloc_type()); +test_type h5(h1.begin(), h1.end(), 10, hasher_type(), alloc_type()); +test_type h6({ 1, 1 }, alloc_type()); +test_type h7({ 1, 1 }, 10, alloc_type()); +test_type h9({ 1, 1 }, 10, hasher_type(), alloc_type()); diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc index db5858132fc..9558d70505f 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc @@ -19,6 +19,22 @@ static_assert(std::is_same_v< 0, std::hash<int>{}, std::allocator<int>{}}), std::unordered_set<int>>); +static_assert(std::is_same_v< + decltype(std::unordered_set{{1, 2, 3}}), + std::unordered_set<int>>); + +static_assert(std::is_same_v< + decltype(std::unordered_set{{1, 2, 3}, + std::allocator<int>{}}), + std::unordered_set<int>>); + +static_assert(std::is_same_v< + decltype(std::unordered_set{{1, 2, 3}, + SimpleAllocator<int>{}}), + std::unordered_set<int, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<int>>>); + static_assert(std::is_same_v< decltype(std::unordered_set{{1, 2, 3}, {}}), @@ -91,6 +107,18 @@ void f() {})), std::unordered_set<int>>); + static_assert(std::is_same_v< + decltype(std::unordered_set{x.begin(), x.end(), + std::allocator<int>{}}), + std::unordered_set<int>>); + + static_assert(std::is_same_v< + decltype(std::unordered_set{x.begin(), x.end(), + SimpleAllocator<int>{}}), + std::unordered_set<int, std::hash<int>, + std::equal_to<int>, + SimpleAllocator<int>>>); + static_assert(std::is_same_v< decltype(std::unordered_set{x.begin(), x.end(), 1}), std::unordered_set<int>>); diff --git a/libstdc++-v3/testsuite/std/ranges/conv/1.cc b/libstdc++-v3/testsuite/std/ranges/conv/1.cc index 231cb9d9934..2caa1b83f30 100644 --- a/libstdc++-v3/testsuite/std/ranges/conv/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/conv/1.cc @@ -12,6 +12,7 @@ #include <testsuite_hooks.h> #include <testsuite_allocator.h> #include <testsuite_iterators.h> +#include <unordered_map> void test_p1206r7_examples() @@ -478,6 +479,26 @@ test_pr119282() return true; } +void +test_lwg2713() +{ + using Alloc = __gnu_test::uneq_allocator<std::pair<const int, const char*>>; + const Alloc alloc(303); + const std::map<int, const char*> m{{1, "one"}, {2, "two"}, {3, "three"}}; + namespace ranges = std::ranges; + + // Call constructors with bucket count + auto m1 = m | ranges::to<std::unordered_map>(0, alloc); + VERIFY( m1.get_allocator() == alloc ); + auto m2 = m | ranges::to<std::unordered_multimap>(0, alloc); + VERIFY( m2.get_allocator() == alloc ); + // These call constructors added in lwg2713 + auto m3 = m | ranges::to<std::unordered_map>(alloc); + VERIFY( m3.get_allocator() == alloc ); + auto m4 = m | ranges::to<std::unordered_multimap>(alloc); + VERIFY( m4.get_allocator() == alloc ); +} + int main() { test_p1206r7_examples(); @@ -487,6 +508,7 @@ int main() test_2_1_3(); test_2_1_4(); test_2_2(); + test_lwg2713(); test_lwg3984(); test_nodiscard(); test_constexpr(); -- 2.48.1