Is it possible to add items to the arrays and hashes at compile time?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jun 7 08:20:17 PDT 2015


On 06/07/2015 05:56 AM, Dennis Ritchie wrote:
> On Sunday, 7 June 2015 at 12:42:12 UTC, Nicholas Wilson wrote:
>> On Sunday, 7 June 2015 at 12:30:12 UTC, Dennis Ritchie wrote:
>> try using a pure function + static e.g.
>>
>>  int[][int][int] somePureDefaultHash() pure
>> {
>>     ... //initialise it here
>> }
>>
>> ...
>> static hash = somePureDefaultHash();
>
> static int[][int][int] hash;
>
> hash[4][6] ~= [34, 65];
> static if (!!(4 in hash)) {}
> // Error: static variable hash cannot be read at compile time

/* Some function that generates an AA */
int[][int][int] initHash(int i)
{
     /* It is nice to see that this function is not called at run time */
     if (!__ctfe) {
         import std.stdio;
         writefln("%s is called at run time", __FUNCTION__);
     }

     return [i : [ i : [i, i] ] ];
}

/* Question: Is there a function to merge two AAs? */
int[][int][int] merge()(int[][int][int][] hashes...)
{
     /* It is nice to see that this function is not called at run time */
     if (!__ctfe) {
         import std.stdio;
         writefln("%s is called at run time", __FUNCTION__);
     }

     int[][int][int] result;

     foreach (hash; hashes) {
         foreach (key, value; hash) {
             result[key] = value;
         }
     }

     return result;
}

/* These three are generated at compile time */
enum firstPart = initHash(1);
enum secondPart = initHash(2);
enum int[][int][int] ctHash = merge(firstPart, secondPart);

/* Although ctHash is useful by itself, as H. S. Teoh said, every
  * reference to that AA at run time will generate a new AA. So, we
  * better refer to it just once.
  *
  * Luckily, as the __ctfe expressions above prove, the initialization
  * happens only once at compile time. I guess the memory layout of
  * 'ctHash' is simply copied to 'hash' below.
  */
int[][int][int] hash;
static this() {
     hash = ctHash;
}

void main()
{
     import std.stdio;

     writeln(hash);

     /* This is to see that the slice elements are not generated at
      * every reference. (It is good that .ptr value of each member
      * slice is the same.) */
     writeln(hash[1][1].ptr, ' ', hash[2][2].ptr);
     writeln(hash[1][1].ptr, ' ', hash[2][2].ptr);
}

Ali



More information about the Digitalmars-d-learn mailing list