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