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