Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- Support for collecting time ordered, historical data
- */
- module plus.utils.history;
- version(ignored) import opmix.mix;
- import std.algorithm;
- import std.conv;
- import std.datetime;
- import std.exception;
- import std.functional;
- import std.range;
- import std.stdio;
- import std.traits;
- struct History(V, alias orderingPred = "a.date < b.date") {
- version(ignored) mixin ReadOnly!_history;
- alias Unqual!V ValueType;
- alias const(ValueType)[] ValueTypeArr;
- // custom <struct public History>
- pure {
- this(const(V)[] values...) {
- foreach(ref value; values) {
- _history ~= value;
- }
- }
- this(const(ValueTypeArr) history){
- _history = history;
- }
- void reserve(size_t size) {
- _history.reserve(size);
- }
- auto opSlice() const {
- return _history[];
- }
- auto opSlice(ulong a, ulong b) const {
- return _history[a .. b];
- }
- auto before(ref const(ValueType) vt) const {
- auto sorted = assumeSorted!orderingPred(_history);
- auto lb = sorted.lowerBound(vt);
- return History!(V, orderingPred)(_history[0 .. lb.length]);
- }
- auto after(ref const(ValueType) vt) const {
- auto ub = assumeSorted!orderingPred(_history).upperBound(vt);
- return History!(V, orderingPred)(_history[$-ub.length .. $]);
- }
- auto onOrBefore(ref const(ValueType) vt) const {
- auto ub = assumeSorted!orderingPred(_history).upperBound(vt);
- return History!(V, orderingPred)(_history[0 .. $-ub.length]);
- }
- auto onOrAfter(ref const(ValueType) vt) const {
- auto lb = assumeSorted!orderingPred(_history).lowerBound(vt);
- return History!(V, orderingPred)(_history[lb.length .. $]);
- }
- auto within(ref const(ValueType) start, ref const(ValueType) end) const {
- auto left = before(end);
- auto result = left.onOrAfter(start);
- return result;
- }
- @property size_t length() const {
- return _history.length;
- }
- @property size_t opDollar() const {
- return _history.length;
- }
- @property size_t empty() const {
- return _history.length == 0;
- }
- ref const(V) opIndex(size_t i) const {
- return _history[i];
- }
- @property ref const(V) front() const { return _history[0]; }
- @property ref const(V) back() const { return _history[$-1]; }
- }
- auto ref opOpAssign(string op, V)(auto ref const(V) additional) /*pure*/ if(op == "~") {
- enforce(0 == _history.length ||
- !binaryFun!(orderingPred)(additional, _history[$-1]),
- text(V.stringof, " must be added in chronological order, but ",
- additional, " comes before ", _history[$-1]));
- _history ~= additional;
- return this;
- }
- // end <struct public History>
- private {
- ValueTypeArr _history;
- }
- }
- static if(1) unittest {
- // custom <unittest history>
- static struct S {
- DateTime date;
- double val;
- }
- alias History!(const(S), "a.date < b.date") SHistory;
- S s1 = S(DateTime(1999,1,1),23.3),
- s2 = S(DateTime(2000,1,1), 24.3),
- s3 = S(DateTime(2001,1,1), 100),
- s4 = S(DateTime(2001,1,1), 200),
- s5 = S(DateTime(2002,1,1), 200);
- auto shist = SHistory(s1, s2);
- shist ~= s3;
- shist ~= s4;
- shist ~= s5;
- auto hitNeedle = S(DateTime(2001,1,1), 0);
- auto missNeedle = S(DateTime(2001,11,1), 0);
- auto futureNeedle = S(DateTime(2002,1,2), 0);
- version(ignored) {
- assert(typesDeepEqual(shist.before(hitNeedle), SHistory(s1, s2)));
- assert(typesDeepEqual(shist.after(hitNeedle), SHistory(s5)));
- assert(typesDeepEqual(shist.onOrAfter(hitNeedle), SHistory(s3, s4, s5)));
- assert(typesDeepEqual(shist.onOrBefore(hitNeedle), SHistory(s1, s2, s3, s4)));
- assert(typesDeepEqual(shist.before(missNeedle), SHistory(s1, s2, s3, s4)));
- assert(typesDeepEqual(shist.after(missNeedle), SHistory(s5)));
- assert(typesDeepEqual(shist.within(hitNeedle, missNeedle),
- SHistory(s3, s4)));
- assert(typesDeepEqual(shist.within(s1, s5),
- SHistory(s1, s2, s3, s4)));
- assert(typesDeepEqual(shist.within(s1, futureNeedle), shist));
- assert(typesDeepEqual(shist.within(s5, futureNeedle), SHistory(s5)));
- }
- // end <unittest history>
- }
- version(ignored)
- version(unittest) {
- import specd.specd;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement