Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-02 07:29:24


Robert Ramey <ramey_at_[hidden]> writes:

> Dave Abrahams wrote:
>
>>Robert Ramey wrote:
>
>>> it seems to me that it is implemented for non - random access
>>> iterators by incrementing one iterator until it equals the other and
>>> return the number of times the increment occured.
>
>>Yeah, it's a mistake. It shouldn't use distance, but operator-.
>>That way neither one of your subtractions would compile.
>
> From the documentation:
>
> counting_iterator requirements
>
> The Incrementable argument shall be Copy Constructible and
> Assignable.
>
> If iterator_category is convertible to forward_iterator_tag or
> forward_traversal_tag, the following must be well-formed:
>
> Incrementable i, j;
> ++i; // pre-increment
> i == j; // operator equal

What's your point?

> Suppose I had used a different iterator as a base - not
> an input iterartor but some kind of forward transveral iterator.
> Would that have been ok?

An input iterator is also OK, though it's destructive: input iterators
are single-pass, so when you increment them, you lose the data they
"refer" to.

A forward iterator is a more useful Incrementable type for
counting_iterator

> Now if I understand correctly? the only difference between the single pass transveral
> and forward transversal is the ability to "rewind".

Not exactly; it's the ability to traverse the same set of elements
starting with a copy of the original iterator.

> As far as I can see the ability doesn't affect the requirement
> stated above.

Correct.

> Are sure that the requirement isn't too strong.

In what way? It isn't requiring anything of your Incrementable type
that it didn't supply.

> The fact that it "accidently" works seems to suggest this.

The operator-() implementation was O(N), not O(1), so it did not
"work" at all as far as iterator requirements are concerned. You
just can't turn an input iterator into a random access iterator no
matter how hard you try.

> from the nomenclature, example, other "counting iterators", and common
> sense, I would expect an example such as the one I presented to
> function as I expected. And in fact it did in the previous release
> candidate.

You got "lucky". Or unlucky, depending on how you look at it.

> That is, its natural to expect the following to function
>
> std::fstream is;
> std::input_iterator begin(is), end();
>
> int filesize = end - begin;

I don't know what leads you to that expectation.
To begin with, there's no such thing as "std::input_iterator".
Secondly, you can't do it with any of the standard input_iterators
such as istream_iterator, istreambuf_iterator, et. al. Why would you
expect more from a wrapper over a standard input iterator?

> Can the design and implement (of off course document) be adjusted
> to permit this?

No way.

> If such a seemingly natural usage is not possible, it should be
> trapped at compile time (as you suggested)

Done.

> and the reason why it can't be supported described in the
> documentation.

I appreciate that any misconception like this can be said to indicate
a documentation failure, but really the input iterator requirements in
the standard and the single pass traversal iterator requirements in
the new iterator concepts are fairly clear. I don't think it's
reasonable to go out of our way to tell people *again* that only
random access iterators into the same sequence can be subtracted from
one another. Then we'd also have to mention +=, -=, [], and addition
and subtraction using the difference_type. Oh, and by the way, only
bidirectional iterators can be decremented. Repeating this
information for each specialized adaptor seems like too much.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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