Multidimensional foreach

Simen kjaeraas simen.kjaras at gmail.com
Fri Dec 18 05:17:08 PST 2009


Simen kjaeraas <simen.kjaras at gmail.com> wrote:

> I have a function that returns an N-dimensional array, where N is a
> template parameter. Now I want to run a foreach loop through each
> element of this array. Is there a known and tested way to do this,
> or should I write my own templates to do it?

I wrote this implementation. Now, to get some meaningful indices
out of it. Do D2's ranges even support that? Oh, and I probably
need to rewrite it in terms of an index instead of slices to get
that working. Bah.

Ideas? Comments? Death threats?


template ArrayBaseType( T ) {
	alias T ArrayBaseType;
}

template ArrayBaseType( T : U[], U ) {
	alias ArrayBaseType!( U ) ArrayBaseType;
}

template MultiDimRange( T ) {
	alias T MultiDimRange;
}

struct MultiDimRange( T : U[][], U ) {
	T arr;
	
	MultiDimRange!( U[] ) subRange;
	
	this( T arg ) {
		arr = arg;
		subRange = arg[ 0 ];
	}
	
	void opAssign( T arg )  {
		arr = arg;
		subRange = arg[ 0 ];
	}
	
	bool empty( ) {
		return ( arr.length <= 1 ) && subRange.empty;
	}
	
	ArrayBaseType!( T ) front( ) {
		assert( !empty, "Called front on empty range." );
		if ( subRange.empty ) {
			typeof( subRange ) tmp = arr[ 1 ];
			return tmp.front( );
		} else {
			return subRange.front( );
		}
	}
	
	ArrayBaseType!( T ) popFront( ) {
		assert( !empty, "Called popFront on empty range." );
		ArrayBaseType!( T ) result;
		if ( subRange.empty ) {
			if ( arr.length <= 1 ) {
				throw new Exception( "Argh!" );
			}
			arr = arr[ 1..$ ];
			subRange = arr[0];
		}
		result = front( );
		subRange.popFront( );
		return result;
	}
}

MultiDimRange!( T ) multiDimRange( T )( T args ) {
	return MultiDimRange!( T )( args );
}

-- 
Simen


More information about the Digitalmars-d-learn mailing list