]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement P1518R2 for container deduction guides
authorJonathan Wakely <jwakely@redhat.com>
Mon, 4 Oct 2021 13:04:20 +0000 (14:04 +0100)
committerJonathan Wakely <jwakely@redhat.com>
Mon, 4 Oct 2021 14:23:28 +0000 (15:23 +0100)
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:
libstdc++-v3/include/bits/forward_list.h
libstdc++-v3/include/bits/stl_bvector.h
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/bits/stl_map.h
libstdc++-v3/include/bits/stl_multimap.h
libstdc++-v3/include/bits/stl_multiset.h
libstdc++-v3/include/bits/stl_queue.h
libstdc++-v3/include/bits/stl_set.h
libstdc++-v3/include/bits/stl_stack.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/debug/deque
libstdc++-v3/include/debug/list
libstdc++-v3/include/debug/map.h
libstdc++-v3/include/debug/multimap.h
libstdc++-v3/include/debug/multiset.h
libstdc++-v3/include/debug/set.h
libstdc++-v3/include/debug/vector
libstdc++-v3/testsuite/23_containers/deque/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/forward_list/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/list/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/map/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/multimap/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/multiset/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/priority_queue/deduction.cc
libstdc++-v3/testsuite/23_containers/queue/deduction.cc
libstdc++-v3/testsuite/23_containers/set/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/stack/deduction.cc
libstdc++-v3/testsuite/23_containers/unordered_map/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/unordered_multimap/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/unordered_multiset/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/unordered_set/cons/deduction.cc
libstdc++-v3/testsuite/23_containers/vector/cons/deduction.cc

index ab6d9389194975446e2971bf97229a471b3f8950..aa8623b4c19752fbb7d81bd9acedcc51a241665c 100644 (file)
@@ -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{})
index a954890ff20279b513f25584118ad942a033914d..3778d5a770a5cf85e2c80563de1e4c4ded3b9b6f 100644 (file)
@@ -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());
index 6095498d440f5a9ef7653be4d6aeaad7ca163382..268fb9ef4058099dd650d308a94de647587a4c25 100644 (file)
@@ -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{})
       { }
 
index 81361dfa4d5b68977bd9c3940748a5fcff13dc23..96d2a2f0f69d71949e4e429e35a463f9594ff186 100644 (file)
@@ -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{})
index 535dbeb745a9861b6e118e2fdefd7536e8230645..cc87f11fb11e3578454d4496009f4c274689b64b 100644 (file)
@@ -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)) { }
index 8157981d0bcd3bac9a3ce6e2b6c63a86928481d7..1b9648e3bd449e3674c0a6244c50439b93e42ddf 100644 (file)
@@ -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)) { }
index ef987600733e9ed98d71993a7ec10abf2493955c..5d9d6195ae169273d7f91e9fd0ed70c14399abfa 100644 (file)
@@ -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)) { }
index ccd1122f848d642391ce86b3ed5320fdd204e814..3da65c78eb80fafd7b6ac10af2fd75e7ae832074 100644 (file)
@@ -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
index a9b9695bca83789311309abff695a7a4c208f1dc..f0dfa05886f2c5b842e6058ed71568448105d930 100644 (file)
@@ -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)) { }
index af234d6899c238dd89547b6001d5ef8605d91501..f04fa6af47984e9e8bc90ffb1f64777661ea9a96 100644 (file)
@@ -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>;
 
