File indexing completed on 2025-12-16 09:59:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifndef BOOST_OUTCOME_BASIC_OUTCOME_HPP
0032 #define BOOST_OUTCOME_BASIC_OUTCOME_HPP
0033
0034 #include "config.hpp"
0035
0036 #include "basic_result.hpp"
0037
0038 #include "detail/basic_outcome_exception_observers.hpp"
0039 #include "detail/basic_outcome_failure_observers.hpp"
0040
0041 #ifdef __clang__
0042 #pragma clang diagnostic push
0043 #pragma clang diagnostic ignored "-Wdocumentation"
0044 #endif
0045
0046 #if defined(_MSC_VER) && !defined(__clang__)
0047 #pragma warning(push)
0048 #pragma warning(disable : 6287)
0049 #endif
0050
0051 BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
0052
0053 template <class R, class S, class P, class NoValuePolicy>
0054 class basic_outcome;
0055
0056 namespace detail
0057 {
0058
0059 template <class value_type, class error_type, class exception_type> struct outcome_predicates
0060 {
0061 using result = result_predicates<value_type, error_type>;
0062
0063
0064 static constexpr bool implicit_constructors_enabled =
0065 result::implicit_constructors_enabled
0066 && !detail::is_implicitly_constructible<value_type, exception_type>
0067 && !detail::is_implicitly_constructible<error_type, exception_type>
0068 && !detail::is_implicitly_constructible<exception_type, value_type>
0069 && !detail::is_implicitly_constructible<exception_type, error_type>;
0070
0071
0072 template <class T>
0073 static constexpr bool enable_value_converting_constructor =
0074 implicit_constructors_enabled
0075 && result::template enable_value_converting_constructor<T>
0076 && !detail::is_implicitly_constructible<exception_type, T>;
0077
0078
0079 template <class T>
0080 static constexpr bool enable_error_converting_constructor =
0081 implicit_constructors_enabled
0082 && result::template enable_error_converting_constructor<T>
0083 && !detail::is_implicitly_constructible<exception_type, T>;
0084
0085
0086 template <class ErrorCondEnum>
0087 static constexpr bool enable_error_condition_converting_constructor = result::template enable_error_condition_converting_constructor<ErrorCondEnum>
0088 && !detail::is_implicitly_constructible<exception_type, ErrorCondEnum>;
0089
0090
0091 template <class T>
0092 static constexpr bool enable_exception_converting_constructor =
0093 implicit_constructors_enabled
0094 && !is_in_place_type_t<std::decay_t<T>>::value
0095 && !detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T> &&
0096 detail::is_implicitly_constructible<exception_type, T>;
0097
0098
0099 template <class T, class U>
0100 static constexpr bool enable_error_exception_converting_constructor =
0101 implicit_constructors_enabled
0102 && !is_in_place_type_t<std::decay_t<T>>::value
0103 && !detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T>
0104 && !detail::is_implicitly_constructible<value_type, U> && detail::is_implicitly_constructible<exception_type, U>;
0105
0106
0107 template <class T, class U, class V, class W>
0108 static constexpr bool enable_compatible_conversion =
0109 (std::is_void<T>::value ||
0110 detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>)
0111 &&(std::is_void<U>::value ||
0112 detail::is_explicitly_constructible<error_type, typename basic_outcome<T, U, V, W>::error_type>)
0113 &&(std::is_void<V>::value ||
0114 detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>)
0115 ;
0116
0117
0118 template <class T, class U, class V, class W>
0119 static constexpr bool enable_make_error_code_compatible_conversion =
0120 trait::is_error_code_available<std::decay_t<error_type>>::value
0121 && !enable_compatible_conversion<T, U, V, W>
0122 && (std::is_void<T>::value ||
0123 detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>)
0124 &&detail::is_explicitly_constructible<error_type,
0125 typename trait::is_error_code_available<U>::type>
0126 && (std::is_void<V>::value ||
0127 detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>);
0128
0129
0130 struct disable_inplace_value_error_exception_constructor;
0131 template <class... Args>
0132 using choose_inplace_value_error_exception_constructor = std::conditional_t<
0133 ((static_cast<int>(detail::is_constructible<value_type, Args...>) + static_cast<int>(detail::is_constructible<error_type, Args...>) +
0134 static_cast<int>(detail::is_constructible<exception_type, Args...>)) > 1),
0135 disable_inplace_value_error_exception_constructor,
0136 std::conditional_t<
0137 detail::is_constructible<value_type, Args...>,
0138 value_type,
0139 std::conditional_t<
0140 detail::is_constructible<error_type, Args...>,
0141 error_type,
0142 std::conditional_t<
0143 detail::is_constructible<exception_type, Args...>,
0144 exception_type,
0145 disable_inplace_value_error_exception_constructor>>>>;
0146 template <class... Args>
0147 static constexpr bool enable_inplace_value_error_exception_constructor =
0148 implicit_constructors_enabled &&
0149 !std::is_same<choose_inplace_value_error_exception_constructor<Args...>, disable_inplace_value_error_exception_constructor>::value;
0150 };
0151
0152
0153 template <class Base, class R, class S, class P, class NoValuePolicy>
0154 using select_basic_outcome_failure_observers =
0155 std::conditional_t<trait::is_error_code_available<S>::value && trait::is_exception_ptr_available<P>::value,
0156 basic_outcome_failure_observers<Base, R, S, P, NoValuePolicy>, Base>;
0157
0158 template <class T, class U, class V> constexpr inline const V &extract_exception_from_failure(const failure_type<U, V> &v)
0159 {
0160 return v.exception();
0161 }
0162 template <class T, class U, class V> constexpr inline V &&extract_exception_from_failure(failure_type<U, V> &&v)
0163 {
0164 return static_cast<failure_type<U, V> &&>(v).exception();
0165 }
0166 template <class T, class U> constexpr inline const U &extract_exception_from_failure(const failure_type<U, void> &v)
0167 {
0168 return v.error();
0169 }
0170 template <class T, class U> constexpr inline U &&extract_exception_from_failure(failure_type<U, void> &&v)
0171 {
0172 return static_cast<failure_type<U, void> &&>(v).error();
0173 }
0174
0175 template <class T> struct is_basic_outcome
0176 {
0177 static constexpr bool value = false;
0178 };
0179 template <class R, class S, class T, class N> struct is_basic_outcome<basic_outcome<R, S, T, N>>
0180 {
0181 static constexpr bool value = true;
0182 };
0183 }
0184
0185
0186
0187
0188 template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>;
0189
0190
0191
0192 template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value;
0193
0194 namespace concepts
0195 {
0196 #if defined(__cpp_concepts)
0197
0198
0199
0200 template <class U>
0201 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL basic_outcome =
0202 BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value ||
0203 (requires(U v) {
0204 BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>(v);
0205 } &&
0206 detail::convertible<
0207 U, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>> &&
0208 detail::base_of<
0209 BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>, U>);
0210 #else
0211 namespace detail
0212 {
0213 inline no_match match_basic_outcome(...);
0214 template <class R, class S, class P, class NVP, class T,
0215 typename = typename T::value_type,
0216 typename = typename T::error_type,
0217 typename = typename T::exception_type,
0218 typename = typename T::no_value_policy_type,
0219 typename std::enable_if_t<std::is_convertible<T, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>>::value &&
0220 std::is_base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>, T>::value,
0221 bool> = true>
0222 inline BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> match_basic_outcome(BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> &&, T &&);
0223
0224 template <class U>
0225 static constexpr bool basic_outcome =
0226 BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value ||
0227 !std::is_same<no_match, decltype(match_basic_outcome(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>(),
0228 std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
0229 }
0230
0231
0232
0233 template <class U> static constexpr bool basic_outcome = detail::basic_outcome<U>;
0234 #endif
0235 }
0236
0237 namespace hooks
0238 {
0239
0240
0241
0242 template <class R, class S, class P, class NoValuePolicy, class U>
0243 constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept;
0244 }
0245
0246
0247
0248
0249 template <class R, class S, class P, class NoValuePolicy>
0250 class BOOST_OUTCOME_NODISCARD basic_outcome
0251 #if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
0252 : public detail::basic_outcome_failure_observers<detail::basic_result_final<R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>,
0253 public detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>,
0254 public detail::basic_result_final<R, S, NoValuePolicy>
0255 #else
0256 : public detail::select_basic_outcome_failure_observers<
0257 detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>
0258 #endif
0259 {
0260 static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used");
0261 static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible");
0262 using base = detail::select_basic_outcome_failure_observers<
0263 detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>;
0264 friend struct policy::base;
0265 template <class T, class U, class V, class W>
0266 friend class basic_outcome;
0267 template <class T, class U, class V, class W, class X>
0268 friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept;
0269
0270 struct implicit_constructors_disabled_tag
0271 {
0272 };
0273 struct value_converting_constructor_tag
0274 {
0275 };
0276 struct error_converting_constructor_tag
0277 {
0278 };
0279 struct error_condition_converting_constructor_tag
0280 {
0281 };
0282 struct exception_converting_constructor_tag
0283 {
0284 };
0285 struct error_exception_converting_constructor_tag
0286 {
0287 };
0288 struct explicit_valueorerror_converting_constructor_tag
0289 {
0290 };
0291 struct explicit_compatible_copy_conversion_tag
0292 {
0293 };
0294 struct explicit_compatible_move_conversion_tag
0295 {
0296 };
0297 struct explicit_make_error_code_compatible_copy_conversion_tag
0298 {
0299 };
0300 struct explicit_make_error_code_compatible_move_conversion_tag
0301 {
0302 };
0303 struct error_failure_tag
0304 {
0305 };
0306 struct exception_failure_tag
0307 {
0308 };
0309
0310 struct disable_in_place_value_type
0311 {
0312 };
0313 struct disable_in_place_error_type
0314 {
0315 };
0316 struct disable_in_place_exception_type
0317 {
0318 };
0319
0320 public:
0321 using value_type = R;
0322 using error_type = S;
0323 using exception_type = P;
0324 using no_value_policy_type = NoValuePolicy;
0325
0326 template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>;
0327
0328 protected:
0329
0330 struct predicate
0331 {
0332 using base = detail::outcome_predicates<value_type, error_type, exception_type>;
0333
0334
0335 static constexpr bool constructors_enabled =
0336 (!std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value || (std::is_void<value_type>::value && std::is_void<error_type>::value))
0337 && (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value ||
0338 (std::is_void<value_type>::value && std::is_void<exception_type>::value))
0339 && (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value ||
0340 (std::is_void<error_type>::value && std::is_void<exception_type>::value))
0341 ;
0342
0343
0344 static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
0345
0346
0347 template <class T>
0348 static constexpr bool enable_value_converting_constructor =
0349 constructors_enabled
0350 && !std::is_same<std::decay_t<T>, basic_outcome>::value
0351 && base::template enable_value_converting_constructor<T>;
0352
0353
0354 template <class T>
0355 static constexpr bool enable_error_converting_constructor =
0356 constructors_enabled
0357 && !std::is_same<std::decay_t<T>, basic_outcome>::value
0358 && base::template enable_error_converting_constructor<T>;
0359
0360
0361 template <class ErrorCondEnum>
0362 static constexpr bool enable_error_condition_converting_constructor =
0363 constructors_enabled
0364 && !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value
0365 && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
0366
0367
0368 template <class T>
0369 static constexpr bool enable_exception_converting_constructor =
0370 constructors_enabled
0371 && !std::is_same<std::decay_t<T>, basic_outcome>::value
0372 && base::template enable_exception_converting_constructor<T>;
0373
0374
0375 template <class T, class U>
0376 static constexpr bool enable_error_exception_converting_constructor =
0377 constructors_enabled
0378 && !std::is_same<std::decay_t<T>, basic_outcome>::value
0379 && base::template enable_error_exception_converting_constructor<T, U>;
0380
0381
0382 template <class T, class U, class V, class W>
0383 static constexpr bool enable_compatible_conversion =
0384 constructors_enabled
0385 && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value
0386 && base::template enable_compatible_conversion<T, U, V, W>;
0387
0388
0389 template <class T, class U, class V, class W>
0390 static constexpr bool enable_make_error_code_compatible_conversion =
0391 constructors_enabled
0392 && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value
0393 && base::template enable_make_error_code_compatible_conversion<T, U, V, W>;
0394
0395
0396 template <class... Args>
0397 static constexpr bool enable_inplace_value_constructor =
0398 constructors_enabled
0399 && (std::is_void<value_type>::value
0400 || detail::is_constructible<value_type, Args...>);
0401
0402
0403 template <class... Args>
0404 static constexpr bool enable_inplace_error_constructor =
0405 constructors_enabled
0406 && (std::is_void<error_type>::value
0407 || detail::is_constructible<error_type, Args...>);
0408
0409
0410 template <class... Args>
0411 static constexpr bool enable_inplace_exception_constructor =
0412 constructors_enabled
0413 && (std::is_void<exception_type>::value
0414 || detail::is_constructible<exception_type, Args...>);
0415
0416
0417 template <class... Args>
0418 static constexpr bool enable_inplace_value_error_exception_constructor =
0419 constructors_enabled
0420 && base::template enable_inplace_value_error_exception_constructor<Args...>;
0421 template <class... Args>
0422 using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>;
0423 };
0424
0425 public:
0426 using value_type_if_enabled =
0427 std::conditional_t<std::is_same<value_type, error_type>::value || std::is_same<value_type, exception_type>::value, disable_in_place_value_type, value_type>;
0428 using error_type_if_enabled =
0429 std::conditional_t<std::is_same<error_type, value_type>::value || std::is_same<error_type, exception_type>::value, disable_in_place_error_type, error_type>;
0430 using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value,
0431 disable_in_place_exception_type, exception_type>;
0432
0433 protected:
0434 detail::devoid<exception_type> _ptr;
0435
0436 public:
0437
0438
0439
0440 BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
0441 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0)))
0442 basic_outcome(Arg && , Args &&...) = delete;
0443
0444
0445
0446
0447 BOOST_OUTCOME_TEMPLATE(class T)
0448 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled
0449 && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> ||
0450 detail::is_implicitly_constructible<exception_type, T>) )))
0451 basic_outcome(T && , implicit_constructors_disabled_tag = implicit_constructors_disabled_tag()) =
0452 delete;
0453
0454
0455
0456
0457 BOOST_OUTCOME_TEMPLATE(class T)
0458 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
0459 constexpr basic_outcome(T &&t, value_converting_constructor_tag = value_converting_constructor_tag()) noexcept(
0460 detail::is_nothrow_constructible<value_type, T>)
0461 : base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)}
0462 , _ptr()
0463 {
0464 no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
0465 }
0466
0467
0468
0469 BOOST_OUTCOME_TEMPLATE(class T)
0470 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
0471 constexpr basic_outcome(T &&t, error_converting_constructor_tag = error_converting_constructor_tag()) noexcept(
0472 detail::is_nothrow_constructible<error_type, T>)
0473 : base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)}
0474 , _ptr()
0475 {
0476 no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
0477 }
0478
0479
0480
0481 BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
0482 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))),
0483 BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
0484 constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag = error_condition_converting_constructor_tag()) noexcept(
0485 noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t)))))
0486 : base{in_place_type<typename base::_error_type>, make_error_code(t)}
0487 {
0488 no_value_policy_type::on_outcome_construction(this, static_cast<ErrorCondEnum &&>(t));
0489 }
0490
0491
0492
0493 BOOST_OUTCOME_TEMPLATE(class T)
0494 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>))
0495 constexpr basic_outcome(T &&t, exception_converting_constructor_tag = exception_converting_constructor_tag()) noexcept(
0496 detail::is_nothrow_constructible<exception_type, T>)
0497 : base()
0498 , _ptr(static_cast<T &&>(t))
0499 {
0500 this->_state._status.set_have_exception(true);
0501 no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t));
0502 }
0503
0504
0505
0506 BOOST_OUTCOME_TEMPLATE(class T, class U)
0507 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>))
0508 constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag = error_exception_converting_constructor_tag()) noexcept(
0509 detail::is_nothrow_constructible<error_type, T> && detail::is_nothrow_constructible<exception_type, U>)
0510 : base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)}
0511 , _ptr(static_cast<U &&>(b))
0512 {
0513 this->_state._status.set_have_exception(true);
0514 no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b));
0515 }
0516
0517
0518
0519
0520 BOOST_OUTCOME_TEMPLATE(class T)
0521 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>),
0522 BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !concepts::basic_outcome<T>),
0523 BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>())))
0524 constexpr explicit basic_outcome(T &&o,
0525 explicit_valueorerror_converting_constructor_tag = explicit_valueorerror_converting_constructor_tag())
0526 : basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))}
0527 {
0528 }
0529
0530
0531
0532 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
0533 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
0534 constexpr explicit basic_outcome(
0535 const basic_outcome<T, U, V, W> &o,
0536 explicit_compatible_copy_conversion_tag = explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0537 detail::is_nothrow_constructible<error_type, U> &&
0538 detail::is_nothrow_constructible<exception_type, V>)
0539 : base{typename base::compatible_conversion_tag(), o}
0540 , _ptr(o._ptr)
0541 {
0542 no_value_policy_type::on_outcome_copy_construction(this, o);
0543 }
0544
0545
0546
0547 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
0548 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
0549 constexpr explicit basic_outcome(
0550 basic_outcome<T, U, V, W> &&o,
0551 explicit_compatible_move_conversion_tag = explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0552 detail::is_nothrow_constructible<error_type, U> &&
0553 detail::is_nothrow_constructible<exception_type, V>)
0554 : base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)}
0555 , _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr))
0556 {
0557 no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o));
0558 }
0559
0560
0561
0562 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
0563 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
0564 constexpr explicit basic_outcome(
0565 const basic_result<T, U, V> &o,
0566 explicit_compatible_copy_conversion_tag = explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0567 detail::is_nothrow_constructible<error_type, U> &&
0568 detail::is_nothrow_constructible<exception_type>)
0569 : base{typename base::compatible_conversion_tag(), o}
0570 , _ptr()
0571 {
0572 no_value_policy_type::on_outcome_copy_construction(this, o);
0573 }
0574
0575
0576
0577 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
0578 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
0579 constexpr explicit basic_outcome(
0580 basic_result<T, U, V> &&o,
0581 explicit_compatible_move_conversion_tag = explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0582 detail::is_nothrow_constructible<error_type, U> &&
0583 detail::is_nothrow_constructible<exception_type>)
0584 : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
0585 , _ptr()
0586 {
0587 no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
0588 }
0589
0590
0591
0592 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
0593 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
0594 constexpr explicit basic_outcome(const basic_result<T, U, V> &o,
0595 explicit_make_error_code_compatible_copy_conversion_tag =
0596 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0597 noexcept(make_error_code(std::declval<U>())) &&
0598 detail::is_nothrow_constructible<exception_type>)
0599 : base{typename base::make_error_code_compatible_conversion_tag(), o}
0600 , _ptr()
0601 {
0602 no_value_policy_type::on_outcome_copy_construction(this, o);
0603 }
0604
0605
0606
0607 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
0608 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
0609 constexpr explicit basic_outcome(basic_result<T, U, V> &&o,
0610 explicit_make_error_code_compatible_move_conversion_tag =
0611 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&
0612 noexcept(make_error_code(std::declval<U>())) &&
0613 detail::is_nothrow_constructible<exception_type>)
0614 : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
0615 , _ptr()
0616 {
0617 no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
0618 }
0619
0620
0621
0622
0623
0624 BOOST_OUTCOME_TEMPLATE(class... Args)
0625 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
0626 constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, Args &&...args) noexcept(detail::is_nothrow_constructible<value_type, Args...>)
0627 : base{_, static_cast<Args &&>(args)...}
0628 , _ptr()
0629 {
0630 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
0631 }
0632
0633
0634
0635 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
0636 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
0637 constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
0638 Args &&...args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>)
0639 : base{_, il, static_cast<Args &&>(args)...}
0640 , _ptr()
0641 {
0642 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
0643 }
0644
0645
0646
0647 BOOST_OUTCOME_TEMPLATE(class... Args)
0648 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
0649 constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, Args &&...args) noexcept(detail::is_nothrow_constructible<error_type, Args...>)
0650 : base{_, static_cast<Args &&>(args)...}
0651 , _ptr()
0652 {
0653 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
0654 }
0655
0656
0657
0658 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
0659 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
0660 constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
0661 Args &&...args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>)
0662 : base{_, il, static_cast<Args &&>(args)...}
0663 , _ptr()
0664 {
0665 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
0666 }
0667
0668
0669
0670 BOOST_OUTCOME_TEMPLATE(class... Args)
0671 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>))
0672 constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> ,
0673 Args &&...args) noexcept(detail::is_nothrow_constructible<exception_type, Args...>)
0674 : base()
0675 , _ptr(static_cast<Args &&>(args)...)
0676 {
0677 this->_state._status.set_have_exception(true);
0678 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...);
0679 }
0680
0681
0682
0683 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
0684 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>))
0685 constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> , std::initializer_list<U> il,
0686 Args &&...args) noexcept(detail::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>)
0687 : base()
0688 , _ptr(il, static_cast<Args &&>(args)...)
0689 {
0690 this->_state._status.set_have_exception(true);
0691 no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...);
0692 }
0693
0694
0695
0696 BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
0697 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>))
0698 constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&...args) noexcept(
0699 noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(),
0700 std::declval<Args>()...)))
0701 : basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
0702 static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
0703 {
0704 }
0705
0706
0707
0708
0709 constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value)
0710 : base{in_place_type<typename base::_value_type>}
0711 {
0712 hooks::set_spare_storage(this, o.spare_storage());
0713 no_value_policy_type::on_outcome_copy_construction(this, o);
0714 }
0715
0716
0717
0718 BOOST_OUTCOME_TEMPLATE(class T)
0719 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
0720 constexpr basic_outcome(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>)
0721 : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)}
0722 {
0723 hooks::set_spare_storage(this, o.spare_storage());
0724 no_value_policy_type::on_outcome_copy_construction(this, o);
0725 }
0726
0727
0728
0729 BOOST_OUTCOME_TEMPLATE(class T)
0730 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
0731 constexpr basic_outcome(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>)
0732 : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
0733 {
0734 hooks::set_spare_storage(this, o.spare_storage());
0735 no_value_policy_type::on_outcome_move_construction(this, static_cast<success_type<T> &&>(o));
0736 }
0737
0738
0739
0740
0741 BOOST_OUTCOME_TEMPLATE(class T)
0742 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
0743 constexpr basic_outcome(const failure_type<T> &o,
0744 error_failure_tag = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>)
0745 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
0746 , _ptr()
0747 {
0748 hooks::set_spare_storage(this, o.spare_storage());
0749 no_value_policy_type::on_outcome_copy_construction(this, o);
0750 }
0751
0752
0753
0754 BOOST_OUTCOME_TEMPLATE(class T)
0755 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
0756 constexpr basic_outcome(const failure_type<T> &o,
0757 exception_failure_tag = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>)
0758 : base()
0759 , _ptr(detail::extract_exception_from_failure<exception_type>(o))
0760 {
0761 this->_state._status.set_have_exception(true);
0762 hooks::set_spare_storage(this, o.spare_storage());
0763 no_value_policy_type::on_outcome_copy_construction(this, o);
0764 }
0765
0766
0767
0768 BOOST_OUTCOME_TEMPLATE(class T)
0769 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
0770 constexpr basic_outcome(const failure_type<T> &o,
0771 explicit_make_error_code_compatible_copy_conversion_tag =
0772 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>())))
0773 : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
0774 , _ptr()
0775 {
0776 hooks::set_spare_storage(this, o.spare_storage());
0777 no_value_policy_type::on_outcome_copy_construction(this, o);
0778 }
0779
0780
0781
0782 BOOST_OUTCOME_TEMPLATE(class T, class U)
0783 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
0784 constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag = explicit_compatible_copy_conversion_tag()) noexcept(
0785 detail::is_nothrow_constructible<error_type, T> && detail::is_nothrow_constructible<exception_type, U>)
0786 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
0787 , _ptr(detail::extract_exception_from_failure<exception_type>(o))
0788 {
0789 if(!o.has_error())
0790 {
0791 this->_state._status.set_have_error(false);
0792 }
0793 if(o.has_exception())
0794 {
0795 this->_state._status.set_have_exception(true);
0796 }
0797 hooks::set_spare_storage(this, o.spare_storage());
0798 no_value_policy_type::on_outcome_copy_construction(this, o);
0799 }
0800
0801
0802
0803
0804 BOOST_OUTCOME_TEMPLATE(class T)
0805 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
0806 constexpr basic_outcome(failure_type<T> &&o,
0807 error_failure_tag = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>)
0808 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
0809 , _ptr()
0810 {
0811 hooks::set_spare_storage(this, o.spare_storage());
0812 no_value_policy_type::on_outcome_copy_construction(this, o);
0813 }
0814
0815
0816
0817 BOOST_OUTCOME_TEMPLATE(class T)
0818 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
0819 constexpr basic_outcome(failure_type<T> &&o,
0820 exception_failure_tag = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>)
0821 : base()
0822 , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o)))
0823 {
0824 this->_state._status.set_have_exception(true);
0825 hooks::set_spare_storage(this, o.spare_storage());
0826 no_value_policy_type::on_outcome_copy_construction(this, o);
0827 }
0828
0829
0830
0831 BOOST_OUTCOME_TEMPLATE(class T)
0832 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
0833 constexpr basic_outcome(failure_type<T> &&o,
0834 explicit_make_error_code_compatible_move_conversion_tag =
0835 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>())))
0836 : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
0837 , _ptr()
0838 {
0839 hooks::set_spare_storage(this, o.spare_storage());
0840 no_value_policy_type::on_outcome_copy_construction(this, o);
0841 }
0842
0843
0844
0845 BOOST_OUTCOME_TEMPLATE(class T, class U)
0846 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
0847 constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag = explicit_compatible_move_conversion_tag()) noexcept(
0848 detail::is_nothrow_constructible<error_type, T> && detail::is_nothrow_constructible<exception_type, U>)
0849 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))}
0850 , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o)))
0851 {
0852 if(!o.has_error())
0853 {
0854 this->_state._status.set_have_error(false);
0855 }
0856 if(o.has_exception())
0857 {
0858 this->_state._status.set_have_exception(true);
0859 }
0860 hooks::set_spare_storage(this, o.spare_storage());
0861 no_value_policy_type::on_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o));
0862 }
0863
0864
0865
0866
0867 using base::operator==;
0868 using base::operator!=;
0869
0870
0871
0872 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
0873 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()),
0874 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()),
0875 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
0876 constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept(
0877 noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>())
0878 && noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>())
0879 && noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
0880 {
0881 if(this->_state._status.have_value() && o._state._status.have_value())
0882 {
0883 return this->_state._value == o._state._value;
0884 }
0885 if(this->_state._status.have_error() && o._state._status.have_error()
0886 && this->_state._status.have_exception() && o._state._status.have_exception())
0887 {
0888 return this->_state._error == o._state._error && this->_ptr == o._ptr;
0889 }
0890 if(this->_state._status.have_error() && o._state._status.have_error())
0891 {
0892 return this->_state._error == o._state._error;
0893 }
0894 if(this->_state._status.have_exception() && o._state._status.have_exception())
0895 {
0896 return this->_ptr == o._ptr;
0897 }
0898 return false;
0899 }
0900
0901
0902
0903 BOOST_OUTCOME_TEMPLATE(class T, class U)
0904 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()),
0905 BOOST_OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>()))
0906 constexpr bool operator==(const failure_type<T, U> &o) const noexcept(
0907 noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
0908 {
0909 if(this->_state._status.have_error() && o._state._status.have_error()
0910 && this->_state._status.have_exception() && o._state._status.have_exception())
0911 {
0912 return this->_state._error == o.error() && this->_ptr == o.exception();
0913 }
0914 if(this->_state._status.have_error() && o._state._status.have_error())
0915 {
0916 return this->_state._error == o.error();
0917 }
0918 if(this->_state._status.have_exception() && o._state._status.have_exception())
0919 {
0920 return this->_ptr == o.exception();
0921 }
0922 return false;
0923 }
0924
0925
0926
0927 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
0928 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()),
0929 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()),
0930 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
0931 constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept(
0932 noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>())
0933 && noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>())
0934 && noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
0935 {
0936 if(this->_state._status.have_value() && o._state._status.have_value())
0937 {
0938 return this->_state._value != o._state._value;
0939 }
0940 if(this->_state._status.have_error() && o._state._status.have_error()
0941 && this->_state._status.have_exception() && o._state._status.have_exception())
0942 {
0943 return this->_state._error != o._state._error || this->_ptr != o._ptr;
0944 }
0945 if(this->_state._status.have_error() && o._state._status.have_error())
0946 {
0947 return this->_state._error != o._state._error;
0948 }
0949 if(this->_state._status.have_exception() && o._state._status.have_exception())
0950 {
0951 return this->_ptr != o._ptr;
0952 }
0953 return true;
0954 }
0955
0956
0957
0958 BOOST_OUTCOME_TEMPLATE(class T, class U)
0959 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()),
0960 BOOST_OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>()))
0961 constexpr bool operator!=(const failure_type<T, U> &o) const noexcept(
0962 noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
0963 {
0964 if(this->_state._status.have_error() && o._state._status.have_error()
0965 && this->_state._status.have_exception() && o._state._status.have_exception())
0966 {
0967 return this->_state._error != o.error() || this->_ptr != o.exception();
0968 }
0969 if(this->_state._status.have_error() && o._state._status.have_error())
0970 {
0971 return this->_state._error != o.error();
0972 }
0973 if(this->_state._status.have_exception() && o._state._status.have_exception())
0974 {
0975 return this->_ptr != o.exception();
0976 }
0977 return true;
0978 }
0979
0980
0981
0982
0983 constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value)
0984 && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value)
0985 && (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value))
0986 {
0987 #ifndef BOOST_NO_EXCEPTIONS
0988 constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
0989 constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
0990 constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value;
0991 #ifdef _MSC_VER
0992 #pragma warning(push)
0993 #pragma warning(disable : 4127)
0994 #endif
0995 if(!exception_throws && !value_throws && !error_throws)
0996 {
0997
0998 this->_state.swap(o._state);
0999 using std::swap;
1000 swap(this->_ptr, o._ptr);
1001 return;
1002 }
1003 struct some_type
1004 {
1005 basic_outcome &a, &b;
1006 bool exceptioned{false};
1007 bool all_good{false};
1008 ~some_type()
1009 {
1010 if(!this->all_good)
1011 {
1012
1013 this->a._state._status.set_have_lost_consistency(true);
1014 this->b._state._status.set_have_lost_consistency(true);
1015 return;
1016 }
1017 if(this->exceptioned)
1018 {
1019
1020 try
1021 {
1022 strong_swap(this->all_good, this->a._ptr, this->b._ptr);
1023 }
1024 catch(...)
1025 {
1026
1027 this->a._state._status.set_have_lost_consistency(true);
1028 this->b._state._status.set_have_lost_consistency(true);
1029
1030 }
1031
1032
1033 auto check = [](basic_outcome *t)
1034 {
1035 if(t->has_value() && (t->has_error() || t->has_exception()))
1036 {
1037 t->_state._status.set_have_error(false).set_have_exception(false);
1038 t->_state._status.set_have_lost_consistency(true);
1039 }
1040 if(!t->has_value() && !(t->has_error() || t->has_exception()))
1041 {
1042
1043 t->_state._status.set_have_error(true).set_have_lost_consistency(true);
1044 }
1045 };
1046 check(&this->a);
1047 check(&this->b);
1048 }
1049 }
1050 } some_type_value{*this, o};
1051 strong_swap(some_type_value.all_good, this->_ptr, o._ptr);
1052 some_type_value.exceptioned = true;
1053 this->_state.swap(o._state);
1054 some_type_value.exceptioned = false;
1055 #ifdef _MSC_VER
1056 #pragma warning(pop)
1057 #endif
1058 #else
1059 this->_state.swap(o._state);
1060 using std::swap;
1061 swap(this->_ptr, o._ptr);
1062 #endif
1063 }
1064
1065
1066
1067
1068 failure_type<error_type, exception_type> as_failure() const &
1069 {
1070 if(this->has_error() && this->has_exception())
1071 {
1072 return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception(), hooks::spare_storage(this));
1073 }
1074 if(this->has_exception())
1075 {
1076 return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception(), hooks::spare_storage(this));
1077 }
1078 return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error(), hooks::spare_storage(this));
1079 }
1080
1081
1082
1083
1084 failure_type<error_type, exception_type> as_failure() &&
1085 {
1086 this->_state._status.set_have_moved_from(true);
1087 if(this->has_error() && this->has_exception())
1088 {
1089 return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception()),
1090 hooks::spare_storage(this));
1091 }
1092 if(this->has_exception())
1093 {
1094 return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception()), hooks::spare_storage(this));
1095 }
1096 return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error()), hooks::spare_storage(this));
1097 }
1098
1099 #ifdef __APPLE__
1100 failure_type<error_type, exception_type> _xcode_workaround_as_failure() &&;
1101 #endif
1102 };
1103
1104
1105
1106 #if __cplusplus < 202000L && !_HAS_CXX20
1107
1108
1109
1110 BOOST_OUTCOME_TEMPLATE(class T, class U, class V,
1111 class R, class S, class P, class N)
1112 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
1113 constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept(
1114 noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
1115 {
1116 return b == a;
1117 }
1118 #endif
1119
1120
1121
1122 BOOST_OUTCOME_TEMPLATE(class T, class U, class V,
1123 class R, class S, class P, class N)
1124 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
1125 constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept(
1126 noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
1127 {
1128 return b != a;
1129 }
1130
1131
1132
1133 template <class R, class S, class P, class N> inline void swap(basic_outcome<R, S, P, N> &a, basic_outcome<R, S, P, N> &b) noexcept(noexcept(a.swap(b)))
1134 {
1135 a.swap(b);
1136 }
1137
1138 namespace hooks
1139 {
1140
1141
1142
1143 template <class R, class S, class P, class NoValuePolicy, class U>
1144 constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept
1145 {
1146 o->_ptr = static_cast<U &&>(v);
1147 o->_state._status.set_have_exception(true);
1148 }
1149 }
1150
1151 BOOST_OUTCOME_V2_NAMESPACE_END
1152
1153 #if defined(_MSC_VER) && !defined(__clang__)
1154 #pragma warning(pop)
1155 #endif
1156
1157 #ifdef __clang__
1158 #pragma clang diagnostic pop
1159 #endif
1160
1161 #include "detail/basic_outcome_exception_observers_impl.hpp"
1162
1163 #if !defined(NDEBUG)
1164 BOOST_OUTCOME_V2_NAMESPACE_BEGIN
1165
1166
1167
1168
1169 static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!");
1170 static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value,
1171 "outcome<int> is not trivially assignable!");
1172 static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!");
1173 static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
1174 "outcome<int> is not trivially copy constructible!");
1175 static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
1176 "outcome<int> is not trivially move constructible!");
1177 static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!");
1178 static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!");
1179
1180
1181 BOOST_OUTCOME_V2_NAMESPACE_END
1182 #endif
1183
1184 #endif