module genite; import std.variant; import std.typetuple; import std.traits; //---------------------------------------------------------------- // Utils //---------------------------------------------------------------- private: /// Stack operations void push(T)(ref T[] a, T e) { a ~= e; } T pop(T)(ref T[] a) { scope(exit) a=a[0..$-1]; return a[$-1]; } T top(T)(const T[] a) { return a[$-1]; } /// Dummy tracer type class X {} //---------------------------------------------------------------- // Zenzen Iterator To Kankei Nai Utils //---------------------------------------------------------------- public: T Constructor_impl(T,P...)(P p) { T t = new T; t.tupleof[0..p.length] = p; return t; } /// Pseudo Constructor template Constructor(T, int N = T.tupleof.length) { alias Constructor_impl!(T, typeof(T.tupleof)[0..N]) Constructor; } //---------------------------------------------------------------- // Generic Iterator Implentation //---------------------------------------------------------------- public: /// Impl class Iterator(alias F, Elem) { private alias F!(Elem) Cont; private alias Variant StkE; private StkE[] stk; this( Cont c ) { stk.push(StkE(c)); } Elem get() { return stk.top().get!(Elem); } bool next() { if( stk.top().peek!(Elem) ) stk.pop(); while( stk.length>0 && stk.top().peek!(Cont) ) if( auto c = stk.pop().get!(Cont) ) foreach_reverse( i,f; c.tupleof ) static if( is(FieldTypeTuple!(F!(X))[i] == F!(X)) || is(FieldTypeTuple!(F!(X))[i] == X) ) stk.push(StkE(f)); return stk.length > 0; } } /// Helper function for generating a iterator from a container Iterator!(F,T) iterator(alias F,T)(F!(T) t) { return new typeof(return)(t); }