Overhauling the notion of output range
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Jul 12 10:49:50 PDT 2010
On 07/12/2010 11:48 AM, Steven Schveighoffer wrote:
> On Mon, 12 Jul 2010 11:05:33 -0400, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> 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
More information about the Digitalmars-d
mailing list