File indexing completed on 2025-12-16 09:59:14
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_CONVERT_HPP
0032 #define BOOST_OUTCOME_CONVERT_HPP
0033
0034 #include "detail/basic_result_storage.hpp"
0035
0036 BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
0037
0038 namespace concepts
0039 {
0040 #if defined(__cpp_concepts)
0041 #if(defined(_MSC_VER) || defined(__clang__) || (defined(__GNUC__) && __cpp_concepts >= 201707) || BOOST_OUTCOME_FORCE_STD_BOOST_OUTCOME_C_CONCEPTS) && \
0042 !BOOST_OUTCOME_FORCE_LEGACY_GCC_BOOST_OUTCOME_C_CONCEPTS
0043 #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL
0044 #else
0045 #ifndef BOOST_OUTCOME_SUPPRESS_LEGACY_CONCEPTS_WARNING
0046 #warning "WARNING: Legacy GCC concepts are known to fail to compile in a number of important situations!"
0047 #endif
0048 #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL bool
0049 #endif
0050 namespace detail
0051 {
0052 template <class T, class U>
0053 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL SameHelper = std::is_same<T, U>::value;
0054 template <class T, class U>
0055 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
0056 template <class T, class U>
0057 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL convertible = std::is_convertible<T, U>::value;
0058 template <class T, class U>
0059 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL base_of = std::is_base_of<T, U>::value;
0060 }
0061
0062
0063
0064
0065
0066 template <class U>
0067 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_none = requires(U a) {
0068 {
0069 a.has_value()
0070 } -> detail::same_as<bool>;
0071 {
0072 a.value()
0073 };
0074 };
0075
0076
0077
0078
0079 template <class U>
0080 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_error = requires(U a) {
0081 {
0082 a.has_value()
0083 } -> detail::same_as<bool>;
0084 {
0085 a.value()
0086 };
0087 {
0088 a.error()
0089 };
0090 };
0091
0092 #else
0093 namespace detail
0094 {
0095 struct no_match
0096 {
0097 };
0098 inline no_match match_value_or_none(...);
0099 inline no_match match_value_or_error(...);
0100 BOOST_OUTCOME_TEMPLATE(class U)
0101 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value()))
0102 inline U match_value_or_none(U &&);
0103 BOOST_OUTCOME_TEMPLATE(class U)
0104 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value()), BOOST_OUTCOME_TEXPR(std::declval<U>().error()))
0105 inline U match_value_or_error(U &&);
0106
0107 template <class U>
0108 static constexpr bool value_or_none =
0109 !std::is_same<no_match, decltype(match_value_or_none(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
0110 template <class U>
0111 static constexpr bool value_or_error =
0112 !std::is_same<no_match, decltype(match_value_or_error(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
0113 }
0114
0115
0116
0117 template <class U> static constexpr bool value_or_none = detail::value_or_none<U>;
0118
0119
0120
0121
0122 template <class U> static constexpr bool value_or_error = detail::value_or_error<U>;
0123 #endif
0124 }
0125
0126 namespace convert
0127 {
0128 #if BOOST_OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220
0129 #if defined(__cpp_concepts)
0130 template <class U>
0131 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrNone = concepts::value_or_none<U>;
0132 template <class U>
0133 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrError = concepts::value_or_error<U>;
0134 #else
0135 template <class U> static constexpr bool ValueOrNone = concepts::value_or_none<U>;
0136 template <class U> static constexpr bool ValueOrError = concepts::value_or_error<U>;
0137 #endif
0138 #endif
0139
0140 namespace detail
0141 {
0142 template <class T, class X> struct make_type
0143 {
0144 template <class U> static constexpr T value(U &&v) { return T{in_place_type<typename T::value_type>, static_cast<U &&>(v).value()}; }
0145 template <class U> static constexpr T error(U &&v) { return T{in_place_type<typename T::error_type>, static_cast<U &&>(v).error()}; }
0146 static constexpr T error() { return T{in_place_type<typename T::error_type>}; }
0147 };
0148 template <class T> struct make_type<T, void>
0149 {
0150 template <class U> static constexpr T value(U && ) { return T{in_place_type<typename T::value_type>}; }
0151 template <class U> static constexpr T error(U && ) { return T{in_place_type<typename T::error_type>}; }
0152 static constexpr T error() { return T{in_place_type<typename T::error_type>}; }
0153 };
0154 }
0155
0156
0157
0158
0159 template <class T, class U> struct value_or_error
0160 {
0161 static constexpr bool enable_result_inputs = false;
0162 static constexpr bool enable_outcome_inputs = false;
0163 BOOST_OUTCOME_TEMPLATE(class X)
0164 BOOST_OUTCOME_TREQUIRES(
0165 BOOST_OUTCOME_TPRED(std::is_same<U, std::decay_t<X>>::value
0166 &&concepts::value_or_error<U>
0167 && (std::is_void<typename std::decay_t<X>::value_type>::value ||
0168 BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::value_type, typename std::decay_t<X>::value_type>)
0169 &&(std::is_void<typename std::decay_t<X>::error_type>::value ||
0170 BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::error_type, typename std::decay_t<X>::error_type>) ))
0171 constexpr T operator()(X &&v)
0172 {
0173 return v.has_value() ? detail::make_type<T, typename T::value_type>::value(static_cast<X &&>(v)) :
0174 detail::make_type<T, typename U::error_type>::error(static_cast<X &&>(v));
0175 }
0176 };
0177 }
0178
0179 BOOST_OUTCOME_V2_NAMESPACE_END
0180
0181 #endif