@@ -237,6 +237,27 @@ namespace httplib {
237237
238238namespace detail {
239239
240+ /*
241+ * Backport std::make_unique from C++14.
242+ *
243+ * NOTE: This code came up with the following stackoverflow post:
244+ * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique
245+ *
246+ */
247+
248+ template <class T , class ... Args>
249+ typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
250+ make_unique (Args &&... args) {
251+ return std::unique_ptr<T>(new T (std::forward<Args>(args)...));
252+ }
253+
254+ template <class T >
255+ typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
256+ make_unique (std::size_t n) {
257+ typedef typename std::remove_extent<T>::type RT;
258+ return std::unique_ptr<T>(new RT[n]);
259+ }
260+
240261struct ci {
241262 bool operator ()(const std::string &s1, const std::string &s2) const {
242263 return std::lexicographical_compare (
@@ -713,8 +734,8 @@ enum Error {
713734
714735class Result {
715736public:
716- Result (const std::shared_ptr <Response> & res, Error err)
717- : res_(res), err_(err) {}
737+ Result (std::unique_ptr <Response> res, Error err)
738+ : res_(std::move( res) ), err_(err) {}
718739 operator bool () const { return res_ != nullptr ; }
719740 bool operator ==(std::nullptr_t ) const { return res_ == nullptr ; }
720741 bool operator !=(std::nullptr_t ) const { return res_ != nullptr ; }
@@ -724,7 +745,7 @@ class Result {
724745 Error error () const { return err_; }
725746
726747private:
727- std::shared_ptr <Response> res_;
748+ std::unique_ptr <Response> res_;
728749 Error err_;
729750};
730751
@@ -950,7 +971,7 @@ class ClientImpl {
950971 bool handle_request (Stream &strm, const Request &req, Response &res,
951972 bool close_connection);
952973 void stop_core ();
953- std::shared_ptr <Response> send_with_content_provider (
974+ std::unique_ptr <Response> send_with_content_provider (
954975 const char *method, const char *path, const Headers &headers,
955976 const std::string &body, size_t content_length,
956977 ContentProvider content_provider, const char *content_type);
@@ -1108,7 +1129,7 @@ class Client {
11081129#endif
11091130
11101131private:
1111- std::shared_ptr <ClientImpl> cli_;
1132+ std::unique_ptr <ClientImpl> cli_;
11121133
11131134#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
11141135 bool is_ssl_ = false ;
@@ -2584,19 +2605,19 @@ bool prepare_content_receiver(T &x, int &status, ContentReceiver receiver,
25842605 bool decompress, U callback) {
25852606 if (decompress) {
25862607 std::string encoding = x.get_header_value (" Content-Encoding" );
2587- std::shared_ptr <decompressor> decompressor;
2608+ std::unique_ptr <decompressor> decompressor;
25882609
25892610 if (encoding.find (" gzip" ) != std::string::npos ||
25902611 encoding.find (" deflate" ) != std::string::npos) {
25912612#ifdef CPPHTTPLIB_ZLIB_SUPPORT
2592- decompressor = std::make_shared <gzip_decompressor>();
2613+ decompressor = detail::make_unique <gzip_decompressor>();
25932614#else
25942615 status = 415 ;
25952616 return false ;
25962617#endif
25972618 } else if (encoding.find (" br" ) != std::string::npos) {
25982619#ifdef CPPHTTPLIB_BROTLI_SUPPORT
2599- decompressor = std::make_shared <brotli_decompressor>();
2620+ decompressor = detail::make_unique <brotli_decompressor>();
26002621#else
26012622 status = 415 ;
26022623 return false ;
@@ -4066,16 +4087,16 @@ inline bool Server::write_response(Stream &strm, bool close_connection,
40664087 }
40674088
40684089 if (type != detail::EncodingType::None) {
4069- std::shared_ptr <detail::compressor> compressor;
4090+ std::unique_ptr <detail::compressor> compressor;
40704091
40714092 if (type == detail::EncodingType::Gzip) {
40724093#ifdef CPPHTTPLIB_ZLIB_SUPPORT
4073- compressor = std::make_shared <detail::gzip_compressor>();
4094+ compressor = detail::make_unique <detail::gzip_compressor>();
40744095 res.set_header (" Content-Encoding" , " gzip" );
40754096#endif
40764097 } else if (type == detail::EncodingType::Brotli) {
40774098#ifdef CPPHTTPLIB_BROTLI_SUPPORT
4078- compressor = std::make_shared <detail::brotli_compressor>();
4099+ compressor = detail::make_unique <detail::brotli_compressor>();
40794100 res.set_header (" Content-Encoding" , " brotli" );
40804101#endif
40814102 }
@@ -4157,17 +4178,17 @@ Server::write_content_with_provider(Stream &strm, const Request &req,
41574178 if (res.is_chunked_content_provider ) {
41584179 auto type = detail::encoding_type (req, res);
41594180
4160- std::shared_ptr <detail::compressor> compressor;
4181+ std::unique_ptr <detail::compressor> compressor;
41614182 if (type == detail::EncodingType::Gzip) {
41624183#ifdef CPPHTTPLIB_ZLIB_SUPPORT
4163- compressor = std::make_shared <detail::gzip_compressor>();
4184+ compressor = detail::make_unique <detail::gzip_compressor>();
41644185#endif
41654186 } else if (type == detail::EncodingType::Brotli) {
41664187#ifdef CPPHTTPLIB_BROTLI_SUPPORT
4167- compressor = std::make_shared <detail::brotli_compressor>();
4188+ compressor = detail::make_unique <detail::brotli_compressor>();
41684189#endif
41694190 } else {
4170- compressor = std::make_shared <detail::nocompressor>();
4191+ compressor = detail::make_unique <detail::nocompressor>();
41714192 }
41724193 assert (compressor != nullptr );
41734194
@@ -5001,7 +5022,7 @@ inline bool ClientImpl::write_request(Stream &strm, const Request &req,
50015022 return true ;
50025023}
50035024
5004- inline std::shared_ptr <Response> ClientImpl::send_with_content_provider (
5025+ inline std::unique_ptr <Response> ClientImpl::send_with_content_provider (
50055026 const char *method, const char *path, const Headers &headers,
50065027 const std::string &body, size_t content_length,
50075028 ContentProvider content_provider, const char *content_type) {
@@ -5070,9 +5091,9 @@ inline std::shared_ptr<Response> ClientImpl::send_with_content_provider(
50705091 }
50715092 }
50725093
5073- auto res = std::make_shared <Response>();
5094+ auto res = detail::make_unique <Response>();
50745095
5075- return send (req, *res) ? res : nullptr ;
5096+ return send (req, *res) ? std::move ( res) : nullptr ;
50765097}
50775098
50785099inline bool ClientImpl::process_request (Stream &strm, const Request &req,
@@ -5168,9 +5189,9 @@ inline Result ClientImpl::Get(const char *path, const Headers &headers,
51685189 req.headers .insert (headers.begin (), headers.end ());
51695190 req.progress = std::move (progress);
51705191
5171- auto res = std::make_shared <Response>();
5192+ auto res = detail::make_unique <Response>();
51725193 auto ret = send (req, *res);
5173- return Result{ret ? res : nullptr , get_last_error ()};
5194+ return Result{ret ? std::move ( res) : nullptr , get_last_error ()};
51745195}
51755196
51765197inline Result ClientImpl::Get (const char *path,
@@ -5232,9 +5253,9 @@ inline Result ClientImpl::Get(const char *path, const Headers &headers,
52325253 req.content_receiver = std::move (content_receiver);
52335254 req.progress = std::move (progress);
52345255
5235- auto res = std::make_shared <Response>();
5256+ auto res = detail::make_unique <Response>();
52365257 auto ret = send (req, *res);
5237- return Result{ret ? res : nullptr , get_last_error ()};
5258+ return Result{ret ? std::move ( res) : nullptr , get_last_error ()};
52385259}
52395260
52405261inline Result ClientImpl::Head (const char *path) {
@@ -5248,9 +5269,9 @@ inline Result ClientImpl::Head(const char *path, const Headers &headers) {
52485269 req.headers .insert (headers.begin (), headers.end ());
52495270 req.path = path;
52505271
5251- auto res = std::make_shared <Response>();
5272+ auto res = detail::make_unique <Response>();
52525273 auto ret = send (req, *res);
5253- return Result{ret ? res : nullptr , get_last_error ()};
5274+ return Result{ret ? std::move ( res) : nullptr , get_last_error ()};
52545275}
52555276
52565277inline Result ClientImpl::Post (const char *path) {
@@ -5267,7 +5288,7 @@ inline Result ClientImpl::Post(const char *path, const Headers &headers,
52675288 const char *content_type) {
52685289 auto ret = send_with_content_provider (" POST" , path, headers, body, 0 , nullptr ,
52695290 content_type);
5270- return Result{ret, get_last_error ()};
5291+ return Result{std::move ( ret) , get_last_error ()};
52715292}
52725293
52735294inline Result ClientImpl::Post (const char *path, const Params ¶ms) {
@@ -5289,7 +5310,7 @@ inline Result ClientImpl::Post(const char *path, const Headers &headers,
52895310 content_length,
52905311 std::move (content_provider),
52915312 content_type);
5292- return Result{ret, get_last_error ()};
5313+ return Result{std::move ( ret) , get_last_error ()};
52935314}
52945315
52955316inline Result ClientImpl::Post (const char *path, const Headers &headers,
@@ -5354,7 +5375,7 @@ inline Result ClientImpl::Put(const char *path, const Headers &headers,
53545375 const char *content_type) {
53555376 auto ret = send_with_content_provider (" PUT" , path, headers, body, 0 , nullptr ,
53565377 content_type);
5357- return Result{ret, get_last_error ()};
5378+ return Result{std::move ( ret) , get_last_error ()};
53585379}
53595380
53605381inline Result ClientImpl::Put (const char *path, size_t content_length,
@@ -5372,7 +5393,7 @@ inline Result ClientImpl::Put(const char *path, const Headers &headers,
53725393 content_length,
53735394 std::move (content_provider),
53745395 content_type);
5375- return Result{ret, get_last_error ()};
5396+ return Result{std::move ( ret) , get_last_error ()};
53765397}
53775398
53785399inline Result ClientImpl::Put (const char *path, const Params ¶ms) {
@@ -5395,7 +5416,7 @@ inline Result ClientImpl::Patch(const char *path, const Headers &headers,
53955416 const char *content_type) {
53965417 auto ret = send_with_content_provider (" PATCH" , path, headers, body, 0 ,
53975418 nullptr , content_type);
5398- return Result{ret, get_last_error ()};
5419+ return Result{std::move ( ret) , get_last_error ()};
53995420}
54005421
54015422inline Result ClientImpl::Patch (const char *path, size_t content_length,
@@ -5413,7 +5434,7 @@ inline Result ClientImpl::Patch(const char *path, const Headers &headers,
54135434 content_length,
54145435 std::move (content_provider),
54155436 content_type);
5416- return Result{ret, get_last_error ()};
5437+ return Result{std::move ( ret) , get_last_error ()};
54175438}
54185439
54195440inline Result ClientImpl::Delete (const char *path) {
@@ -5441,9 +5462,9 @@ inline Result ClientImpl::Delete(const char *path, const Headers &headers,
54415462 if (content_type) { req.headers .emplace (" Content-Type" , content_type); }
54425463 req.body = body;
54435464
5444- auto res = std::make_shared <Response>();
5465+ auto res = detail::make_unique <Response>();
54455466 auto ret = send (req, *res);
5446- return Result{ret ? res : nullptr , get_last_error ()};
5467+ return Result{ret ? std::move ( res) : nullptr , get_last_error ()};
54475468}
54485469
54495470inline Result ClientImpl::Options (const char *path) {
@@ -5457,9 +5478,9 @@ inline Result ClientImpl::Options(const char *path, const Headers &headers) {
54575478 req.headers .insert (headers.begin (), headers.end ());
54585479 req.path = path;
54595480
5460- auto res = std::make_shared <Response>();
5481+ auto res = detail::make_unique <Response>();
54615482 auto ret = send (req, *res);
5462- return Result{ret ? res : nullptr , get_last_error ()};
5483+ return Result{ret ? std::move ( res) : nullptr , get_last_error ()};
54635484}
54645485
54655486inline size_t ClientImpl::is_socket_open () const {
@@ -6234,28 +6255,28 @@ inline Client::Client(const char *scheme_host_port,
62346255
62356256 if (is_ssl) {
62366257#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
6237- cli_ = std::make_shared <SSLClient>(host.c_str (), port, client_cert_path ,
6238- client_key_path);
6258+ cli_ = detail::make_unique <SSLClient>(host.c_str (), port,
6259+ client_cert_path, client_key_path);
62396260 is_ssl_ = is_ssl;
62406261#endif
62416262 } else {
6242- cli_ = std::make_shared <ClientImpl>(host.c_str (), port, client_cert_path ,
6243- client_key_path);
6263+ cli_ = detail::make_unique <ClientImpl>(host.c_str (), port,
6264+ client_cert_path, client_key_path);
62446265 }
62456266 } else {
6246- cli_ = std::make_shared <ClientImpl>(scheme_host_port, 80 , client_cert_path ,
6247- client_key_path);
6267+ cli_ = detail::make_unique <ClientImpl>(scheme_host_port, 80 ,
6268+ client_cert_path, client_key_path);
62486269 }
62496270}
62506271
62516272inline Client::Client (const std::string &host, int port)
6252- : cli_ (std::make_shared <ClientImpl>(host, port)) {}
6273+ : cli_ (detail::make_unique <ClientImpl>(host, port)) {}
62536274
62546275inline Client::Client (const std::string &host, int port,
62556276 const std::string &client_cert_path,
62566277 const std::string &client_key_path)
6257- : cli_ (std::make_shared <ClientImpl>(host, port, client_cert_path,
6258- client_key_path)) {}
6278+ : cli_ (detail::make_unique <ClientImpl>(host, port, client_cert_path,
6279+ client_key_path)) {}
62596280
62606281inline Client::~Client () {}
62616282
0 commit comments