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_DETAIL_TYPE_TRAITS_HPP
11 #define BOOST_BEAST_HTTP_DETAIL_TYPE_TRAITS_HPP
12 
13 #include <boost/beast/core/detail/type_traits.hpp>
14 #include <boost/optional.hpp>
15 #include <cstdint>
16 
17 namespace boost {
18 namespace beast {
19 namespace http {
20 
21 template<bool isRequest, class Fields>
22 class header;
23 
24 template<bool, class, class>
25 class message;
26 
27 template<bool isRequest, class Body, class Fields>
28 class parser;
29 
30 namespace detail {
31 
32 template<class T>
33 class is_header_impl
34 {
35     template<bool b, class F>
36     static std::true_type check(
37         header<b, F> const*);
38     static std::false_type check(...);
39 public:
40     using type = decltype(check((T*)0));
41 };
42 
43 template<class T>
44 using is_header = typename is_header_impl<T>::type;
45 
46 template<class T>
47 struct is_parser : std::false_type {};
48 
49 template<bool isRequest, class Body, class Fields>
50 struct is_parser<parser<isRequest, Body, Fields>> : std::true_type {};
51 
52 struct fields_model
53 {
54     struct writer;
55 
56     string_view method() const;
57     string_view reason() const;
58     string_view target() const;
59 
60 protected:
61     string_view get_method_impl() const;
62     string_view get_target_impl() const;
63     string_view get_reason_impl() const;
64     bool get_chunked_impl() const;
65     bool get_keep_alive_impl(unsigned) const;
66     bool has_content_length_impl() const;
67     void set_method_impl(string_view);
68     void set_target_impl(string_view);
69     void set_reason_impl(string_view);
70     void set_chunked_impl(bool);
71     void set_content_length_impl(boost::optional<std::uint64_t>);
72     void set_keep_alive_impl(unsigned, bool);
73 };
74 
75 template<class T, class = beast::detail::void_t<>>
76 struct has_value_type : std::false_type {};
77 
78 template<class T>
79 struct has_value_type<T, beast::detail::void_t<
80     typename T::value_type
81         > > : std::true_type {};
82 
83 /** Determine if a <em>Body</em> type has a size
84 
85     This metafunction is equivalent to `std::true_type` if
86     Body contains a static member function called `size`.
87 */
88 template<class T, class = void>
89 struct is_body_sized : std::false_type {};
90 
91 template<class T>
92 struct is_body_sized<T, beast::detail::void_t<
93     typename T::value_type,
94         decltype(
95     std::declval<std::uint64_t&>() =
96         T::size(std::declval<typename T::value_type const&>())
97     )>> : std::true_type {};
98 
99 template<class T>
100 struct is_fields_helper : T
101 {
102     template<class U = is_fields_helper>
103     static auto f1(int) -> decltype(
104         std::declval<string_view&>() = std::declval<U const&>().get_method_impl(),
105         std::true_type());
106     static auto f1(...) -> std::false_type;
107     using t1 = decltype(f1(0));
108 
109     template<class U = is_fields_helper>
110     static auto f2(int) -> decltype(
111         std::declval<string_view&>() = std::declval<U const&>().get_target_impl(),
112         std::true_type());
113     static auto f2(...) -> std::false_type;
114     using t2 = decltype(f2(0));
115 
116     template<class U = is_fields_helper>
117     static auto f3(int) -> decltype(
118         std::declval<string_view&>() = std::declval<U const&>().get_reason_impl(),
119         std::true_type());
120     static auto f3(...) -> std::false_type;
121     using t3 = decltype(f3(0));
122 
123     template<class U = is_fields_helper>
124     static auto f4(int) -> decltype(
125         std::declval<bool&>() = std::declval<U const&>().get_chunked_impl(),
126         std::true_type());
127     static auto f4(...) -> std::false_type;
128     using t4 = decltype(f4(0));
129 
130     template<class U = is_fields_helper>
131     static auto f5(int) -> decltype(
132         std::declval<bool&>() = std::declval<U const&>().get_keep_alive_impl(
133             std::declval<unsigned>()),
134         std::true_type());
135     static auto f5(...) -> std::false_type;
136     using t5 = decltype(f5(0));
137 
138     template<class U = is_fields_helper>
139     static auto f6(int) -> decltype(
140         std::declval<bool&>() = std::declval<U const&>().has_content_length_impl(),
141         std::true_type());
142     static auto f6(...) -> std::false_type;
143     using t6 = decltype(f6(0));
144 
145     template<class U = is_fields_helper>
146     static auto f7(int) -> decltype(
147         void(std::declval<U&>().set_method_impl(std::declval<string_view>())),
148         std::true_type());
149     static auto f7(...) -> std::false_type;
150     using t7 = decltype(f7(0));
151 
152     template<class U = is_fields_helper>
153     static auto f8(int) -> decltype(
154         void(std::declval<U&>().set_target_impl(std::declval<string_view>())),
155         std::true_type());
156     static auto f8(...) -> std::false_type;
157     using t8 = decltype(f8(0));
158 
159     template<class U = is_fields_helper>
160     static auto f9(int) -> decltype(
161         void(std::declval<U&>().set_reason_impl(std::declval<string_view>())),
162         std::true_type());
163     static auto f9(...) -> std::false_type;
164     using t9 = decltype(f9(0));
165 
166     template<class U = is_fields_helper>
167     static auto f10(int) -> decltype(
168         void(std::declval<U&>().set_chunked_impl(std::declval<bool>())),
169         std::true_type());
170     static auto f10(...) -> std::false_type;
171     using t10 = decltype(f10(0));
172 
173     template<class U = is_fields_helper>
174     static auto f11(int) -> decltype(
175         void(std::declval<U&>().set_content_length_impl(
176             std::declval<boost::optional<std::uint64_t>>())),
177         std::true_type());
178     static auto f11(...) -> std::false_type;
179     using t11 = decltype(f11(0));
180 
181     template<class U = is_fields_helper>
182     static auto f12(int) -> decltype(
183         void(std::declval<U&>().set_keep_alive_impl(
184             std::declval<unsigned>(),
185             std::declval<bool>())),
186         std::true_type());
187     static auto f12(...) -> std::false_type;
188     using t12 = decltype(f12(0));
189 
190     using type = std::integral_constant<bool,
191          t1::value &&  t2::value && t3::value &&
192          t4::value &&  t5::value && t6::value &&
193          t7::value &&  t8::value && t9::value &&
194         t10::value && t11::value && t12::value>;
195 };
196 
197 } // detail
198 } // http
199 } // beast
200 } // boost
201 
202 #endif
203