From 846f11a96cd8623cdbd74d96b2ff0ca2f1aa1cfd Mon Sep 17 00:00:00 2001 From: Neil Groves Date: Sun, 22 May 2011 22:06:30 +0000 Subject: [PATCH] [boost][range] - Ticket 5236 - Strided reversing past begin issue resolved. [SVN r72107] --- include/boost/range/adaptor/strided.hpp | 43 ++++++++++++------------- test/adaptor_test/strided.cpp | 20 ++++++++++++ 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/include/boost/range/adaptor/strided.hpp b/include/boost/range/adaptor/strided.hpp index abfad5e..e843f62 100755 --- a/include/boost/range/adaptor/strided.hpp +++ b/include/boost/range/adaptor/strided.hpp @@ -176,6 +176,7 @@ namespace boost strided_iterator() : m_first() , m_last() + , m_index(0) , m_stride() { } @@ -184,6 +185,7 @@ namespace boost : super_t(it) , m_first(first) , m_last(last) + , m_index(stride ? (it - first) / stride : 0) , m_stride(stride) { } @@ -194,6 +196,7 @@ namespace boost : super_t(other.base()) , m_first(other.base_begin()) , m_last(other.base_end()) + , m_index(other.get_index()) , m_stride(other.get_stride()) { } @@ -201,44 +204,37 @@ namespace boost base_iterator base_begin() const { return m_first; } base_iterator base_end() const { return m_last; } difference_type get_stride() const { return m_stride; } + difference_type get_index() const { return m_index; } private: void increment() { - base_iterator& it = this->base_reference(); - if ((m_last - it) > m_stride) - it += m_stride; + m_index += m_stride; + if (m_index < (m_last - m_first)) + this->base_reference() = m_first + m_index; else - it = m_last; + this->base_reference() = m_last; } void decrement() { - base_iterator& it = this->base_reference(); - if ((it - m_first) > m_stride) - it -= m_stride; + m_index -= m_stride; + if (m_index >= 0) + this->base_reference() = m_first + m_index; else - it = m_first; + this->base_reference() = m_first; } void advance(difference_type offset) { - base_iterator& it = this->base_reference(); offset *= m_stride; - if (offset >= 0) - { - if ((m_last - it) > offset) - it += offset; - else - it = m_last; - } + m_index += offset; + if (m_index < 0) + this->base_reference() = m_first; + else if (m_index > (m_last - m_first)) + this->base_reference() = m_last; else - { - if ((m_first - it) > offset) - it += offset; - else - it = m_first; - } + this->base_reference() = m_first + m_index; } template @@ -252,12 +248,13 @@ namespace boost bool equal(const strided_iterator& other) const { - return other.base() == this->base(); + return this->base() == other.base(); } private: base_iterator m_first; base_iterator m_last; + difference_type m_index; difference_type m_stride; }; diff --git a/test/adaptor_test/strided.cpp b/test/adaptor_test/strided.cpp index 91beb81..6389a30 100644 --- a/test/adaptor_test/strided.cpp +++ b/test/adaptor_test/strided.cpp @@ -250,6 +250,25 @@ namespace boost BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), output.begin(), output.end() ); } + + template + void strided_test_ticket_5236_check(const Range& rng) + { + BOOST_CHECK_EQUAL( boost::distance(rng), 1 ); + BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), boost::prior(boost::end(rng))), 0 ); + + typename boost::range_iterator::type it = boost::end(rng); + it = it - 1; + + BOOST_CHECK_EQUAL( std::distance(boost::begin(rng), it), 0 ); + } + + void strided_test_ticket_5236() + { + std::vector v; + v.push_back(1); + strided_test_ticket_5236_check( v | boost::adaptors::strided(2) ); + } } } @@ -262,6 +281,7 @@ init_unit_test_suite(int argc, char* argv[]) test->add( BOOST_TEST_CASE( &boost::strided_test ) ); test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) ); test->add( BOOST_TEST_CASE( &boost::strided_test_traversal ) ); + test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) ); return test; }