///
import { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from "./rt/common";
import { idof } from "./builtins";
import { Array } from "./array";
import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_HOLEYARRAY } from "./util/error";
import { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from "./util/string";
@final
export class StaticArray {
[key: number]: T;
// Note that the interface of StaticArray instances must be a semantically
// compatible subset of Array in order for syntax highlighting to work
// properly, for instance when creating static arrays from array literals.
// The additionally provided static methods take care of dealing with static
// arrays exclusively, without having to convert to Array first.
static fromArray(source: Array): StaticArray {
var length = source.length;
var outSize = length << alignof();
var out = changetype>(__new(outSize, idof>()));
if (isManaged()) {
let sourcePtr = source.dataStart;
for (let i = 0; i < length; ++i) {
let off = i << alignof();
let ref = load(sourcePtr + off);
store(changetype(out) + off, ref);
__link(changetype(out), ref, true);
}
} else {
memory.copy(changetype(out), source.dataStart, outSize);
}
return out;
}
static concat(source: StaticArray, other: StaticArray): StaticArray {
var sourceLen = source.length;
var otherLen = select(0, other.length, other === null);
var outLen = sourceLen + otherLen;
if (outLen > BLOCK_MAXSIZE >>> alignof()) throw new Error(E_INVALIDLENGTH);
var out = changetype>(__new(outLen << alignof(), idof>()));
var outStart = changetype(out);
var sourceSize = sourceLen << alignof();
if (isManaged()) {
for (let offset: usize = 0; offset < sourceSize; offset += sizeof()) {
let ref = load(changetype(source) + offset);
store(outStart + offset, ref);
__link(changetype(out), ref, true);
}
outStart += sourceSize;
let otherSize = otherLen << alignof();
for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {
let ref = load(changetype(other) + offset);
store(outStart + offset, ref);
__link(changetype(out), ref, true);
}
} else {
memory.copy(outStart, changetype(source), sourceSize);
memory.copy(outStart + sourceSize, changetype(other), otherLen << alignof());
}
return out;
}
static slice(source: StaticArray, start: i32 = 0, end: i32 = i32.MAX_VALUE): StaticArray {
var length = source.length;
start = start < 0 ? max(start + length, 0) : min(start, length);
end = end < 0 ? max(end + length, 0) : min(end , length);
length = max(end - start, 0);
var sliceSize = length << alignof();
var slice = changetype>(__new(sliceSize, idof>()));
var sourcePtr = changetype(source) + (start << alignof());
if (isManaged()) {
let off: usize = 0;
while (off < sliceSize) {
let ref = load(sourcePtr + off);
store(changetype(slice) + off, ref);
__link(changetype(slice), ref, true);
off += sizeof();
}
} else {
memory.copy(changetype(slice), sourcePtr, sliceSize);
}
return slice;
}
constructor(length: i32) {
if (length > BLOCK_MAXSIZE >>> alignof()) throw new RangeError(E_INVALIDLENGTH);
var outSize = length << alignof();
var out = changetype>(__new(outSize, idof>()));
memory.fill(changetype(out), 0, outSize);
return out;
}
get length(): i32 {
return changetype