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 // <memory>
10 
11 // template <class Alloc>
12 // struct allocator_traits
13 // {
14 //     template <class Ptr, class... Args>
15 //     static constexpr void construct(allocator_type& a, Ptr p, Args&&... args);
16 //     ...
17 // };
18 
19 #include <memory>
20 #include <new>
21 #include <type_traits>
22 #include <cassert>
23 #include <utility>
24 
25 #include "test_macros.h"
26 #include "incomplete_type_helper.h"
27 
28 template <class T>
29 struct A
30 {
31     typedef T value_type;
32 
33 };
34 
35 template <class T>
36 struct B
37 {
38     typedef T value_type;
39 
BB40     TEST_CONSTEXPR_CXX20 B(int& count) : count_(count) {}
41 
42 #if TEST_STD_VER >= 11
43     template <class U, class ...Args>
constructB44     TEST_CONSTEXPR_CXX20 void construct(U* p, Args&& ...args)
45     {
46         ++count_;
47 #if TEST_STD_VER > 17
48         std::construct_at(p, std::forward<Args>(args)...);
49 #else
50         ::new ((void*)p) U(std::forward<Args>(args)...);
51 #endif
52     }
53 #endif
54 
55     int& count_;
56 };
57 
58 struct A0
59 {
A0A060     TEST_CONSTEXPR_CXX20 A0(int* count) {++*count;}
61 };
62 
63 struct A1
64 {
A1A165     TEST_CONSTEXPR_CXX20 A1(int* count, char c)
66     {
67         assert(c == 'c');
68         ++*count;
69     }
70 };
71 
72 struct A2
73 {
A2A274     TEST_CONSTEXPR_CXX20 A2(int* count, char c, int i)
75     {
76         assert(c == 'd');
77         assert(i == 5);
78         ++*count;
79     }
80 };
81 
test()82 TEST_CONSTEXPR_CXX20 bool test()
83 {
84     {
85         int A0_count = 0;
86         A<A0> a;
87         std::allocator<A0> alloc;
88         A0* a0 = alloc.allocate(1);
89         assert(A0_count == 0);
90         std::allocator_traits<A<A0> >::construct(a, a0, &A0_count);
91         assert(A0_count == 1);
92         alloc.deallocate(a0, 1);
93     }
94     {
95         int A1_count = 0;
96         A<A1> a;
97         std::allocator<A1> alloc;
98         A1* a1 = alloc.allocate(1);
99         assert(A1_count == 0);
100         std::allocator_traits<A<A1> >::construct(a, a1, &A1_count, 'c');
101         assert(A1_count == 1);
102         alloc.deallocate(a1, 1);
103     }
104     {
105         int A2_count = 0;
106         A<A2> a;
107         std::allocator<A2> alloc;
108         A2* a2 = alloc.allocate(1);
109         assert(A2_count == 0);
110         std::allocator_traits<A<A2> >::construct(a, a2, &A2_count, 'd', 5);
111         assert(A2_count == 1);
112         alloc.deallocate(a2, 1);
113     }
114     {
115       typedef IncompleteHolder* VT;
116       typedef A<VT> Alloc;
117       Alloc a;
118       std::allocator<VT> alloc;
119       VT* vt = alloc.allocate(1);
120       std::allocator_traits<Alloc>::construct(a, vt, nullptr);
121       alloc.deallocate(vt, 1);
122     }
123 
124 #if TEST_STD_VER >= 11
125     {
126         int A0_count = 0;
127         int b_construct = 0;
128         B<A0> b(b_construct);
129         std::allocator<A0> alloc;
130         A0* a0 = alloc.allocate(1);
131         assert(A0_count == 0);
132         assert(b_construct == 0);
133         std::allocator_traits<B<A0> >::construct(b, a0, &A0_count);
134         assert(A0_count == 1);
135         assert(b_construct == 1);
136         alloc.deallocate(a0, 1);
137     }
138     {
139         int A1_count = 0;
140         int b_construct = 0;
141         B<A1> b(b_construct);
142         std::allocator<A1> alloc;
143         A1* a1 = alloc.allocate(1);
144         assert(A1_count == 0);
145         assert(b_construct == 0);
146         std::allocator_traits<B<A1> >::construct(b, a1, &A1_count, 'c');
147         assert(A1_count == 1);
148         assert(b_construct == 1);
149         alloc.deallocate(a1, 1);
150     }
151     {
152         int A2_count = 0;
153         int b_construct = 0;
154         B<A2> b(b_construct);
155         std::allocator<A2> alloc;
156         A2* a2 = alloc.allocate(1);
157         assert(A2_count == 0);
158         assert(b_construct == 0);
159         std::allocator_traits<B<A2> >::construct(b, a2, &A2_count, 'd', 5);
160         assert(A2_count == 1);
161         assert(b_construct == 1);
162         alloc.deallocate(a2, 1);
163     }
164 #endif
165 
166     return true;
167 }
168 
main(int,char **)169 int main(int, char**)
170 {
171     test();
172 
173 #if TEST_STD_VER > 17
174     static_assert(test());
175 #endif
176 
177     return 0;
178 }
179