xref: /llvm-project/libcxx/test/std/utilities/optional/optional.monadic/or_else.pass.cpp (revision c31cf74c3c3ca8ddd6d695ae7591f6cbfee54a6a)
117cfc57dSNikolas Klauser //===----------------------------------------------------------------------===//
217cfc57dSNikolas Klauser //
317cfc57dSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
417cfc57dSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
517cfc57dSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
617cfc57dSNikolas Klauser //
717cfc57dSNikolas Klauser //===----------------------------------------------------------------------===//
817cfc57dSNikolas Klauser 
917cfc57dSNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
1017cfc57dSNikolas Klauser // <optional>
1117cfc57dSNikolas Klauser 
1217cfc57dSNikolas Klauser // template<class F> constexpr optional or_else(F&&) &&;
1317cfc57dSNikolas Klauser // template<class F> constexpr optional or_else(F&&) const&;
1417cfc57dSNikolas Klauser 
1517cfc57dSNikolas Klauser #include "MoveOnly.h"
1617cfc57dSNikolas Klauser 
1717cfc57dSNikolas Klauser #include <cassert>
1817cfc57dSNikolas Klauser #include <optional>
1917cfc57dSNikolas Klauser 
2017cfc57dSNikolas Klauser struct NonMovable {
2117cfc57dSNikolas Klauser   NonMovable() = default;
2217cfc57dSNikolas Klauser   NonMovable(NonMovable&&) = delete;
2317cfc57dSNikolas Klauser };
2417cfc57dSNikolas Klauser 
2517cfc57dSNikolas Klauser template <class Opt, class F>
2617cfc57dSNikolas Klauser concept has_or_else = requires(Opt&& opt, F&& f) {
2717cfc57dSNikolas Klauser   {std::forward<Opt>(opt).or_else(std::forward<F>(f))};
2817cfc57dSNikolas Klauser };
2917cfc57dSNikolas Klauser 
3017cfc57dSNikolas Klauser template <class T>
return_optional()3117cfc57dSNikolas Klauser std::optional<T> return_optional() {}
3217cfc57dSNikolas Klauser 
3317cfc57dSNikolas Klauser static_assert(has_or_else<std::optional<int>&, decltype(return_optional<int>)>);
3417cfc57dSNikolas Klauser static_assert(has_or_else<std::optional<int>&&, decltype(return_optional<int>)>);
3517cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<MoveOnly>&, decltype(return_optional<MoveOnly>)>);
3617cfc57dSNikolas Klauser static_assert(has_or_else<std::optional<MoveOnly>&&, decltype(return_optional<MoveOnly>)>);
3717cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<NonMovable>&, decltype(return_optional<NonMovable>)>);
3817cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<NonMovable>&&, decltype(return_optional<NonMovable>)>);
3917cfc57dSNikolas Klauser 
take_int(int)4017cfc57dSNikolas Klauser std::optional<int> take_int(int) { return 0; }
take_int_return_void(int)4117cfc57dSNikolas Klauser void take_int_return_void(int) {}
4217cfc57dSNikolas Klauser 
4317cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<int>, decltype(take_int)>);
4417cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<int>, decltype(take_int_return_void)>);
4517cfc57dSNikolas Klauser static_assert(!has_or_else<std::optional<int>, int>);
4617cfc57dSNikolas Klauser 
test()4717cfc57dSNikolas Klauser constexpr bool test() {
4817cfc57dSNikolas Klauser   {
4917cfc57dSNikolas Klauser     std::optional<int> opt;
5017cfc57dSNikolas Klauser     assert(opt.or_else([] { return std::optional<int>{0}; }) == 0);
5117cfc57dSNikolas Klauser     opt = 1;
5217cfc57dSNikolas Klauser     opt.or_else([] {
5317cfc57dSNikolas Klauser       assert(false);
5417cfc57dSNikolas Klauser       return std::optional<int>{};
5517cfc57dSNikolas Klauser     });
5617cfc57dSNikolas Klauser   }
5717cfc57dSNikolas Klauser   {
5817cfc57dSNikolas Klauser     std::optional<MoveOnly> opt;
5917cfc57dSNikolas Klauser     opt = std::move(opt).or_else([] { return std::optional<MoveOnly>{MoveOnly{}}; });
6017cfc57dSNikolas Klauser     std::move(opt).or_else([] {
6117cfc57dSNikolas Klauser       assert(false);
6217cfc57dSNikolas Klauser       return std::optional<MoveOnly>{};
6317cfc57dSNikolas Klauser     });
6417cfc57dSNikolas Klauser   }
6517cfc57dSNikolas Klauser 
6617cfc57dSNikolas Klauser   return true;
6717cfc57dSNikolas Klauser }
6817cfc57dSNikolas Klauser 
main(int,char **)6917cfc57dSNikolas Klauser int main(int, char**) {
7017cfc57dSNikolas Klauser   test();
7117cfc57dSNikolas Klauser   static_assert(test());
72*c31cf74cSLouis Dionne   return 0;
7317cfc57dSNikolas Klauser }
74