File indexing completed on 2025-10-30 08:26:00
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_SYSTEM_ERROR2_HTTP_STATUS_CODE_HPP
0032 #define BOOST_OUTCOME_SYSTEM_ERROR2_HTTP_STATUS_CODE_HPP
0033 
0034 #include "status_code.hpp"
0035 
0036 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_BEGIN
0037 
0038 class _http_status_code_domain;
0039 
0040 using http_status_code = status_code<_http_status_code_domain>;
0041 
0042 namespace mixins
0043 {
0044   template <class Base> struct mixin<Base, _http_status_code_domain> : public Base
0045   {
0046     using Base::Base;
0047 
0048     
0049     inline bool is_http_informational() const noexcept;
0050     
0051     inline bool is_http_success() const noexcept;
0052     
0053     inline bool is_http_redirection() const noexcept;
0054     
0055     inline bool is_http_client_error() const noexcept;
0056     
0057     inline bool is_http_server_error() const noexcept;
0058   };
0059 }  
0060 
0061 
0062 
0063 class _http_status_code_domain : public status_code_domain
0064 {
0065   template <class DomainType> friend class status_code;
0066   using _base = status_code_domain;
0067 
0068 public:
0069   
0070   using value_type = int;
0071   using _base::string_ref;
0072 
0073   
0074   constexpr explicit _http_status_code_domain(typename _base::unique_id_type id = 0xbdb4cde88378a333ull) noexcept
0075       : _base(id)
0076   {
0077   }
0078   _http_status_code_domain(const _http_status_code_domain &) = default;
0079   _http_status_code_domain(_http_status_code_domain &&) = default;
0080   _http_status_code_domain &operator=(const _http_status_code_domain &) = default;
0081   _http_status_code_domain &operator=(_http_status_code_domain &&) = default;
0082   ~_http_status_code_domain() = default;
0083 
0084   
0085   static inline constexpr const _http_status_code_domain &get();
0086 
0087   virtual string_ref name() const noexcept override { return string_ref("HTTP status domain"); }  
0088 
0089   virtual payload_info_t payload_info() const noexcept override
0090   {
0091     return {sizeof(value_type), sizeof(status_code_domain *) + sizeof(value_type),
0092             (alignof(value_type) > alignof(status_code_domain *)) ? alignof(value_type) : alignof(status_code_domain *)};
0093   }
0094 
0095 protected:
0096   virtual bool _do_failure(const status_code<void> &code) const noexcept override  
0097   {
0098     assert(code.domain() == *this);                                     
0099     return static_cast<const http_status_code &>(code).value() >= 400;  
0100   }
0101   virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override  
0102   {
0103     assert(code1.domain() == *this);                                
0104     const auto &c1 = static_cast<const http_status_code &>(code1);  
0105     if(code2.domain() == *this)
0106     {
0107       const auto &c2 = static_cast<const http_status_code &>(code2);  
0108       return c1.value() == c2.value();
0109     }
0110     return false;
0111   }
0112   virtual generic_code _generic_code(const status_code<void> &code) const noexcept override  
0113   {
0114     assert(code.domain() == *this);                               
0115     const auto &c = static_cast<const http_status_code &>(code);  
0116     switch(c.value())
0117     {
0118     case 102:
0119     case 202:
0120       return errc::operation_in_progress;
0121     case 400:
0122       return errc::invalid_argument;
0123     case 401:
0124       return errc::operation_not_permitted;
0125     case 403:
0126       return errc::permission_denied;
0127     case 404:
0128     case 410:
0129       return errc::no_such_file_or_directory;
0130     case 405:
0131     case 418:
0132       return errc::operation_not_supported;
0133     case 406:
0134       return errc::protocol_not_supported;
0135     case 408:
0136       return errc::timed_out;
0137     case 413:
0138       return errc::result_out_of_range;
0139     case 501:
0140       return errc::not_supported;
0141     case 503:
0142       return errc::resource_unavailable_try_again;
0143     case 504:
0144       return errc::timed_out;
0145     case 507:
0146       return errc::no_space_on_device;
0147     default:
0148       return errc::unknown;
0149     }
0150   }
0151   virtual string_ref _do_message(const status_code<void> &code) const noexcept override  
0152   {
0153     assert(code.domain() == *this);                               
0154     const auto &c = static_cast<const http_status_code &>(code);  
0155     return string_ref(
0156     [&]() -> const char *
0157     {
0158       switch(c.value())
0159       {
0160       case 100:
0161         return "Continue";
0162       case 101:
0163         return "Switching Protocols";
0164       case 102:
0165         return "Processing";
0166       case 103:
0167         return "Early Hints";
0168       case 200:
0169         return "OK";
0170       case 201:
0171         return "Created";
0172       case 202:
0173         return "Accepted";
0174       case 203:
0175         return "Non-Authoritative Information";
0176       case 204:
0177         return "No Content";
0178       case 205:
0179         return "Reset Content";
0180       case 206:
0181         return "Partial Content";
0182       case 207:
0183         return "Multi-Status";
0184       case 208:
0185         return "Already Reported";
0186       case 209:
0187         return "IM Used";
0188       case 300:
0189         return "Multiple Choices";
0190       case 301:
0191         return "Moved Permanently";
0192       case 302:
0193         return "Found";
0194       case 303:
0195         return "See Other";
0196       case 304:
0197         return "Not Modified";
0198       case 305:
0199         return "Use Proxy";
0200       case 306:
0201         return "Switch Proxy";
0202       case 307:
0203         return "Temporary Redirect";
0204       case 308:
0205         return "Permanent Redirect";
0206       case 400:
0207         return "Bad Request";
0208       case 401:
0209         return "Unauthorized";
0210       case 402:
0211         return "Payment Required";
0212       case 403:
0213         return "Forbidden";
0214       case 404:
0215         return "Not Found";
0216       case 405:
0217         return "Method Not Allowed";
0218       case 406:
0219         return "Not Acceptable";
0220       case 407:
0221         return "Proxy Authentication Required";
0222       case 408:
0223         return "Request Timeout";
0224       case 409:
0225         return "Conflict";
0226       case 410:
0227         return "Gone";
0228       case 411:
0229         return "Length Required";
0230       case 412:
0231         return "Precondition Failed";
0232       case 413:
0233         return "Payload Too Large";
0234       case 414:
0235         return "URI Too Long";
0236       case 415:
0237         return "Unsupported Media Type";
0238       case 416:
0239         return "Range Not Satisfiable";
0240       case 417:
0241         return "Expectation Failed";
0242       case 418:
0243         return "I'm a teapot";
0244       case 421:
0245         return "Misdirected Request";
0246       case 422:
0247         return "Unprocessable Entity";
0248       case 423:
0249         return "Locked";
0250       case 424:
0251         return "Failed Dependency";
0252       case 425:
0253         return "Too Early";
0254       case 426:
0255         return "Upgrade Required";
0256       case 428:
0257         return "Precondition Required";
0258       case 429:
0259         return "Too Many Requests";
0260       case 431:
0261         return "Request Header Fields Too Large";
0262       case 451:
0263         return "Unavailable For Legal Reasons";
0264       case 500:
0265         return "Internal Server Error";
0266       case 501:
0267         return "Not Implemented";
0268       case 502:
0269         return "Bad Gateway";
0270       case 503:
0271         return "Service Unavailable";
0272       case 504:
0273         return "Gateway Timeout";
0274       case 505:
0275         return "HTTP Version Not Supported";
0276       case 506:
0277         return "Variant Also Negotiates";
0278       case 507:
0279         return "Insufficient Storage";
0280       case 508:
0281         return "Loop Detected";
0282       case 510:
0283         return "Not Extended";
0284       case 511:
0285         return "Network Authentication Required";
0286       default:
0287         return "Unknown";
0288       }
0289     }());
0290   }
0291 #if defined(_CPPUNWIND) || defined(__EXCEPTIONS) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
0292   BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const status_code<void> &code) const override  
0293   {
0294     assert(code.domain() == *this);                               
0295     const auto &c = static_cast<const http_status_code &>(code);  
0296     throw status_error<_http_status_code_domain>(c);
0297   }
0298 #endif
0299 };
0300 
0301 constexpr _http_status_code_domain http_status_code_domain;
0302 inline constexpr const _http_status_code_domain &_http_status_code_domain::get()
0303 {
0304   return http_status_code_domain;
0305 }
0306 
0307 namespace mixins
0308 {
0309   template <class Base> inline bool mixin<Base, _http_status_code_domain>::is_http_informational() const noexcept
0310   {
0311     const auto &c = static_cast<const http_status_code *>(this)->value();
0312     return c >= 100 && c < 200;
0313   }
0314   template <class Base> inline bool mixin<Base, _http_status_code_domain>::is_http_success() const noexcept
0315   {
0316     const auto &c = static_cast<const http_status_code *>(this)->value();
0317     return c >= 200 && c < 300;
0318   }
0319   template <class Base> inline bool mixin<Base, _http_status_code_domain>::is_http_redirection() const noexcept
0320   {
0321     const auto &c = static_cast<const http_status_code *>(this)->value();
0322     return c >= 300 && c < 400;
0323   }
0324   template <class Base> inline bool mixin<Base, _http_status_code_domain>::is_http_client_error() const noexcept
0325   {
0326     const auto &c = static_cast<const http_status_code *>(this)->value();
0327     return c >= 400 && c < 500;
0328   }
0329   template <class Base> inline bool mixin<Base, _http_status_code_domain>::is_http_server_error() const noexcept
0330   {
0331     const auto &c = static_cast<const http_status_code *>(this)->value();
0332     return c >= 500 && c < 600;
0333   }
0334 }  
0335 
0336 
0337 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
0338 
0339 #endif