forked from boostorg/beast
Use variant in buffers_cat_view
This commit is contained in:
@@ -5,6 +5,7 @@ Version 146:
|
|||||||
* Documentation tidying
|
* Documentation tidying
|
||||||
* Fix typo in examples documentation
|
* Fix typo in examples documentation
|
||||||
* Add detail::aligned_union and tidy up
|
* Add detail::aligned_union and tidy up
|
||||||
|
* Use variant in buffers_cat_view
|
||||||
|
|
||||||
API Changes:
|
API Changes:
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ class variant
|
|||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
using type = typename std::tuple_element<
|
using type = typename std::tuple_element<
|
||||||
I , std::tuple<TN...>>::type;
|
I, std::tuple<TN...>>::type;
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
using C = std::integral_constant<std::size_t, I>;
|
using C = std::integral_constant<std::size_t, I>;
|
||||||
@@ -46,10 +46,17 @@ public:
|
|||||||
|
|
||||||
~variant()
|
~variant()
|
||||||
{
|
{
|
||||||
if(i_)
|
|
||||||
destroy(C<0>{});
|
destroy(C<0>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
operator==(variant const& other) const
|
||||||
|
{
|
||||||
|
if(i_ != other.i_)
|
||||||
|
return false;
|
||||||
|
return equal(other, C<0>{});
|
||||||
|
}
|
||||||
|
|
||||||
// 0 = empty
|
// 0 = empty
|
||||||
unsigned char
|
unsigned char
|
||||||
index() const
|
index() const
|
||||||
@@ -61,6 +68,7 @@ public:
|
|||||||
variant(variant&& other)
|
variant(variant&& other)
|
||||||
{
|
{
|
||||||
i_ = other.move(&buf_, C<0>{});
|
i_ = other.move(&buf_, C<0>{});
|
||||||
|
other.i_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
variant(variant const& other)
|
variant(variant const& other)
|
||||||
@@ -71,17 +79,22 @@ public:
|
|||||||
// moved-from object becomes empty
|
// moved-from object becomes empty
|
||||||
variant& operator=(variant&& other)
|
variant& operator=(variant&& other)
|
||||||
{
|
{
|
||||||
if(i_ != 0)
|
if(this != &other)
|
||||||
|
{
|
||||||
destroy(C<0>{});
|
destroy(C<0>{});
|
||||||
i_ = other.move(&buf_, C<0>{});
|
i_ = other.move(&buf_, C<0>{});
|
||||||
|
other.i_ = 0;
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
variant& operator=(variant const& other)
|
variant& operator=(variant const& other)
|
||||||
{
|
{
|
||||||
if(i_ != 0)
|
if(this != &other)
|
||||||
|
{
|
||||||
destroy(C<0>{});
|
destroy(C<0>{});
|
||||||
i_ = other.copy(&buf_, C<0>{});
|
i_ = other.copy(&buf_, C<0>{});
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +102,6 @@ public:
|
|||||||
void
|
void
|
||||||
emplace(Args&&... args)
|
emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
if(i_ != 0)
|
|
||||||
destroy(C<0>{});
|
destroy(C<0>{});
|
||||||
new(&buf_) type<I-1>(
|
new(&buf_) type<I-1>(
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
@@ -117,72 +129,135 @@ public:
|
|||||||
void
|
void
|
||||||
reset()
|
reset()
|
||||||
{
|
{
|
||||||
if(i_ == 0)
|
|
||||||
return;
|
|
||||||
destroy(C<0>{});
|
destroy(C<0>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void
|
||||||
destroy(C<sizeof...(TN)>)
|
destroy(C<0>)
|
||||||
{
|
{
|
||||||
|
auto const I = 0;
|
||||||
|
if(i_ == I)
|
||||||
return;
|
return;
|
||||||
|
destroy(C<I+1>{});
|
||||||
|
i_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
void
|
void
|
||||||
destroy(C<I>)
|
destroy(C<I>)
|
||||||
{
|
{
|
||||||
if(i_ == I+1)
|
if(i_ == I)
|
||||||
{
|
{
|
||||||
using T = type<I>;
|
using T = type<I-1>;
|
||||||
get<I+1>().~T();
|
get<I>().~T();
|
||||||
i_ = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
destroy(C<I+1>{});
|
destroy(C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
void
|
||||||
move(void*, C<sizeof...(TN)>)
|
destroy(C<sizeof...(TN)>)
|
||||||
{
|
{
|
||||||
return 0;
|
auto const I = sizeof...(TN);
|
||||||
|
BOOST_ASSERT(i_ == I);
|
||||||
|
using T = type<I-1>;
|
||||||
|
get<I>().~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char
|
||||||
|
move(void* dest, C<0>)
|
||||||
|
{
|
||||||
|
auto const I = 0;
|
||||||
|
if(i_ == I)
|
||||||
|
return I;
|
||||||
|
return move(dest, C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
unsigned char
|
unsigned char
|
||||||
move(void* dest, C<I>)
|
move(void* dest, C<I>)
|
||||||
{
|
{
|
||||||
if(i_ == I+1)
|
if(i_ == I)
|
||||||
{
|
{
|
||||||
using T = type<I>;
|
using T = type<I-1>;
|
||||||
new(dest) T{std::move(get<I+1>())};
|
new(dest) T(std::move(get<I>()));
|
||||||
get<I+1>().~T();
|
get<I>().~T();
|
||||||
i_ = 0;
|
return I;
|
||||||
return I+1;
|
|
||||||
}
|
}
|
||||||
return move(dest, C<I+1>{});
|
return move(dest, C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
copy(void*, C<sizeof...(TN)>) const
|
move(void* dest, C<sizeof...(TN)>)
|
||||||
{
|
{
|
||||||
return 0;
|
auto const I = sizeof...(TN);
|
||||||
|
BOOST_ASSERT(i_ == I);
|
||||||
|
using T = type<I-1>;
|
||||||
|
new(dest) T(std::move(get<I>()));
|
||||||
|
get<I>().~T();
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char
|
||||||
|
copy(void* dest, C<0>) const
|
||||||
|
{
|
||||||
|
auto const I = 0;
|
||||||
|
if(i_ == I)
|
||||||
|
return I;
|
||||||
|
return copy(dest, C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
unsigned char
|
unsigned char
|
||||||
copy(void* dest, C<I>) const
|
copy(void* dest, C<I>) const
|
||||||
{
|
{
|
||||||
if(i_ == I+1)
|
if(i_ == I)
|
||||||
{
|
{
|
||||||
using T = type<I>;
|
using T = type<I-1>;
|
||||||
auto const& t = get<I+1>();
|
auto const& t = get<I>();
|
||||||
new(dest) T{t};
|
new(dest) T(t);
|
||||||
return I+1;
|
return I;
|
||||||
}
|
}
|
||||||
return copy(dest, C<I+1>{});
|
return copy(dest, C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char
|
||||||
|
copy(void* dest, C<sizeof...(TN)>) const
|
||||||
|
{
|
||||||
|
auto const I = sizeof...(TN);
|
||||||
|
BOOST_ASSERT(i_ == I);
|
||||||
|
using T = type<I-1>;
|
||||||
|
auto const& t = get<I>();
|
||||||
|
new(dest) T(t);
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
equal(variant const& other, C<0>) const
|
||||||
|
{
|
||||||
|
auto constexpr I = 0;
|
||||||
|
if(i_ == I)
|
||||||
|
return true;
|
||||||
|
return equal(other, C<I+1>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t I>
|
||||||
|
bool
|
||||||
|
equal(variant const& other, C<I>) const
|
||||||
|
{
|
||||||
|
if(i_ == I)
|
||||||
|
return get<I>() == other.get<I>();
|
||||||
|
return equal(other, C<I+1>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
equal(variant const& other, C<sizeof...(TN)>) const
|
||||||
|
{
|
||||||
|
auto constexpr I = sizeof...(TN);
|
||||||
|
BOOST_ASSERT(i_ == I);
|
||||||
|
return get<I>() == other.get<I>();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
@@ -11,9 +11,9 @@
|
|||||||
#define BOOST_BEAST_IMPL_BUFFERS_CAT_IPP
|
#define BOOST_BEAST_IMPL_BUFFERS_CAT_IPP
|
||||||
|
|
||||||
#include <boost/beast/core/detail/type_traits.hpp>
|
#include <boost/beast/core/detail/type_traits.hpp>
|
||||||
|
#include <boost/beast/core/detail/variant.hpp>
|
||||||
#include <boost/asio/buffer.hpp>
|
#include <boost/asio/buffer.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <new>
|
#include <new>
|
||||||
@@ -27,39 +27,29 @@ namespace beast {
|
|||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
class buffers_cat_view<Bn...>::const_iterator
|
class buffers_cat_view<Bn...>::const_iterator
|
||||||
{
|
{
|
||||||
std::size_t n_;
|
// VFALCO The logic to skip empty sequences fails
|
||||||
std::tuple<Bn...> const* bn_;
|
// if there is just one buffer in the list.
|
||||||
std::array<char, detail::max_sizeof<
|
static_assert(sizeof...(Bn) >= 2,
|
||||||
typename detail::buffer_sequence_iterator<Bn>::type...>()> buf_;
|
"A minimum of two sequences are required");
|
||||||
|
|
||||||
|
struct past_end
|
||||||
|
{
|
||||||
|
operator bool() const noexcept
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::tuple<Bn...> const* bn_ = nullptr;
|
||||||
|
detail::variant<typename
|
||||||
|
detail::buffer_sequence_iterator<Bn>::type...,
|
||||||
|
past_end> it_;
|
||||||
|
|
||||||
friend class buffers_cat_view<Bn...>;
|
friend class buffers_cat_view<Bn...>;
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
using C = std::integral_constant<std::size_t, I>;
|
using C = std::integral_constant<std::size_t, I>;
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
using iter_t = typename detail::buffer_sequence_iterator<
|
|
||||||
typename std::tuple_element<I, std::tuple<Bn...>>::type>::type;
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
iter_t<I>&
|
|
||||||
iter()
|
|
||||||
{
|
|
||||||
// type-pun
|
|
||||||
return *reinterpret_cast<
|
|
||||||
iter_t<I>*>(static_cast<void*>(buf_.data()));
|
|
||||||
}
|
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = typename
|
using value_type = typename
|
||||||
detail::common_buffers_type<Bn...>::type;
|
detail::common_buffers_type<Bn...>::type;
|
||||||
@@ -69,12 +59,11 @@ public:
|
|||||||
using iterator_category =
|
using iterator_category =
|
||||||
std::bidirectional_iterator_tag;
|
std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
~const_iterator();
|
const_iterator() = default;
|
||||||
const_iterator();
|
const_iterator(const_iterator&& other) = default;
|
||||||
const_iterator(const_iterator&& other);
|
const_iterator(const_iterator const& other) = default;
|
||||||
const_iterator(const_iterator const& other);
|
const_iterator& operator=(const_iterator&& other) = default;
|
||||||
const_iterator& operator=(const_iterator&& other);
|
const_iterator& operator=(const_iterator const& other) = default;
|
||||||
const_iterator& operator=(const_iterator const& other);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator==(const_iterator const& other) const;
|
operator==(const_iterator const& other) const;
|
||||||
@@ -97,9 +86,11 @@ public:
|
|||||||
const_iterator
|
const_iterator
|
||||||
operator++(int);
|
operator++(int);
|
||||||
|
|
||||||
|
// deprecated
|
||||||
const_iterator&
|
const_iterator&
|
||||||
operator--();
|
operator--();
|
||||||
|
|
||||||
|
// deprecated
|
||||||
const_iterator
|
const_iterator
|
||||||
operator--(int);
|
operator--(int);
|
||||||
|
|
||||||
@@ -107,13 +98,6 @@ private:
|
|||||||
const_iterator(
|
const_iterator(
|
||||||
std::tuple<Bn...> const& bn, bool at_end);
|
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>
|
template<std::size_t I>
|
||||||
void
|
void
|
||||||
construct(C<I> const&)
|
construct(C<I> const&)
|
||||||
@@ -121,122 +105,85 @@ private:
|
|||||||
if(boost::asio::buffer_size(
|
if(boost::asio::buffer_size(
|
||||||
std::get<I>(*bn_)) != 0)
|
std::get<I>(*bn_)) != 0)
|
||||||
{
|
{
|
||||||
n_ = I;
|
it_.template emplace<I+1>(
|
||||||
new(&buf_[0]) iter_t<I>{
|
|
||||||
boost::asio::buffer_sequence_begin(
|
boost::asio::buffer_sequence_begin(
|
||||||
std::get<I>(*bn_))};
|
std::get<I>(*bn_)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
construct(C<I+1>{});
|
construct(C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rconstruct(C<0> const&)
|
construct(C<sizeof...(Bn)-1> const&)
|
||||||
|
{
|
||||||
|
auto constexpr I = sizeof...(Bn)-1;
|
||||||
|
it_.template emplace<I+1>(
|
||||||
|
boost::asio::buffer_sequence_begin(
|
||||||
|
std::get<I>(*bn_)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
construct(C<sizeof...(Bn)> const&)
|
||||||
|
{
|
||||||
|
// end
|
||||||
|
auto constexpr I = sizeof...(Bn);
|
||||||
|
it_.template emplace<I+1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t I>
|
||||||
|
void
|
||||||
|
next(C<I> const&)
|
||||||
|
{
|
||||||
|
if(boost::asio::buffer_size(
|
||||||
|
std::get<I>(*bn_)) != 0)
|
||||||
|
{
|
||||||
|
it_.template emplace<I+1>(
|
||||||
|
boost::asio::buffer_sequence_begin(
|
||||||
|
std::get<I>(*bn_)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next(C<I+1>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
next(C<sizeof...(Bn)> const&)
|
||||||
|
{
|
||||||
|
// end
|
||||||
|
auto constexpr I = sizeof...(Bn);
|
||||||
|
it_.template emplace<I+1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t I>
|
||||||
|
void
|
||||||
|
prev(C<I> const&)
|
||||||
|
{
|
||||||
|
if(boost::asio::buffer_size(
|
||||||
|
std::get<I>(*bn_)) != 0)
|
||||||
|
{
|
||||||
|
it_.template emplace<I+1>(
|
||||||
|
boost::asio::buffer_sequence_end(
|
||||||
|
std::get<I>(*bn_)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev(C<I-1>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prev(C<0> const&)
|
||||||
{
|
{
|
||||||
auto constexpr I = 0;
|
auto constexpr I = 0;
|
||||||
if(boost::asio::buffer_size(
|
it_.template emplace<I+1>(
|
||||||
std::get<I>(*bn_)) != 0)
|
|
||||||
{
|
|
||||||
n_ = I;
|
|
||||||
new(&buf_[0]) iter_t<I>{
|
|
||||||
boost::asio::buffer_sequence_end(
|
boost::asio::buffer_sequence_end(
|
||||||
std::get<I>(*bn_))};
|
std::get<I>(*bn_)));
|
||||||
return;
|
|
||||||
}
|
|
||||||
BOOST_THROW_EXCEPTION(std::logic_error{
|
|
||||||
"invalid iterator"});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
void
|
reference
|
||||||
rconstruct(C<I> const&)
|
dereference(C<I> const&) const
|
||||||
{
|
{
|
||||||
if(boost::asio::buffer_size(
|
if(it_.index() == I+1)
|
||||||
std::get<I>(*bn_)) != 0)
|
return *it_.template get<I+1>();
|
||||||
{
|
return dereference(C<I+1>{});
|
||||||
n_ = I;
|
|
||||||
new(&buf_[0]) iter_t<I>{
|
|
||||||
boost::asio::buffer_sequence_end(
|
|
||||||
std::get<I>(*bn_))};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rconstruct(C<I-1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy(C<sizeof...(Bn)> const&)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
void
|
|
||||||
destroy(C<I> const&)
|
|
||||||
{
|
|
||||||
if(n_ == I)
|
|
||||||
{
|
|
||||||
using Iter = iter_t<I>;
|
|
||||||
iter<I>().~Iter();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
destroy(C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
move(const_iterator&&,
|
|
||||||
C<sizeof...(Bn)> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
void
|
|
||||||
move(const_iterator&& other,
|
|
||||||
C<I> const&)
|
|
||||||
{
|
|
||||||
if(n_ == I)
|
|
||||||
{
|
|
||||||
new(&buf_[0]) iter_t<I>{
|
|
||||||
std::move(other.iter<I>())};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
move(std::move(other), C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
copy(const_iterator const&,
|
|
||||||
C<sizeof...(Bn)> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
void
|
|
||||||
copy(const_iterator const& other,
|
|
||||||
C<I> 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]]
|
[[noreturn]]
|
||||||
@@ -248,12 +195,18 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
reference
|
void
|
||||||
dereference(C<I> const&) const
|
increment(C<I> const&)
|
||||||
{
|
{
|
||||||
if(n_ == I)
|
if(it_.index() == I+1)
|
||||||
return *iter<I>();
|
{
|
||||||
return dereference(C<I+1>{});
|
if(++it_.template get<I+1>() !=
|
||||||
|
boost::asio::buffer_sequence_end(
|
||||||
|
std::get<I>(*bn_)))
|
||||||
|
return;
|
||||||
|
return next(C<I+1>{});
|
||||||
|
}
|
||||||
|
increment(C<I+1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
@@ -264,29 +217,12 @@ private:
|
|||||||
"invalid iterator"});
|
"invalid iterator"});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
void
|
|
||||||
increment(C<I> const&)
|
|
||||||
{
|
|
||||||
if(n_ == I)
|
|
||||||
{
|
|
||||||
if(++iter<I>() !=
|
|
||||||
boost::asio::buffer_sequence_end(
|
|
||||||
std::get<I>(*bn_)))
|
|
||||||
return;
|
|
||||||
using Iter = iter_t<I>;
|
|
||||||
iter<I>().~Iter();
|
|
||||||
return construct(C<I+1>{});
|
|
||||||
}
|
|
||||||
increment(C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
decrement(C<sizeof...(Bn)> const&)
|
decrement(C<sizeof...(Bn)> const&)
|
||||||
{
|
{
|
||||||
auto constexpr I = sizeof...(Bn);
|
auto constexpr I = sizeof...(Bn);
|
||||||
if(n_ == I)
|
if(it_.index() == I+1)
|
||||||
rconstruct(C<I-1>{});
|
prev(C<I-1>{});
|
||||||
decrement(C<I-1>{});
|
decrement(C<I-1>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,19 +230,16 @@ private:
|
|||||||
void
|
void
|
||||||
decrement(C<I> const&)
|
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(
|
boost::asio::buffer_sequence_begin(
|
||||||
std::get<I>(*bn_)))
|
std::get<I>(*bn_)))
|
||||||
{
|
{
|
||||||
--iter<I>();
|
--it_.template get<I+1>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
--n_;
|
prev(C<I-1>{});
|
||||||
using Iter = iter_t<I>;
|
|
||||||
iter<I>().~Iter();
|
|
||||||
rconstruct(C<I-1>{});
|
|
||||||
}
|
}
|
||||||
decrement(C<I-1>{});
|
decrement(C<I-1>{});
|
||||||
}
|
}
|
||||||
@@ -315,11 +248,11 @@ private:
|
|||||||
decrement(C<0> const&)
|
decrement(C<0> const&)
|
||||||
{
|
{
|
||||||
auto constexpr I = 0;
|
auto constexpr I = 0;
|
||||||
if(iter<I>() !=
|
if(it_.template get<I+1>() !=
|
||||||
boost::asio::buffer_sequence_begin(
|
boost::asio::buffer_sequence_begin(
|
||||||
std::get<I>(*bn_)))
|
std::get<I>(*bn_)))
|
||||||
{
|
{
|
||||||
--iter<I>();
|
--it_.template get<I+1>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BOOST_THROW_EXCEPTION(std::logic_error{
|
BOOST_THROW_EXCEPTION(std::logic_error{
|
||||||
@@ -331,97 +264,33 @@ private:
|
|||||||
|
|
||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::~const_iterator()
|
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(
|
|
||||||
std::tuple<Bn...> const& bn, bool at_end)
|
std::tuple<Bn...> const& bn, bool at_end)
|
||||||
: bn_(&bn)
|
: bn_(&bn)
|
||||||
{
|
{
|
||||||
if(at_end)
|
if(! at_end)
|
||||||
n_ = sizeof...(Bn);
|
|
||||||
else
|
|
||||||
construct(C<0>{});
|
construct(C<0>{});
|
||||||
}
|
else
|
||||||
|
construct(C<sizeof...(Bn)>{});
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
bool
|
bool
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator==(const_iterator const& other) const
|
const_iterator::
|
||||||
|
operator==(const_iterator const& other) const
|
||||||
{
|
{
|
||||||
if(bn_ != other.bn_)
|
if(bn_ != other.bn_)
|
||||||
return false;
|
return false;
|
||||||
if(n_ != other.n_)
|
return it_ == other.it_;
|
||||||
return false;
|
|
||||||
return equal(other, C<0>{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
auto
|
auto
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator*() const ->
|
const_iterator::
|
||||||
|
operator*() const ->
|
||||||
reference
|
reference
|
||||||
{
|
{
|
||||||
return dereference(C<0>{});
|
return dereference(C<0>{});
|
||||||
@@ -430,7 +299,8 @@ const_iterator::operator*() const ->
|
|||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
auto
|
auto
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator++() ->
|
const_iterator::
|
||||||
|
operator++() ->
|
||||||
const_iterator&
|
const_iterator&
|
||||||
{
|
{
|
||||||
increment(C<0>{});
|
increment(C<0>{});
|
||||||
@@ -440,7 +310,8 @@ const_iterator::operator++() ->
|
|||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
auto
|
auto
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator++(int) ->
|
const_iterator::
|
||||||
|
operator++(int) ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
auto temp = *this;
|
auto temp = *this;
|
||||||
@@ -451,7 +322,8 @@ const_iterator::operator++(int) ->
|
|||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
auto
|
auto
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator--() ->
|
const_iterator::
|
||||||
|
operator--() ->
|
||||||
const_iterator&
|
const_iterator&
|
||||||
{
|
{
|
||||||
decrement(C<sizeof...(Bn)>{});
|
decrement(C<sizeof...(Bn)>{});
|
||||||
@@ -461,7 +333,8 @@ const_iterator::operator--() ->
|
|||||||
template<class... Bn>
|
template<class... Bn>
|
||||||
auto
|
auto
|
||||||
buffers_cat_view<Bn...>::
|
buffers_cat_view<Bn...>::
|
||||||
const_iterator::operator--(int) ->
|
const_iterator::
|
||||||
|
operator--(int) ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
auto temp = *this;
|
auto temp = *this;
|
||||||
|
Reference in New Issue
Block a user