diff options
Diffstat (limited to 'boost/beast/core/impl/buffers_cat.ipp')
-rw-r--r-- | boost/beast/core/impl/buffers_cat.ipp | 327 |
1 files changed, 100 insertions, 227 deletions
diff --git a/boost/beast/core/impl/buffers_cat.ipp b/boost/beast/core/impl/buffers_cat.ipp index d92d55233a..2e82e887fc 100644 --- a/boost/beast/core/impl/buffers_cat.ipp +++ b/boost/beast/core/impl/buffers_cat.ipp @@ -11,9 +11,9 @@ #define BOOST_BEAST_IMPL_BUFFERS_CAT_IPP #include <boost/beast/core/detail/type_traits.hpp> +#include <boost/beast/core/detail/variant.hpp> #include <boost/asio/buffer.hpp> #include <boost/throw_exception.hpp> -#include <array> #include <cstdint> #include <iterator> #include <new> @@ -27,38 +27,28 @@ namespace beast { template<class... Bn> class buffers_cat_view<Bn...>::const_iterator { - std::size_t n_; - std::tuple<Bn...> const* bn_; - std::array<char, detail::max_sizeof< - typename detail::buffer_sequence_iterator<Bn>::type...>()> buf_; + // VFALCO The logic to skip empty sequences fails + // if there is just one buffer in the list. + static_assert(sizeof...(Bn) >= 2, + "A minimum of two sequences are required"); - friend class buffers_cat_view<Bn...>; - - template<std::size_t I> - using C = std::integral_constant<std::size_t, I>; + struct past_end + { + operator bool() const noexcept + { + return true; + } + }; - template<std::size_t I> - using iter_t = typename detail::buffer_sequence_iterator< - typename std::tuple_element<I, std::tuple<Bn...>>::type>::type; + std::tuple<Bn...> const* bn_ = nullptr; + detail::variant<typename + detail::buffer_sequence_iterator<Bn>::type..., + past_end> it_; - template<std::size_t I> - iter_t<I>& - iter() - { - // type-pun - return *reinterpret_cast< - iter_t<I>*>(static_cast<void*>(buf_.data())); - } + friend class buffers_cat_view<Bn...>; template<std::size_t I> - iter_t<I> const& - iter() const - { - // type-pun - return *reinterpret_cast< - iter_t<I> const*>(static_cast< - void const*>(buf_.data())); - } + using C = std::integral_constant<std::size_t, I>; public: using value_type = typename @@ -69,12 +59,11 @@ public: using iterator_category = std::bidirectional_iterator_tag; - ~const_iterator(); - const_iterator(); - const_iterator(const_iterator&& other); - const_iterator(const_iterator const& other); - const_iterator& operator=(const_iterator&& other); - const_iterator& operator=(const_iterator const& other); + const_iterator() = default; + const_iterator(const_iterator&& other) = default; + const_iterator(const_iterator const& other) = default; + const_iterator& operator=(const_iterator&& other) = default; + const_iterator& operator=(const_iterator const& other) = default; bool operator==(const_iterator const& other) const; @@ -97,9 +86,11 @@ public: const_iterator operator++(int); + // deprecated const_iterator& operator--(); + // deprecated const_iterator operator--(int); @@ -107,13 +98,6 @@ private: const_iterator( std::tuple<Bn...> const& bn, bool at_end); - void - construct(C<sizeof...(Bn)> const&) - { - auto constexpr I = sizeof...(Bn); - n_ = I; - } - template<std::size_t I> void construct(C<I> const&) @@ -121,144 +105,90 @@ private: if(boost::asio::buffer_size( std::get<I>(*bn_)) != 0) { - n_ = I; - new(&buf_[0]) iter_t<I>{ + it_.template emplace<I+1>( boost::asio::buffer_sequence_begin( - std::get<I>(*bn_))}; + std::get<I>(*bn_))); return; } construct(C<I+1>{}); } void - rconstruct(C<0> const&) - { - auto constexpr I = 0; - if(boost::asio::buffer_size( - std::get<I>(*bn_)) != 0) - { - n_ = I; - new(&buf_[0]) iter_t<I>{ - boost::asio::buffer_sequence_end( - std::get<I>(*bn_))}; - return; - } - BOOST_THROW_EXCEPTION(std::logic_error{ - "invalid iterator"}); - } - - template<std::size_t I> - void - rconstruct(C<I> const&) + construct(C<sizeof...(Bn)-1> const&) { - if(boost::asio::buffer_size( - std::get<I>(*bn_)) != 0) - { - n_ = I; - new(&buf_[0]) iter_t<I>{ - boost::asio::buffer_sequence_end( - std::get<I>(*bn_))}; - return; - } - rconstruct(C<I-1>{}); + auto constexpr I = sizeof...(Bn)-1; + it_.template emplace<I+1>( + boost::asio::buffer_sequence_begin( + std::get<I>(*bn_))); } void - destroy(C<sizeof...(Bn)> const&) + construct(C<sizeof...(Bn)> const&) { - return; + // end + auto constexpr I = sizeof...(Bn); + it_.template emplace<I+1>(); } template<std::size_t I> void - destroy(C<I> const&) + next(C<I> const&) { - if(n_ == I) + if(boost::asio::buffer_size( + std::get<I>(*bn_)) != 0) { - using Iter = iter_t<I>; - iter<I>().~Iter(); + it_.template emplace<I+1>( + boost::asio::buffer_sequence_begin( + std::get<I>(*bn_))); return; } - destroy(C<I+1>{}); + next(C<I+1>{}); } void - move(const_iterator&&, - C<sizeof...(Bn)> const&) + next(C<sizeof...(Bn)> const&) { + // end + auto constexpr I = sizeof...(Bn); + it_.template emplace<I+1>(); } template<std::size_t I> void - move(const_iterator&& other, - C<I> const&) + prev(C<I> const&) { - if(n_ == I) + if(boost::asio::buffer_size( + std::get<I>(*bn_)) != 0) { - new(&buf_[0]) iter_t<I>{ - std::move(other.iter<I>())}; + it_.template emplace<I+1>( + boost::asio::buffer_sequence_end( + std::get<I>(*bn_))); return; } - move(std::move(other), C<I+1>{}); - } - - void - copy(const_iterator const&, - C<sizeof...(Bn)> const&) - { + prev(C<I-1>{}); } - template<std::size_t I> void - copy(const_iterator const& other, - C<I> const&) + prev(C<0> const&) { - if(n_ == I) - { - new(&buf_[0]) iter_t<I>{ - other.iter<I>()}; - return; - } - copy(other, C<I+1>{}); - } - - bool - equal(const_iterator const&, - C<sizeof...(Bn)> const&) const - { - return true; - } - - template<std::size_t I> - bool - equal(const_iterator const& other, - C<I> const&) const - { - if(n_ == I) - return iter<I>() == other.iter<I>(); - return equal(other, C<I+1>{}); - } - - [[noreturn]] - reference - dereference(C<sizeof...(Bn)> const&) const - { - BOOST_THROW_EXCEPTION(std::logic_error{ - "invalid iterator"}); + auto constexpr I = 0; + it_.template emplace<I+1>( + boost::asio::buffer_sequence_end( + std::get<I>(*bn_))); } template<std::size_t I> reference dereference(C<I> const&) const { - if(n_ == I) - return *iter<I>(); + if(it_.index() == I+1) + return *it_.template get<I+1>(); return dereference(C<I+1>{}); } [[noreturn]] - void - increment(C<sizeof...(Bn)> const&) + reference + dereference(C<sizeof...(Bn)> const&) const { BOOST_THROW_EXCEPTION(std::logic_error{ "invalid iterator"}); @@ -268,25 +198,31 @@ private: void increment(C<I> const&) { - if(n_ == I) + if(it_.index() == I+1) { - if(++iter<I>() != + if(++it_.template get<I+1>() != boost::asio::buffer_sequence_end( std::get<I>(*bn_))) return; - using Iter = iter_t<I>; - iter<I>().~Iter(); - return construct(C<I+1>{}); + return next(C<I+1>{}); } increment(C<I+1>{}); } + [[noreturn]] + void + increment(C<sizeof...(Bn)> const&) + { + BOOST_THROW_EXCEPTION(std::logic_error{ + "invalid iterator"}); + } + void decrement(C<sizeof...(Bn)> const&) { auto constexpr I = sizeof...(Bn); - if(n_ == I) - rconstruct(C<I-1>{}); + if(it_.index() == I+1) + prev(C<I-1>{}); decrement(C<I-1>{}); } @@ -294,19 +230,16 @@ private: void decrement(C<I> const&) { - if(n_ == I) + if(it_.index() == I+1) { - if(iter<I>() != + if(it_.template get<I+1>() != boost::asio::buffer_sequence_begin( std::get<I>(*bn_))) { - --iter<I>(); + --it_.template get<I+1>(); return; } - --n_; - using Iter = iter_t<I>; - iter<I>().~Iter(); - rconstruct(C<I-1>{}); + prev(C<I-1>{}); } decrement(C<I-1>{}); } @@ -315,11 +248,11 @@ private: decrement(C<0> const&) { auto constexpr I = 0; - if(iter<I>() != + if(it_.template get<I+1>() != boost::asio::buffer_sequence_begin( std::get<I>(*bn_))) { - --iter<I>(); + --it_.template get<I+1>(); return; } BOOST_THROW_EXCEPTION(std::logic_error{ @@ -331,97 +264,33 @@ private: template<class... Bn> buffers_cat_view<Bn...>:: -const_iterator::~const_iterator() -{ - destroy(C<0>{}); -} - -template<class... Bn> -buffers_cat_view<Bn...>:: -const_iterator::const_iterator() - : n_(sizeof...(Bn)) - , bn_(nullptr) -{ -} - -template<class... Bn> -buffers_cat_view<Bn...>:: -const_iterator::const_iterator( +const_iterator:: +const_iterator( std::tuple<Bn...> const& bn, bool at_end) : bn_(&bn) { - if(at_end) - n_ = sizeof...(Bn); - else + if(! at_end) construct(C<0>{}); -} - -template<class... Bn> -buffers_cat_view<Bn...>:: -const_iterator::const_iterator(const_iterator&& other) - : n_(other.n_) - , bn_(other.bn_) -{ - move(std::move(other), C<0>{}); -} - -template<class... Bn> -buffers_cat_view<Bn...>:: -const_iterator::const_iterator(const_iterator const& other) - : n_(other.n_) - , bn_(other.bn_) -{ - copy(other, C<0>{}); -} - -template<class... Bn> -auto -buffers_cat_view<Bn...>:: -const_iterator::operator=(const_iterator&& other) -> - const_iterator& -{ - if(&other == this) - return *this; - destroy(C<0>{}); - n_ = other.n_; - bn_ = other.bn_; - // VFALCO What about exceptions? - move(std::move(other), C<0>{}); - return *this; -} - -template<class... Bn> -auto -buffers_cat_view<Bn...>:: -const_iterator::operator=(const_iterator const& other) -> -const_iterator& -{ - if(&other == this) - return *this; - destroy(C<0>{}); - n_ = other.n_; - bn_ = other.bn_; - // VFALCO What about exceptions? - copy(other, C<0>{}); - return *this; + else + construct(C<sizeof...(Bn)>{}); } template<class... Bn> bool buffers_cat_view<Bn...>:: -const_iterator::operator==(const_iterator const& other) const +const_iterator:: +operator==(const_iterator const& other) const { if(bn_ != other.bn_) return false; - if(n_ != other.n_) - return false; - return equal(other, C<0>{}); + return it_ == other.it_; } template<class... Bn> auto buffers_cat_view<Bn...>:: -const_iterator::operator*() const -> +const_iterator:: +operator*() const -> reference { return dereference(C<0>{}); @@ -430,7 +299,8 @@ const_iterator::operator*() const -> template<class... Bn> auto buffers_cat_view<Bn...>:: -const_iterator::operator++() -> +const_iterator:: +operator++() -> const_iterator& { increment(C<0>{}); @@ -440,7 +310,8 @@ const_iterator::operator++() -> template<class... Bn> auto buffers_cat_view<Bn...>:: -const_iterator::operator++(int) -> +const_iterator:: +operator++(int) -> const_iterator { auto temp = *this; @@ -451,7 +322,8 @@ const_iterator::operator++(int) -> template<class... Bn> auto buffers_cat_view<Bn...>:: -const_iterator::operator--() -> +const_iterator:: +operator--() -> const_iterator& { decrement(C<sizeof...(Bn)>{}); @@ -461,7 +333,8 @@ const_iterator::operator--() -> template<class... Bn> auto buffers_cat_view<Bn...>:: -const_iterator::operator--(int) -> +const_iterator:: +operator--(int) -> const_iterator { auto temp = *this; |