Opened 12 years ago

Closed 12 years ago

Last modified 7 years ago

#5014 closed Bugs (fixed)

stride doesn't end iteration properly

Reported by: Maxim.Yanchenko@… Owned by: Neil Groves
Milestone: Boost 1.46.0 Component: range
Version: Boost 1.45.0 Severity: Showstopper
Keywords: Cc:

Description

The code

  std::vector<int> v;
  boost::push_back( v, boost::irange(0, 30) );
  boost::copy( v | boost::adaptors::strided(4)
             , std::ostream_iterator<int>(std::cout, " "));

prints "0 4 8 12 16 20 24" instead of "0 4 8 12 16 20 24 28".

See the discussion for similar cases: http://thread.gmane.org/gmane.comp.lib.boost.devel/211955

Change History (6)

comment:1 by Neil Groves, 12 years ago

The requirement for the strided adaptor were overly severe. It required boost::size(rng) % stride_size == 0.

I have modified the implementation of boost::size(rng) to enable modification of the strided_range constructors. This means that the strided_size no longer needs to be <= boost::size(rng), and that rng may now be a model of the SinglePassRangeConcept or better if the expression boost::size(rng) is also valid.

This has been committed to the trunk. The regression tests shall be monitored before merging to the release branch.

comment:2 by Neil Groves, 12 years ago

Milestone: To Be DeterminedBoost 1.46.0
Resolution: fixed
Status: newclosed

Resolved and passing regression tests.

comment:3 by mimomorin@…, 12 years ago

Resolution: fixed
Status: closedreopened

The above code still prints "0 4 8 12 16 20 24" instead of "0 4 8 12 16 20 24 28". This is because, when constructing strided_range, the end iterator of an input range should advance forward rather than backward. The regression test (libs/range/test/adaptor_test/strided.cpp) passes because a similar thing happens when populating reference in strided_test_impl.

Please see: http://article.gmane.org/gmane.comp.lib.boost.devel/211975 (The codes in the mail assumes stride is greater than zero...)

comment:4 by Neil Groves, 12 years ago

Resolution: fixed
Status: reopenedclosed

I confirm that I made a design error yesterday while making the change to the strided adaptor. The code I committed yesterday did not support ForwardRange or SinglePassRange concepts. Additionally it did not perform as we wanted. It was setting the last iterator in the range to be the last valid iterator on a stride boundary.

To correct this I have added offset and max_offset information into the strided_iterator. This is required so that we can use the offset to go past the end of the range while avoiding advancing the underlying iterator beyond valid values. This change additionally corrects a defect with interoperability of strided iterators.

comment:5 by mimomorin@…, 12 years ago

At line 12 of libs/range/test/adaptor_test/strided.cpp, could you change "Michel Morin" to "Maxim Yanchenko"? I believe Maxim should be credited there. Sorry for bothering you and thanks in advance.

comment:6 by Michel Morin, 7 years ago

At line 12 of libs/range/test/adaptor_test/strided.cpp, could you change "Michel Morin" to "Maxim Yanchenko"?

I just made a PR on github.

Note: See TracTickets for help on using tickets.