From 75b0571e8358f50536dff1d555d0d6ef4b04d680 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sun, 28 May 2017 09:05:29 -0700 Subject: [PATCH] Refactor type_traits (API Change): fix #373 * concepts.hpp is renamed to type_traits.hpp * Body reader and writer concepts are renamed --- CHANGELOG.md | 1 + doc/concept/Body.qbk | 40 +++-- doc/concept/{Writer.qbk => BodyReader.qbk} | 70 ++++---- doc/concept/{Reader.qbk => BodyWriter.qbk} | 82 +++++---- doc/concept/DynamicBuffer.qbk | 2 +- doc/concept/Field.qbk | 6 +- doc/concept/FieldSequence.qbk | 2 +- doc/concept/Streams.qbk | 10 +- doc/design/http_message.qbk | 2 +- doc/http.qbk | 17 +- doc/master.qbk | 7 +- doc/quickref.xml | 12 +- doc/websocket.qbk | 2 +- examples/file_body.hpp | 12 +- include/beast/core/string_view.hpp | 4 +- include/beast/http/buffer_body.hpp | 10 +- include/beast/http/concepts.hpp | 183 -------------------- include/beast/http/dynamic_body.hpp | 16 +- include/beast/http/empty_body.hpp | 8 +- include/beast/http/impl/async_read.ipp | 11 +- include/beast/http/impl/message.ipp | 14 +- include/beast/http/impl/read.ipp | 20 +-- include/beast/http/impl/write.ipp | 114 ++++++------ include/beast/http/message_parser.hpp | 42 ++--- include/beast/http/string_body.hpp | 16 +- include/beast/http/type_traits.hpp | 146 ++++++++++++++++ include/beast/http/write.hpp | 14 +- test/Jamfile | 2 +- test/http/CMakeLists.txt | 2 +- test/http/design.cpp | 8 +- test/http/{concepts.cpp => type_traits.cpp} | 6 +- test/http/write.cpp | 16 +- 32 files changed, 435 insertions(+), 462 deletions(-) rename doc/concept/{Writer.qbk => BodyReader.qbk} (73%) rename doc/concept/{Reader.qbk => BodyWriter.qbk} (71%) delete mode 100644 include/beast/http/concepts.hpp create mode 100644 include/beast/http/type_traits.hpp rename test/http/{concepts.cpp => type_traits.cpp} (72%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d7e2d2..78f54339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ API Changes: * Remove HTTP header aliases * Refactor HTTP serialization +* Refactor type traits -------------------------------------------------------------------------------- diff --git a/doc/concept/Body.qbk b/doc/concept/Body.qbk index b539fae6..84d5f8b3 100644 --- a/doc/concept/Body.qbk +++ b/doc/concept/Body.qbk @@ -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`] + [`std::true_type`] + [ + An alias for `std::true_type` for `X`, otherwise an alias + for `std::false_type`. ] ] ] diff --git a/doc/concept/Writer.qbk b/doc/concept/BodyReader.qbk similarity index 73% rename from doc/concept/Writer.qbk rename to doc/concept/BodyReader.qbk index 6abc297b..001eed45 100644 --- a/doc/concept/Writer.qbk +++ b/doc/concept/BodyReader.qbk @@ -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::value == true`. * `a` denotes a value of type `X`. * `m` denotes a value of type `message const&` where - `std::is_same:value == true`. + `std::is_same:value == true`. * `ec` is a value of type [link beast.ref.error_code `error_code&`]. -* `B` is the type `boost::optional>`. +* `R` is the type `boost::optional>`. -[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`] + [`R`] [ 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`] + [`is_body_reader`] [`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 explicit - writer(message const& msg); + reader(message 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 boost::optional> get(error_code& ec); }; diff --git a/doc/concept/Reader.qbk b/doc/concept/BodyWriter.qbk similarity index 71% rename from doc/concept/Reader.qbk rename to doc/concept/BodyWriter.qbk index b8b22db9..ab7be12f 100644 --- a/doc/concept/Reader.qbk +++ b/doc/concept/BodyWriter.qbk @@ -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::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::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`] + [`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`] + [`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. ] diff --git a/doc/concept/DynamicBuffer.qbk b/doc/concept/DynamicBuffer.qbk index 3ba090d4..d67c00bb 100644 --- a/doc/concept/DynamicBuffer.qbk +++ b/doc/concept/DynamicBuffer.qbk @@ -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`] diff --git a/doc/concept/Field.qbk b/doc/concept/Field.qbk index e628b980..e6abc41a 100644 --- a/doc/concept/Field.qbk +++ b/doc/concept/Field.qbk @@ -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`] diff --git a/doc/concept/FieldSequence.qbk b/doc/concept/FieldSequence.qbk index 2c3aa7f1..7af75ee2 100644 --- a/doc/concept/FieldSequence.qbk +++ b/doc/concept/FieldSequence.qbk @@ -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`] [] diff --git a/doc/concept/Streams.qbk b/doc/concept/Streams.qbk index f8c1c7a7..1da15072 100644 --- a/doc/concept/Streams.qbk +++ b/doc/concept/Streams.qbk @@ -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__ diff --git a/doc/design/http_message.qbk b/doc/design/http_message.qbk index d7e5226d..3071e34f 100644 --- a/doc/design/http_message.qbk +++ b/doc/design/http_message.qbk @@ -111,7 +111,7 @@ If it needs to access the other fields, it can do so using tag dispatch with an object of type `std::integral_constant`. Often, in non-trivial HTTP applications, we want to read the HTTP header -and examine its contents before choosing a top for [*Body]. To accomplish +and examine its contents before choosing a type for [*Body]. To accomplish this, there needs to be a way to model the header portion of a message. And we'd like to do this in a way that allows functions which take the header as a parameter, to also accept a type representing the whole diff --git a/doc/http.qbk b/doc/http.qbk index a1fb2275..79ea2d6b 100644 --- a/doc/http.qbk +++ b/doc/http.qbk @@ -213,17 +213,18 @@ shows the customization points available to user-defined body types: * [*`value_type`]: Determines the type of the [link beast.ref.http__message.body `message::body`] member. If this type defines default construction, move, copy, or swap, then message objects - declared with this [*`Body`] will have those operations defined. + declared with this [*Body] will have those operations defined. -* [*`reader`]: An optional nested type meeting the requirements of - [link beast.ref.Reader [*`Reader`]]. If present, this defines the algorithm - used for parsing bodies of this type. +* [*`body_writer`]: An optional nested type meeting the requirements of + [link beast.ref.BodyWriter [*BodyWriter]]. If present, this defines the + algorithm used to transfer parsed octets into buffers representing the + body. -* [*`writer`]: An optional nested type meeting the requirements of - [link beast.ref.Writer [*`Writer`]]. If present, this defines the algorithm - used for serializing bodies of this type. +* [*`body_reader`]: An optional nested type meeting the requirements of + [link beast.ref.BodyReader [*BodyReader]]. If present, this defines + the algorithm used to obtain buffers representing a body of this type. -The examples included with this library provide a Body implementation that +The examples included with this library provide a [*Body] implementation that serializing message bodies that come from a file. [endsect] diff --git a/doc/master.qbk b/doc/master.qbk index 419f5720..6fc23f46 100644 --- a/doc/master.qbk +++ b/doc/master.qbk @@ -43,10 +43,9 @@ [def __SyncReadStream__ [@http://www.boost.org/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]] [def __SyncWriteStream__ [@http://www.boost.org/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]] -[def __Body__ [link beast.ref.Body [*`Body`]]] +[def __Body__ [link beast.ref.Body [*Body]]] [def __DynamicBuffer__ [link beast.ref.DynamicBuffer [*DynamicBuffer]]] [def __FieldSequence__ [link beast.ref.FieldSequence [*FieldSequence]]] -[def __Parser__ [link beast.ref.Parser [*`Parser`]]] [def __basic_fields__ [link beast.ref.http__basic_fields `basic_fields`]] [def __fields__ [link beast.ref.http__fields `fields`]] @@ -113,13 +112,13 @@ provides implementations of the HTTP and WebSocket protocols. [section:ref Reference] [xinclude quickref.xml] [include concept/Body.qbk] +[include concept/BodyReader.qbk] +[include concept/BodyWriter.qbk] [include concept/BufferSequence.qbk] [include concept/DynamicBuffer.qbk] [include concept/Field.qbk] [include concept/FieldSequence.qbk] -[include concept/Reader.qbk] [include concept/Streams.qbk] -[include concept/Writer.qbk] [include reference.qbk] [endsect] diff --git a/doc/quickref.xml b/doc/quickref.xml index 2e074d1d..8f5cc650 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -74,11 +74,9 @@ Type Traits - is_Body - is_Reader - is_Writer - has_reader - has_writer + is_body + is_body_writer + is_body_reader @@ -90,10 +88,10 @@ Concepts Body + BodyReader + BodyWriter Field FieldSequence - Reader - Writer diff --git a/doc/websocket.qbk b/doc/websocket.qbk index e22c01df..f28eb553 100644 --- a/doc/websocket.qbk +++ b/doc/websocket.qbk @@ -584,7 +584,7 @@ the fragments: Because calls to read data may return a variable amount of bytes, the interface to calls that read data require an object that meets the requirements -of [link beast.ref.DynamicBuffer [*`DynamicBuffer`]]. This concept is modeled on +of __DynamicBuffer__. This concept is modeled on [@http://www.boost.org/doc/html/boost_asio/reference/basic_streambuf.html `boost::asio::basic_streambuf`]. The implementation does not perform queueing or buffering of messages. If diff --git a/examples/file_body.hpp b/examples/file_body.hpp index a2ad9135..c130a03a 100644 --- a/examples/file_body.hpp +++ b/examples/file_body.hpp @@ -24,7 +24,7 @@ struct file_body { using value_type = std::string; - class writer + class reader { std::uint64_t size_ = 0; std::uint64_t offset_ = 0; @@ -39,18 +39,18 @@ struct file_body using const_buffers_type = boost::asio::const_buffers_1; - writer(writer&&) = default; - writer(writer const&) = delete; - writer& operator=(writer const&) = delete; + reader(reader&&) = default; + reader(reader const&) = delete; + reader& operator=(reader const&) = delete; template - writer(message const& m) : path_(m.body) { } - ~writer() + ~reader() { if(file_) fclose(file_); diff --git a/include/beast/core/string_view.hpp b/include/beast/core/string_view.hpp index fbe905e4..f3bd7b1f 100644 --- a/include/beast/core/string_view.hpp +++ b/include/beast/core/string_view.hpp @@ -12,10 +12,10 @@ namespace beast { -/// The type of string_view used by the library +/// The type of string view used by the library using string_view = boost::string_ref; -/// The type of basic_string_view used by the library +/// The type of basic string view used by the library template using basic_string_view = boost::basic_string_ref; diff --git a/include/beast/http/buffer_body.hpp b/include/beast/http/buffer_body.hpp index facd15fe..17c71b31 100644 --- a/include/beast/http/buffer_body.hpp +++ b/include/beast/http/buffer_body.hpp @@ -8,7 +8,7 @@ #ifndef BEAST_HTTP_BUFFER_BODY_HPP #define BEAST_HTTP_BUFFER_BODY_HPP -#include +#include #include #include #include @@ -68,10 +68,10 @@ struct buffer_body std::pair, bool>; #if BEAST_DOXYGEN - /// The algorithm used when serializing this body - using writer = implementation_defined; + /// The algorithm to obtain buffers representing the body + using reader = implementation_defined; #else - class writer + class reader { bool toggle_ = false; value_type const& body_; @@ -84,7 +84,7 @@ struct buffer_body template explicit - writer(message const& msg) : body_(msg.body) { diff --git a/include/beast/http/concepts.hpp b/include/beast/http/concepts.hpp deleted file mode 100644 index 68d3f608..00000000 --- a/include/beast/http/concepts.hpp +++ /dev/null @@ -1,183 +0,0 @@ -// -// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BEAST_HTTP_CONCEPTS_HPP -#define BEAST_HTTP_CONCEPTS_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace beast { -namespace http { - -template -struct message; - -namespace detail { - -struct fields_model -{ - string_view method() const; - string_view reason() const; - string_view target() const; -}; - -struct write_function -{ - template - void - operator()(ConstBufferSequence const&); -}; - -template> -struct has_value_type : std::false_type {}; - -template -struct has_value_type > : std::true_type {}; - -template> -struct has_content_length : std::false_type {}; - -template -struct has_content_length().content_length() - )> > : std::true_type -{ - static_assert(std::is_convertible< - decltype(std::declval().content_length()), - std::uint64_t>::value, - "Writer::content_length requirements not met"); -}; - -} // detail - -/// Determine if `T` meets the requirements of @b Body. -template -#if BEAST_DOXYGEN -struct is_Body : std::integral_constant{}; -#else -using is_Body = detail::has_value_type; -#endif - -/** Determine if a @b Body has a nested type `reader`. - - @tparam T The type to check, which must meet the - requirements of @b Body. -*/ -#if BEAST_DOXYGEN -template -struct has_reader : std::integral_constant{}; -#else -template> -struct has_reader : std::false_type {}; - -template -struct has_reader > : std::true_type {}; -#endif - -/** Determine if a @b Body has a nested type `writer`. - - @tparam T The type to check, which must meet the - requirements of @b Body. -*/ -#if BEAST_DOXYGEN -template -struct has_writer : std::integral_constant{}; -#else -template> -struct has_writer : std::false_type {}; - -template -struct has_writer > : std::true_type {}; -#endif - -/** Determine if `T` meets the requirements of @b Reader for `M`. - - @tparam T The type to test. - - @tparam M The message type to test with, which must be of - type `message`. -*/ -#if BEAST_DOXYGEN -template -struct is_Reader : std::integral_constant {}; -#else -template> -struct is_Reader : std::true_type {}; - -template -struct is_Reader(), - std::declval().init( - std::declval>()), - std::declval().prepare( - std::declval()), - std::declval().commit( - std::declval()), - std::declval().finish() - )> > : std::integral_constant::value && - std::is_convertible().prepare( - std::declval())), - typename T::mutable_buffers_type - >::value> - -{ - static_assert(std::is_same< - typename M::body_type::reader, T>::value, - "Mismatched reader and message"); -}; -#endif - -/** Determine if a @b Body type has a writer which meets requirements. - - @tparam T The body type to test. -*/ -#if BEAST_DOXYGEN -template -struct is_Writer : std::integral_constant {}; -#else -template -struct is_Writer : std::false_type {}; - -template -struct is_Writer().init(std::declval()), - std::declval>&>() = - std::declval().get(std::declval()), - (void)0)>> : std::integral_constant::value && - std::is_constructible const& >::value - > -{ -}; -#endif - -} // http -} // beast - -#endif diff --git a/include/beast/http/dynamic_body.hpp b/include/beast/http/dynamic_body.hpp index 8a954c6e..f2ef0833 100644 --- a/include/beast/http/dynamic_body.hpp +++ b/include/beast/http/dynamic_body.hpp @@ -29,10 +29,10 @@ struct basic_dynamic_body using value_type = DynamicBuffer; #if BEAST_DOXYGEN - /// The algorithm used when parsing this body. - using reader = implementation_defined; + /// The algorithm used store buffers in this body + using writer = implementation_defined; #else - class reader + class writer { value_type& body_; @@ -44,7 +44,7 @@ struct basic_dynamic_body template explicit - reader(message& msg) : body_(msg.body) { @@ -80,10 +80,10 @@ struct basic_dynamic_body #endif #if BEAST_DOXYGEN - /// The algorithm used when serializing this body. - using writer = implementation_defined; + /// The algorithm to obtain buffers representing the body + using reader = implementation_defined; #else - class writer + class reader { DynamicBuffer const& body_; @@ -95,7 +95,7 @@ struct basic_dynamic_body template explicit - writer(message< + reader(message< isRequest, basic_dynamic_body, Fields> const& m) : body_(m.body) { diff --git a/include/beast/http/empty_body.hpp b/include/beast/http/empty_body.hpp index aac87792..5df0942a 100644 --- a/include/beast/http/empty_body.hpp +++ b/include/beast/http/empty_body.hpp @@ -29,10 +29,10 @@ struct empty_body }; #if BEAST_DOXYGEN - /// The algorithm used when serializing this body. - using writer = implementation_defined; + /// The algorithm to obtain buffers representing the body + using reader = implementation_defined; #else - struct writer + struct reader { using is_deferred = std::false_type; @@ -41,7 +41,7 @@ struct empty_body template explicit - writer(message< + reader(message< isRequest, empty_body, Fields> const&) { } diff --git a/include/beast/http/impl/async_read.ipp b/include/beast/http/impl/async_read.ipp index 275fafe0..de26f494 100644 --- a/include/beast/http/impl/async_read.ipp +++ b/include/beast/http/impl/async_read.ipp @@ -8,7 +8,7 @@ #ifndef BEAST_HTTP_IMPL_ASYNC_READ_IPP_HPP #define BEAST_HTTP_IMPL_ASYNC_READ_IPP_HPP -#include +#include #include #include #include @@ -714,13 +714,10 @@ async_read( "AsyncReadStream requirements not met"); static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_reader::value, - "Body has no reader"); - static_assert(is_Reader>::value, - "Reader requirements not met"); + static_assert(is_body_writer::value, + "BodyWriter requirements not met"); async_completion init{handler}; detail::read_message_op #include -#include +#include #include #include #include @@ -130,7 +130,7 @@ prepare_content_length(prepare_info& pi, message const& msg, std::true_type) { - typename Body::writer w(msg); + typename Body::reader w{msg}; // VFALCO This is a design problem! error_code ec; w.init(ec); @@ -159,15 +159,13 @@ prepare(message& msg, Options&&... options) { // VFALCO TODO - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body has no writer"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); detail::prepare_info pi; detail::prepare_content_length(pi, msg, - detail::has_content_length{}); + detail::has_content_length{}); detail::prepare_options(pi, msg, std::forward(options)...); diff --git a/include/beast/http/impl/read.ipp b/include/beast/http/impl/read.ipp index 186e0430..c24a1b05 100644 --- a/include/beast/http/impl/read.ipp +++ b/include/beast/http/impl/read.ipp @@ -8,7 +8,7 @@ #ifndef BEAST_HTTP_IMPL_READ_IPP_HPP #define BEAST_HTTP_IMPL_READ_IPP_HPP -#include +#include #include #include #include @@ -291,13 +291,10 @@ read( "SyncReadStream requirements not met"); static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_reader::value, - "Body has no reader"); - static_assert(is_Reader>::value, - "Reader requirements not met"); + static_assert(is_body_writer::value, + "BodyWriter requirements not met"); error_code ec; beast::http::read(stream, buffer, msg, ec); if(ec) @@ -319,13 +316,10 @@ read( "SyncReadStream requirements not met"); static_assert(is_dynamic_buffer::value, "DynamicBuffer requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_reader::value, - "Body has no reader"); - static_assert(is_Reader>::value, - "Reader requirements not met"); + static_assert(is_body_writer::value, + "BodyWriter requirements not met"); message_parser p; beast::http::read(stream, buffer, p, ec); if(ec) diff --git a/include/beast/http/impl/write.ipp b/include/beast/http/impl/write.ipp index 3c6fbe52..c0ec5131 100644 --- a/include/beast/http/impl/write.ipp +++ b/include/beast/http/impl/write.ipp @@ -8,7 +8,7 @@ #ifndef BEAST_HTTP_IMPL_WRITE_IPP #define BEAST_HTTP_IMPL_WRITE_IPP -#include +#include #include #include #include @@ -183,12 +183,12 @@ operator()(error_code ec, { if(w_.split_) goto go_header_only; - w_.wr_.emplace(w_.m_); - w_.wr_->init(ec); + w_.rd_.emplace(w_.m_); + w_.rd_->init(ec); if(ec) return s_.get_io_service().post( bind_handler(std::move(*this), ec, 0)); - auto result = w_.wr_->get(ec); + auto result = w_.rd_->get(ec); if(ec) { // Can't use need_more when ! is_deferred @@ -248,9 +248,9 @@ operator()(error_code ec, w_.header_done_ = true; if(! is_deferred::value) goto go_complete; - BOOST_ASSERT(! w_.wr_); - w_.wr_.emplace(w_.m_); - w_.wr_->init(ec); + BOOST_ASSERT(! w_.rd_); + w_.rd_.emplace(w_.m_); + w_.rd_->init(ec); if(ec) goto upcall; w_.s_ = do_body; @@ -258,7 +258,7 @@ operator()(error_code ec, case do_body: { - auto result = w_.wr_->get(ec); + auto result = w_.rd_->get(ec); if(ec) return s_.get_io_service().post( bind_handler(std::move(*this), ec, 0)); @@ -303,12 +303,12 @@ operator()(error_code ec, { if(w_.split_) goto go_header_only_c; - w_.wr_.emplace(w_.m_); - w_.wr_->init(ec); + w_.rd_.emplace(w_.m_); + w_.rd_->init(ec); if(ec) return s_.get_io_service().post( bind_handler(std::move(*this), ec, 0)); - auto result = w_.wr_->get(ec); + auto result = w_.rd_->get(ec); if(ec) { // Can't use need_more when ! is_deferred @@ -382,9 +382,9 @@ operator()(error_code ec, w_.s_ = do_final_c; break; } - BOOST_ASSERT(! w_.wr_); - w_.wr_.emplace(w_.m_); - w_.wr_->init(ec); + BOOST_ASSERT(! w_.rd_); + w_.rd_.emplace(w_.m_); + w_.rd_->init(ec); if(ec) goto upcall; w_.s_ = do_body_c; @@ -392,7 +392,7 @@ operator()(error_code ec, case do_body_c: { - auto result = w_.wr_->get(ec); + auto result = w_.rd_->get(ec); if(ec) return s_.get_io_service().post( bind_handler(std::move(*this), @@ -528,12 +528,10 @@ write_some(SyncWriteStream& stream) static_assert( is_sync_write_stream::value, "SyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body::writer requirements not met"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); error_code ec; write_some(stream, ec); if(ec) @@ -551,12 +549,10 @@ write_some(SyncWriteStream& stream, error_code &ec) static_assert( is_sync_write_stream::value, "SyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body::writer requirements not met"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); using boost::asio::buffer_size; switch(s_) @@ -565,11 +561,11 @@ write_some(SyncWriteStream& stream, error_code &ec) { if(split_) goto go_header_only; - wr_.emplace(m_); - wr_->init(ec); + rd_.emplace(m_); + rd_->init(ec); if(ec) return; - auto result = wr_->get(ec); + auto result = rd_->get(ec); if(ec) { // Can't use need_more when ! is_deferred @@ -624,9 +620,9 @@ write_some(SyncWriteStream& stream, error_code &ec) header_done_ = true; if(! is_deferred::value) goto go_complete; - BOOST_ASSERT(! wr_); - wr_.emplace(m_); - wr_->init(ec); + BOOST_ASSERT(! rd_); + rd_.emplace(m_); + rd_->init(ec); if(ec) return; s_ = do_body; @@ -635,7 +631,7 @@ write_some(SyncWriteStream& stream, error_code &ec) case do_body: { - auto result = wr_->get(ec); + auto result = rd_->get(ec); if(ec) return; if(! result) @@ -670,11 +666,11 @@ write_some(SyncWriteStream& stream, error_code &ec) { if(split_) goto go_header_only_c; - wr_.emplace(m_); - wr_->init(ec); + rd_.emplace(m_); + rd_->init(ec); if(ec) return; - auto result = wr_->get(ec); + auto result = rd_->get(ec); if(ec) { // Can't use need_more when ! is_deferred @@ -742,9 +738,9 @@ write_some(SyncWriteStream& stream, error_code &ec) s_ = do_final_c; break; } - BOOST_ASSERT(! wr_); - wr_.emplace(m_); - wr_->init(ec); + BOOST_ASSERT(! rd_); + rd_.emplace(m_); + rd_->init(ec); if(ec) return; s_ = do_body_c; @@ -753,7 +749,7 @@ write_some(SyncWriteStream& stream, error_code &ec) case do_body_c: { - auto result = wr_->get(ec); + auto result = rd_->get(ec); if(ec) return; if(! result) @@ -856,12 +852,10 @@ async_write_some(AsyncWriteStream& stream, { static_assert(is_async_write_stream::value, "AsyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body::writer requirements not met"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); async_completion init{handler}; async_op::value, "SyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body has no writer"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); error_code ec; write(stream, msg, ec); if(ec) @@ -1005,12 +997,10 @@ write(SyncWriteStream& stream, { static_assert(is_sync_write_stream::value, "SyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body has no writer"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); auto ws = make_write_stream(msg); for(;;) { @@ -1034,12 +1024,10 @@ async_write(AsyncWriteStream& stream, static_assert( is_async_write_stream::value, "AsyncWriteStream requirements not met"); - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body has no writer"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); async_completion init{handler}; detail::write_op const& msg) { - static_assert(is_Body::value, + static_assert(is_body::value, "Body requirements not met"); - static_assert(has_writer::value, - "Body has no writer"); - static_assert(is_Writer::value, - "Writer requirements not met"); + static_assert(is_body_reader::value, + "BodyReader requirements not met"); beast::detail::sync_ostream oss{os}; error_code ec; write(oss, msg, ec); diff --git a/include/beast/http/message_parser.hpp b/include/beast/http/message_parser.hpp index ce1c5690..34cfd6a2 100644 --- a/include/beast/http/message_parser.hpp +++ b/include/beast/http/message_parser.hpp @@ -37,16 +37,16 @@ namespace http { template class message_parser : public basic_parser> { using base_type = basic_parser>; - using reader_type = typename Body::reader; + using writer_type = typename Body::writer; message m_; - boost::optional r_; + boost::optional wr_; public: /// The type of message returned by the parser @@ -54,7 +54,7 @@ public: /// The type of buffer sequence representing the body using mutable_buffers_type = - typename reader_type::mutable_buffers_type; + typename writer_type::mutable_buffers_type; /// Constructor (default) message_parser() = default; @@ -152,7 +152,7 @@ public: private: friend class basic_parser< - isRequest, Body::reader::is_direct, + isRequest, Body::writer::is_direct, message_parser>; void @@ -192,22 +192,22 @@ private: void on_body() { - r_.emplace(m_); - r_->init(); + wr_.emplace(m_); + wr_->init(); } void on_body(std::uint64_t content_length) { - r_.emplace(m_); - r_->init(content_length); + wr_.emplace(m_); + wr_->init(content_length); } void on_body(error_code& ec) { - r_.emplace(m_); - r_->init(ec); + wr_.emplace(m_); + wr_->init(ec); if(ec) return; } @@ -216,8 +216,8 @@ private: on_body(std::uint64_t content_length, error_code& ec) { - r_.emplace(m_); - r_->init(content_length, ec); + wr_.emplace(m_); + wr_->init(content_length, ec); if(ec) return; } @@ -226,20 +226,20 @@ private: on_data(string_view const& s, error_code& ec) { - BOOST_STATIC_ASSERT(! Body::reader::is_direct); - r_->write(s, ec); + BOOST_STATIC_ASSERT(! Body::writer::is_direct); + wr_->write(s, ec); } mutable_buffers_type on_prepare(std::size_t n) { - return r_->prepare(n); + return wr_->prepare(n); } void on_commit(std::size_t n) { - r_->commit(n); + wr_->commit(n); } void @@ -252,24 +252,24 @@ private: void on_complete(error_code& ec) { - if(r_) + if(wr_) do_on_complete(ec, std::integral_constant{}); + Body::writer::is_direct>{}); } void do_on_complete( error_code& ec, std::true_type) { - r_->finish(); + wr_->finish(); } void do_on_complete( error_code& ec, std::false_type) { - r_->finish(ec); + wr_->finish(ec); if(ec) return; } diff --git a/include/beast/http/string_body.hpp b/include/beast/http/string_body.hpp index da0dc79a..7e01aacc 100644 --- a/include/beast/http/string_body.hpp +++ b/include/beast/http/string_body.hpp @@ -31,10 +31,10 @@ struct string_body using value_type = std::string; #if BEAST_DOXYGEN - /// The algorithm used when parsing this body. - using reader = implementation_defined; + /// The algorithm used store buffers in this body + using writer = implementation_defined; #else - class reader + class writer { value_type& body_; std::size_t len_ = 0; @@ -47,7 +47,7 @@ struct string_body template explicit - reader(message& m) : body_(m.body) { @@ -93,10 +93,10 @@ struct string_body #endif #if BEAST_DOXYGEN - /// The algorithm used when serializing this body. - using writer = implementation_defined; + /// The algorithm to obtain buffers representing the body + using reader = implementation_defined; #else - class writer + class reader { value_type const& body_; @@ -108,7 +108,7 @@ struct string_body template explicit - writer(message< + reader(message< isRequest, string_body, Fields> const& msg) : body_(msg.body) { diff --git a/include/beast/http/type_traits.hpp b/include/beast/http/type_traits.hpp new file mode 100644 index 00000000..0cc07459 --- /dev/null +++ b/include/beast/http/type_traits.hpp @@ -0,0 +1,146 @@ +// +// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BEAST_HTTP_TYPE_TRAITS_HPP +#define BEAST_HTTP_TYPE_TRAITS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace beast { +namespace http { + +template +struct message; + +namespace detail { + +struct fields_model +{ + string_view method() const; + string_view reason() const; + string_view target() const; +}; + +template> +struct has_value_type : std::false_type {}; + +template +struct has_value_type > : std::true_type {}; + +template> +struct has_content_length : std::false_type {}; + +template +struct has_content_length().content_length() + )> > : std::true_type +{ + static_assert(std::is_convertible< + decltype(std::declval().content_length()), + std::uint64_t>::value, + "Writer::content_length requirements not met"); +}; + +} // detail + +/// Determine if `T` meets the requirements of @b Body. +template +#if BEAST_DOXYGEN +struct is_body : std::integral_constant{}; +#else +using is_body = detail::has_value_type; +#endif + +/** Determine if a @b Body type has a reader. + + This metafunction is equivalent to `std::true_type` if: + + @li @b T has a nested type named `reader` + + @li The nested type meets the requirements of @b BodyReader. + + @tparam T The body type to test. +*/ +#if BEAST_DOXYGEN +template +struct is_body_reader : std::integral_constant {}; +#else +template +struct is_body_reader : std::false_type {}; + +template +struct is_body_reader().init(std::declval()), + std::declval>&>() = + std::declval().get(std::declval()), + (void)0)>> : std::integral_constant::value && + std::is_constructible const& >::value + > +{ +}; +#endif + +/** Determine if a @b Body type has a writer. + + This metafunction is equivalent to `std::true_type` if: + + @li @b T has a nested type named `writer` + + @li The nested type meets the requirements of @b BodyWriter. + + @tparam T The body type to test. +*/ +#if BEAST_DOXYGEN +template +struct is_body_writer : std::integral_constant {}; +#else +template> +struct is_body_writer : std::true_type {}; + +template +struct is_body_writer(), + std::declval().init( + std::declval>()), + std::declval().prepare( + std::declval()), + std::declval().commit( + std::declval()), + std::declval().finish() + )> > : std::integral_constant::value && + std::is_convertible().prepare( + std::declval())), + typename T::writer::mutable_buffers_type + >::value> + +{ +}; +#endif + +} // http +} // beast + +#endif diff --git a/include/beast/http/write.hpp b/include/beast/http/write.hpp index a80fa146..4d434040 100644 --- a/include/beast/http/write.hpp +++ b/include/beast/http/write.hpp @@ -190,27 +190,29 @@ class serializer using buffer_type = basic_multi_buffer; + using reader = typename Body::reader; + using is_deferred = - typename Body::writer::is_deferred; + typename reader::is_deferred; using cb0_t = consuming_buffers>;// body + typename reader::const_buffers_type>>; // body using cb1_t = consuming_buffers< - typename Body::writer::const_buffers_type>; // body + typename reader::const_buffers_type>; // body using ch0_t = consuming_buffers>; // crlf using ch1_t = consuming_buffers>; // crlf using ch2_t = consuming_buffers::max)(); - boost::optional wr_; + boost::optional rd_; buffer_type b_; boost::variant v_; diff --git a/test/Jamfile b/test/Jamfile index a1ea8dad..38995912 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -43,7 +43,6 @@ unit-test http-tests : ../extras/beast/unit_test/main.cpp http/basic_parser.cpp http/buffer_body.cpp - http/concepts.cpp http/design.cpp http/dynamic_body.cpp http/error.cpp @@ -54,6 +53,7 @@ unit-test http-tests : http/read.cpp http/rfc7230.cpp http/string_body.cpp + http/type_traits.cpp http/write.cpp ; diff --git a/test/http/CMakeLists.txt b/test/http/CMakeLists.txt index a12ce939..ea3255ec 100644 --- a/test/http/CMakeLists.txt +++ b/test/http/CMakeLists.txt @@ -12,7 +12,6 @@ add_executable (http-tests ../../extras/beast/unit_test/main.cpp basic_parser.cpp buffer_body.cpp - concepts.cpp design.cpp dynamic_body.cpp empty_body.cpp @@ -24,6 +23,7 @@ add_executable (http-tests read.cpp rfc7230.cpp string_body.cpp + type_traits.cpp write.cpp ) diff --git a/test/http/design.cpp b/test/http/design.cpp index c7f6d2f3..abc1dbaf 100644 --- a/test/http/design.cpp +++ b/test/http/design.cpp @@ -203,7 +203,7 @@ public: { using value_type = std::string; - class reader + class writer { value_type& body_; std::size_t len_ = 0; @@ -216,7 +216,7 @@ public: template explicit - reader(message& m) + writer(message& m) : body_(m.body) { } @@ -315,7 +315,7 @@ public: { using value_type = std::string; - class reader + class writer { value_type& body_; @@ -327,7 +327,7 @@ public: template explicit - reader(message& m) + writer(message& m) : body_(m.body) { } diff --git a/test/http/concepts.cpp b/test/http/type_traits.cpp similarity index 72% rename from test/http/concepts.cpp rename to test/http/type_traits.cpp index 9d274eaa..6527e377 100644 --- a/test/http/concepts.cpp +++ b/test/http/type_traits.cpp @@ -6,16 +6,16 @@ // // Test that header file is self-contained. -#include +#include #include namespace beast { namespace http { -BOOST_STATIC_ASSERT(! is_Writer::value); +BOOST_STATIC_ASSERT(! is_body_reader::value); -BOOST_STATIC_ASSERT(is_Writer::value); +BOOST_STATIC_ASSERT(is_body_reader::value); } // http } // beast diff --git a/test/http/write.cpp b/test/http/write.cpp index 51647cda..c05d1e2d 100644 --- a/test/http/write.cpp +++ b/test/http/write.cpp @@ -37,7 +37,7 @@ public: { using value_type = std::string; - class writer + class reader { value_type const& body_; @@ -49,7 +49,7 @@ public: template explicit - writer(message const& msg) + reader(message const& msg) : body_(msg.body) { } @@ -82,7 +82,7 @@ public: bool mutable read = false; }; - class writer + class reader { int step_ = 0; value_type const& body_; @@ -96,7 +96,7 @@ public: template explicit - writer(message const& msg) : body_(msg.body) { @@ -196,11 +196,11 @@ public: struct fail_body { - class writer; + class reader; class value_type { - friend class writer; + friend class reader; std::string s_; test::fail_counter& fc_; @@ -220,7 +220,7 @@ public: } }; - class writer + class reader { std::size_t n_ = 0; value_type const& body_; @@ -233,7 +233,7 @@ public: template explicit - writer(message const& msg) + reader(message const& msg) : body_(msg.body) { }