Refactor type_traits (API Change):

fix #373

* concepts.hpp is renamed to type_traits.hpp

* Body reader and writer concepts are renamed
This commit is contained in:
Vinnie Falco
2017-05-28 16:00:05 -07:00
parent 8578419433
commit c29451a8dd
32 changed files with 435 additions and 462 deletions
+26 -14
View File
@@ -13,10 +13,10 @@ the algorithms used during parsing and serialization.
In this table:
* `X` is a type meeting the requirements of [*`Body`].
* `X` is a type meeting the requirements of [*Body].
[table Body requirements
[[operation] [type] [semantics, pre/post-conditions]]
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::value_type`]
[]
@@ -26,22 +26,34 @@ In this table:
will be not movable or not copyable.
]
]
[
[`X::reader`]
[]
[
If present, a type meeting the requirements of
[link beast.ref.Reader [*`Reader`]].
Provides an implementation to parse the body.
]
]
[
[`X::writer`]
[]
[
If present, a type meeting the requirements of
[link beast.ref.Writer [*`Writer`]].
Provides an implementation to serialize the body.
If present, indicates that the body can hold a message body
parsing result. The type must meet the requirements of
[link beast.ref.BodyWriter [*BodyWriter]]. The implementation
constructs an object of this type to obtain buffers into which
parsed body octets are placed.
]
]
[
[`X::reader`]
[]
[
If present, indicates that the body is serializable.
The type must meet the requirements of
[link beast.ref.BodyReader [*BodyReader]]. The implementation
constructs an object of this type to obtain buffers representing
the message body for serialization.
]
]
[
[`is_body<X>`]
[`std::true_type`]
[
An alias for `std::true_type` for `X`, otherwise an alias
for `std::false_type`.
]
]
]
@@ -5,44 +5,53 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:Writer Writer requirements]
[section:BodyReader BodyReader requirements]
A [*Writer] provides an online algorithm to obtain a sequence of zero
A [*BodyReader] provides an online algorithm to obtain a sequence of zero
or more buffers from a body during serialization. The implementation creates
an instance of this type when needed, and calls into it zero or more times to
retrieve buffers with body octets. The interface of [*Writer] is intended to
allow serialization in these scenarios:
an instance of this type when needed, and calls into it one or more times to
retrieve buffers holding body octets. The interface of [*BodyReader] is
intended to obtain buffers for these scenarios:
* A body that does not entirely fit in memory.
* A body produced incrementally from coroutine output.
* A body represented by zero or more buffers already in memory.
* A body as a series of buffers when the content size is not known ahead of time.
* Body data generated on demand from other threads.
* A body whose size is not known ahead of time.
* Body data generated dynamically from other threads.
* Body data computed algorithmically.
In this table:
* `X` denotes a type meeting the requirements of [*Writer].
* `X` denotes a type meeting the requirements of [*BodyReader].
* `B` denotes a __Body__ where
`std::is_same<X, B::reader>::value == true`.
* `a` denotes a value of type `X`.
* `m` denotes a value of type `message const&` where
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
* `ec` is a value of type [link beast.ref.error_code `error_code&`].
* `B<T>` is the type `boost::optional<std::pair<T, bool>>`.
* `R<T>` is the type `boost::optional<std::pair<T, bool>>`.
[table Writer requirements
[[operation] [type] [semantics, pre/post-conditions]]
[table BodyReader requirements
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::const_buffers_type`]
[]
[
A nested type which meets the requirements of __ConstBufferSequence__.
A type which meets the requirements of __ConstBufferSequence__.
This is the type of buffer returned by `X::get`.
]
]
[
[`X::is_deferred`]
[]
[
]
]
[
[`X(m);`]
[]
@@ -53,7 +62,7 @@ In this table:
]
[
[`a.init(ec)`]
[`void`]
[]
[
Called immediately after construction. If the function sets an
error code in `ec`, the serialization is aborted and the error
@@ -77,7 +86,7 @@ In this table:
]
[
[`a.get(ec)`]
[`B<X::const_buffers_type>`]
[`R<X::const_buffers_type>`]
[
Called repeatedly after `init` succeeds. This function returns
`boost::none` if all buffers representing the body have been
@@ -92,23 +101,24 @@ In this table:
]
]
[
[`http::is_Writer<X>`]
[`is_body_reader<B>`]
[`std::true_type`]
[
An alias for `std::true_type` for `X`, otherwise an
alias for `std::false_type`.
An alias for `std::true_type` for `B`, otherwise an alias
for `std::false_type`.
]
]
]
[note
Definitions for required `Writer` member functions should be declared
inline so the generated code can become part of the implementation.
Definitions for required [*BodyReader] member functions should
be declared inline so the generated code can become part of the
implementation.
]
Exemplar:
```
struct writer
struct reader
{
public:
/** Controls when the implementation requests buffers.
@@ -124,22 +134,19 @@ public:
*/
using const_buffers_type = boost::asio::const_buffers_1;
/** Construct the writer.
The msg object is guaranteed to exist for the lifetime of the writer.
/** Construct the reader.
@param msg The message whose body is to be written.
*/
template<bool isRequest, class Body, class Headers>
explicit
writer(message<isRequest, Body, Headers> const& msg);
reader(message<isRequest, Body, Headers> const& msg);
/** Initialize the writer.
/** Initialization.
Called once immediately after construction.
The writer can perform initialization which may fail.
@param ec Contains the error code if any errors occur.
@param ec Set to the error, if any occurred.
*/
void
init(error_code& ec);
@@ -147,9 +154,9 @@ public:
/** Returns the content length.
If this member is present, the implementation will set the
Content-Length field accordingly. If absent, the implementation will
use chunk-encoding or terminate the connection to indicate the end
of the message.
Content-Length field accordingly. If absent, the implementation
will use chunk-encoding or terminate the connection to indicate
the end of the message.
*/
std::uint64_t
content_length();
@@ -170,7 +177,6 @@ public:
@li If `ec` contains an error code, the return value is ignored.
*/
template<class WriteFunction>
boost::optional<std::pair<const_buffers_type, bool>>
get(error_code& ec);
};
@@ -5,25 +5,25 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:Reader Reader requirements]
[section:BodyWriter BodyWriter requirements]
Parsers provided by the implementation will construct the corresponding
`reader` object during parsing. This customization point allows the
Body to determine the strategy for storing incoming message body data.
Readers come in two flavors, direct and indirect:
When HTTP messages are parsed, the implementation constructs a
[*BodyWriter] object to provide the means for transferring parsed body
octets into the message container. These body writers come in two flavors,
direct and indirect:
Direct readers provide a buffer to callers, in which body data is placed.
This type of reader is used when the bytes corresponding to the body data
Direct writers provide a buffer to callers, into which body data is placed.
This type of writer is used when the bytes corresponding to the body data
are stored without transformation. The parse algorithm performs stream or
socket reads directly into the reader-provided buffer, hence the name
socket reads directly into the buffer provided by the writer, hence the name
"direct." This model avoids an unnecessary buffer copy. An example of
a [*Body] type with a direct reader is
a __Body__ type with a direct writer is
[link beast.ref.http__string_body `string_body`].
Indirect readers are passed body data in a buffer managed by the parser
algorithm. This reader is appropriate when the body data is transformed
Indirect writers are passed body data in a buffer managed by the parsing
algorithm. This writer is appropriate when the body data is transformed
or not otherwised stored verbatim. Some examples of when an indirect
reader is appropriate:
writer is appropriate:
* When bytes corresponding to the body are written to a file
as they are parsed.
@@ -33,7 +33,10 @@ reader is appropriate:
In the tables below:
* `X` denotes a type meeting the requirements of [*`Reader`].
* `X` denotes a type meeting the requirements of [*Writer].
* `B` denotes a __Body__ where
`std::is_same<X, B::writer>::value == true`.
* `a` denotes a value of type `X`.
@@ -41,31 +44,28 @@ In the tables below:
* `v` is a value convertible to `std::uint64_t` without loss of precision.
* `s` is a value of type `boost::string_ref`.
* `s` is a value of type [link beast.ref.string_view `string_view`].
* `ec` is a value of type [link beast.ref.error_code `error_code&`].
* `m` denotes a value of type `message&` where
`std::is_same<decltype(m.body), Body::value_type>::value == true`.
[table Direct Reader requirements
[[operation] [type] [semantics, pre/post-conditions]]
[table Direct Writer requirements
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::is_direct`]
[`bool`]
[
This static constant must be set to `true` to indicate that
the reader is a direct reader.
This static constant must be set to `true` to indicate this
is a direct writer.
]
]
[
[`X::mutable_buffers_type`]
[]
[
This member type must be present, and meet the requirements
of [*MutableBufferSequence]. It represents the type of
the writable buffers returned by the reader, in which
bytes representing the body are stored by the implementation.
A type which meets the requirements of __MutableBufferSequence__.
]
]
[
@@ -85,7 +85,7 @@ In the tables below:
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages whose
to the body are presented to the writer, for messages whose
body is determined by the end-of-file marker on a stream,
or for messages where the chunked Transfer-Encoding is
specified.
@@ -96,14 +96,14 @@ In the tables below:
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages where
to the body are presented to the writer, for messages where
the Content-Length is specified. The value of `v` will be
set to the number of bytes indicated by the content length.
]
]
[
[`a.prepare(n)`]
[`mutable_buffers_type`]
[`X::mutable_buffers_type`]
[
The implementation calls this function to obtain a mutable
buffer sequence of up to `n` bytes in size in which to place
@@ -116,7 +116,7 @@ In the tables below:
[]
[
The implementation calls this function to indicate to the
reader that `n` bytes of data have been successfully placed
writer that `n` bytes of data have been successfully placed
into the buffer obtained through a prior call to `prepare`.
The value of `n` will be less than or equal to the size of
the buffer returned in the previous call to `prepare`.
@@ -130,16 +130,24 @@ In the tables below:
to the body have been written to the buffers and committed.
]
]
[
[`is_body_writer<B>`]
[`std::true_type`]
[
An alias for `std::true_type` for `B`, otherwise an alias
for `std::false_type`.
]
]
]
[table Indirect Reader requirements
[[operation] [type] [semantics, pre/post-conditions]]
[table Indirect Writer requirements
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::is_direct`]
[`bool`]
[
This static constant must be set to `false` to indicate that
the reader is an indirect reader.
This static constant must be set to `false` to indicate this
is an indirect writer.
]
]
[
@@ -159,7 +167,7 @@ In the tables below:
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages whose
to the body are presented to the writer, for messages whose
body is determined by the end-of-file market on a stream,
or for messages where the chunked Transfer-Encoding is
specified.
@@ -173,7 +181,7 @@ In the tables below:
[]
[
This function is called once before any bytes corresponding
to the body are presented to the reader, for messages where
to the body are presented to the writer, for messages where
the Content-Length is specified. The value of `v` will be
set to the number of bytes indicated by the content length.
If `ec` is set before returning, parsing will stop
@@ -201,9 +209,17 @@ In the tables below:
and the error will be returned to the caller.
]
]
[
[`is_body_writer<B>`]
[`std::true_type`]
[
An alias for `std::true_type` for `B`, otherwise an alias
for `std::false_type`.
]
]
]
[note
Definitions for required `Reader` member functions should be declared
Definitions for required [*Writer] member functions should be declared
inline so the generated code can become part of the implementation.
]
+1 -1
View File
@@ -41,7 +41,7 @@ In the table below:
* `U` denotes a type meeting the requirements for __MutableBufferSequence__.
[table DynamicBuffer requirements
[[operation] [type] [semantics, pre/post-conditions]]
[[expression] [type] [semantics, pre/post-conditions]]
[
[`X::const_buffers_type`]
[`T`]
+3 -3
View File
@@ -7,16 +7,16 @@
[section:Field Field requirements]
A [*`Field`] represents a single HTTP header field/value pair.
A [*Field] represents a single HTTP header field/value pair.
In this table:
* `X` denotes a type meeting the requirements of [*`Field`].
* `X` denotes a type meeting the requirements of [*Field].
* `a` denotes a value of type `X`.
[table Field requirements
[[operation][type][semantics, pre/post-conditions]]
[[expression][type][semantics, pre/post-conditions]]
[
[`a.name()`]
[`boost::string_ref`]
+1 -1
View File
@@ -18,7 +18,7 @@ In this table:
* `c` is a value of type `X const`.
[table FieldSequence requirements
[[operation][type][semantics, pre/post-conditions]]
[[expression][type][semantics, pre/post-conditions]]
[
[`X::value_type`]
[]
+5 -5
View File
@@ -12,21 +12,21 @@ asynchronous I/O. They are based on concepts from `boost::asio`.
[heading:Stream Stream]
A type modeling [*`Stream`] meets either or both of the following requirements:
A type modeling [*Stream] meets either or both of the following requirements:
* [*`AsyncStream`]
* [*`SyncStream`]
* [*AsyncStream]
* [*SyncStream]
[heading:AsyncStream AsyncStream]
A type modeling [*`AsyncStream`] meets the following requirements:
A type modeling [*AsyncStream] meets the following requirements:
* __AsyncReadStream__
* __AsyncWriteStream__
[heading:SyncStream SyncStream]
A type modeling [*`SyncStream`] meets the following requirements:
A type modeling [*SyncStream] meets the following requirements:
* __SyncReadStream__
* __SyncWriteStream__