Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-04-04 08:33:21

0001 /* Proposed SG14 status_code
0002 (C) 2022-2024 Niall Douglas <http://www.nedproductions.biz/> (5 commits)
0003 File Created: Jun 2022
0004 
0005 
0006 Boost Software License - Version 1.0 - August 17th, 2003
0007 
0008 Permission is hereby granted, free of charge, to any person or organization
0009 obtaining a copy of the software and accompanying documentation covered by
0010 this license (the "Software") to use, reproduce, display, distribute,
0011 execute, and transmit the Software, and to prepare derivative works of the
0012 Software, and to permit third-parties to whom the Software is furnished to
0013 do so, all subject to the following:
0014 
0015 The copyright notices in the Software and this entire statement, including
0016 the above license grant, this restriction and the following disclaimer,
0017 must be included in all copies of the Software, in whole or in part, and
0018 all derivative works of the Software, unless such copies or derivative
0019 works are solely in the form of machine-executable object code generated by
0020 a source language processor.
0021 
0022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0024 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
0025 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
0026 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
0027 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
0028 DEALINGS IN THE SOFTWARE.
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 //! A HTTP status code.
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     //! True if the HTTP status code is informational
0049     inline bool is_http_informational() const noexcept;
0050     //! True if the HTTP status code is successful
0051     inline bool is_http_success() const noexcept;
0052     //! True if the HTTP status code is redirection
0053     inline bool is_http_redirection() const noexcept;
0054     //! True if the HTTP status code is client error
0055     inline bool is_http_client_error() const noexcept;
0056     //! True if the HTTP status code is server error
0057     inline bool is_http_server_error() const noexcept;
0058   };
0059 }  // namespace mixins
0060 
0061 /*! The implementation of the domain for HTTP status codes.
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   //! The value type of the HTTP code, which is an `int`
0070   using value_type = int;
0071   using _base::string_ref;
0072 
0073   //! Default constructor
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   //! Constexpr singleton getter. Returns constexpr http_status_code_domain variable.
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"); }  // NOLINT
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  // NOLINT
0097   {
0098     assert(code.domain() == *this);                                     // NOLINT
0099     return static_cast<const http_status_code &>(code).value() >= 400;  // NOLINT
0100   }
0101   virtual bool _do_equivalent(const status_code<void> &code1, const status_code<void> &code2) const noexcept override  // NOLINT
0102   {
0103     assert(code1.domain() == *this);                                // NOLINT
0104     const auto &c1 = static_cast<const http_status_code &>(code1);  // NOLINT
0105     if(code2.domain() == *this)
0106     {
0107       const auto &c2 = static_cast<const http_status_code &>(code2);  // NOLINT
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  // NOLINT
0113   {
0114     assert(code.domain() == *this);                               // NOLINT
0115     const auto &c = static_cast<const http_status_code &>(code);  // NOLINT
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  // NOLINT
0152   {
0153     assert(code.domain() == *this);                               // NOLINT
0154     const auto &c = static_cast<const http_status_code &>(code);  // NOLINT
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  // NOLINT
0293   {
0294     assert(code.domain() == *this);                               // NOLINT
0295     const auto &c = static_cast<const http_status_code &>(code);  // NOLINT
0296     throw status_error<_http_status_code_domain>(c);
0297   }
0298 #endif
0299 };
0300 //! A constexpr source variable for the `getaddrinfo()` code domain, which is that of `getaddrinfo()`. Returned by `_http_status_code_domain::get()`.
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 }  // namespace mixins
0335 
0336 
0337 BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE_END
0338 
0339 #endif