Boost logo

Boost :

Subject: Re: [boost] [gil] Is bit_aligned_pixel_iterator a standard conformant random access iterator?
From: Adam Merz (adammerz_at_[hidden])
Date: 2010-05-31 19:25:44


Hi Christian, this is ildjarn from the MSDN forums. :-]

Christian Henning <chhenning <at> gmail.com> writes:
> Hi there, I'm having an interesting discussion over at the MSDN forums
> regarding compiler errors with MSVC10 that show up when using standard
> algorithms and bit_aligned images. Basically the question is why
> MSVC10 doesn't understand that bit_aligned_pixel_iterator is a random
> access iterator.

To be clear, it's not that MSVC10 doesn't understand that
bit_aligned_pixel_iterator is a random access iterator, it's that
bit_aligned_pixel_iterator *isn't* a random access iterator. I.e.,
std::iterator_traits< bit_aligned_pixel_iterator >::iterator_category is
std::input_iterator_tag on every compiler/platform. It's just that MSVC10
refuses to instantiate std::copy given a destination iterator categorized as an
input iterator (which is a good thing). If GIL had a regression test with a
static assertion that boost::is_same< std::iterator_traits<
bit_aligned_pixel_iterator<...> >::iterator_category,
std::random_access_iterator_tag >::value == true, this would have been caught
long ago. (hint, hint)

One perspective is that the bug here is that bit_aligned_pixel_iterator is
trying to pass itself off as a random access iterator in the first place,
despite the fact that it returns a proxy object rather than an actual
reference, violating the standard's requirements for forward iterators.
However, since it appears to work properly on all tested toolsets, that could
be deemed an acceptable flaw, in which case the proper fix is to pass
iterator_facade a category of std::random_access_iterator_tag rather than
boost::random_access_traversal_tag. Easy enough. :-]

Another perspective is that the bug here is caused by iterator_facade silently
decaying into an input iterator despite being told to function as a random
access iterator. This is documented behavior, so it's not a bug in and of
itself, but the fact that it does so *silently* is a questionable design issue
given that it's negatively affected at least two released libraries so far. I'm
not sure what mechanism could be used to make the decay 'noisy' rather than
silent, but this is clearly a gotcha for users of iterator_facade. Also, the
fact that it decays into an input iterator rather than an input/output iterator
seems arbitrary and less than ideal. Why doesn't it decay into
boost::detail::input_output_iterator_tag? At least then it could be used as a
destination for std::copy.

Keep in mind that the issue surrounding bit_aligned_pixel_iterator applies in
an identical manner to boost::detail::multi_array::array_iterator, as brought
up by Thomas Klimpel multiple times now, most recently here:
http://lists.boost.org/Archives/boost/2010/05/167125.php So whatever solution
is deemed acceptable for bit_aligned_pixel_iterator should be applied to
array_iterator as well, if possible.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk