this(size_t length, T* ptr = null) {
this.ptr = ptr ? ptr : new T[length].ptr;
ref auto opIndex(size_t i) => ptr[i];
ref auto opIndex() => this;
auto opSlice(size_t beg, size_t end)
=> Array(end - beg, &ptr[beg]);
void opOpAssign(string op: "+", R)(R rhs) {
foreach(i; 0..length) ptr[i] += rhs;
foreach(i; 0..length) ptr[i] ~= rhs;
auto toString(ToSink sink) const {
const limit = length - 1;
foreach(i; 0..limit) sink.fmt("%s, ", ptr[i]);
sink.fmt("%s]", ptr[limit]);
this(string id, T value = 0) {
this(T value) { this.value = value; }
auto opCall(T x) => value = x;
auto opCall() inout => value;
auto opOpAssign(string op : "+")(T x)
auto opOpAssign(string op : "~")(string x) => id ~= x;
auto toString(ToSink sink) const
=> sink.fmt("%s: %s", id, value);
alias ToSink = void delegate(const(char)[]);
import std.stdio, std.format: fmt = formattedWrite;
data = [0: "zero", 1: "one", 2: "two", 3: "three",
4: "four", 5: "five", 6: "six"];
auto arr = new Type[len];
e = Type(data[i], cast(int)i);
auto pay = Array!Type(len, arr.ptr);