• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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