Fix buffers_cat uninitialized warning

Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
Damian Jarek
2018-11-22 15:10:47 +01:00
committed by Vinnie Falco
parent 13322fa4bb
commit b9eb1d75d9
3 changed files with 86 additions and 76 deletions

View File

@@ -6,6 +6,7 @@ Version 191:
* Use lean_tuple in buffers_cat * Use lean_tuple in buffers_cat
* Use lean_tuple in bind_handler, bind_front_handler * Use lean_tuple in bind_handler, bind_front_handler
* Use mp11 in detail::variant * Use mp11 in detail::variant
* Fix buffers_cat uninitialized warning
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -24,23 +24,38 @@
namespace boost { namespace boost {
namespace beast { namespace beast {
template<class... Bn> namespace detail {
class buffers_cat_view<Bn...>::const_iterator
{
// 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");
struct buffers_cat_view_iterator_base
{
struct past_end struct past_end
{ {
char unused = 0; // make g++8 happy char unused = 0; // make g++8 happy
boost::asio::mutable_buffer
operator*() const
{
BOOST_THROW_EXCEPTION(std::logic_error{
"invalid iterator"});
}
operator bool() const noexcept operator bool() const noexcept
{ {
return true; return true;
} }
}; };
};
} // detail
template<class... Bn>
class buffers_cat_view<Bn...>::const_iterator
: private detail::buffers_cat_view_iterator_base
{
// 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");
detail::lean_tuple<Bn...> const* bn_ = nullptr; detail::lean_tuple<Bn...> const* bn_ = nullptr;
detail::variant<typename detail::variant<typename
@@ -100,38 +115,6 @@ private:
const_iterator( const_iterator(
detail::lean_tuple<Bn...> const& bn, bool at_end); detail::lean_tuple<Bn...> const& bn, bool at_end);
template<std::size_t I>
void
construct(C<I> const&)
{
if(boost::asio::buffer_size(
detail::get<I>(*bn_)) != 0)
{
it_.template emplace<I+1>(
boost::asio::buffer_sequence_begin(
detail::get<I>(*bn_)));
return;
}
construct(C<I+1>{});
}
void
construct(C<sizeof...(Bn)-1> const&)
{
auto constexpr I = sizeof...(Bn)-1;
it_.template emplace<I+1>(
boost::asio::buffer_sequence_begin(
detail::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> template<std::size_t I>
void void
next(C<I> const&) next(C<I> const&)
@@ -179,45 +162,54 @@ private:
detail::get<I>(*bn_))); detail::get<I>(*bn_)));
} }
template<std::size_t I> struct dereference
reference
dereference(C<I> const&) const
{ {
if(it_.index() == I+1) const_iterator const& self;
return *it_.template get<I+1>();
return dereference(C<I+1>{});
}
[[noreturn]] [[noreturn]]
reference reference
dereference(C<sizeof...(Bn)> const&) const operator()(mp11::mp_size_t<0>)
{
BOOST_THROW_EXCEPTION(std::logic_error{
"invalid iterator"});
}
template<std::size_t I>
void
increment(C<I> const&)
{
if(it_.index() == I+1)
{ {
if(++it_.template get<I+1>() != BOOST_THROW_EXCEPTION(std::logic_error{
boost::asio::buffer_sequence_end( "invalid iterator"});
detail::get<I>(*bn_)))
return;
return next(C<I+1>{});
} }
increment(C<I+1>{});
}
[[noreturn]] template<class I>
void reference operator()(I)
increment(C<sizeof...(Bn)> const&) {
return *self.it_.template get<I::value>();
}
};
struct increment
{ {
BOOST_THROW_EXCEPTION(std::logic_error{ const_iterator& self;
"invalid iterator"});
} [[noreturn]]
void
operator()(mp11::mp_size_t<0>)
{
BOOST_THROW_EXCEPTION(std::logic_error{
"invalid iterator"});
}
[[noreturn]]
void
operator()(mp11::mp_size_t<sizeof...(Bn) + 1>)
{
(*this)(mp11::mp_size_t<0>{});
}
template<std::size_t I>
void
operator()(mp11::mp_size_t<I>)
{
auto& it = self.it_.template get<I>();
if (++it == boost::asio::buffer_sequence_end(
detail::get<I - 1>(*self.bn_)))
self.next(C<I>());
}
};
void void
decrement(C<sizeof...(Bn)> const&) decrement(C<sizeof...(Bn)> const&)
@@ -272,9 +264,9 @@ const_iterator(
: bn_(&bn) : bn_(&bn)
{ {
if(! at_end) if(! at_end)
construct(C<0>{}); next(C<0>{});
else else
construct(C<sizeof...(Bn)>{}); next(C<sizeof...(Bn)>{});
} }
template<class... Bn> template<class... Bn>
@@ -306,7 +298,10 @@ const_iterator::
operator*() const -> operator*() const ->
reference reference
{ {
return dereference(C<0>{}); return mp11::mp_with_index<
sizeof...(Bn) + 2>(
it_.index(),
dereference{*this});
} }
template<class... Bn> template<class... Bn>
@@ -316,7 +311,10 @@ const_iterator::
operator++() -> operator++() ->
const_iterator& const_iterator&
{ {
increment(C<0>{}); mp11::mp_with_index<
sizeof...(Bn) + 2>(
it_.index(),
increment{*this});
return *this; return *this;
} }

View File

@@ -256,6 +256,16 @@ public:
buffers_cat(buffers_prefix(i, buffers), cb)); buffers_cat(buffers_prefix(i, buffers), cb));
} }
void
test_empty_buffer_sequences()
{
using boost::asio::buffer_size;
using boost::asio::const_buffer;
std::vector<const_buffer> v1;
std::vector<const_buffer> v2;
BEAST_EXPECT(buffer_size(buffers_cat(v1, v2)) == 0);
}
void run() override void run() override
{ {
using boost::asio::const_buffer; using boost::asio::const_buffer;
@@ -301,6 +311,7 @@ public:
testIterators(); testIterators();
testGccWarning1(); testGccWarning1();
testGccWarning2(); testGccWarning2();
test_empty_buffer_sequences();
} }
}; };