1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
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 &&;
22 #include <type_traits>
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
)) };
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()>);
35 constexpr void test_val_types() {
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
);
44 // Test const& overload
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
);
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
);
60 // Test const&& overload
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
);
69 constexpr void test_fail() {
72 auto l
= []() -> int {
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);
81 // Test const& overload
83 auto l
= []() -> int {
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);
94 auto l
= []() -> int {
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);
103 // Test const&& overload
105 auto l
= []() -> int {
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);
115 constexpr bool test() {
121 int main(int, char**) {
123 static_assert(test());