File indexing completed on 2025-04-04 08:33:22
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 #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP
0026 #define BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_HPP
0027
0028 #ifndef BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES
0029 #define BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES 1
0030 #endif
0031
0032 #include "generic_code.hpp"
0033
0034 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN
0035
0036 template <class Enum> class _quick_status_code_from_enum_domain;
0037
0038 template <class Enum> using quick_status_code_from_enum_code = status_code<_quick_status_code_from_enum_domain<Enum>>;
0039
0040
0041 template <class Enum> struct quick_status_code_from_enum_defaults
0042 {
0043
0044 using code_type = quick_status_code_from_enum_code<Enum>;
0045
0046 struct mapping
0047 {
0048
0049 using enumeration_type = Enum;
0050
0051
0052 const Enum value;
0053
0054 const char *message;
0055
0056 const std::initializer_list<errc> code_mappings;
0057 };
0058
0059 template <class Base> struct mixin : Base
0060 {
0061 using Base::Base;
0062 };
0063 };
0064
0065
0066
0067 template <class Enum> class _quick_status_code_from_enum_domain : public status_code_domain
0068 {
0069 template <class DomainType> friend class status_code;
0070 using _base = status_code_domain;
0071 using _src = quick_status_code_from_enum<Enum>;
0072
0073 public:
0074
0075 using value_type = Enum;
0076 using _base::string_ref;
0077
0078 constexpr _quick_status_code_from_enum_domain()
0079 : status_code_domain(_src::domain_uuid, _uuid_size<detail::cstrlen(_src::domain_uuid)>())
0080 {
0081 }
0082 _quick_status_code_from_enum_domain(const _quick_status_code_from_enum_domain &) = default;
0083 _quick_status_code_from_enum_domain(_quick_status_code_from_enum_domain &&) = default;
0084 _quick_status_code_from_enum_domain &operator=(const _quick_status_code_from_enum_domain &) = default;
0085 _quick_status_code_from_enum_domain &operator=(_quick_status_code_from_enum_domain &&) = default;
0086 ~_quick_status_code_from_enum_domain() = default;
0087
0088 #if __cplusplus < 201402L && !defined(_MSC_VER)
0089 static inline const _quick_status_code_from_enum_domain &get()
0090 {
0091 static _quick_status_code_from_enum_domain v;
0092 return v;
0093 }
0094 #else
0095 static inline constexpr const _quick_status_code_from_enum_domain &get();
0096 #endif
0097
0098 virtual string_ref name() const noexcept override { return string_ref(_src::domain_name); }
0099
0100 virtual payload_info_t payload_info() const noexcept override
0101 {
0102 return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
0103 (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
0104 }
0105
0106 protected:
0107
0108
0109 static BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 const typename _src::mapping *_find_mapping(value_type v) noexcept
0110 {
0111 for(const auto &i : _src::value_mappings())
0112 {
0113 if(i.value == v)
0114 {
0115 return &i;
0116 }
0117 }
0118 return nullptr;
0119 }
0120
0121 virtual bool _do_failure(const status_code<void> &code) const noexcept override
0122 {
0123 assert(code.domain() == *this);
0124
0125 const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
0126 #if BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES
0127 assert(mapping != nullptr);
0128 #endif
0129 if(mapping != nullptr)
0130 {
0131 for(errc ec : mapping->code_mappings)
0132 {
0133 if(ec == errc::success)
0134 {
0135 return false;
0136 }
0137 }
0138 }
0139 return true;
0140 }
0141 virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override
0142 {
0143 assert(code1.domain() == *this);
0144 const auto &c1 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code1);
0145 if(code2.domain() == *this)
0146 {
0147 const auto &c2 = static_cast<const quick_status_code_from_enum_code<value_type> &>(code2);
0148 return c1.value() == c2.value();
0149 }
0150 if(code2.domain() == generic_code_domain)
0151 {
0152 const auto &c2 = static_cast<const generic_code &>(code2);
0153 const auto *mapping = _find_mapping(c1.value());
0154 #if BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES
0155 assert(mapping != nullptr);
0156 #endif
0157 if(mapping != nullptr)
0158 {
0159 for(errc ec : mapping->code_mappings)
0160 {
0161 if(ec == c2.value())
0162 {
0163 return true;
0164 }
0165 }
0166 }
0167 }
0168 return false;
0169 }
0170 virtual generic_code _generic_code(const status_code<void> &code) const noexcept override
0171 {
0172 assert(code.domain() == *this);
0173 const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
0174 #if BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES
0175 assert(mapping != nullptr);
0176 #endif
0177 if(mapping != nullptr)
0178 {
0179 if(mapping->code_mappings.size() > 0)
0180 {
0181 return *mapping->code_mappings.begin();
0182 }
0183 }
0184 return errc::unknown;
0185 }
0186 virtual string_ref _do_message(const status_code<void> &code) const noexcept override
0187 {
0188 assert(code.domain() == *this);
0189 const auto *mapping = _find_mapping(static_cast<const quick_status_code_from_enum_code<value_type> &>(code).value());
0190 #if BOOST_OUTCOME_SYSTEM_ERROR2_QUICK_STATUS_CODE_FROM_ENUM_ASSERT_ON_MISSING_MAPPING_TABLE_ENTRIES
0191 assert(mapping != nullptr);
0192 #endif
0193 if(mapping != nullptr)
0194 {
0195 return string_ref(mapping->message);
0196 }
0197 return string_ref("unknown");
0198 }
0199 #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
0200 BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override
0201 {
0202 assert(code.domain() == *this);
0203 const auto &c = static_cast<const quick_status_code_from_enum_code<value_type> &>(code);
0204 throw status_error<_quick_status_code_from_enum_domain>(c);
0205 }
0206 #endif
0207 };
0208
0209 #if __cplusplus >= 201402L || defined(_MSC_VER)
0210 template <class Enum> constexpr _quick_status_code_from_enum_domain<Enum> quick_status_code_from_enum_domain = {};
0211 template <class Enum> inline constexpr const _quick_status_code_from_enum_domain<Enum> &_quick_status_code_from_enum_domain<Enum>::get()
0212 {
0213 return quick_status_code_from_enum_domain<Enum>;
0214 }
0215 #endif
0216
0217 namespace mixins
0218 {
0219 template <class Base, class Enum>
0220 struct mixin<Base, _quick_status_code_from_enum_domain<Enum>> : public quick_status_code_from_enum<Enum>::template mixin<Base>
0221 {
0222 using quick_status_code_from_enum<Enum>::template mixin<Base>::mixin;
0223 };
0224 }
0225
0226 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
0227
0228 #endif