1//
2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
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)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
11#define BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
12
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/http/detail/type_traits.hpp>
17#include <boost/asio/buffer.hpp>
18#include <boost/optional.hpp>
19#include <cstdint>
20#include <type_traits>
21#include <utility>
22
23namespace boost {
24namespace beast {
25namespace http {
26
27template<bool, class, class>
28class message;
29
30/** Determine if a type meets the <em>Body</em> named requirements.
31
32 This alias template is `std::true_type` if `T` meets
33 the requirements, otherwise it is `std::false_type`.
34
35 @tparam T The type to test.
36
37 @par Example
38 @code
39 template<bool isRequest, class Body, class Fields>
40 void check_body(message<isRequest, Body, Fields> const&)
41 {
42 static_assert(is_body<Body>::value,
43 "Body type requirements not met");
44 }
45 @endcode
46*/
47template<class T>
48#if BOOST_BEAST_DOXYGEN
49using is_body = __see_below__;
50#else
51using is_body = detail::has_value_type<T>;
52#endif
53
54/** Determine if a type has a nested <em>BodyWriter</em>.
55
56 This alias template is `std::true_type` when:
57
58 @li `T` has a nested type named `writer`
59
60 @li `writer` meets the requirements of <em>BodyWriter</em>.
61
62 @tparam T The body type to test.
63
64 @par Example
65 @code
66 template<bool isRequest, class Body, class Fields>
67 void check_can_serialize(message<isRequest, Body, Fields> const&)
68 {
69 static_assert(is_body_writer<Body>::value,
70 "Cannot serialize Body, no reader");
71 }
72 @endcode
73*/
74#if BOOST_BEAST_DOXYGEN
75template<class T>
76using is_body_writer = __see_below__;
77#else
78template<class T, class = void>
79struct is_body_writer : std::false_type {};
80
81template<class T>
82struct is_body_writer<T, beast::detail::void_t<
83 typename T::writer,
84 typename T::writer::const_buffers_type,
85 decltype(
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 )>> : std::integral_constant<bool,
91 net::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 )
100 > {};
101#endif
102
103/** Determine if a type has a nested <em>BodyWriter</em>.
104
105 This alias template is `std::true_type` when:
106
107 @li `T` has a nested type named `writer`
108
109 @li `writer` meets the requirements of <em>BodyWriter</em>.
110
111 @tparam T The body type to test.
112*/
113#if BOOST_BEAST_DOXYGEN
114template<class T>
115using is_mutable_body_writer = __see_below__;
116#else
117template<class T, class = void>
118struct is_mutable_body_writer : std::false_type {};
119
120template<class T>
121struct is_mutable_body_writer<T, beast::detail::void_t<
122 typename T::writer,
123 typename T::writer::const_buffers_type,
124 decltype(
125 std::declval<typename T::writer&>().init(std::declval<error_code&>()),
126 std::declval<boost::optional<std::pair<
127 typename T::writer::const_buffers_type, bool>>&>() =
128 std::declval<typename T::writer>().get(std::declval<error_code&>())
129 )>> : std::integral_constant<bool,
130 net::is_const_buffer_sequence<
131 typename T::writer::const_buffers_type>::value && ((
132 std::is_constructible<typename T::writer,
133 header<true, detail::fields_model>&,
134 typename T::value_type&>::value &&
135 std::is_constructible<typename T::writer,
136 header<false, detail::fields_model>&,
137 typename T::value_type&>::value &&
138 ! std::is_constructible<typename T::writer,
139 header<true, detail::fields_model> const&,
140 typename T::value_type const&>::value &&
141 ! std::is_constructible<typename T::writer,
142 header<false, detail::fields_model> const&,
143 typename T::value_type const&>::value
144 ))
145 >{};
146#endif
147
148/** Determine if a type has a nested <em>BodyReader</em>.
149
150 This alias template is `std::true_type` when:
151
152 @li `T` has a nested type named `reader`
153
154 @li `reader` meets the requirements of <em>BodyReader</em>.
155
156 @tparam T The body type to test.
157
158 @par Example
159 @code
160 template<bool isRequest, class Body, class Fields>
161 void check_can_parse(message<isRequest, Body, Fields>&)
162 {
163 static_assert(is_body_reader<Body>::value,
164 "Cannot parse Body, no reader");
165 }
166 @endcode
167*/
168#if BOOST_BEAST_DOXYGEN
169template<class T>
170using is_body_reader = __see_below__;
171#else
172template<class T, class = void>
173struct is_body_reader : std::false_type {};
174
175template<class T>
176struct is_body_reader<T, beast::detail::void_t<decltype(
177 std::declval<typename T::reader&>().init(
178 boost::optional<std::uint64_t>(),
179 std::declval<error_code&>()),
180 std::declval<std::size_t&>() =
181 std::declval<typename T::reader&>().put(
182 std::declval<net::const_buffer>(),
183 std::declval<error_code&>()),
184 std::declval<typename T::reader&>().finish(
185 std::declval<error_code&>())
186 )>> : std::integral_constant<bool,
187 (std::is_constructible<typename T::reader,
188 header<true, detail::fields_model>&,
189 typename T::value_type&>::value &&
190 std::is_constructible<typename T::reader,
191 header<false,detail::fields_model>&,
192 typename T::value_type&>::value)
193 >
194{
195};
196#endif
197
198/** Determine if a type meets the <em>Fields</em> named requirements.
199
200 This alias template is `std::true_type` if `T` meets
201 the requirements, otherwise it is `std::false_type`.
202
203 @tparam T The type to test.
204
205 @par Example
206 Use with `static_assert`:
207 @code
208 template<bool isRequest, class Body, class Fields>
209 void f(message<isRequest, Body, Fields> const&)
210 {
211 static_assert(is_fields<Fields>::value,
212 "Fields type requirements not met");
213 ...
214 @endcode
215
216 Use with `std::enable_if` (SFINAE):
217 @code
218 template<bool isRequest, class Body, class Fields>
219 typename std::enable_if<is_fields<Fields>::value>::type
220 f(message<isRequest, Body, Fields> const&);
221 @endcode
222*/
223#if BOOST_BEAST_DOXYGEN
224template<class T>
225using is_fields = __see_below__;
226#else
227template<class T>
228using is_fields = typename detail::is_fields_helper<T>::type;
229#endif
230
231} // http
232} // beast
233} // boost
234
235#endif
236

source code of boost/libs/beast/include/boost/beast/http/type_traits.hpp