2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
11 #define BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/core/error.hpp>
15 #include <boost/beast/core/string.hpp>
16 #include <boost/beast/core/type_traits.hpp>
17 #include <boost/beast/http/detail/type_traits.hpp>
18 #include <boost/asio/buffer.hpp>
19 #include <boost/optional.hpp>
20 #include <type_traits>
27 template<bool, class, class>
30 /** Determine if `T` meets the requirements of @b Body.
32 This metafunction is equivalent to `std::true_type`
33 if `T` has a nested type named `value_type`.
35 @tparam T The body type to test.
39 template<bool isRequest, class Body, class Fields>
40 void check_body(message<isRequest, Body, Fields> const&)
42 static_assert(is_body<Body>::value,
43 "Body requirements not met");
48 #if BOOST_BEAST_DOXYGEN
49 struct is_body : std::integral_constant<bool, ...>{};
51 using is_body = detail::has_value_type<T>;
54 /** Determine if a @b Body type has a reader.
56 This metafunction is equivalent to `std::true_type` if:
58 @li `T` has a nested type named `reader`
60 @li The nested type meets the requirements of @b BodyWriter.
62 @tparam T The body type to test.
66 template<bool isRequest, class Body, class Fields>
67 void check_can_serialize(message<isRequest, Body, Fields> const&)
69 static_assert(is_body_writer<Body>::value,
70 "Cannot serialize Body, no reader");
74 #if BOOST_BEAST_DOXYGEN
76 struct is_body_writer : std::integral_constant<bool, ...> {};
78 template<class T, class = void>
79 struct is_body_writer : std::false_type {};
82 struct is_body_writer<T, beast::detail::void_t<
84 typename T::writer::const_buffers_type,
86 std::declval<typename T::writer&>().init(std::declval<error_code&>()),
87 std::declval<boost::optional<std::pair<
88 typename T::writer::const_buffers_type, bool>>&>() =
89 std::declval<typename T::writer>().get(std::declval<error_code&>()),
90 (void)0)>> : std::integral_constant<bool,
91 boost::asio::is_const_buffer_sequence<
92 typename T::writer::const_buffers_type>::value && (
93 (std::is_constructible<typename T::writer,
94 header<true, detail::fields_model>&,
95 typename T::value_type&>::value &&
96 std::is_constructible<typename T::writer,
97 header<false, detail::fields_model>&,
98 typename T::value_type&>::value) ||
99 // Deprecated BodyWriter Concept (v1.66)
100 (std::is_constructible<typename T::writer,
101 message<true, T, detail::fields_model>&>::value &&
102 std::is_constructible<typename T::writer,
103 message<false, T, detail::fields_model>&>::value)
108 /** Determine if a @b Body type has a reader.
110 This metafunction is equivalent to `std::true_type` if:
112 @li `T` has a nested type named `reader`
114 @li The nested type meets the requirements of @b BodyReader.
116 @tparam T The body type to test.
120 template<bool isRequest, class Body, class Fields>
121 void check_can_parse(message<isRequest, Body, Fields>&)
123 static_assert(is_body_reader<Body>::value,
124 "Cannot parse Body, no reader");
128 #if BOOST_BEAST_DOXYGEN
130 struct is_body_reader : std::integral_constant<bool, ...> {};
132 template<class T, class = void>
133 struct is_body_reader : std::false_type {};
136 struct is_body_reader<T, beast::detail::void_t<decltype(
137 std::declval<typename T::reader&>().init(
138 boost::optional<std::uint64_t>(),
139 std::declval<error_code&>()),
140 std::declval<std::size_t&>() =
141 std::declval<typename T::reader&>().put(
142 std::declval<boost::asio::const_buffer>(),
143 std::declval<error_code&>()),
144 std::declval<typename T::reader&>().finish(
145 std::declval<error_code&>()),
146 (void)0)>> : std::integral_constant<bool,
147 (std::is_constructible<typename T::reader,
148 header<true, detail::fields_model>&,
149 typename T::value_type&>::value &&
150 std::is_constructible<typename T::reader,
151 header<false,detail::fields_model>&,
152 typename T::value_type&>::value) ||
153 // Deprecated BodyReader Concept (v1.66)
154 (std::is_constructible<typename T::reader,
155 message<true, T, detail::fields_model>&>::value &&
156 std::is_constructible<typename T::reader,
157 message<false, T, detail::fields_model>&>::value)
163 /** Determine if `T` meets the requirements of @b Fields
165 @tparam T The body type to test.
169 Use with `static_assert`:
172 template<bool isRequest, class Body, class Fields>
173 void f(message<isRequest, Body, Fields> const&)
175 static_assert(is_fields<Fields>::value,
176 "Fields requirements not met");
180 Use with `std::enable_if` (SFINAE):
183 template<bool isRequest, class Body, class Fields>
184 typename std::enable_if<is_fields<Fields>::value>::type
185 f(message<isRequest, Body, Fields> const&);
188 #if BOOST_BEAST_DOXYGEN
190 struct is_fields : std::integral_constant<bool, ...> {};
193 using is_fields = typename detail::is_fields_helper<T>::type;