1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
11 // XFAIL: availability-bad_optional_access-missing && !no-exceptions
15 // template<class F> constexpr auto and_then(F&&) &;
16 // template<class F> constexpr auto and_then(F&&) &&;
17 // template<class F> constexpr auto and_then(F&&) const&;
18 // template<class F> constexpr auto and_then(F&&) const&&;
23 #include "test_macros.h"
26 constexpr std::optional
<int> operator()(int&) { return 1; }
27 std::optional
<int> operator()(const int&) = delete;
28 std::optional
<int> operator()(int&&) = delete;
29 std::optional
<int> operator()(const int&&) = delete;
33 std::optional
<int> operator()(int&) = delete;
34 constexpr std::optional
<int> operator()(const int&) { return 1; }
35 std::optional
<int> operator()(int&&) = delete;
36 std::optional
<int> operator()(const int&&) = delete;
40 std::optional
<int> operator()(int&) = delete;
41 std::optional
<int> operator()(const int&) = delete;
42 constexpr std::optional
<int> operator()(int&&) { return 1; }
43 std::optional
<int> operator()(const int&&) = delete;
47 std::optional
<int> operator()(int&) = delete;
48 std::optional
<int> operator()(const int&) = delete;
49 std::optional
<int> operator()(int&&) = delete;
50 constexpr std::optional
<int> operator()(const int&&) { return 1; }
54 constexpr std::optional
<int> operator()(int) & { return 1; }
55 std::optional
<int> operator()(int) const& = delete;
56 std::optional
<int> operator()(int) && = delete;
57 std::optional
<int> operator()(int) const&& = delete;
61 std::optional
<int> operator()(int) & = delete;
62 constexpr std::optional
<int> operator()(int) const& { return 1; }
63 std::optional
<int> operator()(int) && = delete;
64 std::optional
<int> operator()(int) const&& = delete;
68 std::optional
<int> operator()(int) & = delete;
69 std::optional
<int> operator()(int) const& = delete;
70 constexpr std::optional
<int> operator()(int) && { return 1; }
71 std::optional
<int> operator()(int) const&& = delete;
75 std::optional
<int> operator()(int) & = delete;
76 std::optional
<int> operator()(int) const& = delete;
77 std::optional
<int> operator()(int) && = delete;
78 constexpr std::optional
<int> operator()(int) const&& { return 1; }
82 constexpr std::optional
<int> operator()(int&) { return std::nullopt
; }
83 std::optional
<int> operator()(const int&) = delete;
84 std::optional
<int> operator()(int&&) = delete;
85 std::optional
<int> operator()(const int&&) = delete;
89 std::optional
<int> operator()(int&) = delete;
90 constexpr std::optional
<int> operator()(const int&) { return std::nullopt
; }
91 std::optional
<int> operator()(int&&) = delete;
92 std::optional
<int> operator()(const int&&) = delete;
96 std::optional
<int> operator()(int&) = delete;
97 std::optional
<int> operator()(const int&) = delete;
98 constexpr std::optional
<int> operator()(int&&) { return std::nullopt
; }
99 std::optional
<int> operator()(const int&&) = delete;
103 std::optional
<int> operator()(int&) = delete;
104 std::optional
<int> operator()(const int&) = delete;
105 std::optional
<int> operator()(int&&) = delete;
106 constexpr std::optional
<int> operator()(const int&&) { return std::nullopt
; }
110 constexpr std::optional
<int> operator()(int) & { return std::nullopt
; }
111 std::optional
<int> operator()(int) const& = delete;
112 std::optional
<int> operator()(int) && = delete;
113 std::optional
<int> operator()(int) const&& = delete;
117 std::optional
<int> operator()(int) & = delete;
118 constexpr std::optional
<int> operator()(int) const& { return std::nullopt
; }
119 std::optional
<int> operator()(int) && = delete;
120 std::optional
<int> operator()(int) const&& = delete;
124 std::optional
<int> operator()(int) & = delete;
125 std::optional
<int> operator()(int) const& = delete;
126 constexpr std::optional
<int> operator()(int) && { return std::nullopt
; }
127 std::optional
<int> operator()(int) const&& = delete;
130 struct NORVCRefQual
{
131 std::optional
<int> operator()(int) & = delete;
132 std::optional
<int> operator()(int) const& = delete;
133 std::optional
<int> operator()(int) && = delete;
134 constexpr std::optional
<int> operator()(int) const&& { return std::nullopt
; }
139 NoCopy(const NoCopy
&) { assert(false); }
140 std::optional
<int> operator()(const NoCopy
&&) { return 1; }
144 std::optional
<int> non_const() { return 1; }
147 constexpr void test_val_types() {
150 // Without & qualifier on F's operator()
152 std::optional
<int> i
{0};
153 assert(i
.and_then(LVal
{}) == 1);
154 assert(i
.and_then(NOLVal
{}) == std::nullopt
);
155 ASSERT_SAME_TYPE(decltype(i
.and_then(LVal
{})), std::optional
<int>);
158 //With & qualifier on F's operator()
160 std::optional
<int> i
{0};
162 assert(i
.and_then(l
) == 1);
164 assert(i
.and_then(nl
) == std::nullopt
);
165 ASSERT_SAME_TYPE(decltype(i
.and_then(l
)), std::optional
<int>);
169 // Test const& overload
171 // Without & qualifier on F's operator()
173 const std::optional
<int> i
{0};
174 assert(i
.and_then(CLVal
{}) == 1);
175 assert(i
.and_then(NOCLVal
{}) == std::nullopt
);
176 ASSERT_SAME_TYPE(decltype(i
.and_then(CLVal
{})), std::optional
<int>);
179 //With & qualifier on F's operator()
181 const std::optional
<int> i
{0};
183 assert(i
.and_then(l
) == 1);
184 const NOCRefQual nl
{};
185 assert(i
.and_then(nl
) == std::nullopt
);
186 ASSERT_SAME_TYPE(decltype(i
.and_then(l
)), std::optional
<int>);
192 // Without & qualifier on F's operator()
194 std::optional
<int> i
{0};
195 assert(std::move(i
).and_then(RVal
{}) == 1);
196 assert(std::move(i
).and_then(NORVal
{}) == std::nullopt
);
197 ASSERT_SAME_TYPE(decltype(std::move(i
).and_then(RVal
{})), std::optional
<int>);
200 //With & qualifier on F's operator()
202 std::optional
<int> i
{0};
203 assert(i
.and_then(RVRefQual
{}) == 1);
204 assert(i
.and_then(NORVRefQual
{}) == std::nullopt
);
205 ASSERT_SAME_TYPE(decltype(i
.and_then(RVRefQual
{})), std::optional
<int>);
209 // Test const&& overload
211 // Without & qualifier on F's operator()
213 const std::optional
<int> i
{0};
214 assert(std::move(i
).and_then(CRVal
{}) == 1);
215 assert(std::move(i
).and_then(NOCRVal
{}) == std::nullopt
);
216 ASSERT_SAME_TYPE(decltype(std::move(i
).and_then(CRVal
{})), std::optional
<int>);
219 //With & qualifier on F's operator()
221 const std::optional
<int> i
{0};
222 const RVCRefQual l
{};
223 assert(i
.and_then(std::move(l
)) == 1);
224 const NORVCRefQual nl
{};
225 assert(i
.and_then(std::move(nl
)) == std::nullopt
);
226 ASSERT_SAME_TYPE(decltype(i
.and_then(std::move(l
))), std::optional
<int>);
231 // check that the lambda body is not instantiated during overload resolution
232 constexpr void test_sfinae() {
233 std::optional
<NonConst
> opt
{};
234 auto l
= [](auto&& x
) { return x
.non_const(); };
236 std::move(opt
).and_then(l
);
239 constexpr bool test() {
241 std::optional
<int> opt
{};
242 const auto& copt
= opt
;
244 const auto never_called
= [](int) {
246 return std::optional
<int>{};
249 opt
.and_then(never_called
);
250 std::move(opt
).and_then(never_called
);
251 copt
.and_then(never_called
);
252 std::move(copt
).and_then(never_called
);
254 std::optional
<NoCopy
> nc
;
255 const auto& cnc
= nc
;
256 std::move(cnc
).and_then(NoCopy
{});
257 std::move(nc
).and_then(NoCopy
{});
262 int main(int, char**) {
264 static_assert(test());