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 U, class... Args>
13 //   void optional<T>::emplace(initializer_list<U> il, Args&&... args);
14 
15 #include <experimental/optional>
16 #include <type_traits>
17 #include <cassert>
18 #include <vector>
19 
20 #if _LIBCPP_STD_VER > 11
21 
22 using std::experimental::optional;
23 
24 class X
25 {
26     int i_;
27     int j_ = 0;
28 public:
29     static bool dtor_called;
X()30     constexpr X() : i_(0) {}
X(int i)31     constexpr X(int i) : i_(i) {}
X(std::initializer_list<int> il)32     constexpr X(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
~X()33     ~X() {dtor_called = true;}
34 
operator ==(const X & x,const X & y)35     friend constexpr bool operator==(const X& x, const X& y)
36         {return x.i_ == y.i_ && x.j_ == y.j_;}
37 };
38 
39 bool X::dtor_called = false;
40 
41 class Y
42 {
43     int i_;
44     int j_ = 0;
45 public:
Y()46     constexpr Y() : i_(0) {}
Y(int i)47     constexpr Y(int i) : i_(i) {}
Y(std::initializer_list<int> il)48     constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
49 
operator ==(const Y & x,const Y & y)50     friend constexpr bool operator==(const Y& x, const Y& y)
51         {return x.i_ == y.i_ && x.j_ == y.j_;}
52 };
53 
54 class Z
55 {
56     int i_;
57     int j_ = 0;
58 public:
59     static bool dtor_called;
Z()60     constexpr Z() : i_(0) {}
Z(int i)61     constexpr Z(int i) : i_(i) {}
Z(std::initializer_list<int> il)62     constexpr Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
63         {throw 6;}
~Z()64     ~Z() {dtor_called = true;}
65 
operator ==(const Z & x,const Z & y)66     friend constexpr bool operator==(const Z& x, const Z& y)
67         {return x.i_ == y.i_ && x.j_ == y.j_;}
68 };
69 
70 bool Z::dtor_called = false;
71 
72 #endif  // _LIBCPP_STD_VER > 11
73 
main()74 int main()
75 {
76 #if _LIBCPP_STD_VER > 11
77     {
78         X x;
79         {
80             optional<X> opt(x);
81             assert(X::dtor_called == false);
82             opt.emplace({1, 2});
83             assert(X::dtor_called == true);
84             assert(*opt == X({1, 2}));
85         }
86     }
87     {
88         optional<std::vector<int>> opt;
89         opt.emplace({1, 2, 3}, std::allocator<int>());
90         assert(static_cast<bool>(opt) == true);
91         assert(*opt == std::vector<int>({1, 2, 3}));
92     }
93     {
94         optional<Y> opt;
95         opt.emplace({1, 2});
96         assert(static_cast<bool>(opt) == true);
97         assert(*opt == Y({1, 2}));
98     }
99     {
100         Z z;
101         optional<Z> opt(z);
102         try
103         {
104             assert(static_cast<bool>(opt) == true);
105             assert(Z::dtor_called == false);
106             opt.emplace({1, 2});
107         }
108         catch (int i)
109         {
110             assert(i == 6);
111             assert(static_cast<bool>(opt) == false);
112             assert(Z::dtor_called == true);
113         }
114     }
115 #endif  // _LIBCPP_STD_VER > 11
116 }
117