123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- //
- // Copyright (c) 2016-2019 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)
- //
- // Official repository: https://github.com/boostorg/beast
- //
- #ifndef BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
- #define BOOST_BEAST_HTTP_TYPE_TRAITS_HPP
- #include <boost/beast/core/detail/config.hpp>
- #include <boost/beast/core/error.hpp>
- #include <boost/beast/core/string.hpp>
- #include <boost/beast/http/detail/type_traits.hpp>
- #include <boost/asio/buffer.hpp>
- #include <boost/optional.hpp>
- #include <type_traits>
- #include <utility>
- namespace boost {
- namespace beast {
- namespace http {
- template<bool, class, class>
- class message;
- /** Determine if a type meets the <em>Body</em> named requirements.
- This alias template is `std::true_type` if `T` meets
- the requirements, otherwise it is `std::false_type`.
- @tparam T The type to test.
- @par Example
- @code
- template<bool isRequest, class Body, class Fields>
- void check_body(message<isRequest, Body, Fields> const&)
- {
- static_assert(is_body<Body>::value,
- "Body type requirements not met");
- }
- @endcode
- */
- template<class T>
- #if BOOST_BEAST_DOXYGEN
- using is_body = __see_below__;
- #else
- using is_body = detail::has_value_type<T>;
- #endif
- /** Determine if a type has a nested <em>BodyWriter</em>.
- This alias template is `std::true_type` when:
- @li `T` has a nested type named `writer`
- @li `writer` meets the requirements of <em>BodyWriter</em>.
- @tparam T The body type to test.
- @par Example
- @code
- template<bool isRequest, class Body, class Fields>
- void check_can_serialize(message<isRequest, Body, Fields> const&)
- {
- static_assert(is_body_writer<Body>::value,
- "Cannot serialize Body, no reader");
- }
- @endcode
- */
- #if BOOST_BEAST_DOXYGEN
- template<class T>
- using is_body_writer = __see_below__;
- #else
- template<class T, class = void>
- struct is_body_writer : std::false_type {};
- template<class T>
- struct is_body_writer<T, beast::detail::void_t<
- typename T::writer,
- typename T::writer::const_buffers_type,
- decltype(
- std::declval<typename T::writer&>().init(std::declval<error_code&>()),
- std::declval<boost::optional<std::pair<
- typename T::writer::const_buffers_type, bool>>&>() =
- std::declval<typename T::writer>().get(std::declval<error_code&>())
- )>> : std::integral_constant<bool,
- net::is_const_buffer_sequence<
- typename T::writer::const_buffers_type>::value && (
- (std::is_constructible<typename T::writer,
- header<true, detail::fields_model>&,
- typename T::value_type&>::value &&
- std::is_constructible<typename T::writer,
- header<false, detail::fields_model>&,
- typename T::value_type&>::value)
- )
- > {};
- #endif
- /** Determine if a type has a nested <em>BodyWriter</em>.
- This alias template is `std::true_type` when:
- @li `T` has a nested type named `writer`
- @li `writer` meets the requirements of <em>BodyWriter</em>.
- @tparam T The body type to test.
- */
- #if BOOST_BEAST_DOXYGEN
- template<class T>
- using is_mutable_body_writer = __see_below__;
- #else
- template<class T, class = void>
- struct is_mutable_body_writer : std::false_type {};
- template<class T>
- struct is_mutable_body_writer<T, beast::detail::void_t<
- typename T::writer,
- typename T::writer::const_buffers_type,
- decltype(
- std::declval<typename T::writer&>().init(std::declval<error_code&>()),
- std::declval<boost::optional<std::pair<
- typename T::writer::const_buffers_type, bool>>&>() =
- std::declval<typename T::writer>().get(std::declval<error_code&>())
- )>> : std::integral_constant<bool,
- net::is_const_buffer_sequence<
- typename T::writer::const_buffers_type>::value && ((
- std::is_constructible<typename T::writer,
- header<true, detail::fields_model>&,
- typename T::value_type&>::value &&
- std::is_constructible<typename T::writer,
- header<false, detail::fields_model>&,
- typename T::value_type&>::value &&
- ! std::is_constructible<typename T::writer,
- header<true, detail::fields_model> const&,
- typename T::value_type const&>::value &&
- ! std::is_constructible<typename T::writer,
- header<false, detail::fields_model> const&,
- typename T::value_type const&>::value
- ))
- >{};
- #endif
- /** Determine if a type has a nested <em>BodyReader</em>.
- This alias template is `std::true_type` when:
- @li `T` has a nested type named `reader`
- @li `reader` meets the requirements of <em>BodyReader</em>.
- @tparam T The body type to test.
- @par Example
- @code
- template<bool isRequest, class Body, class Fields>
- void check_can_parse(message<isRequest, Body, Fields>&)
- {
- static_assert(is_body_reader<Body>::value,
- "Cannot parse Body, no reader");
- }
- @endcode
- */
- #if BOOST_BEAST_DOXYGEN
- template<class T>
- using is_body_reader = __see_below__;
- #else
- template<class T, class = void>
- struct is_body_reader : std::false_type {};
- template<class T>
- struct is_body_reader<T, beast::detail::void_t<decltype(
- std::declval<typename T::reader&>().init(
- boost::optional<std::uint64_t>(),
- std::declval<error_code&>()),
- std::declval<std::size_t&>() =
- std::declval<typename T::reader&>().put(
- std::declval<net::const_buffer>(),
- std::declval<error_code&>()),
- std::declval<typename T::reader&>().finish(
- std::declval<error_code&>())
- )>> : std::integral_constant<bool,
- (std::is_constructible<typename T::reader,
- header<true, detail::fields_model>&,
- typename T::value_type&>::value &&
- std::is_constructible<typename T::reader,
- header<false,detail::fields_model>&,
- typename T::value_type&>::value)
- >
- {
- };
- #endif
- /** Determine if a type meets the <em>Fields</em> named requirements.
- This alias template is `std::true_type` if `T` meets
- the requirements, otherwise it is `std::false_type`.
- @tparam T The type to test.
- @par Example
- Use with `static_assert`:
- @code
- template<bool isRequest, class Body, class Fields>
- void f(message<isRequest, Body, Fields> const&)
- {
- static_assert(is_fields<Fields>::value,
- "Fields type requirements not met");
- ...
- @endcode
- Use with `std::enable_if` (SFINAE):
- @code
- template<bool isRequest, class Body, class Fields>
- typename std::enable_if<is_fields<Fields>::value>::type
- f(message<isRequest, Body, Fields> const&);
- @endcode
- */
- #if BOOST_BEAST_DOXYGEN
- template<class T>
- using is_fields = __see_below__;
- #else
- template<class T>
- using is_fields = typename detail::is_fields_helper<T>::type;
- #endif
- } // http
- } // beast
- } // boost
- #endif
|