digitalmars.D - useful mixin
- David Medlock (58/58) Aug 31 2005 This is no doubt been posted but I thought I would post it anyhow.
- Carlos Santander (24/93) Aug 31 2005 Funny: I defined a couple of similar mixins for my project, except that ...
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 ); } -DavidMFunny: 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