]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/flat_buffer.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / beast / core / flat_buffer.hpp
CommitLineData
b32b8144 1//
92f5a8d4 2// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
b32b8144
FG
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// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_FLAT_BUFFER_HPP
11#define BOOST_BEAST_FLAT_BUFFER_HPP
12
13#include <boost/beast/core/detail/config.hpp>
14#include <boost/beast/core/detail/allocator.hpp>
b32b8144 15#include <boost/asio/buffer.hpp>
92f5a8d4 16#include <boost/core/empty_value.hpp>
b32b8144
FG
17#include <limits>
18#include <memory>
92f5a8d4 19#include <type_traits>
b32b8144
FG
20
21namespace boost {
22namespace beast {
23
92f5a8d4 24/** A dynamic buffer providing buffer sequences of length one.
b32b8144 25
92f5a8d4
TL
26 A dynamic buffer encapsulates memory storage that may be
27 automatically resized as required, where the memory is
28 divided into two regions: readable bytes followed by
29 writable bytes. These memory regions are internal to
30 the dynamic buffer, but direct access to the elements
31 is provided to permit them to be efficiently used with
32 I/O operations.
33
34 Objects of this type meet the requirements of <em>DynamicBuffer</em>
35 and have the following additional properties:
36
37 @li A mutable buffer sequence representing the readable
38 bytes is returned by @ref data when `this` is non-const.
b32b8144
FG
39
40 @li A configurable maximum buffer size may be set upon
41 construction. Attempts to exceed the buffer size will throw
42 `std::length_error`.
43
92f5a8d4
TL
44 @li Buffer sequences representing the readable and writable
45 bytes, returned by @ref data and @ref prepare, will have
46 length one.
47
b32b8144
FG
48 Upon construction, a maximum size for the buffer may be
49 specified. If this limit is exceeded, the `std::length_error`
50 exception will be thrown.
51
52 @note This class is designed for use with algorithms that
53 take dynamic buffers as parameters, and are optimized
54 for the case where the input sequence or output sequence
55 is stored in a single contiguous buffer.
56*/
57template<class Allocator>
58class basic_flat_buffer
59#if ! BOOST_BEAST_DOXYGEN
92f5a8d4 60 : private boost::empty_value<
b32b8144
FG
61 typename detail::allocator_traits<Allocator>::
62 template rebind_alloc<char>>
63#endif
64{
b32b8144
FG
65 template<class OtherAlloc>
66 friend class basic_flat_buffer;
67
68 using base_alloc_type = typename
69 detail::allocator_traits<Allocator>::
70 template rebind_alloc<char>;
71
92f5a8d4
TL
72 static bool constexpr default_nothrow =
73 std::is_nothrow_default_constructible<Allocator>::value;
74
b32b8144 75 using alloc_traits =
92f5a8d4
TL
76 beast::detail::allocator_traits<base_alloc_type>;
77
78 using pocma = typename
79 alloc_traits::propagate_on_container_move_assignment;
80
81 using pocca = typename
82 alloc_traits::propagate_on_container_copy_assignment;
b32b8144
FG
83
84 static
b32b8144 85 std::size_t
92f5a8d4 86 dist(char const* first, char const* last) noexcept
b32b8144
FG
87 {
88 return static_cast<std::size_t>(last - first);
89 }
90
91 char* begin_;
92 char* in_;
93 char* out_;
94 char* last_;
95 char* end_;
96 std::size_t max_;
97
98public:
99 /// The type of allocator used.
100 using allocator_type = Allocator;
101
b32b8144
FG
102 /// Destructor
103 ~basic_flat_buffer();
104
105 /** Constructor
106
92f5a8d4
TL
107 After construction, @ref capacity will return zero, and
108 @ref max_size will return the largest value which may
109 be passed to the allocator's `allocate` function.
b32b8144 110 */
92f5a8d4 111 basic_flat_buffer() noexcept(default_nothrow);
b32b8144
FG
112
113 /** Constructor
114
92f5a8d4
TL
115 After construction, @ref capacity will return zero, and
116 @ref max_size will return the specified value of `limit`.
b32b8144 117
92f5a8d4 118 @param limit The desired maximum size.
b32b8144
FG
119 */
120 explicit
92f5a8d4
TL
121 basic_flat_buffer(
122 std::size_t limit) noexcept(default_nothrow);
b32b8144
FG
123
124 /** Constructor
125
92f5a8d4
TL
126 After construction, @ref capacity will return zero, and
127 @ref max_size will return the largest value which may
128 be passed to the allocator's `allocate` function.
b32b8144 129
92f5a8d4
TL
130 @param alloc The allocator to use for the object.
131
132 @esafe
133
134 No-throw guarantee.
b32b8144
FG
135 */
136 explicit
92f5a8d4 137 basic_flat_buffer(Allocator const& alloc) noexcept;
b32b8144
FG
138
139 /** Constructor
140
92f5a8d4
TL
141 After construction, @ref capacity will return zero, and
142 @ref max_size will return the specified value of `limit`.
143
144 @param limit The desired maximum size.
145
146 @param alloc The allocator to use for the object.
b32b8144 147
92f5a8d4 148 @esafe
b32b8144 149
92f5a8d4 150 No-throw guarantee.
b32b8144
FG
151 */
152 basic_flat_buffer(
92f5a8d4
TL
153 std::size_t limit,
154 Allocator const& alloc) noexcept;
b32b8144 155
92f5a8d4 156 /** Move Constructor
b32b8144 157
92f5a8d4
TL
158 The container is constructed with the contents of `other`
159 using move semantics. The maximum size will be the same
160 as the moved-from object.
b32b8144 161
92f5a8d4
TL
162 Buffer sequences previously obtained from `other` using
163 @ref data or @ref prepare remain valid after the move.
164
165 @param other The object to move from. After the move, the
166 moved-from object will have zero capacity, zero readable
167 bytes, and zero writable bytes.
168
169 @esafe
170
171 No-throw guarantee.
b32b8144 172 */
92f5a8d4 173 basic_flat_buffer(basic_flat_buffer&& other) noexcept;
b32b8144 174
92f5a8d4 175 /** Move Constructor
b32b8144 176
92f5a8d4
TL
177 Using `alloc` as the allocator for the new container, the
178 contents of `other` are moved. If `alloc != other.get_allocator()`,
179 this results in a copy. The maximum size will be the same
180 as the moved-from object.
181
182 Buffer sequences previously obtained from `other` using
183 @ref data or @ref prepare become invalid after the move.
b32b8144
FG
184
185 @param other The object to move from. After the move,
92f5a8d4
TL
186 the moved-from object will have zero capacity, zero readable
187 bytes, and zero writable bytes.
188
189 @param alloc The allocator to use for the object.
b32b8144 190
92f5a8d4
TL
191 @throws std::length_error if `other.size()` exceeds the
192 maximum allocation size of `alloc`.
b32b8144
FG
193 */
194 basic_flat_buffer(
92f5a8d4
TL
195 basic_flat_buffer&& other,
196 Allocator const& alloc);
b32b8144 197
92f5a8d4
TL
198 /** Copy Constructor
199
200 This container is constructed with the contents of `other`
201 using copy semantics. The maximum size will be the same
202 as the copied object.
b32b8144
FG
203
204 @param other The object to copy from.
92f5a8d4
TL
205
206 @throws std::length_error if `other.size()` exceeds the
207 maximum allocation size of the allocator.
b32b8144
FG
208 */
209 basic_flat_buffer(basic_flat_buffer const& other);
210
92f5a8d4
TL
211 /** Copy Constructor
212
213 This container is constructed with the contents of `other`
214 using copy semantics and the specified allocator. The maximum
215 size will be the same as the copied object.
b32b8144
FG
216
217 @param other The object to copy from.
218
92f5a8d4
TL
219 @param alloc The allocator to use for the object.
220
221 @throws std::length_error if `other.size()` exceeds the
222 maximum allocation size of `alloc`.
b32b8144 223 */
92f5a8d4
TL
224 basic_flat_buffer(
225 basic_flat_buffer const& other,
b32b8144
FG
226 Allocator const& alloc);
227
92f5a8d4
TL
228 /** Copy Constructor
229
230 This container is constructed with the contents of `other`
231 using copy semantics. The maximum size will be the same
232 as the copied object.
b32b8144
FG
233
234 @param other The object to copy from.
92f5a8d4
TL
235
236 @throws std::length_error if `other.size()` exceeds the
237 maximum allocation size of the allocator.
b32b8144
FG
238 */
239 template<class OtherAlloc>
240 basic_flat_buffer(
92f5a8d4
TL
241 basic_flat_buffer<OtherAlloc> const& other)
242 noexcept(default_nothrow);
b32b8144 243
92f5a8d4
TL
244 /** Copy Constructor
245
246 This container is constructed with the contents of `other`
247 using copy semantics. The maximum size will be the same
248 as the copied object.
b32b8144
FG
249
250 @param other The object to copy from.
251
92f5a8d4
TL
252 @param alloc The allocator to use for the object.
253
254 @throws std::length_error if `other.size()` exceeds the
255 maximum allocation size of `alloc`.
b32b8144
FG
256 */
257 template<class OtherAlloc>
258 basic_flat_buffer(
259 basic_flat_buffer<OtherAlloc> const& other,
92f5a8d4
TL
260 Allocator const& alloc);
261
262 /** Move Assignment
b32b8144 263
92f5a8d4
TL
264 The container is assigned with the contents of `other`
265 using move semantics. The maximum size will be the same
266 as the moved-from object.
b32b8144 267
92f5a8d4
TL
268 Buffer sequences previously obtained from `other` using
269 @ref data or @ref prepare remain valid after the move.
b32b8144
FG
270
271 @param other The object to move from. After the move,
92f5a8d4
TL
272 the moved-from object will have zero capacity, zero readable
273 bytes, and zero writable bytes.
274
275 @esafe
276
277 No-throw guarantee.
b32b8144
FG
278 */
279 basic_flat_buffer&
92f5a8d4 280 operator=(basic_flat_buffer&& other) noexcept;
b32b8144 281
92f5a8d4 282 /** Copy Assignment
b32b8144 283
92f5a8d4
TL
284 The container is assigned with the contents of `other`
285 using copy semantics. The maximum size will be the same
286 as the copied object.
287
288 After the copy, `this` will have zero writable bytes.
b32b8144
FG
289
290 @param other The object to copy from.
92f5a8d4
TL
291
292 @throws std::length_error if `other.size()` exceeds the
293 maximum allocation size of the allocator.
b32b8144
FG
294 */
295 basic_flat_buffer&
296 operator=(basic_flat_buffer const& other);
297
298 /** Copy assignment
299
92f5a8d4
TL
300 The container is assigned with the contents of `other`
301 using copy semantics. The maximum size will be the same
302 as the copied object.
303
304 After the copy, `this` will have zero writable bytes.
b32b8144
FG
305
306 @param other The object to copy from.
92f5a8d4
TL
307
308 @throws std::length_error if `other.size()` exceeds the
309 maximum allocation size of the allocator.
b32b8144
FG
310 */
311 template<class OtherAlloc>
312 basic_flat_buffer&
313 operator=(basic_flat_buffer<OtherAlloc> const& other);
314
92f5a8d4 315 /// Returns a copy of the allocator used.
b32b8144
FG
316 allocator_type
317 get_allocator() const
318 {
92f5a8d4
TL
319 return this->get();
320 }
321
322 /** Set the maximum allowed capacity
323
324 This function changes the currently configured upper limit
325 on capacity to the specified value.
326
327 @param n The maximum number of bytes ever allowed for capacity.
328
329 @esafe
330
331 No-throw guarantee.
332 */
333 void
334 max_size(std::size_t n) noexcept
335 {
336 max_ = n;
b32b8144
FG
337 }
338
92f5a8d4
TL
339 /** Guarantee a minimum capacity
340
341 This function adjusts the internal storage (if necessary)
342 to guarantee space for at least `n` bytes.
343
344 Buffer sequences previously obtained using @ref data or
345 @ref prepare become invalid.
346
347 @param n The minimum number of byte for the new capacity.
348 If this value is greater than the maximum size, then the
349 maximum size will be adjusted upwards to this value.
350
351 @esafe
352
353 Basic guarantee.
354
355 @throws std::length_error if n is larger than the maximum
356 allocation size of the allocator.
357 */
358 void
359 reserve(std::size_t n);
360
f67539c2 361 /** Request the removal of unused capacity.
92f5a8d4 362
f67539c2
TL
363 This function attempts to reduce @ref capacity()
364 to @ref size(), which may not succeed.
92f5a8d4
TL
365
366 @esafe
367
f67539c2 368 No-throw guarantee.
92f5a8d4
TL
369 */
370 void
f67539c2 371 shrink_to_fit() noexcept;
92f5a8d4
TL
372
373 /** Set the size of the readable and writable bytes to zero.
374
375 This clears the buffer without changing capacity.
376 Buffer sequences previously obtained using @ref data or
377 @ref prepare become invalid.
378
379 @esafe
380
381 No-throw guarantee.
382 */
383 void
384 clear() noexcept;
385
386 /// Exchange two dynamic buffers
387 template<class Alloc>
388 friend
389 void
390 swap(
391 basic_flat_buffer<Alloc>&,
392 basic_flat_buffer<Alloc>&);
393
394 //--------------------------------------------------------------------------
395
396 /// The ConstBufferSequence used to represent the readable bytes.
397 using const_buffers_type = net::const_buffer;
398
92f5a8d4
TL
399 /// The MutableBufferSequence used to represent the writable bytes.
400 using mutable_buffers_type = net::mutable_buffer;
401
402 /// Returns the number of readable bytes.
b32b8144 403 std::size_t
92f5a8d4 404 size() const noexcept
b32b8144
FG
405 {
406 return dist(in_, out_);
407 }
408
92f5a8d4 409 /// Return the maximum number of bytes, both readable and writable, that can ever be held.
b32b8144 410 std::size_t
92f5a8d4 411 max_size() const noexcept
b32b8144
FG
412 {
413 return max_;
414 }
415
92f5a8d4 416 /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
b32b8144 417 std::size_t
92f5a8d4 418 capacity() const noexcept
b32b8144
FG
419 {
420 return dist(begin_, end_);
421 }
422
92f5a8d4 423 /// Returns a constant buffer sequence representing the readable bytes
b32b8144 424 const_buffers_type
92f5a8d4 425 data() const noexcept
b32b8144
FG
426 {
427 return {in_, dist(in_, out_)};
428 }
429
92f5a8d4
TL
430 /// Returns a constant buffer sequence representing the readable bytes
431 const_buffers_type
432 cdata() const noexcept
433 {
434 return data();
435 }
b32b8144 436
92f5a8d4 437 /// Returns a mutable buffer sequence representing the readable bytes
f67539c2 438 mutable_buffers_type
92f5a8d4
TL
439 data() noexcept
440 {
441 return {in_, dist(in_, out_)};
442 }
b32b8144 443
92f5a8d4
TL
444 /** Returns a mutable buffer sequence representing writable bytes.
445
446 Returns a mutable buffer sequence representing the writable
447 bytes containing exactly `n` bytes of storage. Memory may be
448 reallocated as needed.
b32b8144 449
92f5a8d4
TL
450 All buffers sequences previously obtained using
451 @ref data or @ref prepare become invalid.
b32b8144 452
92f5a8d4
TL
453 @param n The desired number of bytes in the returned buffer
454 sequence.
b32b8144 455
92f5a8d4
TL
456 @throws std::length_error if `size() + n` exceeds either
457 `max_size()` or the allocator's maximum allocation size.
b32b8144 458
92f5a8d4 459 @esafe
b32b8144 460
92f5a8d4 461 Strong guarantee.
b32b8144 462 */
92f5a8d4
TL
463 mutable_buffers_type
464 prepare(std::size_t n);
b32b8144 465
92f5a8d4 466 /** Append writable bytes to the readable bytes.
b32b8144 467
92f5a8d4
TL
468 Appends n bytes from the start of the writable bytes to the
469 end of the readable bytes. The remainder of the writable bytes
470 are discarded. If n is greater than the number of writable
471 bytes, all writable bytes are appended to the readable bytes.
b32b8144 472
92f5a8d4
TL
473 All buffers sequences previously obtained using
474 @ref data or @ref prepare become invalid.
b32b8144 475
92f5a8d4
TL
476 @param n The number of bytes to append. If this number
477 is greater than the number of writable bytes, all
478 writable bytes are appended.
b32b8144 479
92f5a8d4 480 @esafe
b32b8144 481
92f5a8d4
TL
482 No-throw guarantee.
483 */
b32b8144 484 void
92f5a8d4
TL
485 commit(std::size_t n) noexcept
486 {
487 out_ += (std::min)(n, dist(out_, last_));
488 }
b32b8144 489
92f5a8d4 490 /** Remove bytes from beginning of the readable bytes.
b32b8144 491
92f5a8d4 492 Removes n bytes from the beginning of the readable bytes.
b32b8144 493
92f5a8d4
TL
494 All buffers sequences previously obtained using
495 @ref data or @ref prepare become invalid.
b32b8144 496
92f5a8d4
TL
497 @param n The number of bytes to remove. If this number
498 is greater than the number of readable bytes, all
499 readable bytes are removed.
b32b8144 500
92f5a8d4 501 @esafe
b32b8144 502
92f5a8d4
TL
503 No-throw guarantee.
504 */
b32b8144 505 void
92f5a8d4
TL
506 consume(std::size_t n) noexcept;
507
508private:
509 template<class OtherAlloc>
510 void copy_from(basic_flat_buffer<OtherAlloc> const& other);
511 void move_assign(basic_flat_buffer&, std::true_type);
512 void move_assign(basic_flat_buffer&, std::false_type);
513 void copy_assign(basic_flat_buffer const&, std::true_type);
514 void copy_assign(basic_flat_buffer const&, std::false_type);
515 void swap(basic_flat_buffer&);
516 void swap(basic_flat_buffer&, std::true_type);
517 void swap(basic_flat_buffer&, std::false_type);
518 char* alloc(std::size_t n);
b32b8144
FG
519};
520
92f5a8d4 521/// A flat buffer which uses the default allocator.
b32b8144
FG
522using flat_buffer =
523 basic_flat_buffer<std::allocator<char>>;
524
525} // beast
526} // boost
527
92f5a8d4 528#include <boost/beast/core/impl/flat_buffer.hpp>
b32b8144
FG
529
530#endif