From: Jonathan Wakely Date: Mon, 4 Oct 2021 13:04:20 +0000 (+0100) Subject: libstdc++: Implement P1518R2 for container deduction guides X-Git-Tag: basepoints/gcc-13~4171 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22d34a2a50651d01669b6fbcdb9677c18d2197c5;p=thirdparty%2Fgcc.git libstdc++: Implement P1518R2 for container deduction guides This implements the C++23 P1518R2 proposal "Stop overconstraining allocators in container deduction guides" as a fix for C++17 and C++20 too. The changes allow class template argument deduction to ignore the type of a constructor argument that initializes an allocator_type parameter if the type should be deducible only from the other arguments. So for the constructor vector(const vector&, const allocator_type&) only the first argument is used for deduction, allowing the second argument to be anything that is implicitly convertible to argument_type. Previously deduction would fail or an ill-formed type would be deduced if the second argument wasn't of type allocator_type. The unordered containers do not need changes, because their allocator-extended constructors use the allocator_type alias, which comes from the dependent base class so is already a non-deduced context. libstdc++-v3/ChangeLog: * include/bits/forward_list.h (forward_list): Use non-deduced context for allocator parameter of allocator-extended copy and move constructors. * include/bits/stl_bvector.h (vector): Likewise. * include/bits/stl_deque.h (deque): Likewise. * include/bits/stl_list.h (list): Likewise. * include/bits/stl_map.h (map): Likewise. * include/bits/stl_multimap.h (multimap): Likewise. * include/bits/stl_multiset.h (multiset): Likewise. * include/bits/stl_set.h (set): Likewise. * include/bits/stl_vector.h (vector): Likewise. * include/bits/stl_queue.h (queue, priority_queue): Do not constrain Allocator template parameter of deduction guides that have a Container parameter. * include/bits/stl_stack.h (stack): Likewise. * include/debug/deque (__gnu_debug::deque): Use non-deduced context for allocator parameter of allocator-extended copy and move constructors. * include/debug/list (__gnu_debug::list): Likewise. * include/debug/map.h (__gnu_debug::map): Likewise. * include/debug/multimap.h (__gnu_debug::multimap): Likewise. * include/debug/multiset.h (__gnu_debug::multiset): Likewise. * include/debug/set.h (__gnu_debug::set): Likewise. * include/debug/vector (__gnu_debug::vector): Likewise. * testsuite/23_containers/deque/cons/deduction.cc: Test class template argument deduction with non-deduced allocator arguments. * testsuite/23_containers/forward_list/cons/deduction.cc: Likewise. * testsuite/23_containers/list/cons/deduction.cc: Likewise. * testsuite/23_containers/map/cons/deduction.cc: Likewise. * testsuite/23_containers/multimap/cons/deduction.cc: Likewise. * testsuite/23_containers/multiset/cons/deduction.cc: Likewise. * testsuite/23_containers/priority_queue/deduction.cc: Likewise. * testsuite/23_containers/queue/deduction.cc: Likewise. * testsuite/23_containers/set/cons/deduction.cc: Likewise. * testsuite/23_containers/stack/deduction.cc: Likewise. * testsuite/23_containers/unordered_map/cons/deduction.cc: Likewise. * testsuite/23_containers/unordered_multimap/cons/deduction.cc: Likewise. * testsuite/23_containers/unordered_multiset/cons/deduction.cc: Likewise. * testsuite/23_containers/unordered_set/cons/deduction.cc: Likewise. * testsuite/23_containers/vector/cons/deduction.cc: Likewise. --- diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index ab6d93891949..aa8623b4c197 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -480,7 +480,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @param __list Input list to copy. * @param __al An allocator object. */ - forward_list(const forward_list& __list, const _Alloc& __al) + forward_list(const forward_list& __list, + const __type_identity_t<_Alloc>& __al) : _Base(_Node_alloc_type(__al)) { _M_range_initialize(__list.begin(), __list.end()); } @@ -508,7 +509,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @param __list Input list to move. * @param __al An allocator object. */ - forward_list(forward_list&& __list, const _Alloc& __al) + forward_list(forward_list&& __list, + const __type_identity_t<_Alloc>& __al) noexcept(_Node_alloc_traits::_S_always_equal()) : forward_list(std::move(__list), _Node_alloc_type(__al), typename _Node_alloc_traits::is_always_equal{}) diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h index a954890ff202..3778d5a770a5 100644 --- a/libstdc++-v3/include/bits/stl_bvector.h +++ b/libstdc++-v3/include/bits/stl_bvector.h @@ -706,13 +706,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } public: - vector(vector&& __x, const allocator_type& __a) + vector(vector&& __x, const __type_identity_t& __a) noexcept(_Bit_alloc_traits::_S_always_equal()) : vector(std::move(__x), __a, typename _Bit_alloc_traits::is_always_equal{}) { } - vector(const vector& __x, const allocator_type& __a) + vector(const vector& __x, const __type_identity_t& __a) : _Base(__a) { _M_initialize(__x.size()); diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 6095498d440f..268fb9ef4058 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -932,14 +932,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque(deque&&) = default; /// Copy constructor with alternative allocator - deque(const deque& __x, const allocator_type& __a) + deque(const deque& __x, const __type_identity_t& __a) : _Base(__a, __x.size()) { std::__uninitialized_copy_a(__x.begin(), __x.end(), this->_M_impl._M_start, _M_get_Tp_allocator()); } /// Move constructor with alternative allocator - deque(deque&& __x, const allocator_type& __a) + deque(deque&& __x, const __type_identity_t& __a) : deque(std::move(__x), __a, typename _Alloc_traits::is_always_equal{}) { } diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 81361dfa4d5b..96d2a2f0f69d 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -836,7 +836,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 : _Base(_Node_alloc_type(__a)) { _M_initialize_dispatch(__l.begin(), __l.end(), __false_type()); } - list(const list& __x, const allocator_type& __a) + list(const list& __x, const __type_identity_t& __a) : _Base(_Node_alloc_type(__a)) { _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); } @@ -856,7 +856,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 } public: - list(list&& __x, const allocator_type& __a) + list(list&& __x, const __type_identity_t& __a) noexcept(_Node_alloc_traits::_S_always_equal()) : list(std::move(__x), __a, typename _Node_alloc_traits::is_always_equal{}) diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 535dbeb745a9..cc87f11fb11e 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -237,11 +237,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Pair_alloc_type(__a)) { } /// Allocator-extended copy constructor. - map(const map& __m, const allocator_type& __a) + map(const map& __m, const __type_identity_t& __a) : _M_t(__m._M_t, _Pair_alloc_type(__a)) { } /// Allocator-extended move constructor. - map(map&& __m, const allocator_type& __a) + map(map&& __m, const __type_identity_t& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { } diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 8157981d0bcd..1b9648e3bd44 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -234,11 +234,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Pair_alloc_type(__a)) { } /// Allocator-extended copy constructor. - multimap(const multimap& __m, const allocator_type& __a) + multimap(const multimap& __m, + const __type_identity_t& __a) : _M_t(__m._M_t, _Pair_alloc_type(__a)) { } /// Allocator-extended move constructor. - multimap(multimap&& __m, const allocator_type& __a) + multimap(multimap&& __m, const __type_identity_t& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Pair_alloc_type(__a)) { } diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index ef987600733e..5d9d6195ae16 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -248,11 +248,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Key_alloc_type(__a)) { } /// Allocator-extended copy constructor. - multiset(const multiset& __m, const allocator_type& __a) + multiset(const multiset& __m, + const __type_identity_t& __a) : _M_t(__m._M_t, _Key_alloc_type(__a)) { } /// Allocator-extended move constructor. - multiset(multiset&& __m, const allocator_type& __a) + multiset(multiset&& __m, const __type_identity_t& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__m._M_t), _Key_alloc_type(__a)) { } diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h index ccd1122f848d..3da65c78eb80 100644 --- a/libstdc++-v3/include/bits/stl_queue.h +++ b/libstdc++-v3/include/bits/stl_queue.h @@ -342,8 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION queue(_Container) -> queue; template, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> queue(_Container, _Allocator) -> queue; @@ -817,8 +816,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template, - typename = _RequireNotAllocator<_Container>, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> priority_queue(_Compare, _Container, _Allocator) -> priority_queue; #endif diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index a9b9695bca83..f0dfa05886f2 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -252,11 +252,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER : _M_t(_Key_alloc_type(__a)) { } /// Allocator-extended copy constructor. - set(const set& __x, const allocator_type& __a) + set(const set& __x, const __type_identity_t& __a) : _M_t(__x._M_t, _Key_alloc_type(__a)) { } /// Allocator-extended move constructor. - set(set&& __x, const allocator_type& __a) + set(set&& __x, const __type_identity_t& __a) noexcept(is_nothrow_copy_constructible<_Compare>::value && _Alloc_traits::_S_always_equal()) : _M_t(std::move(__x._M_t), _Key_alloc_type(__a)) { } diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h index af234d6899c2..f04fa6af4798 100644 --- a/libstdc++-v3/include/bits/stl_stack.h +++ b/libstdc++-v3/include/bits/stl_stack.h @@ -317,8 +317,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION stack(_Container) -> stack; template, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> stack(_Container, _Allocator) -> stack; diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 296da43822a5..2023581bc79c 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -572,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER vector(vector&&) noexcept = default; /// Copy constructor with alternative allocator - vector(const vector& __x, const allocator_type& __a) + vector(const vector& __x, const __type_identity_t& __a) : _Base(__x.size(), __a) { this->_M_impl._M_finish = @@ -604,7 +604,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER public: /// Move constructor with alternative allocator - vector(vector&& __rv, const allocator_type& __m) + vector(vector&& __rv, const __type_identity_t& __m) noexcept( noexcept( vector(std::declval(), std::declval(), std::declval())) ) diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 574cab11c6f6..8e4811149d2d 100644 --- a/libstdc++-v3/include/debug/deque +++ b/libstdc++-v3/include/debug/deque @@ -108,10 +108,10 @@ namespace __debug deque(const deque&) = default; deque(deque&&) = default; - deque(const deque& __d, const _Allocator& __a) + deque(const deque& __d, const __type_identity_t<_Allocator>& __a) : _Base(__d, __a) { } - deque(deque&& __d, const _Allocator& __a) + deque(deque&& __d, const __type_identity_t<_Allocator>& __a) : _Safe(std::move(__d)), _Base(std::move(__d), __a) { } deque(initializer_list __l, diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index b599e93d147c..de30edb19c24 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -115,10 +115,10 @@ namespace __debug ~list() = default; - list(const list& __x, const allocator_type& __a) + list(const list& __x, const __type_identity_t& __a) : _Base(__x, __a) { } - list(list&& __x, const allocator_type& __a) + list(list&& __x, const __type_identity_t& __a) noexcept( std::is_nothrow_constructible<_Base, _Base, const allocator_type&>::value ) diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h index c0153d09abeb..9e142cf70239 100644 --- a/libstdc++-v3/include/debug/map.h +++ b/libstdc++-v3/include/debug/map.h @@ -114,10 +114,10 @@ namespace __debug map(const allocator_type& __a) : _Base(__a) { } - map(const map& __m, const allocator_type& __a) + map(const map& __m, const __type_identity_t& __a) : _Base(__m, __a) { } - map(map&& __m, const allocator_type& __a) + map(map&& __m, const __type_identity_t& __a) noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h index 94929344a9d3..a05b8a8493e6 100644 --- a/libstdc++-v3/include/debug/multimap.h +++ b/libstdc++-v3/include/debug/multimap.h @@ -114,10 +114,11 @@ namespace __debug multimap(const allocator_type& __a) : _Base(__a) { } - multimap(const multimap& __m, const allocator_type& __a) + multimap(const multimap& __m, + const __type_identity_t& __a) : _Base(__m, __a) { } - multimap(multimap&& __m, const allocator_type& __a) + multimap(multimap&& __m, const __type_identity_t& __a) noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h index bb68d8c8f180..a312ccf6f506 100644 --- a/libstdc++-v3/include/debug/multiset.h +++ b/libstdc++-v3/include/debug/multiset.h @@ -113,10 +113,11 @@ namespace __debug multiset(const allocator_type& __a) : _Base(__a) { } - multiset(const multiset& __m, const allocator_type& __a) + multiset(const multiset& __m, + const __type_identity_t& __a) : _Base(__m, __a) { } - multiset(multiset&& __m, const allocator_type& __a) + multiset(multiset&& __m, const __type_identity_t& __a) noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h index cdf35ea53967..01da942eb780 100644 --- a/libstdc++-v3/include/debug/set.h +++ b/libstdc++-v3/include/debug/set.h @@ -113,10 +113,10 @@ namespace __debug set(const allocator_type& __a) : _Base(__a) { } - set(const set& __x, const allocator_type& __a) + set(const set& __x, const __type_identity_t& __a) : _Base(__x, __a) { } - set(set&& __x, const allocator_type& __a) + set(set&& __x, const __type_identity_t& __a) noexcept( noexcept(_Base(std::move(__x._M_base()), __a)) ) : _Safe(std::move(__x._M_safe()), __a), _Base(std::move(__x._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index d30d750a6f07..03fd9405cc91 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -212,10 +212,10 @@ namespace __debug vector(const vector&) = default; vector(vector&&) = default; - vector(const vector& __x, const allocator_type& __a) + vector(const vector& __x, const __type_identity_t& __a) : _Base(__x, __a) { } - vector(vector&& __x, const allocator_type& __a) + vector(vector&& __x, const __type_identity_t& __a) noexcept( std::is_nothrow_constructible<_Base, _Base, const allocator_type&>::value ) diff --git a/libstdc++-v3/testsuite/23_containers/deque/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/deque/cons/deduction.cc index 8a38351e5242..5cb0a58a22c8 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/cons/deduction.cc @@ -19,6 +19,7 @@ #include #include +#include template using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::deque s4(1U, 2L, std::allocator()); check_type>(s4); } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Deque = std::deque>; + Pool* p = nullptr; + Deque d(p); + + std::deque s1(d, p); + check_type(s1); + + std::deque s2(std::move(d), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/forward_list/cons/deduction.cc index eb39682f483b..701231d12594 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/cons/deduction.cc @@ -19,6 +19,7 @@ #include #include +#include template using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::forward_list s4(1U, 2L, std::allocator()); check_type>(s4); } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Flist = std::forward_list>; + Pool* p = nullptr; + Flist f(p); + + std::forward_list s1(f, p); + check_type(s1); + + std::forward_list s2(std::move(f), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc index 3ad1d3f6cb55..c747509ffc51 100644 --- a/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc @@ -19,6 +19,7 @@ #include #include +#include template using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::list s4(1U, 2L, std::allocator()); check_type>(s4); } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using List = std::list>; + Pool* p = nullptr; + List l(p); + + std::list s1(l, p); + check_type(s1); + + std::list s2(std::move(l), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc index e72033c38a6e..f8e6e6e8b994 100644 --- a/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc @@ -222,3 +222,39 @@ void h() std::map, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using PairAlloc = Alloc>; + using Map = std::map, PairAlloc>; + Pool* p = nullptr; + Map m(p); + + std::map s1(m, p); + check_type(s1); + + std::map s2(std::move(m), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc index ffc7502d60cf..f0699e2eefc3 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc @@ -174,3 +174,39 @@ void h() std::multimap, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using PairAlloc = Alloc>; + using MMap = std::multimap, PairAlloc>; + Pool* p = nullptr; + MMap m(p); + + std::multimap s1(m, p); + check_type(s1); + + std::multimap s2(std::move(m), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc index 8b7a16042a4c..7f4581a6aeb8 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc @@ -130,3 +130,38 @@ void g() std::multiset, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using MSet = std::multiset, Alloc>; + Pool* p = nullptr; + MSet s(p); + + std::multiset s1(s, p); + check_type(s1); + + std::multiset s2(std::move(s), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc b/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc index 05c4c570ad56..816efab85c78 100644 --- a/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc @@ -21,6 +21,7 @@ #include #include #include +#include template struct require_same; template struct require_same { using type = void; }; @@ -116,3 +117,39 @@ test02() std::priority_queue s14(seq.begin(), seq.end(), cmp, std::deque{}); check_type, Cmp>>(s14); } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Vector = std::vector>; + using Cmp = std::greater; + Pool* p = nullptr; + Vector v(p); + Cmp cmp; + + std::priority_queue q1(cmp, v, p); + check_type>(q1); + + std::priority_queue q2(cmp, std::move(v), p); + check_type>(q2); + + std::priority_queue q3(q1, p); + check_type>(q3); + + std::priority_queue q4(std::move(q1), p); + check_type>(q4); +} diff --git a/libstdc++-v3/testsuite/23_containers/queue/deduction.cc b/libstdc++-v3/testsuite/23_containers/queue/deduction.cc index ab28f83aa2be..2642ece2b1ac 100644 --- a/libstdc++-v3/testsuite/23_containers/queue/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/queue/deduction.cc @@ -20,6 +20,7 @@ #include #include #include +#include template struct require_same; template struct require_same { using type = void; }; @@ -86,3 +87,36 @@ test02() std::queue s8(std::move(l), l.get_allocator()); check_type>>(s8); } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Deque = std::deque>; + using List = std::list>; + Pool* p = nullptr; + Deque d(p); + List l(p); + + std::queue q1(d, p); + check_type>(q1); + + std::queue q2(l, p); + check_type>(q2); + + std::queue q3(q2, p); + check_type>(q3); +} diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc index 14f36b7c05dd..d77b9fcb73df 100644 --- a/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc @@ -131,3 +131,38 @@ void g() std::set, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Set = std::set, Alloc>; + Pool* p = nullptr; + Set s(p); + + std::set s1(s, p); + check_type(s1); + + std::set s2(std::move(s), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/stack/deduction.cc b/libstdc++-v3/testsuite/23_containers/stack/deduction.cc index db8e31e2bdaa..169a063687b5 100644 --- a/libstdc++-v3/testsuite/23_containers/stack/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/stack/deduction.cc @@ -20,6 +20,7 @@ #include #include #include +#include template struct require_same; template struct require_same { using type = void; }; @@ -58,7 +59,7 @@ test01() void test02() - { +{ std::deque d; std::list l; 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 0785447a81bc..8b69af896a25 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc @@ -124,3 +124,41 @@ void f() std::equal_to, SimpleAllocator>>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using PairAlloc = Alloc>; + using Hash = std::hash; + using Eq = std::equal_to<>; + using UMap = std::unordered_map; + Pool* p = nullptr; + UMap m(p); + + std::unordered_map s1(m, p); + check_type(s1); + + std::unordered_map s2(std::move(m), p); + check_type(s2); +} 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 d8a6f5136c98..e7e535b527a8 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc @@ -133,3 +133,41 @@ void f() std::equal_to, SimpleAllocator>>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using PairAlloc = Alloc>; + using Hash = std::hash; + using Eq = std::equal_to<>; + using UMMap = std::unordered_multimap; + Pool* p = nullptr; + UMMap m(p); + + std::unordered_multimap s1(m, p); + check_type(s1); + + std::unordered_multimap s2(std::move(m), p); + check_type(s2); +} 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 25c2715ea262..22b729749e22 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc @@ -142,3 +142,40 @@ void f() std::equal_to, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Hash = std::hash; + using Eq = std::equal_to<>; + using UMSet = std::unordered_multiset>; + Pool* p = nullptr; + UMSet s(p); + + std::unordered_multiset s1(s, p); + check_type(s1); + + std::unordered_multiset s2(std::move(s), p); + check_type(s2); +} 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 b8c45d2993d6..db5858132fce 100644 --- a/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc @@ -137,3 +137,40 @@ void f() std::equal_to, SimpleAllocator>>); } + +template struct require_same; +template struct require_same { using type = void; }; + +template + typename require_same::type + check_type(U&) { } + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Hash = std::hash; + using Eq = std::equal_to<>; + using USet = std::unordered_set>; + Pool* p = nullptr; + USet s(p); + + std::unordered_set s1(s, p); + check_type(s1); + + std::unordered_set s2(std::move(s), p); + check_type(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc index 9f7b7612c93c..542a0d7ff932 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc @@ -19,6 +19,7 @@ #include #include +#include template using input_iterator_seq @@ -49,6 +50,24 @@ test01() check_type>(s4); } +void +test01b() +{ + std::vector s0; + + std::vector s1 = s0; + check_type>(s1); + + std::vector s2 = std::move(s0); + check_type>(s2); + + const std::vector s3 = s0; + check_type>(s3); + + const std::vector s4 = s3; + check_type>(s4); +} + void test02() { @@ -67,3 +86,59 @@ test02() std::vector s4(1U, 2L, std::allocator()); check_type>(s4); } + +void +test02b() +{ + bool a[1] = {}; + input_iterator_seq seq(a); + + std::vector s1(seq.begin(), seq.end()); + check_type>(s1); + + std::vector s2(seq.begin(), seq.end(), std::allocator()); + check_type>(s2); + + std::vector s3(1U, true); + check_type>(s3); + + std::vector s4(1U, true, std::allocator()); + check_type>(s4); +} + +struct Pool; + +template +struct Alloc : __gnu_test::SimpleAllocator +{ + Alloc(Pool*) { } + + template + Alloc(const Alloc&) { } +}; + +void +test_p1518r2() +{ + // P1518R2 - Stop overconstraining allocators in container deduction guides. + // This is a C++23 feature but we support it for C++17 too. + + using Vector = std::vector>; + Pool* p = nullptr; + Vector v(p); + + std::vector s1(v, p); + check_type(s1); + + std::vector s2(std::move(v), p); + check_type(s2); + + using BVector = std::vector>; + BVector b(p); + + std::vector s3(b, p); + check_type(s3); + + std::vector s4(std::move(b), p); + check_type(s4); +}