From c1d7a83af2aa5a2ab4b884fb53d4123cf2ece625 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 14 Dec 2018 07:21:17 -0800 Subject: [PATCH] buffers_cat fixes and coverage: * Fix operator== for default constructed iterators * More tests and code coverage --- CHANGELOG.md | 1 + include/boost/beast/core/detail/variant.hpp | 1 - include/boost/beast/core/impl/buffers_cat.hpp | 5 +- test/beast/core/buffers_cat.cpp | 59 ++++++++++++++ test/beast/core/buffers_prefix.cpp | 79 +++++++++++-------- 5 files changed, 107 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e216bdf4..9d1e5c22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Version 200 * Don't include OpenSSL for core snippets * Tidy up msvc-14 workaround in multi_buffer +* buffers_cat fixes and coverage -------------------------------------------------------------------------------- diff --git a/include/boost/beast/core/detail/variant.hpp b/include/boost/beast/core/detail/variant.hpp index 02347ae6..835a4310 100644 --- a/include/boost/beast/core/detail/variant.hpp +++ b/include/boost/beast/core/detail/variant.hpp @@ -18,7 +18,6 @@ namespace boost { namespace beast { namespace detail { - // This simple variant gets the job done without // causing too much trouble with template depth: // diff --git a/include/boost/beast/core/impl/buffers_cat.hpp b/include/boost/beast/core/impl/buffers_cat.hpp index bd762bf7..758da311 100644 --- a/include/boost/beast/core/impl/buffers_cat.hpp +++ b/include/boost/beast/core/impl/buffers_cat.hpp @@ -170,6 +170,7 @@ private: reference operator()(mp11::mp_size_t<0>) { + // Dereferencing a default-constructed iterator BOOST_THROW_EXCEPTION(std::logic_error{ "invalid iterator"}); } @@ -279,11 +280,11 @@ operator==(const_iterator const& other) const (bn_ == nullptr) ? ( other.bn_ == nullptr || - other.it_.index() == sizeof...(Bn) + other.it_.index() == sizeof...(Bn) + 1 ):( (other.bn_ == nullptr) ? ( - it_.index() == sizeof...(Bn) + it_.index() == sizeof...(Bn) + 1 ): ( bn_ == other.bn_ && it_ == other.it_ diff --git a/test/beast/core/buffers_cat.cpp b/test/beast/core/buffers_cat.cpp index e0b33d45..0d5e4eba 100644 --- a/test/beast/core/buffers_cat.cpp +++ b/test/beast/core/buffers_cat.cpp @@ -215,6 +215,64 @@ public: decltype(bs)::const_iterator it; decltype(bs2)::const_iterator it2; BEAST_EXPECT(it == it2); + + // decrement begin() should throw + try + { + --bs.begin(); + fail(); + } + catch(std::logic_error const&) + { + pass(); + } + catch(...) + { + fail(); + } + } + + + void + testDefaultIterators() + { + // default ctor is one past the end + char c[2]; + auto bs = buffers_cat( + net::const_buffer(&c[0], 1), + net::const_buffer(&c[1], 1)); + decltype(bs)::const_iterator it; + BEAST_EXPECT(bs.end() == it); + BEAST_EXPECT(it == bs.end()); + decltype(bs)::const_iterator it2; + BEAST_EXPECT(it == it2); + BEAST_EXPECT(it2 == it); + it = bs.end(); + it2 = bs.end(); + BEAST_EXPECT(it == it2); + BEAST_EXPECT(it2 == it); + decltype(bs)::const_iterator it3(it2); + BEAST_EXPECT(it3 == it2); + it = bs.begin(); + BEAST_EXPECT(it != it3); + it = it3; + BEAST_EXPECT(it == it3); + + // dereferencing default iterator should throw + try + { + it = {}; + *it; + fail(); + } + catch(std::logic_error const&) + { + pass(); + } + catch(...) + { + fail(); + } } void @@ -309,6 +367,7 @@ public: testBufferCat(); testIterators(); + testDefaultIterators(); testGccWarning1(); testGccWarning2(); test_empty_buffer_sequences(); diff --git a/test/beast/core/buffers_prefix.cpp b/test/beast/core/buffers_prefix.cpp index 9da26c04..6971ad4d 100644 --- a/test/beast/core/buffers_prefix.cpp +++ b/test/beast/core/buffers_prefix.cpp @@ -125,40 +125,6 @@ public: #endif } - void testIterator() - { - using net::buffer_size; - using net::const_buffer; - char b[3]; - std::array bs{{ - const_buffer{&b[0], 1}, - const_buffer{&b[1], 1}, - const_buffer{&b[2], 1}}}; - auto pb = buffers_prefix(2, bs); - BEAST_EXPECT(bsize1(pb) == 2); - BEAST_EXPECT(bsize2(pb) == 2); - BEAST_EXPECT(bsize3(pb) == 2); - BEAST_EXPECT(bsize4(pb) == 2); - - // default ctor is one past the end - decltype(pb)::const_iterator it; - BEAST_EXPECT(pb.end() == it); - BEAST_EXPECT(it == pb.end()); - decltype(pb)::const_iterator it2; - BEAST_EXPECT(it == it2); - BEAST_EXPECT(it2 == it); - it = pb.end(); - it2 = pb.end(); - BEAST_EXPECT(it == it2); - BEAST_EXPECT(it2 == it); - decltype(pb)::const_iterator it3(it2); - BEAST_EXPECT(it3 == it2); - it = pb.begin(); - BEAST_EXPECT(it != it3); - it = it3; - BEAST_EXPECT(it == it3); - } - void testInPlaceInit() { { @@ -208,13 +174,56 @@ public: } } + void testIterators() + { + char b[3]; + std::array bs{{ + net::const_buffer{&b[0], 1}, + net::const_buffer{&b[1], 1}, + net::const_buffer{&b[2], 1}}}; + auto pb = buffers_prefix(2, bs); + BEAST_EXPECT(bsize1(pb) == 2); + BEAST_EXPECT(bsize2(pb) == 2); + BEAST_EXPECT(bsize3(pb) == 2); + BEAST_EXPECT(bsize4(pb) == 2); + } + + void + testDefaultIterators() + { + // default ctor is one past the end + char b[3]; + std::array bs{{ + net::const_buffer{&b[0], 1}, + net::const_buffer{&b[1], 1}, + net::const_buffer{&b[2], 1}}}; + auto pb = buffers_prefix(2, bs); + decltype(pb)::const_iterator it; + BEAST_EXPECT(pb.end() == it); + BEAST_EXPECT(it == pb.end()); + decltype(pb)::const_iterator it2; + BEAST_EXPECT(it == it2); + BEAST_EXPECT(it2 == it); + it = pb.end(); + it2 = pb.end(); + BEAST_EXPECT(it == it2); + BEAST_EXPECT(it2 == it); + decltype(pb)::const_iterator it3(it2); + BEAST_EXPECT(it3 == it2); + it = pb.begin(); + BEAST_EXPECT(it != it3); + it = it3; + BEAST_EXPECT(it == it3); + } + void run() override { testMatrix(); testMatrix(); testEmptyBuffers(); - testIterator(); testInPlaceInit(); + testIterators(); + testDefaultIterators(); } };