Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

serializer constructs source #77

Merged
merged 2 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions include/boost/http_proto/detail/impl/workspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ struct alignas(alignof(::max_align_t))
U u;

any_impl() = delete;
any_impl(any_impl&&) = default;
any_impl(any_impl const&) = delete;
any_impl(any_impl&&) = delete;

template<class U_>
explicit any_impl(U_&& u_)
: u(std::move(u_))
template<class... Args>
explicit any_impl(Args&&... args)
: u(std::forward<Args>(args)...)
{
}
};
Expand Down Expand Up @@ -86,10 +87,10 @@ space_needed()
return sizeof(any_impl<U>);
}

template<class T>
template<class T, class... Args>
auto
workspace::
push(T&& t) ->
emplace(Args&&... args) ->
typename std::decay<T>::type&
{
static_assert(
Expand All @@ -102,7 +103,7 @@ push(T&& t) ->
undo u(*this);
auto p = ::new(bump_down(
sizeof(U), alignof(U))) U(
std::forward<T>(t));
std::forward<Args>(args)...);
u.commit();
p->next = reinterpret_cast<
any*>(head_);
Expand Down
4 changes: 2 additions & 2 deletions include/boost/http_proto/detail/workspace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ class workspace
reserve_front(
std::size_t n);

template<class T>
template<class T, class... Args>
typename std::decay<T>::type&
push(T&& t);
emplace(Args&&... args);

template<class T>
T*
Expand Down
11 changes: 5 additions & 6 deletions include/boost/http_proto/impl/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ set_body(
if(! got_header())
detail::throw_logic_error();

auto& dyn = ws_.push(
auto& dyn = ws_.emplace<
buffers::any_dynamic_buffer_impl<typename
std::decay<ElasticBuffer>::type,
buffers_N>(std::forward<
ElasticBuffer>(eb)));
buffers_N>>(std::forward<ElasticBuffer>(eb));
eb_ = &dyn;
how_ = how::elastic;
on_set_body();
Expand All @@ -81,10 +80,10 @@ set_body(
if(! got_header())
detail::throw_logic_error();

auto& dyn = ws_.push(
auto& dyn = ws_.emplace<
buffers::any_dynamic_buffer_impl<typename
std::decay<ElasticBuffer>::type&,
buffers_N>(eb));
buffers_N>>(eb);
eb_ = &dyn;
how_ = how::elastic;
on_set_body();
Expand All @@ -109,7 +108,7 @@ set_body(
if(! got_header())
detail::throw_logic_error();

auto& s = ws_.push(
auto& s = ws_.emplace<Sink>(
std::forward<Sink>(sink));
sink_ = &s;
how_ = how::sink;
Expand Down
26 changes: 13 additions & 13 deletions include/boost/http_proto/impl/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

#include <boost/http_proto/detail/except.hpp>
#include <boost/buffers/range.hpp>
#include <iterator>
#include <new>
#include <utility>
ashtum marked this conversation as resolved.
Show resolved Hide resolved

namespace boost {
Expand Down Expand Up @@ -76,8 +74,8 @@ start(
{
start_init(m);
auto const& bs =
ws_.push(std::forward<
ConstBufferSequence>(body));
ws_.emplace<ConstBufferSequence>(
std::forward<ConstBufferSequence>(body));
std::size_t n = std::distance(
buffers::begin(bs),
buffers::end(bs));
Expand All @@ -91,21 +89,23 @@ start(

template<
class Source,
class... Args,
class>
auto
Source&
serializer::
start(
message_view_base const& m,
Source&& src0) ->
typename std::decay<
Source>::type&
Args&&... args)
ashtum marked this conversation as resolved.
Show resolved Hide resolved
{
static_assert(
std::is_constructible<Source, Args...>::value ||
std::is_constructible<Source, buffered_base::allocator&, Args...>::value,
"The Source cannot be constructed with the given arguments");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice !


start_init(m);
auto& src = ws_.push(
std::forward<
Source>(src0));
start_source(
m, std::addressof(src));
auto& src = construct_source<Source>(
std::forward<Args>(args)...);
start_source(m, std::addressof(src));
return src;
}

Expand Down
44 changes: 39 additions & 5 deletions include/boost/http_proto/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,17 @@ class BOOST_SYMBOL_VISIBLE
undefined behavior.
*/
template<
class Source
class Source,
class... Args
#ifndef BOOST_HTTP_PROTO_DOCS
,class = typename std::enable_if<
is_source<Source>::value>::type
#endif
>
auto
Source&
start(
message_view_base const& m,
Source&& body) ->
typename std::decay<
Source>::type&;
Args&&... args);

//--------------------------------------------

Expand Down Expand Up @@ -192,6 +191,41 @@ class BOOST_SYMBOL_VISIBLE
make_array(std::size_t n) ->
detail::array_of_const_buffers;

template<
class Source,
class... Args,
typename std::enable_if<
std::is_constructible<
Source,
Args...>::value>::type* = nullptr>
Source&
construct_source(Args&&... args)
{
return ws_.emplace<Source>(
std::forward<Args>(args)...);
}

template<
class Source,
class... Args,
typename std::enable_if<
std::is_constructible<
Source,
buffered_base::allocator&,
Args...>::value>::type* = nullptr>
Source&
construct_source(Args&&... args)
ashtum marked this conversation as resolved.
Show resolved Hide resolved
{
buffered_base::allocator a(
ws_.data(),
(ws_.size() - ws_.space_needed<Source>()) / 2,
false);
auto& src = ws_.emplace<Source>(
a, std::forward<Args>(args)...);
ws_.reserve_front(a.size_used());
return src;
}

BOOST_HTTP_PROTO_DECL void start_init(message_view_base const&);
BOOST_HTTP_PROTO_DECL void start_empty(message_view_base const&);
BOOST_HTTP_PROTO_DECL void start_buffers(message_view_base const&);
Expand Down
1 change: 0 additions & 1 deletion include/boost/http_proto/source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ namespace http_proto {
*/
struct BOOST_HTTP_PROTO_DECL
source
: buffered_base
{
/** The results of producing data.
*/
Expand Down
5 changes: 0 additions & 5 deletions src/serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,11 +435,6 @@ start_source(
2); // tmp
//if(! cod_)
{
buffered_base::allocator a(
ws_.data(), ws_.size()/2, false);
src->init(a);
ws_.reserve_front(a.size_used());

ashtum marked this conversation as resolved.
Show resolved Hide resolved
tmp0_ = { ws_.data(), ws_.size() };
if(tmp0_.capacity() <
18 + // chunk size
Expand Down
12 changes: 6 additions & 6 deletions test/unit/serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct serializer_test

results
on_read(
buffers::mutable_buffer b)
buffers::mutable_buffer b) override
{
BOOST_TEST(! is_done_);
results rv;
Expand Down Expand Up @@ -162,10 +162,10 @@ struct serializer_test
sr.start(res);
sr.start(res, buffers::const_buffer{});
sr.start(res, buffers::mutable_buffer{});
sr.start(res, test_source{"12345"});
sr.start<test_source>(res, "12345");
sr.start(res, make_const(buffers::const_buffer{}));
sr.start(res, make_const(buffers::mutable_buffer{}));
sr.start(res, make_const(test_source{"12345"}));
sr.start<test_source>(res, make_const("12345"));

serializer(65536);
#ifdef BOOST_HTTP_PROTO_HAS_ZLIB
Expand Down Expand Up @@ -244,7 +244,7 @@ struct serializer_test
// we limit the buffer size of the serializer, requiring
// it to make multiple calls to source::read
serializer sr(1024);
sr.start(res, std::forward<
sr.start<Source>(res, std::forward<
Source>(src));
std::string s = read(sr);
f(s);
Expand Down Expand Up @@ -377,7 +377,7 @@ struct serializer_test
"Expect: 100-continue\r\n"
"Content-Length: 5\r\n"
"\r\n");
sr.start(req, test_source{"12345"});
sr.start<test_source>(req, "12345");
std::string s;
system::result<
serializer::const_buffers_type> rv;
Expand Down Expand Up @@ -457,7 +457,7 @@ struct serializer_test
"\r\n";
serializer sr;
response res(sv);
sr.start(res, test_source{"12345"});
sr.start<test_source>(res, "12345");
auto s = read(sr);
BOOST_TEST(s ==
"HTTP/1.1 200 OK\r\n"
Expand Down
Loading