summaryrefslogtreecommitdiff
path: root/boost/beast/core/flat_buffer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/core/flat_buffer.hpp')
-rw-r--r--boost/beast/core/flat_buffer.hpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/boost/beast/core/flat_buffer.hpp b/boost/beast/core/flat_buffer.hpp
new file mode 100644
index 0000000000..0ccd16bc64
--- /dev/null
+++ b/boost/beast/core/flat_buffer.hpp
@@ -0,0 +1,342 @@
+//
+// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// Official repository: https://github.com/boostorg/beast
+//
+
+#ifndef BOOST_BEAST_FLAT_BUFFER_HPP
+#define BOOST_BEAST_FLAT_BUFFER_HPP
+
+#include <boost/beast/core/detail/config.hpp>
+#include <boost/beast/core/detail/allocator.hpp>
+#include <boost/beast/core/detail/empty_base_optimization.hpp>
+#include <boost/asio/buffer.hpp>
+#include <limits>
+#include <memory>
+
+namespace boost {
+namespace beast {
+
+/** A linear dynamic buffer.
+
+ Objects of this type meet the requirements of @b DynamicBuffer
+ and offer additional invariants:
+
+ @li Buffer sequences returned by @ref data and @ref prepare
+ will always be of length one.
+
+ @li A configurable maximum buffer size may be set upon
+ construction. Attempts to exceed the buffer size will throw
+ `std::length_error`.
+
+ Upon construction, a maximum size for the buffer may be
+ specified. If this limit is exceeded, the `std::length_error`
+ exception will be thrown.
+
+ @note This class is designed for use with algorithms that
+ take dynamic buffers as parameters, and are optimized
+ for the case where the input sequence or output sequence
+ is stored in a single contiguous buffer.
+*/
+template<class Allocator>
+class basic_flat_buffer
+#if ! BOOST_BEAST_DOXYGEN
+ : private detail::empty_base_optimization<
+ typename detail::allocator_traits<Allocator>::
+ template rebind_alloc<char>>
+#endif
+{
+ enum
+ {
+ min_size = 512
+ };
+
+ template<class OtherAlloc>
+ friend class basic_flat_buffer;
+
+ using base_alloc_type = typename
+ detail::allocator_traits<Allocator>::
+ template rebind_alloc<char>;
+
+ using alloc_traits =
+ detail::allocator_traits<base_alloc_type>;
+
+ static
+ inline
+ std::size_t
+ dist(char const* first, char const* last)
+ {
+ return static_cast<std::size_t>(last - first);
+ }
+
+ char* begin_;
+ char* in_;
+ char* out_;
+ char* last_;
+ char* end_;
+ std::size_t max_;
+
+public:
+ /// The type of allocator used.
+ using allocator_type = Allocator;
+
+ /// The type used to represent the input sequence as a list of buffers.
+ using const_buffers_type = boost::asio::mutable_buffer;
+
+ /// The type used to represent the output sequence as a list of buffers.
+ using mutable_buffers_type = boost::asio::mutable_buffer;
+
+ /// Destructor
+ ~basic_flat_buffer();
+
+ /** Constructor
+
+ Upon construction, capacity will be zero.
+ */
+ basic_flat_buffer();
+
+ /** Constructor
+
+ Upon construction, capacity will be zero.
+
+ @param limit The setting for @ref max_size.
+ */
+ explicit
+ basic_flat_buffer(std::size_t limit);
+
+ /** Constructor
+
+ Upon construction, capacity will be zero.
+
+ @param alloc The allocator to construct with.
+ */
+ explicit
+ basic_flat_buffer(Allocator const& alloc);
+
+ /** Constructor
+
+ Upon construction, capacity will be zero.
+
+ @param limit The setting for @ref max_size.
+
+ @param alloc The allocator to use.
+ */
+ basic_flat_buffer(
+ std::size_t limit, Allocator const& alloc);
+
+ /** Constructor
+
+ After the move, `*this` will have an empty output sequence.
+
+ @param other The object to move from. After the move,
+ The object's state will be as if constructed using
+ its current allocator and limit.
+ */
+ basic_flat_buffer(basic_flat_buffer&& other);
+
+ /** Constructor
+
+ After the move, `*this` will have an empty output sequence.
+
+ @param other The object to move from. After the move,
+ The object's state will be as if constructed using
+ its current allocator and limit.
+
+ @param alloc The allocator to use.
+ */
+ basic_flat_buffer(
+ basic_flat_buffer&& other, Allocator const& alloc);
+
+ /** Constructor
+
+ @param other The object to copy from.
+ */
+ basic_flat_buffer(basic_flat_buffer const& other);
+
+ /** Constructor
+
+ @param other The object to copy from.
+
+ @param alloc The allocator to use.
+ */
+ basic_flat_buffer(basic_flat_buffer const& other,
+ Allocator const& alloc);
+
+ /** Constructor
+
+ @param other The object to copy from.
+ */
+ template<class OtherAlloc>
+ basic_flat_buffer(
+ basic_flat_buffer<OtherAlloc> const& other);
+
+ /** Constructor
+
+ @param other The object to copy from.
+
+ @param alloc The allocator to use.
+ */
+ template<class OtherAlloc>
+ basic_flat_buffer(
+ basic_flat_buffer<OtherAlloc> const& other,
+ Allocator const& alloc);
+
+ /** Assignment
+
+ After the move, `*this` will have an empty output sequence.
+
+ @param other The object to move from. After the move,
+ the object's state will be as if constructed using
+ its current allocator and limit.
+ */
+ basic_flat_buffer&
+ operator=(basic_flat_buffer&& other);
+
+ /** Assignment
+
+ After the copy, `*this` will have an empty output sequence.
+
+ @param other The object to copy from.
+ */
+ basic_flat_buffer&
+ operator=(basic_flat_buffer const& other);
+
+ /** Copy assignment
+
+ After the copy, `*this` will have an empty output sequence.
+
+ @param other The object to copy from.
+ */
+ template<class OtherAlloc>
+ basic_flat_buffer&
+ operator=(basic_flat_buffer<OtherAlloc> const& other);
+
+ /// Returns a copy of the associated allocator.
+ allocator_type
+ get_allocator() const
+ {
+ return this->member();
+ }
+
+ /// Returns the size of the input sequence.
+ std::size_t
+ size() const
+ {
+ return dist(in_, out_);
+ }
+
+ /// Return the maximum sum of the input and output sequence sizes.
+ std::size_t
+ max_size() const
+ {
+ return max_;
+ }
+
+ /// Return the maximum sum of input and output sizes that can be held without an allocation.
+ std::size_t
+ capacity() const
+ {
+ return dist(begin_, end_);
+ }
+
+ /// Get a list of buffers that represent the input sequence.
+ const_buffers_type
+ data() const
+ {
+ return {in_, dist(in_, out_)};
+ }
+
+ /** Get a list of buffers that represent the output sequence, with the given size.
+
+ @throws std::length_error if `size() + n` exceeds `max_size()`.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ mutable_buffers_type
+ prepare(std::size_t n);
+
+ /** Move bytes from the output sequence to the input sequence.
+
+ @param n The number of bytes to move. If this is larger than
+ the number of bytes in the output sequences, then the entire
+ output sequences is moved.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ commit(std::size_t n)
+ {
+ out_ += (std::min)(n, dist(out_, last_));
+ }
+
+ /** Remove bytes from the input sequence.
+
+ If `n` is greater than the number of bytes in the input
+ sequence, all bytes in the input sequence are removed.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ consume(std::size_t n);
+
+ /** Reallocate the buffer to fit the input sequence.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ shrink_to_fit();
+
+ /// Exchange two flat buffers
+ template<class Alloc>
+ friend
+ void
+ swap(
+ basic_flat_buffer<Alloc>& lhs,
+ basic_flat_buffer<Alloc>& rhs);
+
+private:
+ void
+ reset();
+
+ template<class DynamicBuffer>
+ void
+ copy_from(DynamicBuffer const& other);
+
+ void
+ move_assign(basic_flat_buffer&, std::true_type);
+
+ void
+ move_assign(basic_flat_buffer&, std::false_type);
+
+ void
+ copy_assign(basic_flat_buffer const&, std::true_type);
+
+ void
+ copy_assign(basic_flat_buffer const&, std::false_type);
+
+ void
+ swap(basic_flat_buffer&);
+
+ void
+ swap(basic_flat_buffer&, std::true_type);
+
+ void
+ swap(basic_flat_buffer&, std::false_type);
+};
+
+using flat_buffer =
+ basic_flat_buffer<std::allocator<char>>;
+
+} // beast
+} // boost
+
+#include <boost/beast/core/impl/flat_buffer.ipp>
+
+#endif