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 // <optional>
11 
12 // template <class... Args> void optional<T>::emplace(Args&&... args);
13 
14 #include <experimental/optional>
15 #include <type_traits>
16 #include <cassert>
17 #include <memory>
18 
19 #if _LIBCPP_STD_VER > 11
20 
21 using std::experimental::optional;
22 
23 class X
24 {
25     int i_;
26     int j_ = 0;
27 public:
X()28     X() : i_(0) {}
X(int i)29     X(int i) : i_(i) {}
X(int i,int j)30     X(int i, int j) : i_(i), j_(j) {}
31 
operator ==(const X & x,const X & y)32     friend bool operator==(const X& x, const X& y)
33         {return x.i_ == y.i_ && x.j_ == y.j_;}
34 };
35 
36 class Y
37 {
38 public:
39     static bool dtor_called;
40     Y() = default;
~Y()41     ~Y() {dtor_called = true;}
42 };
43 
44 bool Y::dtor_called = false;
45 
46 class Z
47 {
48 public:
49     static bool dtor_called;
50     Z() = default;
Z(int)51     Z(int) {throw 6;}
~Z()52     ~Z() {dtor_called = true;}
53 };
54 
55 bool Z::dtor_called = false;
56 
57 #endif  // _LIBCPP_STD_VER > 11
58 
main()59 int main()
60 {
61 #if _LIBCPP_STD_VER > 11
62     {
63         optional<int> opt;
64         opt.emplace();
65         assert(static_cast<bool>(opt) == true);
66         assert(*opt == 0);
67     }
68     {
69         optional<int> opt;
70         opt.emplace(1);
71         assert(static_cast<bool>(opt) == true);
72         assert(*opt == 1);
73     }
74     {
75         optional<int> opt(2);
76         opt.emplace();
77         assert(static_cast<bool>(opt) == true);
78         assert(*opt == 0);
79     }
80     {
81         optional<int> opt(2);
82         opt.emplace(1);
83         assert(static_cast<bool>(opt) == true);
84         assert(*opt == 1);
85     }
86     {
87         optional<X> opt;
88         opt.emplace();
89         assert(static_cast<bool>(opt) == true);
90         assert(*opt == X());
91     }
92     {
93         optional<X> opt;
94         opt.emplace(1);
95         assert(static_cast<bool>(opt) == true);
96         assert(*opt == X(1));
97     }
98     {
99         optional<X> opt;
100         opt.emplace(1, 2);
101         assert(static_cast<bool>(opt) == true);
102         assert(*opt == X(1, 2));
103     }
104     {
105         optional<X> opt(X{3});
106         opt.emplace();
107         assert(static_cast<bool>(opt) == true);
108         assert(*opt == X());
109     }
110     {
111         optional<X> opt(X{3});
112         opt.emplace(1);
113         assert(static_cast<bool>(opt) == true);
114         assert(*opt == X(1));
115     }
116     {
117         optional<X> opt(X{3});
118         opt.emplace(1, 2);
119         assert(static_cast<bool>(opt) == true);
120         assert(*opt == X(1, 2));
121     }
122     {
123         Y y;
124         {
125             optional<Y> opt(y);
126             assert(Y::dtor_called == false);
127             opt.emplace();
128             assert(Y::dtor_called == true);
129         }
130     }
131     {
132         Z z;
133         optional<Z> opt(z);
134         try
135         {
136             assert(static_cast<bool>(opt) == true);
137             assert(Z::dtor_called == false);
138             opt.emplace(1);
139         }
140         catch (int i)
141         {
142             assert(i == 6);
143             assert(static_cast<bool>(opt) == false);
144             assert(Z::dtor_called == true);
145         }
146     }
147 #endif  // _LIBCPP_STD_VER > 11
148 }
149