2 // Copyright (c) 2016-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)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_BUFFERS_PREFIX_HPP
11 #define BOOST_BEAST_BUFFERS_PREFIX_HPP
13 #include <boost/beast/core/detail/config.hpp>
14 #include <boost/beast/core/type_traits.hpp>
15 #include <boost/beast/core/detail/in_place_init.hpp>
16 #include <boost/asio/buffer.hpp>
18 #include <type_traits>
23 /** A buffer sequence adapter that shortens the sequence size.
25 The class adapts a buffer sequence to efficiently represent
26 a shorter subset of the original list of buffers starting
27 with the first byte of the original sequence.
29 @tparam BufferSequence The buffer sequence to adapt.
31 template<class BufferSequence>
32 class buffers_prefix_view
34 using buffers_type = typename
35 std::decay<BufferSequence>::type;
37 using iter_type = typename
38 detail::buffer_sequence_iterator<buffers_type>::type;
44 template<class Deduced>
46 Deduced&& other, std::size_t dist)
47 : bs_(std::forward<Deduced>(other).bs_)
49 , end_(std::next(bs_.begin(), dist))
54 setup(std::size_t size);
57 /// The type for each element in the list of buffers.
58 using value_type = typename std::conditional<
59 std::is_convertible<typename
60 std::iterator_traits<iter_type>::value_type,
61 boost::asio::mutable_buffer>::value,
62 boost::asio::mutable_buffer,
63 boost::asio::const_buffer>::type;
65 #if BOOST_BEAST_DOXYGEN
66 /// A bidirectional iterator type that may be used to read elements.
67 using const_iterator = implementation_defined;
75 buffers_prefix_view(buffers_prefix_view&&);
78 buffers_prefix_view(buffers_prefix_view const&);
81 buffers_prefix_view& operator=(buffers_prefix_view&&);
84 buffers_prefix_view& operator=(buffers_prefix_view const&);
86 /** Construct a buffer sequence prefix.
88 @param size The maximum number of bytes in the prefix.
89 If this is larger than the size of passed, buffers,
90 the resulting sequence will represent the entire
93 @param buffers The buffer sequence to adapt. A copy of
94 the sequence will be made, but ownership of the underlying
95 memory is not transferred.
99 BufferSequence const& buffers);
101 /** Construct a buffer sequence prefix in-place.
103 @param size The maximum number of bytes in the prefix.
104 If this is larger than the size of passed, buffers,
105 the resulting sequence will represent the entire
108 @param args Arguments forwarded to the contained buffers constructor.
110 template<class... Args>
113 boost::in_place_init_t,
116 /// Get a bidirectional iterator to the first element.
120 /// Get a bidirectional iterator to one past the last element.
125 /** Returns a prefix of a constant buffer.
127 The returned buffer points to the same memory as the
128 passed buffer, but with a size that is equal to or less
129 than the size of the original buffer.
131 @param size The size of the returned buffer.
133 @param buffer The buffer to shorten. The underlying
134 memory is not modified.
136 @return A new buffer that points to the first `size`
137 bytes of the original buffer.
140 boost::asio::const_buffer
141 buffers_prefix(std::size_t size,
142 boost::asio::const_buffer buffer)
144 return {buffer.data(),
145 (std::min)(size, buffer.size())};
148 /** Returns a prefix of a mutable buffer.
150 The returned buffer points to the same memory as the
151 passed buffer, but with a size that is equal to or less
152 than the size of the original buffer.
154 @param size The size of the returned buffer.
156 @param buffer The buffer to shorten. The underlying
157 memory is not modified.
159 @return A new buffer that points to the first `size` bytes
160 of the original buffer.
163 boost::asio::mutable_buffer
164 buffers_prefix(std::size_t size,
165 boost::asio::mutable_buffer buffer)
167 return {buffer.data(),
168 (std::min)(size, buffer.size())};
171 /** Returns a prefix of a buffer sequence.
173 This function returns a new buffer sequence which when iterated,
174 presents a shorter subset of the original list of buffers starting
175 with the first byte of the original sequence.
177 @param size The maximum number of bytes in the wrapped
178 sequence. If this is larger than the size of passed,
179 buffers, the resulting sequence will represent the
180 entire input sequence.
182 @param buffers An instance of @b ConstBufferSequence or
183 @b MutableBufferSequence to adapt. A copy of the sequence
184 will be made, but ownership of the underlying memory is
187 template<class BufferSequence>
188 #if BOOST_BEAST_DOXYGEN
189 buffers_prefix_view<BufferSequence>
192 typename std::enable_if<
193 ! std::is_same<BufferSequence,
194 boost::asio::const_buffer>::value &&
195 ! std::is_same<BufferSequence,
196 boost::asio::mutable_buffer>::value,
197 buffers_prefix_view<BufferSequence>>::type
199 buffers_prefix(std::size_t size, BufferSequence const& buffers)
202 boost::asio::is_const_buffer_sequence<BufferSequence>::value ||
203 boost::asio::is_mutable_buffer_sequence<BufferSequence>::value,
204 "BufferSequence requirements not met");
205 return buffers_prefix_view<BufferSequence>(size, buffers);
208 /** Returns the first buffer in a buffer sequence
210 This returns the first buffer in the buffer sequence.
211 If the buffer sequence is an empty range, the returned
212 buffer will have a zero buffer size.
214 @param buffers The buffer sequence. If the sequence is
215 mutable, the returned buffer sequence will also be mutable.
216 Otherwise, the returned buffer sequence will be constant.
218 template<class BufferSequence>
219 typename std::conditional<
220 boost::asio::is_mutable_buffer_sequence<BufferSequence>::value,
221 boost::asio::mutable_buffer,
222 boost::asio::const_buffer>::type
223 buffers_front(BufferSequence const& buffers)
226 boost::asio::buffer_sequence_begin(buffers);
227 if(first == boost::asio::buffer_sequence_end(buffers))
235 #include <boost/beast/core/impl/buffers_prefix.ipp>