Skip to content

Commit d92c02d

Browse files
committed
feat: parsers are default constructible and assignable
1 parent 5909957 commit d92c02d

6 files changed

Lines changed: 191 additions & 73 deletions

File tree

include/boost/http_proto/parser.hpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -614,16 +614,11 @@ class parser
614614
friend class response_parser;
615615
class impl;
616616

617-
BOOST_HTTP_PROTO_DECL
618-
parser(
619-
const rts::context&,
620-
detail::kind);
621-
622-
BOOST_HTTP_PROTO_DECL
623-
parser(parser&& other) noexcept;
624-
625-
BOOST_HTTP_PROTO_DECL
626-
~parser();
617+
BOOST_HTTP_PROTO_DECL ~parser();
618+
BOOST_HTTP_PROTO_DECL parser() noexcept;
619+
BOOST_HTTP_PROTO_DECL parser(parser&& other) noexcept;
620+
BOOST_HTTP_PROTO_DECL parser(rts::context const&, detail::kind);
621+
BOOST_HTTP_PROTO_DECL void assign(parser&& other) noexcept;
627622

628623
BOOST_HTTP_PROTO_DECL
629624
void

include/boost/http_proto/request_parser.hpp

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,62 @@ class request_parser
4343
}
4444
};
4545

46+
/** Destructor.
47+
48+
Any views or buffers obtained from this
49+
parser become invalid.
50+
*/
51+
~request_parser() = default;
52+
53+
/** Constructor.
54+
55+
Default-constructed parsers do not reference any
56+
implementation and therefore must be assigned to before using.
57+
*/
58+
request_parser() noexcept = default;
59+
60+
/** Constructor.
61+
62+
The states of `other` are transferred
63+
to the newly constructed object,
64+
including the allocated buffer.
65+
After construction, the only valid
66+
operations on the moved-from object
67+
are destruction and assignment.
68+
69+
Buffer sequences previously obtained
70+
using @ref prepare or @ref pull_body
71+
remain valid.
72+
73+
@par Complexity
74+
Constant.
75+
76+
@param other The parser to move from.
77+
*/
78+
request_parser(
79+
request_parser&& other) noexcept = default;
80+
81+
/** Assignment.
82+
The states of `other` are transferred
83+
to this object, including the allocated
84+
buffer.
85+
After assignment, the only valid
86+
operations on the moved-from object
87+
are destruction and assignment.
88+
Buffer sequences previously obtained
89+
using @ref prepare or @ref pull_body
90+
remain valid.
91+
@par Complexity
92+
Constant.
93+
@param other The parser to move from.
94+
*/
95+
request_parser&
96+
operator=(request_parser&& other) noexcept
97+
{
98+
assign(std::move(other));
99+
return *this;
100+
}
101+
46102
/** Constructor.
47103
48104
Constructs a parser that uses the @ref
@@ -84,35 +140,7 @@ class request_parser
84140
*/
85141
BOOST_HTTP_PROTO_DECL
86142
explicit
87-
request_parser(const rts::context& ctx);
88-
89-
/** Constructor.
90-
91-
The states of `other` are transferred
92-
to the newly constructed object,
93-
including the allocated buffer.
94-
After construction, the only valid
95-
operations on the moved-from object
96-
are destruction and assignment.
97-
98-
Buffer sequences previously obtained
99-
using @ref prepare or @ref pull_body
100-
remain valid.
101-
102-
@par Complexity
103-
Constant.
104-
105-
@param other The parser to move from.
106-
*/
107-
request_parser(
108-
request_parser&& other) noexcept = default;
109-
110-
/** Destructor.
111-
112-
Any views or buffers obtained from this
113-
parser become invalid.
114-
*/
115-
~request_parser() = default;
143+
request_parser(rts::context const& ctx);
116144

