ideas about ranges
Steven Schveighoffer
schveiguy at yahoo.com
Fri May 22 13:32:25 PDT 2009
On Fri, 22 May 2009 15:55:52 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> 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
More information about the Digitalmars-d
mailing list