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
25template <class E, class F>
26concept 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.
32static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&, int()>);
33static_assert(!has_transform<const std::expected<int, std::unique_ptr<int>>&&, int()>);
34
35constexpr 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
69constexpr 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
115constexpr bool test() {
116 test_fail();
117 test_val_types();
118 return true;
119}
120
121int main(int, char**) {
122 test();
123 static_assert(test());
124
125 return 0;
126}
127

source code of libcxx/test/std/utilities/expected/expected.void/monadic/transform.pass.cpp