145145#define CPPHTTPLIB_LISTEN_BACKLOG 5
146146#endif
147147
148+ #ifndef CPPHTTPLIB_DEFINE_STATIC
149+ #ifdef CPPHTTPLIB_NO_EXIT_TIME_DESTRUCTORS
150+ #define CPPHTTPLIB_DEFINE_STATIC (var_type, var, init ) \
151+ static var_type &var = *new typename std::remove_cv<var_type>::type init
152+ #else
153+ #define CPPHTTPLIB_DEFINE_STATIC (var_type, var, init ) \
154+ static var_type var = typename std::remove_cv<var_type>::type init
155+ #endif
156+ #endif
157+
148158/*
149159 * Headers
150160 */
@@ -2919,7 +2929,7 @@ inline std::string decode_url(const std::string &s,
29192929
29202930inline std::string file_extension (const std::string &path) {
29212931 std::smatch m;
2922- static auto re = std::regex (" \\ .([a-zA-Z0-9]+)$" );
2932+ CPPHTTPLIB_DEFINE_STATIC ( const std::regex, re, (" \\ .([a-zA-Z0-9]+)$" ) );
29232933 if (std::regex_search (path, m, re)) { return m[1 ].str (); }
29242934 return std::string ();
29252935}
@@ -4912,9 +4922,10 @@ class MultipartFormDataParser {
49124922 file_.content_type =
49134923 trim_copy (header.substr (str_len (header_content_type)));
49144924 } else {
4915- static const std::regex re_content_disposition (
4916- R"~( ^Content-Disposition:\s*form-data;\s*(.*)$)~" ,
4917- std::regex_constants::icase);
4925+ CPPHTTPLIB_DEFINE_STATIC (
4926+ const std::regex, re_content_disposition,
4927+ (R"~( ^Content-Disposition:\s*form-data;\s*(.*)$)~" ,
4928+ std::regex_constants::icase));
49184929
49194930 std::smatch m;
49204931 if (std::regex_match (header, m, re_content_disposition)) {
@@ -4935,8 +4946,9 @@ class MultipartFormDataParser {
49354946 it = params.find (" filename*" );
49364947 if (it != params.end ()) {
49374948 // Only allow UTF-8 encoding...
4938- static const std::regex re_rfc5987_encoding (
4939- R"~( ^UTF-8''(.+?)$)~" , std::regex_constants::icase);
4949+ CPPHTTPLIB_DEFINE_STATIC (
4950+ const std::regex, re_rfc5987_encoding,
4951+ (R"~( ^UTF-8''(.+?)$)~" , std::regex_constants::icase));
49404952
49414953 std::smatch m2;
49424954 if (std::regex_match (it->second , m2, re_rfc5987_encoding)) {
@@ -5614,15 +5626,16 @@ class WSInit {
56145626 bool is_valid_ = false ;
56155627};
56165628
5617- static WSInit wsinit_;
5629+ CPPHTTPLIB_DEFINE_STATIC ( WSInit, wsinit_, ()) ;
56185630#endif
56195631
56205632inline bool parse_www_authenticate (const Response &res,
56215633 std::map<std::string, std::string> &auth,
56225634 bool is_proxy) {
56235635 auto auth_key = is_proxy ? " Proxy-Authenticate" : " WWW-Authenticate" ;
56245636 if (res.has_header (auth_key)) {
5625- static auto re = std::regex (R"~( (?:(?:,\s*)?(.+?)=(?:"(.*?)"|([^,]*))))~" );
5637+ CPPHTTPLIB_DEFINE_STATIC (const std::regex, re,
5638+ (R"~( (?:(?:,\s*)?(.+?)=(?:"(.*?)"|([^,]*))))~" ));
56265639 auto s = res.get_header_value (auth_key);
56275640 auto pos = s.find (' ' );
56285641 if (pos != std::string::npos) {
@@ -5706,7 +5719,7 @@ inline void hosted_at(const std::string &hostname,
57065719inline std::string append_query_params (const std::string &path,
57075720 const Params ¶ms) {
57085721 std::string path_with_query = path;
5709- const static std::regex re (" [^?]+\\ ?.*" );
5722+ CPPHTTPLIB_DEFINE_STATIC ( const std::regex, re, (" [^?]+\\ ?.*" ) );
57105723 auto delm = std::regex_match (path, re) ? ' &' : ' ?' ;
57115724 path_with_query += delm + detail::params_to_query_str (params);
57125725 return path_with_query;
@@ -6480,9 +6493,9 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
64806493 if (count != 3 ) { return false ; }
64816494 }
64826495
6483- static const std::set<std::string> methods{
6484- " GET " , " HEAD" , " POST" , " PUT" , " DELETE" ,
6485- " CONNECT " , " OPTIONS" , " TRACE" , " PATCH" , " PRI" };
6496+ CPPHTTPLIB_DEFINE_STATIC ( std::set<std::string>, methods,
6497+ ({ " GET " , " HEAD" , " POST" , " PUT" , " DELETE" , " CONNECT " ,
6498+ " OPTIONS" , " TRACE" , " PATCH" , " PRI" })) ;
64866499
64876500 if (methods.find (req.method ) == methods.end ()) { return false ; }
64886501
@@ -7469,9 +7482,11 @@ inline bool ClientImpl::read_response_line(Stream &strm, const Request &req,
74697482 if (!line_reader.getline ()) { return false ; }
74707483
74717484#ifdef CPPHTTPLIB_ALLOW_LF_AS_LINE_TERMINATOR
7472- const static std::regex re (" (HTTP/1\\ .[01]) (\\ d{3})(?: (.*?))?\r ?\n " );
7485+ CPPTHTTPLIB_DEFINE_STATIC (std::regex, re,
7486+ (" (HTTP/1\\ .[01]) (\\ d{3})(?: (.*?))?\r ?\n " ));
74737487#else
7474- const static std::regex re (" (HTTP/1\\ .[01]) (\\ d{3})(?: (.*?))?\r\n " );
7488+ CPPHTTPLIB_DEFINE_STATIC (const std::regex, re,
7489+ (" (HTTP/1\\ .[01]) (\\ d{3})(?: (.*?))?\r\n " ));
74757490#endif
74767491
74777492 std::cmatch m;
@@ -7703,8 +7718,9 @@ inline bool ClientImpl::redirect(Request &req, Response &res, Error &error) {
77037718 auto location = res.get_header_value (" location" );
77047719 if (location.empty ()) { return false ; }
77057720
7706- const static std::regex re (
7707- R"( (?:(https?):)?(?://(?:\[([a-fA-F\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*)(\?[^#]*)?(?:#.*)?)" );
7721+ CPPHTTPLIB_DEFINE_STATIC (
7722+ const std::regex, re,
7723+ (R"( (?:(https?):)?(?://(?:\[([a-fA-F\d:]+)\]|([^:/?#]+))(?::(\d+))?)?([^?#]*)(\?[^#]*)?(?:#.*)?)" ));
77087724
77097725 std::smatch m;
77107726 if (!std::regex_match (location, m, re)) { return false ; }
@@ -9787,8 +9803,10 @@ inline Client::Client(const std::string &scheme_host_port)
97879803inline Client::Client (const std::string &scheme_host_port,
97889804 const std::string &client_cert_path,
97899805 const std::string &client_key_path) {
9790- const static std::regex re (
9791- R"( (?:([a-z]+):\/\/)?(?:\[([a-fA-F\d:]+)\]|([^:/?#]+))(?::(\d+))?)" );
9806+
9807+ CPPHTTPLIB_DEFINE_STATIC (
9808+ const std::regex, re,
9809+ (R"( (?:([a-z]+):\/\/)?(?:\[([a-fA-F\d:]+)\]|([^:/?#]+))(?::(\d+))?)" ));
97929810
97939811 std::smatch m;
97949812 if (std::regex_match (scheme_host_port, m, re)) {
0 commit comments