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