nested enum like template generator
JS
js.mdnq at gmail.com
Tue Jul 16 16:01:09 PDT 2013
On Tuesday, 16 July 2013 at 21:12:36 UTC, Ali Çehreli wrote:
> On 07/16/2013 02:01 PM, Ali Çehreli wrote:
>
> > On 07/16/2013 01:40 PM, JS wrote:
>
> > > It would be nice if we had some way to data globally(in
> module).
> > >
> > > e.g., __ctfestore["name"] = value;
> >
> > I would expect model-level objects start their lives after
> the program
> > starts running but their initial value can be calculated
> during compile
> > time:
> >
> > import std.stdio;
> > import std.conv;
> >
> > int[string] ctfestore;
> >
> > static this()
> > {
> > ctfestore = A!().globalFunc();
> > }
>
> Ok, I've been silly. That's not CTFE. I meant something like
> this:
>
> static this()
> {
> enum initialValue = A!().globalFunc();
> ctfestore = initialValue;
> }
>
> And only then I got the problem:
>
> > template A()
> > {
> > int c;
> >
> > int[string] globalFunc()
> > {
> > int[string] result;
> >
> > void func()
> > {
> > for ( ; c < 10; ++c) {
>
> Error: static variable c cannot be read at compile time
> called from here: func()
> called from here: globalFunc()
>
> > result[c.to!string] = c;
> > }
> > }
> >
> > func();
> > return result;
> > }
> > }
> >
> > void main()
> > {
> > writeln(ctfestore);
> > }
> >
> > Prints:
> >
> > ["0":0, "4":4, "8":8, "1":1, "5":5, "9":9, "2":2, "6":6,
> "3":3, "7":7]
>
> Ali
yes, that error is the bitch that D loves to slap me with
constantly when using ctfe's and I have to use wierd methods to
get around it. Note that I am mainly talking about string mixins
but the issue is that c is a template variable which is a compile
time construct that has no real meaning inside a ctfe(if that
makes sense). This is why nested functions have to be used... but
then if you want global variables(cross-template variables) you
need some other technique, if it's even possible.
template A() {
int c; // doesn't create a variable c for functions in the
template to use but tells the template define a variable when
used, I guess, as a normal template(not a mixin).
That is, I was initially thinking `int c;` created a compile time
variable inside the template but it doesn't... c does't even
exist until the template is used, but by then, it's too late...
specially if the template is used as a string mixin.
I think we would need somethign like
template A() {
template int c; // or possibly internal int c;
which defines c as a template variable(not a symbolic expression
inserted into code where A is used.
here is code that makes it clear:
module main;
import std.stdio, std.cstream, std.conv;
template A()
{
int c;
int foo() { return ++c; }
enum A = foo(); // Comment out to change A to a standard
template
}
void main(string[] argv)
{
alias A!() a;
//writeln(a.c, a.foo());
writeln(a);
}
Note that A is used two different ways. A as a sort of function
itself(with return foo() and, if that line is commented out, as a
sort of container holding an int and a function.
I think this is the confusion that I had not realizing they are
two different beasts.
When A is acting as a container, foo can use c no problem. When A
is acting as a ctfe, foo can't use c. I'm not sure if this is a
flaw, bug, or what...
I don't see any reason why it can't work both ways, and nesting
the template as a function works to solve the compile time error.
I think both concepts can be unified by having the compiler
implicitly wrap everything inside the template in a function,
accept assignments to A, when used as a ctfe. (this may not work
well though but a start in the right direction)
More information about the Digitalmars-d-learn
mailing list