xref: /llvm-project/libcxx/test/std/utilities/expected/expected.expected/monadic/and_then.pass.cpp (revision cb4433b677a06ecbb3112f39d24b28f19b0d2626)
1acce2a31Syronglin //===----------------------------------------------------------------------===//
2acce2a31Syronglin //
3acce2a31Syronglin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4acce2a31Syronglin // See https://llvm.org/LICENSE.txt for license information.
5acce2a31Syronglin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6acce2a31Syronglin //
7acce2a31Syronglin //===----------------------------------------------------------------------===//
8acce2a31Syronglin 
9acce2a31Syronglin // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
10acce2a31Syronglin 
11acce2a31Syronglin // <expected>
12acce2a31Syronglin 
13acce2a31Syronglin // template<class F> constexpr auto and_then(F&& f) &;
14acce2a31Syronglin // template<class F> constexpr auto and_then(F&& f) const &;
15acce2a31Syronglin // template<class F> constexpr auto and_then(F&& f) &&;
16acce2a31Syronglin // template<class F> constexpr auto and_then(F&& f) const &&;
17acce2a31Syronglin 
18acce2a31Syronglin #include <cassert>
19acce2a31Syronglin #include <concepts>
20acce2a31Syronglin #include <expected>
21acce2a31Syronglin #include <memory>
22acce2a31Syronglin #include <type_traits>
23acce2a31Syronglin #include <utility>
24acce2a31Syronglin 
259f67143bSyronglin #include "../../types.h"
269f67143bSyronglin 
27acce2a31Syronglin struct LVal {
28acce2a31Syronglin   constexpr std::expected<int, int> operator()(int&) { return 1; }
29acce2a31Syronglin   std::expected<int, int> operator()(const int&)  = delete;
30acce2a31Syronglin   std::expected<int, int> operator()(int&&)       = delete;
31acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
32acce2a31Syronglin };
33acce2a31Syronglin 
34acce2a31Syronglin struct CLVal {
35acce2a31Syronglin   std::expected<int, int> operator()(int&) = delete;
36acce2a31Syronglin   constexpr std::expected<int, int> operator()(const int&) { return 1; }
37acce2a31Syronglin   std::expected<int, int> operator()(int&&)       = delete;
38acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
39acce2a31Syronglin };
40acce2a31Syronglin 
41acce2a31Syronglin struct RVal {
42acce2a31Syronglin   std::expected<int, int> operator()(int&)       = delete;
43acce2a31Syronglin   std::expected<int, int> operator()(const int&) = delete;
44acce2a31Syronglin   constexpr std::expected<int, int> operator()(int&&) { return 1; }
45acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
46acce2a31Syronglin };
47acce2a31Syronglin 
48acce2a31Syronglin struct CRVal {
49acce2a31Syronglin   std::expected<int, int> operator()(int&)       = delete;
50acce2a31Syronglin   std::expected<int, int> operator()(const int&) = delete;
51acce2a31Syronglin   std::expected<int, int> operator()(int&&)      = delete;
52acce2a31Syronglin   constexpr std::expected<int, int> operator()(const int&&) { return 1; }
53acce2a31Syronglin };
54acce2a31Syronglin 
55acce2a31Syronglin struct RefQual {
56acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) & { return 1; }
57acce2a31Syronglin   std::expected<int, int> operator()(int) const&  = delete;
58acce2a31Syronglin   std::expected<int, int> operator()(int) &&      = delete;
59acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
60acce2a31Syronglin };
61acce2a31Syronglin 
62acce2a31Syronglin struct CRefQual {
63acce2a31Syronglin   std::expected<int, int> operator()(int) & = delete;
64acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) const& { return 1; }
65acce2a31Syronglin   std::expected<int, int> operator()(int) &&      = delete;
66acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
67acce2a31Syronglin };
68acce2a31Syronglin 
69acce2a31Syronglin struct RVRefQual {
70acce2a31Syronglin   std::expected<int, int> operator()(int) &      = delete;
71acce2a31Syronglin   std::expected<int, int> operator()(int) const& = delete;
72acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) && { return 1; }
73acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
74acce2a31Syronglin };
75acce2a31Syronglin 
76acce2a31Syronglin struct RVCRefQual {
77acce2a31Syronglin   std::expected<int, int> operator()(int) &      = delete;
78acce2a31Syronglin   std::expected<int, int> operator()(int) const& = delete;
79acce2a31Syronglin   std::expected<int, int> operator()(int) &&     = delete;
80acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) const&& { return 1; }
81acce2a31Syronglin };
82acce2a31Syronglin 
83acce2a31Syronglin struct UnexpectedLVal {
84acce2a31Syronglin   constexpr std::expected<int, int> operator()(int&) { return std::expected<int, int>(std::unexpected<int>(5)); }
85acce2a31Syronglin   std::expected<int, int> operator()(const int&)  = delete;
86acce2a31Syronglin   std::expected<int, int> operator()(int&&)       = delete;
87acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
88acce2a31Syronglin };
89acce2a31Syronglin 
90acce2a31Syronglin struct UnexpectedCLVal {
91acce2a31Syronglin   std::expected<int, int> operator()(int&) = delete;
92acce2a31Syronglin   constexpr std::expected<int, int> operator()(const int&) { return std::expected<int, int>(std::unexpected<int>(5)); }
93acce2a31Syronglin   std::expected<int, int> operator()(int&&)       = delete;
94acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
95acce2a31Syronglin };
96acce2a31Syronglin 
97acce2a31Syronglin struct UnexpectedRVal {
98acce2a31Syronglin   std::expected<int, int> operator()(int&)       = delete;
99acce2a31Syronglin   std::expected<int, int> operator()(const int&) = delete;
100acce2a31Syronglin   constexpr std::expected<int, int> operator()(int&&) { return std::expected<int, int>(std::unexpected<int>(5)); }
101acce2a31Syronglin   std::expected<int, int> operator()(const int&&) = delete;
102acce2a31Syronglin };
103acce2a31Syronglin 
104acce2a31Syronglin struct UnexpectedCRVal {
105acce2a31Syronglin   std::expected<int, int> operator()(int&)       = delete;
106acce2a31Syronglin   std::expected<int, int> operator()(const int&) = delete;
107acce2a31Syronglin   std::expected<int, int> operator()(int&&)      = delete;
108acce2a31Syronglin   constexpr std::expected<int, int> operator()(const int&&) { return std::expected<int, int>(std::unexpected<int>(5)); }
109acce2a31Syronglin };
110acce2a31Syronglin 
111acce2a31Syronglin struct UnexpectedRefQual {
112acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) & { return std::expected<int, int>(std::unexpected<int>(5)); }
113acce2a31Syronglin   std::expected<int, int> operator()(int) const&  = delete;
114acce2a31Syronglin   std::expected<int, int> operator()(int) &&      = delete;
115acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
116acce2a31Syronglin };
117acce2a31Syronglin 
118acce2a31Syronglin struct UnexpectedCRefQual {
119acce2a31Syronglin   std::expected<int, int> operator()(int) & = delete;
120acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) const& { return std::expected<int, int>(std::unexpected<int>(5)); }
121acce2a31Syronglin   std::expected<int, int> operator()(int) &&      = delete;
122acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
123acce2a31Syronglin };
124acce2a31Syronglin 
125acce2a31Syronglin struct UnexpectedRVRefQual {
126acce2a31Syronglin   std::expected<int, int> operator()(int) &      = delete;
127acce2a31Syronglin   std::expected<int, int> operator()(int) const& = delete;
128acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) && { return std::expected<int, int>(std::unexpected<int>(5)); }
129acce2a31Syronglin   std::expected<int, int> operator()(int) const&& = delete;
130acce2a31Syronglin };
131acce2a31Syronglin 
132acce2a31Syronglin struct UnexpectedRVCRefQual {
133acce2a31Syronglin   std::expected<int, int> operator()(int) &      = delete;
134acce2a31Syronglin   std::expected<int, int> operator()(int) const& = delete;
135acce2a31Syronglin   std::expected<int, int> operator()(int) &&     = delete;
136acce2a31Syronglin   constexpr std::expected<int, int> operator()(int) const&& { return std::expected<int, int>(std::unexpected<int>(5)); }
137acce2a31Syronglin };
138acce2a31Syronglin 
139acce2a31Syronglin struct NonCopyable {
140acce2a31Syronglin   constexpr NonCopyable(int) {}
141acce2a31Syronglin   NonCopyable(const NonCopyable&) = delete;
142acce2a31Syronglin };
143acce2a31Syronglin 
144acce2a31Syronglin struct NonMovable {
145acce2a31Syronglin   constexpr NonMovable(int) {}
146acce2a31Syronglin   NonMovable(NonMovable&&) = delete;
147acce2a31Syronglin };
148acce2a31Syronglin 
149acce2a31Syronglin struct NonConst {
150acce2a31Syronglin   std::expected<int, int> non_const() { return 1; }
151acce2a31Syronglin };
152acce2a31Syronglin 
153acce2a31Syronglin template <class E, class F>
154acce2a31Syronglin concept has_and_then = requires(E&& e, F&& f) {
155acce2a31Syronglin   {std::forward<E>(e).and_then(std::forward<F>(f))};
156acce2a31Syronglin };
157acce2a31Syronglin 
1589f67143bSyronglin // clang-format off
159acce2a31Syronglin static_assert( has_and_then<std::expected<int, int>&, std::expected<int, int>(int&)>);
160acce2a31Syronglin static_assert(!has_and_then<std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(int&)>);
161acce2a31Syronglin static_assert( has_and_then<const std::expected<int, int>&, std::expected<int, int>(const int&)>);
162acce2a31Syronglin static_assert(!has_and_then<const std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(const int&)>);
163acce2a31Syronglin static_assert( has_and_then<std::expected<int, int>&&, std::expected<int, int>(int)>);
164acce2a31Syronglin static_assert(!has_and_then<std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(int)>);
165acce2a31Syronglin static_assert( has_and_then<const std::expected<int, int>&&, std::expected<int, int>(const int)>);
166acce2a31Syronglin static_assert(!has_and_then<const std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(const int)>);
167acce2a31Syronglin 
168acce2a31Syronglin // [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body.
169acce2a31Syronglin static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&, int()>);
170acce2a31Syronglin static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&&, int()>);
171acce2a31Syronglin 
1729f67143bSyronglin // [LWG 3983] https://cplusplus.github.io/LWG/issue3938, check std::expected monadic ops well-formed with move-only error_type.
1739f67143bSyronglin // There are no effects for `&` and `const &` overload, because the constraints requires is_constructible_v<E, decltype(error())> is true.
1749f67143bSyronglin static_assert(has_and_then<std::expected<int, MoveOnlyErrorType>&&, std::expected<int, MoveOnlyErrorType>(int)>);
1759f67143bSyronglin static_assert(has_and_then<const std::expected<int, MoveOnlyErrorType>&&, std::expected<int, MoveOnlyErrorType>(const int)>);
1769f67143bSyronglin 
177acce2a31Syronglin constexpr void test_val_types() {
178acce2a31Syronglin   // Test & overload
179acce2a31Syronglin   {
180acce2a31Syronglin     // Without & qualifier on F's operator()
181acce2a31Syronglin     {
182acce2a31Syronglin       std::expected<int, int> e{0};
183acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(LVal{});
184acce2a31Syronglin       assert(val == 1);
185acce2a31Syronglin       assert(e.and_then(UnexpectedLVal{}).error() == 5);
186acce2a31Syronglin     }
187acce2a31Syronglin 
188acce2a31Syronglin     // With & qualifier on F's operator()
189acce2a31Syronglin     {
190acce2a31Syronglin       std::expected<int, int> e{0};
191acce2a31Syronglin       RefQual l{};
192acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l);
193acce2a31Syronglin       assert(val == 1);
194acce2a31Syronglin       UnexpectedRefQual nl{};
195acce2a31Syronglin       assert(e.and_then(nl).error() == 5);
196acce2a31Syronglin     }
197acce2a31Syronglin   }
198acce2a31Syronglin 
199acce2a31Syronglin   // Test const& overload
200acce2a31Syronglin   {
201acce2a31Syronglin     // Without & qualifier on F's operator()
202acce2a31Syronglin     {
203acce2a31Syronglin       const std::expected<int, int> e{0};
204acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(CLVal{});
205acce2a31Syronglin       assert(val == 1);
206acce2a31Syronglin       assert(e.and_then(UnexpectedCLVal{}).error() == 5);
207acce2a31Syronglin     }
208acce2a31Syronglin 
209acce2a31Syronglin     // With & qualifier on F's operator()
210acce2a31Syronglin     {
211acce2a31Syronglin       const std::expected<int, int> e{0};
212acce2a31Syronglin       const CRefQual l{};
213acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l);
214acce2a31Syronglin       assert(val == 1);
215acce2a31Syronglin       const UnexpectedCRefQual nl{};
216acce2a31Syronglin       assert(e.and_then(nl).error() == 5);
217acce2a31Syronglin     }
218acce2a31Syronglin   }
219acce2a31Syronglin 
220acce2a31Syronglin   // Test && overload
221acce2a31Syronglin   {
222acce2a31Syronglin     // Without & qualifier on F's operator()
223acce2a31Syronglin     {
224acce2a31Syronglin       std::expected<int, int> e{0};
225acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVal{});
226acce2a31Syronglin       assert(val == 1);
227acce2a31Syronglin       assert(std::move(e).and_then(UnexpectedRVal{}).error() == 5);
228acce2a31Syronglin     }
229acce2a31Syronglin 
230acce2a31Syronglin     // With & qualifier on F's operator()
231acce2a31Syronglin     {
232acce2a31Syronglin       std::expected<int, int> e{0};
233acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVRefQual{});
234acce2a31Syronglin       assert(val == 1);
235acce2a31Syronglin       assert(e.and_then(UnexpectedRVRefQual{}).error() == 5);
236acce2a31Syronglin     }
237acce2a31Syronglin   }
238acce2a31Syronglin 
239acce2a31Syronglin   // Test const&& overload
240acce2a31Syronglin   {
241acce2a31Syronglin     // Without & qualifier on F's operator()
242acce2a31Syronglin     {
243acce2a31Syronglin       const std::expected<int, int> e{0};
244acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(CRVal{});
245acce2a31Syronglin       assert(val == 1);
246acce2a31Syronglin       assert(std::move(e).and_then(UnexpectedCRVal{}).error() == 5);
247acce2a31Syronglin     }
248acce2a31Syronglin 
249acce2a31Syronglin     // With & qualifier on F's operator()
250acce2a31Syronglin     {
251acce2a31Syronglin       const std::expected<int, int> e{0};
252acce2a31Syronglin       const RVCRefQual l{};
253acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(std::move(l));
254acce2a31Syronglin       assert(val == 1);
255acce2a31Syronglin       const UnexpectedRVCRefQual nl{};
256acce2a31Syronglin       assert(std::move(e).and_then(std::move(nl)).error() == 5);
257acce2a31Syronglin     }
258acce2a31Syronglin   }
259acce2a31Syronglin }
260acce2a31Syronglin // clang-format on
261acce2a31Syronglin 
262acce2a31Syronglin // check that the lambda body is not instantiated during overload resolution
263acce2a31Syronglin constexpr void test_sfinae() {
264acce2a31Syronglin   std::expected<NonConst, int> e(std::unexpected<int>(2));
265acce2a31Syronglin   auto l = [](auto&& x) { return x.non_const(); };
266*cb4433b6SStephan T. Lavavej   (void)e.and_then(l);
267*cb4433b6SStephan T. Lavavej   (void)std::move(e).and_then(l);
268acce2a31Syronglin }
269acce2a31Syronglin 
2709f67143bSyronglin constexpr void test_move_only_error_type() {
2719f67143bSyronglin   // Test &&
2729f67143bSyronglin   {
2739f67143bSyronglin     std::expected<int, MoveOnlyErrorType> e;
2749f67143bSyronglin     auto l = [](int) { return std::expected<int, MoveOnlyErrorType>{}; };
275*cb4433b6SStephan T. Lavavej     (void)std::move(e).and_then(l);
2769f67143bSyronglin   }
2779f67143bSyronglin 
2789f67143bSyronglin   // Test const&&
2799f67143bSyronglin   {
2809f67143bSyronglin     const std::expected<int, MoveOnlyErrorType> e;
2819f67143bSyronglin     auto l = [](const int) { return std::expected<int, MoveOnlyErrorType>{}; };
282*cb4433b6SStephan T. Lavavej     (void)std::move(e).and_then(l);
2839f67143bSyronglin   }
2849f67143bSyronglin }
2859f67143bSyronglin 
286acce2a31Syronglin constexpr bool test() {
287acce2a31Syronglin   test_sfinae();
288acce2a31Syronglin   test_val_types();
2899f67143bSyronglin   test_move_only_error_type();
290acce2a31Syronglin 
291acce2a31Syronglin   std::expected<int, int> e(std::unexpected<int>(1));
292acce2a31Syronglin   const auto& ce = e;
293acce2a31Syronglin 
294acce2a31Syronglin   const auto never_called = [](int) {
295acce2a31Syronglin     assert(false);
296acce2a31Syronglin     return std::expected<int, int>();
297acce2a31Syronglin   };
298acce2a31Syronglin 
299*cb4433b6SStephan T. Lavavej   (void)e.and_then(never_called);
300*cb4433b6SStephan T. Lavavej   (void)std::move(e).and_then(never_called);
301*cb4433b6SStephan T. Lavavej   (void)ce.and_then(never_called);
302*cb4433b6SStephan T. Lavavej   (void)std::move(ce).and_then(never_called);
303acce2a31Syronglin 
304acce2a31Syronglin   return true;
305acce2a31Syronglin }
306acce2a31Syronglin 
307acce2a31Syronglin int main(int, char**) {
308acce2a31Syronglin   test();
309acce2a31Syronglin   static_assert(test());
310acce2a31Syronglin 
311acce2a31Syronglin   return 0;
312acce2a31Syronglin }
313