On Thu, Sep 29, 2011 at 3:59 PM, Dave Abrahams
on Thu Sep 29 2011, Brian Allison
wrote: On Thu, Sep 29, 2011 at 9:50 AM, Dave Abrahams
wrote: I'm sorry - but regarding the statement "every valid iterator is-a singular iterator in some sense"... I thought the Standard (2003) explicitly stated that singular values for an iterator had all but one operation as Undefined Behavior, and the only defined operation on an iterator with a singular value was to assign it a non-singular value. (24.1, para 5)
Yes; this is a problem with negative requirements statements. Just like you can't decrement a forward iterator, you can't dereference a singular iterator. However, a bidirectional iterator, which you can decrement, is-a forward iterator. In the same way, a valid iterator is-a singular iterator.
Your ontology seems to have no basis in the ontology of the standard. The last sentence I quoted: *Dereferenceable values are always nonsingular.* This sentence doesn't leave room for a statement like "every valid iterator is-a singular iterator in some sense", given that dereferenceable iterators are valid, and the standard explicitly states that they are non-singular. Your definition of "in a sense" and "in teh same way" are then in contradiction to the standard. You can't modify that requirement of the standard to behave as a parent class acts in a type algebra, where a subclass can override the superclass - unless there is another part of the standard which allows such a replacement [is there?]. Rather, this particular definition seems to set "singular" values apart from defined (whether or not they're safe to dereference) values. If we want to map the concepts to a type algebra, then a singular value would correspond to a "final" type that prohibits subclassing. If we want to be precise about the three partitions of iterators, we should use "singular" in the way that the standard uses it. We could easily use two more terms: Dereferenceable & Nonsingular, where the former is a proper subset of the latter. But the standard seems to explicitly make Singular iterators a non-intersecting set with the Nonsingular set, and all iterators must belong to exactly one of Singular or Nonsingular.
Results of most expressions are undefined for singular values; the only exception is an assignment of a non-singular value to an iterator that holds a singular value. In this case the singular value is overwritten the same way as any other value. Dereferenceable values are always nonsingular. Doesn't the last sentence make it true that "every valid iterator is-a nonsingular iterator"?
(it doesn't, even by logic, since some valid iterators are not dereferenceable, but that aside...). In the sense I'm using is-a, a nonsingular iterator is-a singular iterator. How's that for fun logic? :-)
Your ontology seems to require an overriding of the standard - which part of the standard allows for that overriding?
When the standard says "that's a singular iterator" it's saying you can only assume it supports two operations. That doesn't mean it can't support more operations. It's a constraint on the user, not on the iterator.
But when it says "*Dereferenceable values are always nonsingular.*", that seems to be a constraint on the iterator. Being X or Non-X are mutually exclusive.
In the sense of concept requirements, you can. Any valid iterator supports a superset of the requirements on singular iterators
If you're only concerned with the positive requirements of a concept, then yes. But we must be concerned with both positive and negative requirements - since the standard explicitly excludes dereferenceable values from being singular, then being "singular" doesnt' really map well to concept requirements [if I understand your contextual use of the term].
The point is that the OP claimed every default-constructed iterator is singular. The only way that could be true is if you take the term "is-a" in the sense I'm using it here. That is, I can easily create an iterator that, when default-constructed, supports a strict superset of the required operations for singular iterators.
But I could make an iterator type whose constructor would throw() if it were not to a valid member. A contrived example, but then there would be a type which would refute OP's claim while adhering to the standard. Hence, the OP's claim is in error. Curiosity: why are you trying to form an algebra in which the OP's claim is correct?