mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 05:17:26 +02:00
@ -7,6 +7,7 @@ Version 62:
|
||||
* Tidy up namespaces in examples
|
||||
* Clear the error faster
|
||||
* Avoid explicit operator bool for error
|
||||
* Add http::is_fields trait
|
||||
|
||||
API Changes:
|
||||
|
||||
|
@ -115,6 +115,13 @@ In this table:
|
||||
Transfer-Encoding field if the field is present ahd chunked is the
|
||||
last encoding.
|
||||
]
|
||||
][
|
||||
[`is_fields<X>`]
|
||||
[`std::true_type`]
|
||||
[
|
||||
An alias for `std::true_type` for `X`, otherwise an alias
|
||||
for `std::false_type`.
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -96,6 +96,7 @@
|
||||
<member><link linkend="beast.ref.beast__http__is_body">is_body</link></member>
|
||||
<member><link linkend="beast.ref.beast__http__is_body_writer">is_body_writer</link></member>
|
||||
<member><link linkend="beast.ref.beast__http__is_body_reader">is_body_reader</link></member>
|
||||
<member><link linkend="beast.ref.beast__http__is_fields">is_fields</link></member>
|
||||
</simplelist>
|
||||
<bridgehead renderas="sect3">Concepts</bridgehead>
|
||||
<simplelist type="vert" columns="1">
|
||||
|
@ -9,6 +9,8 @@
|
||||
#define BEAST_HTTP_DETAIL_TYPE_TRAITS_HPP
|
||||
|
||||
#include <beast/core/detail/type_traits.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@ -49,6 +51,15 @@ struct fields_model
|
||||
string_view method() const;
|
||||
string_view reason() const;
|
||||
string_view target() const;
|
||||
|
||||
protected:
|
||||
void set_method_impl(string_view s);
|
||||
void set_target_impl(string_view s);
|
||||
void set_reason_impl(string_view s);
|
||||
string_view get_method_impl() const;
|
||||
string_view get_target_impl() const;
|
||||
string_view get_reason_impl() const;
|
||||
void prepare_payload_impl(bool b, boost::optional<std::uint64_t> n);
|
||||
};
|
||||
|
||||
template<class T, class = beast::detail::void_t<>>
|
||||
@ -75,6 +86,67 @@ struct is_body_sized<T, beast::detail::void_t<
|
||||
T::size(std::declval<typename T::value_type const&>()),
|
||||
(void)0)>> : std::true_type {};
|
||||
|
||||
template<class T>
|
||||
struct is_fields_helper : T
|
||||
{
|
||||
template<class U = is_fields_helper>
|
||||
static auto f1(int) -> decltype(
|
||||
void(std::declval<U&>().set_method_impl(std::declval<string_view>())),
|
||||
std::true_type());
|
||||
static auto f1(...) -> std::false_type;
|
||||
using t1 = decltype(f1(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f2(int) -> decltype(
|
||||
void(std::declval<U&>().set_target_impl(std::declval<string_view>())),
|
||||
std::true_type());
|
||||
static auto f2(...) -> std::false_type;
|
||||
using t2 = decltype(f2(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f3(int) -> decltype(
|
||||
void(std::declval<U&>().set_reason_impl(std::declval<string_view>())),
|
||||
std::true_type());
|
||||
static auto f3(...) -> std::false_type;
|
||||
using t3 = decltype(f3(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f4(int) -> decltype(
|
||||
std::declval<string_view&>() = std::declval<U&>().get_method_impl(),
|
||||
std::true_type());
|
||||
static auto f4(...) -> std::false_type;
|
||||
using t4 = decltype(f4(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f5(int) -> decltype(
|
||||
std::declval<string_view&>() = std::declval<U&>().get_target_impl(),
|
||||
std::true_type());
|
||||
static auto f5(...) -> std::false_type;
|
||||
using t5 = decltype(f5(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f6(int) -> decltype(
|
||||
std::declval<string_view&>() = std::declval<U&>().get_reason_impl(),
|
||||
std::true_type());
|
||||
static auto f6(...) -> std::false_type;
|
||||
using t6 = decltype(f6(0));
|
||||
|
||||
template<class U = is_fields_helper>
|
||||
static auto f7(int) -> decltype(
|
||||
void(std::declval<U&>().prepare_payload_impl(
|
||||
std::declval<bool>(),
|
||||
std::declval<boost::optional<std::uint64_t>>())),
|
||||
std::true_type());
|
||||
static auto f7(...) -> std::false_type;
|
||||
using t7 = decltype(f7(0));
|
||||
|
||||
using type = std::integral_constant<bool,
|
||||
t1::value && t2::value && t3::value &&
|
||||
t4::value && t5::value && t6::value &&
|
||||
t7::value
|
||||
>;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // http
|
||||
} // beast
|
||||
|
@ -48,6 +48,9 @@ template<class Fields>
|
||||
struct header<true, Fields> : Fields
|
||||
#endif
|
||||
{
|
||||
static_assert(is_fields<Fields>::value,
|
||||
"Fields requirements not met");
|
||||
|
||||
/// Indicates if the header is a request or response.
|
||||
#if BEAST_DOXYGEN
|
||||
using is_request = isRequest;
|
||||
@ -196,6 +199,9 @@ private:
|
||||
template<class Fields>
|
||||
struct header<false, Fields> : Fields
|
||||
{
|
||||
static_assert(is_fields<Fields>::value,
|
||||
"Fields requirements not met");
|
||||
|
||||
/// Indicates if the header is a request or response.
|
||||
using is_request = std::false_type;
|
||||
|
||||
|
@ -137,6 +137,39 @@ struct is_body_writer<T, beast::detail::void_t<decltype(
|
||||
};
|
||||
#endif
|
||||
|
||||
/** Determine if `T` meets the requirements of @b Fields
|
||||
|
||||
@tparam T The body type to test.
|
||||
|
||||
@par Example
|
||||
|
||||
Use with `static_assert`:
|
||||
|
||||
@code
|
||||
template<bool isRequest, class Body, class Fields>
|
||||
void f(message<isRequest, Body, Fields> const&)
|
||||
{
|
||||
static_assert(is_fields<Fields>::value,
|
||||
"Fields requirements not met");
|
||||
...
|
||||
@endcode
|
||||
|
||||
Use with `std::enable_if` (SFINAE):
|
||||
|
||||
@code
|
||||
template<bool isRequest, class Body, class Fields>
|
||||
typename std::enable_if<is_fields<Fields>::value>::type
|
||||
f(message<isRequest, Body, Fields> const&);
|
||||
@endcode
|
||||
*/
|
||||
#if BEAST_DOXYGEN
|
||||
template<class T>
|
||||
struct is_fields : std::integral_constant<bool, ...> {};
|
||||
#else
|
||||
template<class T>
|
||||
using is_fields = typename detail::is_fields_helper<T>::type;
|
||||
#endif
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/type_traits.hpp>
|
||||
#include <beast/test/test_allocator.hpp>
|
||||
#include <beast/unit_test/suite.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@ -17,6 +18,8 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
BOOST_STATIC_ASSERT(is_fields<fields>::value);
|
||||
|
||||
class fields_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
|
@ -20,5 +20,13 @@ BOOST_STATIC_ASSERT(is_body_reader<empty_body>::value);
|
||||
|
||||
BOOST_STATIC_ASSERT(! is_body_writer<std::string>::value);
|
||||
|
||||
namespace {
|
||||
|
||||
struct not_fields {};
|
||||
|
||||
} // (anonymous)
|
||||
|
||||
BOOST_STATIC_ASSERT(! is_fields<not_fields>::value);
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
Reference in New Issue
Block a user