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> void 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 opt.emplace();
55 assert(static_cast<bool>(opt) == true);
56 assert(*opt == T(0));
57 }
58 {
59 Opt opt;
60 opt.emplace(1);
61 assert(static_cast<bool>(opt) == true);
62 assert(*opt == T(1));
63 }
64 {
65 Opt opt(2);
66 opt.emplace();
67 assert(static_cast<bool>(opt) == true);
68 assert(*opt == T(0));
69 }
70 {
71 Opt opt(2);
72 opt.emplace(1);
73 assert(static_cast<bool>(opt) == true);
74 assert(*opt == T(1));
75 }
76 }
77
78
79 template <class T>
test_multi_arg()80 void test_multi_arg()
81 {
82 test_one_arg<T>();
83 using Opt = std::optional<T>;
84 {
85 Opt opt;
86 opt.emplace(101, 41);
87 assert(static_cast<bool>(opt) == true);
88 assert(*opt == T(101, 41));
89 }
90 {
91 Opt opt;
92 opt.emplace({1, 2, 3, 4});
93 assert(static_cast<bool>(opt) == true);
94 assert(*opt == T(4)); // T sets its value to the size of the init list
95 }
96 {
97 Opt opt;
98 opt.emplace({1, 2, 3, 4, 5}, 6);
99 assert(static_cast<bool>(opt) == true);
100 assert(*opt == T(5)); // T sets its value to the size of the init list
101 }
102 }
103
104 template <class T>
test_on_test_type()105 void test_on_test_type() {
106
107 T::reset();
108 optional<T> opt;
109 assert(T::alive == 0);
110 {
111 T::reset_constructors();
112 opt.emplace();
113 assert(T::alive == 1);
114 assert(T::constructed == 1);
115 assert(T::default_constructed == 1);
116 assert(T::destroyed == 0);
117 assert(static_cast<bool>(opt) == true);
118 assert(*opt == T());
119 }
120 {
121 T::reset_constructors();
122 opt.emplace();
123 assert(T::alive == 1);
124 assert(T::constructed == 1);
125 assert(T::default_constructed == 1);
126 assert(T::destroyed == 1);
127 assert(static_cast<bool>(opt) == true);
128 assert(*opt == T());
129 }
130 {
131 T::reset_constructors();
132 opt.emplace(101);
133 assert(T::alive == 1);
134 assert(T::constructed == 1);
135 assert(T::value_constructed == 1);
136 assert(T::destroyed == 1);
137 assert(static_cast<bool>(opt) == true);
138 assert(*opt == T(101));
139 }
140 {
141 T::reset_constructors();
142 opt.emplace(-10, 99);
143 assert(T::alive == 1);
144 assert(T::constructed == 1);
145 assert(T::value_constructed == 1);
146 assert(T::destroyed == 1);
147 assert(static_cast<bool>(opt) == true);
148 assert(*opt == T(-10, 99));
149 }
150 {
151 T::reset_constructors();
152 opt.emplace(-10, 99);
153 assert(T::alive == 1);
154 assert(T::constructed == 1);
155 assert(T::value_constructed == 1);
156 assert(T::destroyed == 1);
157 assert(static_cast<bool>(opt) == true);
158 assert(*opt == T(-10, 99));
159 }
160 {
161 T::reset_constructors();
162 opt.emplace({-10, 99, 42, 1});
163 assert(T::alive == 1);
164 assert(T::constructed == 1);
165 assert(T::value_constructed == 1);
166 assert(T::destroyed == 1);
167 assert(static_cast<bool>(opt) == true);
168 assert(*opt == T(4)); // size of the initializer list
169 }
170 {
171 T::reset_constructors();
172 opt.emplace({-10, 99, 42, 1}, 42);
173 assert(T::alive == 1);
174 assert(T::constructed == 1);
175 assert(T::value_constructed == 1);
176 assert(T::destroyed == 1);
177 assert(static_cast<bool>(opt) == true);
178 assert(*opt == T(4)); // size of the initializer list
179 }
180 }
181
182
183
main()184 int main()
185 {
186 {
187 test_on_test_type<TestTypes::TestType>();
188 test_on_test_type<ExplicitTestTypes::TestType>();
189 }
190 {
191 using T = int;
192 test_one_arg<T>();
193 test_one_arg<const T>();
194 }
195 {
196 using T = ConstexprTestTypes::TestType;
197 test_multi_arg<T>();
198 }
199 {
200 using T = ExplicitConstexprTestTypes::TestType;
201 test_multi_arg<T>();
202 }
203 {
204 using T = TrivialTestTypes::TestType;
205 test_multi_arg<T>();
206 }
207 {
208 using T = ExplicitTrivialTestTypes::TestType;
209 test_multi_arg<T>();
210 }
211 {
212 optional<const int> opt;
213 opt.emplace(42);
214 assert(*opt == 42);
215 opt.emplace();
216 assert(*opt == 0);
217 }
218 #ifndef TEST_HAS_NO_EXCEPTIONS
219 Y::dtor_called = false;
220 {
221 Y y;
222 optional<Y> opt(y);
223 try
224 {
225 assert(static_cast<bool>(opt) == true);
226 assert(Y::dtor_called == false);
227 opt.emplace(1);
228 }
229 catch (int i)
230 {
231 assert(i == 6);
232 assert(static_cast<bool>(opt) == false);
233 assert(Y::dtor_called == true);
234 }
235 }
236 #endif
237 }
238