www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to do foreach'able template Array?

reply unknown <sphinski netscape.net> writes:
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.
Sep 01 2006
parent reply Derek Parnell <derek nomail.afraid.org> writes:
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; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 1/09/2006 5:28:19 PM
Sep 01 2006
parent David Medlock <noone nowhere.com> writes:
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
Sep 05 2006