www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Sorry, I just love templates, AAs and mixins :)

reply "Saaa" <empty needmail.com> writes:
public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
{
  mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
  if( elements == null )
  {
    ET[] temp;
    temp.length = 1;
    temp[0] = element;
    mixin(var_name~`[key] = temp;`);
  }
  else
  {
    (*elements).length = (*elements).length + 1;
    (*elements)[(*elements).length-1] = element;
  }
} 
Oct 16 2009
next sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
Why `key`? Where's `key` defined?
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
I don't understand this. Key is not used.
   }
 } 
And how do you use it? I tried to but I failed. Also passing a string as var_name is not nice. Isn't it better to write something like: char[int] x; x.add(1, 'h'); ?
Oct 17 2009
parent reply "Saaa" <empty needmail.com> writes:
Ary Borenszweig wrote:
 Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
Why `key`? Where's `key` defined?
Here: ...(KT key, ET element)
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
I don't understand this. Key is not used.
That's because there is already a link to the key through elements.
   }
 }
And how do you use it? I tried to but I failed.
You need a AA defined like this: BaseType[][KeyType] AAname; addToAA!("AAname")(KeyType key, BaseType value);
 Also passing a string as var_name is not nice. Isn't it better to write 
 something like:

 char[int] x;
 x.add(1, 'h');

 ?
The string is the actual variable name so I think that way doesn't work, right? Check the new version(shorter) in my other reply :D
Oct 18 2009
parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Saaa wrote:
 Ary Borenszweig wrote:
 Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
Why `key`? Where's `key` defined?
Here: ...(KT key, ET element)
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
I don't understand this. Key is not used.
That's because there is already a link to the key through elements.
   }
 }
And how do you use it? I tried to but I failed.
You need a AA defined like this: BaseType[][KeyType] AAname; addToAA!("AAname")(KeyType key, BaseType value);
 Also passing a string as var_name is not nice. Isn't it better to write 
 something like:

 char[int] x;
 x.add(1, 'h');

 ?
The string is the actual variable name so I think that way doesn't work, right? Check the new version(shorter) in my other reply :D
This worked just now with DMD 2.035: ////////////////////////////// BEGIN CODE module test1; import std .stdio ; public void add ( AAA : E[][K], K, E ) ( ref AAA aa, K key, E[] elem ... ) { if ( auto ptr = key in aa ) { *ptr ~= elem; } else { aa[ key ] = elem; } } void main () { int[][ char ] sandbox ; sandbox.add( 'a', 1 ); sandbox.add( 'b', 1, 2 ); sandbox.add( 'c', 1 ); sandbox.add( 'a', 2, 3 ); foreach ( key, elems ; sandbox ) { writeln(` [`, key, `] `, elems); } } ////////////////////////////// END CODE -- Chris Nicholson-Sauls
Oct 18 2009
parent "Saaa" <empty needmail.com> writes:
Chris Nicholson-Sauls wrote:
 Saaa wrote:
 Ary Borenszweig wrote:
 Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
Why `key`? Where's `key` defined?
Here: ...(KT key, ET element)
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
I don't understand this. Key is not used.
That's because there is already a link to the key through elements.
   }
 }
And how do you use it? I tried to but I failed.
You need a AA defined like this: BaseType[][KeyType] AAname; addToAA!("AAname")(KeyType key, BaseType value);
 Also passing a string as var_name is not nice. Isn't it better to write 
 something like:

 char[int] x;
 x.add(1, 'h');

 ?
The string is the actual variable name so I think that way doesn't work, right? Check the new version(shorter) in my other reply :D
This worked just now with DMD 2.035: ////////////////////////////// BEGIN CODE module test1; import std .stdio ; public void add ( AAA : E[][K], K, E ) ( ref AAA aa, K key, E[] elem ... ) { if ( auto ptr = key in aa ) { *ptr ~= elem; } else { aa[ key ] = elem; } } void main () { int[][ char ] sandbox ; sandbox.add( 'a', 1 ); sandbox.add( 'b', 1, 2 ); sandbox.add( 'c', 1 ); sandbox.add( 'a', 2, 3 ); foreach ( key, elems ; sandbox ) { writeln(` [`, key, `] `, elems); } } ////////////////////////////// END CODE -- Chris Nicholson-Sauls
Thanks, that looks nice. One small difference is that main() now needs to have access to sandbox whereas using mixins you could keep sandbox private to add()'s location.
Oct 19 2009
prev sibling parent reply grauzone <none example.net> writes:
Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
   }
 } 
 
 
It's unreadable. What the hell does it do? How do you use it? It's a good example how you can write-only code in D.
Oct 17 2009
parent reply Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
grauzone wrote:
 Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
   }
 }
It's unreadable.
No it isn't. It's an obfusticated version of if( key in var) var[key] ~= element; else var[key] = [element]; but who wants to write that boring code? :)
Oct 17 2009
parent "Saaa" <empty needmail.com> writes:
Ellery Newcomer wrote:
 grauzone wrote:
 Saaa wrote:
 public void addToAA(char[] var_name, KT, ET)(KT key, ET element)
 {
   mixin(ET.stringof~`[]* elements = key in `~var_name~`;`);
   if( elements == null )
   {
     ET[] temp;
     temp.length = 1;
     temp[0] = element;
     mixin(var_name~`[key] = temp;`);
   }
   else
   {
     (*elements).length = (*elements).length + 1;
     (*elements)[(*elements).length-1] = element;
   }
 }
It's unreadable.
No it isn't. It's an obfusticated version of if( key in var) var[key] ~= element; else var[key] = [element];
No, it isn't. It's obfusticated version of the generic version of that code :) I always forget ~= and somehow [] with a single variable in it looks strange, my bad! So, thanks! This is why I posted it in the first place; could you maybe look over DData as well :) I somehow like that I can tell the compiler precisely(mixins) how to generate generic(templates) code..
 but who wants to write that boring code? :)
Isn't your code slower because it always needs to search for the key twice :P Here is the new and improved version : public void addToAAA(char[] var_name, KT, ET)(KT key, ET element) { mixin(ET.stringof~`[]* elements = key in `~var_name~`;`); if( elements == null ) { mixin(var_name~`[key] = [element];`); } else { (*elements) ~= element; } }
Oct 18 2009