diff options
Diffstat (limited to 'boost/beast/core/buffers_prefix.hpp')
-rw-r--r-- | boost/beast/core/buffers_prefix.hpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/boost/beast/core/buffers_prefix.hpp b/boost/beast/core/buffers_prefix.hpp new file mode 100644 index 0000000000..67d58b5c58 --- /dev/null +++ b/boost/beast/core/buffers_prefix.hpp @@ -0,0 +1,237 @@ +// +// 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_BUFFERS_PREFIX_HPP +#define BOOST_BEAST_BUFFERS_PREFIX_HPP + +#include <boost/beast/core/detail/config.hpp> +#include <boost/beast/core/type_traits.hpp> +#include <boost/beast/core/detail/in_place_init.hpp> +#include <boost/asio/buffer.hpp> +#include <cstdint> +#include <type_traits> + +namespace boost { +namespace beast { + +/** A buffer sequence adapter that shortens the sequence size. + + The class adapts a buffer sequence to efficiently represent + a shorter subset of the original list of buffers starting + with the first byte of the original sequence. + + @tparam BufferSequence The buffer sequence to adapt. +*/ +template<class BufferSequence> +class buffers_prefix_view +{ + using buffers_type = typename + std::decay<BufferSequence>::type; + + using iter_type = typename + detail::buffer_sequence_iterator<buffers_type>::type; + + BufferSequence bs_; + std::size_t size_; + iter_type end_; + + template<class Deduced> + buffers_prefix_view( + Deduced&& other, std::size_t dist) + : bs_(std::forward<Deduced>(other).bs_) + , size_(other.size_) + , end_(std::next(bs_.begin(), dist)) + { + } + + void + setup(std::size_t size); + +public: + /// The type for each element in the list of buffers. + using value_type = typename std::conditional< + std::is_convertible<typename + std::iterator_traits<iter_type>::value_type, + boost::asio::mutable_buffer>::value, + boost::asio::mutable_buffer, + boost::asio::const_buffer>::type; + +#if BOOST_BEAST_DOXYGEN + /// A bidirectional iterator type that may be used to read elements. + using const_iterator = implementation_defined; + +#else + class const_iterator; + +#endif + + /// Move constructor. + buffers_prefix_view(buffers_prefix_view&&); + + /// Copy constructor. + buffers_prefix_view(buffers_prefix_view const&); + + /// Move assignment. + buffers_prefix_view& operator=(buffers_prefix_view&&); + + /// Copy assignment. + buffers_prefix_view& operator=(buffers_prefix_view const&); + + /** Construct a buffer sequence prefix. + + @param size The maximum number of bytes in the prefix. + If this is larger than the size of passed, buffers, + the resulting sequence will represent the entire + input sequence. + + @param buffers The buffer sequence to adapt. A copy of + the sequence will be made, but ownership of the underlying + memory is not transferred. + */ + buffers_prefix_view( + std::size_t size, + BufferSequence const& buffers); + + /** Construct a buffer sequence prefix in-place. + + @param size The maximum number of bytes in the prefix. + If this is larger than the size of passed, buffers, + the resulting sequence will represent the entire + input sequence. + + @param args Arguments forwarded to the contained buffers constructor. + */ + template<class... Args> + buffers_prefix_view( + std::size_t size, + boost::in_place_init_t, + Args&&... args); + + /// Get a bidirectional iterator to the first element. + const_iterator + begin() const; + + /// Get a bidirectional iterator to one past the last element. + const_iterator + end() const; +}; + +/** Returns a prefix of a constant buffer. + + The returned buffer points to the same memory as the + passed buffer, but with a size that is equal to or less + than the size of the original buffer. + + @param size The size of the returned buffer. + + @param buffer The buffer to shorten. The underlying + memory is not modified. + + @return A new buffer that points to the first `size` + bytes of the original buffer. +*/ +inline +boost::asio::const_buffer +buffers_prefix(std::size_t size, + boost::asio::const_buffer buffer) +{ + return {buffer.data(), + (std::min)(size, buffer.size())}; +} + +/** Returns a prefix of a mutable buffer. + + The returned buffer points to the same memory as the + passed buffer, but with a size that is equal to or less + than the size of the original buffer. + + @param size The size of the returned buffer. + + @param buffer The buffer to shorten. The underlying + memory is not modified. + + @return A new buffer that points to the first `size` bytes + of the original buffer. +*/ +inline +boost::asio::mutable_buffer +buffers_prefix(std::size_t size, + boost::asio::mutable_buffer buffer) +{ + return {buffer.data(), + (std::min)(size, buffer.size())}; +} + +/** Returns a prefix of a buffer sequence. + + This function returns a new buffer sequence which when iterated, + presents a shorter subset of the original list of buffers starting + with the first byte of the original sequence. + + @param size The maximum number of bytes in the wrapped + sequence. If this is larger than the size of passed, + buffers, the resulting sequence will represent the + entire input sequence. + + @param buffers An instance of @b ConstBufferSequence or + @b MutableBufferSequence to adapt. A copy of the sequence + will be made, but ownership of the underlying memory is + not transferred. +*/ +template<class BufferSequence> +#if BOOST_BEAST_DOXYGEN +buffers_prefix_view<BufferSequence> +#else +inline +typename std::enable_if< + ! std::is_same<BufferSequence, + boost::asio::const_buffer>::value && + ! std::is_same<BufferSequence, + boost::asio::mutable_buffer>::value, + buffers_prefix_view<BufferSequence>>::type +#endif +buffers_prefix(std::size_t size, BufferSequence const& buffers) +{ + static_assert( + boost::asio::is_const_buffer_sequence<BufferSequence>::value || + boost::asio::is_mutable_buffer_sequence<BufferSequence>::value, + "BufferSequence requirements not met"); + return buffers_prefix_view<BufferSequence>(size, buffers); +} + +/** Returns the first buffer in a buffer sequence + + This returns the first buffer in the buffer sequence. + If the buffer sequence is an empty range, the returned + buffer will have a zero buffer size. + + @param buffers The buffer sequence. If the sequence is + mutable, the returned buffer sequence will also be mutable. + Otherwise, the returned buffer sequence will be constant. +*/ +template<class BufferSequence> +typename std::conditional< + boost::asio::is_mutable_buffer_sequence<BufferSequence>::value, + boost::asio::mutable_buffer, + boost::asio::const_buffer>::type +buffers_front(BufferSequence const& buffers) +{ + auto const first = + boost::asio::buffer_sequence_begin(buffers); + if(first == boost::asio::buffer_sequence_end(buffers)) + return {}; + return *first; +} + +} // beast +} // boost + +#include <boost/beast/core/impl/buffers_prefix.ipp> + +#endif |