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
28template <class T>
29struct A
30{
31 typedef T value_type;
32
33};
34
35template <class T>
36struct B
37{
38 typedef T value_type;
39
40 TEST_CONSTEXPR_CXX20 B(int& count) : count_(count) {}
41
42#if TEST_STD_VER >= 11
43 template <class U, class ...Args>
44 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
58struct A0
59{
60 TEST_CONSTEXPR_CXX20 A0(int* count) {++*count;}
61};
62
63struct A1
64{
65 TEST_CONSTEXPR_CXX20 A1(int* count, char c)
66 {
67 assert(c == 'c');
68 ++*count;
69 }
70};
71
72struct A2
73{
74 TEST_CONSTEXPR_CXX20 A2(int* count, char c, int i)
75 {
76 assert(c == 'd');
77 assert(i == 5);
78 ++*count;
79 }
80};
81
82TEST_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(n: 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(p: a0, t: 1);
93 }
94 {
95 int A1_count = 0;
96 A<A1> a;
97 std::allocator<A1> alloc;
98 A1* a1 = alloc.allocate(n: 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(p: a1, t: 1);
103 }
104 {
105 int A2_count = 0;
106 A<A2> a;
107 std::allocator<A2> alloc;
108 A2* a2 = alloc.allocate(n: 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(p: a2, t: 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(n: 1);
120 std::allocator_traits<Alloc>::construct(a&: a, p: vt, args: nullptr);
121 alloc.deallocate(p: vt, t: 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
169int 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

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