opApply and const
Daniel Keep
daniel.keep.lists at gmail.com
Sun Dec 9 04:27:04 PST 2007
Bill Baxter wrote:
> I mentioned it in another thread but I just wanted to confirm it.
> Am I right in thinking that if we want to have user types act like
> built-in containers w.r.t iteration in D2 then we need to implement 12
> different versions of opApply?!
>
> Namely:
>
> [snip]
>
> That's a lot of opApply! I was already mildly annoyed by the four
> needed without const. But with both const (and invariant) it just seems
> downright silly.
>
> --bb
There's really no need for the counter versions. Just solve this the
same way Python did: with a wrapper. Admittedly, this doesn't seem to
work for more than one argument (foreach appears to dislike tuples for
arguments), but it illustrates the general concept.
-- Daniel
module enumerate;
import std.stdio;
import std.traits;
struct Enumerate(T)
{
private
{
T source;
alias ParameterTypeTuple!(typeof(T.opApply))[0] opApply_arg;
alias ParameterTypeTuple!(opApply_arg) opApply_type;
}
int opApply(int delegate(ref size_t, opApply_type) dg)
{
int result = 0;
size_t i = 0;
foreach( x ; source )
{
if( (result=dg(i,x)) != 0 ) break;
++i;
}
return result;
}
}
Enumerate!(T) enumerate(T)(T source)
{
return Enumerate!(T)(source);
}
class Foo
{
static const words = ["On"[],"a","Sunday,","riding","my","bike"];
int opApply(int delegate(ref char[]) dg)
{
int result = 0;
foreach( word ; words )
if( (result=dg(word)) != 0 ) break;
return result;
}
}
void main()
{
foreach( word ; new Foo )
writef("%s ",word);
writefln("");
writefln("");
foreach( i,word ; enumerate(new Foo) )
writefln("[%s] %s", i, word);
}
More information about the Digitalmars-d
mailing list