diff tools/base.d ../tools/base.d 3a4 > 5a7 > 6a9 > 23a27,39 > > template Replace(char[] SOURCE, char[] WHAT, char[] WITH) { > static if(SOURCE.length static if(SOURCE[0..WHAT.length]==WHAT) const char[] Replace=WITH~Replace!(SOURCE[WHAT.length..$], WHAT, WITH); else > const char[] Replace=SOURCE[0]~Replace!(SOURCE[1..$], WHAT, WITH); > } > > // reverse insert at WHERE or start > template RInsert(char[] SRC, char[] WHERE, char[] WITH) { > static if(SRC.length static if(SRC[$-WHERE.length..$]==WHERE) const char[] RInsert=SRC~WITH; else > const char[] RInsert=RInsert!(SRC[0..$-1], WHERE, WITH)~SRC[$-1]; > } diff tools/ext.d ../tools/ext.d 55c55 < /// The new keyword, handled by a struct --- > /// The new "chain" keyword, handled by a struct 65c65 < bool next(ref int whuh) { --- > override bool next(ref int whuh) { 71a72 > /// If obj is C, then dg(cast(C)obj). Else dgElse. 74,75c75,76 < static if(is(R==void)) if (c) dg(c); else dgElse; < else if (c) return dg(c); else return dgElse(); --- > static if(is(R==void)) if (c) dg(c); else if (dgElse) dgElse; > else if (c) return dg(c); else if (dgElse) return dgElse(); 77a79 > /// Like ifIs, but throws an exception when the cast fails 94c96 < Integers[5..10]~map((int e) { return e*3; })~toArray, --- > Integers[5..10]~maps!("_*3")~toArray, 102c104,105 < Integers[10..20]~filter((int e) { return (e%2)?true:false; }), --- > Integers[10..20]~filters!("(_%2)?true:false"), > Integers[10..20]~filter(function(int foo) { return (foo%2)?true:false; }), 119a123 > Integers[0..10]~tszip(Integers[10..20])~maps!("_.values[0]*_.values[1]")~reduces!("+=_"), diff tools/iter.d ../tools/iter.d 2a3 > import std.traits; 61,64c62,79 < struct _map(T, U) { < U delegate(T) dg; < MapIterator!(V.IterType, U) opCat_r(V)(V iter) { < return new MapIterator!(V.IterType, U)(iter, dg); --- > template ExpandSimplifiedFunc(char[] CODE, char[] VARNAME) { > const ExpandSimplifiedFunc=RInsert!(Replace!(CODE, "_", VARNAME), ";", "return "); > } > > template ExpandSimplifiedReduce(char[] CODE, char[] VAR1, char[] VAR2) { > const ExpandSimplifiedReduce=RInsert!(Replace!(CODE, "_", VAR2), ";", VAR1); > } > > struct _map(C) { > C callable; > MapIterator!(C) opCat_r(V)(V iter) { > return new MapIterator!(C)(iter, callable); > } > } > struct _map(char[] CODE) { > private const char[] fn="function(V.IterType MapHiddenParameter) { "~ExpandSimplifiedFunc!(CODE, "MapHiddenParameter")~"; }"; > MapIterator!(typeof(mixin(fn))) opCat_r(V)(V iter) { > return new MapIterator!(typeof(mixin(fn)))(iter, mixin(fn)); 67,72c82,88 < _map!(T, U) map(T, U)(U delegate(T) dg) { return _map!(T, U)(dg); } < class MapIterator(T, U) : NestedIterator!(U, T) { < U delegate(T) dg; < this(Iterator!(T) iter, U delegate(T) d) { super(iter); dg=d; } < bool next(ref U v) { < T sub=void; --- > _map!(CODE) maps(char[] CODE)() { _map!(CODE) e; return e; } > _map!(C) map(C)(C c) { return _map!(C)(c); } > class MapIterator(C) : NestedIterator!(ReturnType!(C), ParameterTypeTuple!(C)) { > C callable; > this(Iterator!(ParameterTypeTuple!(C)) iter, C c) { super(iter); callable=c; } > bool next(ref ReturnType!(C) v) { > ParameterTypeTuple!(C) sub=void; 74c90 < v=dg(sub); --- > v=callable(sub); 79,90c95,116 < struct _filter(T) { < bool delegate(T) dg; < FilterIterator!(V.IterType) opCat_r(V)(V iter) { < return new FilterIterator!(V.IterType)(iter, dg); < } < } < _filter!(T) filter(T)(bool delegate(T) dg) { return _filter!(T)(dg); } < class FilterIterator(T) : NestedIterator!(T, T) { < bool delegate(T) dg; < this(Iterator!(T) iter, bool delegate(T) d) { super(iter); dg=d; } < bool next(ref T v) { < do if (!child.next(v)) return false; while (!dg(v)); --- > struct _filter(C) { > C callable; > FilterIterator!(C) opCat_r(V)(V iter) { > return new FilterIterator!(C)(iter, callable); > } > } > struct _filter(char[] CODE) { > private const char[] fn="function(V.IterType MapHiddenParameter) { "~ExpandSimplifiedFunc!(CODE, "MapHiddenParameter")~"; }"; > FilterIterator!(typeof(mixin(fn))) opCat_r(V)(V iter) { > return new FilterIterator!(typeof(mixin(fn)))(iter, mixin(fn)); > } > } > _filter!(CODE) filters(char[] CODE)() { _filter!(CODE) e; return e; } > _filter!(C) filter(C)(C c) { > static assert(is(ReturnType!(C)==bool)); > return _filter!(C)(c); > } > class FilterIterator(C) : NestedIterator!(Pair!(ParameterTypeTuple!(C))) { > C callable; > this(Iterator!(ParameterTypeTuple!(C)[0]) iter, C c) { super(iter); callable=c; } > bool next(ref ParameterTypeTuple!(C)[0] v) { > do if (!child.next(v)) return false; while (!callable(v)); 114,117c140,147 < struct _reduce(T) { < void delegate(ref T, T) dg; < T opCat_r(Iterator!(T) iter) { < T res=void; --- > struct _reduce(C) { > C callable; > static assert(ParameterTypeTuple!(C).length==2); > static assert(is(ReturnType!(C)==void)); > alias ParameterTypeTuple!(C)[0] Type; > static assert(is(Type==ParameterTypeTuple!(C)[1])); > Type opCat_r(Iterator!(Type) iter) { > Type res=void; 119,120c149,161 < T next=void; < while (iter.next(next)) dg(res, next); --- > Type next=void; > while (iter.next(next)) callable(res, next); > return res; > } > } > struct _reduce(char[] CODE) { > private const char[] fn="function(ref V.IterType RedChangeP, V.IterType RedSrcP) { "~ > ExpandSimplifiedReduce!(CODE, "RedChangeP", "RedSrcP")~"; }"; > V.IterType opCat_r(V)(V iter) { > V.IterType res=void; > if (!iter.next(res)) throw new Exception("Stream too short to further reduce"); > typeof(res) next=void; > while (iter.next(next)) mixin(fn~"(res, next);"); 124c165,166 < _reduce!(T) reduce(T)(void delegate(ref T, T) dg) { return _reduce!(T)(dg); } --- > _reduce!(C) reduce(C)(C c) { return _reduce!(C)(c); } > _reduce!(CODE) reduces(char[] CODE)() { _reduce!(CODE) e; return e; } diff tools/mrv.d ../tools/mrv.d 4,6d3 < template Pointer(T) { alias T *Pointer; } < template Pointers(T...) { alias apply!(Pointer, T) Pointers; } < 24a22,24 > template Pointer(T) { alias T *Pointer; } > template Pointers(T...) { alias apply!(Pointer, T) Pointers; } > diff tools/tests.d ../tools/tests.d 13c13 < /// I <3 this line --- > // I <3 this line 20,22c20,23 < void mustEqual(T, U)(char[] name, T src, U cmp) { < if (src!=cmp) throw new Exception(name~": failed; "~format(src)~" is not "~format(cmp)~"."); < writefln(logResult(name, true, "Result equals "~format(cmp))); --- > void mustEqual(T...)(char[] name, T stuffs) { > foreach (thing; stuffs[0..$-1]) if (thing!=stuffs[$-1]) > throw new Exception(name~": failed; "~format(thing)~" is not "~format(stuffs[$-1])~"."); > writefln(logResult(name, true, "Result equals "~format(stuffs[$-1]))); Only in ../tools: tools