www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Compile time initialization of AA

reply Xavier Bigand <flamaros.xavier gmail.com> writes:
I am trying to initialize an global immutable associative array of structs, but
it doesn't compile.
I am getting the following error message : "Error: not an associative array
initializer".

As I really need to store my data for a compile time purpose if we can't do
that with AA, I'll use arrays instead.

Here is my code :
struct EntryPoint
{
     string  moduleName;
     string  functionName;
     bool    beforeForwarding = false;
}

immutable EntryPoint[string]  entryPoints = [
     "wglDescribePixelFormat": {moduleName:"opengl32.forward_initialization",
functionName:"wglDescribePixelFormat"}
];
Mar 23 2018
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 03/23/2018 03:43 PM, Xavier Bigand wrote:
 I am trying to initialize an global immutable associative array of
 structs, but it doesn't compile.
Current solution is to initialize the AA in a 'static this()' block or ('shared static this()').
 I am getting the following error message : "Error: not an associative
 array initializer".

 As I really need to store my data for a compile time purpose if we can't
 do that with AA, I'll use arrays instead.
You can create and use AAs at compile time, which may be an acceptable use for your case as well: struct EntryPoint { string moduleName; string functionName; bool beforeForwarding = false; } EntryPoint[string] makeEntryPoints() { EntryPoint[string] entryPoints = [ "wglDescribePixelFormat": EntryPoint("opengl32.forward_initialization", "wglDescribePixelFormat") ]; return entryPoints; } string useEntryPoints(EntryPoint[string] aa) { return aa["wglDescribePixelFormat"].moduleName; } void main() { enum s = useEntryPoints(makeEntryPoints()); static const s2 = s; } The computations of 's' and 's2' in main are performed at compile time. If you can getaway with that, great. :) Otherwise, you have to initialize at runtime in a 'shared static this()' block, which can still be 'immutable': // NOTE the addition of 'pure': EntryPoint[string] makeEntryPoints() pure { // Same as above... } immutable EntryPoint[string] entryPoints; shared static this() { // Yes, can initialize immutable: entryPoints = makeEntryPoints(); } Ali
Mar 23 2018
prev sibling next sibling parent Seb <seb wilzba.ch> writes:
On Friday, 23 March 2018 at 22:43:47 UTC, Xavier Bigand wrote:
 I am trying to initialize an global immutable associative array 
 of structs, but it doesn't compile.
 I am getting the following error message : "Error: not an 
 associative array initializer".

 As I really need to store my data for a compile time purpose if 
 we can't do that with AA, I'll use arrays instead.

 Here is my code :
 struct EntryPoint
 {
     string  moduleName;
     string  functionName;
     bool    beforeForwarding = false;
 }

 immutable EntryPoint[string]  entryPoints = [
     "wglDescribePixelFormat": 
 {moduleName:"opengl32.forward_initialization", 
 functionName:"wglDescribePixelFormat"}
 ];
Try this: https://run.dlang.io/is/b7VQVB tl;dr: you can instantiate immutable data in the module constructors. --- struct EntryPoint { string moduleName; string functionName; bool beforeForwarding = false; } static immutable EntryPoint[string] entryPoints; shared static this() { EntryPoint p = {moduleName:"opengl32.forward_initialization", functionName:"wglDescribePixelFormat"}; entryPoints = ["wglDescribePixelFormat" : p]; } void main() { import std.stdio; entryPoints.writeln; } ---
Mar 23 2018
prev sibling next sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Friday, 23 March 2018 at 22:43:47 UTC, Xavier Bigand wrote:
 I am trying to initialize an global immutable associative array 
 of structs, but it doesn't compile.
 I am getting the following error message : "Error: not an 
 associative array initializer".

 As I really need to store my data for a compile time purpose if 
 we can't do that with AA, I'll use arrays instead.

 Here is my code :
 struct EntryPoint
 {
     string  moduleName;
     string  functionName;
     bool    beforeForwarding = false;
 }

 immutable EntryPoint[string]  entryPoints = [
     "wglDescribePixelFormat": 
 {moduleName:"opengl32.forward_initialization", 
 functionName:"wglDescribePixelFormat"}
 ];
Another solution, radically different is to not use an AA but a simple array. Instead of indexing on a string you could simply index on an enum type. As your array is compile time constant, the dynamic nature of AA is not really used and indexing on a enum value is faster and simpler anyway. The trick here is to generate the enum type at compile time. This can be achieved by a string mixin built at compile time. Here an example that I used to generate an enum from the values from another enum. In your case you can look where the "wglDescribePixelFormat" are defined and using imports or string building code. mixin({ string code = "enum LANBIT : ulong { "~ "init = 0,"; /* We set the dummy init value to 0 */ foreach(lanCode; __traits(allMembers, LANIDX)) { static if(lanCode == "IN") code ~= "INVALID = LANIDX2LANID(LANIDX."~lanCode~"),"; else code ~= lanCode~"= LANIDX2LANID(LANIDX."~lanCode~"),"; } code ~= " ALL = INVALID-1, /**< All bits except the LANID_INVALID */ OFFICIAL= BG|CS|DA|DE|EL|EN|ES|ET|FI|FR|GA|HR|HU|IT|LT|LV|MT|NL|PL|PT|RO|SK|SL|SV, /**< Official languages of the EU */ COOFFICIAL=CA|GL|EU|GD|CY /**< Co-official languages of the EU */ "; return code ~ "}"; }()); TL/DR defining constant compile time AA is an oxymoron. AA are by nature dynamic runtime creatures. if the indexes are compile time, a normal array with fixed indexes is enough.
Mar 24 2018
prev sibling parent Xavier Bigand <flamaros.xavier gmail.com> writes:
Le 23/03/2018 à 23:43, Xavier Bigand a écrit :
 I am trying to initialize an global immutable associative array of structs,
but it doesn't compile.
 I am getting the following error message : "Error: not an associative array
initializer".

 As I really need to store my data for a compile time purpose if we can't do
that with AA, I'll use arrays instead.

 Here is my code :
 struct EntryPoint
 {
     string  moduleName;
     string  functionName;
     bool    beforeForwarding = false;
 }

 immutable EntryPoint[string]  entryPoints = [
     "wglDescribePixelFormat": {moduleName:"opengl32.forward_initialization",
functionName:"wglDescribePixelFormat"}
 ];
I finally found something that works great: enum entryPoints = [ "wglChoosePixelFormat": EntryPoint("opengl32.forward_initialization", "client_wglChoosePixelFormat"), "wglDescribePixelFormat": EntryPoint("opengl32.forward_initialization", "client_wglDescribePixelFormat") ]; I am able to use this enum like an AA.
Mar 24 2018