diff tools/base.d ../tools/base.d
23a24,36
> 
> template Replace(char[] SOURCE, char[] WHAT, char[] WITH) {
>   static if(SOURCE.length<WHAT.length) const char[] Replace=SOURCE; else
>   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<WHERE.length) const char[] RInsert=WITH~SRC; else
>   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
94c94
<     Integers[5..10]~map((int e) { return e*3; })~toArray,
---
>     Integers[5..10]~maps!("_*3")~toArray,
102c102,103
<     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; }),
119a121
>     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/tests.d ../tools/tests.d
20c20
< void mustEqual(T, U)(char[] name, T src, U cmp) {
---
> /*void mustEqual(T, U)(char[] name, T src, U cmp) {
22a23,28
> }*/
> 
> 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
