xref: /llvm-project/libcxx/test/std/utilities/expected/expected.expected/monadic/or_else.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 or_else(F&& f) &;
14acce2a31Syronglin // template<class F> constexpr auto or_else(F&& f) const &;
15acce2a31Syronglin // template<class F> constexpr auto or_else(F&& f) &&;
16acce2a31Syronglin // template<class F> constexpr auto or_else(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 template <class E, class F>
84acce2a31Syronglin concept has_or_else =
85acce2a31Syronglin     requires(E&& e, F&& f) {
86acce2a31Syronglin       { std::forward<E>(e).or_else(std::forward<F>(f)) };
87acce2a31Syronglin     };
889f67143bSyronglin // clang-format off
89acce2a31Syronglin // [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body.
90acce2a31Syronglin static_assert(!has_or_else<const std::expected<std::unique_ptr<int>, int>&, int()>);
91acce2a31Syronglin static_assert(!has_or_else<const std::expected<std::unique_ptr<int>, int>&&, int()>);
92acce2a31Syronglin 
939f67143bSyronglin // [LWG 3983] https://cplusplus.github.io/LWG/issue3938, check std::expected monadic ops well-formed with move-only error_type.
949f67143bSyronglin static_assert(has_or_else<std::expected<int, MoveOnlyErrorType>&, std::expected<int, int>(MoveOnlyErrorType &)>);
959f67143bSyronglin static_assert(has_or_else<const std::expected<int, MoveOnlyErrorType>&, std::expected<int, int>(const MoveOnlyErrorType &)>);
969f67143bSyronglin static_assert(has_or_else<std::expected<int, MoveOnlyErrorType>&&, std::expected<int, int>(MoveOnlyErrorType&&)>);
979f67143bSyronglin static_assert(has_or_else<const std::expected<int, MoveOnlyErrorType>&&, std::expected<int, int>(const MoveOnlyErrorType&&)>);
989f67143bSyronglin 
99acce2a31Syronglin constexpr void test_val_types() {
100acce2a31Syronglin   // Test & overload
101acce2a31Syronglin   {
102acce2a31Syronglin     // Without & qualifier on F's operator()
103acce2a31Syronglin     {
104acce2a31Syronglin       std::expected<int, int> e(std::unexpected<int>(0));
105acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(LVal{});
106acce2a31Syronglin       assert(val == 1);
107acce2a31Syronglin     }
108acce2a31Syronglin 
109acce2a31Syronglin     // With & qualifier on F's operator
110acce2a31Syronglin     {
111acce2a31Syronglin       std::expected<int, int> e(std::unexpected<int>(0));
112acce2a31Syronglin       RefQual l{};
113acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(l);
114acce2a31Syronglin       assert(val == 1);
115acce2a31Syronglin     }
116acce2a31Syronglin   }
117acce2a31Syronglin 
118acce2a31Syronglin   // Test const& overload
119acce2a31Syronglin   {
120acce2a31Syronglin     // Without const& qualifier on F's operator()
121acce2a31Syronglin     {
122acce2a31Syronglin       const std::expected<int, int> e(std::unexpected<int>(0));
123acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(CLVal{});
124acce2a31Syronglin       assert(val == 1);
125acce2a31Syronglin     }
126acce2a31Syronglin 
127acce2a31Syronglin     // With const& qualifier on F's operator()
128acce2a31Syronglin     {
129acce2a31Syronglin       const std::expected<int, int> e(std::unexpected<int>(0));
130acce2a31Syronglin       const CRefQual l{};
131acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = e.or_else(l);
132acce2a31Syronglin       assert(val == 1);
133acce2a31Syronglin     }
134acce2a31Syronglin   }
135acce2a31Syronglin 
136acce2a31Syronglin   // Test && overload
137acce2a31Syronglin   {
138acce2a31Syronglin     // Without && qualifier on F's operator()
139acce2a31Syronglin     {
140acce2a31Syronglin       std::expected<int, int> e(std::unexpected<int>(0));
141acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(RVal{});
142acce2a31Syronglin       assert(val == 1);
143acce2a31Syronglin     }
144acce2a31Syronglin 
145acce2a31Syronglin     // With && qualifier on F's operator()
146acce2a31Syronglin     {
147acce2a31Syronglin       std::expected<int, int> e(std::unexpected<int>(0));
148acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(RVRefQual{});
149acce2a31Syronglin       assert(val == 1);
150acce2a31Syronglin     }
151acce2a31Syronglin   }
152acce2a31Syronglin 
153acce2a31Syronglin   // Test const&& overload
154acce2a31Syronglin   {
155acce2a31Syronglin     // Without const&& qualifier on F's operator()
156acce2a31Syronglin     {
157acce2a31Syronglin       const std::expected<int, int> e(std::unexpected<int>(0));
158acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(CRVal{});
159acce2a31Syronglin       assert(val == 1);
160acce2a31Syronglin     }
161acce2a31Syronglin 
162acce2a31Syronglin     // With const&& qualifier on F's operator()
163acce2a31Syronglin     {
164acce2a31Syronglin       const std::expected<int, int> e(std::unexpected<int>(0));
165acce2a31Syronglin       const RVCRefQual l{};
166acce2a31Syronglin       std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).or_else(std::move(l));
167acce2a31Syronglin       assert(val == 1);
168acce2a31Syronglin     }
169acce2a31Syronglin   }
170acce2a31Syronglin }
171acce2a31Syronglin // clang-format on
172acce2a31Syronglin 
173acce2a31Syronglin struct NonConst {
174acce2a31Syronglin   std::expected<int, int> non_const() { return std::expected<int, int>(std::unexpect, 1); }
175acce2a31Syronglin };
176acce2a31Syronglin 
177acce2a31Syronglin // check that the lambda body is not instantiated during overload resolution
178acce2a31Syronglin constexpr void test_sfinae() {
179acce2a31Syronglin   std::expected<int, NonConst> e{1};
180acce2a31Syronglin   auto l = [](auto&& x) { return x.non_const(); };
181*cb4433b6SStephan T. Lavavej   (void)e.or_else(l);
182*cb4433b6SStephan T. Lavavej   (void)std::move(e).or_else(l);
183acce2a31Syronglin }
184acce2a31Syronglin 
1859f67143bSyronglin constexpr void test_move_only_error_type() {
1869f67143bSyronglin   // Test &
1879f67143bSyronglin   {
1889f67143bSyronglin       std::expected<int, MoveOnlyErrorType> e;
1899f67143bSyronglin       auto l = [](MoveOnlyErrorType&) { return std::expected<int, int>{}; };
190*cb4433b6SStephan T. Lavavej       (void)e.or_else(l);
1919f67143bSyronglin   }
1929f67143bSyronglin 
1939f67143bSyronglin   // Test const&
1949f67143bSyronglin   {
1959f67143bSyronglin       const std::expected<int, MoveOnlyErrorType> e;
1969f67143bSyronglin       auto l = [](const MoveOnlyErrorType&) { return std::expected<int, int>{}; };
197*cb4433b6SStephan T. Lavavej       (void)e.or_else(l);
1989f67143bSyronglin   }
1999f67143bSyronglin 
2009f67143bSyronglin   // Test &&
2019f67143bSyronglin   {
2029f67143bSyronglin       std::expected<int, MoveOnlyErrorType> e;
2039f67143bSyronglin       auto l = [](MoveOnlyErrorType&&) { return std::expected<int, int>{}; };
204*cb4433b6SStephan T. Lavavej       (void)std::move(e).or_else(l);
2059f67143bSyronglin   }
2069f67143bSyronglin 
2079f67143bSyronglin   // Test const&&
2089f67143bSyronglin   {
2099f67143bSyronglin       const std::expected<int, MoveOnlyErrorType> e;
2109f67143bSyronglin       auto l = [](const MoveOnlyErrorType&&) { return std::expected<int, int>{}; };
211*cb4433b6SStephan T. Lavavej       (void)std::move(e).or_else(l);
2129f67143bSyronglin   }
2139f67143bSyronglin }
2149f67143bSyronglin 
215acce2a31Syronglin constexpr bool test() {
216acce2a31Syronglin   test_sfinae();
217acce2a31Syronglin   test_val_types();
2189f67143bSyronglin   test_move_only_error_type();
219acce2a31Syronglin 
220acce2a31Syronglin   std::expected<int, int> e(1);
221acce2a31Syronglin   const auto& ce = e;
222acce2a31Syronglin 
223acce2a31Syronglin   const auto never_called = [](int) {
224acce2a31Syronglin     assert(false);
225acce2a31Syronglin     return std::expected<int, int>();
226acce2a31Syronglin   };
227acce2a31Syronglin 
228*cb4433b6SStephan T. Lavavej   (void)e.or_else(never_called);
229*cb4433b6SStephan T. Lavavej   (void)std::move(e).or_else(never_called);
230*cb4433b6SStephan T. Lavavej   (void)ce.or_else(never_called);
231*cb4433b6SStephan T. Lavavej   (void)std::move(ce).or_else(never_called);
232acce2a31Syronglin   return true;
233acce2a31Syronglin }
234acce2a31Syronglin 
235acce2a31Syronglin int main(int, char**) {
236acce2a31Syronglin   test();
237acce2a31Syronglin   static_assert(test());
238acce2a31Syronglin 
239acce2a31Syronglin   return 0;
240acce2a31Syronglin }
241