Use std::make_unique

This commit is contained in:
Tatsuhiro Tsujikawa 2018-10-15 23:02:44 +09:00
parent 6c9196953e
commit ec5729b1fa
31 changed files with 134 additions and 145 deletions

View File

@ -305,7 +305,7 @@ public:
} }
} }
auto handler = auto handler =
make_unique<Http2Handler>(this, fd, ssl, get_next_session_id()); std::make_unique<Http2Handler>(this, fd, ssl, get_next_session_id());
if (!ssl) { if (!ssl) {
if (handler->connection_made() != 0) { if (handler->connection_made() != 0) {
return; return;
@ -358,11 +358,11 @@ public:
} }
FileEntry *cache_fd(const std::string &path, const FileEntry &ent) { FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
#ifdef HAVE_STD_MAP_EMPLACE #ifdef HAVE_STD_MAP_EMPLACE
auto rv = fd_cache_.emplace(path, make_unique<FileEntry>(ent)); auto rv = fd_cache_.emplace(path, std::make_unique<FileEntry>(ent));
#else // !HAVE_STD_MAP_EMPLACE #else // !HAVE_STD_MAP_EMPLACE
// for gcc-4.7 // for gcc-4.7
auto rv = auto rv = fd_cache_.insert(
fd_cache_.insert(std::make_pair(path, make_unique<FileEntry>(ent))); std::make_pair(path, std::make_unique<FileEntry>(ent)));
#endif // !HAVE_STD_MAP_EMPLACE #endif // !HAVE_STD_MAP_EMPLACE
auto &res = (*rv).second; auto &res = (*rv).second;
res->it = rv; res->it = rv;
@ -1023,7 +1023,7 @@ int Http2Handler::submit_push_promise(Stream *stream,
return promised_stream_id; return promised_stream_id;
} }
auto promised_stream = make_unique<Stream>(this, promised_stream_id); auto promised_stream = std::make_unique<Stream>(this, promised_stream_id);
auto &promised_header = promised_stream->header; auto &promised_header = promised_stream->header;
promised_header.method = StringRef::from_lit("GET"); promised_header.method = StringRef::from_lit("GET");
@ -1477,7 +1477,7 @@ int on_begin_headers_callback(nghttp2_session *session,
return 0; return 0;
} }
auto stream = make_unique<Stream>(hd, frame->hd.stream_id); auto stream = std::make_unique<Stream>(hd, frame->hd.stream_id);
add_stream_read_timeout(stream.get()); add_stream_read_timeout(stream.get());
@ -1832,10 +1832,10 @@ public:
if (config_->verbose) { if (config_->verbose) {
std::cerr << "spawning thread #" << i << std::endl; std::cerr << "spawning thread #" << i << std::endl;
} }
auto worker = make_unique<Worker>(); auto worker = std::make_unique<Worker>();
auto loop = ev_loop_new(get_ev_loop_flags()); auto loop = ev_loop_new(get_ev_loop_flags());
worker->sessions = worker->sessions = std::make_unique<Sessions>(sv, loop, config_,
make_unique<Sessions>(sv, loop, config_, sessions_->get_ssl_ctx()); sessions_->get_ssl_ctx());
ev_async_init(&worker->w, worker_acceptcb); ev_async_init(&worker->w, worker_acceptcb);
worker->w.data = worker.get(); worker->w.data = worker.get();
ev_async_start(loop, &worker->w); ev_async_start(loop, &worker->w);

View File

@ -34,7 +34,7 @@ namespace nghttp2 {
namespace asio_http2 { namespace asio_http2 {
namespace client { namespace client {
request::request() : impl_(make_unique<request_impl>()) {} request::request() : impl_(std::make_unique<request_impl>()) {}
request::~request() {} request::~request() {}

View File

@ -34,7 +34,7 @@ namespace nghttp2 {
namespace asio_http2 { namespace asio_http2 {
namespace client { namespace client {
response::response() : impl_(make_unique<response_impl>()) {} response::response() : impl_(std::make_unique<response_impl>()) {}
response::~response() {} response::~response() {}

View File

@ -473,7 +473,7 @@ stream *session_impl::create_push_stream(int32_t stream_id) {
} }
std::unique_ptr<stream> session_impl::create_stream() { std::unique_ptr<stream> session_impl::create_stream() {
return make_unique<stream>(this); return std::make_unique<stream>(this);
} }
const request *session_impl::submit(boost::system::error_code &ec, const request *session_impl::submit(boost::system::error_code &ec,

View File

@ -36,7 +36,7 @@ namespace asio_http2 {
namespace server { namespace server {
http2::http2() : impl_(make_unique<http2_impl>()) {} http2::http2() : impl_(std::make_unique<http2_impl>()) {}
http2::~http2() {} http2::~http2() {}

View File

@ -305,7 +305,8 @@ int http2_handler::start() {
} }
stream *http2_handler::create_stream(int32_t stream_id) { stream *http2_handler::create_stream(int32_t stream_id) {
auto p = streams_.emplace(stream_id, make_unique<stream>(this, stream_id)); auto p =
streams_.emplace(stream_id, std::make_unique<stream>(this, stream_id));
assert(p.second); assert(p.second);
return (*p.first).second.get(); return (*p.first).second.get();
} }

View File

@ -34,7 +34,7 @@ namespace nghttp2 {
namespace asio_http2 { namespace asio_http2 {
namespace server { namespace server {
request::request() : impl_(make_unique<request_impl>()) {} request::request() : impl_(std::make_unique<request_impl>()) {}
request::~request() {} request::~request() {}

View File

@ -34,7 +34,7 @@ namespace nghttp2 {
namespace asio_http2 { namespace asio_http2 {
namespace server { namespace server {
response::response() : impl_(make_unique<response_impl>()) {} response::response() : impl_(std::make_unique<response_impl>()) {}
response::~response() {} response::~response() {}

View File

@ -211,7 +211,7 @@ void rate_period_timeout_w_cb(struct ev_loop *loop, ev_timer *w, int revents) {
--worker->nreqs_rem; --worker->nreqs_rem;
} }
auto client = auto client =
make_unique<Client>(worker->next_client_id++, worker, req_todo); std::make_unique<Client>(worker->next_client_id++, worker, req_todo);
++worker->nconns_made; ++worker->nconns_made;
@ -869,9 +869,9 @@ int Client::connection_made() {
if (next_proto) { if (next_proto) {
auto proto = StringRef{next_proto, next_proto_len}; auto proto = StringRef{next_proto, next_proto_len};
if (util::check_h2_is_selected(proto)) { if (util::check_h2_is_selected(proto)) {
session = make_unique<Http2Session>(this); session = std::make_unique<Http2Session>(this);
} else if (util::streq(NGHTTP2_H1_1, proto)) { } else if (util::streq(NGHTTP2_H1_1, proto)) {
session = make_unique<Http1Session>(this); session = std::make_unique<Http1Session>(this);
} }
// Just assign next_proto to selected_proto anyway to show the // Just assign next_proto to selected_proto anyway to show the
@ -886,7 +886,7 @@ int Client::connection_made() {
std::cout std::cout
<< "Server does not support NPN/ALPN. Falling back to HTTP/1.1." << "Server does not support NPN/ALPN. Falling back to HTTP/1.1."
<< std::endl; << std::endl;
session = make_unique<Http1Session>(this); session = std::make_unique<Http1Session>(this);
selected_proto = NGHTTP2_H1_1.str(); selected_proto = NGHTTP2_H1_1.str();
break; break;
} }
@ -910,11 +910,11 @@ int Client::connection_made() {
} else { } else {
switch (config.no_tls_proto) { switch (config.no_tls_proto) {
case Config::PROTO_HTTP2: case Config::PROTO_HTTP2:
session = make_unique<Http2Session>(this); session = std::make_unique<Http2Session>(this);
selected_proto = NGHTTP2_CLEARTEXT_PROTO_VERSION_ID; selected_proto = NGHTTP2_CLEARTEXT_PROTO_VERSION_ID;
break; break;
case Config::PROTO_HTTP1_1: case Config::PROTO_HTTP1_1:
session = make_unique<Http1Session>(this); session = std::make_unique<Http1Session>(this);
selected_proto = NGHTTP2_H1_1.str(); selected_proto = NGHTTP2_H1_1.str();
break; break;
default: default:
@ -1319,7 +1319,7 @@ void Worker::run() {
--nreqs_rem; --nreqs_rem;
} }
auto client = make_unique<Client>(next_client_id++, this, req_todo); auto client = std::make_unique<Client>(next_client_id++, this, req_todo);
if (client->connect() != 0) { if (client->connect() != 0) {
std::cerr << "client could not connect to host" << std::endl; std::cerr << "client could not connect to host" << std::endl;
client->fail(); client->fail();
@ -1513,7 +1513,7 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
namespace { namespace {
void resolve_host() { void resolve_host() {
if (config.base_uri_unix) { if (config.base_uri_unix) {
auto res = make_unique<addrinfo>(); auto res = std::make_unique<addrinfo>();
res->ai_family = config.unix_addr.sun_family; res->ai_family = config.unix_addr.sun_family;
res->ai_socktype = SOCK_STREAM; res->ai_socktype = SOCK_STREAM;
res->ai_addrlen = sizeof(config.unix_addr); res->ai_addrlen = sizeof(config.unix_addr);
@ -1722,12 +1722,12 @@ std::unique_ptr<Worker> create_worker(uint32_t id, SSL_CTX *ssl_ctx,
} }
if (config.is_rate_mode()) { if (config.is_rate_mode()) {
return make_unique<Worker>(id, ssl_ctx, nreqs, nclients, rate, max_samples, return std::make_unique<Worker>(id, ssl_ctx, nreqs, nclients, rate,
&config); max_samples, &config);
} else { } else {
// Here rate is same as client because the rate_timeout callback // Here rate is same as client because the rate_timeout callback
// will be called only once // will be called only once
return make_unique<Worker>(id, ssl_ctx, nreqs, nclients, nclients, return std::make_unique<Worker>(id, ssl_ctx, nreqs, nclients, nclients,
max_samples, &config); max_samples, &config);
} }
} }

View File

@ -233,7 +233,7 @@ void Request::init_html_parser() {
base_uri += util::get_uri_field(uri.c_str(), u, UF_QUERY); base_uri += util::get_uri_field(uri.c_str(), u, UF_QUERY);
} }
html_parser = make_unique<HtmlParser>(base_uri); html_parser = std::make_unique<HtmlParser>(base_uri);
} }
int Request::update_html_parser(const uint8_t *data, size_t len, int fin) { int Request::update_html_parser(const uint8_t *data, size_t len, int fin) {
@ -527,7 +527,7 @@ int submit_request(HttpClient *client, const Headers &headers, Request *req) {
req->req_nva = std::move(build_headers); req->req_nva = std::move(build_headers);
if (expect_continue) { if (expect_continue) {
auto timer = make_unique<ContinueTimer>(client->loop, req); auto timer = std::make_unique<ContinueTimer>(client->loop, req);
req->continue_timer = std::move(timer); req->continue_timer = std::move(timer);
} }
@ -885,7 +885,7 @@ int HttpClient::connected() {
writefn = &HttpClient::write_clear; writefn = &HttpClient::write_clear;
if (need_upgrade()) { if (need_upgrade()) {
htp = make_unique<http_parser>(); htp = std::make_unique<http_parser>();
http_parser_init(htp.get(), HTTP_RESPONSE); http_parser_init(htp.get(), HTTP_RESPONSE);
htp->data = this; htp->data = this;
@ -1453,8 +1453,8 @@ bool HttpClient::add_request(const std::string &uri,
path_cache.insert(uri); path_cache.insert(uri);
} }
reqvec.push_back( reqvec.push_back(std::make_unique<Request>(uri, u, data_prd, data_length,
make_unique<Request>(uri, u, data_prd, data_length, pri_spec, level)); pri_spec, level));
return true; return true;
} }
@ -1854,7 +1854,7 @@ int on_begin_headers_callback(nghttp2_session *session,
nghttp2_priority_spec_default_init(&pri_spec); nghttp2_priority_spec_default_init(&pri_spec);
auto req = make_unique<Request>("", u, nullptr, 0, pri_spec); auto req = std::make_unique<Request>("", u, nullptr, 0, pri_spec);
req->stream_id = stream_id; req->stream_id = stream_id;
nghttp2_session_set_stream_user_data(session, stream_id, req.get()); nghttp2_session_set_stream_user_data(session, stream_id, req.get());

View File

@ -305,7 +305,7 @@ int save_pid() {
auto &pid_file = config->pid_file; auto &pid_file = config->pid_file;
auto len = config->pid_file.size() + SUFFIX.size(); auto len = config->pid_file.size() + SUFFIX.size();
auto buf = make_unique<char[]>(len + 1); auto buf = std::make_unique<char[]>(len + 1);
auto p = buf.get(); auto p = buf.get();
p = std::copy(std::begin(pid_file), std::end(pid_file), p); p = std::copy(std::begin(pid_file), std::end(pid_file), p);
@ -438,7 +438,7 @@ void exec_binary() {
nghttp2_Exit(EXIT_FAILURE); nghttp2_Exit(EXIT_FAILURE);
} }
auto argv = make_unique<char *[]>(suconfig.argc + 1); auto argv = std::make_unique<char *[]>(suconfig.argc + 1);
argv[0] = exec_path; argv[0] = exec_path;
for (int i = 1; i < suconfig.argc; ++i) { for (int i = 1; i < suconfig.argc; ++i) {
@ -454,7 +454,8 @@ void exec_binary() {
auto &listenerconf = config->conn.listener; auto &listenerconf = config->conn.listener;
// 2 for ENV_ORIG_PID and terminal nullptr. // 2 for ENV_ORIG_PID and terminal nullptr.
auto envp = make_unique<char *[]>(envlen + listenerconf.addrs.size() + 2); auto envp =
std::make_unique<char *[]>(envlen + listenerconf.addrs.size() + 2);
size_t envidx = 0; size_t envidx = 0;
std::vector<ImmutableString> fd_envs; std::vector<ImmutableString> fd_envs;
@ -1354,7 +1355,7 @@ int event_loop() {
return -1; return -1;
} }
worker_process_add(make_unique<WorkerProcess>(loop, pid, ipc_fd)); worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd));
// Write PID file when we are ready to accept connection from peer. // Write PID file when we are ready to accept connection from peer.
// This makes easier to write restart script for nghttpx. Because // This makes easier to write restart script for nghttpx. Because
@ -3140,7 +3141,7 @@ void reload_config(WorkerProcess *wp) {
LOG(NOTICE) << "Reloading configuration"; LOG(NOTICE) << "Reloading configuration";
auto cur_config = mod_config(); auto cur_config = mod_config();
auto new_config = make_unique<Config>(); auto new_config = std::make_unique<Config>();
fill_default_config(new_config.get()); fill_default_config(new_config.get());
@ -3195,7 +3196,7 @@ void reload_config(WorkerProcess *wp) {
// We no longer use signals for this worker. // We no longer use signals for this worker.
last_wp->shutdown_signal_watchers(); last_wp->shutdown_signal_watchers();
worker_process_add(make_unique<WorkerProcess>(loop, pid, ipc_fd)); worker_process_add(std::make_unique<WorkerProcess>(loop, pid, ipc_fd));
if (!get_config()->pid_file.empty()) { if (!get_config()->pid_file.empty()) {
save_pid(); save_pid();

View File

@ -478,7 +478,7 @@ void ClientHandler::setup_upstream_io_callback() {
// For non-TLS version, first create HttpsUpstream. It may be // For non-TLS version, first create HttpsUpstream. It may be
// upgraded to HTTP/2 through HTTP Upgrade or direct HTTP/2 // upgraded to HTTP/2 through HTTP Upgrade or direct HTTP/2
// connection. // connection.
upstream_ = make_unique<HttpsUpstream>(this); upstream_ = std::make_unique<HttpsUpstream>(this);
alpn_ = StringRef::from_lit("http/1.1"); alpn_ = StringRef::from_lit("http/1.1");
read_ = &ClientHandler::read_clear; read_ = &ClientHandler::read_clear;
write_ = &ClientHandler::write_clear; write_ = &ClientHandler::write_clear;
@ -584,7 +584,7 @@ int ClientHandler::validate_next_proto() {
if (util::check_h2_is_selected(proto)) { if (util::check_h2_is_selected(proto)) {
on_read_ = &ClientHandler::upstream_http2_connhd_read; on_read_ = &ClientHandler::upstream_http2_connhd_read;
auto http2_upstream = make_unique<Http2Upstream>(this); auto http2_upstream = std::make_unique<Http2Upstream>(this);
upstream_ = std::move(http2_upstream); upstream_ = std::move(http2_upstream);
alpn_ = make_string_ref(balloc_, proto); alpn_ = make_string_ref(balloc_, proto);
@ -600,7 +600,7 @@ int ClientHandler::validate_next_proto() {
} }
if (proto == StringRef::from_lit("http/1.1")) { if (proto == StringRef::from_lit("http/1.1")) {
upstream_ = make_unique<HttpsUpstream>(this); upstream_ = std::make_unique<HttpsUpstream>(this);
alpn_ = StringRef::from_lit("http/1.1"); alpn_ = StringRef::from_lit("http/1.1");
// At this point, input buffer is already filled with some bytes. // At this point, input buffer is already filled with some bytes.
@ -953,9 +953,9 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
switch (faddr_->alt_mode) { switch (faddr_->alt_mode) {
case ALTMODE_API: case ALTMODE_API:
return make_unique<APIDownstreamConnection>(worker_); return std::make_unique<APIDownstreamConnection>(worker_);
case ALTMODE_HEALTHMON: case ALTMODE_HEALTHMON:
return make_unique<HealthMonitorDownstreamConnection>(); return std::make_unique<HealthMonitorDownstreamConnection>();
} }
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
@ -1058,7 +1058,7 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
if (addr->proto == PROTO_HTTP2) { if (addr->proto == PROTO_HTTP2) {
auto http2session = select_http2_session_with_affinity(group, addr); auto http2session = select_http2_session_with_affinity(group, addr);
auto dconn = make_unique<Http2DownstreamConnection>(http2session); auto dconn = std::make_unique<Http2DownstreamConnection>(http2session);
dconn->set_client_handler(this); dconn->set_client_handler(this);
@ -1069,8 +1069,8 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
auto dconn = dconn_pool->pop_downstream_connection(); auto dconn = dconn_pool->pop_downstream_connection();
if (!dconn) { if (!dconn) {
dconn = make_unique<HttpDownstreamConnection>(group, aff_idx, conn_.loop, dconn = std::make_unique<HttpDownstreamConnection>(group, aff_idx,
worker_); conn_.loop, worker_);
} }
dconn->set_client_handler(this); dconn->set_client_handler(this);
@ -1129,7 +1129,7 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
return nullptr; return nullptr;
} }
auto dconn = make_unique<Http2DownstreamConnection>(http2session); auto dconn = std::make_unique<Http2DownstreamConnection>(http2session);
dconn->set_client_handler(this); dconn->set_client_handler(this);
@ -1152,8 +1152,8 @@ ClientHandler::get_downstream_connection(int &err, Downstream *downstream,
<< " Create new one"; << " Create new one";
} }
dconn = dconn = std::make_unique<HttpDownstreamConnection>(group, 0, conn_.loop,
make_unique<HttpDownstreamConnection>(group, 0, conn_.loop, worker_); worker_);
} }
dconn->set_client_handler(this); dconn->set_client_handler(this);
@ -1166,14 +1166,14 @@ MemchunkPool *ClientHandler::get_mcpool() { return worker_->get_mcpool(); }
SSL *ClientHandler::get_ssl() const { return conn_.tls.ssl; } SSL *ClientHandler::get_ssl() const { return conn_.tls.ssl; }
void ClientHandler::direct_http2_upgrade() { void ClientHandler::direct_http2_upgrade() {
upstream_ = make_unique<Http2Upstream>(this); upstream_ = std::make_unique<Http2Upstream>(this);
alpn_ = StringRef::from_lit(NGHTTP2_CLEARTEXT_PROTO_VERSION_ID); alpn_ = StringRef::from_lit(NGHTTP2_CLEARTEXT_PROTO_VERSION_ID);
on_read_ = &ClientHandler::upstream_read; on_read_ = &ClientHandler::upstream_read;
write_ = &ClientHandler::write_clear; write_ = &ClientHandler::write_clear;
} }
int ClientHandler::perform_http2_upgrade(HttpsUpstream *http) { int ClientHandler::perform_http2_upgrade(HttpsUpstream *http) {
auto upstream = make_unique<Http2Upstream>(this); auto upstream = std::make_unique<Http2Upstream>(this);
auto output = upstream->get_response_buf(); auto output = upstream->get_response_buf();

View File

@ -160,7 +160,7 @@ bool is_secure(const StringRef &filename) {
std::unique_ptr<TicketKeys> std::unique_ptr<TicketKeys>
read_tls_ticket_key_file(const std::vector<StringRef> &files, read_tls_ticket_key_file(const std::vector<StringRef> &files,
const EVP_CIPHER *cipher, const EVP_MD *hmac) { const EVP_CIPHER *cipher, const EVP_MD *hmac) {
auto ticket_keys = make_unique<TicketKeys>(); auto ticket_keys = std::make_unique<TicketKeys>();
auto &keys = ticket_keys->keys; auto &keys = ticket_keys->keys;
keys.resize(files.size()); keys.resize(files.size());
auto enc_keylen = EVP_CIPHER_key_length(cipher); auto enc_keylen = EVP_CIPHER_key_length(cipher);

View File

@ -238,7 +238,7 @@ int ConnectionHandler::create_single_worker() {
} }
} }
single_worker_ = make_unique<Worker>( single_worker_ = std::make_unique<Worker>(
loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(), loop_, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
ticket_keys_, this, config->conn.downstream); ticket_keys_, this, config->conn.downstream);
#ifdef HAVE_MRUBY #ifdef HAVE_MRUBY
@ -299,7 +299,7 @@ int ConnectionHandler::create_worker_thread(size_t num) {
for (size_t i = 0; i < num; ++i) { for (size_t i = 0; i < num; ++i) {
auto loop = ev_loop_new(config->ev_loop_flags); auto loop = ev_loop_new(config->ev_loop_flags);
auto worker = make_unique<Worker>( auto worker = std::make_unique<Worker>(
loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(), loop, sv_ssl_ctx, cl_ssl_ctx, session_cache_ssl_ctx, cert_tree_.get(),
ticket_keys_, this, config->conn.downstream); ticket_keys_, this, config->conn.downstream);
# ifdef HAVE_MRUBY # ifdef HAVE_MRUBY

View File

@ -251,7 +251,7 @@ void start_ev(std::vector<std::unique_ptr<ev_io>> &evs, struct ev_loop *loop,
} }
} }
auto w = make_unique<ev_io>(); auto w = std::make_unique<ev_io>();
ev_io_init(w.get(), cb, fd, event); ev_io_init(w.get(), cb, fd, event);
w->data = data; w->data = data;
ev_io_start(loop, w.get()); ev_io_start(loop, w.get());

View File

@ -106,7 +106,7 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
LOG(INFO) << "DNS entry not found for " << dnsq->host; LOG(INFO) << "DNS entry not found for " << dnsq->host;
} }
auto resolv = make_unique<DualDNSResolver>(loop_); auto resolv = std::make_unique<DualDNSResolver>(loop_);
auto host_copy = auto host_copy =
ImmutableString{std::begin(dnsq->host), std::end(dnsq->host)}; ImmutableString{std::begin(dnsq->host), std::end(dnsq->host)};
auto host = StringRef{host_copy}; auto host = StringRef{host_copy};
@ -180,7 +180,7 @@ int DNSTracker::resolve(Address *result, DNSQuery *dnsq) {
<< ", but it has been expired"; << ", but it has been expired";
} }
auto resolv = make_unique<DualDNSResolver>(loop_); auto resolv = std::make_unique<DualDNSResolver>(loop_);
auto host = StringRef{ent.host}; auto host = StringRef{ent.host};
rv = resolv->resolve(host); rv = resolv->resolve(host);

View File

@ -242,7 +242,7 @@ struct Response {
void resource_pushed(const StringRef &scheme, const StringRef &authority, void resource_pushed(const StringRef &scheme, const StringRef &authority,
const StringRef &path) { const StringRef &path) {
if (!pushed_resources) { if (!pushed_resources) {
pushed_resources = make_unique< pushed_resources = std::make_unique<
std::vector<std::tuple<StringRef, StringRef, StringRef>>>(); std::vector<std::tuple<StringRef, StringRef, StringRef>>>();
} }
pushed_resources->emplace_back(scheme, authority, path); pushed_resources->emplace_back(scheme, authority, path);

View File

@ -307,7 +307,7 @@ int Http2Session::disconnect(bool hard) {
int Http2Session::resolve_name() { int Http2Session::resolve_name() {
int rv; int rv;
auto dns_query = make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr_->host, [this](int status, const Address *result) { addr_->host, [this](int status, const Address *result) {
int rv; int rv;
@ -321,7 +321,7 @@ int Http2Session::resolve_name() {
delete this; delete this;
} }
}); });
resolved_addr_ = make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
auto dns_tracker = worker_->get_dns_tracker(); auto dns_tracker = worker_->get_dns_tracker();
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get());
switch (rv) { switch (rv) {
@ -405,7 +405,7 @@ int Http2Session::initiate_connection() {
on_read_ = &Http2Session::downstream_read_proxy; on_read_ = &Http2Session::downstream_read_proxy;
on_write_ = &Http2Session::downstream_connect_proxy; on_write_ = &Http2Session::downstream_connect_proxy;
proxy_htp_ = make_unique<http_parser>(); proxy_htp_ = std::make_unique<http_parser>();
http_parser_init(proxy_htp_.get(), HTTP_RESPONSE); http_parser_init(proxy_htp_.get(), HTTP_RESPONSE);
proxy_htp_->data = this; proxy_htp_->data = this;
@ -749,7 +749,7 @@ int Http2Session::submit_request(Http2DownstreamConnection *dconn,
const nghttp2_nv *nva, size_t nvlen, const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider *data_prd) { const nghttp2_data_provider *data_prd) {
assert(state_ == CONNECTED); assert(state_ == CONNECTED);
auto sd = make_unique<StreamData>(); auto sd = std::make_unique<StreamData>();
sd->dlnext = sd->dlprev = nullptr; sd->dlnext = sd->dlprev = nullptr;
// TODO Specify nullptr to pri_spec for now // TODO Specify nullptr to pri_spec for now
auto stream_id = auto stream_id =
@ -2215,7 +2215,7 @@ int Http2Session::handle_downstream_push_promise(Downstream *downstream,
auto handler = upstream->get_client_handler(); auto handler = upstream->get_client_handler();
auto promised_dconn = make_unique<Http2DownstreamConnection>(this); auto promised_dconn = std::make_unique<Http2DownstreamConnection>(this);
promised_dconn->set_client_handler(handler); promised_dconn->set_client_handler(handler);
auto ptr = promised_dconn.get(); auto ptr = promised_dconn.get();
@ -2225,7 +2225,7 @@ int Http2Session::handle_downstream_push_promise(Downstream *downstream,
return -1; return -1;
} }
auto promised_sd = make_unique<StreamData>(); auto promised_sd = std::make_unique<StreamData>();
nghttp2_session_set_stream_user_data(session_, promised_stream_id, nghttp2_session_set_stream_user_data(session_, promised_stream_id,
promised_sd.get()); promised_sd.get());

View File

@ -278,7 +278,7 @@ int on_begin_headers_callback(nghttp2_session *session,
} // namespace } // namespace
void Http2Upstream::on_start_request(const nghttp2_frame *frame) { void Http2Upstream::on_start_request(const nghttp2_frame *frame) {
auto downstream = make_unique<Downstream>(this, handler_->get_mcpool(), auto downstream = std::make_unique<Downstream>(this, handler_->get_mcpool(),
frame->hd.stream_id); frame->hd.stream_id);
nghttp2_session_set_stream_user_data(session_, frame->hd.stream_id, nghttp2_session_set_stream_user_data(session_, frame->hd.stream_id,
downstream.get()); downstream.get());
@ -705,7 +705,7 @@ int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
return 0; return 0;
} }
auto promised_downstream = make_unique<Downstream>( auto promised_downstream = std::make_unique<Downstream>(
upstream, handler->get_mcpool(), promised_stream_id); upstream, handler->get_mcpool(), promised_stream_id);
auto &req = promised_downstream->request(); auto &req = promised_downstream->request();
@ -2295,7 +2295,7 @@ Http2Upstream::on_downstream_push_promise(Downstream *downstream,
// promised_stream_id is for backend HTTP/2 session, not for // promised_stream_id is for backend HTTP/2 session, not for
// frontend. // frontend.
auto promised_downstream = auto promised_downstream =
make_unique<Downstream>(this, handler_->get_mcpool(), 0); std::make_unique<Downstream>(this, handler_->get_mcpool(), 0);
auto &promised_req = promised_downstream->request(); auto &promised_req = promised_downstream->request();
promised_downstream->set_downstream_stream_id(promised_stream_id); promised_downstream->set_downstream_stream_id(promised_stream_id);

View File

@ -316,7 +316,7 @@ int HttpDownstreamConnection::initiate_connection() {
if (addr->dns) { if (addr->dns) {
if (!check_dns_result) { if (!check_dns_result) {
auto dns_query = make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr->host, [this](int status, const Address *result) { addr->host, [this](int status, const Address *result) {
int rv; int rv;
@ -335,7 +335,7 @@ int HttpDownstreamConnection::initiate_connection() {
auto dns_tracker = worker_->get_dns_tracker(); auto dns_tracker = worker_->get_dns_tracker();
if (!resolved_addr_) { if (!resolved_addr_) {
resolved_addr_ = make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
} }
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get());
switch (rv) { switch (rv) {

View File

@ -71,7 +71,8 @@ void HttpsUpstream::on_start_request() {
} }
reset_current_header_length(); reset_current_header_length();
auto downstream = make_unique<Downstream>(this, handler_->get_mcpool(), 0); auto downstream =
std::make_unique<Downstream>(this, handler_->get_mcpool(), 0);
attach_downstream(std::move(downstream)); attach_downstream(std::move(downstream));
@ -959,7 +960,8 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
auto downstream = get_downstream(); auto downstream = get_downstream();
if (!downstream) { if (!downstream) {
attach_downstream(make_unique<Downstream>(this, handler_->get_mcpool(), 1)); attach_downstream(
std::make_unique<Downstream>(this, handler_->get_mcpool(), 1));
downstream = get_downstream(); downstream = get_downstream();
} }

View File

@ -227,7 +227,7 @@ int LiveCheck::initiate_connection() {
if (addr_->dns) { if (addr_->dns) {
if (!dns_query_) { if (!dns_query_) {
auto dns_query = make_unique<DNSQuery>( auto dns_query = std::make_unique<DNSQuery>(
addr_->host, [this](int status, const Address *result) { addr_->host, [this](int status, const Address *result) {
int rv; int rv;
@ -242,7 +242,7 @@ int LiveCheck::initiate_connection() {
auto dns_tracker = worker_->get_dns_tracker(); auto dns_tracker = worker_->get_dns_tracker();
if (!resolved_addr_) { if (!resolved_addr_) {
resolved_addr_ = make_unique<Address>(); resolved_addr_ = std::make_unique<Address>();
} }
rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get()); rv = dns_tracker->resolve(resolved_addr_.get(), dns_query.get());

View File

@ -59,7 +59,7 @@ LogConfig::LogConfig()
#ifndef NOTHREADS #ifndef NOTHREADS
# ifdef HAVE_THREAD_LOCAL # ifdef HAVE_THREAD_LOCAL
namespace { namespace {
thread_local std::unique_ptr<LogConfig> config = make_unique<LogConfig>(); thread_local std::unique_ptr<LogConfig> config = std::make_unique<LogConfig>();
} // namespace } // namespace
LogConfig *log_config() { return config.get(); } LogConfig *log_config() { return config.get(); }
@ -88,7 +88,7 @@ void delete_log_config() { delete log_config(); }
# endif // !HAVE_THREAD_LOCAL # endif // !HAVE_THREAD_LOCAL
#else // NOTHREADS #else // NOTHREADS
namespace { namespace {
std::unique_ptr<LogConfig> config = make_unique<LogConfig>(); std::unique_ptr<LogConfig> config = std::make_unique<LogConfig>();
} // namespace } // namespace
LogConfig *log_config() { return config.get(); } LogConfig *log_config() { return config.get(); }

View File

@ -37,8 +37,8 @@ MemcachedDispatcher::MemcachedDispatcher(const Address *addr,
MemchunkPool *mcpool, MemchunkPool *mcpool,
std::mt19937 &gen) std::mt19937 &gen)
: loop_(loop), : loop_(loop),
mconn_(make_unique<MemcachedConnection>(addr, loop_, ssl_ctx, sni_name, mconn_(std::make_unique<MemcachedConnection>(addr, loop_, ssl_ctx,
mcpool, gen)) {} sni_name, mcpool, gen)) {}
MemcachedDispatcher::~MemcachedDispatcher() {} MemcachedDispatcher::~MemcachedDispatcher() {}

View File

@ -180,7 +180,8 @@ RProc *compile(mrb_state *mrb, const StringRef &filename) {
std::unique_ptr<MRubyContext> create_mruby_context(const StringRef &filename) { std::unique_ptr<MRubyContext> create_mruby_context(const StringRef &filename) {
if (filename.empty()) { if (filename.empty()) {
return make_unique<MRubyContext>(nullptr, mrb_nil_value(), mrb_nil_value()); return std::make_unique<MRubyContext>(nullptr, mrb_nil_value(),
mrb_nil_value());
} }
auto mrb = mrb_open(); auto mrb = mrb_open();
@ -216,7 +217,7 @@ std::unique_ptr<MRubyContext> create_mruby_context(const StringRef &filename) {
mrb_gc_protect(mrb, env); mrb_gc_protect(mrb, env);
mrb_gc_protect(mrb, app); mrb_gc_protect(mrb, app);
return make_unique<MRubyContext>(mrb, std::move(app), std::move(env)); return std::make_unique<MRubyContext>(mrb, std::move(app), std::move(env));
} }
mrb_sym intern_ptr(mrb_state *mrb, void *ptr) { mrb_sym intern_ptr(mrb_state *mrb, void *ptr) {

View File

@ -67,7 +67,7 @@ void Router::add_node(RNode *node, const char *pattern, size_t patlen,
ssize_t index, ssize_t wildcard_index) { ssize_t index, ssize_t wildcard_index) {
auto pat = make_string_ref(balloc_, StringRef{pattern, patlen}); auto pat = make_string_ref(balloc_, StringRef{pattern, patlen});
auto new_node = auto new_node =
make_unique<RNode>(pat.c_str(), pat.size(), index, wildcard_index); std::make_unique<RNode>(pat.c_str(), pat.size(), index, wildcard_index);
add_next_node(node, std::move(new_node)); add_next_node(node, std::move(new_node));
} }
@ -131,8 +131,8 @@ size_t Router::add_route(const StringRef &pattern, size_t idx, bool wildcard) {
if (node->len > j) { if (node->len > j) {
// node must be split into 2 nodes. new_node is now the child // node must be split into 2 nodes. new_node is now the child
// of node. // of node.
auto new_node = make_unique<RNode>(&node->s[j], node->len - j, auto new_node = std::make_unique<RNode>(
node->index, node->wildcard_index); &node->s[j], node->len - j, node->index, node->wildcard_index);
std::swap(node->next, new_node->next); std::swap(node->next, new_node->next);
node->len = j; node->len = j;

View File

@ -329,7 +329,7 @@ int tls_session_new_cb(SSL *ssl, SSL_SESSION *session) {
LOG(INFO) << "Memcached: cache session, id=" << util::format_hex(id, idlen); LOG(INFO) << "Memcached: cache session, id=" << util::format_hex(id, idlen);
} }
auto req = make_unique<MemcachedRequest>(); auto req = std::make_unique<MemcachedRequest>();
req->op = MEMCACHED_OP_ADD; req->op = MEMCACHED_OP_ADD;
req->key = MEMCACHED_SESSION_CACHE_KEY_PREFIX.str(); req->key = MEMCACHED_SESSION_CACHE_KEY_PREFIX.str();
req->key += req->key +=
@ -397,7 +397,7 @@ SSL_SESSION *tls_session_get_cb(SSL *ssl,
<< util::format_hex(id, idlen); << util::format_hex(id, idlen);
} }
auto req = make_unique<MemcachedRequest>(); auto req = std::make_unique<MemcachedRequest>();
req->op = MEMCACHED_OP_GET; req->op = MEMCACHED_OP_GET;
req->key = MEMCACHED_SESSION_CACHE_KEY_PREFIX.str(); req->key = MEMCACHED_SESSION_CACHE_KEY_PREFIX.str();
req->key += req->key +=
@ -1831,7 +1831,7 @@ std::unique_ptr<CertLookupTree> create_cert_lookup_tree() {
if (!upstream_tls_enabled(config->conn)) { if (!upstream_tls_enabled(config->conn)) {
return nullptr; return nullptr;
} }
return make_unique<CertLookupTree>(); return std::make_unique<CertLookupTree>();
} }
namespace { namespace {

View File

@ -36,7 +36,7 @@ using namespace nghttp2;
namespace shrpx { namespace shrpx {
void test_shrpx_tls_create_lookup_tree(void) { void test_shrpx_tls_create_lookup_tree(void) {
auto tree = make_unique<tls::CertLookupTree>(); auto tree = std::make_unique<tls::CertLookupTree>();
constexpr StringRef hostnames[] = { constexpr StringRef hostnames[] = {
StringRef::from_lit("example.com"), // 0 StringRef::from_lit("example.com"), // 0
@ -85,7 +85,7 @@ void test_shrpx_tls_create_lookup_tree(void) {
}; };
num = array_size(names); num = array_size(names);
tree = make_unique<tls::CertLookupTree>(); tree = std::make_unique<tls::CertLookupTree>();
for (size_t idx = 0; idx < num; ++idx) { for (size_t idx = 0; idx < num; ++idx) {
tree->add_cert(names[idx], idx); tree->add_cert(names[idx], idx);
} }
@ -123,7 +123,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
NGHTTP2_SRC_DIR "/test.nghttp2.org.pem"; NGHTTP2_SRC_DIR "/test.nghttp2.org.pem";
auto nghttp2_ssl_ctx = SSL_CTX_new(SSLv23_server_method()); auto nghttp2_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
auto nghttp2_ssl_ctx_del = defer(SSL_CTX_free, nghttp2_ssl_ctx); auto nghttp2_ssl_ctx_del = defer(SSL_CTX_free, nghttp2_ssl_ctx);
auto nghttp2_tls_ctx_data = make_unique<tls::TLSContextData>(); auto nghttp2_tls_ctx_data = std::make_unique<tls::TLSContextData>();
nghttp2_tls_ctx_data->cert_file = nghttp2_certfile; nghttp2_tls_ctx_data->cert_file = nghttp2_certfile;
SSL_CTX_set_app_data(nghttp2_ssl_ctx, nghttp2_tls_ctx_data.get()); SSL_CTX_set_app_data(nghttp2_ssl_ctx, nghttp2_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(nghttp2_ssl_ctx, nghttp2_certfile); rv = SSL_CTX_use_certificate_chain_file(nghttp2_ssl_ctx, nghttp2_certfile);
@ -134,7 +134,7 @@ void test_shrpx_tls_cert_lookup_tree_add_ssl_ctx(void) {
NGHTTP2_SRC_DIR "/test.example.com.pem"; NGHTTP2_SRC_DIR "/test.example.com.pem";
auto examples_ssl_ctx = SSL_CTX_new(SSLv23_server_method()); auto examples_ssl_ctx = SSL_CTX_new(SSLv23_server_method());
auto examples_ssl_ctx_del = defer(SSL_CTX_free, examples_ssl_ctx); auto examples_ssl_ctx_del = defer(SSL_CTX_free, examples_ssl_ctx);
auto examples_tls_ctx_data = make_unique<tls::TLSContextData>(); auto examples_tls_ctx_data = std::make_unique<tls::TLSContextData>();
examples_tls_ctx_data->cert_file = examples_certfile; examples_tls_ctx_data->cert_file = examples_certfile;
SSL_CTX_set_app_data(examples_ssl_ctx, examples_tls_ctx_data.get()); SSL_CTX_set_app_data(examples_ssl_ctx, examples_tls_ctx_data.get());
rv = SSL_CTX_use_certificate_chain_file(examples_ssl_ctx, examples_certfile); rv = SSL_CTX_use_certificate_chain_file(examples_ssl_ctx, examples_certfile);

View File

@ -133,7 +133,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
conn_handler_(conn_handler), conn_handler_(conn_handler),
ticket_keys_(ticket_keys), ticket_keys_(ticket_keys),
connect_blocker_( connect_blocker_(
make_unique<ConnectBlocker>(randgen_, loop_, []() {}, []() {})), std::make_unique<ConnectBlocker>(randgen_, loop_, []() {}, []() {})),
graceful_shutdown_(false) { graceful_shutdown_(false) {
ev_async_init(&w_, eventcb); ev_async_init(&w_, eventcb);
w_.data = this; w_.data = this;
@ -148,7 +148,7 @@ Worker::Worker(struct ev_loop *loop, SSL_CTX *sv_ssl_ctx, SSL_CTX *cl_ssl_ctx,
auto &session_cacheconf = get_config()->tls.session_cache; auto &session_cacheconf = get_config()->tls.session_cache;
if (!session_cacheconf.memcached.host.empty()) { if (!session_cacheconf.memcached.host.empty()) {
session_cache_memcached_dispatcher_ = make_unique<MemcachedDispatcher>( session_cache_memcached_dispatcher_ = std::make_unique<MemcachedDispatcher>(
&session_cacheconf.memcached.addr, loop, &session_cacheconf.memcached.addr, loop,
tls_session_cache_memcached_ssl_ctx, tls_session_cache_memcached_ssl_ctx,
StringRef{session_cacheconf.memcached.host}, &mcpool_, randgen_); StringRef{session_cacheconf.memcached.host}, &mcpool_, randgen_);
@ -250,8 +250,8 @@ void Worker::replace_downstream_config(
auto shared_addr_ptr = shared_addr.get(); auto shared_addr_ptr = shared_addr.get();
dst_addr.connect_blocker = dst_addr.connect_blocker = std::make_unique<ConnectBlocker>(
make_unique<ConnectBlocker>(randgen_, loop_, randgen_, loop_,
[shared_addr_ptr, &dst_addr]() { [shared_addr_ptr, &dst_addr]() {
switch (dst_addr.proto) { switch (dst_addr.proto) {
case PROTO_HTTP1: case PROTO_HTTP1:
@ -277,8 +277,8 @@ void Worker::replace_downstream_config(
} }
}); });
dst_addr.live_check = dst_addr.live_check = std::make_unique<LiveCheck>(
make_unique<LiveCheck>(loop_, cl_ssl_ctx_, this, &dst_addr, randgen_); loop_, cl_ssl_ctx_, this, &dst_addr, randgen_);
if (dst_addr.proto == PROTO_HTTP2) { if (dst_addr.proto == PROTO_HTTP2) {
++num_http2; ++num_http2;
@ -305,7 +305,7 @@ void Worker::replace_downstream_config(
if (shared_addr->affinity.type != AFFINITY_NONE) { if (shared_addr->affinity.type != AFFINITY_NONE) {
for (auto &addr : shared_addr->addrs) { for (auto &addr : shared_addr->addrs) {
addr.dconn_pool = make_unique<DownstreamConnectionPool>(); addr.dconn_pool = std::make_unique<DownstreamConnectionPool>();
} }
} }

View File

@ -270,7 +270,7 @@ void memcached_get_ticket_key_cb(struct ev_loop *loop, ev_timer *w,
auto conn_handler = static_cast<ConnectionHandler *>(w->data); auto conn_handler = static_cast<ConnectionHandler *>(w->data);
auto dispatcher = conn_handler->get_tls_ticket_key_memcached_dispatcher(); auto dispatcher = conn_handler->get_tls_ticket_key_memcached_dispatcher();
auto req = make_unique<MemcachedRequest>(); auto req = std::make_unique<MemcachedRequest>();
req->key = "nghttpx:tls-ticket-key"; req->key = "nghttpx:tls-ticket-key";
req->op = MEMCACHED_OP_GET; req->op = MEMCACHED_OP_GET;
req->cb = [conn_handler, w](MemcachedRequest *req, MemcachedResult res) { req->cb = [conn_handler, w](MemcachedRequest *req, MemcachedResult res) {
@ -411,16 +411,16 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
auto gen = util::make_mt19937(); auto gen = util::make_mt19937();
auto conn_handler = make_unique<ConnectionHandler>(loop, gen); auto conn_handler = std::make_unique<ConnectionHandler>(loop, gen);
for (auto &addr : config->conn.listener.addrs) { for (auto &addr : config->conn.listener.addrs) {
conn_handler->add_acceptor( conn_handler->add_acceptor(
make_unique<AcceptHandler>(&addr, conn_handler.get())); std::make_unique<AcceptHandler>(&addr, conn_handler.get()));
} }
#ifdef HAVE_NEVERBLEED #ifdef HAVE_NEVERBLEED
std::array<char, NEVERBLEED_ERRBUF_SIZE> nb_errbuf; std::array<char, NEVERBLEED_ERRBUF_SIZE> nb_errbuf;
auto nb = make_unique<neverbleed_t>(); auto nb = std::make_unique<neverbleed_t>();
if (neverbleed_init(nb.get(), nb_errbuf.data()) != 0) { if (neverbleed_init(nb.get(), nb_errbuf.data()) != 0) {
LOG(FATAL) << "neverbleed_init failed: " << nb_errbuf.data(); LOG(FATAL) << "neverbleed_init failed: " << nb_errbuf.data();
return -1; return -1;
@ -452,7 +452,7 @@ int worker_process_event_loop(WorkerProcessConfig *wpconf) {
} }
conn_handler->set_tls_ticket_key_memcached_dispatcher( conn_handler->set_tls_ticket_key_memcached_dispatcher(
make_unique<MemcachedDispatcher>( std::make_unique<MemcachedDispatcher>(
&ticketconf.memcached.addr, loop, ssl_ctx, &ticketconf.memcached.addr, loop, ssl_ctx,
StringRef{memcachedconf.host}, &mcpool, gen)); StringRef{memcachedconf.host}, &mcpool, gen));

View File

@ -39,22 +39,6 @@
namespace nghttp2 { namespace nghttp2 {
#if __cplusplus > 201103L
using std::make_unique;
#else // __cplusplus <= 201103L
template <typename T, typename... U>
typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(U &&... u) {
return std::unique_ptr<T>(new T(std::forward<U>(u)...));
}
template <typename T>
typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
make_unique(size_t size) {
return std::unique_ptr<T>(new typename std::remove_extent<T>::type[size]());
}
#endif // __cplusplus <= 201103L
// std::forward is constexpr since C++14 // std::forward is constexpr since C++14
template <typename... T> template <typename... T>
constexpr std::array< constexpr std::array<
@ -201,7 +185,7 @@ constexpr double operator"" _ms(unsigned long long ms) { return ms / 1000.; }
// Returns a copy of NULL-terminated string [first, last). // Returns a copy of NULL-terminated string [first, last).
template <typename InputIt> template <typename InputIt>
std::unique_ptr<char[]> strcopy(InputIt first, InputIt last) { std::unique_ptr<char[]> strcopy(InputIt first, InputIt last) {
auto res = make_unique<char[]>(last - first + 1); auto res = std::make_unique<char[]>(last - first + 1);
*std::copy(first, last, res.get()) = '\0'; *std::copy(first, last, res.get()) = '\0';
return res; return res;
} }