digitalmars.D - cannot interpret `cast(void)0` at compile time?
- Dadoum (75/75) May 09 2023 Hello,
- Salih Dincer (55/65) May 09 2023 To tell the truth, I'm a little confused. π
- Dadoum (7/60) May 09 2023 The problem I encounter happens because one of the variable is a
Hello, I am making a libplist wrapper and I am currently writing a template to handle associative arrays and preserve the order of the keys in the conversion process. (I already talked a bit about that [here](https://forum.dlang.org/post/pxevvegnaqueprwrkfos forum.dlang.org)) I have `plistConvert` which is a function with a lot of overloads to convert any other type to its plist counterpart already, and I want to have a template `pl` to convert associative arrays to PlistDict. Here is the code: ```d import std.stdio; // stubs class PlistDict {public void opIndexAssign(Plist element, string key) {writeln("key added: ", key);}} class Plist {} Plist plistConvert(T)(T val) => new Plist(); struct Wrapper { Plist delegate() val; } private Plist convertToPlist(alias U)() { return U.plistConvert(); } // Preserves the order since associative arrays are hashed at runtime. template pl(alias U) { static if (is(typeof(U): Wrapper[string])) { pragma(inline, true) PlistDict pl() { auto dict = new PlistDict(); static foreach (k, v; U) { dict[k] = v.val(); } return dict; } } else { static if (is(typeof(() => U.plistConvert()) == delegate)) { enum a = &convertToPlist!U; pragma(msg, a.stringof); enum pl = Wrapper(a); } else { enum pl = Wrapper(() => U.plistConvert()); } } } void main() { auto runtimeValue = "tac"; auto request = pl!([ "constantKey": pl!"CONSTANT", "runtimeKey": pl!runtimeValue ]); } ``` Transforming the associative array into an associative array of delegates was a trick given by ag0aep6g in the other thread, but now I encounter a new error: `Error: cannot interpret `cast(void)0` at compile time`. No line given or anything on DMD or LDC2 (on GDC it's giving a line in std.math.exponential???). The problem lies here: ```d pragma(msg, a.stringof); enum pl = Wrapper(a); ``` because if Wrapper gets a random argument, it will work. Also, giving a lambda to Wrapper as such: `enum pl = Wrapper(() => U.plistConvert());` \ is also not working: ``` delegate `app.pl(alias U)` is a nested function and cannot be accessed from `app.pl!(["constantKey":Wrapper(() pure nothrow safe => plistConvert("CONSTANT")), "runtimeKey":Wrapper(delegate () pure nothrow safe => plistConvert(runtimeValue))]).pl ``` So I feel kind of blocked, I don't understand the first error and the second one seems to not be resoluble in this design. Any thoughts?
May 09 2023
On Tuesday, 9 May 2023 at 09:54:21 UTC, Dadoum wrote:Hello, I am making a libplist wrapper and I am currently writing a template to handle associative arrays and preserve the order of the keys in the conversion process. (I already talked a bit about that [here](https://forum.dlang.org/post/pxevvegnaqueprwrkfos forum.dlang.org)) I have `plistConvert` which is a function with a lot of overloads to convert any other type to its plist counterpart already, and I want to have a template `pl` to convert associative arrays to PlistDict.To tell the truth, I'm a little confused. π So I can't understand why we should use the delegate. Below I will share a similar example and it includes a wrapper (Bar), your class (PlistDict) and it works: ```d alias AA = Bar[string]; struct Bar // Wrapper { int value; } class Foo // PlistDict { void opIndexAssign(Bar element, string key) { import std.stdio; key.writeln(" added, value: ", element.value); } } template PL(alias R) // pl { static if(is(typeof(R) == AA)) { auto PL() { auto dict = new Foo(); static foreach (K, V; R) { dict[K] = V; } return dict; } } else static if(is(typeof(R) == int)) { enum PL = Bar(R); } else { enum PL = Bar(); } } void main() { enum two = 2; auto request = PL!( [ "one": PL!1, "two": PL!two, "zero": PL!"zero" ] ); } /* one added, value: 1 two added, value: 2 zero added, value: 0 */ ``` SDB 79
May 09 2023
On Tuesday, 9 May 2023 at 23:27:07 UTC, Salih Dincer wrote:To tell the truth, I'm a little confused. π So I can't understand why we should use the delegate. Below I will share a similar example and it includes a wrapper (Bar), your class (PlistDict) and it works: ```d alias AA = Bar[string]; struct Bar // Wrapper { int value; } class Foo // PlistDict { void opIndexAssign(Bar element, string key) { import std.stdio; key.writeln(" added, value: ", element.value); } } template PL(alias R) // pl { static if(is(typeof(R) == AA)) { auto PL() { auto dict = new Foo(); static foreach (K, V; R) { dict[K] = V; } return dict; } } else static if(is(typeof(R) == int)) { enum PL = Bar(R); } else { enum PL = Bar(); } } void main() { enum two = 2; auto request = PL!( [ "one": PL!1, "two": PL!two, "zero": PL!"zero" ] ); } /* one added, value: 1 two added, value: 2 zero added, value: 0 */ ```The problem I encounter happens because one of the variable is a run time one. Instead of `enum two`, there is `auto two`, and when we pass it in a template, we have to put in a delegate to prevent the compiler from evaluating it (it canβt because itβs runtime). But then the template has to create a delegate to a local variable and the scope where you can use it is very limited.
May 09 2023