Skip to content

Instantly share code, notes, and snippets.

/test.d Secret

Created October 23, 2016 19:15
Show Gist options
  • Save anonymous/4fb79b4aba79b59348273288993740cb to your computer and use it in GitHub Desktop.
Save anonymous/4fb79b4aba79b59348273288993740cb to your computer and use it in GitHub Desktop.
struct CumulativeSum(Range, Seed)
{
this(Range r, Seed s)
{
import std.range.primitives : empty;
_r = r;
_s = s;
if (!_r.empty) sumFront;
}
@property
auto front()
{
return _s;
}
void popFront()
{
import std.range.primitives : popFront, empty;
_r.popFront;
if (!_r.empty) sumFront;
}
@property
bool empty()
{
import std.range.primitives : empty;
return _r.empty;
}
private:
Range _r;
Seed _s;
Seed compensation = 0;
void sumFront()
{
import std.range.primitives : front;
immutable y = _r.front - compensation;
immutable t = _s + y;
compensation = (t - _s) - y;
_s = t;
}
}
auto cumulativeSum(Range)(Range r)
{
import std.range.primitives : ElementType;
import std.traits : isFloatingPoint;
alias E = ElementType!Range;
static if (isFloatingPoint!E) alias Seed = typeof(E.init + 0.0);
else alias Seed = typeof(E.init + E.init);
return r.cumulativeSum(Seed(0));
}
auto cumulativeSum(Range, Seed)(Range r, Seed s)
{
import std.traits : isFloatingPoint;
// import std.algorithm.iteration : cumulativeFold; // Not in release yet
static if (isFloatingPoint!Seed) return CumulativeSum!(Range, Seed)(r, s);
else return r.cumulativeFold!((a, b) => a + b)(s);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment