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