From 99706347cd6d51e00f427a7985d3458402f9b905 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 25 Jan 2017 09:38:29 -0500 Subject: [PATCH] Make decorator copyable --- CHANGELOG.md | 1 + include/beast/websocket/detail/decorator.hpp | 62 +++++++++++++++++-- .../beast/websocket/detail/stream_base.hpp | 2 +- include/beast/websocket/impl/stream.ipp | 6 +- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b62cf34..b6d8be83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ * bjam use clang on MACOSX * Simplify Travis package install specification * Add optional yield_to arguments +* Make decorator copyable -------------------------------------------------------------------------------- diff --git a/include/beast/websocket/detail/decorator.hpp b/include/beast/websocket/detail/decorator.hpp index 1250d35b..7d10587f 100644 --- a/include/beast/websocket/detail/decorator.hpp +++ b/include/beast/websocket/detail/decorator.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include namespace beast { @@ -27,13 +28,17 @@ struct abstract_decorator virtual ~abstract_decorator() = default; + virtual + abstract_decorator* + copy() = 0; + virtual void operator()(request_type& req) = 0; virtual void - operator()(response_type& resp) = 0; + operator()(response_type& res) = 0; }; template @@ -69,6 +74,7 @@ class decorator : public abstract_decorator public: decorator() = default; + decorator(decorator const&) = default; decorator(T&& t) : t_(std::move(t)) @@ -80,6 +86,12 @@ public: { } + abstract_decorator* + copy() override + { + return new decorator(*this); + } + void operator()(request_type& req) override { @@ -87,9 +99,9 @@ public: } void - operator()(response_type& resp) override + operator()(response_type& res) override { - (*this)(resp, typename call_res_possible::type{}); + (*this)(res, typename call_res_possible::type{}); } private: @@ -124,8 +136,48 @@ struct default_decorator { }; -using decorator_type = - std::unique_ptr; +class decorator_type +{ + std::unique_ptr p_; + +public: + decorator_type(decorator_type&&) = default; + decorator_type& operator=(decorator_type&&) = default; + + decorator_type(decorator_type const& other) + : p_(other.p_->copy()) + { + } + + decorator_type& + operator=(decorator_type const& other) + { + p_ = std::unique_ptr< + abstract_decorator>{other.p_->copy()}; + return *this; + } + + template::type, + decorator_type>::value>> + decorator_type(T&& t) + : p_(new decorator{std::forward(t)}) + { + } + + void + operator()(request_type& req) + { + (*p_)(req); + } + + void + operator()(response_type& res) + { + (*p_)(res); + } +}; } // detail } // websocket diff --git a/include/beast/websocket/detail/stream_base.hpp b/include/beast/websocket/detail/stream_base.hpp index 2256d140..6bde6171 100644 --- a/include/beast/websocket/detail/stream_base.hpp +++ b/include/beast/websocket/detail/stream_base.hpp @@ -128,7 +128,7 @@ protected: stream_base& operator=(stream_base const&) = delete; stream_base() - : d_(new decorator{}) + : d_(detail::default_decorator{}) { } diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index 2e419249..9d89f9cd 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -72,7 +72,7 @@ build_request(boost::string_ref const& host, key = detail::make_sec_ws_key(maskgen_); req.fields.insert("Sec-WebSocket-Key", key); req.fields.insert("Sec-WebSocket-Version", "13"); - (*d_)(req); + d_(req); http::prepare(req, http::connection::upgrade); return req; } @@ -91,7 +91,7 @@ build_response(http::request const& req) res.reason = http::reason_string(res.status); res.version = req.version; res.body = text; - (*d_)(res); + d_(res); prepare(res, (is_keep_alive(req) && keep_alive_) ? http::connection::keep_alive : @@ -141,7 +141,7 @@ build_response(http::request const& req) detail::make_sec_ws_accept(key)); } res.fields.replace("Server", "Beast.WSProto"); - (*d_)(res); + d_(res); http::prepare(res, http::connection::upgrade); return res; }