1 // Copyright (C) 2019 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library.  This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3.  If not see
16 // <http://www.gnu.org/licenses/>.
17 
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do run { target c++2a } }
20 
21 // P0591R4 makes uses-allocator construction apply recursively for nested pairs
22 
23 #include <scoped_allocator>
24 #include <vector>
25 #include <testsuite_hooks.h>
26 #include <testsuite_allocator.h>
27 
28 struct X
29 {
30   using allocator_type = __gnu_test::uneq_allocator<int>;
31 
XX32   X(int personality) : a(personality) { }
XX33   X(std::allocator_arg_t, allocator_type a) : a(a) { }
XX34   X(std::allocator_arg_t, allocator_type a, const X&) : a(a) { }
35 
36   allocator_type a;
37 };
38 
39 void
test01()40 test01()
41 {
42   using value_type = std::pair<std::pair<X, int>, std::pair<int, X>>;
43   using scoped_alloc
44     = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator<value_type>>;
45 
46   const scoped_alloc a(10);
47   std::vector<value_type, scoped_alloc> v(a);
48   VERIFY( v.get_allocator().get_personality() == a.get_personality() );
49 
50   value_type val( { X(1), 2 }, { 3, X(4) } );
51   v.push_back(val);
52   X& x1 = v.back().first.first;
53   VERIFY( x1.a.get_personality() != val.first.first.a.get_personality() );
54   VERIFY( x1.a.get_personality() == a.get_personality() );
55 
56   X& x2 = v.back().second.second;
57   VERIFY( x2.a.get_personality() != val.second.second.a.get_personality() );
58   VERIFY( x2.a.get_personality() == a.get_personality() );
59 
60   // Check other members of the pairs are correctly initialized too:
61   VERIFY( v.back().first.second == val.first.second );
62   VERIFY( v.back().second.first == val.second.first );
63 }
64 
65 void
test02()66 test02()
67 {
68   using value_type = std::pair<std::pair<X, int>, std::pair<int, X>>;
69   using scoped_alloc
70     = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator<value_type>,
71 				    X::allocator_type>;
72 
73   const scoped_alloc a(10, 20);
74   std::vector<value_type, scoped_alloc> v(a);
75   VERIFY( v.get_allocator().get_personality() == a.get_personality() );
76 
77   value_type val( { X(1), 2 }, { 3, X(4) } );
78   v.push_back(val);
79   X& x1 = v.back().first.first;
80   VERIFY( x1.a.get_personality() != val.first.first.a.get_personality() );
81   VERIFY( x1.a.get_personality() != a.get_personality() );
82   VERIFY( x1.a.get_personality() == a.inner_allocator().get_personality() );
83 
84   X& x2 = v.back().second.second;
85   VERIFY( x2.a.get_personality() != val.second.second.a.get_personality() );
86   VERIFY( x2.a.get_personality() != a.get_personality() );
87   VERIFY( x2.a.get_personality() == a.inner_allocator().get_personality() );
88 
89   // Check other members of the pairs are correctly initialized too:
90   VERIFY( v.back().first.second == val.first.second );
91   VERIFY( v.back().second.first == val.second.first );
92 }
93 
94 int
main()95 main()
96 {
97   test01();
98   test02();
99 }
100