diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2021-10-04 14:04:20 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2021-10-04 15:23:28 +0100 |
commit | 22d34a2a50651d01669b6fbcdb9677c18d2197c5 (patch) | |
tree | 98479ac458d4dac2a683cd42f001aff3cc1f6d60 | |
parent | 728e639d82099035fdfe69b716a54717ae7050e0 (diff) | |
download | gcc-22d34a2a50651d01669b6fbcdb9677c18d2197c5.zip gcc-22d34a2a50651d01669b6fbcdb9677c18d2197c5.tar.gz gcc-22d34a2a50651d01669b6fbcdb9677c18d2197c5.tar.bz2 |
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<bool>): 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.
33 files changed, 568 insertions, 39 deletions
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index ab6d938..aa8623b 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 a954890..3778d5a 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<allocator_type>& __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<allocator_type>& __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 6095498..268fb9e 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<allocator_type>& __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<allocator_type>& __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 81361df..96d2a2f 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<allocator_type>& __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<allocator_type>& __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 535dbeb..cc87f11 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<allocator_type>& __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<allocator_type>& __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 8157981..1b9648e 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<allocator_type>& __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<allocator_type>& __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 ef98760..5d9d619 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<allocator_type>& __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<allocator_type>& __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 ccd1122..3da65c7 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<typename _Container::value_type, _Container>; template<typename _Container, typename _Allocator, - typename = _RequireNotAllocator<_Container>, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> queue(_Container, _Allocator) -> queue<typename _Container::value_type, _Container>; @@ -817,8 +816,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Compare, typename _Container, typename _Allocator, typename = _RequireNotAllocator<_Compare>, - typename = _RequireNotAllocator<_Container>, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> priority_queue(_Compare, _Container, _Allocator) -> priority_queue<typename _Container::value_type, _Container, _Compare>; #endif diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index a9b9695..f0dfa05 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<allocator_type>& __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<allocator_type>& __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 af234d6..f04fa6a 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<typename _Container::value_type, _Container>; template<typename _Container, typename _Allocator, - typename = _RequireNotAllocator<_Container>, - typename = _RequireAllocator<_Allocator>> + typename = _RequireNotAllocator<_Container>> stack(_Container, _Allocator) -> stack<typename _Container::value_type, _Container>; diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 296da43..2023581 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<allocator_type>& __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<allocator_type>& __m) noexcept( noexcept( vector(std::declval<vector&&>(), std::declval<const allocator_type&>(), std::declval<typename _Alloc_traits::is_always_equal>())) ) diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque index 574cab1..8e48111 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<value_type> __l, diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index b599e93..de30edb 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<allocator_type>& __a) : _Base(__x, __a) { } - list(list&& __x, const allocator_type& __a) + list(list&& __x, const __type_identity_t<allocator_type>& __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 c0153d0..9e142cf 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<allocator_type>& __a) : _Base(__m, __a) { } - map(map&& __m, const allocator_type& __a) + map(map&& __m, const __type_identity_t<allocator_type>& __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 9492934..a05b8a8 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<allocator_type>& __a) : _Base(__m, __a) { } - multimap(multimap&& __m, const allocator_type& __a) + multimap(multimap&& __m, const __type_identity_t<allocator_type>& __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 bb68d8c..a312ccf 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<allocator_type>& __a) : _Base(__m, __a) { } - multiset(multiset&& __m, const allocator_type& __a) + multiset(multiset&& __m, const __type_identity_t<allocator_type>& __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 cdf35ea..01da942 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<allocator_type>& __a) : _Base(__x, __a) { } - set(set&& __x, const allocator_type& __a) + set(set&& __x, const __type_identity_t<allocator_type>& __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 d30d750..03fd940 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<allocator_type>& __a) : _Base(__x, __a) { } - vector(vector&& __x, const allocator_type& __a) + vector(vector&& __x, const __type_identity_t<allocator_type>& __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 8a38351..5cb0a58 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 <deque> #include <testsuite_iterators.h> +#include <testsuite_allocator.h> template<typename T> using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::deque s4(1U, 2L, std::allocator<long>()); check_type<std::deque<long>>(s4); } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, Alloc<unsigned>>; + Pool* p = nullptr; + Deque d(p); + + std::deque s1(d, p); + check_type<Deque>(s1); + + std::deque s2(std::move(d), p); + check_type<Deque>(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 eb39682..701231d 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 <forward_list> #include <testsuite_iterators.h> +#include <testsuite_allocator.h> template<typename T> using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::forward_list s4(1U, 2L, std::allocator<long>()); check_type<std::forward_list<long>>(s4); } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, Alloc<unsigned>>; + Pool* p = nullptr; + Flist f(p); + + std::forward_list s1(f, p); + check_type<Flist>(s1); + + std::forward_list s2(std::move(f), p); + check_type<Flist>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc index 3ad1d3f..c747509 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 <list> #include <testsuite_iterators.h> +#include <testsuite_allocator.h> template<typename T> using input_iterator_seq @@ -67,3 +68,31 @@ test02() std::list s4(1U, 2L, std::allocator<long>()); check_type<std::list<long>>(s4); } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, Alloc<unsigned>>; + Pool* p = nullptr; + List l(p); + + std::list s1(l, p); + check_type<List>(s1); + + std::list s2(std::move(l), p); + check_type<List>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc index e72033c..f8e6e6e 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<int, double, std::less<int>, SimpleAllocator<value_type>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<std::pair<const unsigned, void*>>; + using Map = std::map<unsigned, void*, std::greater<>, PairAlloc>; + Pool* p = nullptr; + Map m(p); + + std::map s1(m, p); + check_type<Map>(s1); + + std::map s2(std::move(m), p); + check_type<Map>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc index ffc7502..f0699e2 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<int, double, std::less<int>, SimpleAllocator<value_type>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<std::pair<const unsigned, void*>>; + using MMap = std::multimap<unsigned, void*, std::greater<>, PairAlloc>; + Pool* p = nullptr; + MMap m(p); + + std::multimap s1(m, p); + check_type<MMap>(s1); + + std::multimap s2(std::move(m), p); + check_type<MMap>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc index 8b7a160..7f4581a6 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<int, std::less<int>, SimpleAllocator<value_type>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, std::greater<>, Alloc<unsigned>>; + Pool* p = nullptr; + MSet s(p); + + std::multiset s1(s, p); + check_type<MSet>(s1); + + std::multiset s2(std::move(s), p); + check_type<MSet>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc b/libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc index 05c4c57..816efab 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 <deque> #include <vector> #include <testsuite_iterators.h> +#include <testsuite_allocator.h> template<typename T, typename U> struct require_same; template<typename T> struct require_same<T, T> { using type = void; }; @@ -116,3 +117,39 @@ test02() std::priority_queue s14(seq.begin(), seq.end(), cmp, std::deque<short>{}); check_type<std::priority_queue<short, std::deque<short>, Cmp>>(s14); } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<short, Alloc<short>>; + using Cmp = std::greater<long>; + Pool* p = nullptr; + Vector v(p); + Cmp cmp; + + std::priority_queue q1(cmp, v, p); + check_type<std::priority_queue<short, Vector, Cmp>>(q1); + + std::priority_queue q2(cmp, std::move(v), p); + check_type<std::priority_queue<short, Vector, Cmp>>(q2); + + std::priority_queue q3(q1, p); + check_type<std::priority_queue<short, Vector, Cmp>>(q3); + + std::priority_queue q4(std::move(q1), p); + check_type<std::priority_queue<short, Vector, Cmp>>(q4); +} diff --git a/libstdc++-v3/testsuite/23_containers/queue/deduction.cc b/libstdc++-v3/testsuite/23_containers/queue/deduction.cc index ab28f83..2642ece 100644 --- a/libstdc++-v3/testsuite/23_containers/queue/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/queue/deduction.cc @@ -20,6 +20,7 @@ #include <queue> #include <deque> #include <list> +#include <testsuite_allocator.h> template<typename T, typename U> struct require_same; template<typename T> struct require_same<T, T> { using type = void; }; @@ -86,3 +87,36 @@ test02() std::queue s8(std::move(l), l.get_allocator()); check_type<std::queue<long, std::list<long>>>(s8); } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, Alloc<unsigned>>; + using List = std::list<long, Alloc<long>>; + Pool* p = nullptr; + Deque d(p); + List l(p); + + std::queue q1(d, p); + check_type<std::queue<unsigned, Deque>>(q1); + + std::queue q2(l, p); + check_type<std::queue<long, List>>(q2); + + std::queue q3(q2, p); + check_type<std::queue<long, List>>(q3); +} diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc index 14f36b7..d77b9fc 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<int, std::less<int>, SimpleAllocator<value_type>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, std::greater<>, Alloc<unsigned>>; + Pool* p = nullptr; + Set s(p); + + std::set s1(s, p); + check_type<Set>(s1); + + std::set s2(std::move(s), p); + check_type<Set>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/stack/deduction.cc b/libstdc++-v3/testsuite/23_containers/stack/deduction.cc index db8e31e..169a063 100644 --- a/libstdc++-v3/testsuite/23_containers/stack/deduction.cc +++ b/libstdc++-v3/testsuite/23_containers/stack/deduction.cc @@ -20,6 +20,7 @@ #include <stack> #include <deque> #include <list> +#include <testsuite_allocator.h> template<typename T, typename U> struct require_same; template<typename T> struct require_same<T, T> { using type = void; }; @@ -58,7 +59,7 @@ test01() void test02() - { +{ std::deque<unsigned> d; std::list<long> 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 0785447..8b69af8 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<int>, SimpleAllocator<std::pair<const int, double>>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<std::pair<const unsigned, void*>>; + using Hash = std::hash<unsigned long>; + using Eq = std::equal_to<>; + using UMap = std::unordered_map<unsigned, void*, Hash, Eq, PairAlloc>; + Pool* p = nullptr; + UMap m(p); + + std::unordered_map s1(m, p); + check_type<UMap>(s1); + + std::unordered_map s2(std::move(m), p); + check_type<UMap>(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 d8a6f51..e7e535b 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<int>, SimpleAllocator<std::pair<const int, double>>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<std::pair<const unsigned, void*>>; + using Hash = std::hash<unsigned long>; + using Eq = std::equal_to<>; + using UMMap = std::unordered_multimap<unsigned, void*, Hash, Eq, PairAlloc>; + Pool* p = nullptr; + UMMap m(p); + + std::unordered_multimap s1(m, p); + check_type<UMMap>(s1); + + std::unordered_multimap s2(std::move(m), p); + check_type<UMMap>(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 25c2715..22b7297 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<int>, SimpleAllocator<int>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned long>; + using Eq = std::equal_to<>; + using UMSet = std::unordered_multiset<unsigned, Hash, Eq, Alloc<unsigned>>; + Pool* p = nullptr; + UMSet s(p); + + std::unordered_multiset s1(s, p); + check_type<UMSet>(s1); + + std::unordered_multiset s2(std::move(s), p); + check_type<UMSet>(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 b8c45d2..db58581 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<int>, SimpleAllocator<int>>>); } + +template<typename T, typename U> struct require_same; +template<typename T> struct require_same<T, T> { using type = void; }; + +template<typename T, typename U> + typename require_same<T, U>::type + check_type(U&) { } + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned long>; + using Eq = std::equal_to<>; + using USet = std::unordered_set<unsigned, Hash, Eq, Alloc<unsigned>>; + Pool* p = nullptr; + USet s(p); + + std::unordered_set s1(s, p); + check_type<USet>(s1); + + std::unordered_set s2(std::move(s), p); + check_type<USet>(s2); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc b/libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc index 9f7b761..542a0d7 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 <vector> #include <testsuite_iterators.h> +#include <testsuite_allocator.h> template<typename T> using input_iterator_seq @@ -50,6 +51,24 @@ test01() } void +test01b() +{ + std::vector<bool> s0; + + std::vector s1 = s0; + check_type<std::vector<bool>>(s1); + + std::vector s2 = std::move(s0); + check_type<std::vector<bool>>(s2); + + const std::vector s3 = s0; + check_type<const std::vector<bool>>(s3); + + const std::vector s4 = s3; + check_type<const std::vector<bool>>(s4); +} + +void test02() { unsigned a[1] = {}; @@ -67,3 +86,59 @@ test02() std::vector s4(1U, 2L, std::allocator<long>()); check_type<std::vector<long>>(s4); } + +void +test02b() +{ + bool a[1] = {}; + input_iterator_seq<bool> seq(a); + + std::vector s1(seq.begin(), seq.end()); + check_type<std::vector<bool>>(s1); + + std::vector s2(seq.begin(), seq.end(), std::allocator<bool>()); + check_type<std::vector<bool>>(s2); + + std::vector s3(1U, true); + check_type<std::vector<bool>>(s3); + + std::vector s4(1U, true, std::allocator<bool>()); + check_type<std::vector<bool>>(s4); +} + +struct Pool; + +template<typename T> +struct Alloc : __gnu_test::SimpleAllocator<T> +{ + Alloc(Pool*) { } + + template<typename U> + Alloc(const Alloc<U>&) { } +}; + +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<unsigned, Alloc<unsigned>>; + Pool* p = nullptr; + Vector v(p); + + std::vector s1(v, p); + check_type<Vector>(s1); + + std::vector s2(std::move(v), p); + check_type<Vector>(s2); + + using BVector = std::vector<bool, Alloc<bool>>; + BVector b(p); + + std::vector s3(b, p); + check_type<BVector>(s3); + + std::vector s4(std::move(b), p); + check_type<BVector>(s4); +} |