xref: /llvm-project/libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp (revision bf95a0cd2073b6f5bd2c00bc645be00d38bf49a6)
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 transform_error(F&& f) &;
14acce2a31Syronglin // template<class F> constexpr auto transform_error(F&& f) const &;
15acce2a31Syronglin // template<class F> constexpr auto transform_error(F&& f) &&;
16acce2a31Syronglin // template<class F> constexpr auto transform_error(F&& f) const &&;
17acce2a31Syronglin 
18acce2a31Syronglin #include <expected>
19acce2a31Syronglin #include <concepts>
20acce2a31Syronglin #include <cassert>
21acce2a31Syronglin #include <memory>
22acce2a31Syronglin #include <type_traits>
23acce2a31Syronglin #include <utility>
24acce2a31Syronglin 
25acce2a31Syronglin template <class E, class F>
26acce2a31Syronglin concept has_transform =
27acce2a31Syronglin     requires(E&& e, F&& f) {
28acce2a31Syronglin       { std::forward<E>(e).transform(std::forward<F>(f)) };
29acce2a31Syronglin     };
30acce2a31Syronglin 
31acce2a31Syronglin // [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body.
32acce2a31Syronglin static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&, int()>);
33acce2a31Syronglin static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&&, int()>);
34acce2a31Syronglin 
test_val_types()35acce2a31Syronglin constexpr void test_val_types() {
36acce2a31Syronglin   // Test & overload
37acce2a31Syronglin   {
38*bf95a0cdSStephan T. Lavavej     auto l = []() -> int { return 1; };
39acce2a31Syronglin     std::expected<void, int> v;
40acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
41acce2a31Syronglin     assert(val == 1);
42acce2a31Syronglin   }
43acce2a31Syronglin 
44acce2a31Syronglin   // Test const& overload
45acce2a31Syronglin   {
46*bf95a0cdSStephan T. Lavavej     auto l = []() -> int { return 1; };
47acce2a31Syronglin     const std::expected<void, int> v;
48acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
49acce2a31Syronglin     assert(val == 1);
50acce2a31Syronglin   }
51acce2a31Syronglin 
52acce2a31Syronglin   // Test && overload
53acce2a31Syronglin   {
54*bf95a0cdSStephan T. Lavavej     auto l = []() -> int { return 1; };
55acce2a31Syronglin     std::expected<void, int> v;
56acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
57acce2a31Syronglin     assert(val == 1);
58acce2a31Syronglin   }
59acce2a31Syronglin 
60acce2a31Syronglin   // Test const&& overload
61acce2a31Syronglin   {
62*bf95a0cdSStephan T. Lavavej     auto l = []() -> int { return 1; };
63acce2a31Syronglin     const std::expected<void, int> v;
64acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
65acce2a31Syronglin     assert(val == 1);
66acce2a31Syronglin   }
67acce2a31Syronglin }
68acce2a31Syronglin 
test_fail()69acce2a31Syronglin constexpr void test_fail() {
70acce2a31Syronglin   // Test & overload
71acce2a31Syronglin   {
72*bf95a0cdSStephan T. Lavavej     auto l = []() -> int {
73acce2a31Syronglin       assert(false);
74acce2a31Syronglin       return 0;
75acce2a31Syronglin     };
76acce2a31Syronglin     std::expected<void, int> v(std::unexpected<int>(5));
77acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
78acce2a31Syronglin     assert(val.error() == 5);
79acce2a31Syronglin   }
80acce2a31Syronglin 
81acce2a31Syronglin   // Test const& overload
82acce2a31Syronglin   {
83*bf95a0cdSStephan T. Lavavej     auto l = []() -> int {
84acce2a31Syronglin       assert(false);
85acce2a31Syronglin       return 0;
86acce2a31Syronglin     };
87acce2a31Syronglin     const std::expected<void, int> v(std::unexpected<int>(5));
88acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = v.transform(l);
89acce2a31Syronglin     assert(val.error() == 5);
90acce2a31Syronglin   }
91acce2a31Syronglin 
92acce2a31Syronglin   // Test && overload
93acce2a31Syronglin   {
94*bf95a0cdSStephan T. Lavavej     auto l = []() -> int {
95acce2a31Syronglin       assert(false);
96acce2a31Syronglin       return 0;
97acce2a31Syronglin     };
98acce2a31Syronglin     std::expected<void, int> v(std::unexpected<int>(5));
99acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
100acce2a31Syronglin     assert(val.error() == 5);
101acce2a31Syronglin   }
102acce2a31Syronglin 
103acce2a31Syronglin   // Test const&& overload
104acce2a31Syronglin   {
105*bf95a0cdSStephan T. Lavavej     auto l = []() -> int {
106acce2a31Syronglin       assert(false);
107acce2a31Syronglin       return 0;
108acce2a31Syronglin     };
109acce2a31Syronglin     const std::expected<void, int> v(std::unexpected<int>(5));
110acce2a31Syronglin     std::same_as<std::expected<int, int>> decltype(auto) val = std::move(v).transform(l);
111acce2a31Syronglin     assert(val.error() == 5);
112acce2a31Syronglin   }
113acce2a31Syronglin }
114acce2a31Syronglin 
test()115acce2a31Syronglin constexpr bool test() {
116acce2a31Syronglin   test_fail();
117acce2a31Syronglin   test_val_types();
118acce2a31Syronglin   return true;
119acce2a31Syronglin }
120acce2a31Syronglin 
main(int,char **)121acce2a31Syronglin int main(int, char**) {
122acce2a31Syronglin   test();
123acce2a31Syronglin   static_assert(test());
124acce2a31Syronglin 
125acce2a31Syronglin   return 0;
126acce2a31Syronglin }
127