More powerful foreach statements

Oskar Linde oskar.lindeREM at OVEgmail.com
Fri Jul 21 02:37:02 PDT 2006


Ben Phillips wrote:
> In article <e9ogh7$b1b$1 at digitaldaemon.com>, kris says...
>> 1)  foreach (int i, Foo f; ManyFooInstance)
>>              if (i is 0)
>>                  ....
>>
>> Or somthing like that.
>>
> 
> I tested it and it works, AND its documented. My fault.
> 
>> 2) foreach (int element; collection.reverse)
>> 	    ...
>>
>> where #2 returns a type which supports foreach. Typically, this would be 
>> some kind of Iterator construct. IIRC, someone already has a framework 
>> for such things? Was it Oskar?
>>
> 
> I remember seeing stuff like this in the MinTL code, but having to create a
> separate type for each type of iteration that you want to support seems rather
> silly (though adding a new language feature to do so may be equally silly as
> well).
> 
> Also, that still doesn't allow one to go reverse order through a builtin array
> with a foreach, unless of course you call ".reverse", which is needlessly
> expensive.

Yes it does. Something like this:

//Converts static arrays to dynamic arrays, leaving other types as
//they are
template MakeDynamic(T) {
         static if( is(typeof(Declare!(T).ptr[0]) E))
                 static if (is(T:E[]))
                         alias E[] MakeDynamic;
                 else
                         alias T MakeDynamic;
         else
                 alias T MakeDynamic;
}


struct ArrayReverseIterator(Array) {
	MakeDynamic!(Array) array;

	alias elementType!(Array) Element;

	int opApply(int delegate(inout Element) dg) {
		for (int i = array.length-1; i >= 0; i--) {
			if (auto status = dg(array[i]))
				return status;
		}
		return 0;
	}
}

ArrayReverseIterator!(Array) reverseIterator(Array)(Array array) {
	ArrayReverseIterator!(Array) iter;
	iter.array = array;
	return iter;
}


Usage:

foreach(x; "abcd".reverseIterator())
	writefln("x = %s",x);

/Oskar



More information about the Digitalmars-d mailing list