Created
August 14, 2021 11:13
-
-
Save UplinkCoder/e60584a2c8f46ae4a490117b878ecec1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ctx_ = ctx; | |
import std.meta; | |
import std.traits; | |
template isStruct(alias S) | |
{ | |
enum isStruct = (is(S == struct)); | |
} | |
template isFunction(alias F) | |
{ | |
enum isFunction = (is(typeof(F) == function)); | |
} | |
template MemberOf(alias M) | |
{ | |
template MemberOfInner(string memberName) | |
{ | |
static if (is(mixin("M." ~ memberName)) || is(typeof(mixin("M." ~ memberName)))) | |
{ | |
alias MemberOfInner = mixin("M." ~ memberName); | |
} | |
} | |
alias MemberOf = MemberOfInner; | |
} | |
template MembersOf(alias M) | |
{ | |
template MembersOfInner(memberStrings...) | |
{ | |
alias MembersOfInner = staticMap!(MemberOf!M, memberStrings); | |
} | |
alias MembersOf = MembersOfInner; | |
} | |
template StructCollector(alias M) | |
{ | |
alias StructCollector | |
= Filter!(isStruct, staticMap!(MembersOf!M, __traits(allMembers, M))); | |
} | |
template FunctionCollector(alias M) | |
{ | |
alias FunctionCollector | |
= Filter!(isFunction, staticMap!(MembersOf!M, __traits(allMembers, M))); | |
} | |
template Params(alias F) | |
{ | |
static if (is(F == function)) | |
{ | |
static if (is(F P == __parameters)) | |
{ | |
alias Params = P; | |
} | |
} | |
else static if (is(typeof(F) P == __parameters)) | |
{ | |
alias Params = P; | |
} | |
else | |
{ | |
static assert(0, F.stringof ~ " is not a function"); | |
} | |
} | |
template isSame(alias A) | |
{ | |
template isSameInner(alias B) | |
{ | |
enum isSameInner = is(A == B); | |
} | |
alias isSame = isSameInner; | |
} | |
template isSame(alias A, alias B) | |
{ | |
enum isSame = is(A == B); | |
} | |
template FunctionHasParamType(alias F, alias P) | |
{ | |
alias FParams = Params!F; | |
// Unqual doesn't get rid of the const in our params :( | |
// so we have to run 2 filters | |
alias Fil1 = Filter!(isTOrConstT!P, FParams); | |
enum FunctionHasParamType = (Fil1.length != 0); | |
} | |
template isTOrConstT(alias T, alias A) | |
{ | |
alias ConstT = const(T); | |
enum isTOrConstT = isSame!(T, A) || isSame!(ConstT, A); | |
} | |
template isTOrConstT(alias T) | |
{ | |
template isTOrConstTInner(alias A) | |
{ | |
alias ConstT = const(T); | |
enum isTOrConstTInner = isSame!(T, A) || isSame!(ConstT, A); | |
} | |
alias isTOrConstT = isTOrConstTInner; | |
} | |
template FunctionHasContextType(alias F) | |
{ | |
enum FunctionHasContextType = FunctionHasParamType!(F, Structs[0]*); | |
} | |
alias Funcs = FunctionCollector!ctx_; | |
alias Structs = StructCollector!ctx_; | |
alias FilteredFuncs = Filter!(FunctionHasContextType, Funcs); | |
alias WrapperStrings = staticMap!(WrapperStringMap!(Structs[0]*), FilteredFuncs); | |
template WrapperStringMap(alias Ctx) | |
{ | |
template WrapperStringInner(alias F) | |
{ | |
enum WrapperStringInner = WrapperString!(Ctx, F); | |
} | |
alias WrapperStringMap = WrapperStringInner; | |
} | |
template WrapperString(alias Ctx, alias F) | |
{ | |
enum WrapperString = () { | |
alias RetType = ReturnType!F; | |
alias FParams = Params!(F); | |
string FName = __traits(identifier, F); | |
string result = RetType.stringof ~ " " ~ FName ~ " ("; | |
alias PIdents = ParameterIdentifierTuple!F; | |
bool wasCtx; | |
foreach(i, P;FParams) | |
{ | |
wasCtx = false; | |
static if (isTOrConstT!(Ctx, P)) | |
{ | |
wasCtx = true; | |
} | |
else | |
{ | |
result ~= P.stringof ~ " " ~ PIdents[i] ~ ", "; | |
} | |
} | |
if (!wasCtx) result = result[0 .. $-2]; | |
result ~= ")\n"; | |
result ~= " "; | |
result ~= FName ~ " ("; | |
foreach(i, P;FParams) | |
{ | |
static if (isTOrConstT!(Ctx*, P)) | |
{ | |
result ~= "ctx, "; | |
} | |
else | |
{ | |
result ~= PIdents[i] ~ ", "; | |
} | |
} | |
result = result[0 .. $-2] ~ ");\n"; | |
result ~= "}\n"; | |
return result; | |
} (); | |
} | |
// lets be generous and not count the cost of joining | |
// import std.array : join; | |
// pragma(msg, [WrapperStrings].join("\n")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment