Static associative array expressions

Steven Schveighoffer schveiguy at gmail.com
Mon Sep 20 13:02:22 UTC 2021


On 9/20/21 2:11 AM, Kagamin wrote:
> On Sunday, 19 September 2021 at 11:55:04 UTC, Steven Schveighoffer wrote:
>> On 9/19/21 1:43 AM, Stefan Koch wrote:
>>
>>> What do you guys think?
>>
>> I think an easier fix is just to change the call that does the AA 
>> literals to something that can be CTFEd. Right now it's an extern(C) 
>> hook that is opaque and takes void[] and TypeInfos.
>>
>> Something like:
>>
>> ```d
>> V[K] __aALiteral(V, K)(K[] keys, V[] values);
>> ```
>>
>> Then just lower the call to that, and if that is CTFEable, it works.
>>
> 
> Isn't that already kinda possible?
> A quick example:
> ```d
> struct StaticHashTable(TKey,TValue)
> {
>      struct Pair { TKey key, TValue value }
>      Pair[] items;
>      inout(TValue) opIndex(in TKey key) pure inout
>      {
>          foreach(i;items)if(i.key==key)return i.value;
>          assert(false);
>      }
> }
> 
> StaticHashTable!(TKey,TValue) make(TKey,TValue)(in TValue[TKey] aa) pure
> {
>      StaticHashTable!(TKey,TValue) s;
>      s.items.length=8;
>      s.items[0].key="a";
>      s.items[0].value=aa["a"];
>      return s;
> }
> 
> immutable s=make(["a":"b","c":"d"]);
> static assert(s["a"]=="b");
> ```
> That is, you can serialize a hashtable into anything with a relatively 
> easy syntax.

A `StaticHashTable` is not a builtin AA. The idea is to allow AAs to be 
generated at compile time, and then moved into usable runtime AAs.

One thing that is horrific, but possible, is to generate something like:

```d
struct FakeAA(K, V)
{
     // mimic the true AA impl
     struct FakeBucket {
         size_t hash;
         void * entry;
     }
     struct FakeAAImpl
     {
         FakeBucket[] buckets;
         uint used;
         uint deleted;
         TypeInfo_Struct entryTI;
         uint firstUsed;
         immutable uint keysz;
         immutable uint valsz;
         immutable uint valoff;
         ubyte flags;
     }
     FakeAAImpl *impl;
     V[K] __get() { return *(cast(V[K]*)&impl); }
     alias __get this;
}
```

And then build that thing at compile time based on the CTFE AA.

But I would still like to see the AA static initializer "just work".

-Steve


More information about the Digitalmars-d mailing list