1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // <memory>
11 
12 // template <class OuterAlloc, class... InnerAllocs>
13 //   class scoped_allocator_adaptor
14 
15 // template <class T, class... Args> void construct(T* p, Args&&... args);
16 
17 #include <scoped_allocator>
18 #include <cassert>
19 #include <string>
20 
21 #include "allocators.h"
22 
23 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
24 
25 struct B
26 {
27     static bool constructed;
28 
29     typedef A1<B> allocator_type;
30 
31     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 
47     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 
63     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 
80     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 
97     explicit F(int i, int j)
98     {
99         assert(i == 1);
100         assert(j == 2);
101     }
102 
103     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 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
115 
116 int main()
117 {
118 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
119 
120     {
121         typedef std::scoped_allocator_adaptor<A1<std::string>> A;
122         A a;
123         char buf[100];
124         typedef std::string S;
125         S* s = (S*)buf;
126         a.construct(s, 4, 'c');
127         assert(*s == "cccc");
128         s->~S();
129     }
130 
131     {
132         typedef std::scoped_allocator_adaptor<A1<B>> A;
133         A a(A1<B>(5));
134         char buf[100];
135         typedef B S;
136         S* s = (S*)buf;
137         a.construct(s, 6);
138         assert(S::constructed);
139         s->~S();
140     }
141 
142     {
143         typedef std::scoped_allocator_adaptor<A1<int>, A2<C>> A;
144         A a(A1<int>(5), A2<C>(7));
145         char buf[100];
146         typedef C S;
147         S* s = (S*)buf;
148         a.construct(s, 8);
149         assert(S::constructed);
150         s->~S();
151     }
152 
153     {
154         typedef std::scoped_allocator_adaptor<A1<int>, A2<D>> A;
155         A a(A1<int>(5), A2<D>(3));
156         char buf[100];
157         typedef D S;
158         S* s = (S*)buf;
159         a.construct(s, 1, 2);
160         assert(S::constructed);
161         s->~S();
162     }
163 
164     {
165         typedef std::scoped_allocator_adaptor<A3<E>, A2<E>> K;
166         typedef std::scoped_allocator_adaptor<K, A1<E>> A;
167         A a(K(), A1<E>(50));
168         char buf[100];
169         typedef E S;
170         S* s = (S*)buf;
171         A3<E>::constructed = false;
172         a.construct(s, 1, 2);
173         assert(S::constructed);
174         assert(A3<E>::constructed);
175         s->~S();
176     }
177 
178     {
179         typedef std::scoped_allocator_adaptor<A3<F>, A2<F>> K;
180         typedef std::scoped_allocator_adaptor<K, A1<F>> A;
181         A a(K(), A1<F>(50));
182         char buf[100];
183         typedef F S;
184         S* s = (S*)buf;
185         A3<F>::constructed = false;
186         a.construct(s, 1, 2);
187         assert(!S::constructed);
188         assert(A3<F>::constructed);
189         s->~S();
190     }
191 
192 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
193 }
194