]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/beast/core/flat_buffer.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / flat_buffer.hpp
CommitLineData
b32b8144
FG
1//
2// Copyright (c) 2016-2017 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// 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>
15#include <boost/beast/core/detail/empty_base_optimization.hpp>
16#include <boost/asio/buffer.hpp>
17#include <limits>
18#include <memory>
19
20namespace boost {
21namespace beast {
22
23/** A linear dynamic buffer.
24
25 Objects of this type meet the requirements of @b DynamicBuffer
26 and offer additional invariants:
27
28 @li Buffer sequences returned by @ref data and @ref prepare
29 will always be of length one.
30
31 @li A configurable maximum buffer size may be set upon
32 construction. Attempts to exceed the buffer size will throw
33 `std::length_error`.
34
35 Upon construction, a maximum size for the buffer may be
36 specified. If this limit is exceeded, the `std::length_error`
37 exception will be thrown.
38
39 @note This class is designed for use with algorithms that
40 take dynamic buffers as parameters, and are optimized
41 for the case where the input sequence or output sequence
42 is stored in a single contiguous buffer.
43*/
44template<class Allocator>
45class basic_flat_buffer
46#if ! BOOST_BEAST_DOXYGEN
47 : private detail::empty_base_optimization<
48 typename detail::allocator_traits<Allocator>::
49 template rebind_alloc<char>>
50#endif
51{
52 enum
53 {
54 min_size = 512
55 };
56
57 template<class OtherAlloc>
58 friend class basic_flat_buffer;
59
60 using base_alloc_type = typename
61 detail::allocator_traits<Allocator>::
62 template rebind_alloc<char>;
63
64 using alloc_traits =
65 detail::allocator_traits<base_alloc_type>;
66
67 static
68 inline
69 std::size_t
70 dist(char const* first, char const* last)
71 {
72 return static_cast<std::size_t>(last - first);
73 }
74
75 char* begin_;
76 char* in_;
77 char* out_;
78 char* last_;
79 char* end_;
80 std::size_t max_;
81
82public:
83 /// The type of allocator used.
84 using allocator_type = Allocator;
85
86 /// The type used to represent the input sequence as a list of buffers.
87 using const_buffers_type = boost::asio::mutable_buffer;
88
89 /// The type used to represent the output sequence as a list of buffers.
90 using mutable_buffers_type = boost::asio::mutable_buffer;
91
92 /// Destructor
93 ~basic_flat_buffer();
94
95 /** Constructor
96
97 Upon construction, capacity will be zero.
98 */
99 basic_flat_buffer();
100
101 /** Constructor
102
103 Upon construction, capacity will be zero.
104
105 @param limit The setting for @ref max_size.
106 */
107 explicit
108 basic_flat_buffer(std::size_t limit);
109
110 /** Constructor
111
112 Upon construction, capacity will be zero.
113
114 @param alloc The allocator to construct with.
115 */
116 explicit
117 basic_flat_buffer(Allocator const& alloc);
118
119 /** Constructor
120
121 Upon construction, capacity will be zero.
122
123 @param limit The setting for @ref max_size.
124
125 @param alloc The allocator to use.
126 */
127 basic_flat_buffer(
128 std::size_t limit, Allocator const& alloc);
129
130 /** Constructor
131
132 After the move, `*this` will have an empty output sequence.
133
134 @param other The object to move from. After the move,
135 The object's state will be as if constructed using
136 its current allocator and limit.
137 */
138 basic_flat_buffer(basic_flat_buffer&& other);
139
140 /** Constructor
141
142 After the move, `*this` will have an empty output sequence.
143
144 @param other The object to move from. After the move,
145 The object's state will be as if constructed using
146 its current allocator and limit.
147
148 @param alloc The allocator to use.
149 */
150 basic_flat_buffer(
151 basic_flat_buffer&& other, Allocator const& alloc);
152
153 /** Constructor
154
155 @param other The object to copy from.
156 */
157 basic_flat_buffer(basic_flat_buffer const& other);
158
159 /** Constructor
160
161 @param other The object to copy from.
162
163 @param alloc The allocator to use.
164 */
165 basic_flat_buffer(basic_flat_buffer const& other,
166 Allocator const& alloc);
167
168 /** Constructor
169
170 @param other The object to copy from.
171 */
172 template<class OtherAlloc>
173 basic_flat_buffer(
174 basic_flat_buffer<OtherAlloc> const& other);
175
176 /** Constructor
177
178 @param other The object to copy from.
179
180 @param alloc The allocator to use.
181 */
182 template<class OtherAlloc>
183 basic_flat_buffer(
184 basic_flat_buffer<OtherAlloc> const& other,
185 Allocator const& alloc);
186
187 /** Assignment
188
189 After the move, `*this` will have an empty output sequence.
190
191 @param other The object to move from. After the move,
192 the object's state will be as if constructed using
193 its current allocator and limit.
194 */
195 basic_flat_buffer&
196 operator=(basic_flat_buffer&& other);
197
198 /** Assignment
199
200 After the copy, `*this` will have an empty output sequence.
201
202 @param other The object to copy from.
203 */
204 basic_flat_buffer&
205 operator=(basic_flat_buffer const& other);
206
207 /** Copy assignment
208
209 After the copy, `*this` will have an empty output sequence.
210
211 @param other The object to copy from.
212 */
213 template<class OtherAlloc>
214 basic_flat_buffer&
215 operator=(basic_flat_buffer<OtherAlloc> const& other);
216
217 /// Returns a copy of the associated allocator.
218 allocator_type
219 get_allocator() const
220 {
221 return this->member();
222 }
223
224 /// Returns the size of the input sequence.
225 std::size_t
226 size() const
227 {
228 return dist(in_, out_);
229 }
230
231 /// Return the maximum sum of the input and output sequence sizes.
232 std::size_t
233 max_size() const
234 {
235 return max_;
236 }
237
238 /// Return the maximum sum of input and output sizes that can be held without an allocation.
239 std::size_t
240 capacity() const
241 {
242 return dist(begin_, end_);
243 }
244
245 /// Get a list of buffers that represent the input sequence.
246 const_buffers_type
247 data() const
248 {
249 return {in_, dist(in_, out_)};
250 }
251
252 /** Get a list of buffers that represent the output sequence, with the given size.
253
254 @throws std::length_error if `size() + n` exceeds `max_size()`.
255
256 @note All previous buffers sequences obtained from
257 calls to @ref data or @ref prepare are invalidated.
258 */
259 mutable_buffers_type
260 prepare(std::size_t n);
261
262 /** Move bytes from the output sequence to the input sequence.
263
264 @param n The number of bytes to move. If this is larger than
265 the number of bytes in the output sequences, then the entire
266 output sequences is moved.
267
268 @note All previous buffers sequences obtained from
269 calls to @ref data or @ref prepare are invalidated.
270 */
271 void
272 commit(std::size_t n)
273 {
274 out_ += (std::min)(n, dist(out_, last_));
275 }
276
277 /** Remove bytes from the input sequence.
278
279 If `n` is greater than the number of bytes in the input
280 sequence, all bytes in the input sequence are removed.
281
282 @note All previous buffers sequences obtained from
283 calls to @ref data or @ref prepare are invalidated.
284 */
285 void
286 consume(std::size_t n);
287
288 /** Reallocate the buffer to fit the input sequence.
289
290 @note All previous buffers sequences obtained from
291 calls to @ref data or @ref prepare are invalidated.
292 */
293 void
294 shrink_to_fit();
295
296 /// Exchange two flat buffers
297 template<class Alloc>
298 friend
299 void
300 swap(
301 basic_flat_buffer<Alloc>& lhs,
302 basic_flat_buffer<Alloc>& rhs);
303
304private:
305 void
306 reset();
307
308 template<class DynamicBuffer>
309 void
310 copy_from(DynamicBuffer const& other);
311
312 void
313 move_assign(basic_flat_buffer&, std::true_type);
314
315 void
316 move_assign(basic_flat_buffer&, std::false_type);
317
318 void
319 copy_assign(basic_flat_buffer const&, std::true_type);
320
321 void
322 copy_assign(basic_flat_buffer const&, std::false_type);
323
324 void
325 swap(basic_flat_buffer&);
326
327 void
328 swap(basic_flat_buffer&, std::true_type);
329
330 void
331 swap(basic_flat_buffer&, std::false_type);
332};
333
334using flat_buffer =
335 basic_flat_buffer<std::allocator<char>>;
336
337} // beast
338} // boost
339
340#include <boost/beast/core/impl/flat_buffer.ipp>
341
342#endif