Thread overview
How to do foreach'able template Array?
Sep 01, 2006
unknown
Sep 01, 2006
Derek Parnell
Sep 06, 2006
David Medlock
September 01, 2006
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.
September 01, 2006
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
September 06, 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