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 // UNSUPPORTED: c++98, c++03, c++11, c++14
11 // <optional>
12
13 // template <class... Args> T& optional<T>::emplace(Args&&... args);
14
15 #include <optional>
16 #include <type_traits>
17 #include <cassert>
18 #include <memory>
19
20 #include "test_macros.h"
21 #include "archetypes.hpp"
22
23 using std::optional;
24
25 class X
26 {
27 int i_;
28 int j_ = 0;
29 public:
X()30 X() : i_(0) {}
X(int i)31 X(int i) : i_(i) {}
X(int i,int j)32 X(int i, int j) : i_(i), j_(j) {}
33
operator ==(const X & x,const X & y)34 friend bool operator==(const X& x, const X& y)
35 {return x.i_ == y.i_ && x.j_ == y.j_;}
36 };
37
38 class Y
39 {
40 public:
41 static bool dtor_called;
42 Y() = default;
Y(int)43 Y(int) { TEST_THROW(6);}
~Y()44 ~Y() {dtor_called = true;}
45 };
46
47 bool Y::dtor_called = false;
48
49 template <class T>
test_one_arg()50 void test_one_arg() {
51 using Opt = std::optional<T>;
52 {
53 Opt opt;
54 auto & v = opt.emplace();
55 static_assert( std::is_same_v<T&, decltype(v)>, "" );
56 assert(static_cast<bool>(opt) == true);
57 assert(*opt == T(0));
58 assert(&v == &*opt);
59 }
60 {
61 Opt opt;
62 auto & v = opt.emplace(1);
63 static_assert( std::is_same_v<T&, decltype(v)>, "" );
64 assert(static_cast<bool>(opt) == true);
65 assert(*opt == T(1));
66 assert(&v == &*opt);
67 }
68 {
69 Opt opt(2);
70 auto & v = opt.emplace();
71 static_assert( std::is_same_v<T&, decltype(v)>, "" );
72 assert(static_cast<bool>(opt) == true);
73 assert(*opt == T(0));
74 assert(&v == &*opt);
75 }
76 {
77 Opt opt(2);
78 auto & v = opt.emplace(1);
79 static_assert( std::is_same_v<T&, decltype(v)>, "" );
80 assert(static_cast<bool>(opt) == true);
81 assert(*opt == T(1));
82 assert(&v == &*opt);
83 }
84 }
85
86
87 template <class T>
test_multi_arg()88 void test_multi_arg()
89 {
90 test_one_arg<T>();
91 using Opt = std::optional<T>;
92 {
93 Opt opt;
94 auto &v = opt.emplace(101, 41);
95 static_assert( std::is_same_v<T&, decltype(v)>, "" );
96 assert(static_cast<bool>(opt) == true);
97 assert( v == T(101, 41));
98 assert(*opt == T(101, 41));
99 }
100 {
101 Opt opt;
102 auto &v = opt.emplace({1, 2, 3, 4});
103 static_assert( std::is_same_v<T&, decltype(v)>, "" );
104 assert(static_cast<bool>(opt) == true);
105 assert( v == T(4)); // T sets its value to the size of the init list
106 assert(*opt == T(4));
107 }
108 {
109 Opt opt;
110 auto &v = opt.emplace({1, 2, 3, 4, 5}, 6);
111 static_assert( std::is_same_v<T&, decltype(v)>, "" );
112 assert(static_cast<bool>(opt) == true);
113 assert( v == T(5)); // T sets its value to the size of the init list
114 assert(*opt == T(5)); // T sets its value to the size of the init list
115 }
116 }
117
118 template <class T>
test_on_test_type()119 void test_on_test_type() {
120
121 T::reset();
122 optional<T> opt;
123 assert(T::alive == 0);
124 {
125 T::reset_constructors();
126 auto &v = opt.emplace();
127 static_assert( std::is_same_v<T&, decltype(v)>, "" );
128 assert(T::alive == 1);
129 assert(T::constructed == 1);
130 assert(T::default_constructed == 1);
131 assert(T::destroyed == 0);
132 assert(static_cast<bool>(opt) == true);
133 assert(*opt == T());
134 assert(&v == &*opt);
135 }
136 {
137 T::reset_constructors();
138 auto &v = opt.emplace();
139 static_assert( std::is_same_v<T&, decltype(v)>, "" );
140 assert(T::alive == 1);
141 assert(T::constructed == 1);
142 assert(T::default_constructed == 1);
143 assert(T::destroyed == 1);
144 assert(static_cast<bool>(opt) == true);
145 assert(*opt == T());
146 assert(&v == &*opt);
147 }
148 {
149 T::reset_constructors();
150 auto &v = opt.emplace(101);
151 static_assert( std::is_same_v<T&, decltype(v)>, "" );
152 assert(T::alive == 1);
153 assert(T::constructed == 1);
154 assert(T::value_constructed == 1);
155 assert(T::destroyed == 1);
156 assert(static_cast<bool>(opt) == true);
157 assert(*opt == T(101));
158 assert(&v == &*opt);
159 }
160 {
161 T::reset_constructors();
162 auto &v = opt.emplace(-10, 99);
163 static_assert( std::is_same_v<T&, decltype(v)>, "" );
164 assert(T::alive == 1);
165 assert(T::constructed == 1);
166 assert(T::value_constructed == 1);
167 assert(T::destroyed == 1);
168 assert(static_cast<bool>(opt) == true);
169 assert(*opt == T(-10, 99));
170 assert(&v == &*opt);
171 }
172 {
173 T::reset_constructors();
174 auto &v = opt.emplace(-10, 99);
175 static_assert( std::is_same_v<T&, decltype(v)>, "" );
176 assert(T::alive == 1);
177 assert(T::constructed == 1);
178 assert(T::value_constructed == 1);
179 assert(T::destroyed == 1);
180 assert(static_cast<bool>(opt) == true);
181 assert(*opt == T(-10, 99));
182 assert(&v == &*opt);
183 }
184 {
185 T::reset_constructors();
186 auto &v = opt.emplace({-10, 99, 42, 1});
187 static_assert( std::is_same_v<T&, decltype(v)>, "" );
188 assert(T::alive == 1);
189 assert(T::constructed == 1);
190 assert(T::value_constructed == 1);
191 assert(T::destroyed == 1);
192 assert(static_cast<bool>(opt) == true);
193 assert(*opt == T(4)); // size of the initializer list
194 assert(&v == &*opt);
195 }
196 {
197 T::reset_constructors();
198 auto &v = opt.emplace({-10, 99, 42, 1}, 42);
199 static_assert( std::is_same_v<T&, decltype(v)>, "" );
200 assert(T::alive == 1);
201 assert(T::constructed == 1);
202 assert(T::value_constructed == 1);
203 assert(T::destroyed == 1);
204 assert(static_cast<bool>(opt) == true);
205 assert(*opt == T(4)); // size of the initializer list
206 assert(&v == &*opt);
207 }
208 }
209
210
211
main()212 int main()
213 {
214 {
215 test_on_test_type<TestTypes::TestType>();
216 test_on_test_type<ExplicitTestTypes::TestType>();
217 }
218 {
219 using T = int;
220 test_one_arg<T>();
221 test_one_arg<const T>();
222 }
223 {
224 using T = ConstexprTestTypes::TestType;
225 test_multi_arg<T>();
226 }
227 {
228 using T = ExplicitConstexprTestTypes::TestType;
229 test_multi_arg<T>();
230 }
231 {
232 using T = TrivialTestTypes::TestType;
233 test_multi_arg<T>();
234 }
235 {
236 using T = ExplicitTrivialTestTypes::TestType;
237 test_multi_arg<T>();
238 }
239 {
240 optional<const int> opt;
241 auto &v = opt.emplace(42);
242 static_assert( std::is_same_v<const int&, decltype(v)>, "" );
243 assert(*opt == 42);
244 assert( v == 42);
245 opt.emplace();
246 assert(*opt == 0);
247 }
248 #ifndef TEST_HAS_NO_EXCEPTIONS
249 Y::dtor_called = false;
250 {
251 Y y;
252 optional<Y> opt(y);
253 try
254 {
255 assert(static_cast<bool>(opt) == true);
256 assert(Y::dtor_called == false);
257 auto &v = opt.emplace(1);
258 static_assert( std::is_same_v<Y&, decltype(v)>, "" );
259 assert(false);
260 }
261 catch (int i)
262 {
263 assert(i == 6);
264 assert(static_cast<bool>(opt) == false);
265 assert(Y::dtor_called == true);
266 }
267 }
268 #endif
269 }
270