How to do foreach'able template Array?

David Medlock noone at nowhere.com
Tue Sep 5 17:58:03 PDT 2006


Derek Parnell wrote:
> On Fri, 01 Sep 2006 10:21:57 +0300, unknown wrote:
> 
> 
>>How to implement foreachable template Array class:
>>
>>class Array(T)
>>{
>>   T[] arr;
>>
>>   public this() {}
>>   public int count() { return arr.length; }
>>   public void add(T t) { arr.length = arr.length+1; arr[length-1] = t; }
>>
>>   opApply() {
>>     ???
>>   }
>>}
>>
>>I could not find out how to write correct operator opApply.
> 
> 
>     int opApply(int delegate(inout T elem) dg)
>     {   int result = 0;
> 
> 	for (int i = 0; i < arr.length; i++)
> 	{
> 	    result = dg(arr[i]);
> 	    if (result)
> 		break;
> 	}
> 	return result;
>     }
>     int opApply(int delegate(inout int idx; inout T elem) dg)
>     {   int result = 0;
> 
> 	for (int i = 0; i < arr.length; i++)
> 	{
> 	    result = dg(i, arr[i]);
> 	    if (result)
> 		break;
> 	}
> 	return result;
>     }


You can also turn any object into an iterable one with the following mixin:
//use this one for arrays

template applyThis( V, alias var )
{
   public int opApply( int delegate( inout V val ) dg )
   {
     int n = 0;
     foreach( V val; var ) { n = dg(val); if (n) break; }
     return n;
   }
   public int opApply( int delegate( inout int index, inout V val ) dg )
   {
     int n = 0;
     foreach( int index, V val; var ) { n = dg(index,val); if (n) break; }
     return n;
   }
   public V opIndex( int index )
   {
     if ( index<=var.length ) return V.init;
     return var[index];
   }
   public V opIndexAssign( V val, int index )
   {
     if ( var.length<=index ) var.length = index+1;
     return var[index] = val;
   }
}

// Use this one for associative arrays
template applyThis( K, V, alias var )
{
   public int opApply( int delegate( inout K key, inout V val ) dg )
   {
     int n = 0;
     foreach( K key, V val; var ) { n = dg(key,val); if (n) break; }
     return n;
   }

   public V opIndex( K key )
   {
     V* ptr = (key in var);
     if ( ptr is null ) return V.init;
     else return ptr[0];
   }

   public V opIndexAssign( V val, K key )
   {
     return var[key] = val;
   }
}


then say:

class Foo
{
   Bar[]	  array;

   mixin applyThis!(Bar,array);
}


Then you can use it like this:
Foo f = new Foo();
foreach( Bar b; foo ) {...}

-DavidM



More information about the Digitalmars-d-learn mailing list