Make decorator copyable

This commit is contained in:
Vinnie Falco
2017-01-25 09:38:29 -05:00
parent c594bbac3f
commit 99706347cd
4 changed files with 62 additions and 9 deletions

View File

@@ -3,6 +3,7 @@
* bjam use clang on MACOSX
* Simplify Travis package install specification
* Add optional yield_to arguments
* Make decorator copyable
--------------------------------------------------------------------------------

View File

@@ -12,6 +12,7 @@
#include <beast/http/message.hpp>
#include <beast/http/string_body.hpp>
#include <beast/version.hpp>
#include <type_traits>
#include <utility>
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<class T>
@@ -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<abstract_decorator>;
class decorator_type
{
std::unique_ptr<abstract_decorator> 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<class T, class =
typename std::enable_if<! std::is_same<
typename std::decay<T>::type,
decorator_type>::value>>
decorator_type(T&& t)
: p_(new decorator<T>{std::forward<T>(t)})
{
}
void
operator()(request_type& req)
{
(*p_)(req);
}
void
operator()(response_type& res)
{
(*p_)(res);
}
};
} // detail
} // websocket

View File

@@ -128,7 +128,7 @@ protected:
stream_base& operator=(stream_base const&) = delete;
stream_base()
: d_(new decorator<default_decorator>{})
: d_(detail::default_decorator{})
{
}

View File

@@ -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<Body, Fields> 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<Body, Fields> 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;
}