1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // UNSUPPORTED: c++03, c++11, c++14
10 // <optional>
11
12 // template <class U, class... Args>
13 // T& optional<T>::emplace(initializer_list<U> il, Args&&... args);
14
15 #include <optional>
16 #include <type_traits>
17 #include <cassert>
18 #include <vector>
19
20 #include "test_macros.h"
21
22 using std::optional;
23
24 class X
25 {
26 int i_;
27 int j_ = 0;
28 bool* dtor_called_;
29 public:
X(bool & dtor_called)30 constexpr X(bool& dtor_called) : i_(0), dtor_called_(&dtor_called) {}
X(int i,bool & dtor_called)31 constexpr X(int i, bool& dtor_called) : i_(i), dtor_called_(&dtor_called) {}
X(std::initializer_list<int> il,bool & dtor_called)32 constexpr X(std::initializer_list<int> il, bool& dtor_called)
33 : i_(il.begin()[0]), j_(il.begin()[1]), dtor_called_(&dtor_called) {}
~X()34 TEST_CONSTEXPR_CXX20 ~X() {*dtor_called_ = true;}
35
operator ==(const X & x,const X & y)36 friend constexpr bool operator==(const X& x, const X& y)
37 {return x.i_ == y.i_ && x.j_ == y.j_;}
38 };
39
40 class Y
41 {
42 int i_;
43 int j_ = 0;
44 public:
Y()45 constexpr Y() : i_(0) {}
Y(int i)46 constexpr Y(int i) : i_(i) {}
Y(std::initializer_list<int> il)47 constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
48
operator ==(const Y & x,const Y & y)49 friend constexpr bool operator==(const Y& x, const Y& y)
50 {return x.i_ == y.i_ && x.j_ == y.j_;}
51 };
52
53 class Z
54 {
55 int i_;
56 int j_ = 0;
57 public:
58 static bool dtor_called;
Z()59 Z() : i_(0) {}
Z(int i)60 Z(int i) : i_(i) {}
Z(std::initializer_list<int> il)61 Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
62 { TEST_THROW(6);}
~Z()63 ~Z() {dtor_called = true;}
64
operator ==(const Z & x,const Z & y)65 friend bool operator==(const Z& x, const Z& y)
66 {return x.i_ == y.i_ && x.j_ == y.j_;}
67 };
68
69 bool Z::dtor_called = false;
70
check_X()71 TEST_CONSTEXPR_CXX20 bool check_X()
72 {
73 bool dtor_called = false;
74 X x(dtor_called);
75 optional<X> opt(x);
76 assert(dtor_called == false);
77 auto &v = opt.emplace({1, 2}, dtor_called);
78 static_assert( std::is_same_v<X&, decltype(v)>, "" );
79 assert(dtor_called);
80 assert(*opt == X({1, 2}, dtor_called));
81 assert(&v == &*opt);
82 return true;
83 }
84
check_Y()85 TEST_CONSTEXPR_CXX20 bool check_Y()
86 {
87 optional<Y> opt;
88 auto &v = opt.emplace({1, 2});
89 static_assert( std::is_same_v<Y&, decltype(v)>, "" );
90 assert(static_cast<bool>(opt) == true);
91 assert(*opt == Y({1, 2}));
92 assert(&v == &*opt);
93 return true;
94 }
95
main(int,char **)96 int main(int, char**)
97 {
98 {
99 check_X();
100 #if TEST_STD_VER > 17
101 static_assert(check_X());
102 #endif
103 }
104 {
105 optional<std::vector<int>> opt;
106 auto &v = opt.emplace({1, 2, 3}, std::allocator<int>());
107 static_assert( std::is_same_v<std::vector<int>&, decltype(v)>, "" );
108 assert(static_cast<bool>(opt) == true);
109 assert(*opt == std::vector<int>({1, 2, 3}));
110 assert(&v == &*opt);
111 }
112 {
113 check_Y();
114 #if TEST_STD_VER > 17
115 static_assert(check_Y());
116 #endif
117 }
118 #ifndef TEST_HAS_NO_EXCEPTIONS
119 {
120 Z z;
121 optional<Z> opt(z);
122 try
123 {
124 assert(static_cast<bool>(opt) == true);
125 assert(Z::dtor_called == false);
126 auto &v = opt.emplace({1, 2});
127 static_assert( std::is_same_v<Z&, decltype(v)>, "" );
128 assert(false);
129 }
130 catch (int i)
131 {
132 assert(i == 6);
133 assert(static_cast<bool>(opt) == false);
134 assert(Z::dtor_called == true);
135 }
136 }
137 #endif
138
139 return 0;
140 }
141