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)
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:
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:
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?