digitalmars.D.learn - Compile time initialization of AA
- Xavier Bigand (13/13) Mar 23 2018 I am trying to initialize an global immutable associative array of struc...
- =?UTF-8?Q?Ali_=c3=87ehreli?= (39/45) Mar 23 2018 Current solution is to initialize the AA in a 'static this()' block or
- Seb (25/43) Mar 23 2018 Try this:
- Patrick Schluter (37/55) Mar 24 2018 Another solution, radically different is to not use an AA but a
- Xavier Bigand (7/20) Mar 24 2018 I finally found something that works great:
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
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
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
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
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