module pry.stream; import pry.traits; import std.range.primitives, std.traits, std.utf; struct SimpleStream(S) if(isSomeString!S) { private: size_t _index; S _range; public: alias Range = S; static struct Error { size_t location; string reason; } dchar front(){ size_t t = _index; return decode(_range, t); } this(S source){ _range = source; _index = 0; } void popFront(){ _index += stride(_range, _index); } @property bool empty(){ return _index == _range.length; } S slice(size_t i){ return _range[i .. _index]; } size_t mark(){ return _index; } void restore(size_t i){ _index = i; } @property size_t location() { return _index; } } static assert(isStream!(SimpleStream!string)); /// Wrap a given slicable random access range into a SimpleStream. auto stream(Range)(Range range) if(isRandomAccessRange!Range || isSomeString!Range) { return SimpleStream!Range(range); }