1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 
11 // <memory>
12 
13 // template <class OuterAlloc, class... InnerAllocs>
14 //   class scoped_allocator_adaptor
15 
16 // template <class T, class... Args> void construct(T* p, Args&&... args);
17 
18 #include <scoped_allocator>
19 #include <cassert>
20 #include <string>
21 
22 #include "test_macros.h"
23 #include "allocators.h"
24 
25 struct B
26 {
27     static bool constructed;
28 
29     typedef A1<B> allocator_type;
30 
BB31     explicit B(std::allocator_arg_t, const allocator_type& a, int i)
32     {
33         assert(a.id() == 5);
34         assert(i == 6);
35         constructed = true;
36     }
37 };
38 
39 bool B::constructed = false;
40 
41 struct C
42 {
43     static bool constructed;
44 
45     typedef std::scoped_allocator_adaptor<A2<C>> allocator_type;
46 
CC47     explicit C(std::allocator_arg_t, const allocator_type& a, int i)
48     {
49         assert(a.id() == 7);
50         assert(i == 8);
51         constructed = true;
52     }
53 };
54 
55 bool C::constructed = false;
56 
57 struct D
58 {
59     static bool constructed;
60 
61     typedef std::scoped_allocator_adaptor<A2<D>> allocator_type;
62 
DD63     explicit D(int i, int j, const allocator_type& a)
64     {
65         assert(i == 1);
66         assert(j == 2);
67         assert(a.id() == 3);
68         constructed = true;
69     }
70 };
71 
72 bool D::constructed = false;
73 
74 struct E
75 {
76     static bool constructed;
77 
78     typedef std::scoped_allocator_adaptor<A1<E>> allocator_type;
79 
EE80     explicit E(int i, int j, const allocator_type& a)
81     {
82         assert(i == 1);
83         assert(j == 2);
84         assert(a.id() == 50);
85         constructed = true;
86     }
87 };
88 
89 bool E::constructed = false;
90 
91 struct F
92 {
93     static bool constructed;
94 
95     typedef std::scoped_allocator_adaptor<A2<F>> allocator_type;
96 
FF97     explicit F(int i, int j)
98     {
99         assert(i == 1);
100         assert(j == 2);
101     }
102 
FF103     explicit F(int i, int j, const allocator_type& a)
104     {
105         assert(i == 1);
106         assert(j == 2);
107         assert(a.id() == 50);
108         constructed = true;
109     }
110 };
111 
112 bool F::constructed = false;
113 
114 struct G
115 {
116     static bool constructed;
117 
118     typedef std::allocator<G> allocator_type;
119 
GG120     G(std::allocator_arg_t, allocator_type&&) { assert(false); }
GG121     G(allocator_type&) { constructed = true; }
122 };
123 
124 bool G::constructed = false;
125 
main(int,char **)126 int main(int, char**)
127 {
128 
129     {
130         typedef std::scoped_allocator_adaptor<A1<std::string>> A;
131         A a;
132         char buf[100];
133         typedef std::string S;
134         S* s = (S*)buf;
135         a.construct(s, 4, 'c');
136         assert(*s == "cccc");
137         s->~S();
138     }
139 
140     {
141         typedef std::scoped_allocator_adaptor<A1<B>> A;
142         A a(A1<B>(5));
143         char buf[100];
144         typedef B S;
145         S* s = (S*)buf;
146         a.construct(s, 6);
147         assert(S::constructed);
148         s->~S();
149     }
150 
151     {
152         typedef std::scoped_allocator_adaptor<A1<int>, A2<C>> A;
153         A a(A1<int>(5), A2<C>(7));
154         char buf[100];
155         typedef C S;
156         S* s = (S*)buf;
157         a.construct(s, 8);
158         assert(S::constructed);
159         s->~S();
160     }
161 
162     {
163         typedef std::scoped_allocator_adaptor<A1<int>, A2<D>> A;
164         A a(A1<int>(5), A2<D>(3));
165         char buf[100];
166         typedef D S;
167         S* s = (S*)buf;
168         a.construct(s, 1, 2);
169         assert(S::constructed);
170         s->~S();
171     }
172 
173     {
174         typedef std::scoped_allocator_adaptor<A3<E>, A2<E>> K;
175         typedef std::scoped_allocator_adaptor<K, A1<E>> A;
176         A a(K(), A1<E>(50));
177         char buf[100];
178         typedef E S;
179         S* s = (S*)buf;
180         A3<E>::constructed = false;
181         a.construct(s, 1, 2);
182         assert(S::constructed);
183         assert(A3<E>::constructed);
184         s->~S();
185     }
186 
187     {
188         typedef std::scoped_allocator_adaptor<A3<F>, A2<F>> K;
189         typedef std::scoped_allocator_adaptor<K, A1<F>> A;
190         A a(K(), A1<F>(50));
191         char buf[100];
192         typedef F S;
193         S* s = (S*)buf;
194         A3<F>::constructed = false;
195         a.construct(s, 1, 2);
196         assert(!S::constructed);
197         assert(A3<F>::constructed);
198         s->~S();
199     }
200 
201     // LWG 2586
202     // Test that is_constructible uses an lvalue ref so the correct constructor
203     // is picked.
204     {
205         std::scoped_allocator_adaptor<G::allocator_type> sa;
206         G* ptr = sa.allocate(1);
207         sa.construct(ptr);
208         assert(G::constructed);
209         sa.deallocate(ptr, 1);
210     }
211 
212   return 0;
213 }
214