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