[range] [1.40] iterator_range::size broken for non-random access iterators

We were just upgrading from 1.34.1 to 1.39.0 and I ran into this issue which I note is still in the trunk (and I would assume the 1.40 candidate). The definition of iterator_range::size is using operator- where it should be using std::distance as it did in boost 1.34 days: """ difference_type size() const { BOOST_ASSERT( !is_singular() ); return m_End - m_Begin; } """ It used to be: """ #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) return std::distance<IteratorT>( m_Begin, m_End ); #else return std::distance( m_Begin, m_End ); #endif """ I'm not sure why it would have changed but it's no longer working with bi-directional iterators, etc. Can we put back the old version? Can we get this fixed for 1.40? Thanks, -Ryan

Ryan Gallagher wrote:
We were just upgrading from 1.34.1 to 1.39.0 and I ran into this issue which I note is still in the trunk (and I would assume the 1.40 candidate).
The definition of iterator_range::size is using operator- where it should be using std::distance as it did in boost 1.34 days:
<snip>
I'm not sure why it would have changed but it's no longer working with bi-directional iterators, etc. Can we put back the old version? Can we get this fixed for 1.40? Thanks,
This change is intentional. We decided that iterator_range::size should be O(1), or else it shouldn't compile. To get the old behavior, you can use boost::distance in boost/range/distance.hpp. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler <eric <at> boostpro.com> writes:
Ryan Gallagher wrote:
We were just upgrading from 1.34.1 to 1.39.0 and I ran into this issue which I note is still in the trunk (and I would assume the 1.40 candidate).
The definition of iterator_range::size is using operator- where it should be using std::distance as it did in boost 1.34 days:
<snip>
This change is intentional. We decided that iterator_range::size should be O(1), or else it shouldn't compile.
To get the old behavior, you can use boost::distance in boost/range/distance.hpp.
I never call size directly though, it's just being used through sub_range<> although I'm not sure why this method is being instantiated. I have a multi-index index on which I call equal_range. I wrapped this result in a sub_range<index<tag>::type> and return it. The compiler (msvc8) seems to complain when I assign this result to a sub_range<> instance (I don't see this calling size() though). I then pass it to BOOST_FOREACH -- perhaps this is where size() is being called. If this is the case, then BOOST_FOREACH is broken due to this change. I suppose I can change to not wrap the pair of iterators in sub_range and just pass them to BOOST_FOREACH as that's also a supported sequence type. It's just not as nice, -Ryan

Ryan Gallagher wrote:
Eric Niebler <eric <at> boostpro.com> writes:
Ryan Gallagher wrote:
We were just upgrading from 1.34.1 to 1.39.0 and I ran into this issue which I note is still in the trunk (and I would assume the 1.40 candidate).
The definition of iterator_range::size is using operator- where it should be using std::distance as it did in boost 1.34 days: <snip> This change is intentional. We decided that iterator_range::size should be O(1), or else it shouldn't compile.
To get the old behavior, you can use boost::distance in boost/range/distance.hpp.
I never call size directly though, it's just being used through sub_range<> although I'm not sure why this method is being instantiated.
I have a multi-index index on which I call equal_range. I wrapped this result in a sub_range<index<tag>::type> and return it. The compiler (msvc8) seems to complain when I assign this result to a sub_range<> instance (I don't see this calling size() though). I then pass it to BOOST_FOREACH -- perhaps this is where size() is being called. If this is the case, then BOOST_FOREACH is broken due to this change.
BOOST_FOREACH does not call size.
I suppose I can change to not wrap the pair of iterators in sub_range and just pass them to BOOST_FOREACH as that's also a supported sequence type. It's just not as nice,
Please send code that reproduces the error. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler <eric <at> boostpro.com> writes:
BOOST_FOREACH does not call size. <snip> Please send code that reproduces the error.
Yeah, I just tried reproing it with std::set<int> and it doesn't, so obviously you're right that BOOST_FOREACH isn't causing the size() instantiation. I'll try to repro it with a real multi-index ordered index in a couple hours and get back to you. Thanks, -Ryan

Eric Niebler <eric <at> boostpro.com> writes:
Ryan Gallagher wrote:
Eric Niebler <eric <at> boostpro.com> writes:
Ryan Gallagher wrote: To get the old behavior, you can use boost::distance in boost/range/distance.hpp.
I never call size directly though, it's just being used through sub_range<> although I'm not sure why this method is being instantiated.
Sigh, my mistake...I found the call to sub_range<>::size(), the error message was pointing me elsewhere for some reason. I'll change it as you suggest. Thanks for your patience, -Ryan
participants (2)
-
Eric Niebler
-
Ryan Gallagher