Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 24, 2013 Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Greetings! I have a problem in my code and I need an advice. I need possibility of creating "two-dimensional" AA in module scope that I can access at compile-time. I considered that it should be marked as enum to do this but I get strange error. There is a piece of code to test. //--------------- import std.stdio; enum string[int][string] pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ], "ks": [ 1: "first", 2: "second", 3: "third" ], "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ] ]; void main() { writeln(pohodEnumValues); } //--------END OF CODE ----- In dmd 2.064.2 I get following output: Compilation output: /d521/f517.d(4): Error: not an associative array initializer Elements of AA are used as template arguments so I need them at compile-time. I need help, please)) |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | Compiling following code makes another strange error message. import std.stdio; enum string[int][string] pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ].dup, "ks": [ 1: "first", 2: "second", 3: "third" ].dup, "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ].dup ]; void main() { writeln(pohodEnumValues); } //------- Compilation output: /opt/compilers/dmd2/include/object.di(435): Error: _aaApply2 cannot be interpreted at compile time, because it has no available source code /opt/compilers/dmd2/include/object.di(458): called from here: this.opApply(delegate int(ref int __applyArg0, ref string __applyArg1) => 0) /d895/f161.d(5): called from here: [3:"skiing", 5:"rafting", 7:"jumping"].dup() |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | Geez, I just spent 15' trying to make this work! AA + Compile-time are like oil and water.
You can use CTFE and an initializing function. It's a bit cumbersome, but it works.
module main;
import std.stdio;
string[int][string] initializePohod()
{
string[int][string] result;
result["vid"] = [ 3: "skiing", 5: "rafting", 7: "jumping" ];
result["ks"] = [ 1: "first", 2: "second", 3: "third" ];
result["prepare"] = [ 1:"planning", 3:"preparing", 5:"complete" ];
return result;
}
enum string[int][string] pohodEnumValues = initializePohod();
void main()
{
writeln(pohodEnumValues);
pragma(msg, pohodEnumValues); // there, accessible during compilation.
}
On Sun, Nov 24, 2013 at 1:01 PM, Uranuz <neuranuz@gmail.com> wrote:
> Greetings! I have a problem in my code and I need an advice. I need possibility of creating "two-dimensional" AA in module scope that I can access at compile-time. I considered that it should be marked as enum to do this but I get strange error. There is a piece of code to test.
>
> //---------------
> import std.stdio;
>
>
> enum string[int][string] pohodEnumValues = [
> "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ],
> "ks": [ 1: "first", 2: "second", 3: "third" ],
> "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ]
> ];
>
>
> void main()
> {
> writeln(pohodEnumValues);
>
> }
> //--------END OF CODE -----
>
> In dmd 2.064.2 I get following output:
>
> Compilation output:
> /d521/f517.d(4): Error: not an associative array initializer
>
> Elements of AA are used as template arguments so I need them at
> compile-time. I need help, please))
|
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Thanks! I'll try it. Another question is can I use immutable variables in compile time or they are just runtime variables that are once initialized and can't be modified? Is it only way to use manifest constants (enum). And what is semantics of enum constants? In D we have a lot of modifiers: static, enum, const, immutable. So sometimes I get stuck with question what to use? Could someone briefly explain the purpose of each one of these? |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | On Sunday, 24 November 2013 at 13:58:11 UTC, Philippe Sigaud
wrote:
> You can use CTFE and an initializing function. It's a bit cumbersome,
> but it works.
Lambda's to the rescue!
//----
enum string[int][string] pohodEnumValues =
(){
string[int][string] result;
result["vid"] = [ 3: "skiing", 5: "rafting", 7: "jumping" ];
result["ks"] = [ 1: "first", 2: "second", 3: "third" ];
result["prepare"] = [ 1:"planning", 3:"preparing",
5:"complete" ];
return result;
}();
//----
This is cleaner, IMO.
|
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | While looking at this example JavaScript syntax calling to mind)) |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | On Sun, Nov 24, 2013 at 5:14 PM, Uranuz <neuranuz@gmail.com> wrote: > Thanks! I'll try it. Another question is can I use immutable variables in compile time or they are just runtime variables that are once initialized and can't be modified? Is it only way to use manifest constants (enum). And what is semantics of enum constants? In D we have a lot of modifiers: static, enum, const, immutable. So sometimes I get stuck with question what to use? Could someone briefly explain the purpose of each one of these? A named enum has no 'real' existence: you cannot take its address (it has none), for example. It's a glorified literal, which is just replaced by its value every time it's used. Which means using enum` in conjunction with dynamic arrays and associative arrays is prone to drastically limit your code speed, because there will be an allocation for each instance. An immutable value is much more standard: it's allocated once, you can take its address and so on. It can be allocated at runtime and once it's allocated, no one can change it. It A const value cannot be modified in the current scope, but someone else, elsewhere, might. See: http://ddili.org/ders/d.en/const_and_immutable.html And also: http://ddili.org/ders/d.en/const_member_functions.html |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Sun, Nov 24, 2013 at 5:19 PM, monarch_dodra <monarchdodra@gmail.com> wrote:
> This is cleaner, IMO.
Well, in an ideal world, we wouldn't have to fall back to these contortions.
|
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | As far as I understand I can't use immutable values as template arguments. It's what I need in my code. I'll give an example. //--------------- import std.stdio; immutable(string[int][string]) pohodEnumValues; shared static this() { pohodEnumValues = [ "vid": [ 3: "skiing", 5: "rafting", 7: "jumping" ], "ks": [ 1: "first", 2: "second", 3: "third" ], "prepare": [ 1:"planning", 3:"preparing", 5:"complete" ] ]; } //Some template method void foo(string arg)() { //Some actions here } void main() { foreach( name, item; pohodEnumValues ) { foo!(name)(); //I need name at compile time here } } //----------------- Because we have only compile time foreach over tuple this is not working. Can someone give an advice, please? |
November 24, 2013 Re: Initializing "two-dimensional" compile-time enum | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | This example above will not compile because name is not a compile time expression. But I can't undersatnd how to make some kind of compile-time variable. If we have advanced metaprogramming features I think possibility of defining compile-time variables is needed. Am I right or not? I think defining compile-time array as Tuple!("first", "second", "third") looking sophisticated. |
Copyright © 1999-2021 by the D Language Foundation