Boost logo

Boost :

Subject: Re: [boost] Is Boost.Range broken?
From: David Abrahams (dave_at_[hidden])
Date: 2008-11-21 22:00:30


on Fri Nov 21 2008, "Scott McMurray" <me22.ca+boost-AT-gmail.com> wrote:

> On Fri, Nov 21, 2008 at 17:09, Tomas Puverle
> <Tomas.Puverle_at_[hidden]> wrote:
>> 1) Empty ranges are useless and they cannot even be reliably tested for
>> emptiness.
>
> No, empty ranges are useful and can be reliably tested.
>
>> The empty() function now asserts and the is_singular() function
>> behaves differently between debug and release builds, making it impossible to
>> detect if a range is, in fact, empty.
>
> Yes, singular ranges are almost useless, and cannot be tested for
> singularity. This seems reasonable, as it's just like ints and
> iterators. I wouldn't say that a singular range is empty, just as I
> wouldn't say that an uninitialized int has a value.

That's my inclination, too. Of course, I wouldn't object to another
iterator range class that gives the stronger guarantee that it is never
singular. There's no point in distinguishing the idea of "singular"
from that of "empty" if they are really the same thing, though.

> I would agree that is_singular should not be available at all in
> release builds, if it's never useful there. I'd consider it analagous
> to iterator debugging features, and would think it might be exposition
> only.

"Exposition only" in the standard is used to give a sense of how
something might be implemented, or to say, "here's a working
implementation but we're not saying you actually have to do it that way,
so long as you give the right observable behavior."

So I don't think "exposition only" is quite the right terminology.
Iterator debugging isn't described that way anywhere, AFAIK.

>> In addition, this is not documented well and can lead to subtle bugs
>> and undefined behaviour, which will only manifest itself in release
>> builds.
>
> But what semantics for empty *are* documented?
>
> http://www.boost.org/doc/libs/1_37_0/libs/range/doc/boost_range.html#Semanticsempty(x)
> returns boost::begin(x) == boost::end(x)
>
> That's undefined when begin and end return singular iterators,

Correct.

> so I'm not convinced that the "singular implies empty" behaviour was
> ever documented. (The "returns" entry for empty is the same for
> 1_36_0, 1_35_0, 1_34_0, and 1_33_1.)

Hmmm.

>> 2) The behaviour is unintuitive. Range is a generalisation of the interface of
>> the std::containers. With this change, containers and ranges can no longer be
>> used in the same code path.
>
> Why would you ever want to pass a default-constructed range to anything?

I will admit that there have been times that I really wished
default-constructed iterators all had a value analogous to NULL, that
was different from all other values of the same type and yet
nonsingular. But that's not how it is, and if you're going to build a
range on top of the existing iterator abstraction, I don't see how you
can do much better.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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