Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2013
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 4.35 KB | None | 0 0
  1. /**
  2.    Support for collecting time ordered, historical data
  3. */
  4. module plus.utils.history;
  5.  
  6. version(ignored) import opmix.mix;
  7. import std.algorithm;
  8. import std.conv;
  9. import std.datetime;
  10. import std.exception;
  11. import std.functional;
  12. import std.range;
  13. import std.stdio;
  14. import std.traits;
  15.  
  16. struct History(V, alias orderingPred = "a.date < b.date") {
  17.   version(ignored) mixin ReadOnly!_history;
  18.   alias Unqual!V ValueType;
  19.   alias const(ValueType)[] ValueTypeArr;
  20.  
  21.   // custom <struct public History>
  22.  
  23.   pure {
  24.  
  25.     this(const(V)[] values...) {
  26.       foreach(ref value; values) {
  27.         _history ~= value;
  28.       }
  29.     }
  30.  
  31.     this(const(ValueTypeArr) history){
  32.       _history = history;
  33.     }
  34.  
  35.     void reserve(size_t size) {
  36.       _history.reserve(size);
  37.     }
  38.  
  39.     auto opSlice() const {
  40.       return _history[];
  41.     }
  42.  
  43.     auto opSlice(ulong a, ulong b) const {
  44.       return _history[a .. b];
  45.     }
  46.  
  47.     auto before(ref const(ValueType) vt) const {
  48.       auto sorted = assumeSorted!orderingPred(_history);
  49.       auto lb = sorted.lowerBound(vt);
  50.       return History!(V, orderingPred)(_history[0 .. lb.length]);
  51.     }
  52.  
  53.     auto after(ref const(ValueType) vt) const {
  54.       auto ub = assumeSorted!orderingPred(_history).upperBound(vt);
  55.       return History!(V, orderingPred)(_history[$-ub.length .. $]);
  56.     }
  57.  
  58.     auto onOrBefore(ref const(ValueType) vt) const {
  59.       auto ub = assumeSorted!orderingPred(_history).upperBound(vt);
  60.       return History!(V, orderingPred)(_history[0 .. $-ub.length]);
  61.     }
  62.  
  63.     auto onOrAfter(ref const(ValueType) vt) const {
  64.       auto lb = assumeSorted!orderingPred(_history).lowerBound(vt);
  65.       return History!(V, orderingPred)(_history[lb.length .. $]);
  66.     }
  67.  
  68.     auto within(ref const(ValueType) start, ref const(ValueType) end) const {
  69.       auto left = before(end);
  70.       auto result = left.onOrAfter(start);
  71.       return result;
  72.     }
  73.  
  74.     @property size_t length() const {
  75.       return _history.length;
  76.     }
  77.  
  78.     @property size_t opDollar() const {
  79.       return _history.length;
  80.     }
  81.  
  82.     @property size_t empty() const {
  83.       return _history.length == 0;
  84.     }
  85.  
  86.     ref const(V) opIndex(size_t i) const {
  87.       return _history[i];
  88.     }
  89.  
  90.     @property ref const(V) front() const { return _history[0]; }
  91.     @property ref const(V) back() const { return _history[$-1];  }
  92.   }
  93.  
  94.   auto ref opOpAssign(string op, V)(auto ref const(V) additional) /*pure*/ if(op == "~") {
  95.     enforce(0 == _history.length ||
  96.             !binaryFun!(orderingPred)(additional, _history[$-1]),
  97.             text(V.stringof, " must be added in chronological order, but ",
  98.                  additional, " comes before ", _history[$-1]));
  99.     _history ~= additional;
  100.     return this;
  101.   }
  102.  
  103.   // end <struct public History>
  104.  
  105.   private {
  106.     ValueTypeArr _history;
  107.   }
  108. }
  109.  
  110. static if(1) unittest {
  111.   // custom <unittest history>
  112.  
  113.   static struct S {
  114.     DateTime date;
  115.     double val;
  116.   }
  117.  
  118.   alias History!(const(S), "a.date < b.date") SHistory;
  119.  
  120.   S s1 = S(DateTime(1999,1,1),23.3),
  121.     s2 = S(DateTime(2000,1,1), 24.3),
  122.     s3 = S(DateTime(2001,1,1), 100),
  123.     s4 = S(DateTime(2001,1,1), 200),
  124.     s5 = S(DateTime(2002,1,1), 200);
  125.  
  126.   auto shist = SHistory(s1, s2);
  127.  
  128.   shist ~= s3;
  129.   shist ~= s4;
  130.   shist ~= s5;
  131.  
  132.   auto hitNeedle = S(DateTime(2001,1,1), 0);
  133.   auto missNeedle = S(DateTime(2001,11,1), 0);
  134.   auto futureNeedle = S(DateTime(2002,1,2), 0);
  135.  
  136.   version(ignored) {
  137.     assert(typesDeepEqual(shist.before(hitNeedle), SHistory(s1, s2)));
  138.     assert(typesDeepEqual(shist.after(hitNeedle), SHistory(s5)));
  139.     assert(typesDeepEqual(shist.onOrAfter(hitNeedle), SHistory(s3, s4, s5)));
  140.     assert(typesDeepEqual(shist.onOrBefore(hitNeedle), SHistory(s1, s2, s3, s4)));
  141.  
  142.     assert(typesDeepEqual(shist.before(missNeedle), SHistory(s1, s2, s3, s4)));
  143.     assert(typesDeepEqual(shist.after(missNeedle), SHistory(s5)));
  144.  
  145.     assert(typesDeepEqual(shist.within(hitNeedle, missNeedle),
  146.                           SHistory(s3, s4)));
  147.     assert(typesDeepEqual(shist.within(s1, s5),
  148.                           SHistory(s1, s2, s3, s4)));
  149.     assert(typesDeepEqual(shist.within(s1, futureNeedle), shist));
  150.     assert(typesDeepEqual(shist.within(s5, futureNeedle), SHistory(s5)));
  151.   }
  152.  
  153.   // end <unittest history>
  154. }
  155. version(ignored)
  156. version(unittest) {
  157.   import specd.specd;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement