ideas about ranges

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri May 22 12:55:52 PDT 2009


Steven Schveighoffer wrote:
> Another idea is to make the T the ref'd arg, similar to how the system 
> call read() works:
> 
> bool popNext(ref T);
> 
> This has some benefits:
> 
> 1) you aren't checking a temporary for emptyness, so it fits well within 
> a loop construct
> 2) you can avoid returning a dummy element in the empty range case.
> 3) you avoid returning a piece of possibly large data on the stack when 
> it's probably just going to get copied anyways (although the compiler 
> can sometimes optimize this).

We considered that as well. It is problematic because looking at 
elements always entails copying them, which is rather silly if you do it 
for e.g. an array.

By golly, I kid you not but the interface I personally like the most is:

struct ArchetypalInputRange(T)
{
     T* popNext();
}

popNext returns a pointer to a T (the value may be reused) or null when 
the range is done. Iteration becomes easy and efficient for all types. 
An input range would still have to keep a buffer (and return a pointer 
to it), but things are not awkward to implement.

Given the bad reputation that pointers have, I guess people wouldn't 
like this all that much.

> I'm not convinced that range is the best fit for ref'd data anyways, 
> opApply is much more adept at it.

If ranges aren't fit to mutate stuff, we failed. Many algorithms in 
std.algorithm mutate their data and I can't bring myself to think how 
I'd implement them all with opApply.

> How does implementation of popNext look?
> 
> bool popNext(R)(R r, ref ElementType!R elem)
>      if (isForwardRange!R)
> {
>      if (r.empty)
>          return false;
>      elem = r.front();
>      r.popFront();
>      return true;
> }

It forces a copy whenever you want to take a look at something.


Andrei



More information about the Digitalmars-d mailing list