Skip to content

Instantly share code, notes, and snippets.

@yebblies
Created February 4, 2014 15:55
Show Gist options
  • Save yebblies/8806318 to your computer and use it in GitHub Desktop.
Save yebblies/8806318 to your computer and use it in GitHub Desktop.
Tempalted visitor pattern
import std.stdio;
import std.traits;
class A
{
abstract void accept(Visitor);
}
class B : A
{
override void accept(Visitor v) { v.visit(this); }
}
class C : A
{
override void accept(Visitor v) { v.visit(this); }
}
class Visitor
{
void visit(A a) { assert(0); }
void visit(B b) { visit(cast(A)b); }
void visit(C c) { visit(cast(A)c); }
}
string genvisitor(alias agg, string name)()
{
string r;
r ~= ReturnType!(__traits(getOverloads, agg, name)[0]).stringof ~ " result;\n";
r ~= "alias visit = super.visit;\n";
foreach(o; __traits(getOverloads, agg, name))
{
static assert(ParameterTypeTuple!o.length == 1);
r ~= "override void visit(" ~ ParameterTypeTuple!o[0].stringof ~ " x) { result = " ~ __traits(identifier, o) ~ "(x); }\n";
}
return r;
}
enum TVisitor(alias agg, string name) = genvisitor!(agg, name)();
class XVisitor : Visitor
{
mixin(TVisitor!(typeof(this), "doAdd"));
int doAdd(B b) { return 1; }
int doAdd(C c) { return 2; }
}
int doAdd(A a)
{
auto v = new XVisitor;
a.accept(v);
return v.result;
}
void main()
{
A b = new B;
A c = new C;
auto xv = new XVisitor;
writeln(b.doAdd());
writeln(c.doAdd());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment