On Fri, 22 May 2009 15:55:52 -0400, Andrei Alexandrescu <[email protected]> wrote:

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.

This is why I was suggesting that foreach has to support both the simple popNext API and the range API. Which sucks, but I can't see a way around it without using pointers...


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.

Then maybe we have to come up with a better pointer... I kind of like the way classes work for this. Comparing them to null does what you want it to do, but doing anything else with it forwards to the underlying data. It's rebindable, and you can't do arithmetic on the pointer.

ref accomplishes all of this, except you can't get at the underlying pointer to do things like compare to null or rebind. Maybe we simply need some new operators to get at the ref addresses.

ref T popNext();
ref T t; // initialized to null
while((t =& popNext()) ==& null)
...
Still doesn't look as good as:

while(auto t = popNext())

Hm.. what about returning an array of 0 or one element? (ugh).

What about a type which acts like a class reference for simple data types:

struct rref(T)
{
  prviate T *data;
  ref T opStar() {return *data;}
  ref T opDot() {return *data;}
  void opAssign(ref T t) {data = &t;}
}

Need some compiler help to allow comparing to null, probably want this to be a builtin type, and have some better syntax.

BTW, I like your solution the best too. I thought of using pointers, but decided against it because of the taboo factor.

-Steve

Reply via email to