File indexing completed on 2025-09-13 08:42:38
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_GENERIC_CODE_HPP
0026 #define BOOST_OUTCOME_SYSTEM_ERROR2_GENERIC_CODE_HPP
0027
0028 #include "status_error.hpp"
0029
0030 #include <cerrno> // for error constants
0031
0032 #if defined(_MSC_VER) && !defined(__clang__)
0033 #pragma warning(push)
0034 #pragma warning(disable : 6326)
0035 #endif
0036
0037 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN
0038
0039
0040 enum class errc : int
0041 {
0042 success = 0,
0043 unknown = -1,
0044
0045 address_family_not_supported = EAFNOSUPPORT,
0046 address_in_use = EADDRINUSE,
0047 address_not_available = EADDRNOTAVAIL,
0048 already_connected = EISCONN,
0049 argument_list_too_long = E2BIG,
0050 argument_out_of_domain = EDOM,
0051 bad_address = EFAULT,
0052 bad_file_descriptor = EBADF,
0053 bad_message = EBADMSG,
0054 broken_pipe = EPIPE,
0055 connection_aborted = ECONNABORTED,
0056 connection_already_in_progress = EALREADY,
0057 connection_refused = ECONNREFUSED,
0058 connection_reset = ECONNRESET,
0059 cross_device_link = EXDEV,
0060 destination_address_required = EDESTADDRREQ,
0061 device_or_resource_busy = EBUSY,
0062 directory_not_empty = ENOTEMPTY,
0063 executable_format_error = ENOEXEC,
0064 file_exists = EEXIST,
0065 file_too_large = EFBIG,
0066 filename_too_long = ENAMETOOLONG,
0067 function_not_supported = ENOSYS,
0068 host_unreachable = EHOSTUNREACH,
0069 identifier_removed = EIDRM,
0070 illegal_byte_sequence = EILSEQ,
0071 inappropriate_io_control_operation = ENOTTY,
0072 interrupted = EINTR,
0073 invalid_argument = EINVAL,
0074 invalid_seek = ESPIPE,
0075 io_error = EIO,
0076 is_a_directory = EISDIR,
0077 message_size = EMSGSIZE,
0078 network_down = ENETDOWN,
0079 network_reset = ENETRESET,
0080 network_unreachable = ENETUNREACH,
0081 no_buffer_space = ENOBUFS,
0082 no_child_process = ECHILD,
0083 no_link = ENOLINK,
0084 no_lock_available = ENOLCK,
0085 no_message = ENOMSG,
0086 no_protocol_option = ENOPROTOOPT,
0087 no_space_on_device = ENOSPC,
0088 no_stream_resources = ENOSR,
0089 no_such_device_or_address = ENXIO,
0090 no_such_device = ENODEV,
0091 no_such_file_or_directory = ENOENT,
0092 no_such_process = ESRCH,
0093 not_a_directory = ENOTDIR,
0094 not_a_socket = ENOTSOCK,
0095 not_a_stream = ENOSTR,
0096 not_connected = ENOTCONN,
0097 not_enough_memory = ENOMEM,
0098 not_supported = ENOTSUP,
0099 operation_canceled = ECANCELED,
0100 operation_in_progress = EINPROGRESS,
0101 operation_not_permitted = EPERM,
0102 operation_not_supported = EOPNOTSUPP,
0103 operation_would_block = EWOULDBLOCK,
0104 owner_dead = EOWNERDEAD,
0105 permission_denied = EACCES,
0106 protocol_error = EPROTO,
0107 protocol_not_supported = EPROTONOSUPPORT,
0108 read_only_file_system = EROFS,
0109 resource_deadlock_would_occur = EDEADLK,
0110 resource_unavailable_try_again = EAGAIN,
0111 result_out_of_range = ERANGE,
0112 state_not_recoverable = ENOTRECOVERABLE,
0113 stream_timeout = ETIME,
0114 text_file_busy = ETXTBSY,
0115 timed_out = ETIMEDOUT,
0116 too_many_files_open_in_system = ENFILE,
0117 too_many_files_open = EMFILE,
0118 too_many_links = EMLINK,
0119 too_many_symbolic_link_levels = ELOOP,
0120 value_too_large = EOVERFLOW,
0121 wrong_protocol_type = EPROTOTYPE
0122 };
0123
0124 namespace detail
0125 {
0126 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline const char *generic_code_message(errc code) noexcept
0127 {
0128 switch(code)
0129 {
0130 case errc::success:
0131 return "Success";
0132 case errc::address_family_not_supported:
0133 return "Address family not supported by protocol";
0134 case errc::address_in_use:
0135 return "Address already in use";
0136 case errc::address_not_available:
0137 return "Cannot assign requested address";
0138 case errc::already_connected:
0139 return "Transport endpoint is already connected";
0140 case errc::argument_list_too_long:
0141 return "Argument list too long";
0142 case errc::argument_out_of_domain:
0143 return "Numerical argument out of domain";
0144 case errc::bad_address:
0145 return "Bad address";
0146 case errc::bad_file_descriptor:
0147 return "Bad file descriptor";
0148 case errc::bad_message:
0149 return "Bad message";
0150 case errc::broken_pipe:
0151 return "Broken pipe";
0152 case errc::connection_aborted:
0153 return "Software caused connection abort";
0154 case errc::connection_already_in_progress:
0155 return "Operation already in progress";
0156 case errc::connection_refused:
0157 return "Connection refused";
0158 case errc::connection_reset:
0159 return "Connection reset by peer";
0160 case errc::cross_device_link:
0161 return "Invalid cross-device link";
0162 case errc::destination_address_required:
0163 return "Destination address required";
0164 case errc::device_or_resource_busy:
0165 return "Device or resource busy";
0166 case errc::directory_not_empty:
0167 return "Directory not empty";
0168 case errc::executable_format_error:
0169 return "Exec format error";
0170 case errc::file_exists:
0171 return "File exists";
0172 case errc::file_too_large:
0173 return "File too large";
0174 case errc::filename_too_long:
0175 return "File name too long";
0176 case errc::function_not_supported:
0177 return "Function not implemented";
0178 case errc::host_unreachable:
0179 return "No route to host";
0180 case errc::identifier_removed:
0181 return "Identifier removed";
0182 case errc::illegal_byte_sequence:
0183 return "Invalid or incomplete multibyte or wide character";
0184 case errc::inappropriate_io_control_operation:
0185 return "Inappropriate ioctl for device";
0186 case errc::interrupted:
0187 return "Interrupted system call";
0188 case errc::invalid_argument:
0189 return "Invalid argument";
0190 case errc::invalid_seek:
0191 return "Illegal seek";
0192 case errc::io_error:
0193 return "Input/output error";
0194 case errc::is_a_directory:
0195 return "Is a directory";
0196 case errc::message_size:
0197 return "Message too long";
0198 case errc::network_down:
0199 return "Network is down";
0200 case errc::network_reset:
0201 return "Network dropped connection on reset";
0202 case errc::network_unreachable:
0203 return "Network is unreachable";
0204 case errc::no_buffer_space:
0205 return "No buffer space available";
0206 case errc::no_child_process:
0207 return "No child processes";
0208 case errc::no_link:
0209 return "Link has been severed";
0210 case errc::no_lock_available:
0211 return "No locks available";
0212 case errc::no_message:
0213 return "No message of desired type";
0214 case errc::no_protocol_option:
0215 return "Protocol not available";
0216 case errc::no_space_on_device:
0217 return "No space left on device";
0218 case errc::no_stream_resources:
0219 return "Out of streams resources";
0220 case errc::no_such_device_or_address:
0221 return "No such device or address";
0222 case errc::no_such_device:
0223 return "No such device";
0224 case errc::no_such_file_or_directory:
0225 return "No such file or directory";
0226 case errc::no_such_process:
0227 return "No such process";
0228 case errc::not_a_directory:
0229 return "Not a directory";
0230 case errc::not_a_socket:
0231 return "Socket operation on non-socket";
0232 case errc::not_a_stream:
0233 return "Device not a stream";
0234 case errc::not_connected:
0235 return "Transport endpoint is not connected";
0236 case errc::not_enough_memory:
0237 return "Cannot allocate memory";
0238 #if ENOTSUP != EOPNOTSUPP
0239 case errc::not_supported:
0240 return "Operation not supported";
0241 #endif
0242 case errc::operation_canceled:
0243 return "Operation canceled";
0244 case errc::operation_in_progress:
0245 return "Operation now in progress";
0246 case errc::operation_not_permitted:
0247 return "Operation not permitted";
0248 case errc::operation_not_supported:
0249 return "Operation not supported";
0250 #if EAGAIN != EWOULDBLOCK
0251 case errc::operation_would_block:
0252 return "Resource temporarily unavailable";
0253 #endif
0254 case errc::owner_dead:
0255 return "Owner died";
0256 case errc::permission_denied:
0257 return "Permission denied";
0258 case errc::protocol_error:
0259 return "Protocol error";
0260 case errc::protocol_not_supported:
0261 return "Protocol not supported";
0262 case errc::read_only_file_system:
0263 return "Read-only file system";
0264 case errc::resource_deadlock_would_occur:
0265 return "Resource deadlock avoided";
0266 case errc::resource_unavailable_try_again:
0267 return "Resource temporarily unavailable";
0268 case errc::result_out_of_range:
0269 return "Numerical result out of range";
0270 case errc::state_not_recoverable:
0271 return "State not recoverable";
0272 case errc::stream_timeout:
0273 return "Timer expired";
0274 case errc::text_file_busy:
0275 return "Text file busy";
0276 case errc::timed_out:
0277 return "Connection timed out";
0278 case errc::too_many_files_open_in_system:
0279 return "Too many open files in system";
0280 case errc::too_many_files_open:
0281 return "Too many open files";
0282 case errc::too_many_links:
0283 return "Too many links";
0284 case errc::too_many_symbolic_link_levels:
0285 return "Too many levels of symbolic links";
0286 case errc::value_too_large:
0287 return "Value too large for defined data type";
0288 case errc::wrong_protocol_type:
0289 return "Protocol wrong type for socket";
0290 default:
0291 return "unknown";
0292 }
0293 }
0294 }
0295
0296
0297
0298 class _generic_code_domain : public status_code_domain
0299 {
0300 template <class> friend class status_code;
0301 using _base = status_code_domain;
0302
0303 public:
0304
0305 using value_type = errc;
0306 using string_ref = _base::string_ref;
0307
0308 public:
0309
0310 constexpr explicit _generic_code_domain(typename _base::unique_id_type id = 0x746d6354f4f733e9) noexcept
0311 : _base(id)
0312 {
0313 }
0314 _generic_code_domain(const _generic_code_domain &) = default;
0315 _generic_code_domain(_generic_code_domain &&) = default;
0316 _generic_code_domain &operator=(const _generic_code_domain &) = default;
0317 _generic_code_domain &operator=(_generic_code_domain &&) = default;
0318 ~_generic_code_domain() = default;
0319
0320
0321 static inline constexpr const _generic_code_domain &get();
0322
0323 virtual _base::string_ref name() const noexcept override { return string_ref("generic domain"); }
0324
0325 virtual payload_info_t payload_info() const noexcept override
0326 {
0327 return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
0328 (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
0329 }
0330
0331 protected:
0332 virtual bool _do_failure(const status_code<void> &code) const noexcept override
0333 {
0334 assert(code.domain() == *this);
0335 return static_cast<const generic_code &>(code).value() != errc::success;
0336 }
0337 virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override
0338 {
0339 assert(code1.domain() == *this);
0340 const auto &c1 = static_cast<const generic_code &>(code1);
0341 if(code2.domain() == *this)
0342 {
0343 const auto &c2 = static_cast<const generic_code &>(code2);
0344 return c1.value() == c2.value();
0345 }
0346 return false;
0347 }
0348 virtual generic_code _generic_code(const status_code<void> &code) const noexcept override
0349 {
0350 assert(code.domain() == *this);
0351 return static_cast<const generic_code &>(code);
0352 }
0353 virtual _base::string_ref _do_message(const status_code<void> &code) const noexcept override
0354 {
0355 assert(code.domain() == *this);
0356 const auto &c = static_cast<const generic_code &>(code);
0357 return string_ref(detail::generic_code_message(c.value()));
0358 }
0359 #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
0360 BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override
0361 {
0362 assert(code.domain() == *this);
0363 const auto &c = static_cast<const generic_code &>(code);
0364 throw status_error<_generic_code_domain>(c);
0365 }
0366 #endif
0367 };
0368
0369 using generic_error = status_error<_generic_code_domain>;
0370
0371 constexpr _generic_code_domain generic_code_domain;
0372 inline constexpr const _generic_code_domain &_generic_code_domain::get()
0373 {
0374 return generic_code_domain;
0375 }
0376
0377 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline generic_code make_status_code(errc c) noexcept
0378 {
0379 return generic_code(in_place, c);
0380 }
0381
0382
0383
0384
0385
0386 template <class T> inline BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 bool status_code<void>::equivalent(const status_code<T> &o) const noexcept
0387 {
0388 if(_domain && o._domain)
0389 {
0390 if(_domain->_do_equivalent(*this, o))
0391 {
0392 return true;
0393 }
0394 if(o._domain->_do_equivalent(o, *this))
0395 {
0396 return true;
0397 }
0398 generic_code c1 = o._domain->_generic_code(o);
0399 if(c1.value() != errc::unknown && _domain->_do_equivalent(*this, c1))
0400 {
0401 return true;
0402 }
0403 generic_code c2 = _domain->_generic_code(*this);
0404 if(c2.value() != errc::unknown && o._domain->_do_equivalent(o, c2))
0405 {
0406 return true;
0407 }
0408 }
0409
0410 return (!_domain && !o._domain);
0411 }
0412
0413 template <class DomainType1, class DomainType2>
0414 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
0415 {
0416 return a.equivalent(b);
0417 }
0418
0419 template <class DomainType1, class DomainType2>
0420 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const status_code<DomainType2> &b) noexcept
0421 {
0422 return !a.equivalent(b);
0423 }
0424
0425 BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T,
0426 class MakeStatusCodeResult =
0427 typename detail::safe_get_make_status_code_result<const T &>::type)
0428 BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value))
0429 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b)
0430 {
0431 return a.equivalent(make_status_code(b));
0432 }
0433
0434 BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1,
0435 class MakeStatusCodeResult =
0436 typename detail::safe_get_make_status_code_result<const T &>::type)
0437 BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value))
0438 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b)
0439 {
0440 return b.equivalent(make_status_code(a));
0441 }
0442
0443 BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class DomainType1, class T,
0444 class MakeStatusCodeResult =
0445 typename detail::safe_get_make_status_code_result<const T &>::type)
0446 BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value))
0447 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b)
0448 {
0449 return !a.equivalent(make_status_code(b));
0450 }
0451
0452 BOOST_OUTCOME_SYSTEM_ERROR2_TEMPLATE(class T, class DomainType1,
0453 class MakeStatusCodeResult =
0454 typename detail::safe_get_make_status_code_result<const T &>::type)
0455 BOOST_OUTCOME_SYSTEM_ERROR2_TREQUIRES(BOOST_OUTCOME_SYSTEM_ERROR2_TPRED(is_status_code<MakeStatusCodeResult>::value))
0456 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b)
0457 {
0458 return !b.equivalent(make_status_code(a));
0459 }
0460
0461 template <class DomainType1, class T,
0462 class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type
0463 >
0464 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const status_code<DomainType1> &a, const T &b)
0465 {
0466 return a.equivalent(QuickStatusCodeType(b));
0467 }
0468
0469 template <class T, class DomainType1,
0470 class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type
0471 >
0472 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator==(const T &a, const status_code<DomainType1> &b)
0473 {
0474 return b.equivalent(QuickStatusCodeType(a));
0475 }
0476
0477 template <class DomainType1, class T,
0478 class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type
0479 >
0480 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const status_code<DomainType1> &a, const T &b)
0481 {
0482 return !a.equivalent(QuickStatusCodeType(b));
0483 }
0484
0485 template <class T, class DomainType1,
0486 class QuickStatusCodeType = typename quick_status_code_from_enum<T>::code_type
0487 >
0488 BOOST_OUTCOME_SYSTEM_ERROR2_CONSTEXPR14 inline bool operator!=(const T &a, const status_code<DomainType1> &b)
0489 {
0490 return !b.equivalent(QuickStatusCodeType(a));
0491 }
0492
0493
0494 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
0495
0496 #if defined(_MSC_VER) && !defined(__clang__)
0497 #pragma warning(pop)
0498 #endif
0499
0500 #endif