// Operator overloading to make a 1-based array
class Arr {
protected var value;
public proc create() {
if (oadl::arg(0).isarray()) {
// If an array is passed as the first arg, make
// it the initializer
if ((oadl::nargs() < 2) || !oadl::arg(1)) {
// By-reference unless "false" is the second arg
value = oadl::arg(0);
}
else {
// By-value otherwise
value = @oadl::arg(0);
}
}
else if (oadl::nargs()) {
// Otherwise, assume it is as if it were an iterator
value = new Array(oadl::argvec().pack());
forall (value#[i]) value#[i] = i+1;
}
else {
value = nil;
}
}
operator [] () { // a[i,j,k,...] => [](i,j,k,...)
var i, n = oadl::nargs(), res = value;
for (i = 0; i < n; i++) {
res = res[oadl::arg(i)-1];
}
return res;
}
operator [=] () { // a[i,j,k,...] = b => [=](b,i,j,k,...)
var n = oadl::nargs();
var val = oadl::arg(n-1);
var idx = oadl::argvec()[:n-2] - 1;
var hash = (idx*value.stride()).reduce(`+);
value#[hash] = val;
}
operator #[] (idx) {
return value#[idx-1];
}
operator #[=] (idx,val) {
value#[idx-1] = val;
}
operator + (rhs) {
if (rhs ?= Arr) rhs = rhs.value;
return new Arr(value + rhs);
}
operator \+ (lhs) {
return new Arr(lhs + value);
}
operator - (rhs) {
if (rhs ?= Arr) rhs = rhs.value;
return new Arr(value - rhs);
}
operator \- (lhs) {
return new Arr(lhs + value);
}
operator !- (lhs) {
return new Arr(-value);
}
operator * (rhs) {
if (rhs ?= Arr) rhs = rhs.value;
return new Arr(value * rhs);
}
operator \* (lhs) {
return new Arr(lhs * value);
}
operator / (rhs) {
if (rhs ?= Arr) rhs = rhs.value;
return new Arr(value / rhs);
}
operator \/ (lhs) {
return new Arr(lhs / value);
}
public proc print() {
"", value, '\n';
}
public proc sizeof() { return value.sizeof(); }
public proc shape() { return value.shape(); }
public proc rank() { return value.rank(); }
public proc length() { return value.length(); }
public proc isarray() { return true; }
public proc concat(b) { return new Arr(value ## b); }
public proc subr() {
var a = oadl::argvec();
forall (a[i]) if (a[i] != nil) a[i]--;
a = value.subr#(a);
return new Arr(a, false);
}
}
proc main()
{
var a = new Arr(2,3,4);
"a[1,1,1] = ", a[1,1,1], '\n';
forall (a[i,j,k]) a[i+1,j+1,k+1] *= 100;
forall (a#[i]) a#[i+1] -= 1;
a.print();
a += 1;
a /= 100;
a.print();
var b = a[1:2,1:2,1:2];
b[1,1,1] = 1000;
b.print();
a.print();
b = foreach (a[i,j,k]) {
"a[" ## String(i+1) ## ","
## String(j+1) ## ","
## String(k+1) ## "] = "
## String(a[i+1,j+1,k+1])
};
"", b, '\n';
}