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
25struct B {
26 static bool constructed;
27
28 typedef A1<B> allocator_type;
29
30 explicit B(std::allocator_arg_t, const allocator_type& a, int i) {
31 assert(a.id() == 5);
32 assert(i == 6);
33 constructed = true;
34 }
35};
36
37bool B::constructed = false;
38
39struct C {
40 static bool constructed;
41
42 typedef std::scoped_allocator_adaptor<A2<C>> allocator_type;
43
44 explicit C(std::allocator_arg_t, const allocator_type& a, int i) {
45 assert(a.id() == 7);
46 assert(i == 8);
47 constructed = true;
48 }
49};
50
51bool C::constructed = false;
52
53struct D {
54 static bool constructed;
55
56 typedef std::scoped_allocator_adaptor<A2<D>> allocator_type;
57
58 explicit D(int i, int j, const allocator_type& a) {
59 assert(i == 1);
60 assert(j == 2);
61 assert(a.id() == 3);
62 constructed = true;
63 }
64};
65
66bool D::constructed = false;
67
68struct E {
69 static bool constructed;
70
71 typedef std::scoped_allocator_adaptor<A1<E>> allocator_type;
72
73 explicit E(int i, int j, const allocator_type& a) {
74 assert(i == 1);
75 assert(j == 2);
76 assert(a.id() == 50);
77 constructed = true;
78 }
79};
80
81bool E::constructed = false;
82
83struct F {
84 static bool constructed;
85
86 typedef std::scoped_allocator_adaptor<A2<F>> allocator_type;
87
88 explicit F(int i, int j) {
89 assert(i == 1);
90 assert(j == 2);
91 }
92
93 explicit F(int i, int j, const allocator_type& a) {
94 assert(i == 1);
95 assert(j == 2);
96 assert(a.id() == 50);
97 constructed = true;
98 }
99};
100
101bool F::constructed = false;
102
103struct G {
104 static bool constructed;
105
106 typedef std::scoped_allocator_adaptor<std::allocator<G>> allocator_type;
107
108 G(std::allocator_arg_t, allocator_type&&) { assert(false); }
109 G(const allocator_type&) { constructed = true; }
110};
111
112bool G::constructed = false;
113
114int main(int, char**) {
115 {
116 typedef std::scoped_allocator_adaptor<A1<std::string>> A;
117 A a;
118 char buf[100];
119 typedef std::string S;
120 S* s = (S*)buf;
121 a.construct(s, 4, 'c');
122 assert(*s == "cccc");
123 s->~S();
124 }
125
126 {
127 typedef std::scoped_allocator_adaptor<A1<B>> A;
128 A a(A1<B>(5));
129 char buf[100];
130 typedef B S;
131 S* s = (S*)buf;
132 a.construct(s, 6);
133 assert(S::constructed);
134 s->~S();
135 }
136
137 {
138 typedef std::scoped_allocator_adaptor<A1<int>, A2<C>> A;
139 A a(A1<int>(5), A2<C>(7));
140 char buf[100];
141 typedef C S;
142 S* s = (S*)buf;
143 a.construct(s, 8);
144 assert(S::constructed);
145 s->~S();
146 }
147
148 {
149 typedef std::scoped_allocator_adaptor<A1<int>, A2<D>> A;
150 A a(A1<int>(5), A2<D>(3));
151 char buf[100];
152 typedef D S;
153 S* s = (S*)buf;
154 a.construct(s, 1, 2);
155 assert(S::constructed);
156 s->~S();
157 }
158
159 {
160 typedef std::scoped_allocator_adaptor<A3<E>, A2<E>> K;
161 typedef std::scoped_allocator_adaptor<K, A1<E>> A;
162 A a(K(), A1<E>(50));
163 char buf[100];
164 typedef E S;
165 S* s = (S*)buf;
166 A3<E>::constructed = false;
167 a.construct(s, 1, 2);
168 assert(S::constructed);
169 assert(A3<E>::constructed);
170 s->~S();
171 }
172
173 {
174 typedef std::scoped_allocator_adaptor<A3<F>, A2<F>> K;
175 typedef std::scoped_allocator_adaptor<K, A1<F>> A;
176 A a(K(), A1<F>(50));
177 char buf[100];
178 typedef F S;
179 S* s = (S*)buf;
180 A3<F>::constructed = false;
181 a.construct(s, 1, 2);
182 assert(!S::constructed);
183 assert(A3<F>::constructed);
184 s->~S();
185 }
186
187 // LWG 2586
188 // Test that is_constructible uses an lvalue ref so the correct constructor
189 // is picked.
190 {
191 G::allocator_type sa;
192 G* ptr = sa.allocate(n: 1);
193 sa.construct(p: ptr);
194 assert(G::constructed);
195 sa.deallocate(p: ptr, n: 1);
196 }
197
198 return 0;
199}
200

source code of libcxx/test/std/utilities/allocator.adaptor/allocator.adaptor.members/construct.pass.cpp