index 296da43822a559dd356273abd46390debaa56a8a..2023581bc79cd08e809f4477ea05f26cf967cc90 100644 (file)
@@ -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>())) )
index 574cab11c6f6c3eedf88f689275104ededc7e9a1..8e4811149d2d36082c20cf88ffe251d91fca059b 100644 (file)
@@ -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,
index b599e93d147cf86f4f3bbff5cec574dd3b63f7eb..de30edb19c2406cdaec152403c74a76544c7db53 100644 (file)
@@ -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 )
index c0153d09abeb4c56ad73c2b47a636e8ef2a7ff8b..9e142cf70239a0c9fee379ce7213958e3f72dbcd 100644 (file)
@@ -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) { }
index 94929344a9d343be34bf383457d1f04b13bbda27..a05b8a8493e67e2912a5777efd833154c6d7a06a 100644 (file)
@@ -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) { }
index bb68d8c8f180a8abb0624f1ea37a0ae29063beca..a312ccf6f5066732706dc6141765d8254122ff06 100644 (file)
@@ -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) { }
index cdf35ea539676591d68b44f2839c746b9e3de32e..01da942eb78056d8476132bf22c774669e0f11e4 100644 (file)
@@ -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) { }
index d30d750a6f07092e6d7994e4e0b53f22d35261aa..03fd9405cc91ddee77788fb2bf9e7dc4225f96df 100644 (file)
@@ -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 )
index 8a38351e524217841583e309fbf3aa37fae3cf1b..5cb0a58a22c821e5bcfc8a081d6c3d7f3b4b379f 100644 (file)
@@ -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);
+}
index eb39682f483be6b8cc4895575b2fbeed5b7d2fb1..701231d12594d1aab9e277c1187b9c70ac402e39 100644 (file)
@@ -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);
+}
index 3ad1d3f6cb55caa998a8c593ace239e29408e8b8..c747509ffc51eb45b5fac4a34da00626d50664d1 100644 (file)
@@ -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);
+}
index e72033c38a6e0b2bec46436f33e305c2f8576d8b..f8e6e6e8b99427c88f89e0981d469db6fa861223 100644 (file)
@@ -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);
+}
index ffc7502d60cf978a919159c2ca99dc41784e520d..f0699e2eefc38fc95e455dd30febe596050b920b 100644 (file)
@@ -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);
+}
index 8b7a16042a4cc75b8801446bf9dd89f6de9a199a..7f4581a6aeb87d73f441fff09811aed54419574d 100644 (file)
@@ -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);
+}
index 05c4c570ad568b19b2ca2c9c93a35ab2a6c39b78..816efab85c78976941a3ac6d60c09589939216e6 100644 (file)
@@ -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);
+}
index ab28f83aa2bec452f51cab33ed76625d3197b8ca..2642ece2b1acdd8a7bd567ac10ac42afd969bad0 100644 (file)
@@ -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);
+}
index 14f36b7c05dd2583f5f44668dda0fbbbe34f0948..d77b9fcb73df8e53afa59c983b90525392fd6f6b 100644 (file)
@@ -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);
+}
index db8e31e2bdaae2e719c93b71b3d2b69eb81a3de9..169a063687b5bd8dc424e1d7c2d14e5ce90d12be 100644 (file)
@@ -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;
 
index 0785447a81bcd5a12c3220bdffb91b9e392716ae..8b69af896a25c09985ba9b1947230e31d10ef02c 100644 (file)
@@ -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);
+}
index d8a6f5136c98ed6af71932171d1cacc4ece465ff..e7e535b527a83b41b47c969553a7a24be05d3fd4 100644 (file)
@@ -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);
+}
index 25c2715ea262f1c7eaa232659ea8fef16f3a9a6e..22b729749e22adae7a7b1eea8d42c00f13f4b06e 100644 (file)
@@ -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);
+}
index b8c45d2993d6ba6c0a84ff0827fb13e7ef58132a..db5858132fce9be910d352a34b88e84339d9fc37 100644 (file)
@@ -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);
+}
index 9f7b7612c93c42cdbcad0c790d9201292002d6c7..542a0d7ff9329e2fd2f2eb3850dffc0102f894cd 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <vector>
 #include <testsuite_iterators.h>
+#include <testsuite_allocator.h>
 
 template<typename T>
   using input_iterator_seq
@@ -49,6 +50,24 @@ test01()
   check_type<const std::vector<unsigned>>(s4);
 }
 
+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()
 {
@@ -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);
+}