// // Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BEAST_HTTP_TYPE_CHECK_HPP #define BEAST_HTTP_TYPE_CHECK_HPP #include #include #include #include #include #include #include namespace beast { namespace http { namespace detail { struct write_function { template void operator()(ConstBufferSequence const&); }; template> struct has_value_type : std::false_type {}; template struct has_value_type > : std::true_type {}; template> struct has_content_length : std::false_type {}; template struct has_content_length().content_length() )> > : std::true_type { static_assert(std::is_convertible< decltype(std::declval().content_length()), std::uint64_t>::value, "Writer::content_length requirements not met"); }; #if 0 template> struct is_Writer : std::false_type {}; template struct is_Writer().init( std::declval()) // VFALCO This is unfortunate, we have to provide the template // argument type because this is not a deduced context? // ,std::declval().template write( std::declval(), std::declval(), std::declval()) )> > : std::integral_constant::value && std::is_convertible().template write( std::declval(), std::declval(), std::declval())), boost::tribool>::value > { static_assert(std::is_same< typename M::body_type::writer, T>::value, "Mismatched writer and message"); }; #else template class is_Writer { template().init(std::declval()), std::true_type{})> static R check1(int); template static std::false_type check1(...); using type1 = decltype(check1(0)); // VFALCO This is unfortunate, we have to provide the template // argument type because this is not a deduced context? // template().template write( std::declval(), std::declval(), std::declval())) , boost::tribool>> static R check2(int); template static std::false_type check2(...); using type2 = decltype(check2(0)); public: static_assert(std::is_same< typename M::body_type::writer, T>::value, "Mismatched writer and message"); using type = std::integral_constant::value && type1::value && type2::value >; }; #endif template class is_Parser { template().complete()), bool>> static R check1(int); template static std::false_type check1(...); using type1 = decltype(check1(0)); template().write( std::declval(), std::declval())), std::size_t>> static R check2(int); template static std::false_type check2(...); using type2 = decltype(check2(0)); template().write_eof(std::declval()), std::true_type{})> static R check3(int); template static std::false_type check3(...); using type3 = decltype(check3(0)); public: using type = std::integral_constant; }; } // detail /// Determine if `T` meets the requirements of @b Body. template #if GENERATING_DOCS struct is_Body : std::integral_constant{}; #else using is_Body = detail::has_value_type; #endif /** Determine if a @b Body has a nested type `reader`. @tparam T The type to check, which must meet the requirements of @b Body. */ #if GENERATING_DOCS template struct has_reader : std::integral_constant{}; #else template> struct has_reader : std::false_type {}; template struct has_reader > : std::true_type {}; #endif /** Determine if a @b Body has a nested type `writer`. @tparam T The type to check, which must meet the requirements of @b Body. */ #if GENERATING_DOCS template struct has_writer : std::integral_constant{}; #else template> struct has_writer : std::false_type {}; template struct has_writer > : std::true_type {}; #endif /** Determine if `T` meets the requirements of @b Reader for `M`. @tparam T The type to test. @tparam M The message type to test with, which must be of type `message`. */ #if GENERATING_DOCS template struct is_Reader : std::integral_constant {}; #else template> struct is_Reader : std::false_type {}; template struct is_Reader().init( std::declval()), std::declval().write( std::declval(), std::declval(), std::declval()) )> > : std::integral_constant::value > { static_assert(std::is_same< typename M::body_type::reader, T>::value, "Mismatched reader and message"); }; #endif /** Determine if `T` meets the requirements of @b Writer for `M`. @tparam T The type to test. @tparam M The message type to test with, which must be of type `message`. */ template #if GENERATING_DOCS struct is_Writer : std::integral_constant {}; #else using is_Writer = typename detail::is_Writer::type; #endif /// Determine if `T` meets the requirements of @b Parser. template #if GENERATING_DOCS struct is_Parser : std::integral_constant{}; #else using is_Parser = typename detail::is_Parser::type; #endif } // http } // beast #endif