
Sure there are, but that's irrelevant. The standard doesn't require iterators that have been constructed to be in a valid state, and that's all there is to it.
By the same logic, we should never be able to build any compound types which have any members which could potentially be in some invalid state. When I default construct a string class, it has some internal representation with a char pointer, which doesn't necessarily point to any valid memory. Does that mean that the observable behaviour of that class should be undefined? Or that asking the string if it's empty should abort my application? Maybe you want your string class to do that but I can't have mine work like that. Hence we need two different implementations. That is exactly what I proposed.
It's not a matter of choice of design. It's a matter of following the standard.
I really have not idea what you're referring to. There is nothing about iterator_range in the C++ standard. We can choose to define the semantics any way we choose.
In your specific case it's not a problem, but iterator_range aims at being generic.
Generic means that it's applicable to a wide variety of types. Cutting out support for a subset of valid types for no good reason = less generic.
As I said, if it was just me, I would have designed the iterator concepts differently so as *not* to require default construction, which standard iterator concepts do, and that is bringing the singular states in.
Then perhaps you should try to come up with a design we could discuss here rather than just criticizing without actually proposing something. Then we could get somewhere. This, what is happening now on this mail topic is very typical of this mailing list and this is what makes it so hard to try be involved. By now, I could have written ten range implementations and fixed all of my code. Instead, I'm spending time trying to get this (IMHO important) component somehow integrated back into boost. If instead of arguing about minutia we could actually talk about a real design, we could make progress. At the moment all of the useful brain power is spent on trying to prove that what we're doing is wrong. Your problem domain is different from mine. Physicists call the imaginary number 'j'. In mathematics, we refer to it as 'i'. Does it make one or the other wrong? I gave a demonstrable use case, which, IMHO, is actually very powerful thanks to the generality of iterator_range. Not one of the opponents of what we're saying has come up with a single suggestion of how the current iterator_range can meet my needs or justify why it should be acceptable for boost to change documented behaviour without any notice. Whether or not the original semantics were "pure" in some way is irrelevant. Boost is a published library and it broke people's code. Now you are arguing in favour of alienating a collection of current users of boost because it seems, you don't deem their use case important enough. Boost needs to be nimble and glaring problems should, of course, be fixed. At the same time, the developers should recognise how widely used boost is and at least have enough of a feeling of responsibility towards the users not to just break things willy-nilly. I asked Thorsten if there were any actual use cases in which the overhead of the additional boolean check was causing problem. He never replied. And when such breakage happens, my hope would be that the developers would try to work with the affected people instead of calling their use cases irrelevant. Tom