|
||||
File indexing completed on 2025-01-18 09:29:28
0001 // 0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // Official repository: https://github.com/boostorg/beast 0008 // 0009 0010 #ifndef BOOST_BEAST_FLAT_BUFFER_HPP 0011 #define BOOST_BEAST_FLAT_BUFFER_HPP 0012 0013 #include <boost/beast/core/detail/config.hpp> 0014 #include <boost/beast/core/detail/allocator.hpp> 0015 #include <boost/asio/buffer.hpp> 0016 #include <boost/core/empty_value.hpp> 0017 #include <limits> 0018 #include <memory> 0019 #include <type_traits> 0020 0021 namespace boost { 0022 namespace beast { 0023 0024 /** A dynamic buffer providing buffer sequences of length one. 0025 0026 A dynamic buffer encapsulates memory storage that may be 0027 automatically resized as required, where the memory is 0028 divided into two regions: readable bytes followed by 0029 writable bytes. These memory regions are internal to 0030 the dynamic buffer, but direct access to the elements 0031 is provided to permit them to be efficiently used with 0032 I/O operations. 0033 0034 Objects of this type meet the requirements of <em>DynamicBuffer</em> 0035 and have the following additional properties: 0036 0037 @li A mutable buffer sequence representing the readable 0038 bytes is returned by @ref data when `this` is non-const. 0039 0040 @li A configurable maximum buffer size may be set upon 0041 construction. Attempts to exceed the buffer size will throw 0042 `std::length_error`. 0043 0044 @li Buffer sequences representing the readable and writable 0045 bytes, returned by @ref data and @ref prepare, will have 0046 length one. 0047 0048 Upon construction, a maximum size for the buffer may be 0049 specified. If this limit is exceeded, the `std::length_error` 0050 exception will be thrown. 0051 0052 @note This class is designed for use with algorithms that 0053 take dynamic buffers as parameters, and are optimized 0054 for the case where the input sequence or output sequence 0055 is stored in a single contiguous buffer. 0056 */ 0057 template<class Allocator> 0058 class basic_flat_buffer 0059 #if ! BOOST_BEAST_DOXYGEN 0060 : private boost::empty_value< 0061 typename detail::allocator_traits<Allocator>:: 0062 template rebind_alloc<char>> 0063 #endif 0064 { 0065 template<class OtherAlloc> 0066 friend class basic_flat_buffer; 0067 0068 using base_alloc_type = typename 0069 detail::allocator_traits<Allocator>:: 0070 template rebind_alloc<char>; 0071 0072 static bool constexpr default_nothrow = 0073 std::is_nothrow_default_constructible<Allocator>::value; 0074 0075 using alloc_traits = 0076 beast::detail::allocator_traits<base_alloc_type>; 0077 0078 using pocma = typename 0079 alloc_traits::propagate_on_container_move_assignment; 0080 0081 using pocca = typename 0082 alloc_traits::propagate_on_container_copy_assignment; 0083 0084 static 0085 std::size_t 0086 dist(char const* first, char const* last) noexcept 0087 { 0088 return static_cast<std::size_t>(last - first); 0089 } 0090 0091 char* begin_; 0092 char* in_; 0093 char* out_; 0094 char* last_; 0095 char* end_; 0096 std::size_t max_; 0097 0098 public: 0099 /// The type of allocator used. 0100 using allocator_type = Allocator; 0101 0102 /// Destructor 0103 ~basic_flat_buffer(); 0104 0105 /** Constructor 0106 0107 After construction, @ref capacity will return zero, and 0108 @ref max_size will return the largest value which may 0109 be passed to the allocator's `allocate` function. 0110 */ 0111 basic_flat_buffer() noexcept(default_nothrow); 0112 0113 /** Constructor 0114 0115 After construction, @ref capacity will return zero, and 0116 @ref max_size will return the specified value of `limit`. 0117 0118 @param limit The desired maximum size. 0119 */ 0120 explicit 0121 basic_flat_buffer( 0122 std::size_t limit) noexcept(default_nothrow); 0123 0124 /** Constructor 0125 0126 After construction, @ref capacity will return zero, and 0127 @ref max_size will return the largest value which may 0128 be passed to the allocator's `allocate` function. 0129 0130 @param alloc The allocator to use for the object. 0131 0132 @esafe 0133 0134 No-throw guarantee. 0135 */ 0136 explicit 0137 basic_flat_buffer(Allocator const& alloc) noexcept; 0138 0139 /** Constructor 0140 0141 After construction, @ref capacity will return zero, and 0142 @ref max_size will return the specified value of `limit`. 0143 0144 @param limit The desired maximum size. 0145 0146 @param alloc The allocator to use for the object. 0147 0148 @esafe 0149 0150 No-throw guarantee. 0151 */ 0152 basic_flat_buffer( 0153 std::size_t limit, 0154 Allocator const& alloc) noexcept; 0155 0156 /** Move Constructor 0157 0158 The container is constructed with the contents of `other` 0159 using move semantics. The maximum size will be the same 0160 as the moved-from object. 0161 0162 Buffer sequences previously obtained from `other` using 0163 @ref data or @ref prepare remain valid after the move. 0164 0165 @param other The object to move from. After the move, the 0166 moved-from object will have zero capacity, zero readable 0167 bytes, and zero writable bytes. 0168 0169 @esafe 0170 0171 No-throw guarantee. 0172 */ 0173 basic_flat_buffer(basic_flat_buffer&& other) noexcept; 0174 0175 /** Move Constructor 0176 0177 Using `alloc` as the allocator for the new container, the 0178 contents of `other` are moved. If `alloc != other.get_allocator()`, 0179 this results in a copy. The maximum size will be the same 0180 as the moved-from object. 0181 0182 Buffer sequences previously obtained from `other` using 0183 @ref data or @ref prepare become invalid after the move. 0184 0185 @param other The object to move from. After the move, 0186 the moved-from object will have zero capacity, zero readable 0187 bytes, and zero writable bytes. 0188 0189 @param alloc The allocator to use for the object. 0190 0191 @throws std::length_error if `other.size()` exceeds the 0192 maximum allocation size of `alloc`. 0193 */ 0194 basic_flat_buffer( 0195 basic_flat_buffer&& other, 0196 Allocator const& alloc); 0197 0198 /** Copy Constructor 0199 0200 This container is constructed with the contents of `other` 0201 using copy semantics. The maximum size will be the same 0202 as the copied object. 0203 0204 @param other The object to copy from. 0205 0206 @throws std::length_error if `other.size()` exceeds the 0207 maximum allocation size of the allocator. 0208 */ 0209 basic_flat_buffer(basic_flat_buffer const& other); 0210 0211 /** Copy Constructor 0212 0213 This container is constructed with the contents of `other` 0214 using copy semantics and the specified allocator. The maximum 0215 size will be the same as the copied object. 0216 0217 @param other The object to copy from. 0218 0219 @param alloc The allocator to use for the object. 0220 0221 @throws std::length_error if `other.size()` exceeds the 0222 maximum allocation size of `alloc`. 0223 */ 0224 basic_flat_buffer( 0225 basic_flat_buffer const& other, 0226 Allocator const& alloc); 0227 0228 /** Copy Constructor 0229 0230 This container is constructed with the contents of `other` 0231 using copy semantics. The maximum size will be the same 0232 as the copied object. 0233 0234 @param other The object to copy from. 0235 0236 @throws std::length_error if `other.size()` exceeds the 0237 maximum allocation size of the allocator. 0238 */ 0239 template<class OtherAlloc> 0240 basic_flat_buffer( 0241 basic_flat_buffer<OtherAlloc> const& other) 0242 noexcept(default_nothrow); 0243 0244 /** Copy Constructor 0245 0246 This container is constructed with the contents of `other` 0247 using copy semantics. The maximum size will be the same 0248 as the copied object. 0249 0250 @param other The object to copy from. 0251 0252 @param alloc The allocator to use for the object. 0253 0254 @throws std::length_error if `other.size()` exceeds the 0255 maximum allocation size of `alloc`. 0256 */ 0257 template<class OtherAlloc> 0258 basic_flat_buffer( 0259 basic_flat_buffer<OtherAlloc> const& other, 0260 Allocator const& alloc); 0261 0262 /** Move Assignment 0263 0264 The container is assigned with the contents of `other` 0265 using move semantics. The maximum size will be the same 0266 as the moved-from object. 0267 0268 Buffer sequences previously obtained from `other` using 0269 @ref data or @ref prepare remain valid after the move. 0270 0271 @param other The object to move from. After the move, 0272 the moved-from object will have zero capacity, zero readable 0273 bytes, and zero writable bytes. 0274 0275 @esafe 0276 0277 No-throw guarantee. 0278 */ 0279 basic_flat_buffer& 0280 operator=(basic_flat_buffer&& other) noexcept; 0281 0282 /** Copy Assignment 0283 0284 The container is assigned with the contents of `other` 0285 using copy semantics. The maximum size will be the same 0286 as the copied object. 0287 0288 After the copy, `this` will have zero writable bytes. 0289 0290 @param other The object to copy from. 0291 0292 @throws std::length_error if `other.size()` exceeds the 0293 maximum allocation size of the allocator. 0294 */ 0295 basic_flat_buffer& 0296 operator=(basic_flat_buffer const& other); 0297 0298 /** Copy assignment 0299 0300 The container is assigned with the contents of `other` 0301 using copy semantics. The maximum size will be the same 0302 as the copied object. 0303 0304 After the copy, `this` will have zero writable bytes. 0305 0306 @param other The object to copy from. 0307 0308 @throws std::length_error if `other.size()` exceeds the 0309 maximum allocation size of the allocator. 0310 */ 0311 template<class OtherAlloc> 0312 basic_flat_buffer& 0313 operator=(basic_flat_buffer<OtherAlloc> const& other); 0314 0315 /// Returns a copy of the allocator used. 0316 allocator_type 0317 get_allocator() const 0318 { 0319 return this->get(); 0320 } 0321 0322 /** Set the maximum allowed capacity 0323 0324 This function changes the currently configured upper limit 0325 on capacity to the specified value. 0326 0327 @param n The maximum number of bytes ever allowed for capacity. 0328 0329 @esafe 0330 0331 No-throw guarantee. 0332 */ 0333 void 0334 max_size(std::size_t n) noexcept 0335 { 0336 max_ = n; 0337 } 0338 0339 /** Guarantee a minimum capacity 0340 0341 This function adjusts the internal storage (if necessary) 0342 to guarantee space for at least `n` bytes. 0343 0344 Buffer sequences previously obtained using @ref data or 0345 @ref prepare become invalid. 0346 0347 @param n The minimum number of byte for the new capacity. 0348 If this value is greater than the maximum size, then the 0349 maximum size will be adjusted upwards to this value. 0350 0351 @esafe 0352 0353 Basic guarantee. 0354 0355 @throws std::length_error if n is larger than the maximum 0356 allocation size of the allocator. 0357 */ 0358 void 0359 reserve(std::size_t n); 0360 0361 /** Request the removal of unused capacity. 0362 0363 This function attempts to reduce @ref capacity() 0364 to @ref size(), which may not succeed. 0365 0366 @esafe 0367 0368 No-throw guarantee. 0369 */ 0370 void 0371 shrink_to_fit() noexcept; 0372 0373 /** Set the size of the readable and writable bytes to zero. 0374 0375 This clears the buffer without changing capacity. 0376 Buffer sequences previously obtained using @ref data or 0377 @ref prepare become invalid. 0378 0379 @esafe 0380 0381 No-throw guarantee. 0382 */ 0383 void 0384 clear() noexcept; 0385 0386 /// Exchange two dynamic buffers 0387 template<class Alloc> 0388 friend 0389 void 0390 swap( 0391 basic_flat_buffer<Alloc>&, 0392 basic_flat_buffer<Alloc>&); 0393 0394 //-------------------------------------------------------------------------- 0395 0396 /// The ConstBufferSequence used to represent the readable bytes. 0397 using const_buffers_type = net::const_buffer; 0398 0399 /// The MutableBufferSequence used to represent the writable bytes. 0400 using mutable_buffers_type = net::mutable_buffer; 0401 0402 /// Returns the number of readable bytes. 0403 std::size_t 0404 size() const noexcept 0405 { 0406 return dist(in_, out_); 0407 } 0408 0409 /// Return the maximum number of bytes, both readable and writable, that can ever be held. 0410 std::size_t 0411 max_size() const noexcept 0412 { 0413 return max_; 0414 } 0415 0416 /// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation. 0417 std::size_t 0418 capacity() const noexcept 0419 { 0420 return dist(begin_, end_); 0421 } 0422 0423 /// Returns a constant buffer sequence representing the readable bytes 0424 const_buffers_type 0425 data() const noexcept 0426 { 0427 return {in_, dist(in_, out_)}; 0428 } 0429 0430 /// Returns a constant buffer sequence representing the readable bytes 0431 const_buffers_type 0432 cdata() const noexcept 0433 { 0434 return data(); 0435 } 0436 0437 /// Returns a mutable buffer sequence representing the readable bytes 0438 mutable_buffers_type 0439 data() noexcept 0440 { 0441 return {in_, dist(in_, out_)}; 0442 } 0443 0444 /** Returns a mutable buffer sequence representing writable bytes. 0445 0446 Returns a mutable buffer sequence representing the writable 0447 bytes containing exactly `n` bytes of storage. Memory may be 0448 reallocated as needed. 0449 0450 All buffers sequences previously obtained using 0451 @ref data or @ref prepare become invalid. 0452 0453 @param n The desired number of bytes in the returned buffer 0454 sequence. 0455 0456 @throws std::length_error if `size() + n` exceeds either 0457 `max_size()` or the allocator's maximum allocation size. 0458 0459 @esafe 0460 0461 Strong guarantee. 0462 */ 0463 mutable_buffers_type 0464 prepare(std::size_t n); 0465 0466 /** Append writable bytes to the readable bytes. 0467 0468 Appends n bytes from the start of the writable bytes to the 0469 end of the readable bytes. The remainder of the writable bytes 0470 are discarded. If n is greater than the number of writable 0471 bytes, all writable bytes are appended to the readable bytes. 0472 0473 All buffers sequences previously obtained using 0474 @ref data or @ref prepare become invalid. 0475 0476 @param n The number of bytes to append. If this number 0477 is greater than the number of writable bytes, all 0478 writable bytes are appended. 0479 0480 @esafe 0481 0482 No-throw guarantee. 0483 */ 0484 void 0485 commit(std::size_t n) noexcept 0486 { 0487 out_ += (std::min)(n, dist(out_, last_)); 0488 } 0489 0490 /** Remove bytes from beginning of the readable bytes. 0491 0492 Removes n bytes from the beginning of the readable bytes. 0493 0494 All buffers sequences previously obtained using 0495 @ref data or @ref prepare become invalid. 0496 0497 @param n The number of bytes to remove. If this number 0498 is greater than the number of readable bytes, all 0499 readable bytes are removed. 0500 0501 @esafe 0502 0503 No-throw guarantee. 0504 */ 0505 void 0506 consume(std::size_t n) noexcept; 0507 0508 private: 0509 template<class OtherAlloc> 0510 void copy_from(basic_flat_buffer<OtherAlloc> const& other); 0511 void move_assign(basic_flat_buffer&, std::true_type); 0512 void move_assign(basic_flat_buffer&, std::false_type); 0513 void copy_assign(basic_flat_buffer const&, std::true_type); 0514 void copy_assign(basic_flat_buffer const&, std::false_type); 0515 void swap(basic_flat_buffer&); 0516 void swap(basic_flat_buffer&, std::true_type); 0517 void swap(basic_flat_buffer&, std::false_type); 0518 char* alloc(std::size_t n); 0519 }; 0520 0521 /// A flat buffer which uses the default allocator. 0522 using flat_buffer = 0523 basic_flat_buffer<std::allocator<char>>; 0524 0525 } // beast 0526 } // boost 0527 0528 #include <boost/beast/core/impl/flat_buffer.hpp> 0529 0530 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |