Skip to content

Instantly share code, notes, and snippets.

@JesseKPhillips
Created April 14, 2019 17:09
Show Gist options
  • Save JesseKPhillips/9fe592976261db05c7a83d4d631f74ef to your computer and use it in GitHub Desktop.
Save JesseKPhillips/9fe592976261db05c7a83d4d631f74ef to your computer and use it in GitHub Desktop.
Creates a range over a range that utilizes a function to create the next iteration off the previous result and the next element.
// Execute with dmd arguments: -unittest -main
import std.range;
import std.traits;
/**
* Calls fun with the previous result and the current iteration state.
*/
struct WithPrevious(alias fun, StateType) {
StateType _state;
ElementType!StateType current;
void popFront()
{
current = front();
_state.popFront();
}
@property ElementType!StateType front()
{
return fun(current, _state.front);
}
@property typeof(this) save()
{
auto ans = this;
ans._state = this._state.save();
return ans;
}
static if(isInfinite!StateType)
enum bool empty = false;
else
bool empty() const {
return _state.empty;
}
}
///
unittest {
import std.path;
import std.algorithm;
enum path = r"foo/bar/foobar".pathSplitter;
static assert(path.withPrevious!buildPath
.equal([
buildPath("foo"),
buildPath("foo","bar"),
buildPath("foo","bar","foobar")]));
}
WithPrevious!(fun, CommonType!(State))
withPrevious(alias fun, State)(State initial) if(isInputRange!State) {
CommonType!(State) state = initial;
return typeof(return)(state);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment