local enum
Mr.Bingo
Bingo at Namo.com
Sat Jul 7 18:48:35 UTC 2018
static foreach and enum do not play nice together!
import std.meta, std.stdio;
import std.string : leftJustify, center, rightJustify;
alias functions = staticMap!(ApplyRight!(Instantiate, string),
leftJustify, center, rightJustify);
void main()
{
string result = "|";
static foreach (f; functions)
{
enum y = &f;
// pragma(msg, y("hello", 17));
mixin("enum z = &"~f~".stringof;");
pragma(msg, z);
auto x = &f; // not a template, but a function
instantiation
result ~= x("hello", 17);
result ~= "|";
}
writeln(result); // "hello ; hello ; hello;
}
Besides the issue of trying to print out information about f at
compile time, which is what I was working on here, since the
above is a cool way to aggregate similar functions at compile
time, I run in to the notorious issue of using enum's in loops!
The enums are local in nature and are used to store intermediate
results but the looping tries to redefine them, which gives an
error.
Instead, how about having a new type or keyword such as __local
than can create a temporary enum that is only valid inside the
loop just like a local variable:
void main()
{
string result = "|";
static foreach (f; functions)
{
__local enum y = &f;
// pragma(msg, y("hello", 17));
mixin("__local enum z = &"~f~".stringof;");
pragma(msg, z);
auto x = &f; // not a template, but a function
instantiation
result ~= x("hello", 17);
result ~= "|";
}
writeln(result); // "hello ; hello ; hello;
}
here y and z then are local to the static for each and only exist
within it's scope. The compiler then will not error out about
redefinitions.
I know this is a trivial example that does not require __local
enums but in many cases they are necessary or reduce complexity.
Because I'm nice, I will give a hack that can be used, but this
hack should only be used by those who think the compiler
shouldn't automatically do this type of stuff for us:
void main()
{
static foreach (k, f; [113,22,13])
{
mixin("enum y"~to!string(k)~" = f;");
mixin("pragma(msg, y"~to!string(k)~");");
}
}
The idea is simply to create a new enum per loop. This is not an
acceptable hack but the compiler could do this internally really
simple, which is what __local would signify reducing all the
overhead and the above is then represented as
void main()
{
static foreach (f; [113,22,13])
{
__local enum y = f;
pragma(msg, y);
}
}
Much nicer and one can imagine how this would simplify a lot of
code.
Another, probably better idea is to simply allow enums to be
overwritten at compile time:
void main()
{
venum y;
static foreach (f; [113,22,13])
{
y = f;
pragma(msg, y);
}
}
More information about the Digitalmars-d
mailing list