Skip to content

Instantly share code, notes, and snippets.

@unleashy
Last active October 15, 2017 00:05
Show Gist options
  • Save unleashy/c40e9e6503c473d8c3fd07dd990b7e7f to your computer and use it in GitHub Desktop.
Save unleashy/c40e9e6503c473d8c3fd07dd990b7e7f to your computer and use it in GitHub Desktop.
generate is-spec
import std.string, std.algorithm, std.range.primitives;
// a | void a()
// a :: b, c, ... | void a(b, c, ...)
// a :: b, c, ... -> r | r a(b, c, ...)
// a -> r | r a()
string generateIsSpec(string typename, string spec)
{
auto buf = "{\nimport std.traits : lvalueOf;\n" ~
"return is(typeof(" ~ typename ~ ".init) == " ~ typename ~ ") &&\n";
auto specSplitted = spec.lineSplitter;
size_t i = 0;
foreach (const l; specSplitted) {
if (l.strip.empty) {
continue;
}
if (i != 0 && !specSplitted.empty) {
buf ~= " &&\n";
}
buf ~= "is(typeof(lvalueOf!(" ~ typename ~ ").";
if (auto parts = l.findSplit("::")) {
auto fname = parts[0].strip;
buf ~= fname ~ "(";
auto fspec = parts[2].findSplit("->");
auto fparams = (fspec ? fspec[0] : parts[2]).splitter(',');
if (!fparams.empty) {
auto j = 0;
foreach (const param; fparams) {
if (j != 0 && !fparams.empty) {
buf ~= ", ";
}
buf ~= "lvalueOf!(" ~ param.strip ~ ")";
++j;
}
buf ~= ")";
}
buf ~= ")";
auto fretType = fspec[2].strip;
if (!fretType.empty && fretType != "void") {
buf ~= " == " ~ fretType;
}
} else if (auto parts = l.findSplit("->")) {
auto fname = parts[0].strip;
buf ~= fname ~ "())";
auto fretType = parts[2].strip;
if (!fretType.empty && fretType != "void") {
buf ~= " == " ~ fretType;
}
} else {
buf ~= l.strip ~ "())";
}
buf ~= ")";
++i;
}
return buf ~ ";\n}()";
}
enum isThing(T) = mixin(generateIsSpec(
"T",
"
hello :: int, string -> Asd
ayy :: real
wellShit -> string
doit
"
));
struct Asd
{
int a;
string b;
}
struct Thing
{
static assert(isThing!Thing);
Asd hello(int a, string b)
{
return Asd(a, b);
}
void ayy(real hurr)
{
}
string wellShit()
{
return "ohoho";
}
void doit() {}
}
struct Foo(Thingo) if (isThing!Thingo)
{
Thingo t;
}
void main(string[] args)
{
auto foo = Foo!Thing();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment