1 /// Lazy map-based range (mutate on function.) 2 module tern.algorithm.lazy_map; 3 4 import tern.traits; 5 import tern.object : loadLength; 6 import std.conv; 7 8 /// Lazy map-based range implementation. 9 public struct LazyMap(alias F, T) 10 if (isForward!T && isCallable!F) 11 { 12 T _range; 13 alias _range this; 14 15 public: 16 final: 17 size_t length; 18 19 string toString() 20 { 21 return this[0..length].to!string; 22 } 23 24 /// Gets the internally held range after predication. 25 T range() 26 { 27 if (length == 0) 28 return T.init; 29 30 return this[0..length]; 31 } 32 33 this(T range) 34 { 35 _range = range; 36 length = _range.loadLength; 37 } 38 39 T opSlice(ptrdiff_t start, ptrdiff_t end) 40 { 41 T slice; 42 foreach (ref u; _range) 43 { 44 slice ~= opIndex(start++); 45 46 if (start >= end) 47 break; 48 } 49 return slice; 50 } 51 52 ref auto opIndex(ptrdiff_t index) 53 { 54 return F(_range[index]); 55 throw new Throwable("Lazy filter index out of bounds!"); 56 } 57 58 size_t opDollar() 59 { 60 return length; 61 } 62 }