//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // // template constexpr auto transform_error(F&& f) &; // template constexpr auto transform_error(F&& f) const &; // template constexpr auto transform_error(F&& f) &&; // template constexpr auto transform_error(F&& f) const &&; #include #include #include #include #include #include template concept has_transform = requires(E&& e, F&& f) { { std::forward(e).transform(std::forward(f)) }; }; // [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. static_assert(!has_transform>&, int()>); static_assert(!has_transform>&&, int()>); constexpr void test_val_types() { // Test & overload { auto l = []() -> int { return 1; }; std::expected v; std::same_as> decltype(auto) val = v.transform(l); assert(val == 1); } // Test const& overload { auto l = []() -> int { return 1; }; const std::expected v; std::same_as> decltype(auto) val = v.transform(l); assert(val == 1); } // Test && overload { auto l = []() -> int { return 1; }; std::expected v; std::same_as> decltype(auto) val = std::move(v).transform(l); assert(val == 1); } // Test const&& overload { auto l = []() -> int { return 1; }; const std::expected v; std::same_as> decltype(auto) val = std::move(v).transform(l); assert(val == 1); } } constexpr void test_fail() { // Test & overload { auto l = []() -> int { assert(false); return 0; }; std::expected v(std::unexpected(5)); std::same_as> decltype(auto) val = v.transform(l); assert(val.error() == 5); } // Test const& overload { auto l = []() -> int { assert(false); return 0; }; const std::expected v(std::unexpected(5)); std::same_as> decltype(auto) val = v.transform(l); assert(val.error() == 5); } // Test && overload { auto l = []() -> int { assert(false); return 0; }; std::expected v(std::unexpected(5)); std::same_as> decltype(auto) val = std::move(v).transform(l); assert(val.error() == 5); } // Test const&& overload { auto l = []() -> int { assert(false); return 0; }; const std::expected v(std::unexpected(5)); std::same_as> decltype(auto) val = std::move(v).transform(l); assert(val.error() == 5); } } constexpr bool test() { test_fail(); test_val_types(); return true; } int main(int, char**) { test(); static_assert(test()); return 0; }