File indexing completed on 2025-12-16 09:59:12
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_EXPERIMENTAL_STATUS_OUTCOME_HPP
0032 #define BOOST_OUTCOME_EXPERIMENTAL_STATUS_OUTCOME_HPP
0033
0034 #include "../basic_outcome.hpp"
0035
0036 #include "../detail/trait_std_exception.hpp"
0037 #include "status_result.hpp"
0038
0039 #include "boost/exception_ptr.hpp"
0040
0041 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN
0042 template <class DomainType> inline std::exception_ptr basic_outcome_failure_exception_from_error(const status_code<DomainType> &sc)
0043 {
0044 (void) sc;
0045 #ifndef BOOST_NO_EXCEPTIONS
0046 try
0047 {
0048 sc.throw_exception();
0049 }
0050 catch(...)
0051 {
0052 return std::current_exception();
0053 }
0054 #endif
0055 return {};
0056 }
0057 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
0058
0059 BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
0060
0061 namespace experimental
0062 {
0063 namespace policy
0064 {
0065 template <class T, class EC, class E>
0066 using default_status_outcome_policy = std::conditional_t<
0067 std::is_void<EC>::value && std::is_void<E>::value,
0068 BOOST_OUTCOME_V2_NAMESPACE::policy::terminate,
0069 std::conditional_t<(is_status_code<EC>::value || is_errored_status_code<EC>::value) &&
0070 (std::is_void<E>::value || BOOST_OUTCOME_V2_NAMESPACE::trait::is_exception_ptr_available<E>::value),
0071 status_code_throw<T, EC, E>,
0072 BOOST_OUTCOME_V2_NAMESPACE::policy::fail_to_compile_observers
0073 >>;
0074 }
0075
0076
0077
0078
0079 template <class R, class S = erased_errored_status_code<typename system_code::value_type>, class P = std::exception_ptr,
0080 class NoValuePolicy = policy::default_status_outcome_policy<R, S, P>>
0081 using status_outcome = basic_outcome<R, S, P, NoValuePolicy>;
0082
0083
0084
0085
0086 BOOST_OUTCOME_TEMPLATE(class R, class S, class P, class NoValuePolicy)
0087 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_copy_constructible<R>::value &&std::is_copy_constructible<P>::value &&
0088 (is_status_code<S>::value || is_errored_status_code<S>::value)))
0089 inline basic_outcome<R, S, P, NoValuePolicy> clone(const basic_outcome<R, S, P, NoValuePolicy> &v)
0090 {
0091 if(v)
0092 {
0093 return success_type<R>(v.assume_value());
0094 }
0095 if(v.has_error() && v.has_exception())
0096 {
0097 return failure_type<S, P>(v.assume_error().clone(), v.assume_exception(), hooks::spare_storage(&v));
0098 }
0099 if(v.has_exception())
0100 {
0101 return failure_type<S, P>(in_place_type<P>, v.assume_exception(), hooks::spare_storage(&v));
0102 }
0103 return failure_type<S, P>(in_place_type<S>, v.assume_error().clone(), hooks::spare_storage(&v));
0104 }
0105
0106
0107
0108
0109 BOOST_OUTCOME_TEMPLATE(class S, class P, class NoValuePolicy)
0110 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(std::is_copy_constructible<P>::value && (is_status_code<S>::value || is_errored_status_code<S>::value)))
0111 inline basic_outcome<void, S, P, NoValuePolicy> clone(const basic_outcome<void, S, P, NoValuePolicy> &v)
0112 {
0113 if(v)
0114 {
0115 return success_type<void>();
0116 }
0117 if(v.has_error() && v.has_exception())
0118 {
0119 return failure_type<S, P>(v.assume_error().clone(), v.assume_exception(), hooks::spare_storage(&v));
0120 }
0121 if(v.has_exception())
0122 {
0123 return failure_type<S, P>(in_place_type<P>, v.assume_exception(), hooks::spare_storage(&v));
0124 }
0125 return failure_type<S, P>(in_place_type<S>, v.assume_error().clone(), hooks::spare_storage(&v));
0126 }
0127
0128 namespace policy
0129 {
0130 template <class T, class DomainType, class E> struct status_code_throw<T, status_code<DomainType>, E> : base
0131 {
0132 using _base = base;
0133 template <class Impl> static constexpr void wide_value_check(Impl &&self)
0134 {
0135 if(!base::_has_value(static_cast<Impl &&>(self)))
0136 {
0137 if(base::_has_exception(static_cast<Impl &&>(self)))
0138 {
0139 BOOST_OUTCOME_V2_NAMESPACE::policy::detail::_rethrow_exception<trait::is_exception_ptr_available<E>::value>(
0140 base::_exception<T, status_code<DomainType>, E, status_code_throw>(static_cast<Impl &&>(self)));
0141 }
0142 if(base::_has_error(static_cast<Impl &&>(self)))
0143 {
0144 #ifndef BOOST_NO_EXCEPTIONS
0145 base::_error(static_cast<Impl &&>(self)).throw_exception();
0146 #else
0147 BOOST_OUTCOME_THROW_EXCEPTION("wide value check failed");
0148 #endif
0149 }
0150 }
0151 }
0152 template <class Impl> static constexpr void wide_error_check(Impl &&self) { _base::narrow_error_check(static_cast<Impl &&>(self)); }
0153 template <class Impl> static constexpr void wide_exception_check(Impl &&self) { _base::narrow_exception_check(static_cast<Impl &&>(self)); }
0154 };
0155 template <class T, class DomainType, class E>
0156 struct status_code_throw<T, errored_status_code<DomainType>, E> : status_code_throw<T, status_code<DomainType>, E>
0157 {
0158 status_code_throw() = default;
0159 using status_code_throw<T, status_code<DomainType>, E>::status_code_throw;
0160 };
0161 }
0162
0163 }
0164
0165 BOOST_OUTCOME_V2_NAMESPACE_END
0166
0167 #endif