On 07/12/2010 11:48 AM, Steven Schveighoffer wrote:
On Mon, 12 Jul 2010 11:05:33 -0400, Andrei Alexandrescu
<[email protected]> wrote:

On 07/12/2010 09:59 AM, Steven Schveighoffer wrote:
If I always have to do something like this in order to append a single
element:

put(r, (&elem)[0..1]);

No, the library does that. Look here:

http://www.dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L306


So you're saying it's not ok for an output range to support appending a
single element, but it's ok for put to support appending a single element?

Yes. The point is that with a delegate you must choose between accepting E and E[]. Given the constraint, it's better for everyone to accept E[] and let put() take care of the occasional E by doing the wraparoo (&elem)[0..1].

Well, all that will end up happening is cases where appending a single
element is the only possibility will produce overloaded add functions,
one that takes a single element, and one that takes an array. The one
that takes an array will look like this:

foreach(e; arr)
add(e);

That's fine. the point is that if you put this loop on the wrong side of the delegate, it's much less efficient.

I can tell you this for sure, because it's exactly what's in many
dcollections classes.

So what happens when you call put(r, e) for one of these output classes?
Instead of just calling add(e), it calls (add((&e)[0..1])) which in turn
goes through some needless loop, which then ends up calling add(e). I
don't see why this is preferable.

Ah, I see. There is a confusion. The array restriction is only for delegates. For straight ranges, you should accept individual Es. Let me copy the current definition of isOutputRange:

template isOutputRange(R, E)
{
    enum bool isOutputRange = is(typeof(
    {
        R r;
        E e;
        r.put(e);          // can write element to range
    }()))
        ||
    isInputRange!R && is(typeof(
    {
        R r;
        E e;
        r.front = e;       // can assign to the front of range
    }()))
        ||
        is(typeof(
    {
        R r;
        E[] es;
        r(es);
    }()));
}

Notice how the E[] requirement is for delegates only.


Andrei

Reply via email to