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