History variables: Difference between revisions

Formatting and small changes in D entry
(Formatting and small changes in D entry)
Line 262:
 
=={{header|D}}==
D does not have history variables. The following implementation provides a generic HistoryVariable that protects the historical values by defining them as 'immutableconst'.
 
<lang d>import std.stdio, std.array, std.string, std.datetime, std.traits;
import std.array;
import std.string;
import std.datetime;
import std.traits;
 
/*// A history variable */.
/* A value in a point in time */
struct HistoryValueHistoryVariable(T) {
///* A value in a point in time */.
{
static struct HistoryValue {
SysTime time;
T value SysTime time;
{T value;
 
// Alternative to the more common toString.
void toString(scope void delegate(const(char)[]) output) const
//void toString(scope void delegate(string) output) const {
{
void toString(scope void delegate(const(char)[]) output) const {
output(format("%s; %s", time, value));
}
}
}
 
immutableconst(HistoryValue!T)[] values;
/* A history variable */
struct HistoryVariable(T)
{
immutable(HistoryValue!T)[] values;
 
private void addValue(T value) {
values ~= cast(immutable)HistoryValue!T(Clock.currTime(), value);
{
values ~= cast(immutable)HistoryValue!T(Clock.currTime, value);
}
 
void opAssign(T value) {
{
addValue(value);
}
 
@property T currentValue() const pure nothrow @property{
{
return values.back.value;
}
Line 304 ⟶ 296:
alias this = currentValue;
 
@property auto history() const pure nothrow @property{
{
return values;
}
 
{/**
/* Demonstrating D's compile-time reflection features. The member
* functions that are in this 'static if' block would be added for
* variablesfunctions that are ofin this 'static if' arrayblock typeswould (includingbe strings).added */for
types T that are arrays (including strings). */
static if (isArray!T) {
// Append-with-assign operator.
 
void opOpAssign(string op : "~")(T element) {
// Append-with-assign operator
void opOpAssign(string op : "addValue(currentValue ~")(T element);
{
auto newValue = currentValue ~ element;
addValue(newValue);
}
 
// ... similarSimilar implementation for other array operators ...
}
}
 
void testmain(T) : int)(){
struct HistoryVariable(T)!int x;
{
variablex = 21;
auto variable = HistoryVariable!int();
variablex = 32;
 
variablex = 13;
writefln("%(%s\n%)\n", variablex.history);
variable = 2;
variable = 3;
 
writefln("%(%s\n%)", variable.history);
}
 
void test(T : string)()
{
auto s = HistoryVariable!string();
 
auto variable = HistoryVariable!int()string s;
s = "hello";
s ~= " world";
s = "goodby";
 
writefln("%(%s\n%)", s.history);
}</lang>
}
'''{{out|Sample Output'''}}
 
void main()
{
test!int();
test!string();
}
</lang>
 
'''Sample Output'''
 
<pre>2013-Jan-19 23:04:55.1660302; 1
2013-Jan-19 23:04:55.1660407; 2
2013-Jan-19 23:04:55.1660424; 3
 
2013-Jan-19 23:04:55.1662551; hello
2013-Jan-19 23:04:55.1662581; hello world