2 // Copyright (c) 2013-2016 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_FLAT_STREAMBUF_HPP
9 #define BEAST_FLAT_STREAMBUF_HPP
11 #include <beast/config.hpp>
12 #include <beast/core/detail/empty_base_optimization.hpp>
13 #include <boost/asio/buffer.hpp>
19 /** A linear dynamic buffer.
21 Objects of this type meet the requirements of @b DynamicBuffer
22 and offer additional invariants:
24 @li Buffer sequences returned by @ref data and @ref prepare
25 will always be of length one.
27 @li A configurable maximum buffer size may be set upon
28 construction. Attempts to exceed the buffer size will throw
31 @note This class is designed for use with algorithms that
32 take dynamic buffers as parameters, and are optimized
33 for the case where the input sequence or output sequence
34 is stored in a single contiguous buffer.
36 template<class Allocator>
37 class basic_flat_streambuf
39 : private detail::empty_base_optimization<
40 typename std::allocator_traits<Allocator>::
41 template rebind_alloc<char>>
46 /// The type of allocator used.
47 using allocator_type = Allocator;
49 using allocator_type = typename
50 std::allocator_traits<Allocator>::
51 template rebind_alloc<char>;
60 template<class OtherAlloc>
61 friend class basic_flat_streambuf;
64 std::allocator_traits<allocator_type>;
69 dist(char const* first, char const* last)
71 return static_cast<std::size_t>(last - first);
82 /// The type used to represent the input sequence as a list of buffers.
83 using const_buffers_type = boost::asio::const_buffers_1;
85 /// The type used to represent the output sequence as a list of buffers.
86 using mutable_buffers_type = boost::asio::mutable_buffers_1;
88 /// Copy assignment (disallowed).
90 operator=(basic_flat_streambuf const&) = delete;
93 ~basic_flat_streambuf();
97 The new object will have the same input sequence
98 and an empty output sequence.
100 @note After the move, the moved-from object will
101 have a capacity of zero, an empty input sequence,
102 and an empty output sequence.
104 basic_flat_streambuf(basic_flat_streambuf&&);
106 /** Move constructor.
108 The new object will have the same input sequence
109 and an empty output sequence.
111 @note After the move, the moved-from object will
112 have a capacity of zero, an empty input sequence,
113 and an empty output sequence.
115 @param alloc The allocator to associate with the
118 basic_flat_streambuf(basic_flat_streambuf&&,
119 Allocator const& alloc);
121 /** Copy constructor.
123 The new object will have a copy of the input sequence
124 and an empty output sequence.
126 basic_flat_streambuf(basic_flat_streambuf const&);
128 /** Copy constructor.
130 The new object will have a copy of the input sequence
131 and an empty output sequence.
133 @param alloc The allocator to associate with the
136 basic_flat_streambuf(basic_flat_streambuf const&,
137 Allocator const& alloc);
139 /** Copy constructor.
141 The new object will have a copy of the input sequence
142 and an empty output sequence.
144 template<class OtherAlloc>
145 basic_flat_streambuf(
146 basic_flat_streambuf<OtherAlloc> const&);
148 /** Copy constructor.
150 The new object will have a copy of the input sequence
151 and an empty output sequence.
153 @param alloc The allocator to associate with the
156 template<class OtherAlloc>
157 basic_flat_streambuf(
158 basic_flat_streambuf<OtherAlloc> const&,
159 Allocator const& alloc);
161 /** Construct a flat stream buffer.
163 No allocation is performed; the buffer will have
164 empty input and output sequences.
166 @param limit An optional non-zero value specifying the
167 maximum of the sum of the input and output sequence sizes
168 that can be allocated. If unspecified, the largest
169 possible value of `std::size_t` is used.
172 basic_flat_streambuf(std::size_t limit = (
173 std::numeric_limits<std::size_t>::max)());
175 /** Construct a flat stream buffer.
177 No allocation is performed; the buffer will have
178 empty input and output sequences.
180 @param alloc The allocator to associate with the
183 @param limit An optional non-zero value specifying the
184 maximum of the sum of the input and output sequence sizes
185 that can be allocated. If unspecified, the largest
186 possible value of `std::size_t` is used.
188 basic_flat_streambuf(Allocator const& alloc,
189 std::size_t limit = (
190 std::numeric_limits<std::size_t>::max)());
192 /// Returns a copy of the associated allocator.
194 get_allocator() const
196 return this->member();
199 /// Returns the size of the input sequence.
203 return dist(in_, out_);
206 /// Return the maximum sum of the input and output sequence sizes.
213 /// Return the maximum sum of input and output sizes that can be held without an allocation.
217 return dist(p_, end_);
220 /// Get a list of buffers that represent the input sequence.
224 return {in_, dist(in_, out_)};
227 /** Get a list of buffers that represent the output sequence, with the given size.
229 @throws std::length_error if `size() + n` exceeds `max_size()`.
231 @note All previous buffers sequences obtained from
232 calls to @ref data or @ref prepare are invalidated.
235 prepare(std::size_t n);
237 /** Move bytes from the output sequence to the input sequence.
239 @param n The number of bytes to move. If this is larger than
240 the number of bytes in the output sequences, then the entire
241 output sequences is moved.
243 @note All previous buffers sequences obtained from
244 calls to @ref data or @ref prepare are invalidated.
247 commit(std::size_t n)
249 out_ += (std::min)(n, dist(out_, last_));
252 /** Remove bytes from the input sequence.
254 If `n` is greater than the number of bytes in the input
255 sequence, all bytes in the input sequence are removed.
257 @note All previous buffers sequences obtained from
258 calls to @ref data or @ref prepare are invalidated.
261 consume(std::size_t n);
263 /** Reserve space in the stream.
265 This reallocates the buffer if necessary.
267 @note All previous buffers sequences obtained from
268 calls to @ref data or @ref prepare are invalidated.
270 @param n The number of bytes to reserve. Upon success,
271 the capacity will be at least `n`.
273 @throws std::length_error if `n` exceeds `max_size()`.
276 reserve(std::size_t n);
278 /** Reallocate the buffer to fit the input sequence.
280 @note All previous buffers sequences obtained from
281 calls to @ref data or @ref prepare are invalidated.
286 // Helper for boost::asio::read_until
287 template<class OtherAlloc>
290 read_size_helper(basic_flat_streambuf<
291 OtherAlloc> const&, std::size_t);
295 move_from(basic_flat_streambuf& other);
297 template<class OtherAlloc>
299 copy_from(basic_flat_streambuf<
300 OtherAlloc> const& other);
303 using flat_streambuf =
304 basic_flat_streambuf<std::allocator<char>>;
308 #include <beast/core/impl/flat_streambuf.ipp>