xref: /llvm-project/libcxx/test/std/utilities/expected/expected.void/monadic/transform_error.pass.cpp (revision 9e9404387d3b787305dc8bf21b0e20c477b6ff39)
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 // GCC has a issue for `Guaranteed copy elision for potentially-overlapping non-static data members`,
12 // please refer to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108333
13 // XFAIL: gcc-14
14 
15 // <expected>
16 
17 // template<class F> constexpr auto transform_error(F&& f) &;
18 // template<class F> constexpr auto transform_error(F&& f) const &;
19 // template<class F> constexpr auto transform_error(F&& f) &&;
20 // template<class F> constexpr auto transform_error(F&& f) const &&;
21 
22 #include <expected>
23 #include <concepts>
24 #include <cassert>
25 #include <type_traits>
26 #include <utility>
27 
28 struct NonCopy {
29   int value;
NonCopyNonCopy30   constexpr explicit NonCopy(int val) : value(val) {}
31   NonCopy(const NonCopy&) = delete;
32 };
33 
test_val_types()34 constexpr void test_val_types() {
35   // Test & overload
36   {
37     auto l = [](auto) -> int { return 1; };
38     std::expected<void, int> v(std::unexpected<int>(2));
39     std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l);
40     assert(val.error() == 1);
41   }
42 
43   // Test const& overload
44   {
45     auto l = [](auto) -> int { return 1; };
46     const std::expected<void, int> v(std::unexpected<int>(2));
47     std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l);
48     assert(val.error() == 1);
49   }
50 
51   // Test && overload
52   {
53     auto l = [](auto) -> int { return 1; };
54     std::expected<void, int> v(std::unexpected<int>(2));
55     std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l);
56     assert(val.error() == 1);
57   }
58 
59   // Test const&& overload
60   {
61     auto l = [](auto) -> int { return 1; };
62     const std::expected<void, int> v(std::unexpected<int>(2));
63     std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l);
64     assert(val.error() == 1);
65   }
66 }
67 
test_fail()68 constexpr void test_fail() {
69   // Test & overload
70   {
71     auto l = [](auto) -> int {
72       assert(false);
73       return 0;
74     };
75     std::expected<void, int> v;
76     std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l);
77     assert(val.has_value());
78   }
79 
80   // Test const& overload
81   {
82     auto l = [](auto) -> int {
83       assert(false);
84       return 0;
85     };
86     const std::expected<void, int> v;
87     std::same_as<std::expected<void, int>> decltype(auto) val = v.transform_error(l);
88     assert(val.has_value());
89   }
90 
91   // Test && overload
92   {
93     auto l = [](auto) -> int {
94       assert(false);
95       return 0;
96     };
97     std::expected<void, int> v;
98     std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l);
99     assert(val.has_value());
100   }
101 
102   // Test const&& overload
103   {
104     auto l = [](auto) -> int {
105       assert(false);
106       return 0;
107     };
108     const std::expected<void, int> v;
109     std::same_as<std::expected<void, int>> decltype(auto) val = std::move(v).transform_error(l);
110     assert(val.has_value());
111   }
112 }
113 
114 // check unex member is direct-non-list-initialized with invoke(std::forward<F>(f))
test_direct_non_list_init()115 constexpr void test_direct_non_list_init() {
116   auto x = [](int i) { return NonCopy(i); };
117   std::expected<void, int> v(std::unexpected<int>(2));
118   std::expected<void, NonCopy> nv = v.transform_error(x);
119   assert(nv.error().value == 2);
120 }
121 
test()122 constexpr bool test() {
123   test_fail();
124   test_val_types();
125   test_direct_non_list_init();
126   return true;
127 }
128 
main(int,char **)129 int main(int, char**) {
130   test();
131   static_assert(test());
132 
133   return 0;
134 }
135