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 and_then(F&& f) &; 14 // template<class F> constexpr auto and_then(F&& f) const &; 15 // template<class F> constexpr auto and_then(F&& f) &&; 16 // template<class F> constexpr auto and_then(F&& f) const &&; 17 18 #include <cassert> 19 #include <concepts> 20 #include <expected> 21 #include <memory> 22 #include <type_traits> 23 #include <utility> 24 25 struct LVal { 26 constexpr std::expected<int, int> operator()(int&) { return 1; } 27 std::expected<int, int> operator()(const int&) = delete; 28 std::expected<int, int> operator()(int&&) = delete; 29 std::expected<int, int> operator()(const int&&) = delete; 30 }; 31 32 struct CLVal { 33 std::expected<int, int> operator()(int&) = delete; 34 constexpr std::expected<int, int> operator()(const int&) { return 1; } 35 std::expected<int, int> operator()(int&&) = delete; 36 std::expected<int, int> operator()(const int&&) = delete; 37 }; 38 39 struct RVal { 40 std::expected<int, int> operator()(int&) = delete; 41 std::expected<int, int> operator()(const int&) = delete; 42 constexpr std::expected<int, int> operator()(int&&) { return 1; } 43 std::expected<int, int> operator()(const int&&) = delete; 44 }; 45 46 struct CRVal { 47 std::expected<int, int> operator()(int&) = delete; 48 std::expected<int, int> operator()(const int&) = delete; 49 std::expected<int, int> operator()(int&&) = delete; 50 constexpr std::expected<int, int> operator()(const int&&) { return 1; } 51 }; 52 53 struct RefQual { 54 constexpr std::expected<int, int> operator()(int) & { return 1; } 55 std::expected<int, int> operator()(int) const& = delete; 56 std::expected<int, int> operator()(int) && = delete; 57 std::expected<int, int> operator()(int) const&& = delete; 58 }; 59 60 struct CRefQual { 61 std::expected<int, int> operator()(int) & = delete; 62 constexpr std::expected<int, int> operator()(int) const& { return 1; } 63 std::expected<int, int> operator()(int) && = delete; 64 std::expected<int, int> operator()(int) const&& = delete; 65 }; 66 67 struct RVRefQual { 68 std::expected<int, int> operator()(int) & = delete; 69 std::expected<int, int> operator()(int) const& = delete; 70 constexpr std::expected<int, int> operator()(int) && { return 1; } 71 std::expected<int, int> operator()(int) const&& = delete; 72 }; 73 74 struct RVCRefQual { 75 std::expected<int, int> operator()(int) & = delete; 76 std::expected<int, int> operator()(int) const& = delete; 77 std::expected<int, int> operator()(int) && = delete; 78 constexpr std::expected<int, int> operator()(int) const&& { return 1; } 79 }; 80 81 struct UnexpectedLVal { 82 constexpr std::expected<int, int> operator()(int&) { return std::expected<int, int>(std::unexpected<int>(5)); } 83 std::expected<int, int> operator()(const int&) = delete; 84 std::expected<int, int> operator()(int&&) = delete; 85 std::expected<int, int> operator()(const int&&) = delete; 86 }; 87 88 struct UnexpectedCLVal { 89 std::expected<int, int> operator()(int&) = delete; 90 constexpr std::expected<int, int> operator()(const int&) { return std::expected<int, int>(std::unexpected<int>(5)); } 91 std::expected<int, int> operator()(int&&) = delete; 92 std::expected<int, int> operator()(const int&&) = delete; 93 }; 94 95 struct UnexpectedRVal { 96 std::expected<int, int> operator()(int&) = delete; 97 std::expected<int, int> operator()(const int&) = delete; 98 constexpr std::expected<int, int> operator()(int&&) { return std::expected<int, int>(std::unexpected<int>(5)); } 99 std::expected<int, int> operator()(const int&&) = delete; 100 }; 101 102 struct UnexpectedCRVal { 103 std::expected<int, int> operator()(int&) = delete; 104 std::expected<int, int> operator()(const int&) = delete; 105 std::expected<int, int> operator()(int&&) = delete; 106 constexpr std::expected<int, int> operator()(const int&&) { return std::expected<int, int>(std::unexpected<int>(5)); } 107 }; 108 109 struct UnexpectedRefQual { 110 constexpr std::expected<int, int> operator()(int) & { return std::expected<int, int>(std::unexpected<int>(5)); } 111 std::expected<int, int> operator()(int) const& = delete; 112 std::expected<int, int> operator()(int) && = delete; 113 std::expected<int, int> operator()(int) const&& = delete; 114 }; 115 116 struct UnexpectedCRefQual { 117 std::expected<int, int> operator()(int) & = delete; 118 constexpr std::expected<int, int> operator()(int) const& { return std::expected<int, int>(std::unexpected<int>(5)); } 119 std::expected<int, int> operator()(int) && = delete; 120 std::expected<int, int> operator()(int) const&& = delete; 121 }; 122 123 struct UnexpectedRVRefQual { 124 std::expected<int, int> operator()(int) & = delete; 125 std::expected<int, int> operator()(int) const& = delete; 126 constexpr std::expected<int, int> operator()(int) && { return std::expected<int, int>(std::unexpected<int>(5)); } 127 std::expected<int, int> operator()(int) const&& = delete; 128 }; 129 130 struct UnexpectedRVCRefQual { 131 std::expected<int, int> operator()(int) & = delete; 132 std::expected<int, int> operator()(int) const& = delete; 133 std::expected<int, int> operator()(int) && = delete; 134 constexpr std::expected<int, int> operator()(int) const&& { return std::expected<int, int>(std::unexpected<int>(5)); } 135 }; 136 137 struct NonCopyable { 138 constexpr NonCopyable(int) {} 139 NonCopyable(const NonCopyable&) = delete; 140 }; 141 142 struct NonMovable { 143 constexpr NonMovable(int) {} 144 NonMovable(NonMovable&&) = delete; 145 }; 146 147 struct NonConst { 148 std::expected<int, int> non_const() { return 1; } 149 }; 150 151 template <class E, class F> 152 concept has_and_then = requires(E&& e, F&& f) { 153 {std::forward<E>(e).and_then(std::forward<F>(f))}; 154 }; 155 156 static_assert( has_and_then<std::expected<int, int>&, std::expected<int, int>(int&)>); 157 static_assert(!has_and_then<std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(int&)>); 158 static_assert( has_and_then<const std::expected<int, int>&, std::expected<int, int>(const int&)>); 159 static_assert(!has_and_then<const std::expected<int, NonCopyable>&, std::expected<int, NonCopyable>(const int&)>); 160 static_assert( has_and_then<std::expected<int, int>&&, std::expected<int, int>(int)>); 161 static_assert(!has_and_then<std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(int)>); 162 static_assert( has_and_then<const std::expected<int, int>&&, std::expected<int, int>(const int)>); 163 static_assert(!has_and_then<const std::expected<int, NonMovable>&&, std::expected<int, NonMovable>(const int)>); 164 165 // [LWG 3877] https://cplusplus.github.io/LWG/issue3877, check constraint failing but not compile error inside the function body. 166 static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&, int()>); 167 static_assert(!has_and_then<const std::expected<int, std::unique_ptr<int>>&&, int()>); 168 169 // clang-format off 170 constexpr void test_val_types() { 171 // Test & overload 172 { 173 // Without &qualifier on F'soperator() 174 { 175 std::expected<int, int> e{0}; 176 std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(LVal{}); 177 assert(val == 1); 178 assert(e.and_then(UnexpectedLVal{}).error() == 5); 179 } 180 181 // With & qualifier on F's operator() 182 { 183 std::expected<int, int> e{0}; 184 RefQual l{}; 185 std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l); 186 assert(val == 1); 187 UnexpectedRefQual nl{}; 188 assert(e.and_then(nl).error() == 5); 189 } 190 } 191 192 // Test const& overload 193 { 194 // Without & qualifier on F's operator() 195 { 196 const std::expected<int, int> e{0}; 197 std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(CLVal{}); 198 assert(val == 1); 199 assert(e.and_then(UnexpectedCLVal{}).error() == 5); 200 } 201 202 // With & qualifier on F's operator() 203 { 204 const std::expected<int, int> e{0}; 205 const CRefQual l{}; 206 std::same_as<std::expected<int, int>> decltype(auto) val = e.and_then(l); 207 assert(val == 1); 208 const UnexpectedCRefQual nl{}; 209 assert(e.and_then(nl).error() == 5); 210 } 211 } 212 213 // Test && overload 214 { 215 // Without & qualifier on F's operator() 216 { 217 std::expected<int, int> e{0}; 218 std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVal{}); 219 assert(val == 1); 220 assert(std::move(e).and_then(UnexpectedRVal{}).error() == 5); 221 } 222 223 // With & qualifier on F's operator() 224 { 225 std::expected<int, int> e{0}; 226 std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(RVRefQual{}); 227 assert(val == 1); 228 assert(e.and_then(UnexpectedRVRefQual{}).error() == 5); 229 } 230 } 231 232 // Test const&& overload 233 { 234 // Without & qualifier on F's operator() 235 { 236 const std::expected<int, int> e{0}; 237 std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(CRVal{}); 238 assert(val == 1); 239 assert(std::move(e).and_then(UnexpectedCRVal{}).error() == 5); 240 } 241 242 // With & qualifier on F's operator() 243 { 244 const std::expected<int, int> e{0}; 245 const RVCRefQual l{}; 246 std::same_as<std::expected<int, int>> decltype(auto) val = std::move(e).and_then(std::move(l)); 247 assert(val == 1); 248 const UnexpectedRVCRefQual nl{}; 249 assert(std::move(e).and_then(std::move(nl)).error() == 5); 250 } 251 } 252 } 253 // clang-format on 254 255 // check that the lambda body is not instantiated during overload resolution 256 constexpr void test_sfinae() { 257 std::expected<NonConst, int> e(std::unexpected<int>(2)); 258 auto l = [](auto&& x) { return x.non_const(); }; 259 e.and_then(l); 260 std::move(e).and_then(l); 261 } 262 263 constexpr bool test() { 264 test_sfinae(); 265 test_val_types(); 266 267 std::expected<int, int> e(std::unexpected<int>(1)); 268 const auto& ce = e; 269 270 const auto never_called = [](int) { 271 assert(false); 272 return std::expected<int, int>(); 273 }; 274 275 e.and_then(never_called); 276 std::move(e).and_then(never_called); 277 ce.and_then(never_called); 278 std::move(ce).and_then(never_called); 279 280 return true; 281 } 282 283 int main(int, char**) { 284 test(); 285 static_assert(test()); 286 287 return 0; 288 } 289