Subject: Re: [boost] [concept_check] Should OutputIterator check for output_iterator_tag?
From: Ronald Garcia (rxg_at_[hidden])
Date: 2012-01-10 15:40:27
Hi Dave (and Jeremy),
Thanks for the note. I didn't realize that random_access_iterator_tag is not convertible to output_iterator!
At least looking at page 607 of n1905 (Draft Standard), that seems to clearly be the case.
To top that off, reading page 605 of n1905, it sounds like every iterator must have an iterator_category defined, but input_iterator_tag is a perfectly fine iterator category.
It sounds like any iterator that at least models input_iterator does not need to have an iterator_category that is convertible to output_iterator_tag. Does that sound right? If so, then
there is a bug in MSVC 2010's implementation of copy, which is the trac issue that I have been diagnosing:
> (IDL refers to _ITERATOR_DEBUG_LEVEL, which is 0 in release mode and 2 in debug mode.)
> -- The problem is that multi_array iterators report themselves as input iterators, which can't be written to (e.g. as the destination of a copy()). Under IDL=0, copy() doesn't actually care how its destination iterator is marked with an iterator category tag, it just tries to write to the destination iterator, and that works. Under IDL > 0, copy() wants to know whether its source and destination iterators are both random-access, in which case it can perform a range check and unwrap the destination iterator for increased performance. It does this by overloading foo(input_iterator_tag, output_iterator_tag) and foo(random_access_iterator_tag, random_access_iterator_tag) and calling foo(category(source), category(destination)). If both source and destination are random-access, both overloads are viable (i.e. callable) and the second overload is preferred, so it's actually called. Otherwise, source is required to be at least an input iterator (maybe stronger) and destination is required to be at least an output iterator (maybe stronger) so the first overload must be viable and the second overload will be non-viable, so the first overload wins by default.
> However, if the destination is not marked as an output iterator or stronger, then the first overload is non-viable as well as the second, so overload resolution fails and boom.
On Jan 10, 2012, at 4:09 AM, Dave Abrahams wrote:
> on Mon Jan 09 2012, Ronald Garcia <rxg-AT-cs.cmu.edu> wrote:
>> In tracking down a problem with Boost.MultiArray, I'd like to write a
>> test case that exhibits the failure. Specifically, certain iterators
>> should be models of OutputIterator, and it's my impression that an
>> output iterator needs to have an iterator_category that's convertible
>> to output_iterator_tag(). However, it looks like the OutputIterator
>> Concept checker in the concept checker library does not check that the
>> output iterator has such an iterator_category. Is that an oversight,
>> or is it not the case that an output iterator have a category that's
>> convertible to output_iterator_tag? It looks like InputIterator,
>> RandomAccessIterator concept checkers perform such a check.
> All I can tell you is that I tried not to change the meaning of the
> existing checker for OutputIterator... so technically you'll have to ask
> Jeremy ;-)
> Come to think of it, since random_access_iterator_tag is not convertible
> to output_iterator_tag, and char* is definitely an OutputIterator, I
> don't think you can make that requirement.
> Dave Abrahams
> BoostPro Computing
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk