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
25struct 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
39bool B::constructed = false;
40
41struct 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
55bool C::constructed = false;
56
57struct 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
72bool D::constructed = false;
73
74struct 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
89bool E::constructed = false;
90
91struct 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
112bool F::constructed = false;
113
114#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
115
116int 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