]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/beast/core/multi_buffer.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / beast / core / multi_buffer.hpp
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_MULTI_BUFFER_HPP
11 #define BOOST_BEAST_MULTI_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 <boost/intrusive/list.hpp>
18 #include <iterator>
19 #include <limits>
20 #include <memory>
21 #include <type_traits>
22
23 namespace boost {
24 namespace beast {
25
26 /** A @b DynamicBuffer that uses multiple buffers internally.
27
28 The implementation uses a sequence of one or more character arrays
29 of varying sizes. Additional character array objects are appended to
30 the sequence to accommodate changes in the size of the character
31 sequence.
32
33 @note Meets the requirements of @b DynamicBuffer.
34
35 @tparam Allocator The allocator to use for managing memory.
36 */
37 template<class Allocator>
38 class basic_multi_buffer
39 #if ! BOOST_BEAST_DOXYGEN
40 : private detail::empty_base_optimization<
41 typename detail::allocator_traits<Allocator>::
42 template rebind_alloc<char>>
43 #endif
44 {
45 using base_alloc_type = typename
46 detail::allocator_traits<Allocator>::
47 template rebind_alloc<char>;
48
49 // Storage for the list of buffers representing the input
50 // and output sequences. The allocation for each element
51 // contains `element` followed by raw storage bytes.
52 class element;
53
54 using alloc_traits = detail::allocator_traits<base_alloc_type>;
55 using list_type = typename boost::intrusive::make_list<element,
56 boost::intrusive::constant_time_size<true>>::type;
57 using iter = typename list_type::iterator;
58 using const_iter = typename list_type::const_iterator;
59
60 using size_type = typename alloc_traits::size_type;
61 using const_buffer = boost::asio::const_buffer;
62 using mutable_buffer = boost::asio::mutable_buffer;
63
64 static_assert(std::is_base_of<std::bidirectional_iterator_tag,
65 typename std::iterator_traits<iter>::iterator_category>::value,
66 "BidirectionalIterator requirements not met");
67
68 static_assert(std::is_base_of<std::bidirectional_iterator_tag,
69 typename std::iterator_traits<const_iter>::iterator_category>::value,
70 "BidirectionalIterator requirements not met");
71
72 std::size_t max_ =
73 (std::numeric_limits<std::size_t>::max)();
74 list_type list_; // list of allocated buffers
75 iter out_; // element that contains out_pos_
76 size_type in_size_ = 0; // size of the input sequence
77 size_type in_pos_ = 0; // input offset in list_.front()
78 size_type out_pos_ = 0; // output offset in *out_
79 size_type out_end_ = 0; // output end offset in list_.back()
80
81 public:
82 /// The type of allocator used.
83 using allocator_type = Allocator;
84
85 #if BOOST_BEAST_DOXYGEN
86 /// The type used to represent the input sequence as a list of buffers.
87 using const_buffers_type = implementation_defined;
88
89 /// The type used to represent the output sequence as a list of buffers.
90 using mutable_buffers_type = implementation_defined;
91
92 #else
93 class const_buffers_type;
94
95 class mutable_buffers_type;
96
97 #endif
98
99 /// Destructor
100 ~basic_multi_buffer();
101
102 /** Constructor
103
104 Upon construction, capacity will be zero.
105 */
106 basic_multi_buffer();
107
108 /** Constructor.
109
110 @param limit The setting for @ref max_size.
111 */
112 explicit
113 basic_multi_buffer(std::size_t limit);
114
115 /** Constructor.
116
117 @param alloc The allocator to use.
118 */
119 explicit
120 basic_multi_buffer(Allocator const& alloc);
121
122 /** Constructor.
123
124 @param limit The setting for @ref max_size.
125
126 @param alloc The allocator to use.
127 */
128 basic_multi_buffer(
129 std::size_t limit, Allocator const& alloc);
130
131 /** Move constructor
132
133 After the move, `*this` will have an empty output sequence.
134
135 @param other The object to move from. After the move,
136 The object's state will be as if constructed using
137 its current allocator and limit.
138 */
139 basic_multi_buffer(basic_multi_buffer&& other);
140
141 /** Move constructor
142
143 After the move, `*this` will have an empty output sequence.
144
145 @param other The object to move from. After the move,
146 The object's state will be as if constructed using
147 its current allocator and limit.
148
149 @param alloc The allocator to use.
150 */
151 basic_multi_buffer(basic_multi_buffer&& other,
152 Allocator const& alloc);
153
154 /** Copy constructor.
155
156 @param other The object to copy from.
157 */
158 basic_multi_buffer(basic_multi_buffer const& other);
159
160 /** Copy constructor
161
162 @param other The object to copy from.
163
164 @param alloc The allocator to use.
165 */
166 basic_multi_buffer(basic_multi_buffer const& other,
167 Allocator const& alloc);
168
169 /** Copy constructor.
170
171 @param other The object to copy from.
172 */
173 template<class OtherAlloc>
174 basic_multi_buffer(basic_multi_buffer<
175 OtherAlloc> const& other);
176
177 /** Copy constructor.
178
179 @param other The object to copy from.
180
181 @param alloc The allocator to use.
182 */
183 template<class OtherAlloc>
184 basic_multi_buffer(basic_multi_buffer<
185 OtherAlloc> const& other, allocator_type const& alloc);
186
187 /** Move 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_multi_buffer&
196 operator=(basic_multi_buffer&& other);
197
198 /** Copy 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_multi_buffer& operator=(basic_multi_buffer const& other);
205
206 /** Copy assignment
207
208 After the copy, `*this` will have an empty output sequence.
209
210 @param other The object to copy from.
211 */
212 template<class OtherAlloc>
213 basic_multi_buffer& operator=(
214 basic_multi_buffer<OtherAlloc> const& other);
215
216 /// Returns a copy of the associated allocator.
217 allocator_type
218 get_allocator() const
219 {
220 return this->member();
221 }
222
223 /// Returns the size of the input sequence.
224 size_type
225 size() const
226 {
227 return in_size_;
228 }
229
230 /// Returns the permitted maximum sum of the sizes of the input and output sequence.
231 size_type
232 max_size() const
233 {
234 return max_;
235 }
236
237 /// Returns the maximum sum of the sizes of the input sequence and output sequence the buffer can hold without requiring reallocation.
238 std::size_t
239 capacity() const;
240
241 /** Get a list of buffers that represents the input sequence.
242
243 @note These buffers remain valid across subsequent calls to `prepare`.
244 */
245 const_buffers_type
246 data() const;
247
248 /** Get a list of buffers that represents the output sequence, with the given size.
249
250 @note Buffers representing the input sequence acquired prior to
251 this call remain valid.
252 */
253 mutable_buffers_type
254 prepare(size_type n);
255
256 /** Move bytes from the output sequence to the input sequence.
257
258 @note Buffers representing the input sequence acquired prior to
259 this call remain valid.
260 */
261 void
262 commit(size_type n);
263
264 /// Remove bytes from the input sequence.
265 void
266 consume(size_type n);
267
268 template<class Alloc>
269 friend
270 void
271 swap(
272 basic_multi_buffer<Alloc>& lhs,
273 basic_multi_buffer<Alloc>& rhs);
274
275 private:
276 template<class OtherAlloc>
277 friend class basic_multi_buffer;
278
279 void
280 delete_list();
281
282 void
283 reset();
284
285 template<class DynamicBuffer>
286 void
287 copy_from(DynamicBuffer const& other);
288
289 void
290 move_assign(basic_multi_buffer& other, std::false_type);
291
292 void
293 move_assign(basic_multi_buffer& other, std::true_type);
294
295 void
296 copy_assign(basic_multi_buffer const& other, std::false_type);
297
298 void
299 copy_assign(basic_multi_buffer const& other, std::true_type);
300
301 void
302 swap(basic_multi_buffer&);
303
304 void
305 swap(basic_multi_buffer&, std::true_type);
306
307 void
308 swap(basic_multi_buffer&, std::false_type);
309
310 void
311 debug_check() const;
312 };
313
314 /// A typical multi buffer
315 using multi_buffer = basic_multi_buffer<std::allocator<char>>;
316
317 } // beast
318 } // boost
319
320 #include <boost/beast/core/impl/multi_buffer.ipp>
321
322 #endif