63 lines
1.5 KiB
D
63 lines
1.5 KiB
D
import std.stdio, std.array, std.string, std.datetime, std.traits;
|
|
|
|
/// A history variable.
|
|
struct HistoryVariable(T) {
|
|
/// A value in a point in time.
|
|
static struct HistoryValue {
|
|
SysTime time;
|
|
T value;
|
|
|
|
// Alternative to the more common toString.
|
|
//void toString(scope void delegate(string) output) const {
|
|
void toString(scope void delegate(const(char)[]) output)const {
|
|
output(format("%s; %s", time, value));
|
|
}
|
|
}
|
|
|
|
const(HistoryValue)[] values;
|
|
|
|
private void addValue(T value) {
|
|
values ~= HistoryValue(Clock.currTime(), value);
|
|
}
|
|
|
|
void opAssign(T value) {
|
|
addValue(value);
|
|
}
|
|
|
|
@property T currentValue() const pure nothrow {
|
|
return values.back.value;
|
|
}
|
|
|
|
alias currentValue this;
|
|
|
|
@property auto history() const pure nothrow {
|
|
return values;
|
|
}
|
|
|
|
/**
|
|
Demonstrating D's compile-time reflection features. The member
|
|
functions that are in this 'static if' block would be added for
|
|
types T that are arrays (including strings). */
|
|
static if (isArray!T) {
|
|
// Append-with-assign operator.
|
|
void opOpAssign(string op : "~")(T element) {
|
|
addValue(currentValue ~ element);
|
|
}
|
|
|
|
// Similar implementation for other array operators...
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
HistoryVariable!int x;
|
|
x = 1;
|
|
x = 2;
|
|
x = 3;
|
|
writefln("%(%s\n%)\n", x.history);
|
|
|
|
HistoryVariable!string s;
|
|
s = "hello";
|
|
s ~= " world";
|
|
s = "goodby";
|
|
writefln("%(%s\n%)", s.history);
|
|
}
|