Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 08, 2020 Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Hello, class A{ int i = 42; } Is there a way to get that 42? (Input is the class A and the name of the field 'i') A.i.init returns 0, so it doesn't care about the class. classinfo.m_init can be an option, but maybe there's a nicer way to do this? Thx! |
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:
> Hello,
>
> class A{
> int i = 42;
> }
>
> Is there a way to get that 42? (Input is the class A and the name of the field 'i')
>
> A.i.init returns 0, so it doesn't care about the class.
>
> classinfo.m_init can be an option, but maybe there's a nicer way to do this?
>
> Thx!
Try A.init.i
|
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:
> classinfo.m_init can be an option, but maybe there's a nicer way to do this?
eh the initializer i think is the best. you can sometimes shortcut it
pragma(msg, (new A).i);
which will call the ctor at ctfe and get the value. but if there isn't a default constructor that's harder. (of course at runtime you can yank it out of the init member... but ctfe will fail that i believe because of the reinterpret cast involved).
i can't think of a better way right now.
|
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Drug | On Sunday, 9 February 2020 at 00:15:47 UTC, Drug wrote:
> On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:
>> Hello,
>>
>> class A{
>> int i = 42;
>> }
>>
>> Is there a way to get that 42? (Input is the class A and the name of the field 'i')
>>
>> A.i.init returns 0, so it doesn't care about the class.
>>
>> classinfo.m_init can be an option, but maybe there's a nicer way to do this?
>>
>> Thx!
>
> Try A.init.i
I tried and A.init.stringof == "void()"
That generates a new question, what is void() ?
It has no sizeof property.
I guess it's the voidest of the voids in D :D
|
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote:
> On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote:
>> classinfo.m_init can be an option, but maybe there's a nicer way to do this?
>
> eh the initializer i think is the best. you can sometimes shortcut it
>
> pragma(msg, (new A).i);
>
> which will call the ctor at ctfe and get the value. but if there isn't a default constructor that's harder. (of course at runtime you can yank it out of the init member... but ctfe will fail that i believe because of the reinterpret cast involved).
>
> i can't think of a better way right now.
Thank you! It works!
Somehow I thought that 'new' is too much in CTFE, now I can rethink that.
|
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote: > On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote: Using what I've learned: class A{ int i=42; void init(){ // reInitialize class fields alias T = typeof(this); mixin([FieldNameTuple!T].map!(n => n~"=(new T)."~n~";").join); } } (I also like to live dangerously with string mixins :D) |
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On Sunday, 9 February 2020 at 00:57:05 UTC, realhet wrote: > On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote: >> On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote: mixin([FieldNameTuple!T].map!(n => n~"=(new T)."~n~";").join); After checking it in the asm debugger, it turned out, that it evaluates (new T) in runtime. (Silly me, because the constructor can have side effects.) So I first put the default values into an enum, and then do the assignment: foreach(n; FieldNameTuple!T){{ mixin("enum def = (new T).@; @ = def;".replace("@", n)); }} And that became as fast as it can be: mov dword ptr ds:[rax+10], 2A Thanks for the help again. |
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On Sunday, 9 February 2020 at 00:57:05 UTC, realhet wrote:
> On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote:
>> On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe wrote:
>
> Using what I've learned:
>
> class A{
> int i=42;
>
> void init(){ // reInitialize class fields
> alias T = typeof(this);
> mixin([FieldNameTuple!T].map!(n => n~"=(new T)."~n~";").join);
> }
>
> }
>
> (I also like to live dangerously with string mixins :D)
Tip: don't name a member function `init`, since it will conflict with the built-in `.init` property.
Here's a version without string mixins, for comparison:
void initialize() {
static foreach (i, field; typeof(this).tupleof) {{
// force compile-time evaluation
enum initValue = (new typeof(this)).tupleof[i];
field = initValue;
}}
}
|
February 08, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to realhet | On 2/8/20 7:39 PM, realhet wrote: > On Sunday, 9 February 2020 at 00:15:47 UTC, Drug wrote: >> On Saturday, 8 February 2020 at 23:37:56 UTC, realhet wrote: >>> Hello, >>> >>> class A{ >>> int i = 42; >>> } >>> >>> Is there a way to get that 42? (Input is the class A and the name of the field 'i') >>> >>> A.i.init returns 0, so it doesn't care about the class. >>> >>> classinfo.m_init can be an option, but maybe there's a nicer way to do this? >>> >>> Thx! >> >> Try A.init.i > > I tried and A.init.stringof == "void()" > > That generates a new question, what is void() ? > It has no sizeof property. > I guess it's the voidest of the voids in D :D Looks like you wrote a function void init() inside your class. Don't do that. D has a default init property. But as an aside, A.init has a value of null. So A.init.i => segfault. The 42 lives inside the intializer, which is a void array stored in the TypeInfo. But you probably don't want to get it that way. Adam's way is technically a good way to get it. But you don't necessarily need that (and it might not be what you are looking for -- the constructor could easily change i to a different value). Problem is that typeid cannot be read at compile time. https://issues.dlang.org/show_bug.cgi?id=7147 If you could do that, you could construct a "pre-constructed" class instance, and use it as the prototype for reading the int value. -Steve |
February 09, 2020 Re: Getting the initial value of a class field in compile time. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | On Sunday, 9 February 2020 at 01:19:55 UTC, Paul Backus wrote:
> On Sunday, 9 February 2020 at 00:57:05 UTC, realhet wrote:
>> On Sunday, 9 February 2020 at 00:41:12 UTC, realhet wrote:
>>> On Sunday, 9 February 2020 at 00:27:21 UTC, Adam D. Ruppe
> enum initValue = (new typeof(this)).tupleof[i];
Wow, thx! Accessing by index instead of name. Really powerful!
|
Copyright © 1999-2021 by the D Language Foundation