Boost C++ Libraries: Ticket #7824: "++--rng.end() == rng.end()" can fail for strided ranges https://svn.boost.org/trac10/ticket/7824 <p> Attached a test case for which "<code>++--rng.end() == rng.end()</code>" fails. </p> <p> Due to this bug, libc++'s <code>deque&lt;T&gt;::insert</code> function misunderstands the size of strided ranges. For example, </p> <pre class="wiki">using boost::strided_range; using boost::adaptors::strided; int ar[3] = {0, 1, 2}; strided_range&lt;int[3]&gt; rng = ar | strided(3); std::deque&lt;int&gt; cont; cont.insert(cont.begin(), rng.begin(), rng.end()); std::cout &lt;&lt; cont.size() &lt;&lt; std::endl; </pre><p> outputs 2 (not 1) with libc++. You can see <code>libs/range/test/adaptor_test/strided.cpp</code> fails on test runners with libc++. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7824 Trac 1.4.3 Michel Morin Sat, 22 Dec 2012 07:54:47 GMT attachment set https://svn.boost.org/trac10/ticket/7824 https://svn.boost.org/trac10/ticket/7824 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">strided_testcase.cpp</span> </li> </ul> <p> A test case for which "<code>++--rng.end() == rng.end()</code>" fails. </p> Ticket Michel Morin Sat, 22 Dec 2012 08:49:51 GMT <link>https://svn.boost.org/trac10/ticket/7824#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7824#comment:1</guid> <description> <p> Just for reference, here is a sample implementation of <code>strided_iterator</code> for <code>Random Access Range</code> (without zero-stride support), which can pass <code>strided.cpp</code> test (other than <code>strided_test_zero_stride</code>). </p> <pre class="wiki">// for Random Access Range (without zero-stride support) template &lt;typename BaseIterator&gt; class strided_iterator&lt;BaseIterator, boost::random_access_traversal_tag&gt; : public iterator_facade&lt; strided_iterator&lt;BaseIterator, boost::random_access_traversal_tag&gt; , typename std::iterator_traits&lt;BaseIterator&gt;::value_type , boost::random_access_traversal_tag , typename std::iterator_traits&lt;BaseIterator&gt;::reference , typename std::iterator_traits&lt;BaseIterator&gt;::difference_type &gt; { public: // types typedef typename std::iterator_traits&lt;BaseIterator&gt;::reference reference; typedef typename std::iterator_traits&lt;BaseIterator&gt;::difference_type difference_type; // ctors strided_iterator() {} strided_iterator( BaseIterator first , BaseIterator it , BaseIterator last , difference_type stride ) : m_begin(first) , m_offset((it - first) % stride == 0 ? (it - first) / stride : (it - first) / stride + 1) , m_stride(stride) {} private: // iterator_facade core operations friend class boost::iterator_core_access; reference dereference() const { return *(m_begin + m_stride * m_offset); } bool equal(strided_iterator const&amp; other) const { return m_begin == other.m_begin &amp;&amp; m_offset == other.m_offset; } void increment() { ++m_offset; } void decrement() { --m_offset; } void advance(difference_type n) { m_offset += n; } difference_type distance_to(strided_iterator const&amp; other) const { return other.m_offset - m_offset; } // data BaseIterator m_begin; // the begin iterator of an input range difference_type m_offset; // the number of strides taken by this iterator difference_type m_stride; }; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Neil Groves</dc:creator> <pubDate>Thu, 27 Feb 2014 13:28:00 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/7824#comment:2 https://svn.boost.org/trac10/ticket/7824#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Thanks for the report. The posted implementation does fix this problem but would introduce a number of others. I have reimplemented the strided iterators and eliminated this issue. </p> <p> I apologise for the nuisance this defect has caused you. Thanks for helping. </p> Ticket