$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r72107 - in trunk: boost/range/adaptor libs/range/test/adaptor_test
From: neil_at_[hidden]
Date: 2011-05-22 18:06:31
Author: neilgroves
Date: 2011-05-22 18:06:30 EDT (Sun, 22 May 2011)
New Revision: 72107
URL: http://svn.boost.org/trac/boost/changeset/72107
Log:
[boost][range] - Ticket 5236 - Strided reversing past begin issue resolved.
Text files modified: 
   trunk/boost/range/adaptor/strided.hpp          |    43 ++++++++++++++++++--------------------- 
   trunk/libs/range/test/adaptor_test/strided.cpp |    20 ++++++++++++++++++                      
   2 files changed, 40 insertions(+), 23 deletions(-)
Modified: trunk/boost/range/adaptor/strided.hpp
==============================================================================
--- trunk/boost/range/adaptor/strided.hpp	(original)
+++ trunk/boost/range/adaptor/strided.hpp	2011-05-22 18:06:30 EDT (Sun, 22 May 2011)
@@ -176,6 +176,7 @@
             strided_iterator()
                 : m_first()
                 , m_last()
+                , m_index(0)
                 , m_stride()
             {
             }
@@ -184,6 +185,7 @@
                 : super_t(it)
                 , m_first(first)
                 , m_last(last)
+                , m_index(stride ? (it - first) / stride : 0)
                 , m_stride(stride)
             {
             }
@@ -194,6 +196,7 @@
                 : 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 @@
             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<class OtherIterator>
@@ -252,12 +248,13 @@
 
             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;
         };
 
Modified: trunk/libs/range/test/adaptor_test/strided.cpp
==============================================================================
--- trunk/libs/range/test/adaptor_test/strided.cpp	(original)
+++ trunk/libs/range/test/adaptor_test/strided.cpp	2011-05-22 18:06:30 EDT (Sun, 22 May 2011)
@@ -250,6 +250,25 @@
             BOOST_CHECK_EQUAL_COLLECTIONS( reference.begin(), reference.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 @@
     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;
 }