import { COMPARATOR, SORT } from "./util/sort"; import { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_NOTIMPLEMENTED } from "./util/error"; import { joinIntegerArray, joinFloatArray } from "./util/string"; import { REVERSE, FILL } from "./util/bytes"; import { idof } from "./builtins"; import { ArrayBufferView } from "./arraybuffer"; export class Int8Array extends ArrayBufferView { [key: number]: i8; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength; } @operator("[]") private __get(index: i32): i8 { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } @unsafe @operator("{}") private __uget(index: i32): i8 { return load(this.dataStart + index); } @operator("[]=") private __set(index: i32, value: native): void { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + index, value); } @unsafe @operator("{}=") private __uset(index: i32, value: native): void { store(this.dataStart + index, value); } at(index: i32): i8 { let len = this.byteLength; index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } includes(searchElement: i8, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: i8, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: i8, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array { FILL(this.dataStart, this.length, u8(value), start, end); return this; } sort(comparator: (a: i8, b: i8) => i32 = COMPARATOR()): Int8Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int8Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: i8, index: i32, self: Int8Array) => i8): Int8Array { return MAP(this, fn); } filter(fn: (value: i8, index: i32, self: Int8Array) => bool): Int8Array { return FILTER(this, fn); } findIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: i8, index: i32, self: Int8Array) => bool): bool { return SOME(this, fn); } every(fn: (value: i8, index: i32, self: Int8Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: i8, index: i32, self: Int8Array) => void): void { FOREACH(this, fn); } reverse(): Int8Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } toString(): string { return this.join(); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int8Array { return WRAP(buffer, byteOffset, length); } } export class Uint8Array extends ArrayBufferView { [key: number]: u8; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength; } @operator("[]") private __get(index: i32): u8 { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } @unsafe @operator("{}") private __uget(index: i32): u8 { return load(this.dataStart + index); } @operator("[]=") private __set(index: i32, value: native): void { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + index, value); } @unsafe @operator("{}=") private __uset(index: i32, value: native): void { store(this.dataStart + index, value); } at(index: i32): u8 { let len = this.byteLength; index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } includes(searchElement: u8, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: u8, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array { FILL(this.dataStart, this.length, u8(value), start, end); return this; } sort(comparator: (a: u8, b: u8) => i32 = COMPARATOR()): Uint8Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: u8, index: i32, self: Uint8Array) => u8): Uint8Array { return MAP(this, fn); } filter(fn: (value: u8, index: i32, self: Uint8Array) => bool): Uint8Array { return FILTER(this, fn); } findIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: u8, index: i32, self: Uint8Array) => bool): bool { return SOME(this, fn); } every(fn: (value: u8, index: i32, self: Uint8Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: u8, index: i32, self: Uint8Array) => void): void { FOREACH(this, fn); } reverse(): Uint8Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8Array { return WRAP(buffer, byteOffset, length); } } export class Uint8ClampedArray extends ArrayBufferView { [key: number]: u8; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength; } @operator("[]") private __get(index: i32): u8 { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } @unsafe @operator("{}") private __uget(index: i32): u8 { return load(this.dataStart + index); } @operator("[]=") private __set(index: i32, value: native): void { if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + index, ~(value >> 31) & (((255 - value) >> 31) | value)); } @unsafe @operator("{}=") private __uset(index: i32, value: native): void { store(this.dataStart + index, ~(value >> 31) & (((255 - value) >> 31) | value)); } at(index: i32): u8 { let len = this.byteLength; index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + index); } includes(searchElement: u8, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: u8, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray { value = ~(value >> 31) & (((255 - value) >> 31) | value); FILL(this.dataStart, this.length, u8(value), start, end); return this; } sort(comparator: (a: u8, b: u8) => i32 = COMPARATOR()): Uint8ClampedArray { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray { return SLICE(this, begin, end); } subarray(start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray { return SUBARRAY(this, start, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8ClampedArray { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: u8, index: i32, array: Uint8ClampedArray) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: u8, index: i32, array: Uint8ClampedArray) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: u8, index: i32, self: Uint8ClampedArray) => u8): Uint8ClampedArray { return MAP(this, fn); } filter(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): Uint8ClampedArray { return FILTER(this, fn); } findIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool { return SOME(this, fn); } every(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: u8, index: i32, self: Uint8ClampedArray) => void): void { FOREACH(this, fn); } reverse(): Uint8ClampedArray { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8ClampedArray { return WRAP(buffer, byteOffset, length); } } export class Int16Array extends ArrayBufferView { [key: number]: i16; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): i16 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): i16 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: native): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: native): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): i16 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: i16, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: i16, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: i16, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array { FILL(this.dataStart, this.length, u16(value), start, end); return this; } sort(comparator: (a: i16, b: i16) => i32 = COMPARATOR()): Int16Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int16Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: i16, index: i32, self: Int16Array) => i16): Int16Array { return MAP(this, fn); } filter(fn: (value: i16, index: i32, self: Int16Array) => bool): Int16Array { return FILTER(this, fn); } findIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: i16, index: i32, self: Int16Array) => bool): bool { return SOME(this, fn); } every(fn: (value: i16, index: i32, self: Int16Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: i16, index: i32, self: Int16Array) => void): void { FOREACH(this, fn); } reverse(): Int16Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int16Array { return WRAP(buffer, byteOffset, length); } } export class Uint16Array extends ArrayBufferView { [key: number]: u16; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): u16 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): u16 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: native): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: native): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): u16 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: u16, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: u16, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: u16, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array { FILL(this.dataStart, this.length, u16(value), start, end); return this; } sort(comparator: (a: u16, b: u16) => i32 = COMPARATOR()): Uint16Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint16Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: u16, index: i32, self: Uint16Array) => u16): Uint16Array { return MAP(this, fn); } filter(fn: (value: u16, index: i32, self: Uint16Array) => bool): Uint16Array { return FILTER(this, fn); } findIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: u16, index: i32, self: Uint16Array) => bool): bool { return SOME(this, fn); } every(fn: (value: u16, index: i32, self: Uint16Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: u16, index: i32, self: Uint16Array) => void): void { FOREACH(this, fn); } reverse(): Uint16Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint16Array { return WRAP(buffer, byteOffset, length); } } export class Int32Array extends ArrayBufferView { [key: number]: i32; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): i32 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): i32 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: i32): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: i32): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): i32 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: i32, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: i32, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: i32, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array { FILL(this.dataStart, this.length, u32(value), start, end); return this; } sort(comparator: (a: i32, b: i32) => i32 = COMPARATOR()): Int32Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int32Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: i32, index: i32, self: Int32Array) => i32): Int32Array { return MAP(this, fn); } filter(fn: (value: i32, index: i32, self: Int32Array) => bool): Int32Array { return FILTER(this, fn); } findIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: i32, index: i32, self: Int32Array) => bool): bool { return SOME(this, fn); } every(fn: (value: i32, index: i32, self: Int32Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: i32, index: i32, self: Int32Array) => void): void { FOREACH(this, fn); } reverse(): Int32Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int32Array { return WRAP(buffer, byteOffset, length); } } export class Uint32Array extends ArrayBufferView { [key: number]: u32; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): u32 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): u32 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: u32): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: u32): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): u32 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: u32, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: u32, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: u32, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array { FILL(this.dataStart, this.length, value, start, end); return this; } sort(comparator: (a: u32, b: u32) => i32 = COMPARATOR()): Uint32Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint32Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: u32, index: i32, self: Uint32Array) => u32): Uint32Array { return MAP(this, fn); } filter(fn: (value: u32, index: i32, self: Uint32Array) => bool): Uint32Array { return FILTER(this, fn); } findIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: u32, index: i32, self: Uint32Array) => bool): bool { return SOME(this, fn); } every(fn: (value: u32, index: i32, self: Uint32Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: u32, index: i32, self: Uint32Array) => void): void { FOREACH(this, fn); } reverse(): Uint32Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint32Array { return WRAP(buffer, byteOffset, length); } } export class Int64Array extends ArrayBufferView { [key: number]: i64; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): i64 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): i64 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: i64): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: i64): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): i64 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: i64, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: i64, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: i64, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: i64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array { FILL(this.dataStart, this.length, u64(value), start, end); return this; } sort(comparator: (a: i64, b: i64) => i32 = COMPARATOR()): Int64Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int64Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: i64, index: i32, self: Int64Array) => i64): Int64Array { return MAP(this, fn); } filter(fn: (value: i64, index: i32, self: Int64Array) => bool): Int64Array { return FILTER(this, fn); } findIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: i64, index: i32, self: Int64Array) => bool): bool { return SOME(this, fn); } every(fn: (value: i64, index: i32, self: Int64Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: i64, index: i32, self: Int64Array) => void): void { FOREACH(this, fn); } reverse(): Int64Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int64Array { return WRAP(buffer, byteOffset, length); } } export class Uint64Array extends ArrayBufferView { [key: number]: u64; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): u64 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): u64 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: u64): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: u64): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): u64 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: u64, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: u64, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: u64, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: u64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array { FILL(this.dataStart, this.length, value, start, end); return this; } sort(comparator: (a: u64, b: u64) => i32 = COMPARATOR()): Uint64Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint64Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: u64, index: i32, self: Uint64Array) => u64): Uint64Array { return MAP(this, fn); } filter(fn: (value: u64, index: i32, self: Uint64Array) => bool): Uint64Array { return FILTER(this, fn); } findIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: u64, index: i32, self: Uint64Array) => bool): bool { return SOME(this, fn); } every(fn: (value: u64, index: i32, self: Uint64Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: u64, index: i32, self: Uint64Array) => void): void { FOREACH(this, fn); } reverse(): Uint64Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinIntegerArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint64Array { return WRAP(buffer, byteOffset, length); } } export class Float32Array extends ArrayBufferView { [key: number]: f32; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): f32 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): f32 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: f32): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: f32): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): f32 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: f32, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: f32, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: f32, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: f32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array { FILL(this.dataStart, this.length, value, start, end); return this; } sort(comparator: (a: f32, b: f32) => i32 = COMPARATOR()): Float32Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float32Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: f32, index: i32, self: Float32Array) => f32): Float32Array { return MAP(this, fn); } filter(fn: (value: f32, index: i32, self: Float32Array) => bool): Float32Array { return FILTER(this, fn); } findIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: f32, index: i32, self: Float32Array) => bool): bool { return SOME(this, fn); } every(fn: (value: f32, index: i32, self: Float32Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: f32, index: i32, self: Float32Array) => void): void { FOREACH(this, fn); } reverse(): Float32Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinFloatArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float32Array { return WRAP(buffer, byteOffset, length); } } export class Float64Array extends ArrayBufferView { [key: number]: f64; // @ts-ignore: decorator @lazy static readonly BYTES_PER_ELEMENT: i32 = sizeof(); constructor(length: i32) { super(length, alignof()); } get length(): i32 { return this.byteLength >>> alignof(); } @operator("[]") private __get(index: i32): f64 { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } @unsafe @operator("{}") private __uget(index: i32): f64 { return load(this.dataStart + (index << alignof())); } @operator("[]=") private __set(index: i32, value: f64): void { if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE); store(this.dataStart + (index << alignof()), value); } @unsafe @operator("{}=") private __uset(index: i32, value: f64): void { store(this.dataStart + (index << alignof()), value); } at(index: i32): f64 { let len = this.byteLength >>> alignof(); index += select(0, len, index >= 0); if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE); return load(this.dataStart + (index << alignof())); } includes(searchElement: f64, fromIndex: i32 = 0): bool { return INCLUDES(this, searchElement, fromIndex); } indexOf(searchElement: f64, fromIndex: i32 = 0): i32 { return INDEX_OF(this, searchElement, fromIndex); } lastIndexOf(searchElement: f64, fromIndex: i32 = this.length): i32 { return LAST_INDEX_OF(this, searchElement, fromIndex); } fill(value: f64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array { FILL(this.dataStart, this.length, value, start, end); return this; } sort(comparator: (a: f64, b: f64) => i32 = COMPARATOR()): Float64Array { SORT(this.dataStart, this.length, comparator); return this; } slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array { return SLICE(this, begin, end); } subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array { return SUBARRAY(this, begin, end); } copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float64Array { return COPY_WITHIN(this, target, start, end); } reduce( fn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T, initialValue: T, ): T { return REDUCE(this, fn, initialValue); } reduceRight( fn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T, initialValue: T, ): T { return REDUCE_RIGHT(this, fn, initialValue); } map(fn: (value: f64, index: i32, self: Float64Array) => f64): Float64Array { return MAP(this, fn); } filter(fn: (value: f64, index: i32, self: Float64Array) => bool): Float64Array { return FILTER(this, fn); } findIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 { return FIND_INDEX(this, fn); } findLastIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 { return FIND_LAST_INDEX(this, fn); } some(fn: (value: f64, index: i32, self: Float64Array) => bool): bool { return SOME(this, fn); } every(fn: (value: f64, index: i32, self: Float64Array) => bool): bool { return EVERY(this, fn); } forEach(fn: (value: f64, index: i32, self: Float64Array) => void): void { FOREACH(this, fn); } reverse(): Float64Array { REVERSE(this.dataStart, this.length); return this; } join(separator: string = ","): string { return joinFloatArray(this.dataStart, this.length, separator); } set>(source: U, offset: i32 = 0): void { SET(this, source, offset); } toString(): string { return this.join(); } static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float64Array { return WRAP(buffer, byteOffset, length); } } // @ts-ignore: decorator @inline function SLICE( array: TArray, start: i32, end: i32 ): TArray { let len = array.length; start = start < 0 ? max(start + len, 0) : min(start, len); end = end < 0 ? max(end + len, 0) : min(end , len); len = max(end - start, 0); let slice = instantiate(len); memory.copy( slice.dataStart, array.dataStart + (start << alignof()), len << alignof() ); return slice; } // @ts-ignore: decorator @inline function SUBARRAY( array: TArray, begin: i32, end: i32 ): TArray { let len = array.length; begin = begin < 0 ? max(len + begin, 0) : min(begin, len); end = end < 0 ? max(len + end, 0) : min(end, len); end = max(end, begin); let out = changetype(__new(offsetof(), idof())); let buf = changetype(array.buffer); store(changetype(out), buf, offsetof("buffer")); __link(changetype(out), buf, false); store(changetype(out), array.dataStart + (begin << alignof()), offsetof("dataStart")); store(changetype(out), (end - begin) << alignof(), offsetof("byteLength")); return out; } // @ts-ignore: decorator @inline function COPY_WITHIN( array: TArray, target: i32, start: i32, end: i32 ): TArray { let len = array.length; let ptr = array.dataStart; end = min(end, len); let to = target < 0 ? max(len + target, 0) : min(target, len); let from = start < 0 ? max(len + start, 0) : min(start, len); let last = end < 0 ? max(len + end, 0) : min(end, len); let count = min(last - from, len - to); memory.copy( ptr + (to << alignof()), ptr + (from << alignof()), count << alignof() ); return array; } // @ts-ignore: decorator @inline function REDUCE( array: TArray, fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet, initialValue: TRet ): TRet { let ptr = array.dataStart; for (let i = 0, k = array.length; i < k; i++) { initialValue = fn(initialValue, load(ptr + (i << alignof())), i, array); } return initialValue; } // @ts-ignore: decorator @inline function REDUCE_RIGHT( array: TArray, fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet, initialValue: TRet ): TRet { let ptr = array.dataStart; for (let i = array.length - 1; i >= 0; i--) { initialValue = fn(initialValue, load(ptr + (i << alignof())), i, array); } return initialValue; } // @ts-ignore: decorator @inline function MAP( array: TArray, fn: (value: T, index: i32, self: TArray) => T, ): TArray { let len = array.length; let ptr = array.dataStart; let byteLength = len << alignof(); let out = changetype(__new(offsetof(), idof())); let buf = changetype(__new(byteLength, idof())); for (let i = 0; i < len; i++) { store( changetype(buf) + (i << alignof()), fn(load(ptr + (i << alignof())), i, array) ); } store(changetype(out), changetype(buf), offsetof("buffer")); __link(changetype(out), changetype(buf), false); store(changetype(out), changetype(buf), offsetof("dataStart")); store(changetype(out), byteLength, offsetof("byteLength")); return out; } // @ts-ignore: decorator @inline function FILTER( array: TArray, fn: (value: T, index: i32, self: TArray) => bool, ): TArray { let len = array.length; let out = changetype(__new(offsetof(), idof())); let buf = changetype(__new(len << alignof(), idof())); let dataStart = array.dataStart; let j: usize = 0; for (let i = 0; i < len; i++) { let value = load(dataStart + (i << alignof())); if (fn(value, i, array)) { store( changetype(buf) + (j++ << alignof()), value ); } } // shrink output buffer let byteLength = j << alignof(); let data = __renew(changetype(buf), byteLength); store(changetype(out), data, offsetof("buffer")); __link(changetype(out), data, false); store(changetype(out), byteLength, offsetof("byteLength")); store(changetype(out), data, offsetof("dataStart")); return out; } // @ts-ignore: decorator @inline function FIND_INDEX( array: TArray, fn: (value: T, index: i32, array: TArray) => bool, ): i32 { let ptr = array.dataStart; for (let i = 0, k = array.length; i < k; i++) { if (fn(load(ptr + (i << alignof())), i, array)) return i; } return -1; } // @ts-ignore: decorator @inline function FIND_LAST_INDEX( array: TArray, fn: (value: T, index: i32, array: TArray) => bool, ): i32 { let ptr = array.dataStart; for (let i = array.length - 1; i >= 0; --i) { if (fn(load(ptr + (i << alignof())), i, array)) return i; } return -1; } // @ts-ignore: decorator @inline function INCLUDES( array: TArray, searchElement: T, fromIndex: i32, ): bool { if (isFloat()) { let index: isize = fromIndex; let len: isize = array.length; if (len == 0 || index >= len) return false; if (index < 0) index = max(len + index, 0); let dataStart = array.dataStart; while (index < len) { let elem = load(dataStart + (index << alignof())); // @ts-ignore if (elem == searchElement || isNaN(elem) & isNaN(searchElement)) return true; ++index; } return false; } else { return INDEX_OF(array, searchElement, fromIndex) >= 0; } } // @ts-ignore: decorator @inline function INDEX_OF( array: TArray, searchElement: T, fromIndex: i32, ): i32 { let index: isize = fromIndex; let len: isize = array.length; if (len == 0 || index >= len) return -1; if (index < 0) index = max(len + index, 0); let dataStart = array.dataStart; while (index < len) { if (load(dataStart + (index << alignof())) == searchElement) return index; ++index; } return -1; } // @ts-ignore: decorator @inline function LAST_INDEX_OF( array: TArray, searchElement: T, fromIndex: i32, ): i32 { let index: isize = fromIndex; let len: isize = array.length; if (len == 0) return -1; if (index < 0) index = len + index; // no need to clamp else if (index >= len) index = len - 1; let dataStart = array.dataStart; while (index >= 0) { if (load(dataStart + (index << alignof())) == searchElement) return index; --index; } return -1; } // @ts-ignore: decorator @inline function SOME( array: TArray, fn: (value: T, index: i32, array: TArray) => bool, ): bool { let ptr = array.dataStart; for (let i = 0, k = array.length; i < k; i++) { if (fn(load(ptr + (i << alignof())), i, array)) return true; } return false; } // @ts-ignore: decorator @inline function EVERY( array: TArray, fn: (value: T, index: i32, array: TArray) => bool, ): bool { let ptr = array.dataStart; for (let i = 0, k = array.length; i < k; i++) { if (fn(load(ptr + (i << alignof())), i, array)) continue; return false; } return true; } // @ts-ignore: decorator @inline function FOREACH( array: TArray, fn: (value: T, index: i32, array: TArray) => void, ): void { let ptr = array.dataStart; for (let i = 0, k = array.length; i < k; i++) { fn(load(ptr + (i << alignof())), i, array); } } // @ts-ignore: decorator @inline function WRAP( buffer: ArrayBuffer, byteOffset: i32 = 0, len: i32 = -1 ): TArray { let byteLength: i32; let bufferByteLength = buffer.byteLength; const mask: u32 = sizeof() - 1; if (i32(byteOffset > bufferByteLength) | (byteOffset & mask)) { throw new RangeError(E_INDEXOUTOFRANGE); } if (len < 0) { if (len == -1) { if (bufferByteLength & mask) { throw new RangeError(E_INVALIDLENGTH); } byteLength = bufferByteLength - byteOffset; } else { throw new RangeError(E_INVALIDLENGTH); } } else { byteLength = len << alignof(); if (byteOffset + byteLength > bufferByteLength) { throw new RangeError(E_INVALIDLENGTH); } } let out = changetype(__new(offsetof(), idof())); store(changetype(out), changetype(buffer), offsetof("buffer")); __link(changetype(out), changetype(buffer), false); store(changetype(out), byteLength, offsetof("byteLength")); store(changetype(out), changetype(buffer) + byteOffset, offsetof("dataStart")); return out; } // @ts-ignore: decorator @inline function SET< TArray extends ArrayLike, UArray extends ArrayLike >( target: TArray, source: UArray, offset: i32 = 0 ): void { // need to assert at compile time that U is not a reference or a function if (isReference>()) { ERROR(E_NOTIMPLEMENTED); } let sourceLen = source.length; if (offset < 0 || sourceLen + offset > target.length) { // offset is out of bounds throw new RangeError(E_INDEXOUTOFRANGE); } // @ts-ignore: dataStart let targetStart = target.dataStart + (offset << (alignof>())); // @ts-ignore: dataStart let sourceStart = source.dataStart; // if the types align and match, use memory.copy() instead of manual loop if ( isInteger>() == isInteger>() && alignof>() == alignof>() && !(isSigned>() && target instanceof Uint8ClampedArray) ) { memory.copy(targetStart, sourceStart, sourceLen << (alignof>())); } else { for (let i = 0; i < sourceLen; i++) { let ptr = targetStart + (i << (alignof>())); let value = load>(sourceStart + (i << (alignof>()))); // if TArray is Uint8ClampedArray, then values must be clamped if (target instanceof Uint8ClampedArray) { if (isFloat>()) { store>(ptr, isFinite>(value) ? >max>(0, min>(255, value)) : 0 ); } else { if (!isSigned>()) { store>(ptr, min>(255, value)); } else if (sizeof>() <= 4) { store>(ptr, ~(value >> 31) & (((255 - value) >> 31) | value)); } else { store>(ptr, ~(value >> 63) & (((255 - value) >> 63) | value)); } } } else { if (isFloat>() && !isFloat>()) { store>(ptr, isFinite>(value) ? >value : 0); } else { store>(ptr, >value); } } } } }