digitalmars.D - [core.reflect] autowrap example
- Stefan Koch (134/134) Oct 06 2021 Good Morning Everyone,
- Stefan Koch (4/6) Oct 06 2021 this won't compile of course.
Good Morning Everyone, I have been working a little to present some real world example of where core.reflect might be used. One of them is automatic wrapper generation. something). There is a library called autowrap which does this using templates and string mixins. Which tries to get the `__traits` reflection data into string form as soon as possible in order to avoid template overhead. ```D import core.reflect.reflect; import core.reflect.utils; string getDlangInterfaceType(const Type type) { assert(isAggregateType(T)); auto u = unqualType(type); auto slice_type = cast(TypeSlice) type; if (slice_type !is null) { u = unqualType(slice_type.nextOf); } string result; switch(u.serial) { case getType("Duration", ReflectFlags.Default, sc).serial : result = "Marshalled_Duration"; break; case getType("DateTime", ReflectFlags.Default, sc).serial : case getType("Date", ReflectFlags.Default, sc).serial : case getType("TimeOfDay", ReflectFlags.Default, sc).serial : result = "Marshalled_std_datetime_date"; break; case getType("SysTime", ReflectFlags.Default, sc).serial : result = "Marshalled_std_datetime_systime"; break; default : result = getAggregate(u).fqn(); } if (slice_type) { return result ~= "[]"; } return result; } static assert(() { auto st = nodeFromName("SysTime"); return st.getType().getDlangInterfaceType(); } () == "Marshalled_std_datetime_systime"); // works at compile time. struct S { DateTime[] dates; } static immutable s = nodeFromName("S", ReflectFlags.Members); void main() { string result; printf("%s\n", getType(s) .fields()[0] .getType() .getDlangInterfaceType().ptr ); // works at runtime as well -- output: "Marshalled_std_datetime_date[]" // perhaps with some garbage at the end if you are unlucky and it's not a '\0' } ``` Note the functions `getType`,`getAggregate`, `fields` `fqn` and `unqualType` are defined in the core.reflect utility module As a comparison here is the version which exists in `autowrap/csharp` today: ```D private string getDLangInterfaceType(T)() { import core.time : Duration; import std.datetime.date : Date, DateTime, TimeOfDay; import std.datetime.systime : SysTime; import std.traits : fullyQualifiedName, Unqual; alias U = Unqual!T; // FIXME This code really should be reworked so that there's no need to // check for arrays of date/time types, but rather it's part of the general // array handling. static if(is(U == Duration)) return "Marshalled_Duration"; else static if(is(U == DateTime) || is(U == Date) || is(U == TimeOfDay)) return "Marshalled_std_datetime_date"; else static if(is(U == SysTime)) return "Marshalled_std_datetime_systime"; else static if(is(U == Duration[])) return "Marshalled_Duration[]"; else static if(is(U == DateTime[]) || is(U == Date[]) || is(U == TimeOfDay[])) return "Marshalled_std_datetime_date[]"; else static if(is(U == SysTime[])) return "Marshalled_std_datetime_systime[]"; else return fullyQualifiedName!T; } ``` As you can see the version in auto-wrap appears to be shorter. mainly because there are no separate lines for the types `DateTime` `Time` and `TimeOfDay`. Also note that you cannot use the getType which takes a string at runtime. the only reason this works is because the cases are supposed to be constant expressions and at compile time it gets constant-folded into ```D case 2658LU: { result = "Marshalled_Duration"; break; } case 53134LU: case 55933LU: case 56951LU: { result = "Marshalled_std_datetime_date"; break; } case 99806LU: { result = "Marshalled_std_datetime_systime"; break; } ```
Oct 06 2021
On Wednesday, 6 October 2021 at 11:43:46 UTC, Stefan Koch wrote:Good Morning Everyone,assert(isAggregateType(T));this won't compile of course. I shouldn't edit my examples after running them :) just read the example without this line.
Oct 06 2021