August 31, 2005 useful mixin | ||||
---|---|---|---|---|
| ||||
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 |
September 01, 2005 Re: useful mixin | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | 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 |
Copyright © 1999-2021 by the D Language Foundation