117145
/** Return a reference to the parsed request headers.
118146

include/boost/http_proto/response_parser.hpp

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,62 @@ class response_parser
4343
}
4444
};
4545

46+
/** Destructor.
47+
48+
Any views or buffers obtained from this
49+
parser become invalid.
50+
*/
51+
~response_parser() = default;
52+
53+
/** Constructor.
54+
55+
Default-constructed parsers do not reference any
56+
implementation and therefore must be assigned to before using.
57+
*/
58+
response_parser() = default;
59+
60+
/** Constructor.
61+
62+
The states of `other` are transferred
63+
to the newly constructed object,
64+
including the allocated buffer.
65+
After construction, the only valid
66+
operations on the moved-from object
67+
are destruction and assignemt.
68+
69+
Buffer sequences previously obtained
70+
using @ref prepare or @ref pull_body
71+
remain valid.
72+
73+
@par Complexity
74+
Constant.
75+
76+
@param other The parser to move from.
77+
*/
78+
response_parser(
79+
response_parser&& other) noexcept = default;
80+
81+
/** Assignment.
82+
The states of `other` are transferred
83+
to this object, including the allocated
84+
buffer.
85+
After assignment, the only valid
86+
operations on the moved-from object
87+
are destruction and assignment.
88+
Buffer sequences previously obtained
89+
using @ref prepare or @ref pull_body
90+
remain valid.
91+
@par Complexity
92+
Constant.
93+
@param other The parser to move from.
94+
*/
95+
response_parser&
96+
operator=(response_parser&& other) noexcept
97+
{
98+
assign(std::move(other));
99+
return *this;
100+
}
101+
46102
/** Constructor.
47103
48104
Constructs a parser that uses the @ref
@@ -84,35 +140,7 @@ class response_parser
84140
*/
85141
BOOST_HTTP_PROTO_DECL
86142
explicit
87-
response_parser(const rts::context& ctx);
88-
89-
/** Constructor.
90-
91-
The states of `other` are transferred
92-
to the newly constructed object,
93-
including the allocated buffer.
94-
After construction, the only valid
95-
operations on the moved-from object
96-
are destruction and assignemt.
97-
98-
Buffer sequences previously obtained
99-
using @ref prepare or @ref pull_body
100-
remain valid.
101-
102-
@par Complexity
103-
Constant.
104-
105-
@param other The parser to move from.
106-
*/
107-
response_parser(
108-
response_parser&& other) noexcept = default;
109-
110-
/** Destructor.
111-
112-
Any views or buffers obtained from this
113-
parser become invalid.
114-
*/
115-
~response_parser() = default;
143+
response_parser(rts::context const& ctx);
116144

117145
/** Prepare for the next message on the stream.
118146

src/parser.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,11 +1848,15 @@ class parser::impl
18481848
//------------------------------------------------
18491849

18501850
parser::
1851-
parser(const rts::context& ctx, detail::kind k)
1852-
: impl_(new impl(ctx, k))
1851+
~parser()
1852+
{
1853+
delete impl_;
1854+
}
1855+
1856+
parser::
1857+
parser() noexcept
1858+
: impl_(nullptr)
18531859
{
1854-
// TODO: use a single allocation for
1855-
// impl and workspace buffer.
18561860
}
18571861

18581862
parser::
@@ -1863,9 +1867,24 @@ parser(parser&& other) noexcept
18631867
}
18641868

18651869
parser::
1866-
~parser()
1870+
parser(
1871+
rts::context const& ctx,
1872+
detail::kind k)
1873+
: impl_(new impl(ctx, k))
1874+
{
1875+
// TODO: use a single allocation for
1876+
// impl and workspace buffer.
1877+
}
1878+
1879+
void
1880+
parser::
1881+
assign(parser&& other) noexcept
18671882
{
1883+
if(this == &other)
1884+
return;
18681885
delete impl_;
1886+
impl_ = other.impl_;
1887+
other.impl_ = nullptr;
18691888
}
18701889

18711890
//--------------------------------------------

test/unit/request_parser.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,26 @@ struct request_parser_test
200200
void
201201
testSpecial()
202202
{
203+
// request_parser()
204+
{
205+
BOOST_TEST_NO_THROW(request_parser());
206+
}
207+
208+
// operator=(request_parser&&)
209+
{
210+
request_parser pr;
211+
BOOST_TEST_NO_THROW(pr = request_parser());
212+
}
213+
{
214+
request_parser pr;
215+
216+
rts::context ctx;
217+
request_parser::config cfg;
218+
install_parser_service(ctx, cfg);
219+
220+
BOOST_TEST_NO_THROW(pr = request_parser(ctx));
221+
}
222+
203223
// request_parser(rts::context&)
204224
{
205225
rts::context ctx;
@@ -215,6 +235,10 @@ struct request_parser_test
215235
request_parser pr1(ctx);
216236
request_parser pr2(std::move(pr1));
217237
}
238+
{
239+
BOOST_TEST_NO_THROW(
240+
request_parser(request_parser()));
241+
}
218242
}
219243

220244
//--------------------------------------------

test/unit/response_parser.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ class response_parser_test
2323
void
2424
testSpecial()
2525
{
26+
// response_parser()
27+
{
28+
BOOST_TEST_NO_THROW(response_parser());
29+
}
30+
31+
// operator=(response_parser&&)
32+
{
33+
response_parser pr;
34+
35+
rts::context ctx;
36+
response_parser::config cfg;
37+
install_parser_service(ctx, cfg);
38+
39+
BOOST_TEST_NO_THROW(pr = response_parser(ctx));
40+
}
41+
{
42+
response_parser pr;
43+
BOOST_TEST_NO_THROW(pr = response_parser());
44+
}
45+
2646
// response_parser(rts::context&)
2747
{
2848
rts::context ctx;
@@ -38,6 +58,10 @@ class response_parser_test
3858
response_parser pr1(ctx);
3959
response_parser pr2(std::move(pr1));
4060
}
61+
{
62+
BOOST_TEST_NO_THROW(
63+
response_parser(response_parser()));
64+
}
4165
}
4266

4367
void

0 commit comments

Comments
 (0)