[boost][range] - Ticket 5236 - Strided reversing past begin issue resolved.

[SVN r72107]
This commit is contained in:
Neil Groves
2011-05-22 22:06:30 +00:00
parent 8810c4c4aa
commit 846f11a96c
2 changed files with 40 additions and 23 deletions

View File

@ -176,6 +176,7 @@ namespace boost
strided_iterator() strided_iterator()
: m_first() : m_first()
, m_last() , m_last()
, m_index(0)
, m_stride() , m_stride()
{ {
} }
@ -184,6 +185,7 @@ namespace boost
: super_t(it) : super_t(it)
, m_first(first) , m_first(first)
, m_last(last) , m_last(last)
, m_index(stride ? (it - first) / stride : 0)
, m_stride(stride) , m_stride(stride)
{ {
} }
@ -194,6 +196,7 @@ namespace boost
: super_t(other.base()) : super_t(other.base())
, m_first(other.base_begin()) , m_first(other.base_begin())
, m_last(other.base_end()) , m_last(other.base_end())
, m_index(other.get_index())
, m_stride(other.get_stride()) , m_stride(other.get_stride())
{ {
} }
@ -201,44 +204,37 @@ namespace boost
base_iterator base_begin() const { return m_first; } base_iterator base_begin() const { return m_first; }
base_iterator base_end() const { return m_last; } base_iterator base_end() const { return m_last; }
difference_type get_stride() const { return m_stride; } difference_type get_stride() const { return m_stride; }
difference_type get_index() const { return m_index; }
private: private:
void increment() void increment()
{ {
base_iterator& it = this->base_reference(); m_index += m_stride;
if ((m_last - it) > m_stride) if (m_index < (m_last - m_first))
it += m_stride; this->base_reference() = m_first + m_index;
else else
it = m_last; this->base_reference() = m_last;
} }
void decrement() void decrement()
{ {
base_iterator& it = this->base_reference(); m_index -= m_stride;
if ((it - m_first) > m_stride) if (m_index >= 0)
it -= m_stride; this->base_reference() = m_first + m_index;
else else
it = m_first; this->base_reference() = m_first;
} }
void advance(difference_type offset) void advance(difference_type offset)
{ {
base_iterator& it = this->base_reference();
offset *= m_stride; offset *= m_stride;
if (offset >= 0) m_index += offset;
{ if (m_index < 0)
if ((m_last - it) > offset) this->base_reference() = m_first;
it += offset; else if (m_index > (m_last - m_first))
else this->base_reference() = m_last;
it = m_last;
}
else else
{ this->base_reference() = m_first + m_index;
if ((m_first - it) > offset)
it += offset;
else
it = m_first;
}
} }
template<class OtherIterator> template<class OtherIterator>
@ -252,12 +248,13 @@ namespace boost
bool equal(const strided_iterator& other) const bool equal(const strided_iterator& other) const
{ {
return other.base() == this->base(); return this->base() == other.base();
} }
private: private:
base_iterator m_first; base_iterator m_first;
base_iterator m_last; base_iterator m_last;
difference_type m_index;
difference_type m_stride; difference_type m_stride;
}; };

View File

@ -250,6 +250,25 @@ namespace boost
BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(), BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.end(),
output.begin(), output.end() ); output.begin(), output.end() );
} }
template<typename Range>
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<const Range>::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<int> 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_test ) );
test->add( BOOST_TEST_CASE( &boost::strided_defect_Trac5014 ) ); 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_traversal ) );
test->add( BOOST_TEST_CASE( &boost::strided_test_ticket_5236 ) );
return test; return test;
} }