diff options
Diffstat (limited to 'boost/beast/core/impl/buffers_suffix.hpp')
-rw-r--r-- | boost/beast/core/impl/buffers_suffix.hpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/boost/beast/core/impl/buffers_suffix.hpp b/boost/beast/core/impl/buffers_suffix.hpp new file mode 100644 index 0000000000..9822b4df70 --- /dev/null +++ b/boost/beast/core/impl/buffers_suffix.hpp @@ -0,0 +1,225 @@ +// +// Copyright (c) 2016-2019 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_IMPL_BUFFERS_SUFFIX_HPP +#define BOOST_BEAST_IMPL_BUFFERS_SUFFIX_HPP + +#include <boost/beast/core/buffer_traits.hpp> +#include <boost/beast/core/buffer_traits.hpp> +#include <boost/type_traits.hpp> +#include <algorithm> +#include <cstdint> +#include <iterator> +#include <type_traits> +#include <utility> + +namespace boost { +namespace beast { + +template<class Buffers> +class buffers_suffix<Buffers>::const_iterator +{ + friend class buffers_suffix<Buffers>; + + using iter_type = buffers_iterator_type<Buffers>; + + iter_type it_{}; + buffers_suffix const* b_ = nullptr; + +public: +#if BOOST_WORKAROUND(BOOST_MSVC, < 1910) + using value_type = typename std::conditional< + boost::is_convertible<typename + std::iterator_traits<iter_type>::value_type, + net::mutable_buffer>::value, + net::mutable_buffer, + net::const_buffer>::type; +#else + using value_type = buffers_type<Buffers>; +#endif + using pointer = value_type const*; + using reference = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = + std::bidirectional_iterator_tag; + + const_iterator() = default; + const_iterator( + const_iterator const& other) = default; + const_iterator& operator=( + const_iterator const& other) = default; + + bool + operator==(const_iterator const& other) const + { + return b_ == other.b_ && it_ == other.it_; + } + + bool + operator!=(const_iterator const& other) const + { + return !(*this == other); + } + + reference + operator*() const + { + if(it_ == b_->begin_) + return value_type(*it_) + b_->skip_; + return value_type(*it_); + } + + pointer + operator->() const = delete; + + const_iterator& + operator++() + { + ++it_; + return *this; + } + + const_iterator + operator++(int) + { + auto temp = *this; + ++(*this); + return temp; + } + + const_iterator& + operator--() + { + --it_; + return *this; + } + + const_iterator + operator--(int) + { + auto temp = *this; + --(*this); + return temp; + } + +private: + const_iterator( + buffers_suffix const& b, + iter_type it) + : it_(it) + , b_(&b) + { + } +}; + +//------------------------------------------------------------------------------ + +template<class Buffers> +buffers_suffix<Buffers>:: +buffers_suffix() + : begin_(net::buffer_sequence_begin(bs_)) +{ +} + +template<class Buffers> +buffers_suffix<Buffers>:: +buffers_suffix(buffers_suffix const& other) + : buffers_suffix(other, + std::distance<iter_type>( + net::buffer_sequence_begin( + other.bs_), other.begin_)) +{ +} + +template<class Buffers> +buffers_suffix<Buffers>:: +buffers_suffix(Buffers const& bs) + : bs_(bs) + , begin_(net::buffer_sequence_begin(bs_)) +{ + static_assert( + net::is_const_buffer_sequence<Buffers>::value || + net::is_mutable_buffer_sequence<Buffers>::value, + "BufferSequence type requirements not met"); +} + +template<class Buffers> +template<class... Args> +buffers_suffix<Buffers>:: +buffers_suffix(boost::in_place_init_t, Args&&... args) + : bs_(std::forward<Args>(args)...) + , begin_(net::buffer_sequence_begin(bs_)) +{ + static_assert(sizeof...(Args) > 0, + "Missing constructor arguments"); + static_assert( + std::is_constructible<Buffers, Args...>::value, + "Buffers not constructible from arguments"); +} + +template<class Buffers> +auto +buffers_suffix<Buffers>:: +operator=(buffers_suffix const& other) -> + buffers_suffix& +{ + auto const dist = std::distance<iter_type>( + net::buffer_sequence_begin(other.bs_), + other.begin_); + bs_ = other.bs_; + begin_ = std::next( + net::buffer_sequence_begin(bs_), dist); + skip_ = other.skip_; + return *this; +} + +template<class Buffers> +auto +buffers_suffix<Buffers>:: +begin() const -> + const_iterator +{ + return const_iterator{*this, begin_}; +} + +template<class Buffers> +auto +buffers_suffix<Buffers>:: +end() const -> + const_iterator +{ + return const_iterator{*this, + net::buffer_sequence_end(bs_)}; +} + +template<class Buffers> +void +buffers_suffix<Buffers>:: +consume(std::size_t amount) +{ + auto const end = + net::buffer_sequence_end(bs_); + for(;amount > 0 && begin_ != end; ++begin_) + { + auto const len = + buffer_bytes(*begin_) - skip_; + if(amount < len) + { + skip_ += amount; + break; + } + amount -= len; + skip_ = 0; + } +} + +} // beast +} // boost + +#endif |