2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
8 #ifndef BEAST_DETAIL_WRITE_DYNABUF_HPP
9 #define BEAST_DETAIL_WRITE_DYNABUF_HPP
11 #include <beast/core/buffer_concepts.hpp>
12 #include <boost/asio/buffer.hpp>
13 #include <boost/lexical_cast.hpp>
19 // detects string literals.
21 struct is_string_literal : std::integral_constant<bool,
22 ! std::is_same<T, typename std::remove_extent<T>::type>::value &&
23 std::is_same<char, typename std::remove_extent<T>::type>::value>
27 // `true` if a call to boost::asio::buffer(T const&) is possible
28 // note: we exclude string literals because boost::asio::buffer()
29 // will include the null terminator, which we don't want.
31 class is_BufferConvertible
33 template<class U, class R = decltype(
34 boost::asio::buffer(std::declval<U const&>()),
38 static std::false_type check(...);
39 using type = decltype(check<T>(0));
41 static bool const value = type::value &&
42 ! is_string_literal<T>::value;
45 template<class DynamicBuffer>
47 write_dynabuf(DynamicBuffer& dynabuf,
48 boost::asio::const_buffer const& buffer)
50 using boost::asio::buffer_copy;
51 using boost::asio::buffer_size;
52 dynabuf.commit(buffer_copy(
53 dynabuf.prepare(buffer_size(buffer)),
57 template<class DynamicBuffer>
59 write_dynabuf(DynamicBuffer& dynabuf,
60 boost::asio::mutable_buffer const& buffer)
62 using boost::asio::buffer_copy;
63 using boost::asio::buffer_size;
64 dynabuf.commit(buffer_copy(
65 dynabuf.prepare(buffer_size(buffer)),
69 template<class DynamicBuffer, class T>
70 typename std::enable_if<
71 is_BufferConvertible<T>::value &&
72 ! std::is_convertible<T, boost::asio::const_buffer>::value &&
73 ! std::is_convertible<T, boost::asio::mutable_buffer>::value
75 write_dynabuf(DynamicBuffer& dynabuf, T const& t)
77 using boost::asio::buffer_copy;
78 using boost::asio::buffer_size;
79 auto const buffers = boost::asio::buffer(t);
80 dynabuf.commit(buffer_copy(
81 dynabuf.prepare(buffer_size(buffers)),
85 template<class DynamicBuffer, class Buffers>
86 typename std::enable_if<
87 is_ConstBufferSequence<Buffers>::value &&
88 ! is_BufferConvertible<Buffers>::value &&
89 ! std::is_convertible<Buffers, boost::asio::const_buffer>::value &&
90 ! std::is_convertible<Buffers, boost::asio::mutable_buffer>::value
92 write_dynabuf(DynamicBuffer& dynabuf, Buffers const& buffers)
94 using boost::asio::buffer_copy;
95 using boost::asio::buffer_size;
96 dynabuf.commit(buffer_copy(
97 dynabuf.prepare(buffer_size(buffers)),
101 template<class DynamicBuffer, std::size_t N>
103 write_dynabuf(DynamicBuffer& dynabuf, const char (&s)[N])
105 using boost::asio::buffer_copy;
106 dynabuf.commit(buffer_copy(
107 dynabuf.prepare(N - 1),
108 boost::asio::buffer(s, N - 1)));
111 template<class DynamicBuffer, class T>
112 typename std::enable_if<
113 ! is_string_literal<T>::value &&
114 ! is_ConstBufferSequence<T>::value &&
115 ! is_BufferConvertible<T>::value &&
116 ! std::is_convertible<T, boost::asio::const_buffer>::value &&
117 ! std::is_convertible<T, boost::asio::mutable_buffer>::value
119 write_dynabuf(DynamicBuffer& dynabuf, T const& t)
121 using boost::asio::buffer;
122 using boost::asio::buffer_copy;
123 auto const s = boost::lexical_cast<std::string>(t);
124 dynabuf.commit(buffer_copy(
125 dynabuf.prepare(s.size()), buffer(s)));
128 template<class DynamicBuffer, class T0, class T1, class... TN>
130 write_dynabuf(DynamicBuffer& dynabuf,
131 T0 const& t0, T1 const& t1, TN const&... tn)
133 write_dynabuf(dynabuf, t0);
134 write_dynabuf(dynabuf, t1, tn...);