Add Fields to a struct with core.reflect
Stefan Koch
uplink.coder at googlemail.com
Wed Aug 18 22:27:14 UTC 2021
Good Evening,
I am currently creating the first `core.codegen` prototypes and I
gave myself the task to create a type from an existing one that
has added fields.
This is the code which uses core reflect.
```d
import core.reflect.reflect;
import core.reflect.dscope;
AggregateDeclaration aggregateFromType(const Type type)
{
AggregateDeclaration result = null;
if (auto ts = cast(TypeStruct)type)
{
result = ts.sym;
} else if (auto tc = cast(TypeClass)type)
{
result = tc.sym;
}
return result;
}
struct S
{
int x;
int y;
}
//@(core.codegen)
template addField(T, Type type, string name)
{
mixin(() {
static immutable srcAggType = cast(immutable Type)
nodeFromName("T");
static immutable srcAgg = cast(immutable
AggregateDeclaration) aggregateFromType(srcAggType);
assert(srcAgg, "type was not an aggregate");
string result = "struct addField {";
foreach(f;srcAgg.fields)
{
result ~= " " ~ f.type.identifier ~ " " ~ f.name ~
";\n";
}
result ~= " " ~ type.identifier ~ " " ~ name ~ ";\n";
result ~= "}\n";
return result;
} ());
}
static immutable ModuleScope = currentScope(); // we need to get
our module scope here
// because the
place nodeFromName is used in has no scope
alias i32 = int; // right now we nee this to make 'int' into a
declarartion.
alias SwithZW = addField!(addField!(S,
cast(Type)nodeFromName("i32", ModuleScope), "z"),
cast(Type)nodeFromName("i32", ModuleScope), "w");
pragma(msg, __traits(allMembers, SwithZW));
// outputs: tuple("x", "y", "z", "w");
```
I find it compelling enough that I am considering not to work on
`core.codegen` at the moment.
strings are actually alright to do this.
of course working with longer strings will quickly run into ctfe
limitations.
If only someone would improve the ctfe engine ;)
Cheers,
Stefan
P.S. this code needs a small extension to the compiler which
allows static class literals to be used as template parameters
but this is actually trivial to do :)
I'll post a PR for that soon.
More information about the Digitalmars-d
mailing list