Back to home page

EIC code displayed by LXR

 
 

    


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