// // 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_DETAIL_WRITE_DYNABUF_HPP #define BEAST_DETAIL_WRITE_DYNABUF_HPP #include #include #include #include namespace beast { namespace detail { // detects string literals. template struct is_string_literal : std::integral_constant::type>::value && std::is_same::type>::value> { }; // `true` if a call to boost::asio::buffer(T const&) is possible // note: we exclude string literals because boost::asio::buffer() // will include the null terminator, which we don't want. template class is_BufferConvertible { template()), std::true_type{})> static R check(int); template static std::false_type check(...); using type = decltype(check(0)); public: static bool const value = type::value && ! is_string_literal::value; }; template void write_dynabuf(DynamicBuffer& dynabuf, boost::asio::const_buffer const& buffer) { using boost::asio::buffer_copy; using boost::asio::buffer_size; dynabuf.commit(buffer_copy( dynabuf.prepare(buffer_size(buffer)), buffer)); } template void write_dynabuf(DynamicBuffer& dynabuf, boost::asio::mutable_buffer const& buffer) { using boost::asio::buffer_copy; using boost::asio::buffer_size; dynabuf.commit(buffer_copy( dynabuf.prepare(buffer_size(buffer)), buffer)); } template typename std::enable_if< is_BufferConvertible::value && ! std::is_convertible::value && ! std::is_convertible::value >::type write_dynabuf(DynamicBuffer& dynabuf, T const& t) { using boost::asio::buffer_copy; using boost::asio::buffer_size; auto const buffers = boost::asio::buffer(t); dynabuf.commit(buffer_copy( dynabuf.prepare(buffer_size(buffers)), buffers)); } template typename std::enable_if< is_ConstBufferSequence::value && ! is_BufferConvertible::value && ! std::is_convertible::value && ! std::is_convertible::value >::type write_dynabuf(DynamicBuffer& dynabuf, Buffers const& buffers) { using boost::asio::buffer_copy; using boost::asio::buffer_size; dynabuf.commit(buffer_copy( dynabuf.prepare(buffer_size(buffers)), buffers)); } template void write_dynabuf(DynamicBuffer& dynabuf, const char (&s)[N]) { using boost::asio::buffer_copy; dynabuf.commit(buffer_copy( dynabuf.prepare(N - 1), boost::asio::buffer(s, N - 1))); } template typename std::enable_if< ! is_string_literal::value && ! is_ConstBufferSequence::value && ! is_BufferConvertible::value && ! std::is_convertible::value && ! std::is_convertible::value >::type write_dynabuf(DynamicBuffer& dynabuf, T const& t) { using boost::asio::buffer; using boost::asio::buffer_copy; auto const s = boost::lexical_cast(t); dynabuf.commit(buffer_copy( dynabuf.prepare(s.size()), buffer(s))); } template void write_dynabuf(DynamicBuffer& dynabuf, T0 const& t0, T1 const& t1, TN const&... tn) { write_dynabuf(dynabuf, t0); write_dynabuf(dynabuf, t1, tn...); } } // detail } // beast #endif