digitalmars.D - useful mixin
- David Medlock <noone nowhere.com> Aug 31 2005
- Carlos Santander <csantander619 gmail.com> Aug 31 2005
This is no doubt been posted but I thought I would post it anyhow.
Often you have a class which basically adds functionality over a map or
array. These two mixins implement the opApply/opIndex functions for you.
//// THE CODE ==================
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;
}
}
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;
}
}
/// Example: ==================
class MyWidgets
{
Widget[] widgets;
Widget[char[]] lookup;
//... other useful stuff
mixin applyThis!( Widget, widgets );
mixin applyThis!( char[], Widget, lookup );
}
-DavidM
Aug 31 2005
David Medlock escribió:This is no doubt been posted but I thought I would post it anyhow. Often you have a class which basically adds functionality over a map or array. These two mixins implement the opApply/opIndex functions for you. //// THE CODE ================== 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; } } 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; } } /// Example: ================== class MyWidgets { Widget[] widgets; Widget[char[]] lookup; //... other useful stuff mixin applyThis!( Widget, widgets ); mixin applyThis!( char[], Widget, lookup ); } -DavidM
Funny: I defined a couple of similar mixins for my project, except that I didn't define opIndex nor opIndexAssign. This solution has a problem when you need opApply for more than one collection. Eg: class MyWidgets { Widget[] widgets; Widget[char[]] lookup; Property[char[]] properties; //or whatever you want //... other useful stuff mixin applyThis!( Widget, widgets ); mixin applyThis!( char[], Widget, lookup ); mixin applyThis!( char[], Property, properties ); } The compiler won't let you do that, so you have to do: mixin applyThis!( Widget, widgets ) foo1; mixin applyThis!( char[], Widget, lookup ) foo2; mixin applyThis!( char[], Property, properties ) foo3; alias foo1.opApply opApply; alias foo2.opApply opApply; ... It's the only downside. -- Carlos Santander Bernal
Aug 31 2005








Carlos Santander <csantander619 gmail.com>