static map as a type function

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Sep 24 05:13:49 UTC 2020


On 9/23/20 5:46 AM, Stefan Koch wrote:
> struct DummyType {} // just a dummy to get the right inference
> 
> auto getUDAs(alias T) { return __traits(getAttributes, T); } // needed 
> because that's the shortest thing that'll return alias[]
> 
> alias alias_array = typeof(getUDAs(DummyType));
> 
> auto static_map_tf(alias F)(alias_array types ...)
> {
>      typeof(F(DummyType))[] result;
>      result.length = types.length;
> 
>      foreach(i, t;types)
>      {
>          result[i] = F(t);
>      }
> 
>      return result;
> }
> 
> size_t sizeOf(alias t)
> {
>      return t.sizeof;
> }
> 
> alias Int = int;
> alias Ushort = ushort; // we need these aliases because the parser won't 
> allow us to call a function with a reserved type identifier.
> 
> static assert(static_map_tf!sizeOf(Int, Ushort) == [4, 2]);

Was looking at this example thinking, if only we had an object available 
for each type. And then it struck me - we already do. It's typeid. For 
each type T, typeid(T) yields an object (of type class TypeInfo) that 
can be copied, compared etc.

So the example could be written with typeid as such:

TypeInfo[] static_map_tf(alias F)(TypeInfo[] types...)
{
     typeof(F(types[0]))[] result;
     result.length = types.length;
     foreach(i, t; types)
     {
         result[i] = F(t);
     }
     return result;
}

size_t sizeOf(TypeInfo t)
{
     return mixin("(" ~ t.toString ~ ").sizeof");
}

static assert(static_map_tf!sizeOf(typeid(int), typeid(ushort)) == [4, 2]);

A few comments:

* Currently mixin closes the circle by taking back the typeid to the 
type it started from. It would be nice to have something better, e.g. 
t.Type would just be the type.

* In the current implementation values returned by typeid() cannot be 
read during compilation. So one question is if they could. Per 
https://github.com/dlang/druntime/pull/3174, that can be done largely at 
the library level.

* This could work with no change to the language definition. All that's 
needed to get lift is make TypeInfo values usable during compilation.



More information about the Digitalmars-d mailing list