127 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 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 & overload37 {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& overload45 {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 && overload53 {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&& overload61 {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 & overload71 {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& overload82 {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 && overload93 {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&& overload104 {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