
on Sat Nov 22 2008, Tomas Puverle <Tomas.Puverle-AT-morganstanley.com> wrote:
The library may indeed have been poorly documented, but I don't see how what you wrote here addresses Scott's statement in any way. You simply cannot count on undocumented behaviors of a library; they are subject to change without notice.
The behaviour WAS documented, as I've stated in a different thread: It's right there at the top of the iterator_range class if the pre 1.35 docs.
Agreed, now that I've seen your quote.
However, I have to say I don't like what you're doing - I feel like you're trying to prove that what we're doing is actually wrong in some way.
I'm sorry you feel that way. I don't intend that at all.
We're looking for a solution to real problem.
Agreed.
Forget for a second about whether it or it documented. The question is - what can be done?
Agreed again. However, whether it was documented or not has a huge effect on my opinion about what can be done.
at the top of iterator_range we see:
/*! \file Defines the \c iterator_class and related functions. \c iterator_range is a simple wrapper of iterator pair idiom. It provides a rich subset of Container interface. */
This implies to me that range is trying to look and feel like a container - not like an iterator.
I understand that you drew that conclusion, but IMO it's a huge stretch to claim that a concept that doesn't even exist for containers (singularity) should behave in some container-like way for ranges.
Remember that our problem is not with is_singular(),
A lot of arguments have been flying around this thread, some about is_singular and others about the fundamental nature of the Range concept. I understand those are not *your* concern.
it is with empty(). is_singular() is just an implementatin artifact. The behaviour we care about is whether or not a default constructed iterator_range should be empty(), in line with standard containers.
Understood.
I agree that singular iterators (as defined in the standard) are undefined when default constructed;
To be precise, they're not undefined. All singular iterators are alike, regardless of how they're produced (default-constructed or otherwise). They have two defined operations: assignment and destruction.
But not all default constucted iterators are singular.
True, but in generic code (e.g. inside of iterator_range), in the absence of any further information, you have to treat them that way.
You're free to define models of Range that have a default-constructed empty state. Requiring all models of Range to behave that way is antithetical to the principles of generic programming.
We certainly agree on this. We're not proposing that we have a single iterator_range class that fits all purposes, again as I've stated in several posts.
I understand that. Others' arguments seemed to be headed that way.
but AFAICT the only thing that a Range has in common with a container is that it supplies a begin() and end() that delimit a sequence of elements.
Actually, the similarity is much stronger than that:
iterator begin() const; iterator end() const; size_type size() const; bool empty() const;
On the Range concept those are free functions, not members.
Unfortunately I don't have my standard at hand (it's at work) but IIRC all of the are part of the "Container requirements".
Yes, but they're not part of the "Range requirements." If they were, pair<int*,int*> couldn't be a Range. -- Dave Abrahams BoostPro Computing http://www.boostpro.com