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) {}
34 X(const X&) = default;
35 X& operator=(const X&) = default;
~X()36 TEST_CONSTEXPR_CXX20 ~X() {*dtor_called_ = true;}
37
operator ==(const X & x,const X & y)38 friend constexpr bool operator==(const X& x, const X& y)
39 {return x.i_ == y.i_ && x.j_ == y.j_;}
40 };
41
42 class Y
43 {
44 int i_;
45 int j_ = 0;
46 public:
Y()47 constexpr Y() : i_(0) {}
Y(int i)48 constexpr Y(int i) : i_(i) {}
Y(std::initializer_list<int> il)49 constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
50
operator ==(const Y & x,const Y & y)51 friend constexpr bool operator==(const Y& x, const Y& y)
52 {return x.i_ == y.i_ && x.j_ == y.j_;}
53 };
54
55 class Z
56 {
57 int i_;
58 int j_ = 0;
59 public:
60 static bool dtor_called;
Z()61 Z() : i_(0) {}
Z(int i)62 Z(int i) : i_(i) {}
Z(std::initializer_list<int> il)63 Z(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1])
64 { TEST_THROW(6);}
65 Z(const Z&) = default;
66 Z& operator=(const Z&) = default;
~Z()67 ~Z() {dtor_called = true;}
68
operator ==(const Z & x,const Z & y)69 friend bool operator==(const Z& x, const Z& y)
70 {return x.i_ == y.i_ && x.j_ == y.j_;}
71 };
72
73 bool Z::dtor_called = false;
74
check_X()75 TEST_CONSTEXPR_CXX20 bool check_X()
76 {
77 bool dtor_called = false;
78 X x(dtor_called);
79 optional<X> opt(x);
80 assert(dtor_called == false);
81 auto &v = opt.emplace({1, 2}, dtor_called);
82 static_assert( std::is_same_v<X&, decltype(v)>, "" );
83 assert(dtor_called);
84 assert(*opt == X({1, 2}, dtor_called));
85 assert(&v == &*opt);
86 return true;
87 }
88
check_Y()89 TEST_CONSTEXPR_CXX20 bool check_Y()
90 {
91 optional<Y> opt;
92 auto &v = opt.emplace({1, 2});
93 static_assert( std::is_same_v<Y&, decltype(v)>, "" );
94 assert(static_cast<bool>(opt) == true);
95 assert(*opt == Y({1, 2}));
96 assert(&v == &*opt);
97 return true;
98 }
99
main(int,char **)100 int main(int, char**)
101 {
102 {
103 check_X();
104 #if TEST_STD_VER > 17
105 static_assert(check_X());
106 #endif
107 }
108 {
109 optional<std::vector<int>> opt;
110 auto &v = opt.emplace({1, 2, 3}, std::allocator<int>());
111 static_assert( std::is_same_v<std::vector<int>&, decltype(v)>, "" );
112 assert(static_cast<bool>(opt) == true);
113 assert(*opt == std::vector<int>({1, 2, 3}));
114 assert(&v == &*opt);
115 }
116 {
117 check_Y();
118 #if TEST_STD_VER > 17
119 static_assert(check_Y());
120 #endif
121 }
122 #ifndef TEST_HAS_NO_EXCEPTIONS
123 {
124 Z z;
125 optional<Z> opt(z);
126 try
127 {
128 assert(static_cast<bool>(opt) == true);
129 assert(Z::dtor_called == false);
130 auto &v = opt.emplace({1, 2});
131 static_assert( std::is_same_v<Z&, decltype(v)>, "" );
132 assert(false);
133 }
134 catch (int i)
135 {
136 assert(i == 6);
137 assert(static_cast<bool>(opt) == false);
138 assert(Z::dtor_called == true);
139 }
140 }
141 #endif
142
143 return 0;
144 }
145