//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // // template constexpr optional or_else(F&&) &&; // template constexpr optional or_else(F&&) const&; #include "MoveOnly.h" #include #include struct NonMovable { NonMovable() = default; NonMovable(NonMovable&&) = delete; }; template concept has_or_else = requires(Opt&& opt, F&& f) { {std::forward(opt).or_else(std::forward(f))}; }; template std::optional return_optional() {} static_assert(has_or_else&, decltype(return_optional)>); static_assert(has_or_else&&, decltype(return_optional)>); static_assert(!has_or_else&, decltype(return_optional)>); static_assert(has_or_else&&, decltype(return_optional)>); static_assert(!has_or_else&, decltype(return_optional)>); static_assert(!has_or_else&&, decltype(return_optional)>); std::optional take_int(int) { return 0; } void take_int_return_void(int) {} static_assert(!has_or_else, decltype(take_int)>); static_assert(!has_or_else, decltype(take_int_return_void)>); static_assert(!has_or_else, int>); constexpr bool test() { { std::optional opt; assert(opt.or_else([] { return std::optional{0}; }) == 0); opt = 1; opt.or_else([] { assert(false); return std::optional{}; }); } { std::optional opt; opt = std::move(opt).or_else([] { return std::optional{MoveOnly{}}; }); std::move(opt).or_else([] { assert(false); return std::optional{}; }); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }