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
22using std::optional;
23
24class X
25{
26 int i_;
27 int j_ = 0;
28 bool* dtor_called_;
29public:
30 constexpr X(bool& dtor_called) : i_(0), dtor_called_(&dtor_called) {}
31 constexpr X(int i, bool& dtor_called) : i_(i), dtor_called_(&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;
36 TEST_CONSTEXPR_CXX20 ~X() {*dtor_called_ = true;}
37
38 friend constexpr bool operator==(const X& x, const X& y)
39 {return x.i_ == y.i_ && x.j_ == y.j_;}
40};
41
42class Y
43{
44 int i_;
45 int j_ = 0;
46public:
47 constexpr Y() : i_(0) {}
48 constexpr Y(int i) : i_(i) {}
49 constexpr Y(std::initializer_list<int> il) : i_(il.begin()[0]), j_(il.begin()[1]) {}
50
51 friend constexpr bool operator==(const Y& x, const Y& y)
52 {return x.i_ == y.i_ && x.j_ == y.j_;}
53};
54
55class Z
56{
57 int i_;
58 int j_ = 0;
59public:
60 static bool dtor_called;
61 Z() : i_(0) {}
62 Z(int i) : i_(i) {}
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;
67 ~Z() {dtor_called = true;}
68
69 friend bool operator==(const Z& x, const Z& y)
70 {return x.i_ == y.i_ && x.j_ == y.j_;}
71};
72
73bool Z::dtor_called = false;
74
75TEST_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
89TEST_CONSTEXPR_CXX20 bool check_Y()
90{
91 optional<Y> opt;
92 auto &v = opt.emplace(il: {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
100int 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(il: {1, 2, 3}, args: 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(il: {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

source code of libcxx/test/std/utilities/optional/optional.object/optional.object.assign/emplace_initializer_list.pass.cpp