_indexed_ iteration using opApply or range
Jonathan M Davis
jmdavisProg at gmx.com
Sun Dec 12 12:32:23 PST 2010
On Sunday 12 December 2010 12:15:00 Simen kjaeraas wrote:
> spir <denis.spir at gmail.com> wrote:
> > Hello,
> >
> > Had a nice time figuring out how to let opApply allow index iteration
> >
> > like:
> > foreach (i, x ; collection) {}
> >
> > Finally managed to do it adding 'i' everywhere:
> >
> > struct S1 {
> >
> > private int[] elements = [];
> > int opApply (int delegate (ref uint, ref int) block) {
> >
> > foreach (uint i, int n ; this.elements)
> >
> > block(i, n);
> >
> > return 0;
> >
> > }
> >
> > }
> >
> > Is this the intended idiom?
>
> opApply is a strange beast. Your version does not handle early returns
> or other errors, for which block's return type should be checked:
>
> int opApply( int delegate( ref uint, ref int ) block ) {
> foreach ( uint i, int n; this.elements ) {
> if ( auto ret = block( i, n ) != 0 ) {
> return ret;
> }
> }
> return 0;
> }
>
> As for the i, yes, you have to do it like that. In fact, you can have as
> many parameters you want for the delegate, and refer to them in the
> foreach:
>
> struct foo{
> int opApply( T... )( int delegate( ref T ) dg ) {
> return 0;
> }
> }
>
>
> foo f;
> foreach ( int i, double d, string s; f ) {}
>
> > Now, I'm trying to make this work with ranges instead (input range only
> > as of now). Seems i'm not smart enough to guess it alone...
>
> The trick to ranges is that they modify themselves. For a simple array
> wrapper
> range this may be a way:
>
> struct wrapper( T ) {
> T[] data;
> void popFront( ) {
> data = data[1..$];
> }
> ref T front( ) {
> return data[0];
> }
> bool empty( ) {
> return data.length == 0;
> }
> }
>
> Feel free to ask if you wonder about anything specific.
I'd also point out that the correct type for indexing is generally size_t.
That's what arrays use. I believe that size_t _is_ uint on 32 bit machines, but
it's going to be ulong on 64 bit machines. So, using uint is not portable.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list