using Invercargill.DataStructures; namespace Invercargill.Modifiers { public class Cache : Enumerable { private Vector vector; private Enumerable inner; private Tracker inner_tracker; public Cache(Enumerable inner) { this.inner = inner; inner_tracker = this.inner.get_tracker(); vector = new Vector(); } public override uint? peek_count() { return inner.peek_count(); } public override EnumerableInfo get_info() { return new EnumerableInfo.infer_single(this, EnumerableCategory.CACHED, inner); } public override Tracker get_tracker () { var i = 0; return new AssertingLambdaTracker(() => has_nth(i), () => vector[i++]); } private bool has_nth(int n) { lock(vector) { if(vector.count() > n) { return true; } while(vector.count() <= n) { if(inner_tracker.has_next()) { vector.add(inner_tracker.get_next()); } else { return false; } } return true; } } } }