Thread overview
Identifying associative array types from a template?
Dec 02, 2007
Christopher Wright
Dec 02, 2007
Christopher Wright
Dec 02, 2007
Kirk McDonald
Dec 02, 2007
Christopher Wright
December 02, 2007
I want to identify the types that make up an associative array that I get as a template parameter, something like:

template decomposeAA (T) {
   static if (is (TT TVal : TVal[TKey])) {
      alias Tuple!(TVal, TKey) decomposeAA;
   } else {
      static assert (false, "not an associative array");
   }
}


Now, if I put conditions on TKey, this works, at least in D2. If I don't put conditions on TKey, it always static asserts, even if I give it an associative array.

Is this a bug? Is there another way to get the key type and value type?
December 02, 2007
Christopher Wright wrote:
> I want to identify the types that make up an associative array that I get as a template parameter, something like:
> 
> template decomposeAA (T) {
>    static if (is (TT TVal : TVal[TKey])) {
>       alias Tuple!(TVal, TKey) decomposeAA;
>    } else {
>       static assert (false, "not an associative array");
>    }
> }
> 
> 
> Now, if I put conditions on TKey, this works, at least in D2. If I don't put conditions on TKey, it always static asserts, even if I give it an associative array.
> 
> Is this a bug? Is there another way to get the key type and value type?

Okay, for a workaround I can do:
alias typeof(T.keys[0]) TKey;
alias typeof(T[TKey.init]) TValue;

And that'll match primitive AA's and anything that offers a similar interface. Which is good enough for my purposes.

Still, I think the behavior of my initial attempt is wrong: it seems to follow the specs, and it's the naive approach, and it fails silently. It should at least have an error message.
December 02, 2007
Christopher Wright wrote:
> I want to identify the types that make up an associative array that I get as a template parameter, something like:
> 
> template decomposeAA (T) {
>    static if (is (TT TVal : TVal[TKey])) {
>       alias Tuple!(TVal, TKey) decomposeAA;
>    } else {
>       static assert (false, "not an associative array");
>    }
> }
> 
> 
> Now, if I put conditions on TKey, this works, at least in D2. If I don't put conditions on TKey, it always static asserts, even if I give it an associative array.
> 
> Is this a bug? Is there another way to get the key type and value type?

Pyd has used this template for about as long as I can remember:

template isAA(T) {
    const bool isAA = is(typeof(T.init.values[0])[typeof(T.init.keys[0])] == T);
}

Writing an AA decomposing template is easy, given that:

template decomposeAA(T) {
    static assert(isAA!(T), "Not an associative array!");
    alias Tuple!(typeof(T.init.values[0]), typeof(T.init.keys[0])) dcomposeAA;
}

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
December 02, 2007
Kirk McDonald wrote:
> Christopher Wright wrote:
>> I want to identify the types that make up an associative array that I get as a template parameter, something like:
>>
>> template decomposeAA (T) {
>>    static if (is (TT TVal : TVal[TKey])) {
>>       alias Tuple!(TVal, TKey) decomposeAA;
>>    } else {
>>       static assert (false, "not an associative array");
>>    }
>> }
>>
>>
>> Now, if I put conditions on TKey, this works, at least in D2. If I don't put conditions on TKey, it always static asserts, even if I give it an associative array.
>>
>> Is this a bug? Is there another way to get the key type and value type?
> 
> Pyd has used this template for about as long as I can remember:
> 
> template isAA(T) {
>     const bool isAA = is(typeof(T.init.values[0])[typeof(T.init.keys[0])] == T);
> }
> 
> Writing an AA decomposing template is easy, given that:
> 
> template decomposeAA(T) {
>     static assert(isAA!(T), "Not an associative array!");
>     alias Tuple!(typeof(T.init.values[0]), typeof(T.init.keys[0])) dcomposeAA;
> }
> 

Thanks, I wound up doing essentially that. I guess I'll avoid attempting complex is expressions in the future; I don't understand them very well.