1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef _LIBCPP___EXPECTED_EXPECTED_H 10 #define _LIBCPP___EXPECTED_EXPECTED_H 11 12 #include <__assert> 13 #include <__config> 14 #include <__expected/bad_expected_access.h> 15 #include <__expected/unexpect.h> 16 #include <__expected/unexpected.h> 17 #include <__memory/addressof.h> 18 #include <__memory/construct_at.h> 19 #include <__type_traits/conjunction.h> 20 #include <__type_traits/disjunction.h> 21 #include <__type_traits/is_assignable.h> 22 #include <__type_traits/is_constructible.h> 23 #include <__type_traits/is_convertible.h> 24 #include <__type_traits/is_copy_assignable.h> 25 #include <__type_traits/is_copy_constructible.h> 26 #include <__type_traits/is_default_constructible.h> 27 #include <__type_traits/is_function.h> 28 #include <__type_traits/is_move_assignable.h> 29 #include <__type_traits/is_move_constructible.h> 30 #include <__type_traits/is_nothrow_constructible.h> 31 #include <__type_traits/is_nothrow_copy_assignable.h> 32 #include <__type_traits/is_nothrow_copy_constructible.h> 33 #include <__type_traits/is_nothrow_default_constructible.h> 34 #include <__type_traits/is_nothrow_move_assignable.h> 35 #include <__type_traits/is_nothrow_move_constructible.h> 36 #include <__type_traits/is_reference.h> 37 #include <__type_traits/is_same.h> 38 #include <__type_traits/is_swappable.h> 39 #include <__type_traits/is_trivially_copy_constructible.h> 40 #include <__type_traits/is_trivially_destructible.h> 41 #include <__type_traits/is_trivially_move_constructible.h> 42 #include <__type_traits/is_void.h> 43 #include <__type_traits/lazy.h> 44 #include <__type_traits/negation.h> 45 #include <__type_traits/remove_cv.h> 46 #include <__type_traits/remove_cvref.h> 47 #include <__utility/exception_guard.h> 48 #include <__utility/forward.h> 49 #include <__utility/in_place.h> 50 #include <__utility/move.h> 51 #include <__utility/swap.h> 52 #include <cstdlib> // for std::abort 53 #include <initializer_list> 54 55 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 56 # pragma GCC system_header 57 #endif 58 59 #if _LIBCPP_STD_VER >= 23 60 61 _LIBCPP_BEGIN_NAMESPACE_STD 62 63 namespace __expected { 64 65 template <class _Err, class _Arg> 66 _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { 67 # ifndef _LIBCPP_NO_EXCEPTIONS 68 throw bad_expected_access<_Err>(std::forward<_Arg>(__arg)); 69 # else 70 (void)__arg; 71 std::abort(); 72 # endif 73 } 74 75 } // namespace __expected 76 77 template <class _Tp, class _Err> 78 class expected { 79 static_assert( 80 !is_reference_v<_Tp> && 81 !is_function_v<_Tp> && 82 !is_same_v<remove_cv_t<_Tp>, in_place_t> && 83 !is_same_v<remove_cv_t<_Tp>, unexpect_t> && 84 !__is_std_unexpected<remove_cv_t<_Tp>>::value && 85 __valid_std_unexpected<_Err>::value 86 , 87 "[expected.object.general] A program that instantiates the definition of template expected<T, E> for a " 88 "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " 89 "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " 90 "definition of the template expected<T, E> with a type for the E parameter that is not a valid " 91 "template argument for unexpected is ill-formed."); 92 93 template <class _Up, class _OtherErr> 94 friend class expected; 95 96 public: 97 using value_type = _Tp; 98 using error_type = _Err; 99 using unexpected_type = unexpected<_Err>; 100 101 template <class _Up> 102 using rebind = expected<_Up, error_type>; 103 104 // [expected.object.ctor], constructors 105 _LIBCPP_HIDE_FROM_ABI constexpr expected() 106 noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened 107 requires is_default_constructible_v<_Tp> 108 : __has_val_(true) { 109 std::construct_at(std::addressof(__union_.__val_)); 110 } 111 112 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; 113 114 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) 115 requires(is_copy_constructible_v<_Tp> && 116 is_copy_constructible_v<_Err> && 117 is_trivially_copy_constructible_v<_Tp> && 118 is_trivially_copy_constructible_v<_Err>) 119 = default; 120 121 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) 122 noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened 123 requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && 124 !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) 125 : __has_val_(__other.__has_val_) { 126 if (__has_val_) { 127 std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); 128 } else { 129 std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); 130 } 131 } 132 133 134 _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) 135 requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> 136 && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) 137 = default; 138 139 _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) 140 noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) 141 requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && 142 !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) 143 : __has_val_(__other.__has_val_) { 144 if (__has_val_) { 145 std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); 146 } else { 147 std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); 148 } 149 } 150 151 private: 152 template <class _Up, class _OtherErr, class _UfQual, class _OtherErrQual> 153 using __can_convert = 154 _And< is_constructible<_Tp, _UfQual>, 155 is_constructible<_Err, _OtherErrQual>, 156 _Not<is_constructible<_Tp, expected<_Up, _OtherErr>&>>, 157 _Not<is_constructible<_Tp, expected<_Up, _OtherErr>>>, 158 _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>&>>, 159 _Not<is_constructible<_Tp, const expected<_Up, _OtherErr>>>, 160 _Not<is_convertible<expected<_Up, _OtherErr>&, _Tp>>, 161 _Not<is_convertible<expected<_Up, _OtherErr>&&, _Tp>>, 162 _Not<is_convertible<const expected<_Up, _OtherErr>&, _Tp>>, 163 _Not<is_convertible<const expected<_Up, _OtherErr>&&, _Tp>>, 164 _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>, 165 _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>, 166 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, 167 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>> >; 168 169 170 public: 171 template <class _Up, class _OtherErr> 172 requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value 173 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _Up&, _Tp> || 174 !is_convertible_v<const _OtherErr&, _Err>) 175 expected(const expected<_Up, _OtherErr>& __other) 176 noexcept(is_nothrow_constructible_v<_Tp, const _Up&> && 177 is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened 178 : __has_val_(__other.__has_val_) { 179 if (__has_val_) { 180 std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); 181 } else { 182 std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); 183 } 184 } 185 186 template <class _Up, class _OtherErr> 187 requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value 188 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) 189 expected(expected<_Up, _OtherErr>&& __other) 190 noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened 191 : __has_val_(__other.__has_val_) { 192 if (__has_val_) { 193 std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); 194 } else { 195 std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); 196 } 197 } 198 199 template <class _Up = _Tp> 200 requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> && 201 !__is_std_unexpected<remove_cvref_t<_Up>>::value && is_constructible_v<_Tp, _Up>) 202 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) 203 expected(_Up&& __u) 204 noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened 205 : __has_val_(true) { 206 std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u)); 207 } 208 209 210 template <class _OtherErr> 211 requires is_constructible_v<_Err, const _OtherErr&> 212 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) 213 expected(const unexpected<_OtherErr>& __unex) 214 noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened 215 : __has_val_(false) { 216 std::construct_at(std::addressof(__union_.__unex_), __unex.error()); 217 } 218 219 template <class _OtherErr> 220 requires is_constructible_v<_Err, _OtherErr> 221 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) 222 expected(unexpected<_OtherErr>&& __unex) 223 noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened 224 : __has_val_(false) { 225 std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); 226 } 227 228 template <class... _Args> 229 requires is_constructible_v<_Tp, _Args...> 230 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) 231 noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened 232 : __has_val_(true) { 233 std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); 234 } 235 236 template <class _Up, class... _Args> 237 requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > 238 _LIBCPP_HIDE_FROM_ABI constexpr explicit 239 expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) 240 noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened 241 : __has_val_(true) { 242 std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); 243 } 244 245 template <class... _Args> 246 requires is_constructible_v<_Err, _Args...> 247 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) 248 noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened 249 : __has_val_(false) { 250 std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); 251 } 252 253 template <class _Up, class... _Args> 254 requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > 255 _LIBCPP_HIDE_FROM_ABI constexpr explicit 256 expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) 257 noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened 258 : __has_val_(false) { 259 std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); 260 } 261 262 // [expected.object.dtor], destructor 263 264 _LIBCPP_HIDE_FROM_ABI constexpr ~expected() 265 requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) 266 = default; 267 268 _LIBCPP_HIDE_FROM_ABI constexpr ~expected() 269 requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) 270 { 271 if (__has_val_) { 272 std::destroy_at(std::addressof(__union_.__val_)); 273 } else { 274 std::destroy_at(std::addressof(__union_.__unex_)); 275 } 276 } 277 278 private: 279 template <class _T1, class _T2, class... _Args> 280 _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) { 281 if constexpr (is_nothrow_constructible_v<_T1, _Args...>) { 282 std::destroy_at(std::addressof(__oldval)); 283 std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); 284 } else if constexpr (is_nothrow_move_constructible_v<_T1>) { 285 _T1 __tmp(std::forward<_Args>(__args)...); 286 std::destroy_at(std::addressof(__oldval)); 287 std::construct_at(std::addressof(__newval), std::move(__tmp)); 288 } else { 289 static_assert( 290 is_nothrow_move_constructible_v<_T2>, 291 "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can " 292 "be reverted to the previous state in case an exception is thrown during the assignment."); 293 _T2 __tmp(std::move(__oldval)); 294 std::destroy_at(std::addressof(__oldval)); 295 auto __trans = 296 std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); }); 297 std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); 298 __trans.__complete(); 299 } 300 } 301 302 public: 303 // [expected.object.assign], assignment 304 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; 305 306 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) 307 noexcept(is_nothrow_copy_assignable_v<_Tp> && 308 is_nothrow_copy_constructible_v<_Tp> && 309 is_nothrow_copy_assignable_v<_Err> && 310 is_nothrow_copy_constructible_v<_Err>) // strengthened 311 requires(is_copy_assignable_v<_Tp> && 312 is_copy_constructible_v<_Tp> && 313 is_copy_assignable_v<_Err> && 314 is_copy_constructible_v<_Err> && 315 (is_nothrow_move_constructible_v<_Tp> || 316 is_nothrow_move_constructible_v<_Err>)) 317 { 318 if (__has_val_ && __rhs.__has_val_) { 319 __union_.__val_ = __rhs.__union_.__val_; 320 } else if (__has_val_) { 321 __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_); 322 } else if (__rhs.__has_val_) { 323 __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_); 324 } else { 325 __union_.__unex_ = __rhs.__union_.__unex_; 326 } 327 // note: only reached if no exception+rollback was done inside __reinit_expected 328 __has_val_ = __rhs.__has_val_; 329 return *this; 330 } 331 332 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) 333 noexcept(is_nothrow_move_assignable_v<_Tp> && 334 is_nothrow_move_constructible_v<_Tp> && 335 is_nothrow_move_assignable_v<_Err> && 336 is_nothrow_move_constructible_v<_Err>) 337 requires(is_move_constructible_v<_Tp> && 338 is_move_assignable_v<_Tp> && 339 is_move_constructible_v<_Err> && 340 is_move_assignable_v<_Err> && 341 (is_nothrow_move_constructible_v<_Tp> || 342 is_nothrow_move_constructible_v<_Err>)) 343 { 344 if (__has_val_ && __rhs.__has_val_) { 345 __union_.__val_ = std::move(__rhs.__union_.__val_); 346 } else if (__has_val_) { 347 __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_)); 348 } else if (__rhs.__has_val_) { 349 __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_)); 350 } else { 351 __union_.__unex_ = std::move(__rhs.__union_.__unex_); 352 } 353 // note: only reached if no exception+rollback was done inside __reinit_expected 354 __has_val_ = __rhs.__has_val_; 355 return *this; 356 } 357 358 template <class _Up = _Tp> 359 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) 360 requires(!is_same_v<expected, remove_cvref_t<_Up>> && 361 !__is_std_unexpected<remove_cvref_t<_Up>>::value && 362 is_constructible_v<_Tp, _Up> && 363 is_assignable_v<_Tp&, _Up> && 364 (is_nothrow_constructible_v<_Tp, _Up> || 365 is_nothrow_move_constructible_v<_Tp> || 366 is_nothrow_move_constructible_v<_Err>)) 367 { 368 if (__has_val_) { 369 __union_.__val_ = std::forward<_Up>(__v); 370 } else { 371 __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v)); 372 __has_val_ = true; 373 } 374 return *this; 375 } 376 377 private: 378 template <class _OtherErrQual> 379 static constexpr bool __can_assign_from_unexpected = 380 _And< is_constructible<_Err, _OtherErrQual>, 381 is_assignable<_Err&, _OtherErrQual>, 382 _Lazy<_Or, 383 is_nothrow_constructible<_Err, _OtherErrQual>, 384 is_nothrow_move_constructible<_Tp>, 385 is_nothrow_move_constructible<_Err>> >::value; 386 387 public: 388 template <class _OtherErr> 389 requires(__can_assign_from_unexpected<const _OtherErr&>) 390 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { 391 if (__has_val_) { 392 __reinit_expected(__union_.__unex_, __union_.__val_, __un.error()); 393 __has_val_ = false; 394 } else { 395 __union_.__unex_ = __un.error(); 396 } 397 return *this; 398 } 399 400 template <class _OtherErr> 401 requires(__can_assign_from_unexpected<_OtherErr>) 402 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { 403 if (__has_val_) { 404 __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error())); 405 __has_val_ = false; 406 } else { 407 __union_.__unex_ = std::move(__un.error()); 408 } 409 return *this; 410 } 411 412 template <class... _Args> 413 requires is_nothrow_constructible_v<_Tp, _Args...> 414 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept { 415 if (__has_val_) { 416 std::destroy_at(std::addressof(__union_.__val_)); 417 } else { 418 std::destroy_at(std::addressof(__union_.__unex_)); 419 __has_val_ = true; 420 } 421 return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); 422 } 423 424 template <class _Up, class... _Args> 425 requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... > 426 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept { 427 if (__has_val_) { 428 std::destroy_at(std::addressof(__union_.__val_)); 429 } else { 430 std::destroy_at(std::addressof(__union_.__unex_)); 431 __has_val_ = true; 432 } 433 return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); 434 } 435 436 437 public: 438 // [expected.object.swap], swap 439 _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) 440 noexcept(is_nothrow_move_constructible_v<_Tp> && 441 is_nothrow_swappable_v<_Tp> && 442 is_nothrow_move_constructible_v<_Err> && 443 is_nothrow_swappable_v<_Err>) 444 requires(is_swappable_v<_Tp> && 445 is_swappable_v<_Err> && 446 is_move_constructible_v<_Tp> && 447 is_move_constructible_v<_Err> && 448 (is_nothrow_move_constructible_v<_Tp> || 449 is_nothrow_move_constructible_v<_Err>)) 450 { 451 auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { 452 if constexpr (is_nothrow_move_constructible_v<_Err>) { 453 _Err __tmp(std::move(__with_err.__union_.__unex_)); 454 std::destroy_at(std::addressof(__with_err.__union_.__unex_)); 455 auto __trans = std::__make_exception_guard([&] { 456 std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp)); 457 }); 458 std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_)); 459 __trans.__complete(); 460 std::destroy_at(std::addressof(__with_val.__union_.__val_)); 461 std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp)); 462 } else { 463 static_assert(is_nothrow_move_constructible_v<_Tp>, 464 "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so " 465 "that it can be reverted to the previous state in case an exception is thrown during swap."); 466 _Tp __tmp(std::move(__with_val.__union_.__val_)); 467 std::destroy_at(std::addressof(__with_val.__union_.__val_)); 468 auto __trans = std::__make_exception_guard([&] { 469 std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); 470 }); 471 std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); 472 __trans.__complete(); 473 std::destroy_at(std::addressof(__with_err.__union_.__unex_)); 474 std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp)); 475 } 476 __with_val.__has_val_ = false; 477 __with_err.__has_val_ = true; 478 }; 479 480 if (__has_val_) { 481 if (__rhs.__has_val_) { 482 using std::swap; 483 swap(__union_.__val_, __rhs.__union_.__val_); 484 } else { 485 __swap_val_unex_impl(*this, __rhs); 486 } 487 } else { 488 if (__rhs.__has_val_) { 489 __swap_val_unex_impl(__rhs, *this); 490 } else { 491 using std::swap; 492 swap(__union_.__unex_, __rhs.__union_.__unex_); 493 } 494 } 495 } 496 497 _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) 498 noexcept(noexcept(__x.swap(__y))) 499 requires requires { __x.swap(__y); } 500 { 501 __x.swap(__y); 502 } 503 504 // [expected.object.obs], observers 505 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { 506 _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); 507 return std::addressof(__union_.__val_); 508 } 509 510 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { 511 _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); 512 return std::addressof(__union_.__val_); 513 } 514 515 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { 516 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); 517 return __union_.__val_; 518 } 519 520 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { 521 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); 522 return __union_.__val_; 523 } 524 525 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { 526 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); 527 return std::move(__union_.__val_); 528 } 529 530 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { 531 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); 532 return std::move(__union_.__val_); 533 } 534 535 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } 536 537 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } 538 539 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { 540 if (!__has_val_) { 541 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); 542 } 543 return __union_.__val_; 544 } 545 546 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { 547 if (!__has_val_) { 548 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); 549 } 550 return __union_.__val_; 551 } 552 553 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { 554 if (!__has_val_) { 555 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); 556 } 557 return std::move(__union_.__val_); 558 } 559 560 _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { 561 if (!__has_val_) { 562 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); 563 } 564 return std::move(__union_.__val_); 565 } 566 567 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { 568 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 569 return __union_.__unex_; 570 } 571 572 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { 573 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 574 return __union_.__unex_; 575 } 576 577 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { 578 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 579 return std::move(__union_.__unex_); 580 } 581 582 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { 583 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 584 return std::move(__union_.__unex_); 585 } 586 587 template <class _Up> 588 _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { 589 static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible"); 590 static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); 591 return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v)); 592 } 593 594 template <class _Up> 595 _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { 596 static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible"); 597 static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); 598 return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); 599 } 600 601 // [expected.object.eq], equality operators 602 template <class _T2, class _E2> 603 requires(!is_void_v<_T2>) 604 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { 605 if (__x.__has_val_ != __y.__has_val_) { 606 return false; 607 } else { 608 if (__x.__has_val_) { 609 return __x.__union_.__val_ == __y.__union_.__val_; 610 } else { 611 return __x.__union_.__unex_ == __y.__union_.__unex_; 612 } 613 } 614 } 615 616 template <class _T2> 617 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) { 618 return __x.__has_val_ && static_cast<bool>(__x.__union_.__val_ == __v); 619 } 620 621 template <class _E2> 622 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) { 623 return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __e.error()); 624 } 625 626 private: 627 struct __empty_t {}; 628 // use named union because [[no_unique_address]] cannot be applied to an unnamed union 629 _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { 630 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} 631 632 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() 633 requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) 634 = default; 635 636 // the expected's destructor handles this 637 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() 638 requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) 639 {} 640 641 _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; 642 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; 643 _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; 644 } __union_; 645 646 bool __has_val_; 647 }; 648 649 template <class _Tp, class _Err> 650 requires is_void_v<_Tp> 651 class expected<_Tp, _Err> { 652 static_assert(__valid_std_unexpected<_Err>::value, 653 "[expected.void.general] A program that instantiates expected<T, E> with a E that is not a " 654 "valid argument for unexpected<E> is ill-formed"); 655 656 template <class, class> 657 friend class expected; 658 659 template <class _Up, class _OtherErr, class _OtherErrQual> 660 using __can_convert = 661 _And< is_void<_Up>, 662 is_constructible<_Err, _OtherErrQual>, 663 _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>&>>, 664 _Not<is_constructible<unexpected<_Err>, expected<_Up, _OtherErr>>>, 665 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>&>>, 666 _Not<is_constructible<unexpected<_Err>, const expected<_Up, _OtherErr>>>>; 667 668 public: 669 using value_type = _Tp; 670 using error_type = _Err; 671 using unexpected_type = unexpected<_Err>; 672 673 template <class _Up> 674 using rebind = expected<_Up, error_type>; 675 676 // [expected.void.ctor], constructors 677 _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {} 678 679 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; 680 681 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) 682 requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) 683 = default; 684 685 _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) 686 noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened 687 requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) 688 : __has_val_(__rhs.__has_val_) { 689 if (!__rhs.__has_val_) { 690 std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); 691 } 692 } 693 694 _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) 695 requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) 696 = default; 697 698 _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) 699 noexcept(is_nothrow_move_constructible_v<_Err>) 700 requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) 701 : __has_val_(__rhs.__has_val_) { 702 if (!__rhs.__has_val_) { 703 std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); 704 } 705 } 706 707 template <class _Up, class _OtherErr> 708 requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value 709 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) 710 expected(const expected<_Up, _OtherErr>& __rhs) 711 noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened 712 : __has_val_(__rhs.__has_val_) { 713 if (!__rhs.__has_val_) { 714 std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); 715 } 716 } 717 718 template <class _Up, class _OtherErr> 719 requires __can_convert<_Up, _OtherErr, _OtherErr>::value 720 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) 721 expected(expected<_Up, _OtherErr>&& __rhs) 722 noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened 723 : __has_val_(__rhs.__has_val_) { 724 if (!__rhs.__has_val_) { 725 std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); 726 } 727 } 728 729 template <class _OtherErr> 730 requires is_constructible_v<_Err, const _OtherErr&> 731 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<const _OtherErr&, _Err>) 732 expected(const unexpected<_OtherErr>& __unex) 733 noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened 734 : __has_val_(false) { 735 std::construct_at(std::addressof(__union_.__unex_), __unex.error()); 736 } 737 738 template <class _OtherErr> 739 requires is_constructible_v<_Err, _OtherErr> 740 _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) 741 expected(unexpected<_OtherErr>&& __unex) 742 noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened 743 : __has_val_(false) { 744 std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); 745 } 746 747 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} 748 749 template <class... _Args> 750 requires is_constructible_v<_Err, _Args...> 751 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) 752 noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened 753 : __has_val_(false) { 754 std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); 755 } 756 757 template <class _Up, class... _Args> 758 requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > 759 _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) 760 noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened 761 : __has_val_(false) { 762 std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); 763 } 764 765 // [expected.void.dtor], destructor 766 767 _LIBCPP_HIDE_FROM_ABI constexpr ~expected() 768 requires is_trivially_destructible_v<_Err> 769 = default; 770 771 _LIBCPP_HIDE_FROM_ABI constexpr ~expected() 772 requires(!is_trivially_destructible_v<_Err>) 773 { 774 if (!__has_val_) { 775 std::destroy_at(std::addressof(__union_.__unex_)); 776 } 777 } 778 779 // [expected.void.assign], assignment 780 781 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; 782 783 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) 784 noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened 785 requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) 786 { 787 if (__has_val_) { 788 if (!__rhs.__has_val_) { 789 std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); 790 __has_val_ = false; 791 } 792 } else { 793 if (__rhs.__has_val_) { 794 std::destroy_at(std::addressof(__union_.__unex_)); 795 __has_val_ = true; 796 } else { 797 __union_.__unex_ = __rhs.__union_.__unex_; 798 } 799 } 800 return *this; 801 } 802 803 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete; 804 805 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) 806 noexcept(is_nothrow_move_assignable_v<_Err> && 807 is_nothrow_move_constructible_v<_Err>) 808 requires(is_move_assignable_v<_Err> && 809 is_move_constructible_v<_Err>) 810 { 811 if (__has_val_) { 812 if (!__rhs.__has_val_) { 813 std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); 814 __has_val_ = false; 815 } 816 } else { 817 if (__rhs.__has_val_) { 818 std::destroy_at(std::addressof(__union_.__unex_)); 819 __has_val_ = true; 820 } else { 821 __union_.__unex_ = std::move(__rhs.__union_.__unex_); 822 } 823 } 824 return *this; 825 } 826 827 template <class _OtherErr> 828 requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>) 829 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { 830 if (__has_val_) { 831 std::construct_at(std::addressof(__union_.__unex_), __un.error()); 832 __has_val_ = false; 833 } else { 834 __union_.__unex_ = __un.error(); 835 } 836 return *this; 837 } 838 839 template <class _OtherErr> 840 requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>) 841 _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { 842 if (__has_val_) { 843 std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error())); 844 __has_val_ = false; 845 } else { 846 __union_.__unex_ = std::move(__un.error()); 847 } 848 return *this; 849 } 850 851 _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept { 852 if (!__has_val_) { 853 std::destroy_at(std::addressof(__union_.__unex_)); 854 __has_val_ = true; 855 } 856 } 857 858 // [expected.void.swap], swap 859 _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) 860 noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) 861 requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) 862 { 863 auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { 864 std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); 865 std::destroy_at(std::addressof(__with_err.__union_.__unex_)); 866 __with_val.__has_val_ = false; 867 __with_err.__has_val_ = true; 868 }; 869 870 if (__has_val_) { 871 if (!__rhs.__has_val_) { 872 __swap_val_unex_impl(*this, __rhs); 873 } 874 } else { 875 if (__rhs.__has_val_) { 876 __swap_val_unex_impl(__rhs, *this); 877 } else { 878 using std::swap; 879 swap(__union_.__unex_, __rhs.__union_.__unex_); 880 } 881 } 882 } 883 884 _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) 885 noexcept(noexcept(__x.swap(__y))) 886 requires requires { __x.swap(__y); } 887 { 888 __x.swap(__y); 889 } 890 891 // [expected.void.obs], observers 892 _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } 893 894 _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } 895 896 _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { 897 _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); 898 } 899 900 _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { 901 if (!__has_val_) { 902 __expected::__throw_bad_expected_access<_Err>(__union_.__unex_); 903 } 904 } 905 906 _LIBCPP_HIDE_FROM_ABI constexpr void value() && { 907 if (!__has_val_) { 908 __expected::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); 909 } 910 } 911 912 _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { 913 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 914 return __union_.__unex_; 915 } 916 917 _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { 918 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 919 return __union_.__unex_; 920 } 921 922 _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { 923 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 924 return std::move(__union_.__unex_); 925 } 926 927 _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { 928 _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); 929 return std::move(__union_.__unex_); 930 } 931 932 // [expected.void.eq], equality operators 933 template <class _T2, class _E2> 934 requires is_void_v<_T2> 935 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { 936 if (__x.__has_val_ != __y.__has_val_) { 937 return false; 938 } else { 939 return __x.__has_val_ || static_cast<bool>(__x.__union_.__unex_ == __y.__union_.__unex_); 940 } 941 } 942 943 template <class _E2> 944 _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) { 945 return !__x.__has_val_ && static_cast<bool>(__x.__union_.__unex_ == __y.error()); 946 } 947 948 private: 949 struct __empty_t {}; 950 // use named union because [[no_unique_address]] cannot be applied to an unnamed union 951 _LIBCPP_NO_UNIQUE_ADDRESS union __union_t { 952 _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} 953 954 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() 955 requires(is_trivially_destructible_v<_Err>) 956 = default; 957 958 // the expected's destructor handles this 959 _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() 960 requires(!is_trivially_destructible_v<_Err>) 961 {} 962 963 _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; 964 _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; 965 } __union_; 966 967 bool __has_val_; 968 }; 969 970 _LIBCPP_END_NAMESPACE_STD 971 972 #endif // _LIBCPP_STD_VER >= 23 973 974 #endif // _LIBCPP___EXPECTED_EXPECTED_H 975