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