
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.