range and algorithm-related stuff

Daniel Keep daniel.keep.lists at gmail.com
Sat Jan 24 20:14:51 PST 2009



Andrei Alexandrescu wrote:
> dsimcha wrote:
>> == Quote from Andrei Alexandrescu (SeeWebsiteForEmail at erdani.org)'s
>> article
>>> I'm working on the new range stuff and the range-based algorithm. In all
>>> likelihood, you all might be pleased with the results.
>>> I wanted to gauge opinions on a couple of issues. One is, should the
>>> empty() member function for ranges be const? On the face of it it
>>> should, but I don't want that to be a hindrance. I presume non-const
>>> empty might be necessary sometimes, e.g. figuring out if a stream is
>>> empty effectively means fetching an element off it.
>>
>> Play devil's advocate with me.  Given that making empty() non-const
>> would make the
>> internal implementation of things more flexible, and that next() has
>> to be
>> non-const, so the range interface as a whole is non-const, what is the
>> practical
>> advantage to making empty() const?
> 
> If empty, head, toe, opIndex, and length are const, there's plenty you
> can do with the const range. The problem is that there are higher-order
> range that need to make assumptions about the underlying range. Consider
>  a simple range Retro that iterates another range in reverse order:
> 
> struct Retro(R)
> {
>     private R _original;
>     ...
>     bool empty() { return _original.empty; }
> }
> 
> Should Retro make empty const or non-const? If it does, then ranges that
> make const non-empty won't work with Retro. If it doesn't, then users
> can't use empty for a const Retro.

Couldn't you do something like this?

struct Retro(R)
{
    private R _original;
    ...
    // Don't know how to write the isMemberConst test...
    static if( isMemberConst!( R, "empty" ) )
    {
        const bool empty() { return _original.empty; }
    }
    else
    {
        bool empty() { return _original.empty; }
    }
}

Propogate const-ness where possible, but don't prevent it from
functioning otherwise.

Incidentally, I'd have proposed something like:

    protectionOf!(_original.empty) bool empty() { return _original.empty; }

But I doubt that's possible with templates :P

> [snip]

I'm with dsimcha on the distinction between std.algorithm and std.range.

  -- Daniel



More information about the Digitalmars-d mailing list