Associative Array Initializers

Kevin Bealer kevinbealer at gmail.com
Thu Jan 25 00:15:07 PST 2007


Bill Baxter wrote:
> Serg Kovrov wrote:
>> Frits van Bommel wrote:
>>> No, that's one of the big missing things.
>>
>> Exactly!
>>
> 
> Seems like with tuples now it might be possible to make a function that 
> would do the trick:
> 
> int[char[]] months = AA("Jan", 1, "Feb", 2, "Mar", 3);
> 
> This could be another interesting challenge akin to Andrei's max() 
> challenge.  Write a function that constructs an AA from it's arguments 
> using the "best" types.
> 
> For that matter it would be interesting to see a template which 
> constructs an array using the best type to hold the arguments (as 
> opposed to just the type of the first argument).
> 
> --bb

I don't know why all this syntax is needed; in particular, without the 
a.dup, it crashes.  I don't know why -- it might be a bug or just a bad 
assumption on my part.

// -*- c++ -*-

import std.stdio;
import std.string;
import std.traits;

template AA_types(E...) {
     static if(isStaticArray!(typeof(E[0]))) {
         alias typeof(E[0].init)[] AA_key;
         alias typeof(E[1])        AA_value;
         alias AA_value[AA_key]    AA_type;
     } else {
         alias typeof(E[0])     AA_key;
         alias typeof(E[1])     AA_value;
         alias AA_value[AA_key] AA_type;
     }

}

AA_types!(E).AA_type AA(E...)(E values)
{
     static assert(values.length);
     static assert((values.length % 2) == 0);

     alias AA_types!(E).AA_key   TKey;
     alias AA_types!(E).AA_value TValue;
     alias AA_types!(E).AA_type  TArray;

     TKey   K;
     TArray rv;

     foreach(i, a; values) {
         static if ((i & 1) == 0) {
             static if (is(typeof(a.length))) {
                 K = a.dup;
             } else {
                 K = a;
             }
         }
         static if ((i & 1) == 1) {
             rv[K] = a;
         }
     }


     return rv;
}

int main(char[][] args)
{
     auto f = AA("run", 2, "the", 1, "you long", 4);

     foreach(i, a; f) {
         writefln("%s -> %s", i, a);
     }

     return 0;
}



More information about the Digitalmars-d mailing list