]> git.proxmox.com Git - ceph.git/blob - ceph/src/Beast/include/beast/core/flat_streambuf.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / core / flat_streambuf.hpp
1 //
2 // Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7
8 #ifndef BEAST_FLAT_STREAMBUF_HPP
9 #define BEAST_FLAT_STREAMBUF_HPP
10
11 #include <beast/config.hpp>
12 #include <beast/core/detail/empty_base_optimization.hpp>
13 #include <boost/asio/buffer.hpp>
14 #include <limits>
15 #include <memory>
16
17 namespace beast {
18
19 /** A linear dynamic buffer.
20
21 Objects of this type meet the requirements of @b DynamicBuffer
22 and offer additional invariants:
23
24 @li Buffer sequences returned by @ref data and @ref prepare
25 will always be of length one.
26
27 @li A configurable maximum buffer size may be set upon
28 construction. Attempts to exceed the buffer size will throw
29 `std::length_error`.
30
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.
35 */
36 template<class Allocator>
37 class basic_flat_streambuf
38 #if ! BEAST_DOXYGEN
39 : private detail::empty_base_optimization<
40 typename std::allocator_traits<Allocator>::
41 template rebind_alloc<char>>
42 #endif
43 {
44 public:
45 #if BEAST_DOXYGEN
46 /// The type of allocator used.
47 using allocator_type = Allocator;
48 #else
49 using allocator_type = typename
50 std::allocator_traits<Allocator>::
51 template rebind_alloc<char>;
52 #endif
53
54 private:
55 enum
56 {
57 min_size = 512
58 };
59
60 template<class OtherAlloc>
61 friend class basic_flat_streambuf;
62
63 using alloc_traits =
64 std::allocator_traits<allocator_type>;
65
66 static
67 inline
68 std::size_t
69 dist(char const* first, char const* last)
70 {
71 return static_cast<std::size_t>(last - first);
72 }
73
74 char* p_;
75 char* in_;
76 char* out_;
77 char* last_;
78 char* end_;
79 std::size_t max_;
80
81 public:
82 /// The type used to represent the input sequence as a list of buffers.
83 using const_buffers_type = boost::asio::const_buffers_1;
84
85 /// The type used to represent the output sequence as a list of buffers.
86 using mutable_buffers_type = boost::asio::mutable_buffers_1;
87
88 /// Copy assignment (disallowed).
89 basic_flat_streambuf&
90 operator=(basic_flat_streambuf const&) = delete;
91
92 /// Destructor.
93 ~basic_flat_streambuf();
94
95 /** Move constructor.
96
97 The new object will have the same input sequence
98 and an empty output sequence.
99
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.
103 */
104 basic_flat_streambuf(basic_flat_streambuf&&);
105
106 /** Move constructor.
107
108 The new object will have the same input sequence
109 and an empty output sequence.
110
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.
114
115 @param alloc The allocator to associate with the
116 stream buffer.
117 */
118 basic_flat_streambuf(basic_flat_streambuf&&,
119 Allocator const& alloc);
120
121 /** Copy constructor.
122
123 The new object will have a copy of the input sequence
124 and an empty output sequence.
125 */
126 basic_flat_streambuf(basic_flat_streambuf const&);
127
128 /** Copy constructor.
129
130 The new object will have a copy of the input sequence
131 and an empty output sequence.
132
133 @param alloc The allocator to associate with the
134 stream buffer.
135 */
136 basic_flat_streambuf(basic_flat_streambuf const&,
137 Allocator const& alloc);
138
139 /** Copy constructor.
140
141 The new object will have a copy of the input sequence
142 and an empty output sequence.
143 */
144 template<class OtherAlloc>
145 basic_flat_streambuf(
146 basic_flat_streambuf<OtherAlloc> const&);
147
148 /** Copy constructor.
149
150 The new object will have a copy of the input sequence
151 and an empty output sequence.
152
153 @param alloc The allocator to associate with the
154 stream buffer.
155 */
156 template<class OtherAlloc>
157 basic_flat_streambuf(
158 basic_flat_streambuf<OtherAlloc> const&,
159 Allocator const& alloc);
160
161 /** Construct a flat stream buffer.
162
163 No allocation is performed; the buffer will have
164 empty input and output sequences.
165
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.
170 */
171 explicit
172 basic_flat_streambuf(std::size_t limit = (
173 std::numeric_limits<std::size_t>::max)());
174
175 /** Construct a flat stream buffer.
176
177 No allocation is performed; the buffer will have
178 empty input and output sequences.
179
180 @param alloc The allocator to associate with the
181 stream buffer.
182
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.
187 */
188 basic_flat_streambuf(Allocator const& alloc,
189 std::size_t limit = (
190 std::numeric_limits<std::size_t>::max)());
191
192 /// Returns a copy of the associated allocator.
193 allocator_type
194 get_allocator() const
195 {
196 return this->member();
197 }
198
199 /// Returns the size of the input sequence.
200 std::size_t
201 size() const
202 {
203 return dist(in_, out_);
204 }
205
206 /// Return the maximum sum of the input and output sequence sizes.
207 std::size_t
208 max_size() const
209 {
210 return max_;
211 }
212
213 /// Return the maximum sum of input and output sizes that can be held without an allocation.
214 std::size_t
215 capacity() const
216 {
217 return dist(p_, end_);
218 }
219
220 /// Get a list of buffers that represent the input sequence.
221 const_buffers_type
222 data() const
223 {
224 return {in_, dist(in_, out_)};
225 }
226
227 /** Get a list of buffers that represent the output sequence, with the given size.
228
229 @throws std::length_error if `size() + n` exceeds `max_size()`.
230
231 @note All previous buffers sequences obtained from
232 calls to @ref data or @ref prepare are invalidated.
233 */
234 mutable_buffers_type
235 prepare(std::size_t n);
236
237 /** Move bytes from the output sequence to the input sequence.
238
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.
242
243 @note All previous buffers sequences obtained from
244 calls to @ref data or @ref prepare are invalidated.
245 */
246 void
247 commit(std::size_t n)
248 {
249 out_ += (std::min)(n, dist(out_, last_));
250 }
251
252 /** Remove bytes from the input sequence.
253
254 If `n` is greater than the number of bytes in the input
255 sequence, all bytes in the input sequence are removed.
256
257 @note All previous buffers sequences obtained from
258 calls to @ref data or @ref prepare are invalidated.
259 */
260 void
261 consume(std::size_t n);
262
263 /** Reserve space in the stream.
264
265 This reallocates the buffer if necessary.
266
267 @note All previous buffers sequences obtained from
268 calls to @ref data or @ref prepare are invalidated.
269
270 @param n The number of bytes to reserve. Upon success,
271 the capacity will be at least `n`.
272
273 @throws std::length_error if `n` exceeds `max_size()`.
274 */
275 void
276 reserve(std::size_t n);
277
278 /** Reallocate the buffer to fit the input sequence.
279
280 @note All previous buffers sequences obtained from
281 calls to @ref data or @ref prepare are invalidated.
282 */
283 void
284 shrink_to_fit();
285
286 // Helper for boost::asio::read_until
287 template<class OtherAlloc>
288 friend
289 std::size_t
290 read_size_helper(basic_flat_streambuf<
291 OtherAlloc> const&, std::size_t);
292
293 private:
294 void
295 move_from(basic_flat_streambuf& other);
296
297 template<class OtherAlloc>
298 void
299 copy_from(basic_flat_streambuf<
300 OtherAlloc> const& other);
301 };
302
303 using flat_streambuf =
304 basic_flat_streambuf<std::allocator<char>>;
305
306 } // beast
307
308 #include <beast/core/impl/flat_streambuf.ipp>
309
310 #endif