• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// Autogenerated file. DO NOT EDIT
17
18package escompat
19
20class Int8ArrayIteratorKeys implements IterableIterator<number> {
21    private length: int
22    private idx: int = 0
23
24    constructor(parent: Int8Array) {
25        this.length = parent.length as int
26    }
27
28    public override $_iterator(): IterableIterator<number> {
29        return this
30    }
31
32    override next(): IteratorResult<number> {
33        if (this.idx < 0 || this.idx >= this.length) {
34            return new IteratorResult<number>()
35        }
36        return new IteratorResult<number>(false, this.idx++ as number)
37    }
38}
39
40class Int8ArrayIterator implements IterableIterator<Number> {
41    private parent: Int8Array
42    private idx: int = 0
43
44    constructor(parent: Int8Array) {
45        this.parent = parent
46    }
47
48    public override $_iterator(): IterableIterator<Number> {
49        return this
50    }
51
52    override next(): IteratorResult<Number> {
53        if (this.idx < 0 || this.idx >= this.parent.length as int) {
54            return new IteratorResult<Number>()
55        }
56        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
57    }
58}
59
60class Int8ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
61    private parent: Int8Array
62    private idx: int = 0
63
64    constructor(parent: Int8Array) {
65        this.parent = parent
66    }
67
68    public override $_iterator(): IterableIterator<[Number, Number]> {
69        return this
70    }
71
72    override next(): IteratorResult<[Number, Number]> {
73        if (this.idx < 0 || this.idx >= this.parent.length as int) {
74            return new IteratorResult<[Number, Number]>()
75        }
76        return new IteratorResult<[Number, Number]>(
77            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
78        )
79    }
80}
81
82
83/**
84 * JS Int8Array API-compatible class
85 */
86export final class Int8Array implements Iterable<Number>, ArrayLike<Number> {
87    public static readonly BYTES_PER_ELEMENT: number = 1
88    internal readonly lengthInt: int
89
90    /**
91     * Creates an empty Int8Array.
92     */
93    public constructor() {
94        this(0 as int)
95    }
96
97    /**
98     * Creates an Int8Array with respect to data accessed via Iterable<Number> interface
99     */
100    public constructor(elements: Iterable<Number>) {
101        const items: Object = elements as Object
102        if (items instanceof ArrayLike) {
103            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
104            this.byteLength = arr.length as int * Int8Array.BYTES_PER_ELEMENT as int
105            this.lengthInt = arr.length as int
106            this.buffer = new ArrayBuffer(this.byteLength as int)
107            this.byteOffset = 0
108            for (let i: int = 0; i < this.lengthInt; ++i) {
109                this.setUnsafe(i, arr.$_get(i).byteValue())
110            }
111        } else {
112          let x = Int8Array.from(elements)
113          this.byteLength = x.byteLength
114          this.lengthInt = x.lengthInt
115          this.buffer = x.buffer
116          this.byteOffset = x.byteOffset
117        }
118    }
119
120    /**
121     * Creates an Int8Array with respect to data, byteOffset and length.
122     *
123     * @param buf data initializer
124     *
125     * @param byteOffset byte offset from begin of the buf
126     *
127     * @param length size of elements of type byte in newly created Int8Array
128     */
129    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
130        let intByteOffset: int = 0
131        if (byteOffset != undefined) {
132            intByteOffset = byteOffset.intValue()
133            if (intByteOffset < 0) {
134                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
135            }
136        }
137        let intByteLength: int
138        if (buf instanceof ArrayBuffer) {
139            intByteLength = (buf as ArrayBuffer).getByteLength()
140        } else if (buf instanceof SharedArrayBuffer) {
141            intByteLength = (buf as SharedArrayBuffer).getByteLength()
142        } else {
143            throw new Error("unexpected type of ArrayBufferLike")
144        }
145        intByteLength = intByteLength - intByteOffset
146        if (intByteLength < 0) {
147            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
148        }
149
150        let intLength: int
151        if (length != undefined) {
152            intLength = length.intValue()
153            if (intLength > intByteLength / Int8Array.BYTES_PER_ELEMENT as int) {
154                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
155            }
156        } else {
157            intLength = intByteLength / Int8Array.BYTES_PER_ELEMENT as int
158        }
159        if (intLength < 0) {
160            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
161        }
162        if (intLength < intByteLength / Int8Array.BYTES_PER_ELEMENT as int) {
163            intByteLength = intLength * Int8Array.BYTES_PER_ELEMENT as int
164        }
165        this.byteLength = intByteLength
166        this.byteOffset = intByteOffset
167        this.lengthInt = intLength
168        this.buffer = buf
169    }
170
171    /**
172     * Creates an Int8Array with respect to data, byteOffset and length.
173     *
174     * @param buf data initializer
175     *
176     * @param byteOffset byte offset from begin of the buf
177     *
178     * @param length size of elements of type byte in newly created Int8Array
179     */
180    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
181        this(buf, byteOffset, undefined)
182    }
183
184    /**
185     * Creates an Int8Array with respect to data, byteOffset and length.
186     *
187     * @param buf data initializer
188     *
189     * @param byteOffset byte offset from begin of the buf
190     *
191     * @param length size of elements of type byte in newly created Int8Array
192     */
193    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
194        this(buf, new Number(byteOffset), new Number(length))
195    }
196
197    /**
198     * Creates an Int8Array with respect to data, byteOffset and length.
199     *
200     * @param buf data initializer
201     *
202     * @param byteOffset byte offset from begin of the buf
203     *
204     * @param length size of elements of type byte in newly created Int8Array
205     */
206    public constructor(buf: ArrayBufferLike, byteOffset: number) {
207        this(buf, new Number(byteOffset), undefined)
208    }
209
210    /**
211     * Creates an Int8Array with respect to data, byteOffset and length.
212     *
213     * @param buf data initializer
214     *
215     * @param byteOffset byte offset from begin of the buf
216     *
217     * @param length size of elements of type byte in newly created Int8Array
218     */
219    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
220        this(buf, new Number(byteOffset), new Number(length))
221    }
222
223    /**
224     * Creates an Int8Array with respect to buf and byteOffset.
225     *
226     * @param buf data initializer
227     *
228     * @param byteOffset byte offset from begin of the buf
229     */
230    public constructor(buf: ArrayBufferLike, byteOffset: int) {
231        this(buf, new Number(byteOffset), undefined)
232    }
233
234    /**
235     * Creates an Int8Array with respect to buf.
236     *
237     * @param buf data initializer
238     */
239    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
240        if (buf instanceof ArrayBuffer) {
241            this.byteLength = (buf as ArrayBuffer).getByteLength()
242            if (this.byteLength % Int8Array.BYTES_PER_ELEMENT as int != 0) {
243               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 1 as Int8Array.BYTES_PER_ELEMENT")
244            }
245            this.lengthInt = this.byteLength / Int8Array.BYTES_PER_ELEMENT as int
246            this.buffer = buf as ArrayBuffer
247            this.byteOffset = 0
248        } else if (buf instanceof SharedArrayBuffer) {
249            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
250            if (this.byteLength % Int8Array.BYTES_PER_ELEMENT as int != 0) {
251               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 1 as Int8Array.BYTES_PER_ELEMENT")
252            }
253            this.lengthInt = this.byteLength / Int8Array.BYTES_PER_ELEMENT as int
254            this.buffer = buf as SharedArrayBuffer
255            this.byteOffset = 0
256        } else if (buf instanceof ArrayLike) {
257            // NOTE (ikorobkov): dealing with this overload is tricky
258            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
259            let arr = Array.from<Number>((buf as ArrayLike<Number>))
260            this.byteLength = arr.length as int * Int8Array.BYTES_PER_ELEMENT as int
261            this.lengthInt = arr.length as int
262            this.buffer = new ArrayBuffer(this.byteLength as int)
263            this.byteOffset = 0
264            for (let i: int = 0; i < this.lengthInt; ++i) {
265                this.setUnsafe(i, arr.$_get(i).byteValue())
266            }
267        } else {
268            throw new Error("unexpected type of buf")
269        }
270    }
271
272    /**
273     * Creates an Int8Array with respect to length.
274     *
275     * @param length data initializer
276     */
277    public constructor(length: int) {
278        if (length < 0) {
279            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
280        }
281        this.lengthInt = length
282        this.byteLength = length * Int8Array.BYTES_PER_ELEMENT as int
283        this.byteOffset = 0
284        this.buffer = new ArrayBuffer(this.byteLength as int)
285    }
286
287    /**
288     * Creates an Int8Array with respect to length.
289     *
290     * @param length data initializer
291     */
292    public constructor(length: number) {
293        this(length as int)
294    }
295
296    /**
297     * Creates a copy of Int8Array.
298     *
299     * @param other data initializer
300     */
301    public constructor(other: Int8Array) {
302        if (other.buffer instanceof ArrayBuffer) {
303            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
304        } else if (other.buffer instanceof SharedArrayBuffer) {
305            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
306        } else {
307            throw new Error("unexpected type of buffer")
308        }
309        this.byteLength = other.byteLength
310        this.lengthInt = other.length as int
311        this.byteOffset = 0
312    }
313
314    /**
315     * Creates an Int8Array from number[]
316     */
317    public constructor(numbers: number[]) {
318        this(numbers.length)
319        for (let i: int = 0; i < this.lengthInt; ++i) {
320            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
321        }
322    }
323
324    /**
325     * Creates an Int8Array from int[]
326     */
327    public constructor(numbers: int[]) {
328        this(numbers.length)
329        for (let i: int = 0; i < this.lengthInt; ++i) {
330            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
331        }
332    }
333
334    internal zeroIfInfinity(val: number): number {
335        if ((val == Infinity) || (val == -Infinity)) {
336            return 0 as number
337        }
338        return val as number
339    }
340
341    internal zeroIfInfinity(val: byte): byte {
342        if ((val == Infinity) || (val == -Infinity)) {
343            return 0 as byte
344        }
345        return val
346    }
347
348    /**
349     * Assigns val as element on index.
350     *
351     * @param val value to set
352     *
353     * @param index index to change
354     */
355    public $_set(index: number, val: number): void {
356        this.$_set(index as int, val)
357    }
358
359    /**
360     * Assigns val as element on index.
361     *
362     * @param val value to set
363     *
364     * @param index index to change
365     */
366    public $_set(index: int, val: number): void {
367        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
368        if (index < 0 || index >= this.lengthInt) {
369            throw new RangeError("invalid index")
370        }
371        let v = this.zeroIfInfinity(val)
372        this.setUnsafe(index, v as byte)
373    }
374
375    /**
376     * Assigns val as element on index.
377     *
378     * @param val value to set
379     *
380     * @param index index to change
381     */
382    public $_set(index: number, val: int): void {
383        this.$_set(index as int, val)
384    }
385
386    /**
387     * Assigns val as element on index.
388     *
389     * @param val value to set
390     *
391     * @param index index to change
392     */
393    public $_set(index: int, val: int): void {
394        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
395        if (index < 0 || index >= this.lengthInt) {
396            throw new RangeError("invalid index")
397        }
398        let v = this.zeroIfInfinity(val as byte)
399        this.setUnsafe(index, v as byte)
400    }
401
402    /**
403     * Assigns val as element on index.
404     *
405     * @param val value to set
406     *
407     * @param index index to change
408     */
409    public $_set(index: number, val: byte): void {
410        this.$_set(index as int, val)
411    }
412
413    /**
414     * Assigns val as element on index.
415     *
416     * @param val value to set
417     *
418     * @param index index to change
419     */
420    public $_set(index: int, val: byte): void {
421        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
422        if (index < 0 || index >= this.lengthInt) {
423            throw new RangeError("invalid index")
424        }
425        let v = this.zeroIfInfinity(val)
426        this.setUnsafe(index, v)
427    }
428
429    /** Number of byte stored in Int8Array */
430    public get length(): number {
431        return this.lengthInt
432    }
433
434    /**
435     * Returns an instance of number at passed index.
436     *
437     * @param index index to look at
438     *
439     * @returns a primitive at index
440     */
441    public override $_get(index: number): Number {
442        return this.$_get(index as int) as Number
443    }
444
445    /**
446     * Returns an instance of number at passed index.
447     *
448     * @param index index to look at
449     *
450     * @returns a primitive at index
451     */
452    public $_get(index: int): number {
453        if (index < 0 || index >= this.lengthInt) {
454            throw new RangeError("invalid index")
455        }
456        return this.getUnsafe(index) as number
457    }
458
459    /**
460     * Returns an instance of primitive type at passed index.
461     *
462     * @param index index to look at
463     *
464     * @returns a primitive at index
465     */
466    public at(index: number): Number | undefined {
467        return this.at(index as int)
468    }
469
470    /**
471     * Returns an instance of primitive type at passed index.
472     *
473     * @param index index to look at
474     *
475     * @returns a primitive at index
476     */
477    public at(index: int): Number | undefined {
478        let k: int
479        if (index >= 0) {
480            k = index
481        } else {
482            k = this.lengthInt + index
483        }
484        if (k < 0 || k >= this.lengthInt) {
485            return undefined
486        }
487        return new Number(this.getUnsafe(k))
488    }
489
490    /**
491     * Makes a copy of internal elements to targetPos from startPos to endPos.
492     *
493     * @param target insert index to place copied elements
494     *
495     * @param start start index to begin copy from
496     *
497     * @param end last index to end copy from, excluded
498     *
499     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
500     */
501    public copyWithin(target: number, start: number, end?: number): Int8Array {
502        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
503    }
504
505    /**
506     * Makes a copy of internal elements to targetPos from startPos to endPos.
507     *
508     * @param target insert index to place copied elements
509     *
510     * @param start start index to begin copy from
511     *
512     * @param end last index to end copy from, excluded
513     *
514     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
515     */
516    public copyWithin(target: int, start: number, end?: number): Int8Array {
517        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
518    }
519
520    /**
521     * Makes a copy of internal elements to targetPos from startPos to endPos.
522     *
523     * @param target insert index to place copied elements
524     *
525     * @param start start index to begin copy from
526     *
527     * @param end last index to end copy from, excluded
528     *
529     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
530     */
531    public copyWithin(target: number, start: int, end?: number): Int8Array {
532        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
533    }
534
535    /**
536     * Makes a copy of internal elements to targetPos from startPos to endPos.
537     *
538     * @param target insert index to place copied elements
539     *
540     * @param start start index to begin copy from
541     *
542     * @param end last index to end copy from, excluded
543     *
544     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
545     */
546    public copyWithin(target: int, start: int, end?: number): Int8Array {
547        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
548    }
549
550    /**
551     * Makes a copy of internal elements to targetPos from startPos to endPos.
552     *
553     * @param target insert index to place copied elements
554     *
555     * @param start start index to begin copy from
556     *
557     * @param end last index to end copy from, excluded
558     *
559     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
560     */
561    public copyWithin(target: int, start: int, end: int): Int8Array {
562        let toPos = normalizeIndex(target, this.lengthInt)
563        let fromPos = normalizeIndex(start, this.lengthInt)
564        const finalPos = normalizeIndex(end, this.lengthInt)
565        let count: int = finalPos - fromPos
566        if (count > (this.lengthInt - toPos)) {
567            count = this.lengthInt - toPos
568        }
569        let direction: int = 1
570        if ((fromPos < toPos) && (toPos < fromPos + count)) {
571            fromPos = fromPos + count - 1
572            toPos   = toPos   + count - 1
573            direction = -1
574        }
575        while (count > 0) {
576            const value = this.getUnsafe(fromPos)
577            this.setUnsafe(toPos, value)
578            fromPos = fromPos + direction
579            toPos = toPos + direction
580            --count
581        }
582        return this
583    }
584
585    /**
586     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
587     *
588     * @param target insert index to place copied elements
589     *
590     * See rules of parameters normalization:
591     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
592     */
593    public copyWithin(target: number): Int8Array {
594        return this.copyWithin(target as int)
595    }
596
597    /**
598     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
599     *
600     * @param target insert index to place copied elements
601     *
602     * See rules of parameters normalization:
603     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
604     */
605    public copyWithin(target: int): Int8Array {
606        return this.copyWithin(target, 0, this.lengthInt)
607    }
608
609    /**
610     * Returns an array of key, value pairs for every entry in the Int8Array
611     *
612     * @returns key, value pairs for every entry in the array
613     */
614    public entries(): IterableIterator<[Number, Number]> {
615        return new Int8ArrayIteratorEntries(this)
616    }
617
618    /**
619     * Fills the Int8Array with specified value
620     *
621     * @param value new valuy
622     *
623     * @returns modified Int8Array
624     */
625    public fill(value: number, start?: number, end?: number): this {
626        value = this.zeroIfInfinity(value)
627        this.fill(value as byte, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
628        return this
629    }
630
631    /**
632     * Fills the Int8Array with specified value
633     *
634     * @param value new valuy
635     *
636     * @returns modified Int8Array
637     */
638    public fill(value: number, start: int, end?: number): this {
639        value = this.zeroIfInfinity(value)
640        this.fill(value as byte, start as int, asIntOrDefault(end, this.lengthInt))
641        return this
642    }
643
644    /**
645     * Fills the Int8Array with specified value
646     *
647     * @param value new valuy
648     *
649     * @returns modified Int8Array
650     */
651    public fill(value: number, start: int, end: number): this {
652        value = this.zeroIfInfinity(value)
653        this.fill(value as byte, start as int, end as int)
654        return this
655    }
656
657    /**
658     * Fills the Int8Array with specified value
659     *
660     * @param value new valuy
661     *
662     * @returns modified Int8Array
663     */
664    public fill(value: number, start: number, end: int): this {
665        value = this.zeroIfInfinity(value)
666        this.fill(value as byte, start as int, end as int)
667        return this
668    }
669
670    /**
671     * Fills the Int8Array with specified value
672     *
673     * @param value new valuy
674     *
675     * @returns modified Int8Array
676     */
677    public fill(value: number, start: int, end: int): this {
678        value = this.zeroIfInfinity(value)
679        this.fill(value as byte, start as int, end as int)
680        return this
681    }
682
683    /**
684     * Fills the Int8Array with specified value
685     *
686     * @param value new valuy
687     *
688     * @returns modified Int8Array
689     */
690    public fill(value: byte, start?: number, end?: number): this {
691        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
692        return this
693    }
694
695    /**
696     * Fills the Int8Array with specified value
697     *
698     * @param value new valuy
699     *
700     * @returns modified Int8Array
701     */
702    public fill(value: byte, start: int, end?: number): this {
703        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
704        return this
705    }
706
707    /**
708     * Fills the Int8Array with specified value
709     *
710     * @param value new valuy
711     *
712     * @returns modified Int8Array
713     */
714    public fill(value: byte, start: int, end: number): this {
715        this.fill(value, start as int, end as int)
716        return this
717    }
718
719    /**
720     * Fills the Int8Array with specified value
721     *
722     * @param value new valuy
723     *
724     * @returns modified Int8Array
725     */
726    public fill(value: byte, start: number, end: int): this {
727        this.fill(value, start as int, end as int)
728        return this
729    }
730
731    /**
732     * Fills the Int8Array with specified value
733     *
734     * @param value new valuy
735     *
736     * @returns modified Int8Array
737     */
738    public fill(value: byte, start: int, end: int): this {
739        const k = normalizeIndex(start, this.lengthInt)
740        const finalPos = normalizeIndex(end, this.lengthInt)
741        for (let i: int = k; i < finalPos; ++i) {
742            this.setUnsafe(i, value)
743        }
744        return this
745    }
746
747    /**
748     * Assigns val as element on insertPos.
749     * @description Added to avoid (un)packing a single value into array to use overloaded set(byte[], insertPos)
750     *
751     * @param val value to set
752     *
753     * @param insertPos index to change
754     */
755    public set(insertPos: number, val: number): void {
756        this.$_set(insertPos, val)
757    }
758
759    /**
760     * Assigns val as element on insertPos.
761     * @description Added to avoid (un)packing a single value into array to use overloaded set(byte[], insertPos)
762     *
763     * @param val value to set
764     *
765     * @param insertPos index to change
766     */
767    public set(insertPos: int, val: byte): void {
768        this.$_set(insertPos, val)
769    }
770
771    /**
772     * Copies all elements of arr to the current Int8Array starting from insertPos.
773     *
774     * @param arr array to copy data from
775     *
776     * @param insertPos start index where data from arr will be inserted
777     *
778     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
779     */
780    public set(arr: number[], insertPos: number): void {
781        const offset = insertPos as int
782        if (offset < 0 || offset + arr.length > this.lengthInt) {
783            throw new RangeError("offset is out of bounds")
784        }
785        for (let i = 0; i < arr.length as int; ++i) {
786            let v = this.zeroIfInfinity(arr[i])
787            this.setUnsafe(offset + i, v as byte)
788        }
789    }
790
791    /**
792     * Copies all elements of arr to the current Int8Array starting from insertPos.
793     *
794     * @param arr array to copy data from
795     *
796     * @param insertPos start index where data from arr will be inserted
797     *
798     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
799     */
800    public set(arr: byte[], insertPos: int): void {
801        const offset = insertPos as int
802        if (offset < 0 || offset + arr.length > this.lengthInt) {
803            throw new RangeError("offset is out of bounds")
804        }
805        for (let i = 0; i < arr.length as int; ++i) {
806            let v = this.zeroIfInfinity(arr[i])
807            this.setUnsafe(offset + i, v)
808        }
809    }
810
811    /**
812     * Copies all elements of arr to the current Int8Array.
813     *
814     * @param arr array to copy data from
815     */
816    public set(arr: number[]): void {
817        this.set(arr, 0 as number)
818    }
819
820    /**
821     * Copies all elements of arr to the current Int8Array.
822     *
823     * @param arr array to copy data from
824     */
825    public set(arr: byte[]): void {
826        this.set(arr, 0 as int)
827    }
828
829    /**
830     * Copies elements from an ArrayLike object to the Int8Array.
831     *
832     * @param array An ArrayLike object containing the elements to copy.
833     *
834     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
835     */
836    public set(array: ArrayLike<number>, offset: number = 0): void {
837        const insertPos = offset as int
838        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
839            throw new RangeError("offset is out of bounds")
840        }
841        for (let i = 0; i < array.length as int; ++i) {
842            let v = this.zeroIfInfinity(array[i])
843            this.setUnsafe(insertPos + i, v as byte)
844        }
845    }
846
847    /**
848     * Returns a new array from a set of elements.
849     *
850     * @param items a set of elements to include in the new array object.
851     *
852     * @returns new Int8Array
853     */
854    public static of(...items: number[]): Int8Array {
855        let res = new Int8Array(items.length as int)
856        for (let i: int = 0; i < items.length; i++) {
857            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as byte)
858        }
859        return res
860    }
861
862    /**
863     * Returns a new array from a set of elements.
864     *
865     * @param items a set of elements to include in the new array object.
866     *
867     * @returns new Int8Array
868     */
869    public static of(...items: int[]): Int8Array {
870        let res = new Int8Array(items.length as int)
871        for (let i: int = 0; i < items.length; i++) {
872            res.setUnsafe(i, items[i] as byte)
873        }
874        return res
875    }
876
877    /**
878     * Returns a new array from a set of elements.
879     *
880     * @param items a set of elements to include in the new array object.
881     *
882     * @returns new Int8Array
883     */
884    public static of(...items: byte[]): Int8Array {
885        let res = new Int8Array(items.length as int)
886        for (let i: int = 0; i < items.length; i++) {
887            res.setUnsafe(i, items[i])
888        }
889        return res
890    }
891
892    /**
893     * Returns a new array from a set of elements.
894     *
895     * @param items a set of elements to include in the new array object.
896     *
897     * @returns new Int8Array
898     */
899    public static of(): Int8Array {
900        return new Int8Array(0 as int)
901    }
902
903    /**
904     * Creates an array from an array-like or iterable object.
905     *
906     * @param arrayLike An array-like or iterable object to convert to an array.
907     *
908     * @returns new Int8Array
909     */
910    public static from(arrayLike: ArrayLike<number>): Int8Array {
911        return Int8Array.from<number>(arrayLike, (x: number, k: number): number => x)
912    }
913
914    /**
915     * Creates an array from an array-like or iterable object.
916     *
917     * @param arrayLike An array-like or iterable object to convert to an array.
918     *
919     * @param mapfn A mapping function to call on every element of the array.
920     *
921     * @returns new Int8Array
922     */
923    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int8Array {
924        if (mapfn == undefined) {
925            mapfn = (v: number, k: number): number => { return v }
926        }
927
928        let iter = arrayLike.$_iterator()
929        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
930        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
931        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
932        //  we can make one pass through the iterator without the need for memory reallocation.
933        const maybeLength = tryGetIteratorLength(arrayLike)
934        if (maybeLength) {
935            const result = new Int8Array(maybeLength)
936            for (let i = 0; i < maybeLength; ++i) {
937                const x = iter.next()
938                if (x.done) {
939                    return new Int8Array(result.buffer, 0, i)
940                }
941                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as byte)
942            }
943            return result
944        }
945
946        // NOTE (templin.konstantin): Create builtin array as buffer
947        let temp = new Int8Array(6)
948        let index = new int[1]
949        index[0] = 0
950
951        iteratorForEach<number>(iter, (x: number): void => {
952            if (index[0] + 1 > temp.lengthInt) {
953                // NOTE (templin.konstantin): Progressive reallocation
954                const curLength = (temp.buffer as Buffer).getByteLength()
955                const tb = new ArrayBuffer(curLength * 2)
956                for (let i = 0; i < curLength; ++i) {
957                    tb.set(i, (temp.buffer as Buffer).at(i))
958                }
959                temp = new Int8Array(tb)
960            }
961            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as byte)
962            index[0]++
963        })
964        return new Int8Array(temp.buffer, 0, index[0])
965    }
966
967
968    /**
969     * Creates an array from an array-like or iterable object.
970     *
971     * @param arrayLike An array-like or iterable object to convert to an array.
972     *
973     * @param mapfn A mapping function to call on every element of the array.
974     *
975     * @returns new Int8Array
976     */
977    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int8Array {
978        let res = new Int8Array(arrayLike.length)
979        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
980        const idx = new int[1]
981        idx[0] = 0
982        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
983            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as byte)
984            idx[0] += 1
985        })
986        return res
987    }
988
989    /**
990     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
991     *
992     * @param searchElement The element to search for
993     *
994     * @param fromIndex The position in this array at which to begin searching for searchElement
995     *
996     * @returns true if searchElement is in Int8Array, false otherwise
997     */
998    public includes(searchElement: number, fromIndex?: number): boolean {
999        if (isNaN(searchElement)) {
1000            return false
1001        }
1002        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
1003    }
1004
1005    /**
1006     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
1007     *
1008     * @param searchElement The element to search for
1009     *
1010     * @param fromIndex The position in this array at which to begin searching for searchElement
1011     *
1012     * @returns true if e is in Int8Array, false otherwise
1013     */
1014    public includes(searchElement: byte, fromIndex: int): boolean {
1015        return this.indexOf(searchElement as int, fromIndex) != -1
1016    }
1017
1018    /**
1019     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
1020     *
1021     * @param searchElement The element to search for
1022     *
1023     * @param fromIndex The position in this array at which to begin searching for searchElement
1024     *
1025     * @returns true if searchElement is in Int8Array, false otherwise
1026     */
1027    public includes(searchElement: byte): boolean {
1028        return this.includes(searchElement, 0)
1029    }
1030
1031    /**
1032     * Returns the index of the first occurrence of a value in Int8Array.
1033     *
1034     * @param searchElement The value to locate in the array.
1035     *
1036     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1037     *  search starts at index 0.
1038     *
1039     * @returns index of element if it presents, -1 otherwise
1040     */
1041    public indexOf(searchElement: number, fromIndex?: number): number {
1042        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
1043    }
1044
1045    /**
1046     * Returns the index of the first occurrence of a value in Int8Array.
1047     *
1048     * @param searchElement The value to locate in the array.
1049     *
1050     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1051     *  search starts at index 0.
1052     *
1053     * @returns index of element if it presents, -1 otherwise
1054     */
1055    public indexOf(searchElement: number, fromIndex: int): number {
1056        if (isNaN(searchElement)) {
1057            return -1
1058        }
1059        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
1060        for (let i = fromIndex; i < this.lengthInt; i++) {
1061            if (this.getUnsafe(i) as number == searchElement) {
1062                return i
1063            }
1064        }
1065        return -1
1066    }
1067
1068    /**
1069     * Returns the index of the first occurrence of a value in Int8Array.
1070     *
1071     * @param searchElement The value to locate in the array.
1072     *
1073     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1074     *  search starts at index 0.
1075     *
1076     * @returns index of element if it presents, -1 otherwise
1077     */
1078    public indexOf(searchElement: int, fromIndex: int): number {
1079        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
1080        for (let i = fromIndex; i < this.lengthInt; i++) {
1081            if (this.getUnsafe(i) == searchElement as byte) {
1082                return i
1083            }
1084        }
1085        return -1
1086    }
1087
1088    /**
1089     * Returns the index of the first occurrence of a value in Int8Array.
1090     *
1091     * @param searchElement The value to locate in the array.
1092     *
1093     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1094     *  search starts at index 0.
1095     *
1096     * @returns index of element if it presents, -1 otherwise
1097     */
1098    public indexOf(searchElement: int): number {
1099        return this.indexOf(searchElement, 0)
1100    }
1101
1102    /**
1103     * Adds all the elements of an array separated by the specified separator string
1104     *
1105     * @param separator A string used to separate one element of an array from the next in the
1106     * resulting String. If omitted, the array elements are separated with a comma
1107     *
1108     * @returns joined representation
1109     */
1110    public join(separator?: String): string {
1111        if (separator == undefined) {
1112            return this.join(",")
1113        }
1114        let res: StringBuilder = new StringBuilder("")
1115        for (let i = 0; i < this.lengthInt - 1; ++i) {
1116            res.append(this.getUnsafe(i) as number)
1117            res.append(separator)
1118        }
1119        if (this.lengthInt > 0) {
1120            res.append(this.getUnsafe(this.lengthInt - 1) as number)
1121        }
1122        return res.toString()
1123    }
1124
1125    /**
1126     * Returns an list of keys in Int8Array
1127     *
1128     * @returns iterator over keys
1129     */
1130    public keys(): IterableIterator<number> {
1131        return new Int8ArrayIteratorKeys(this)
1132    }
1133
1134    /**
1135     * Returns the index of the last occurrence of a value in Int8Array.
1136     *
1137     * @param searchElement The value to locate in the array.
1138     *
1139     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1140     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1141     *
1142     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1143     */
1144    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
1145        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
1146    }
1147
1148    /**
1149     * Returns the index of the last occurrence of a value in Int8Array.
1150     *
1151     * @param searchElement The value to locate in the array.
1152     *
1153     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1154     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1155     *
1156     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1157     */
1158    public lastIndexOf(searchElement: number): number {
1159        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1160    }
1161
1162    /**
1163     * Returns the index of the last occurrence of a value in Int8Array.
1164     *
1165     * @param searchElement The value to locate in the array.
1166     *
1167     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1168     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1169     *
1170     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1171     */
1172    public lastIndexOf(searchElement: number, fromIndex: int): number {
1173        if (isNaN(searchElement)) {
1174            return -1
1175        }
1176        if (this.lengthInt == 0) {
1177            return -1
1178        }
1179        let k: int = this.lengthInt + fromIndex
1180        if (fromIndex >= 0) {
1181            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
1182        }
1183        while (k >= 0) {
1184            if (this.getUnsafe(k) as number == searchElement) {
1185                return k
1186            }
1187            k--
1188        }
1189        return -1
1190    }
1191
1192    /**
1193     * Returns the index of the last occurrence of a value in Int8Array.
1194     *
1195     * @param searchElement The value to locate in the array.
1196     *
1197     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1198     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1199     *
1200     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1201     */
1202    public lastIndexOf(searchElement: int, fromIndex: int): number {
1203        if (this.lengthInt == 0) {
1204            return -1
1205        }
1206        let k: int = this.lengthInt + fromIndex
1207        if (fromIndex >= 0) {
1208            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
1209        }
1210        while (k >= 0) {
1211            if (this.getUnsafe(k) == searchElement as byte) {
1212                return k
1213            }
1214            k--
1215        }
1216        return -1
1217    }
1218
1219    /**
1220     * Returns the index of the last occurrence of a value in Int8Array.
1221     *
1222     * @param searchElement The value to locate in the array.
1223     *
1224     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1225     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1226     *
1227     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1228     */
1229    public lastIndexOf(searchElement: int): number {
1230        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1231    }
1232
1233    /**
1234    * Creates a new Int8Array using initializer
1235    *
1236    * @param data initializer
1237    *
1238    * @returns a new Int8Array from data
1239    */
1240    public of(data: Object[]): Int8Array {
1241        throw new Error("Int8Array.of: not implemented")
1242    }
1243
1244    /**
1245     * Creates a new Int8Array using reversed data from the current one
1246     *
1247     * @returns a new Int8Array using reversed data from the current one
1248     */
1249    public reverse(): Int8Array {
1250        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
1251            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
1252            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
1253            this.setUnsafe(i, tmp)
1254        }
1255        return this
1256    }
1257
1258    /**
1259     * Creates a slice of current Int8Array using range [begin, end)
1260     *
1261     * @param begin start index to be taken into slice
1262     *
1263     * @param end last index to be taken into slice
1264     *
1265     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1266     *
1267     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1268     */
1269    public slice(begin?: number, end?: number): Int8Array {
1270        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1271    }
1272
1273    /**
1274     * Creates a slice of current Int8Array using range [begin, end)
1275     *
1276     * @param begin start index to be taken into slice
1277     *
1278     * @param end last index to be taken into slice
1279     *
1280     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1281     *
1282     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1283     */
1284    public slice(begin: number, end: number): Int8Array {
1285        return this.slice(begin as int, end as int)
1286    }
1287
1288    /**
1289     * Creates a slice of current Int8Array using range [begin, end)
1290     *
1291     * @param begin start index to be taken into slice
1292     *
1293     * @param end last index to be taken into slice
1294     *
1295     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1296     *
1297     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1298     */
1299    public slice(begin: number, end: int): Int8Array {
1300        return this.slice(begin as int, end as int)
1301    }
1302
1303    /**
1304     * Creates a slice of current Int8Array using range [begin, end)
1305     *
1306     * @param begin start index to be taken into slice
1307     *
1308     * @param end last index to be taken into slice
1309     *
1310     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1311     *
1312     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1313     */
1314    public slice(begin: int, end: number): Int8Array {
1315        return this.slice(begin as int, end as int)
1316    }
1317
1318    /**
1319     * Creates a slice of current Int8Array using range [begin, end)
1320     *
1321     * @param begin start index to be taken into slice
1322     *
1323     * @param end last index to be taken into slice
1324     *
1325     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1326     *
1327     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1328     */
1329    public slice(begin: int, end: int): Int8Array {
1330        const len: int = this.lengthInt
1331        const relStart = normalizeIndex(begin, len)
1332        const relEnd = normalizeIndex(end, len)
1333        let count = relEnd - relStart
1334        if (count < 0) {
1335            count = 0
1336        }
1337        if (this.buffer instanceof ArrayBuffer) {
1338            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int8Array.BYTES_PER_ELEMENT as int, relEnd * Int8Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
1339            return new Int8Array(buf)
1340        } else if (this.buffer instanceof SharedArrayBuffer) {
1341            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int8Array.BYTES_PER_ELEMENT as int, relEnd * Int8Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
1342            return new Int8Array(buf)
1343        } else {
1344            throw new Error("unexpected type of buffer")
1345        }
1346    }
1347
1348    /**
1349     * Creates a slice of current Int8Array using range [begin, this.length).
1350     *
1351     * @param begin start index to be taken into slice
1352     *
1353     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1354     */
1355    public slice(begin: number): Int8Array {
1356        return this.slice(begin as int)
1357    }
1358
1359    /**
1360     * Creates a slice of current Int8Array using range [begin, this.length).
1361     *
1362     * @param begin start index to be taken into slice
1363     *
1364     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1365     */
1366    public slice(begin: int): Int8Array {
1367        return this.slice(begin, this.lengthInt)
1368    }
1369
1370    /**
1371     * Creates a Int8Array with the same underlying ArrayBufferLike
1372     *
1373     * @param begin start index, inclusive
1374     *
1375     * @param end last index, exclusive
1376     *
1377     * @returns new Int8Array with the same underlying ArrayBufferLike
1378     */
1379    public subarray(begin?: number, end?: number): Int8Array {
1380        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1381    }
1382
1383    /**
1384     * Creates a Int8Array with the same underlying ArrayBufferLike
1385     *
1386     * @param begin start index, inclusive
1387     *
1388     * @param end last index, exclusive
1389     *
1390     * @returns new Int8Array with the same underlying ArrayBufferLike
1391     */
1392    public subarray(begin: number, end: number): Int8Array {
1393        return this.subarray(begin as int, end as int)
1394    }
1395
1396    /**
1397     * Creates a Int8Array with the same underlying ArrayBufferLike
1398     *
1399     * @param begin start index, inclusive
1400     *
1401     * @param end last index, exclusive
1402     *
1403     * @returns new Int8Array with the same underlying ArrayBufferLike
1404     */
1405    public subarray(begin: number, end: int): Int8Array {
1406        return this.subarray(begin as int, end as int)
1407    }
1408
1409    /**
1410     * Creates a Int8Array with the same underlying ArrayBufferLike
1411     *
1412     * @param begin start index, inclusive
1413     *
1414     * @param end last index, exclusive
1415     *
1416     * @returns new Int8Array with the same underlying ArrayBufferLike
1417     */
1418    public subarray(begin: int, end: number): Int8Array {
1419        return this.subarray(begin as int, end as int)
1420    }
1421
1422    /**
1423     * Creates a Int8Array with the same underlying ArrayBufferLike
1424     *
1425     * @param begin start index, inclusive
1426     *
1427     * @param end last index, exclusive
1428     *
1429     * @returns new Int8Array with the same underlying ArrayBufferLike
1430     */
1431    public subarray(begin: int, end: int): Int8Array {
1432        const len: int = this.lengthInt
1433        const relStart = normalizeIndex(begin, len)
1434        const relEnd = normalizeIndex(end, len)
1435        let count = relEnd - relStart
1436        if (count < 0) {
1437            count = 0
1438        }
1439        return new Int8Array(this.buffer, relStart * Int8Array.BYTES_PER_ELEMENT as int, count)
1440    }
1441
1442    /**
1443     * Creates a Int8Array with the same ArrayBufferLike
1444     *
1445     * @param begin start index, inclusive
1446     *
1447     * @returns new Int8Array with the same ArrayBufferLike
1448     */
1449    public subarray(begin: number): Int8Array {
1450        return this.subarray(begin as int, this.lengthInt)
1451    }
1452
1453    /**
1454     * Creates a Int8Array with the same ArrayBufferLike
1455     *
1456     * @param begin start index, inclusive
1457     *
1458     * @returns new Int8Array with the same ArrayBufferLike
1459     */
1460    public subarray(begin: int): Int8Array {
1461        return this.subarray(begin as int, this.lengthInt)
1462    }
1463
1464    /**
1465     * Converts Int8Array to a string with respect to locale
1466     *
1467     * @param locales
1468     *
1469     * @param options
1470     *
1471     * @returns string representation
1472     */
1473    public toLocaleString(locales: Object, options: Object): string {
1474        throw new Error("Int8Array.toLocaleString: not implemented")
1475    }
1476
1477    /**
1478     * Converts Int8Array to a string with respect to locale
1479     *
1480     * @param locales
1481     *
1482     * @returns string representation
1483     */
1484    public toLocaleString(locales: Object): string {
1485        return this.toLocaleString(new Object(), new Object())
1486    }
1487
1488    /**
1489     * Converts Int8Array to a string with respect to locale
1490     *
1491     * @returns string representation
1492     */
1493    public toLocaleString(): string {
1494        let res: StringBuilder = new StringBuilder("")
1495        for (let i = 0; i < this.lengthInt - 1; ++i) {
1496            res.append((this.getUnsafe(i) as Number).toLocaleString())
1497            res.append(",")
1498        }
1499        if (this.lengthInt > 0) {
1500            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
1501        }
1502        return res.toString()
1503    }
1504
1505    /**
1506     * Creates a reversed copy
1507     *
1508     * @returns a reversed copy
1509     */
1510    public toReversed(): Int8Array {
1511        return new Int8Array(this).reverse()
1512    }
1513
1514    /**
1515     * Creates a sorted copy
1516     *
1517     * @returns a sorted copy
1518     */
1519    public toSorted(): Int8Array {
1520        return new Int8Array(this).sort()
1521    }
1522
1523    /**
1524     * Returns a string representation of the Int8Array
1525     *
1526     * @returns a string representation of the Int8Array
1527     */
1528    public override toString(): string {
1529        return this.join(",")
1530    }
1531
1532    /**
1533     * Returns array values iterator
1534     *
1535     * @returns an iterator
1536     */
1537    public values(): IterableIterator<Number> {
1538        return new Int8ArrayIterator(this)
1539    }
1540
1541    /**
1542     * Iteratorable interface implementation
1543     *
1544     * @returns iterator over all elements
1545     */
1546    public override $_iterator(): IterableIterator<Number> {
1547        return this.values()
1548    }
1549
1550    /**
1551     * Creates a copy with replaced value on index
1552     *
1553     * @param index
1554     *
1555     * @param value
1556     *
1557     * @returns an Int8Array with replaced value on index
1558     */
1559    public with(index: number, value: number): Int8Array {
1560        return this.with(index as int, value as byte)
1561    }
1562
1563    /**
1564     * Creates a copy with replaced value on index
1565     *
1566     * @param index
1567     *
1568     * @param value
1569     *
1570     * @returns an Int8Array with replaced value on index
1571     */
1572    public with(index: int, value: byte): Int8Array {
1573        let res = new Int8Array(this)
1574        res.set(index, value)
1575        return res
1576    }
1577
1578    /// === with element lambda functions ===
1579    /**
1580     * Determines whether the specified callback function returns true for all elements of an array.
1581     *
1582     * @param predicate A function that accepts one argument.
1583     * The every method calls the predicate function for each element in the array until the predicate returns a false,
1584     * or until the end of the array.
1585     *
1586     * @returns true unless predicate function returns a false for an array element,
1587     * in which case false is immediately returned.
1588     */
1589    public every(predicate: (element: number) => boolean): boolean {
1590        return this.every((element: number, index: number, array: Int8Array): boolean => predicate(element))
1591    }
1592
1593    /**
1594     * creates a new Int8Array from current Int8Array based on a condition fn
1595     *
1596     * @param fn the condition to apply for each element
1597     *
1598     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
1599     */
1600    public filter(fn: (val: number) => boolean): Int8Array {
1601        let newF: (val: number, index: number, array: Int8Array) => boolean =
1602            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1603        return this.filter(newF)
1604    }
1605
1606    /**
1607     * Returns the value of the first element in the array where predicate is true, and undefined
1608     * otherwise
1609     *
1610     * @param predicate find calls predicate once for each element of the array, in ascending
1611     * order, until it finds one where predicate returns true. If such an element is found, find
1612     * immediately returns that element value. Otherwise, find returns undefined
1613     *
1614     * @returns number | undefined
1615     */
1616    public find(predicate: () => boolean): number | undefined {
1617        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate())
1618    }
1619
1620    /**
1621     * Returns the value of the first element in the array where predicate is true, and undefined
1622     * otherwise
1623     *
1624     * @param predicate find calls predicate once for each element of the array, in ascending
1625     * order, until it finds one where predicate returns true. If such an element is found, find
1626     * immediately returns that element value. Otherwise, find returns undefined
1627     *
1628     * @returns number | undefined
1629     */
1630    public find(predicate: (value: number) => boolean): number | undefined {
1631        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate(value))
1632    }
1633
1634    /**
1635     * Returns the index of the first element in the array where predicate is true, and -1
1636     * otherwise
1637     *
1638     * @param predicate find calls predicate once for each element of the array, in ascending
1639     * order, until it finds one where predicate returns true. If such an element is found,
1640     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
1641     *
1642     * @returns number
1643     */
1644    public findIndex(predicate: (value: number) => boolean): number {
1645        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate(value)) as number
1646    }
1647
1648    /**
1649     * Finds the last element in the Int8Array that satisfies the condition
1650     *
1651     * @param fn condition
1652     *
1653     * @returns the last element that satisfies fn
1654     */
1655    public findLast(fn: (val: number) => boolean): number {
1656        let newF: (val: number, index: number, array: Int8Array) => boolean =
1657            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1658        return this.findLast(newF) as number
1659    }
1660
1661    /**
1662     * Finds an index of the last element in the Int8Array that satisfies the condition
1663     *
1664     * @param fn condition
1665     *
1666     * @returns the index of the last element that satisfies fn, -1 otherwise
1667     */
1668    public findLastIndex(fn: (val: number) => boolean): number {
1669        let newF: (val: number, index: number, array: Int8Array) => boolean =
1670            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1671        return this.findLastIndex(newF) as number
1672    }
1673
1674    /**
1675     * Performs the specified action for each element in Int8Array
1676     *
1677     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
1678     * callbackfn function one time for each element in the array.
1679     *
1680     * @returns None
1681     */
1682    public forEach(callbackfn: (value: number) => void): void {
1683        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn(value))
1684    }
1685
1686    /**
1687     * Determines whether the specified callback function returns true for any element of an array.
1688     *
1689     * @param predicate A function that accepts one argument.
1690     * The some method calls the predicate function for each element in the array
1691     * until the predicate returns a true or until the end of the array.
1692     *
1693     * @returns false unless predicate function returns true for an array element,
1694     * in which case true is immediately returned.
1695     */
1696    public some(predicate: (element: number) => boolean): boolean {
1697        return this.some((element: number, index: number, array: Int8Array): boolean => predicate(element))
1698    }
1699
1700    // NOTE (kprokopenko): this may be not skipped
1701    /**
1702     * Sorts in-place
1703     *
1704     * @param compareFn comparator —  used to determine the order of the elements.
1705     * compareFn returns a negative value if first argument is less than second argument,
1706     * zero if they're equal and a positive value otherwise.
1707     * If omitted, the elements are sorted in ascending order.
1708     *
1709     * @returns sorted Int8Array
1710     */
1711    public sort(compareFn?: (a: number, b: number) => number): this {
1712        let arr: byte[] = new byte[this.lengthInt]
1713        for (let i = 0; i < this.lengthInt; ++i) {
1714            arr[i] = this.getUnsafe(i)
1715        }
1716        let cmp = (l: byte, r: byte): number => {
1717                return (l - r) as number
1718            }
1719        if (compareFn != undefined) {
1720            cmp = (l: byte, r: byte): number => {
1721                return compareFn!(l as number, r as number)
1722            }
1723        }
1724        sort(arr, cmp)
1725        for (let i = 0; i < this.lengthInt; ++i) {
1726            this.setUnsafe(i, arr[i])
1727        }
1728        return this
1729    }
1730
1731    /**
1732     * Sorts in-place
1733     *
1734     * @param compareFn comparator —  used to determine the order of the elements.
1735     * compareFn returns a negative value if first argument is less than second argument,
1736     * zero if they're equal and a positive value otherwise.
1737     *
1738     * @returns sorted Int8Array
1739     */
1740    public sort(compareFn: (a: number) => number): this {
1741        let cmp = (a: number, b: number) => { return compareFn(a)}
1742        this.sort(cmp)
1743        return this
1744    }
1745
1746    /**
1747     * Sorts in-place
1748     *
1749     * @param fn compareFn —  used to determine the order of the elements.
1750     * compareFn returns a negative value if first argument is less than second argument,
1751     * zero if they're equal and a positive value otherwise.
1752     *
1753     * @returns sorted Int8Array
1754     */
1755    public sort(compareFn: () => number): this {
1756        let cmp = (a: number, b: number) => { return compareFn()}
1757        this.sort(cmp)
1758        return this
1759    }
1760
1761    /**
1762     * Determines whether the specified callback function returns true for any element of an array.
1763     *
1764     * @param predicate A function that accepts three arguments.
1765     * The some method calls the predicate function for each element in the array
1766     * until the predicate returns a true or until the end of the array.
1767     *
1768     * @returns false unless predicate function returns true for an array element,
1769     * in which case true is immediately returned.
1770     */
1771    public some(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
1772        for (let i = 0; i < this.lengthInt; ++i) {
1773            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
1774                return true
1775            }
1776        }
1777        return false
1778    }
1779
1780    /**
1781     * Determines whether the specified callback function returns true for any element of an array.
1782     *
1783     * @param predicate A function that accepts two arguments.
1784     * The some method calls the predicate function for each element in the array
1785     * until the predicate returns a true or until the end of the array.
1786     *
1787     * @returns false unless predicate function returns true for an array element,
1788     * in which case true is immediately returned.
1789     */
1790    public some(predicate: (element: number, index: number) => boolean): boolean {
1791        return this.some((element: number, index: number, array: Int8Array): boolean => predicate(element, index as number))
1792    }
1793
1794    /**
1795     * Determines whether the specified callback function returns true for any element of an array.
1796     *
1797     * @param predicate A function that accepts no arguments.
1798     * The some method calls the predicate function for each element in the array
1799     * until the predicate returns a true or until the end of the array.
1800     *
1801     * @returns false unless predicate function returns true for an array element,
1802     * in which case true is immediately returned.
1803     */
1804    public some(predicate: () => boolean): boolean {
1805        return this.some((element: number, index: number, array: Int8Array): boolean => predicate())
1806    }
1807
1808    /**
1809     * Calls the specified callback function for all the elements in an array.
1810     * The return value of the callback function is the accumulated result,
1811     * and is provided as an argument in the next call to the callback function.
1812     *
1813     * @param callbackfn A function that accepts four arguments.
1814     * The reduce method calls the callbackfn function one time for each element in the array.
1815     *
1816     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1817     * The first call to the callbackfn function provides this value as an argument.
1818     *
1819     * @returns The value that results from running the callback function to completion over the entire typed array.
1820     */
1821    public reduce<U = number>(
1822                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
1823                initialValue: U): U {
1824        let accumulatedValue = initialValue
1825        for (let i = 0; i < this.lengthInt; ++i) {
1826            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1827        }
1828        return accumulatedValue
1829    }
1830
1831    /**
1832     * Calls the specified callback function for all the elements in an array.
1833     * The return value of the callback function is the accumulated result,
1834     * and is provided as an argument in the next call to the callback function.
1835     *
1836     * @param callbackfn A function that accepts three arguments.
1837     * The reduce method calls the callbackfn function one time for each element in the array.
1838     *
1839     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1840     * The first call to the callbackfn function provides this value as an argument.
1841     *
1842     * @returns The value that results from running the callback function to completion over the entire typed array.
1843     */
1844    public reduce<U = number>(
1845                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
1846                initialValue: U): U {
1847        return this.reduce(
1848                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1849                        callbackfn(prevVal, currVal, currIndex), initialValue)
1850    }
1851
1852    /**
1853     * Calls the specified callback function for all the elements in an array.
1854     * The return value of the callback function is the accumulated result,
1855     * and is provided as an argument in the next call to the callback function.
1856     *
1857     * @param callbackfn A function that accepts two arguments.
1858     * The reduce method calls the callbackfn function one time for each element in the array.
1859     *
1860     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1861     * The first call to the callbackfn function provides this value as an argument.
1862     *
1863     * @returns The value that results from running the callback function to completion over the entire typed array.
1864     */
1865    public reduce<U = number>(
1866                callbackfn: (previousValue: U, currentValue: number) => U,
1867                initialValue: U): U {
1868        return this.reduce(
1869                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1870                        callbackfn(prevVal, currVal), initialValue)
1871    }
1872
1873    /**
1874     * Calls the specified callback function for all the elements in an array.
1875     * The return value of the callback function is the accumulated result,
1876     * and is provided as an argument in the next call to the callback function.
1877     *
1878     * @param callbackfn A function that accepts one argument
1879     * The reduce method calls the callbackfn function one time for each element in the array.
1880     *
1881     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1882     * The first call to the callbackfn function provides this value as an argument.
1883     *
1884     * @returns The value that results from running the callback function to completion over the entire typed array.
1885     */
1886    public reduce<U = number>(
1887                callbackfn: (previousValue: U) => U,
1888                initialValue: U): U {
1889        return this.reduce(
1890                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1891                        callbackfn(prevVal), initialValue)
1892    }
1893
1894    /**
1895     * Calls the specified callback function for all the elements in an array.
1896     * The return value of the callback function is the accumulated result,
1897     * and is provided as an argument in the next call to the callback function.
1898     *
1899     * @param callbackfn A function that accepts no arguments
1900     * The reduce method calls the callbackfn function one time for each element in the array.
1901     *
1902     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1903     * The first call to the callbackfn function provides this value as an argument.
1904     *
1905     * @returns The value that results from running the callback function to completion over the entire typed array.
1906     */
1907    public reduce<U = number>(
1908                callbackfn: () => U,
1909                initialValue: U): U {
1910        return this.reduce(
1911                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1912                        callbackfn(), initialValue)
1913    }
1914
1915    /**
1916     * Calls the specified callback function for all the elements in an array.
1917     * The return value of the callback function is the accumulated result,
1918     * and is provided as an argument in the next call to the callback function.
1919     *
1920     * @param callbackfn A function that accepts four arguments.
1921     * The reduce method calls the callbackfn function one time for each element in the array.
1922     * The first call to the callbackfn function provides array first element value as an argument
1923     *
1924     * @returns The value that results from running the callback function to completion over the entire typed array.
1925     * calling reduce method on an empty array without an initial value creates a TypeError
1926     */
1927    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
1928        if (this.lengthInt == 0) {
1929            throw new TypeError("Reduce of empty array with no initial value")
1930        }
1931
1932        let accumulatedValue = this.getUnsafe(0) as number
1933        for (let i = 1; i < this.lengthInt; ++i) {
1934            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1935        }
1936        return accumulatedValue
1937    }
1938
1939    /**
1940     * Calls the specified callback function for all the elements in an array.
1941     * The return value of the callback function is the accumulated result,
1942     * and is provided as an argument in the next call to the callback function.
1943     *
1944     * @param callbackfn A function that accepts three arguments.
1945     * The reduce method calls the callbackfn function one time for each element in the array.
1946     * The first call to the callbackfn function provides array first element value as an argument
1947     *
1948     * @returns The value that results from running the callback function to completion over the entire typed array.
1949     * calling reduce method on an empty array without an initial value creates a TypeError
1950     */
1951    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
1952        return this.reduce(
1953                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1954                        callbackfn(prevVal, currVal, currIndex))
1955    }
1956
1957    /**
1958     * Calls the specified callback function for all the elements in an array.
1959     * The return value of the callback function is the accumulated result,
1960     * and is provided as an argument in the next call to the callback function.
1961     *
1962     * @param callbackfn A function that accepts two arguments.
1963     * The reduce method calls the callbackfn function one time for each element in the array.
1964     * The first call to the callbackfn function provides array first element value as an argument
1965     *
1966     * @returns The value that results from running the callback function to completion over the entire typed array.
1967     * calling reduce method on an empty array without an initial value creates a TypeError
1968     */
1969    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
1970        return this.reduce(
1971                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1972                        callbackfn(prevVal, currVal))
1973    }
1974
1975    /**
1976     * Calls the specified callback function for all the elements in an array.
1977     * The return value of the callback function is the accumulated result,
1978     * and is provided as an argument in the next call to the callback function.
1979     *
1980     * @param callbackfn A function that accepts one argument.
1981     * The reduce method calls the callbackfn function one time for each element in the array.
1982     * The first call to the callbackfn function provides array first element value as an argument
1983     *
1984     * @returns The value that results from running the callback function to completion over the entire typed array.
1985     * calling reduce method on an empty array without an initial value creates a TypeError
1986     */
1987    public reduce(callbackfn: (previousValue: number) => number): number {
1988        return this.reduce(
1989                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1990                        callbackfn(prevVal))
1991    }
1992
1993    /**
1994     * Calls the specified callback function for all the elements in an array.
1995     * The return value of the callback function is the accumulated result,
1996     * and is provided as an argument in the next call to the callback function.
1997     *
1998     * @param callbackfn A function that accepts no arguments.
1999     * The reduce method calls the callbackfn function one time for each element in the array.
2000     * The first call to the callbackfn function provides array first element value as an argument
2001     *
2002     * @returns The value that results from running the callback function to completion over the entire typed array.
2003     * calling reduce method on an empty array without an initial value creates a TypeError
2004     */
2005    public reduce(callbackfn: () => number): number {
2006        return this.reduce(
2007                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
2008                        callbackfn())
2009    }
2010
2011
2012    /**
2013     * Calls the specified callback function for all the elements in an array, in descending order.
2014     * The return value of the callback function is the accumulated result,
2015     * and is provided as an argument in the next call to the callback function.
2016     *
2017     * @param callbackfn A function that accepts four arguments.
2018     * The reduceRight method calls the callbackfn function one time for each element in the array.
2019     *
2020     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2021     * The first call to the callbackfn function provides this value as an argument.
2022     *
2023     * @returns The value that results from running the callback function to completion over the entire typed array.
2024     */
2025    public reduceRight<U = number>(
2026                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
2027                initialValue: U): U {
2028        let accumulatedValue = initialValue
2029        for (let i = this.lengthInt - 1; i >= 0; --i) {
2030            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
2031        }
2032        return accumulatedValue
2033    }
2034
2035    /**
2036     * Calls the specified callback function for all the elements in an array, in descending order.
2037     * The return value of the callback function is the accumulated result,
2038     * and is provided as an argument in the next call to the callback function.
2039     *
2040     * @param callbackfn A function that accepts three arguments.
2041     * The reduceRight method calls the callbackfn function one time for each element in the array.
2042     *
2043     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2044     * The first call to the callbackfn function provides this value as an argument.
2045     *
2046     * @returns The value that results from running the callback function to completion over the entire typed array.
2047     */
2048    public reduceRight<U = number>(
2049                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
2050                initialValue: U): U {
2051        return this.reduceRight(
2052                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2053                        callbackfn(prevVal, currVal, currIndex), initialValue)
2054    }
2055
2056    /**
2057     * Calls the specified callback function for all the elements in an array, in descending order.
2058     * The return value of the callback function is the accumulated result,
2059     * and is provided as an argument in the next call to the callback function.
2060     *
2061     * @param callbackfn A function that accepts two arguments.
2062     * The reduceRight method calls the callbackfn function one time for each element in the array.
2063     *
2064     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2065     * The first call to the callbackfn function provides this value as an argument.
2066     *
2067     * @returns The value that results from running the callback function to completion over the entire typed array.
2068     */
2069    public reduceRight<U = number>(
2070                callbackfn: (previousValue: U, currentValue: number) => U,
2071                initialValue: U): U {
2072        return this.reduceRight(
2073                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2074                        callbackfn(prevVal, currVal), initialValue)
2075    }
2076
2077    /**
2078     * Calls the specified callback function for all the elements in an array, in descending order.
2079     * The return value of the callback function is the accumulated result,
2080     * and is provided as an argument in the next call to the callback function.
2081     *
2082     * @param callbackfn A function that accepts one argument.
2083     * The reduceRight method calls the callbackfn function one time for each element in the array.
2084     *
2085     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2086     * The first call to the callbackfn function provides this value as an argument.
2087     *
2088     * @returns The value that results from running the callback function to completion over the entire typed array.
2089     */
2090    public reduceRight<U = number>(
2091                callbackfn: (previousValue: U) => U,
2092                initialValue: U): U {
2093        return this.reduceRight(
2094                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2095                        callbackfn(prevVal), initialValue)
2096    }
2097
2098    /**
2099     * Calls the specified callback function for all the elements in an array, in descending order.
2100     * The return value of the callback function is the accumulated result,
2101     * and is provided as an argument in the next call to the callback function.
2102     *
2103     * @param callbackfn A function that accepts no arguments.
2104     * The reduceRight method calls the callbackfn function one time for each element in the array.
2105     *
2106     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2107     * The first call to the callbackfn function provides this value as an argument.
2108     *
2109     * @returns The value that results from running the callback function to completion over the entire typed array.
2110     */
2111    public reduceRight<U = number>(
2112                callbackfn: () => U,
2113                initialValue: U): U {
2114        return this.reduceRight(
2115                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2116                        callbackfn(), initialValue)
2117    }
2118
2119    /**
2120     * Calls the specified callback function for all the elements in an array, in descending order.
2121     * The return value of the callback function is the accumulated result,
2122     * and is provided as an argument in the next call to the callback function.
2123     *
2124     * @param callbackfn A function that accepts four arguments.
2125     * The reduceRight method calls the callbackfn function one time for each element in the array.
2126     * The first call to the callbackfn function provides array last element value as an argument
2127     *
2128     * @returns The value that results from running the callback function to completion over the entire typed array.
2129     * calling reduceRight method on an empty array without an initial value creates a TypeError
2130     */
2131    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
2132        if (this.lengthInt == 0) {
2133            throw new TypeError("Reduce of empty array with no initial value")
2134        }
2135
2136        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
2137        for (let i = this.lengthInt - 2; i >= 0; --i) {
2138            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
2139        }
2140        return accumulatedValue
2141    }
2142
2143    /**
2144     * Calls the specified callback function for all the elements in an array, in descending order.
2145     * The return value of the callback function is the accumulated result,
2146     * and is provided as an argument in the next call to the callback function.
2147     *
2148     * @param callbackfn A function that accepts three arguments.
2149     * The reduceRight method calls the callbackfn function one time for each element in the array.
2150     * The first call to the callbackfn function provides array last element value as an argument
2151     *
2152     * @returns The value that results from running the callback function to completion over the entire typed array.
2153     * calling reduceRight method on an empty array without an initial value creates a TypeError
2154     */
2155    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
2156        return this.reduceRight(
2157                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2158                        callbackfn(prevValue, currValue, currIndex))
2159    }
2160
2161    /**
2162     * Calls the specified callback function for all the elements in an array, in descending order.
2163     * The return value of the callback function is the accumulated result,
2164     * and is provided as an argument in the next call to the callback function.
2165     *
2166     * @param callbackfn A function that accepts two arguments.
2167     * The reduceRight method calls the callbackfn function one time for each element in the array.
2168     * The first call to the callbackfn function provides array last element value as an argument
2169     *
2170     * @returns The value that results from running the callback function to completion over the entire typed array.
2171     * calling reduceRight method on an empty array without an initial value creates a TypeError
2172     */
2173    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
2174        return this.reduceRight(
2175                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2176                        callbackfn(prevValue, currValue))
2177    }
2178
2179    /**
2180     * Calls the specified callback function for all the elements in an array, in descending order.
2181     * The return value of the callback function is the accumulated result,
2182     * and is provided as an argument in the next call to the callback function.
2183     *
2184     * @param callbackfn A function that accepts one argument.
2185     * The reduceRight method calls the callbackfn function one time for each element in the array.
2186     * The first call to the callbackfn function provides array last element value as an argument
2187     *
2188     * @returns The value that results from running the callback function to completion over the entire typed array.
2189     * calling reduceRight method on an empty array without an initial value creates a TypeError
2190     */
2191    public reduceRight(callbackfn: (previousValue: number) => number): number {
2192        return this.reduceRight(
2193                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2194                        callbackfn(prevValue))
2195    }
2196
2197    /**
2198     * Calls the specified callback function for all the elements in an array, in descending order.
2199     * The return value of the callback function is the accumulated result,
2200     * and is provided as an argument in the next call to the callback function.
2201     *
2202     * @param callbackfn A function that accepts no arguments.
2203     * The reduceRight method calls the callbackfn function one time for each element in the array.
2204     * The first call to the callbackfn function provides array last element value as an argument
2205     *
2206     * @returns The value that results from running the callback function to completion over the entire typed array.
2207     * calling reduceRight method on an empty array without an initial value creates a TypeError
2208     */
2209    public reduceRight(callbackfn: () => number): number {
2210        return this.reduceRight(
2211                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2212                        callbackfn())
2213    }
2214
2215   /**
2216    * Creates a new Int8Array using fn(arr[i]) over all elements of current Int8Array.
2217    *
2218    * @param fn a function to apply for each element of current Int8Array
2219    *
2220    * @returns a new Int8Array where for each element from current Int8Array fn was applied
2221    */
2222    public map(fn: (val: number, index: number, array: Int8Array) => number): Int8Array {
2223        let resBuf = new ArrayBuffer(this.lengthInt * Int8Array.BYTES_PER_ELEMENT as int)
2224        let res = new Int8Array(resBuf, 0, resBuf.getByteLength() / Int8Array.BYTES_PER_ELEMENT as int)
2225        for (let i = 0; i < this.lengthInt; ++i) {
2226            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as byte)
2227        }
2228        return res
2229    }
2230
2231    /**
2232     * Creates a new Int8Array using fn(arr[i], i) over all elements of current Int8Array
2233     *
2234     * @param fn a function to apply for each element of current Int8Array
2235     *
2236     * @returns a new Int8Array where for each element from current Int8Array fn was applied
2237     */
2238    public map(fn: (val: number, index: number) => number): Int8Array {
2239        let newF: (val: number, index: number, array: Int8Array) => number =
2240            (val: number, index: number, array: Int8Array): number => { return fn(val, index) }
2241        return this.map(newF)
2242    }
2243
2244    /**
2245     * Creates a new Int8Array using fn(arr[i]) over all elements of current Int8Array
2246     *
2247     * @param fn a function to apply for each element of current Int8Array
2248     *
2249     * @returns a new Int8Array where for each element from current Int8Array fn was applied
2250     */
2251    public map(fn: (val: number) => number): Int8Array {
2252        let newF: (val: number, index: number, array: Int8Array) => number =
2253            (val: number, index: number, array: Int8Array): number => { return fn(val) }
2254        return this.map(newF)
2255    }
2256
2257    /**
2258     * Creates a new Int8Array using fn() over all elements of current Int8Array
2259     *
2260     * @param fn a function to apply for each element of current Int8Array
2261     *
2262     * @returns a new Int8Array where for each element from current Int8Array fn was applied
2263     */
2264    public map(fn: () => number): Int8Array {
2265        let newF: (val: number, index: number, array: Int8Array) => number =
2266            (val: number, index: number, array: Int8Array): number => { return fn() }
2267        return this.map(newF)
2268    }
2269
2270
2271    /**
2272     * Determines whether the specified callback function returns true for all elements of an array.
2273     *
2274     * @param predicate A function that accepts three arguments.
2275     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2276     * or until the end of the array.
2277     *
2278     * @returns true unless predicate function returns a false for an array element,
2279     * in which case false is immediately returned.
2280     */
2281    public every(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
2282        for (let i = 0; i < this.lengthInt; ++i) {
2283            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
2284                return false
2285            }
2286        }
2287        return true
2288    }
2289
2290    /**
2291     * Determines whether the specified callback function returns true for all elements of an array.
2292     *
2293     * @param predicate A function that accepts two arguments.
2294     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2295     * or until the end of the array.
2296     *
2297     * @returns true unless predicate function returns a false for an array element,
2298     * in which case false is immediately returned.
2299     */
2300    public every(predicate: (element: number, index: number) => boolean): boolean {
2301        return this.every((element: number, index: number, array: Int8Array): boolean => predicate(element, index))
2302    }
2303
2304    /**
2305     * Determines whether the specified callback function returns true for all elements of an array.
2306     *
2307     * @param predicate A function that accepts no arguments.
2308     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2309     * or until the end of the array.
2310     *
2311     * @returns true unless predicate function returns a false for an array element,
2312     * in which case false is immediately returned.
2313     */
2314    public every(predicate: () => boolean): boolean {
2315        return this.every((element: number, index: number, array: Int8Array): boolean => predicate())
2316    }
2317
2318    /**
2319     * Creates a new Int8Array from current Int8Array based on a condition fn.
2320     *
2321     * @param fn the condition to apply for each element
2322     *
2323     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2324     */
2325    public filter(fn: (val: number, index: number, array: Int8Array) => boolean): Int8Array {
2326        let markers = new boolean[this.lengthInt]
2327        let resLen = 0
2328        for (let i = 0; i < this.lengthInt; ++i) {
2329            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
2330            if (markers[i]) {
2331                ++resLen
2332            }
2333        }
2334        let resBuf = new ArrayBuffer(resLen * Int8Array.BYTES_PER_ELEMENT as int)
2335        let res = new Int8Array(resBuf, 0)
2336        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
2337            if (markers[i]) {
2338                res.set(j, this.getUnsafe(i))
2339                ++j
2340            }
2341        }
2342        return res
2343    }
2344
2345    /**
2346     * creates a new Int8Array from current Int8Array based on a condition fn
2347     *
2348     * @param fn the condition to apply for each element
2349     *
2350     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2351     */
2352    public filter(fn: (val: number, index: number) => boolean): Int8Array {
2353        let newF: (val: number, index: number, array: Int8Array) => boolean =
2354            (val: number, index: number, array: Int8Array): boolean => { return fn(val, index as number) }
2355        return this.filter(newF)
2356    }
2357
2358    /**
2359     * creates a new Int8Array from current Int8Array based on a condition fn
2360     *
2361     * @param fn the condition to apply for each element
2362     *
2363     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2364     */
2365    public filter(fn: () => boolean): Int8Array {
2366        let newF: (val: number, index: number, array: Int8Array) => boolean =
2367            (val: number, index: number, array: Int8Array): boolean => { return fn() }
2368        return this.filter(newF)
2369    }
2370
2371    /**
2372     * Returns the value of the first element in the array where predicate is true, and undefined
2373     * otherwise
2374     *
2375     * @param predicate find calls predicate once for each element of the array, in ascending
2376     * order, until it finds one where predicate returns true. If such an element is found, find
2377     * immediately returns that element value. Otherwise, find returns undefined
2378     *
2379     * @returns number | undefined
2380     */
2381    public find(predicate: (value: number, index: number, obj: Int8Array) => boolean): number | undefined {
2382        for (let i = 0; i < this.lengthInt; ++i) {
2383            let val = this.getUnsafe(i)
2384            if (predicate(val as number, i as number, this)) {
2385                return val as number
2386            }
2387        }
2388        return undefined
2389    }
2390
2391    /**
2392     * Returns the value of the first element in the array where predicate is true, and undefined
2393     * otherwise
2394     *
2395     * @param predicate find calls predicate once for each element of the array, in ascending
2396     * order, until it finds one where predicate returns true. If such an element is found, find
2397     * immediately returns that element value. Otherwise, find returns undefined
2398     *
2399     * @returns number | undefined
2400     */
2401    public find(predicate: (value: number, index: number) => boolean): number | undefined {
2402        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate(value, index))
2403    }
2404
2405    /**
2406     * Returns the index of the first element in the array where predicate is true, and -1
2407     * otherwise
2408     *
2409     * @param predicate find calls predicate once for each element of the array, in ascending
2410     * order, until it finds one where predicate returns true. If such an element is found,
2411     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2412     *
2413     * @returns number
2414     */
2415    public findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean): number {
2416        for (let i = 0; i < this.lengthInt; ++i) {
2417            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
2418                return i as number
2419            }
2420        }
2421        return -1 as number
2422    }
2423
2424    /**
2425     * Returns the index of the first element in the array where predicate is true, and -1
2426     * otherwise
2427     *
2428     * @param predicate find calls predicate once for each element of the array, in ascending
2429     * order, until it finds one where predicate returns true. If such an element is found,
2430     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2431     *
2432     * @returns number
2433     */
2434    public findIndex(predicate: (value: number, index: number) => boolean): number {
2435        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate(value, index as number)) as number
2436    }
2437
2438    /**
2439     * Returns the index of the first element in the array where predicate is true, and -1
2440     * otherwise
2441     *
2442     * @param predicate find calls predicate once for each element of the array, in ascending
2443     * order, until it finds one where predicate returns true. If such an element is found,
2444     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2445     *
2446     * @returns number
2447     */
2448    public findIndex(predicate: () => boolean): number {
2449        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate()) as number
2450    }
2451
2452    /**
2453     * Finds the last element in the Int8Array that satisfies the condition
2454     *
2455     * @param fn condition
2456     *
2457     * @returns the last element that satisfies fn
2458     */
2459    public findLast(fn: (val: number, index: number, array: Int8Array) => boolean): byte {
2460        for (let i = this.lengthInt - 1; i >= 0; --i) {
2461            let val = this.getUnsafe(i)
2462            if (fn(val as number, i as number, this)) {
2463                return val
2464            }
2465        }
2466        throw new Error("Int8Array.findLast: not implemented if an element was not found")
2467    }
2468
2469    /**
2470     * Finds the last element in the Int8Array that satisfies the condition
2471     *
2472     * @param fn condition
2473     *
2474     * @returns the last element that satisfies fn
2475     */
2476    public findLast(fn: (val: number, index: number) => boolean): byte {
2477        let newF: (val: number, index: number, array: Int8Array) => boolean =
2478            (val: number, index: number, array: Int8Array): boolean => { return fn(val as number, index as number) }
2479        return this.findLast(newF)
2480    }
2481
2482    /**
2483     * Finds an index of the last element in the Int8Array that satisfies the condition
2484     *
2485     * @param fn condition
2486     *
2487     * @returns the index of the last element that satisfies fn, -1 otherwise
2488     */
2489    public findLastIndex(fn: (val: number, index: number, array: Int8Array) => boolean): number {
2490        for (let i = this.lengthInt - 1; i >= 0; --i) {
2491            let val = this.getUnsafe(i)
2492            if (fn(val as number, i as number, this)) {
2493                return i
2494            }
2495        }
2496        return -1 as number
2497    }
2498
2499    /**
2500     * Finds an index of the last element in the Int8Array that satisfies the condition
2501     *
2502     * @param fn condition
2503     *
2504     * @returns the index of the last element that satisfies fn, -1 otherwise
2505     */
2506    public findLastIndex(fn: (val: number, index: number) => boolean): number {
2507        let newF: (val: number, index: number, array: Int8Array) => boolean =
2508            (val: number, index: number, array: Int8Array): boolean => { return fn(val, index as number) }
2509        return this.findLastIndex(newF) as number
2510    }
2511
2512    /**
2513     * Performs the specified action for each element in Int8Array
2514     *
2515     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2516     * callbackfn function one time for each element in the array.
2517     *
2518     * @returns None
2519     */
2520    public forEach(callbackfn: (value: number, index: number, array: Int8Array) => void): void {
2521        for (let i = 0; i < this.lengthInt; ++i) {
2522            callbackfn(this.getUnsafe(i) as number, i as number, this)
2523        }
2524    }
2525
2526    /**
2527     * Performs the specified action for each element in Int8Array
2528     *
2529     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2530     * callbackfn function one time for each element in the array.
2531     *
2532     * @returns None
2533     */
2534    public forEach(callbackfn: (value: number, index: number) => void): void {
2535        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn(value, index))
2536    }
2537
2538    /**
2539     * Performs the specified action for each element in Int8Array
2540     *
2541     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2542     * callbackfn function one time for each element in the array.
2543     *
2544     * @returns None
2545     */
2546    public forEach(callbackfn: () => void): void {
2547        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn())
2548    }
2549
2550    /**
2551     * Returns the object itself
2552     *
2553     * @returns Int8Array
2554     */
2555    public valueOf(): Int8Array {
2556        return this
2557    }
2558
2559    internal getUnsafe(index: int): byte {
2560        let byteIndex = index * Int8Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
2561        let res : byte = 0
2562        let byteVal : byte
2563        if (IS_LITTLE_ENDIAN) {
2564            if (this.buffer instanceof ArrayBuffer) {
2565                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2566                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
2567                    res = (res | byteVal << (8 * i)) as byte
2568                }
2569            } else if (this.buffer instanceof SharedArrayBuffer) {
2570                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2571                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
2572                    res = (res | byteVal << (8 * i)) as byte
2573                }
2574            } else {
2575                throw new Error("unexpected type of ArrayBufferLike")
2576            }
2577            return res
2578        } else {
2579            if (this.buffer instanceof ArrayBuffer) {
2580                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2581                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 0 - i)
2582                    res = (res | byteVal << (8 * i)) as byte
2583                }
2584            } else if (this.buffer instanceof SharedArrayBuffer) {
2585                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2586                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 0 - i)
2587                    res = (res | byteVal << (8 * i)) as byte
2588                }
2589            } else {
2590                throw new Error("unexpected type of ArrayBufferLike")
2591            }
2592            return res
2593        }
2594    }
2595
2596    internal setUnsafe(insertPos: int, val: byte): void {
2597        let startByte = insertPos * Int8Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
2598        let bits = val
2599        if (IS_LITTLE_ENDIAN) {
2600            if (this.buffer instanceof ArrayBuffer) {
2601                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2602                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2603                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
2604                }
2605            } else if (this.buffer instanceof SharedArrayBuffer) {
2606                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2607                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2608                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
2609                }
2610            } else {
2611                throw new Error("unexpected type of ArrayBufferLike")
2612            }
2613        } else {
2614            if (this.buffer instanceof ArrayBuffer) {
2615                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; i++) {
2616                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2617                    (this.buffer as ArrayBuffer).set(startByte + 0 - i, byteVal)
2618                }
2619            } else if (this.buffer instanceof SharedArrayBuffer) {
2620                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; i++) {
2621                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2622                    (this.buffer as SharedArrayBuffer).set(startByte + 0 - i, byteVal)
2623                }
2624            } else {
2625                throw new Error("unexpected type of ArrayBufferLike")
2626            }
2627        }
2628    }
2629
2630    /** Underlying ArrayBufferLike */
2631    public readonly buffer: ArrayBufferLike
2632
2633    /** Byte offset within the underlying ArrayBufferLike */
2634    public readonly byteOffset: number
2635
2636    /** Number of bytes used */
2637    public readonly byteLength: number
2638
2639    /** String \"Int8Array\" */
2640    public readonly name = "Int8Array"
2641}
2642
2643class Int16ArrayIteratorKeys implements IterableIterator<number> {
2644    private length: int
2645    private idx: int = 0
2646
2647    constructor(parent: Int16Array) {
2648        this.length = parent.length as int
2649    }
2650
2651    public override $_iterator(): IterableIterator<number> {
2652        return this
2653    }
2654
2655    override next(): IteratorResult<number> {
2656        if (this.idx < 0 || this.idx >= this.length) {
2657            return new IteratorResult<number>()
2658        }
2659        return new IteratorResult<number>(false, this.idx++ as number)
2660    }
2661}
2662
2663class Int16ArrayIterator implements IterableIterator<Number> {
2664    private parent: Int16Array
2665    private idx: int = 0
2666
2667    constructor(parent: Int16Array) {
2668        this.parent = parent
2669    }
2670
2671    public override $_iterator(): IterableIterator<Number> {
2672        return this
2673    }
2674
2675    override next(): IteratorResult<Number> {
2676        if (this.idx < 0 || this.idx >= this.parent.length as int) {
2677            return new IteratorResult<Number>()
2678        }
2679        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
2680    }
2681}
2682
2683class Int16ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
2684    private parent: Int16Array
2685    private idx: int = 0
2686
2687    constructor(parent: Int16Array) {
2688        this.parent = parent
2689    }
2690
2691    public override $_iterator(): IterableIterator<[Number, Number]> {
2692        return this
2693    }
2694
2695    override next(): IteratorResult<[Number, Number]> {
2696        if (this.idx < 0 || this.idx >= this.parent.length as int) {
2697            return new IteratorResult<[Number, Number]>()
2698        }
2699        return new IteratorResult<[Number, Number]>(
2700            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
2701        )
2702    }
2703}
2704
2705
2706/**
2707 * JS Int16Array API-compatible class
2708 */
2709export final class Int16Array implements Iterable<Number>, ArrayLike<Number> {
2710    public static readonly BYTES_PER_ELEMENT: number = 2
2711    internal readonly lengthInt: int
2712
2713    /**
2714     * Creates an empty Int16Array.
2715     */
2716    public constructor() {
2717        this(0 as int)
2718    }
2719
2720    /**
2721     * Creates an Int16Array with respect to data accessed via Iterable<Number> interface
2722     */
2723    public constructor(elements: Iterable<Number>) {
2724        const items: Object = elements as Object
2725        if (items instanceof ArrayLike) {
2726            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
2727            this.byteLength = arr.length as int * Int16Array.BYTES_PER_ELEMENT as int
2728            this.lengthInt = arr.length as int
2729            this.buffer = new ArrayBuffer(this.byteLength as int)
2730            this.byteOffset = 0
2731            for (let i: int = 0; i < this.lengthInt; ++i) {
2732                this.setUnsafe(i, arr.$_get(i).shortValue())
2733            }
2734        } else {
2735          let x = Int16Array.from(elements)
2736          this.byteLength = x.byteLength
2737          this.lengthInt = x.lengthInt
2738          this.buffer = x.buffer
2739          this.byteOffset = x.byteOffset
2740        }
2741    }
2742
2743    /**
2744     * Creates an Int16Array with respect to data, byteOffset and length.
2745     *
2746     * @param buf data initializer
2747     *
2748     * @param byteOffset byte offset from begin of the buf
2749     *
2750     * @param length size of elements of type short in newly created Int16Array
2751     */
2752    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
2753        let intByteOffset: int = 0
2754        if (byteOffset != undefined) {
2755            intByteOffset = byteOffset.intValue()
2756            if (intByteOffset < 0) {
2757                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
2758            }
2759        }
2760        let intByteLength: int
2761        if (buf instanceof ArrayBuffer) {
2762            intByteLength = (buf as ArrayBuffer).getByteLength()
2763        } else if (buf instanceof SharedArrayBuffer) {
2764            intByteLength = (buf as SharedArrayBuffer).getByteLength()
2765        } else {
2766            throw new Error("unexpected type of ArrayBufferLike")
2767        }
2768        intByteLength = intByteLength - intByteOffset
2769        if (intByteLength < 0) {
2770            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
2771        }
2772
2773        if (intByteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2774            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2775        }
2776        if (intByteOffset % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2777            throw new RangeError("byteOffset should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2778        }
2779
2780        let intLength: int
2781        if (length != undefined) {
2782            intLength = length.intValue()
2783            if (intLength > intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
2784                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
2785            }
2786        } else {
2787            intLength = intByteLength / Int16Array.BYTES_PER_ELEMENT as int
2788        }
2789        if (intLength < 0) {
2790            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
2791        }
2792        if (intLength < intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
2793            intByteLength = intLength * Int16Array.BYTES_PER_ELEMENT as int
2794        }
2795        this.byteLength = intByteLength
2796        this.byteOffset = intByteOffset
2797        this.lengthInt = intLength
2798        this.buffer = buf
2799    }
2800
2801    /**
2802     * Creates an Int16Array with respect to data, byteOffset and length.
2803     *
2804     * @param buf data initializer
2805     *
2806     * @param byteOffset byte offset from begin of the buf
2807     *
2808     * @param length size of elements of type short in newly created Int16Array
2809     */
2810    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
2811        this(buf, byteOffset, undefined)
2812    }
2813
2814    /**
2815     * Creates an Int16Array with respect to data, byteOffset and length.
2816     *
2817     * @param buf data initializer
2818     *
2819     * @param byteOffset byte offset from begin of the buf
2820     *
2821     * @param length size of elements of type short in newly created Int16Array
2822     */
2823    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
2824        this(buf, new Number(byteOffset), new Number(length))
2825    }
2826
2827    /**
2828     * Creates an Int16Array with respect to data, byteOffset and length.
2829     *
2830     * @param buf data initializer
2831     *
2832     * @param byteOffset byte offset from begin of the buf
2833     *
2834     * @param length size of elements of type short in newly created Int16Array
2835     */
2836    public constructor(buf: ArrayBufferLike, byteOffset: number) {
2837        this(buf, new Number(byteOffset), undefined)
2838    }
2839
2840    /**
2841     * Creates an Int16Array with respect to data, byteOffset and length.
2842     *
2843     * @param buf data initializer
2844     *
2845     * @param byteOffset byte offset from begin of the buf
2846     *
2847     * @param length size of elements of type short in newly created Int16Array
2848     */
2849    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
2850        this(buf, new Number(byteOffset), new Number(length))
2851    }
2852
2853    /**
2854     * Creates an Int16Array with respect to buf and byteOffset.
2855     *
2856     * @param buf data initializer
2857     *
2858     * @param byteOffset byte offset from begin of the buf
2859     */
2860    public constructor(buf: ArrayBufferLike, byteOffset: int) {
2861        this(buf, new Number(byteOffset), undefined)
2862    }
2863
2864    /**
2865     * Creates an Int16Array with respect to buf.
2866     *
2867     * @param buf data initializer
2868     */
2869    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
2870        if (buf instanceof ArrayBuffer) {
2871            this.byteLength = (buf as ArrayBuffer).getByteLength()
2872            if (this.byteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2873               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2874            }
2875            this.lengthInt = this.byteLength / Int16Array.BYTES_PER_ELEMENT as int
2876            this.buffer = buf as ArrayBuffer
2877            this.byteOffset = 0
2878        } else if (buf instanceof SharedArrayBuffer) {
2879            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
2880            if (this.byteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2881               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2882            }
2883            this.lengthInt = this.byteLength / Int16Array.BYTES_PER_ELEMENT as int
2884            this.buffer = buf as SharedArrayBuffer
2885            this.byteOffset = 0
2886        } else if (buf instanceof ArrayLike) {
2887            // NOTE (ikorobkov): dealing with this overload is tricky
2888            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
2889            let arr = Array.from<Number>((buf as ArrayLike<Number>))
2890            this.byteLength = arr.length as int * Int16Array.BYTES_PER_ELEMENT as int
2891            this.lengthInt = arr.length as int
2892            this.buffer = new ArrayBuffer(this.byteLength as int)
2893            this.byteOffset = 0
2894            for (let i: int = 0; i < this.lengthInt; ++i) {
2895                this.setUnsafe(i, arr.$_get(i).shortValue())
2896            }
2897        } else {
2898            throw new Error("unexpected type of buf")
2899        }
2900    }
2901
2902    /**
2903     * Creates an Int16Array with respect to length.
2904     *
2905     * @param length data initializer
2906     */
2907    public constructor(length: int) {
2908        if (length < 0) {
2909            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
2910        }
2911        this.lengthInt = length
2912        this.byteLength = length * Int16Array.BYTES_PER_ELEMENT as int
2913        this.byteOffset = 0
2914        this.buffer = new ArrayBuffer(this.byteLength as int)
2915    }
2916
2917    /**
2918     * Creates an Int16Array with respect to length.
2919     *
2920     * @param length data initializer
2921     */
2922    public constructor(length: number) {
2923        this(length as int)
2924    }
2925
2926    /**
2927     * Creates a copy of Int16Array.
2928     *
2929     * @param other data initializer
2930     */
2931    public constructor(other: Int16Array) {
2932        if (other.buffer instanceof ArrayBuffer) {
2933            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
2934        } else if (other.buffer instanceof SharedArrayBuffer) {
2935            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
2936        } else {
2937            throw new Error("unexpected type of buffer")
2938        }
2939        this.byteLength = other.byteLength
2940        this.lengthInt = other.length as int
2941        this.byteOffset = 0
2942    }
2943
2944    /**
2945     * Creates an Int16Array from number[]
2946     */
2947    public constructor(numbers: number[]) {
2948        this(numbers.length)
2949        for (let i: int = 0; i < this.lengthInt; ++i) {
2950            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2951        }
2952    }
2953
2954    /**
2955     * Creates an Int16Array from int[]
2956     */
2957    public constructor(numbers: int[]) {
2958        this(numbers.length)
2959        for (let i: int = 0; i < this.lengthInt; ++i) {
2960            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2961        }
2962    }
2963
2964    internal zeroIfInfinity(val: number): number {
2965        if ((val == Infinity) || (val == -Infinity)) {
2966            return 0 as number
2967        }
2968        return val as number
2969    }
2970
2971    internal zeroIfInfinity(val: short): short {
2972        if ((val == Infinity) || (val == -Infinity)) {
2973            return 0 as short
2974        }
2975        return val
2976    }
2977
2978    /**
2979     * Assigns val as element on index.
2980     *
2981     * @param val value to set
2982     *
2983     * @param index index to change
2984     */
2985    public $_set(index: number, val: number): void {
2986        this.$_set(index as int, val)
2987    }
2988
2989    /**
2990     * Assigns val as element on index.
2991     *
2992     * @param val value to set
2993     *
2994     * @param index index to change
2995     */
2996    public $_set(index: int, val: number): void {
2997        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
2998        if (index < 0 || index >= this.lengthInt) {
2999            throw new RangeError("invalid index")
3000        }
3001        let v = this.zeroIfInfinity(val)
3002        this.setUnsafe(index, v as short)
3003    }
3004
3005    /**
3006     * Assigns val as element on index.
3007     *
3008     * @param val value to set
3009     *
3010     * @param index index to change
3011     */
3012    public $_set(index: number, val: int): void {
3013        this.$_set(index as int, val)
3014    }
3015
3016    /**
3017     * Assigns val as element on index.
3018     *
3019     * @param val value to set
3020     *
3021     * @param index index to change
3022     */
3023    public $_set(index: int, val: int): void {
3024        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
3025        if (index < 0 || index >= this.lengthInt) {
3026            throw new RangeError("invalid index")
3027        }
3028        let v = this.zeroIfInfinity(val as short)
3029        this.setUnsafe(index, v as short)
3030    }
3031
3032    /**
3033     * Assigns val as element on index.
3034     *
3035     * @param val value to set
3036     *
3037     * @param index index to change
3038     */
3039    public $_set(index: number, val: short): void {
3040        this.$_set(index as int, val)
3041    }
3042
3043    /**
3044     * Assigns val as element on index.
3045     *
3046     * @param val value to set
3047     *
3048     * @param index index to change
3049     */
3050    public $_set(index: int, val: short): void {
3051        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
3052        if (index < 0 || index >= this.lengthInt) {
3053            throw new RangeError("invalid index")
3054        }
3055        let v = this.zeroIfInfinity(val)
3056        this.setUnsafe(index, v)
3057    }
3058
3059    /** Number of short stored in Int16Array */
3060    public get length(): number {
3061        return this.lengthInt
3062    }
3063
3064    /**
3065     * Returns an instance of number at passed index.
3066     *
3067     * @param index index to look at
3068     *
3069     * @returns a primitive at index
3070     */
3071    public override $_get(index: number): Number {
3072        return this.$_get(index as int) as Number
3073    }
3074
3075    /**
3076     * Returns an instance of number at passed index.
3077     *
3078     * @param index index to look at
3079     *
3080     * @returns a primitive at index
3081     */
3082    public $_get(index: int): number {
3083        if (index < 0 || index >= this.lengthInt) {
3084            throw new RangeError("invalid index")
3085        }
3086        return this.getUnsafe(index) as number
3087    }
3088
3089    /**
3090     * Returns an instance of primitive type at passed index.
3091     *
3092     * @param index index to look at
3093     *
3094     * @returns a primitive at index
3095     */
3096    public at(index: number): Number | undefined {
3097        return this.at(index as int)
3098    }
3099
3100    /**
3101     * Returns an instance of primitive type at passed index.
3102     *
3103     * @param index index to look at
3104     *
3105     * @returns a primitive at index
3106     */
3107    public at(index: int): Number | undefined {
3108        let k: int
3109        if (index >= 0) {
3110            k = index
3111        } else {
3112            k = this.lengthInt + index
3113        }
3114        if (k < 0 || k >= this.lengthInt) {
3115            return undefined
3116        }
3117        return new Number(this.getUnsafe(k))
3118    }
3119
3120    /**
3121     * Makes a copy of internal elements to targetPos from startPos to endPos.
3122     *
3123     * @param target insert index to place copied elements
3124     *
3125     * @param start start index to begin copy from
3126     *
3127     * @param end last index to end copy from, excluded
3128     *
3129     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3130     */
3131    public copyWithin(target: number, start: number, end?: number): Int16Array {
3132        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3133    }
3134
3135    /**
3136     * Makes a copy of internal elements to targetPos from startPos to endPos.
3137     *
3138     * @param target insert index to place copied elements
3139     *
3140     * @param start start index to begin copy from
3141     *
3142     * @param end last index to end copy from, excluded
3143     *
3144     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3145     */
3146    public copyWithin(target: int, start: number, end?: number): Int16Array {
3147        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3148    }
3149
3150    /**
3151     * Makes a copy of internal elements to targetPos from startPos to endPos.
3152     *
3153     * @param target insert index to place copied elements
3154     *
3155     * @param start start index to begin copy from
3156     *
3157     * @param end last index to end copy from, excluded
3158     *
3159     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3160     */
3161    public copyWithin(target: number, start: int, end?: number): Int16Array {
3162        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3163    }
3164
3165    /**
3166     * Makes a copy of internal elements to targetPos from startPos to endPos.
3167     *
3168     * @param target insert index to place copied elements
3169     *
3170     * @param start start index to begin copy from
3171     *
3172     * @param end last index to end copy from, excluded
3173     *
3174     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3175     */
3176    public copyWithin(target: int, start: int, end?: number): Int16Array {
3177        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3178    }
3179
3180    /**
3181     * Makes a copy of internal elements to targetPos from startPos to endPos.
3182     *
3183     * @param target insert index to place copied elements
3184     *
3185     * @param start start index to begin copy from
3186     *
3187     * @param end last index to end copy from, excluded
3188     *
3189     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3190     */
3191    public copyWithin(target: int, start: int, end: int): Int16Array {
3192        let toPos = normalizeIndex(target, this.lengthInt)
3193        let fromPos = normalizeIndex(start, this.lengthInt)
3194        const finalPos = normalizeIndex(end, this.lengthInt)
3195        let count: int = finalPos - fromPos
3196        if (count > (this.lengthInt - toPos)) {
3197            count = this.lengthInt - toPos
3198        }
3199        let direction: int = 1
3200        if ((fromPos < toPos) && (toPos < fromPos + count)) {
3201            fromPos = fromPos + count - 1
3202            toPos   = toPos   + count - 1
3203            direction = -1
3204        }
3205        while (count > 0) {
3206            const value = this.getUnsafe(fromPos)
3207            this.setUnsafe(toPos, value)
3208            fromPos = fromPos + direction
3209            toPos = toPos + direction
3210            --count
3211        }
3212        return this
3213    }
3214
3215    /**
3216     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
3217     *
3218     * @param target insert index to place copied elements
3219     *
3220     * See rules of parameters normalization:
3221     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
3222     */
3223    public copyWithin(target: number): Int16Array {
3224        return this.copyWithin(target as int)
3225    }
3226
3227    /**
3228     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
3229     *
3230     * @param target insert index to place copied elements
3231     *
3232     * See rules of parameters normalization:
3233     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
3234     */
3235    public copyWithin(target: int): Int16Array {
3236        return this.copyWithin(target, 0, this.lengthInt)
3237    }
3238
3239    /**
3240     * Returns an array of key, value pairs for every entry in the Int16Array
3241     *
3242     * @returns key, value pairs for every entry in the array
3243     */
3244    public entries(): IterableIterator<[Number, Number]> {
3245        return new Int16ArrayIteratorEntries(this)
3246    }
3247
3248    /**
3249     * Fills the Int16Array with specified value
3250     *
3251     * @param value new valuy
3252     *
3253     * @returns modified Int16Array
3254     */
3255    public fill(value: number, start?: number, end?: number): this {
3256        value = this.zeroIfInfinity(value)
3257        this.fill(value as short, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
3258        return this
3259    }
3260
3261    /**
3262     * Fills the Int16Array with specified value
3263     *
3264     * @param value new valuy
3265     *
3266     * @returns modified Int16Array
3267     */
3268    public fill(value: number, start: int, end?: number): this {
3269        value = this.zeroIfInfinity(value)
3270        this.fill(value as short, start as int, asIntOrDefault(end, this.lengthInt))
3271        return this
3272    }
3273
3274    /**
3275     * Fills the Int16Array with specified value
3276     *
3277     * @param value new valuy
3278     *
3279     * @returns modified Int16Array
3280     */
3281    public fill(value: number, start: int, end: number): this {
3282        value = this.zeroIfInfinity(value)
3283        this.fill(value as short, start as int, end as int)
3284        return this
3285    }
3286
3287    /**
3288     * Fills the Int16Array with specified value
3289     *
3290     * @param value new valuy
3291     *
3292     * @returns modified Int16Array
3293     */
3294    public fill(value: number, start: number, end: int): this {
3295        value = this.zeroIfInfinity(value)
3296        this.fill(value as short, start as int, end as int)
3297        return this
3298    }
3299
3300    /**
3301     * Fills the Int16Array with specified value
3302     *
3303     * @param value new valuy
3304     *
3305     * @returns modified Int16Array
3306     */
3307    public fill(value: number, start: int, end: int): this {
3308        value = this.zeroIfInfinity(value)
3309        this.fill(value as short, start as int, end as int)
3310        return this
3311    }
3312
3313    /**
3314     * Fills the Int16Array with specified value
3315     *
3316     * @param value new valuy
3317     *
3318     * @returns modified Int16Array
3319     */
3320    public fill(value: short, start?: number, end?: number): this {
3321        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
3322        return this
3323    }
3324
3325    /**
3326     * Fills the Int16Array with specified value
3327     *
3328     * @param value new valuy
3329     *
3330     * @returns modified Int16Array
3331     */
3332    public fill(value: short, start: int, end?: number): this {
3333        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
3334        return this
3335    }
3336
3337    /**
3338     * Fills the Int16Array with specified value
3339     *
3340     * @param value new valuy
3341     *
3342     * @returns modified Int16Array
3343     */
3344    public fill(value: short, start: int, end: number): this {
3345        this.fill(value, start as int, end as int)
3346        return this
3347    }
3348
3349    /**
3350     * Fills the Int16Array with specified value
3351     *
3352     * @param value new valuy
3353     *
3354     * @returns modified Int16Array
3355     */
3356    public fill(value: short, start: number, end: int): this {
3357        this.fill(value, start as int, end as int)
3358        return this
3359    }
3360
3361    /**
3362     * Fills the Int16Array with specified value
3363     *
3364     * @param value new valuy
3365     *
3366     * @returns modified Int16Array
3367     */
3368    public fill(value: short, start: int, end: int): this {
3369        const k = normalizeIndex(start, this.lengthInt)
3370        const finalPos = normalizeIndex(end, this.lengthInt)
3371        for (let i: int = k; i < finalPos; ++i) {
3372            this.setUnsafe(i, value)
3373        }
3374        return this
3375    }
3376
3377    /**
3378     * Assigns val as element on insertPos.
3379     * @description Added to avoid (un)packing a single value into array to use overloaded set(short[], insertPos)
3380     *
3381     * @param val value to set
3382     *
3383     * @param insertPos index to change
3384     */
3385    public set(insertPos: number, val: number): void {
3386        this.$_set(insertPos, val)
3387    }
3388
3389    /**
3390     * Assigns val as element on insertPos.
3391     * @description Added to avoid (un)packing a single value into array to use overloaded set(short[], insertPos)
3392     *
3393     * @param val value to set
3394     *
3395     * @param insertPos index to change
3396     */
3397    public set(insertPos: int, val: short): void {
3398        this.$_set(insertPos, val)
3399    }
3400
3401    /**
3402     * Copies all elements of arr to the current Int16Array starting from insertPos.
3403     *
3404     * @param arr array to copy data from
3405     *
3406     * @param insertPos start index where data from arr will be inserted
3407     *
3408     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
3409     */
3410    public set(arr: number[], insertPos: number): void {
3411        const offset = insertPos as int
3412        if (offset < 0 || offset + arr.length > this.lengthInt) {
3413            throw new RangeError("offset is out of bounds")
3414        }
3415        for (let i = 0; i < arr.length as int; ++i) {
3416            let v = this.zeroIfInfinity(arr[i])
3417            this.setUnsafe(offset + i, v as short)
3418        }
3419    }
3420
3421    /**
3422     * Copies all elements of arr to the current Int16Array starting from insertPos.
3423     *
3424     * @param arr array to copy data from
3425     *
3426     * @param insertPos start index where data from arr will be inserted
3427     *
3428     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
3429     */
3430    public set(arr: short[], insertPos: int): void {
3431        const offset = insertPos as int
3432        if (offset < 0 || offset + arr.length > this.lengthInt) {
3433            throw new RangeError("offset is out of bounds")
3434        }
3435        for (let i = 0; i < arr.length as int; ++i) {
3436            let v = this.zeroIfInfinity(arr[i])
3437            this.setUnsafe(offset + i, v)
3438        }
3439    }
3440
3441    /**
3442     * Copies all elements of arr to the current Int16Array.
3443     *
3444     * @param arr array to copy data from
3445     */
3446    public set(arr: number[]): void {
3447        this.set(arr, 0 as number)
3448    }
3449
3450    /**
3451     * Copies all elements of arr to the current Int16Array.
3452     *
3453     * @param arr array to copy data from
3454     */
3455    public set(arr: short[]): void {
3456        this.set(arr, 0 as int)
3457    }
3458
3459    /**
3460     * Copies elements from an ArrayLike object to the Int16Array.
3461     *
3462     * @param array An ArrayLike object containing the elements to copy.
3463     *
3464     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
3465     */
3466    public set(array: ArrayLike<number>, offset: number = 0): void {
3467        const insertPos = offset as int
3468        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
3469            throw new RangeError("offset is out of bounds")
3470        }
3471        for (let i = 0; i < array.length as int; ++i) {
3472            let v = this.zeroIfInfinity(array[i])
3473            this.setUnsafe(insertPos + i, v as short)
3474        }
3475    }
3476
3477    /**
3478     * Returns a new array from a set of elements.
3479     *
3480     * @param items a set of elements to include in the new array object.
3481     *
3482     * @returns new Int16Array
3483     */
3484    public static of(...items: number[]): Int16Array {
3485        let res = new Int16Array(items.length as int)
3486        for (let i: int = 0; i < items.length; i++) {
3487            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as short)
3488        }
3489        return res
3490    }
3491
3492    /**
3493     * Returns a new array from a set of elements.
3494     *
3495     * @param items a set of elements to include in the new array object.
3496     *
3497     * @returns new Int16Array
3498     */
3499    public static of(...items: int[]): Int16Array {
3500        let res = new Int16Array(items.length as int)
3501        for (let i: int = 0; i < items.length; i++) {
3502            res.setUnsafe(i, items[i] as short)
3503        }
3504        return res
3505    }
3506
3507    /**
3508     * Returns a new array from a set of elements.
3509     *
3510     * @param items a set of elements to include in the new array object.
3511     *
3512     * @returns new Int16Array
3513     */
3514    public static of(...items: short[]): Int16Array {
3515        let res = new Int16Array(items.length as int)
3516        for (let i: int = 0; i < items.length; i++) {
3517            res.setUnsafe(i, items[i])
3518        }
3519        return res
3520    }
3521
3522    /**
3523     * Returns a new array from a set of elements.
3524     *
3525     * @param items a set of elements to include in the new array object.
3526     *
3527     * @returns new Int16Array
3528     */
3529    public static of(): Int16Array {
3530        return new Int16Array(0 as int)
3531    }
3532
3533    /**
3534     * Creates an array from an array-like or iterable object.
3535     *
3536     * @param arrayLike An array-like or iterable object to convert to an array.
3537     *
3538     * @returns new Int16Array
3539     */
3540    public static from(arrayLike: ArrayLike<number>): Int16Array {
3541        return Int16Array.from<number>(arrayLike, (x: number, k: number): number => x)
3542    }
3543
3544    /**
3545     * Creates an array from an array-like or iterable object.
3546     *
3547     * @param arrayLike An array-like or iterable object to convert to an array.
3548     *
3549     * @param mapfn A mapping function to call on every element of the array.
3550     *
3551     * @returns new Int16Array
3552     */
3553    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int16Array {
3554        if (mapfn == undefined) {
3555            mapfn = (v: number, k: number): number => { return v }
3556        }
3557
3558        let iter = arrayLike.$_iterator()
3559        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
3560        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
3561        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
3562        //  we can make one pass through the iterator without the need for memory reallocation.
3563        const maybeLength = tryGetIteratorLength(arrayLike)
3564        if (maybeLength) {
3565            const result = new Int16Array(maybeLength)
3566            for (let i = 0; i < maybeLength; ++i) {
3567                const x = iter.next()
3568                if (x.done) {
3569                    return new Int16Array(result.buffer, 0, i)
3570                }
3571                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as short)
3572            }
3573            return result
3574        }
3575
3576        // NOTE (templin.konstantin): Create builtin array as buffer
3577        let temp = new Int16Array(6)
3578        let index = new int[1]
3579        index[0] = 0
3580
3581        iteratorForEach<number>(iter, (x: number): void => {
3582            if (index[0] + 1 > temp.lengthInt) {
3583                // NOTE (templin.konstantin): Progressive reallocation
3584                const curLength = (temp.buffer as Buffer).getByteLength()
3585                const tb = new ArrayBuffer(curLength * 2)
3586                for (let i = 0; i < curLength; ++i) {
3587                    tb.set(i, (temp.buffer as Buffer).at(i))
3588                }
3589                temp = new Int16Array(tb)
3590            }
3591            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as short)
3592            index[0]++
3593        })
3594        return new Int16Array(temp.buffer, 0, index[0])
3595    }
3596
3597
3598    /**
3599     * Creates an array from an array-like or iterable object.
3600     *
3601     * @param arrayLike An array-like or iterable object to convert to an array.
3602     *
3603     * @param mapfn A mapping function to call on every element of the array.
3604     *
3605     * @returns new Int16Array
3606     */
3607    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int16Array {
3608        let res = new Int16Array(arrayLike.length)
3609        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
3610        const idx = new int[1]
3611        idx[0] = 0
3612        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
3613            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as short)
3614            idx[0] += 1
3615        })
3616        return res
3617    }
3618
3619    /**
3620     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3621     *
3622     * @param searchElement The element to search for
3623     *
3624     * @param fromIndex The position in this array at which to begin searching for searchElement
3625     *
3626     * @returns true if searchElement is in Int16Array, false otherwise
3627     */
3628    public includes(searchElement: number, fromIndex?: number): boolean {
3629        if (isNaN(searchElement)) {
3630            return false
3631        }
3632        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
3633    }
3634
3635    /**
3636     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3637     *
3638     * @param searchElement The element to search for
3639     *
3640     * @param fromIndex The position in this array at which to begin searching for searchElement
3641     *
3642     * @returns true if e is in Int16Array, false otherwise
3643     */
3644    public includes(searchElement: short, fromIndex: int): boolean {
3645        return this.indexOf(searchElement as int, fromIndex) != -1
3646    }
3647
3648    /**
3649     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3650     *
3651     * @param searchElement The element to search for
3652     *
3653     * @param fromIndex The position in this array at which to begin searching for searchElement
3654     *
3655     * @returns true if searchElement is in Int16Array, false otherwise
3656     */
3657    public includes(searchElement: short): boolean {
3658        return this.includes(searchElement, 0)
3659    }
3660
3661    /**
3662     * Returns the index of the first occurrence of a value in Int16Array.
3663     *
3664     * @param searchElement The value to locate in the array.
3665     *
3666     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3667     *  search starts at index 0.
3668     *
3669     * @returns index of element if it presents, -1 otherwise
3670     */
3671    public indexOf(searchElement: number, fromIndex?: number): number {
3672        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
3673    }
3674
3675    /**
3676     * Returns the index of the first occurrence of a value in Int16Array.
3677     *
3678     * @param searchElement The value to locate in the array.
3679     *
3680     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3681     *  search starts at index 0.
3682     *
3683     * @returns index of element if it presents, -1 otherwise
3684     */
3685    public indexOf(searchElement: number, fromIndex: int): number {
3686        if (isNaN(searchElement)) {
3687            return -1
3688        }
3689        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
3690        for (let i = fromIndex; i < this.lengthInt; i++) {
3691            if (this.getUnsafe(i) as number == searchElement) {
3692                return i
3693            }
3694        }
3695        return -1
3696    }
3697
3698    /**
3699     * Returns the index of the first occurrence of a value in Int16Array.
3700     *
3701     * @param searchElement The value to locate in the array.
3702     *
3703     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3704     *  search starts at index 0.
3705     *
3706     * @returns index of element if it presents, -1 otherwise
3707     */
3708    public indexOf(searchElement: int, fromIndex: int): number {
3709        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
3710        for (let i = fromIndex; i < this.lengthInt; i++) {
3711            if (this.getUnsafe(i) == searchElement as short) {
3712                return i
3713            }
3714        }
3715        return -1
3716    }
3717
3718    /**
3719     * Returns the index of the first occurrence of a value in Int16Array.
3720     *
3721     * @param searchElement The value to locate in the array.
3722     *
3723     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3724     *  search starts at index 0.
3725     *
3726     * @returns index of element if it presents, -1 otherwise
3727     */
3728    public indexOf(searchElement: int): number {
3729        return this.indexOf(searchElement, 0)
3730    }
3731
3732    /**
3733     * Adds all the elements of an array separated by the specified separator string
3734     *
3735     * @param separator A string used to separate one element of an array from the next in the
3736     * resulting String. If omitted, the array elements are separated with a comma
3737     *
3738     * @returns joined representation
3739     */
3740    public join(separator?: String): string {
3741        if (separator == undefined) {
3742            return this.join(",")
3743        }
3744        let res: StringBuilder = new StringBuilder("")
3745        for (let i = 0; i < this.lengthInt - 1; ++i) {
3746            res.append(this.getUnsafe(i) as number)
3747            res.append(separator)
3748        }
3749        if (this.lengthInt > 0) {
3750            res.append(this.getUnsafe(this.lengthInt - 1) as number)
3751        }
3752        return res.toString()
3753    }
3754
3755    /**
3756     * Returns an list of keys in Int16Array
3757     *
3758     * @returns iterator over keys
3759     */
3760    public keys(): IterableIterator<number> {
3761        return new Int16ArrayIteratorKeys(this)
3762    }
3763
3764    /**
3765     * Returns the index of the last occurrence of a value in Int16Array.
3766     *
3767     * @param searchElement The value to locate in the array.
3768     *
3769     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3770     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3771     *
3772     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3773     */
3774    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
3775        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
3776    }
3777
3778    /**
3779     * Returns the index of the last occurrence of a value in Int16Array.
3780     *
3781     * @param searchElement The value to locate in the array.
3782     *
3783     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3784     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3785     *
3786     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3787     */
3788    public lastIndexOf(searchElement: number): number {
3789        return this.lastIndexOf(searchElement, this.lengthInt - 1)
3790    }
3791
3792    /**
3793     * Returns the index of the last occurrence of a value in Int16Array.
3794     *
3795     * @param searchElement The value to locate in the array.
3796     *
3797     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3798     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3799     *
3800     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3801     */
3802    public lastIndexOf(searchElement: number, fromIndex: int): number {
3803        if (isNaN(searchElement)) {
3804            return -1
3805        }
3806        if (this.lengthInt == 0) {
3807            return -1
3808        }
3809        let k: int = this.lengthInt + fromIndex
3810        if (fromIndex >= 0) {
3811            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
3812        }
3813        while (k >= 0) {
3814            if (this.getUnsafe(k) as number == searchElement) {
3815                return k
3816            }
3817            k--
3818        }
3819        return -1
3820    }
3821
3822    /**
3823     * Returns the index of the last occurrence of a value in Int16Array.
3824     *
3825     * @param searchElement The value to locate in the array.
3826     *
3827     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3828     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3829     *
3830     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3831     */
3832    public lastIndexOf(searchElement: int, fromIndex: int): number {
3833        if (this.lengthInt == 0) {
3834            return -1
3835        }
3836        let k: int = this.lengthInt + fromIndex
3837        if (fromIndex >= 0) {
3838            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
3839        }
3840        while (k >= 0) {
3841            if (this.getUnsafe(k) == searchElement as short) {
3842                return k
3843            }
3844            k--
3845        }
3846        return -1
3847    }
3848
3849    /**
3850     * Returns the index of the last occurrence of a value in Int16Array.
3851     *
3852     * @param searchElement The value to locate in the array.
3853     *
3854     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3855     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3856     *
3857     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3858     */
3859    public lastIndexOf(searchElement: int): number {
3860        return this.lastIndexOf(searchElement, this.lengthInt - 1)
3861    }
3862
3863    /**
3864    * Creates a new Int16Array using initializer
3865    *
3866    * @param data initializer
3867    *
3868    * @returns a new Int16Array from data
3869    */
3870    public of(data: Object[]): Int16Array {
3871        throw new Error("Int16Array.of: not implemented")
3872    }
3873
3874    /**
3875     * Creates a new Int16Array using reversed data from the current one
3876     *
3877     * @returns a new Int16Array using reversed data from the current one
3878     */
3879    public reverse(): Int16Array {
3880        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
3881            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
3882            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
3883            this.setUnsafe(i, tmp)
3884        }
3885        return this
3886    }
3887
3888    /**
3889     * Creates a slice of current Int16Array using range [begin, end)
3890     *
3891     * @param begin start index to be taken into slice
3892     *
3893     * @param end last index to be taken into slice
3894     *
3895     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3896     *
3897     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3898     */
3899    public slice(begin?: number, end?: number): Int16Array {
3900        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
3901    }
3902
3903    /**
3904     * Creates a slice of current Int16Array using range [begin, end)
3905     *
3906     * @param begin start index to be taken into slice
3907     *
3908     * @param end last index to be taken into slice
3909     *
3910     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3911     *
3912     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3913     */
3914    public slice(begin: number, end: number): Int16Array {
3915        return this.slice(begin as int, end as int)
3916    }
3917
3918    /**
3919     * Creates a slice of current Int16Array using range [begin, end)
3920     *
3921     * @param begin start index to be taken into slice
3922     *
3923     * @param end last index to be taken into slice
3924     *
3925     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3926     *
3927     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3928     */
3929    public slice(begin: number, end: int): Int16Array {
3930        return this.slice(begin as int, end as int)
3931    }
3932
3933    /**
3934     * Creates a slice of current Int16Array using range [begin, end)
3935     *
3936     * @param begin start index to be taken into slice
3937     *
3938     * @param end last index to be taken into slice
3939     *
3940     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3941     *
3942     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3943     */
3944    public slice(begin: int, end: number): Int16Array {
3945        return this.slice(begin as int, end as int)
3946    }
3947
3948    /**
3949     * Creates a slice of current Int16Array using range [begin, end)
3950     *
3951     * @param begin start index to be taken into slice
3952     *
3953     * @param end last index to be taken into slice
3954     *
3955     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3956     *
3957     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3958     */
3959    public slice(begin: int, end: int): Int16Array {
3960        const len: int = this.lengthInt
3961        const relStart = normalizeIndex(begin, len)
3962        const relEnd = normalizeIndex(end, len)
3963        let count = relEnd - relStart
3964        if (count < 0) {
3965            count = 0
3966        }
3967        if (this.buffer instanceof ArrayBuffer) {
3968            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int16Array.BYTES_PER_ELEMENT as int, relEnd * Int16Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
3969            return new Int16Array(buf)
3970        } else if (this.buffer instanceof SharedArrayBuffer) {
3971            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int16Array.BYTES_PER_ELEMENT as int, relEnd * Int16Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
3972            return new Int16Array(buf)
3973        } else {
3974            throw new Error("unexpected type of buffer")
3975        }
3976    }
3977
3978    /**
3979     * Creates a slice of current Int16Array using range [begin, this.length).
3980     *
3981     * @param begin start index to be taken into slice
3982     *
3983     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3984     */
3985    public slice(begin: number): Int16Array {
3986        return this.slice(begin as int)
3987    }
3988
3989    /**
3990     * Creates a slice of current Int16Array using range [begin, this.length).
3991     *
3992     * @param begin start index to be taken into slice
3993     *
3994     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3995     */
3996    public slice(begin: int): Int16Array {
3997        return this.slice(begin, this.lengthInt)
3998    }
3999
4000    /**
4001     * Creates a Int16Array with the same underlying ArrayBufferLike
4002     *
4003     * @param begin start index, inclusive
4004     *
4005     * @param end last index, exclusive
4006     *
4007     * @returns new Int16Array with the same underlying ArrayBufferLike
4008     */
4009    public subarray(begin?: number, end?: number): Int16Array {
4010        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
4011    }
4012
4013    /**
4014     * Creates a Int16Array with the same underlying ArrayBufferLike
4015     *
4016     * @param begin start index, inclusive
4017     *
4018     * @param end last index, exclusive
4019     *
4020     * @returns new Int16Array with the same underlying ArrayBufferLike
4021     */
4022    public subarray(begin: number, end: number): Int16Array {
4023        return this.subarray(begin as int, end as int)
4024    }
4025
4026    /**
4027     * Creates a Int16Array with the same underlying ArrayBufferLike
4028     *
4029     * @param begin start index, inclusive
4030     *
4031     * @param end last index, exclusive
4032     *
4033     * @returns new Int16Array with the same underlying ArrayBufferLike
4034     */
4035    public subarray(begin: number, end: int): Int16Array {
4036        return this.subarray(begin as int, end as int)
4037    }
4038
4039    /**
4040     * Creates a Int16Array with the same underlying ArrayBufferLike
4041     *
4042     * @param begin start index, inclusive
4043     *
4044     * @param end last index, exclusive
4045     *
4046     * @returns new Int16Array with the same underlying ArrayBufferLike
4047     */
4048    public subarray(begin: int, end: number): Int16Array {
4049        return this.subarray(begin as int, end as int)
4050    }
4051
4052    /**
4053     * Creates a Int16Array with the same underlying ArrayBufferLike
4054     *
4055     * @param begin start index, inclusive
4056     *
4057     * @param end last index, exclusive
4058     *
4059     * @returns new Int16Array with the same underlying ArrayBufferLike
4060     */
4061    public subarray(begin: int, end: int): Int16Array {
4062        const len: int = this.lengthInt
4063        const relStart = normalizeIndex(begin, len)
4064        const relEnd = normalizeIndex(end, len)
4065        let count = relEnd - relStart
4066        if (count < 0) {
4067            count = 0
4068        }
4069        return new Int16Array(this.buffer, relStart * Int16Array.BYTES_PER_ELEMENT as int, count)
4070    }
4071
4072    /**
4073     * Creates a Int16Array with the same ArrayBufferLike
4074     *
4075     * @param begin start index, inclusive
4076     *
4077     * @returns new Int16Array with the same ArrayBufferLike
4078     */
4079    public subarray(begin: number): Int16Array {
4080        return this.subarray(begin as int, this.lengthInt)
4081    }
4082
4083    /**
4084     * Creates a Int16Array with the same ArrayBufferLike
4085     *
4086     * @param begin start index, inclusive
4087     *
4088     * @returns new Int16Array with the same ArrayBufferLike
4089     */
4090    public subarray(begin: int): Int16Array {
4091        return this.subarray(begin as int, this.lengthInt)
4092    }
4093
4094    /**
4095     * Converts Int16Array to a string with respect to locale
4096     *
4097     * @param locales
4098     *
4099     * @param options
4100     *
4101     * @returns string representation
4102     */
4103    public toLocaleString(locales: Object, options: Object): string {
4104        throw new Error("Int16Array.toLocaleString: not implemented")
4105    }
4106
4107    /**
4108     * Converts Int16Array to a string with respect to locale
4109     *
4110     * @param locales
4111     *
4112     * @returns string representation
4113     */
4114    public toLocaleString(locales: Object): string {
4115        return this.toLocaleString(new Object(), new Object())
4116    }
4117
4118    /**
4119     * Converts Int16Array to a string with respect to locale
4120     *
4121     * @returns string representation
4122     */
4123    public toLocaleString(): string {
4124        let res: StringBuilder = new StringBuilder("")
4125        for (let i = 0; i < this.lengthInt - 1; ++i) {
4126            res.append((this.getUnsafe(i) as Number).toLocaleString())
4127            res.append(",")
4128        }
4129        if (this.lengthInt > 0) {
4130            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
4131        }
4132        return res.toString()
4133    }
4134
4135    /**
4136     * Creates a reversed copy
4137     *
4138     * @returns a reversed copy
4139     */
4140    public toReversed(): Int16Array {
4141        return new Int16Array(this).reverse()
4142    }
4143
4144    /**
4145     * Creates a sorted copy
4146     *
4147     * @returns a sorted copy
4148     */
4149    public toSorted(): Int16Array {
4150        return new Int16Array(this).sort()
4151    }
4152
4153    /**
4154     * Returns a string representation of the Int16Array
4155     *
4156     * @returns a string representation of the Int16Array
4157     */
4158    public override toString(): string {
4159        return this.join(",")
4160    }
4161
4162    /**
4163     * Returns array values iterator
4164     *
4165     * @returns an iterator
4166     */
4167    public values(): IterableIterator<Number> {
4168        return new Int16ArrayIterator(this)
4169    }
4170
4171    /**
4172     * Iteratorable interface implementation
4173     *
4174     * @returns iterator over all elements
4175     */
4176    public override $_iterator(): IterableIterator<Number> {
4177        return this.values()
4178    }
4179
4180    /**
4181     * Creates a copy with replaced value on index
4182     *
4183     * @param index
4184     *
4185     * @param value
4186     *
4187     * @returns an Int16Array with replaced value on index
4188     */
4189    public with(index: number, value: number): Int16Array {
4190        return this.with(index as int, value as short)
4191    }
4192
4193    /**
4194     * Creates a copy with replaced value on index
4195     *
4196     * @param index
4197     *
4198     * @param value
4199     *
4200     * @returns an Int16Array with replaced value on index
4201     */
4202    public with(index: int, value: short): Int16Array {
4203        let res = new Int16Array(this)
4204        res.set(index, value)
4205        return res
4206    }
4207
4208    /// === with element lambda functions ===
4209    /**
4210     * Determines whether the specified callback function returns true for all elements of an array.
4211     *
4212     * @param predicate A function that accepts one argument.
4213     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4214     * or until the end of the array.
4215     *
4216     * @returns true unless predicate function returns a false for an array element,
4217     * in which case false is immediately returned.
4218     */
4219    public every(predicate: (element: number) => boolean): boolean {
4220        return this.every((element: number, index: number, array: Int16Array): boolean => predicate(element))
4221    }
4222
4223    /**
4224     * creates a new Int16Array from current Int16Array based on a condition fn
4225     *
4226     * @param fn the condition to apply for each element
4227     *
4228     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4229     */
4230    public filter(fn: (val: number) => boolean): Int16Array {
4231        let newF: (val: number, index: number, array: Int16Array) => boolean =
4232            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4233        return this.filter(newF)
4234    }
4235
4236    /**
4237     * Returns the value of the first element in the array where predicate is true, and undefined
4238     * otherwise
4239     *
4240     * @param predicate find calls predicate once for each element of the array, in ascending
4241     * order, until it finds one where predicate returns true. If such an element is found, find
4242     * immediately returns that element value. Otherwise, find returns undefined
4243     *
4244     * @returns number | undefined
4245     */
4246    public find(predicate: () => boolean): number | undefined {
4247        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate())
4248    }
4249
4250    /**
4251     * Returns the value of the first element in the array where predicate is true, and undefined
4252     * otherwise
4253     *
4254     * @param predicate find calls predicate once for each element of the array, in ascending
4255     * order, until it finds one where predicate returns true. If such an element is found, find
4256     * immediately returns that element value. Otherwise, find returns undefined
4257     *
4258     * @returns number | undefined
4259     */
4260    public find(predicate: (value: number) => boolean): number | undefined {
4261        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate(value))
4262    }
4263
4264    /**
4265     * Returns the index of the first element in the array where predicate is true, and -1
4266     * otherwise
4267     *
4268     * @param predicate find calls predicate once for each element of the array, in ascending
4269     * order, until it finds one where predicate returns true. If such an element is found,
4270     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
4271     *
4272     * @returns number
4273     */
4274    public findIndex(predicate: (value: number) => boolean): number {
4275        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate(value)) as number
4276    }
4277
4278    /**
4279     * Finds the last element in the Int16Array that satisfies the condition
4280     *
4281     * @param fn condition
4282     *
4283     * @returns the last element that satisfies fn
4284     */
4285    public findLast(fn: (val: number) => boolean): number {
4286        let newF: (val: number, index: number, array: Int16Array) => boolean =
4287            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4288        return this.findLast(newF) as number
4289    }
4290
4291    /**
4292     * Finds an index of the last element in the Int16Array that satisfies the condition
4293     *
4294     * @param fn condition
4295     *
4296     * @returns the index of the last element that satisfies fn, -1 otherwise
4297     */
4298    public findLastIndex(fn: (val: number) => boolean): number {
4299        let newF: (val: number, index: number, array: Int16Array) => boolean =
4300            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4301        return this.findLastIndex(newF) as number
4302    }
4303
4304    /**
4305     * Performs the specified action for each element in Int16Array
4306     *
4307     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
4308     * callbackfn function one time for each element in the array.
4309     *
4310     * @returns None
4311     */
4312    public forEach(callbackfn: (value: number) => void): void {
4313        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn(value))
4314    }
4315
4316    /**
4317     * Determines whether the specified callback function returns true for any element of an array.
4318     *
4319     * @param predicate A function that accepts one argument.
4320     * The some method calls the predicate function for each element in the array
4321     * until the predicate returns a true or until the end of the array.
4322     *
4323     * @returns false unless predicate function returns true for an array element,
4324     * in which case true is immediately returned.
4325     */
4326    public some(predicate: (element: number) => boolean): boolean {
4327        return this.some((element: number, index: number, array: Int16Array): boolean => predicate(element))
4328    }
4329
4330    // NOTE (kprokopenko): this may be not skipped
4331    /**
4332     * Sorts in-place
4333     *
4334     * @param compareFn comparator —  used to determine the order of the elements.
4335     * compareFn returns a negative value if first argument is less than second argument,
4336     * zero if they're equal and a positive value otherwise.
4337     * If omitted, the elements are sorted in ascending order.
4338     *
4339     * @returns sorted Int16Array
4340     */
4341    public sort(compareFn?: (a: number, b: number) => number): this {
4342        let arr: short[] = new short[this.lengthInt]
4343        for (let i = 0; i < this.lengthInt; ++i) {
4344            arr[i] = this.getUnsafe(i)
4345        }
4346        let cmp = (l: short, r: short): number => {
4347                return (l - r) as number
4348            }
4349        if (compareFn != undefined) {
4350            cmp = (l: short, r: short): number => {
4351                return compareFn!(l as number, r as number)
4352            }
4353        }
4354        sort(arr, cmp)
4355        for (let i = 0; i < this.lengthInt; ++i) {
4356            this.setUnsafe(i, arr[i])
4357        }
4358        return this
4359    }
4360
4361    /**
4362     * Sorts in-place
4363     *
4364     * @param compareFn comparator —  used to determine the order of the elements.
4365     * compareFn returns a negative value if first argument is less than second argument,
4366     * zero if they're equal and a positive value otherwise.
4367     *
4368     * @returns sorted Int16Array
4369     */
4370    public sort(compareFn: (a: number) => number): this {
4371        let cmp = (a: number, b: number) => { return compareFn(a)}
4372        this.sort(cmp)
4373        return this
4374    }
4375
4376    /**
4377     * Sorts in-place
4378     *
4379     * @param fn compareFn —  used to determine the order of the elements.
4380     * compareFn returns a negative value if first argument is less than second argument,
4381     * zero if they're equal and a positive value otherwise.
4382     *
4383     * @returns sorted Int16Array
4384     */
4385    public sort(compareFn: () => number): this {
4386        let cmp = (a: number, b: number) => { return compareFn()}
4387        this.sort(cmp)
4388        return this
4389    }
4390
4391    /**
4392     * Determines whether the specified callback function returns true for any element of an array.
4393     *
4394     * @param predicate A function that accepts three arguments.
4395     * The some method calls the predicate function for each element in the array
4396     * until the predicate returns a true or until the end of the array.
4397     *
4398     * @returns false unless predicate function returns true for an array element,
4399     * in which case true is immediately returned.
4400     */
4401    public some(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
4402        for (let i = 0; i < this.lengthInt; ++i) {
4403            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
4404                return true
4405            }
4406        }
4407        return false
4408    }
4409
4410    /**
4411     * Determines whether the specified callback function returns true for any element of an array.
4412     *
4413     * @param predicate A function that accepts two arguments.
4414     * The some method calls the predicate function for each element in the array
4415     * until the predicate returns a true or until the end of the array.
4416     *
4417     * @returns false unless predicate function returns true for an array element,
4418     * in which case true is immediately returned.
4419     */
4420    public some(predicate: (element: number, index: number) => boolean): boolean {
4421        return this.some((element: number, index: number, array: Int16Array): boolean => predicate(element, index as number))
4422    }
4423
4424    /**
4425     * Determines whether the specified callback function returns true for any element of an array.
4426     *
4427     * @param predicate A function that accepts no arguments.
4428     * The some method calls the predicate function for each element in the array
4429     * until the predicate returns a true or until the end of the array.
4430     *
4431     * @returns false unless predicate function returns true for an array element,
4432     * in which case true is immediately returned.
4433     */
4434    public some(predicate: () => boolean): boolean {
4435        return this.some((element: number, index: number, array: Int16Array): boolean => predicate())
4436    }
4437
4438    /**
4439     * Calls the specified callback function for all the elements in an array.
4440     * The return value of the callback function is the accumulated result,
4441     * and is provided as an argument in the next call to the callback function.
4442     *
4443     * @param callbackfn A function that accepts four arguments.
4444     * The reduce method calls the callbackfn function one time for each element in the array.
4445     *
4446     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4447     * The first call to the callbackfn function provides this value as an argument.
4448     *
4449     * @returns The value that results from running the callback function to completion over the entire typed array.
4450     */
4451    public reduce<U = number>(
4452                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
4453                initialValue: U): U {
4454        let accumulatedValue = initialValue
4455        for (let i = 0; i < this.lengthInt; ++i) {
4456            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4457        }
4458        return accumulatedValue
4459    }
4460
4461    /**
4462     * Calls the specified callback function for all the elements in an array.
4463     * The return value of the callback function is the accumulated result,
4464     * and is provided as an argument in the next call to the callback function.
4465     *
4466     * @param callbackfn A function that accepts three arguments.
4467     * The reduce method calls the callbackfn function one time for each element in the array.
4468     *
4469     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4470     * The first call to the callbackfn function provides this value as an argument.
4471     *
4472     * @returns The value that results from running the callback function to completion over the entire typed array.
4473     */
4474    public reduce<U = number>(
4475                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
4476                initialValue: U): U {
4477        return this.reduce(
4478                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4479                        callbackfn(prevVal, currVal, currIndex), initialValue)
4480    }
4481
4482    /**
4483     * Calls the specified callback function for all the elements in an array.
4484     * The return value of the callback function is the accumulated result,
4485     * and is provided as an argument in the next call to the callback function.
4486     *
4487     * @param callbackfn A function that accepts two arguments.
4488     * The reduce method calls the callbackfn function one time for each element in the array.
4489     *
4490     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4491     * The first call to the callbackfn function provides this value as an argument.
4492     *
4493     * @returns The value that results from running the callback function to completion over the entire typed array.
4494     */
4495    public reduce<U = number>(
4496                callbackfn: (previousValue: U, currentValue: number) => U,
4497                initialValue: U): U {
4498        return this.reduce(
4499                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4500                        callbackfn(prevVal, currVal), initialValue)
4501    }
4502
4503    /**
4504     * Calls the specified callback function for all the elements in an array.
4505     * The return value of the callback function is the accumulated result,
4506     * and is provided as an argument in the next call to the callback function.
4507     *
4508     * @param callbackfn A function that accepts one argument
4509     * The reduce method calls the callbackfn function one time for each element in the array.
4510     *
4511     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4512     * The first call to the callbackfn function provides this value as an argument.
4513     *
4514     * @returns The value that results from running the callback function to completion over the entire typed array.
4515     */
4516    public reduce<U = number>(
4517                callbackfn: (previousValue: U) => U,
4518                initialValue: U): U {
4519        return this.reduce(
4520                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4521                        callbackfn(prevVal), initialValue)
4522    }
4523
4524    /**
4525     * Calls the specified callback function for all the elements in an array.
4526     * The return value of the callback function is the accumulated result,
4527     * and is provided as an argument in the next call to the callback function.
4528     *
4529     * @param callbackfn A function that accepts no arguments
4530     * The reduce method calls the callbackfn function one time for each element in the array.
4531     *
4532     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4533     * The first call to the callbackfn function provides this value as an argument.
4534     *
4535     * @returns The value that results from running the callback function to completion over the entire typed array.
4536     */
4537    public reduce<U = number>(
4538                callbackfn: () => U,
4539                initialValue: U): U {
4540        return this.reduce(
4541                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4542                        callbackfn(), initialValue)
4543    }
4544
4545    /**
4546     * Calls the specified callback function for all the elements in an array.
4547     * The return value of the callback function is the accumulated result,
4548     * and is provided as an argument in the next call to the callback function.
4549     *
4550     * @param callbackfn A function that accepts four arguments.
4551     * The reduce method calls the callbackfn function one time for each element in the array.
4552     * The first call to the callbackfn function provides array first element value as an argument
4553     *
4554     * @returns The value that results from running the callback function to completion over the entire typed array.
4555     * calling reduce method on an empty array without an initial value creates a TypeError
4556     */
4557    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
4558        if (this.lengthInt == 0) {
4559            throw new TypeError("Reduce of empty array with no initial value")
4560        }
4561
4562        let accumulatedValue = this.getUnsafe(0) as number
4563        for (let i = 1; i < this.lengthInt; ++i) {
4564            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4565        }
4566        return accumulatedValue
4567    }
4568
4569    /**
4570     * Calls the specified callback function for all the elements in an array.
4571     * The return value of the callback function is the accumulated result,
4572     * and is provided as an argument in the next call to the callback function.
4573     *
4574     * @param callbackfn A function that accepts three arguments.
4575     * The reduce method calls the callbackfn function one time for each element in the array.
4576     * The first call to the callbackfn function provides array first element value as an argument
4577     *
4578     * @returns The value that results from running the callback function to completion over the entire typed array.
4579     * calling reduce method on an empty array without an initial value creates a TypeError
4580     */
4581    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
4582        return this.reduce(
4583                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4584                        callbackfn(prevVal, currVal, currIndex))
4585    }
4586
4587    /**
4588     * Calls the specified callback function for all the elements in an array.
4589     * The return value of the callback function is the accumulated result,
4590     * and is provided as an argument in the next call to the callback function.
4591     *
4592     * @param callbackfn A function that accepts two arguments.
4593     * The reduce method calls the callbackfn function one time for each element in the array.
4594     * The first call to the callbackfn function provides array first element value as an argument
4595     *
4596     * @returns The value that results from running the callback function to completion over the entire typed array.
4597     * calling reduce method on an empty array without an initial value creates a TypeError
4598     */
4599    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
4600        return this.reduce(
4601                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4602                        callbackfn(prevVal, currVal))
4603    }
4604
4605    /**
4606     * Calls the specified callback function for all the elements in an array.
4607     * The return value of the callback function is the accumulated result,
4608     * and is provided as an argument in the next call to the callback function.
4609     *
4610     * @param callbackfn A function that accepts one argument.
4611     * The reduce method calls the callbackfn function one time for each element in the array.
4612     * The first call to the callbackfn function provides array first element value as an argument
4613     *
4614     * @returns The value that results from running the callback function to completion over the entire typed array.
4615     * calling reduce method on an empty array without an initial value creates a TypeError
4616     */
4617    public reduce(callbackfn: (previousValue: number) => number): number {
4618        return this.reduce(
4619                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4620                        callbackfn(prevVal))
4621    }
4622
4623    /**
4624     * Calls the specified callback function for all the elements in an array.
4625     * The return value of the callback function is the accumulated result,
4626     * and is provided as an argument in the next call to the callback function.
4627     *
4628     * @param callbackfn A function that accepts no arguments.
4629     * The reduce method calls the callbackfn function one time for each element in the array.
4630     * The first call to the callbackfn function provides array first element value as an argument
4631     *
4632     * @returns The value that results from running the callback function to completion over the entire typed array.
4633     * calling reduce method on an empty array without an initial value creates a TypeError
4634     */
4635    public reduce(callbackfn: () => number): number {
4636        return this.reduce(
4637                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4638                        callbackfn())
4639    }
4640
4641
4642    /**
4643     * Calls the specified callback function for all the elements in an array, in descending order.
4644     * The return value of the callback function is the accumulated result,
4645     * and is provided as an argument in the next call to the callback function.
4646     *
4647     * @param callbackfn A function that accepts four arguments.
4648     * The reduceRight method calls the callbackfn function one time for each element in the array.
4649     *
4650     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4651     * The first call to the callbackfn function provides this value as an argument.
4652     *
4653     * @returns The value that results from running the callback function to completion over the entire typed array.
4654     */
4655    public reduceRight<U = number>(
4656                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
4657                initialValue: U): U {
4658        let accumulatedValue = initialValue
4659        for (let i = this.lengthInt - 1; i >= 0; --i) {
4660            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4661        }
4662        return accumulatedValue
4663    }
4664
4665    /**
4666     * Calls the specified callback function for all the elements in an array, in descending order.
4667     * The return value of the callback function is the accumulated result,
4668     * and is provided as an argument in the next call to the callback function.
4669     *
4670     * @param callbackfn A function that accepts three arguments.
4671     * The reduceRight method calls the callbackfn function one time for each element in the array.
4672     *
4673     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4674     * The first call to the callbackfn function provides this value as an argument.
4675     *
4676     * @returns The value that results from running the callback function to completion over the entire typed array.
4677     */
4678    public reduceRight<U = number>(
4679                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
4680                initialValue: U): U {
4681        return this.reduceRight(
4682                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4683                        callbackfn(prevVal, currVal, currIndex), initialValue)
4684    }
4685
4686    /**
4687     * Calls the specified callback function for all the elements in an array, in descending order.
4688     * The return value of the callback function is the accumulated result,
4689     * and is provided as an argument in the next call to the callback function.
4690     *
4691     * @param callbackfn A function that accepts two arguments.
4692     * The reduceRight method calls the callbackfn function one time for each element in the array.
4693     *
4694     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4695     * The first call to the callbackfn function provides this value as an argument.
4696     *
4697     * @returns The value that results from running the callback function to completion over the entire typed array.
4698     */
4699    public reduceRight<U = number>(
4700                callbackfn: (previousValue: U, currentValue: number) => U,
4701                initialValue: U): U {
4702        return this.reduceRight(
4703                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4704                        callbackfn(prevVal, currVal), initialValue)
4705    }
4706
4707    /**
4708     * Calls the specified callback function for all the elements in an array, in descending order.
4709     * The return value of the callback function is the accumulated result,
4710     * and is provided as an argument in the next call to the callback function.
4711     *
4712     * @param callbackfn A function that accepts one argument.
4713     * The reduceRight method calls the callbackfn function one time for each element in the array.
4714     *
4715     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4716     * The first call to the callbackfn function provides this value as an argument.
4717     *
4718     * @returns The value that results from running the callback function to completion over the entire typed array.
4719     */
4720    public reduceRight<U = number>(
4721                callbackfn: (previousValue: U) => U,
4722                initialValue: U): U {
4723        return this.reduceRight(
4724                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4725                        callbackfn(prevVal), initialValue)
4726    }
4727
4728    /**
4729     * Calls the specified callback function for all the elements in an array, in descending order.
4730     * The return value of the callback function is the accumulated result,
4731     * and is provided as an argument in the next call to the callback function.
4732     *
4733     * @param callbackfn A function that accepts no arguments.
4734     * The reduceRight method calls the callbackfn function one time for each element in the array.
4735     *
4736     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4737     * The first call to the callbackfn function provides this value as an argument.
4738     *
4739     * @returns The value that results from running the callback function to completion over the entire typed array.
4740     */
4741    public reduceRight<U = number>(
4742                callbackfn: () => U,
4743                initialValue: U): U {
4744        return this.reduceRight(
4745                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4746                        callbackfn(), initialValue)
4747    }
4748
4749    /**
4750     * Calls the specified callback function for all the elements in an array, in descending order.
4751     * The return value of the callback function is the accumulated result,
4752     * and is provided as an argument in the next call to the callback function.
4753     *
4754     * @param callbackfn A function that accepts four arguments.
4755     * The reduceRight method calls the callbackfn function one time for each element in the array.
4756     * The first call to the callbackfn function provides array last element value as an argument
4757     *
4758     * @returns The value that results from running the callback function to completion over the entire typed array.
4759     * calling reduceRight method on an empty array without an initial value creates a TypeError
4760     */
4761    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
4762        if (this.lengthInt == 0) {
4763            throw new TypeError("Reduce of empty array with no initial value")
4764        }
4765
4766        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
4767        for (let i = this.lengthInt - 2; i >= 0; --i) {
4768            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4769        }
4770        return accumulatedValue
4771    }
4772
4773    /**
4774     * Calls the specified callback function for all the elements in an array, in descending order.
4775     * The return value of the callback function is the accumulated result,
4776     * and is provided as an argument in the next call to the callback function.
4777     *
4778     * @param callbackfn A function that accepts three arguments.
4779     * The reduceRight method calls the callbackfn function one time for each element in the array.
4780     * The first call to the callbackfn function provides array last element value as an argument
4781     *
4782     * @returns The value that results from running the callback function to completion over the entire typed array.
4783     * calling reduceRight method on an empty array without an initial value creates a TypeError
4784     */
4785    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
4786        return this.reduceRight(
4787                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4788                        callbackfn(prevValue, currValue, currIndex))
4789    }
4790
4791    /**
4792     * Calls the specified callback function for all the elements in an array, in descending order.
4793     * The return value of the callback function is the accumulated result,
4794     * and is provided as an argument in the next call to the callback function.
4795     *
4796     * @param callbackfn A function that accepts two arguments.
4797     * The reduceRight method calls the callbackfn function one time for each element in the array.
4798     * The first call to the callbackfn function provides array last element value as an argument
4799     *
4800     * @returns The value that results from running the callback function to completion over the entire typed array.
4801     * calling reduceRight method on an empty array without an initial value creates a TypeError
4802     */
4803    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
4804        return this.reduceRight(
4805                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4806                        callbackfn(prevValue, currValue))
4807    }
4808
4809    /**
4810     * Calls the specified callback function for all the elements in an array, in descending order.
4811     * The return value of the callback function is the accumulated result,
4812     * and is provided as an argument in the next call to the callback function.
4813     *
4814     * @param callbackfn A function that accepts one argument.
4815     * The reduceRight method calls the callbackfn function one time for each element in the array.
4816     * The first call to the callbackfn function provides array last element value as an argument
4817     *
4818     * @returns The value that results from running the callback function to completion over the entire typed array.
4819     * calling reduceRight method on an empty array without an initial value creates a TypeError
4820     */
4821    public reduceRight(callbackfn: (previousValue: number) => number): number {
4822        return this.reduceRight(
4823                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4824                        callbackfn(prevValue))
4825    }
4826
4827    /**
4828     * Calls the specified callback function for all the elements in an array, in descending order.
4829     * The return value of the callback function is the accumulated result,
4830     * and is provided as an argument in the next call to the callback function.
4831     *
4832     * @param callbackfn A function that accepts no arguments.
4833     * The reduceRight method calls the callbackfn function one time for each element in the array.
4834     * The first call to the callbackfn function provides array last element value as an argument
4835     *
4836     * @returns The value that results from running the callback function to completion over the entire typed array.
4837     * calling reduceRight method on an empty array without an initial value creates a TypeError
4838     */
4839    public reduceRight(callbackfn: () => number): number {
4840        return this.reduceRight(
4841                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4842                        callbackfn())
4843    }
4844
4845   /**
4846    * Creates a new Int16Array using fn(arr[i]) over all elements of current Int16Array.
4847    *
4848    * @param fn a function to apply for each element of current Int16Array
4849    *
4850    * @returns a new Int16Array where for each element from current Int16Array fn was applied
4851    */
4852    public map(fn: (val: number, index: number, array: Int16Array) => number): Int16Array {
4853        let resBuf = new ArrayBuffer(this.lengthInt * Int16Array.BYTES_PER_ELEMENT as int)
4854        let res = new Int16Array(resBuf, 0, resBuf.getByteLength() / Int16Array.BYTES_PER_ELEMENT as int)
4855        for (let i = 0; i < this.lengthInt; ++i) {
4856            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as short)
4857        }
4858        return res
4859    }
4860
4861    /**
4862     * Creates a new Int16Array using fn(arr[i], i) over all elements of current Int16Array
4863     *
4864     * @param fn a function to apply for each element of current Int16Array
4865     *
4866     * @returns a new Int16Array where for each element from current Int16Array fn was applied
4867     */
4868    public map(fn: (val: number, index: number) => number): Int16Array {
4869        let newF: (val: number, index: number, array: Int16Array) => number =
4870            (val: number, index: number, array: Int16Array): number => { return fn(val, index) }
4871        return this.map(newF)
4872    }
4873
4874    /**
4875     * Creates a new Int16Array using fn(arr[i]) over all elements of current Int16Array
4876     *
4877     * @param fn a function to apply for each element of current Int16Array
4878     *
4879     * @returns a new Int16Array where for each element from current Int16Array fn was applied
4880     */
4881    public map(fn: (val: number) => number): Int16Array {
4882        let newF: (val: number, index: number, array: Int16Array) => number =
4883            (val: number, index: number, array: Int16Array): number => { return fn(val) }
4884        return this.map(newF)
4885    }
4886
4887    /**
4888     * Creates a new Int16Array using fn() over all elements of current Int16Array
4889     *
4890     * @param fn a function to apply for each element of current Int16Array
4891     *
4892     * @returns a new Int16Array where for each element from current Int16Array fn was applied
4893     */
4894    public map(fn: () => number): Int16Array {
4895        let newF: (val: number, index: number, array: Int16Array) => number =
4896            (val: number, index: number, array: Int16Array): number => { return fn() }
4897        return this.map(newF)
4898    }
4899
4900
4901    /**
4902     * Determines whether the specified callback function returns true for all elements of an array.
4903     *
4904     * @param predicate A function that accepts three arguments.
4905     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4906     * or until the end of the array.
4907     *
4908     * @returns true unless predicate function returns a false for an array element,
4909     * in which case false is immediately returned.
4910     */
4911    public every(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
4912        for (let i = 0; i < this.lengthInt; ++i) {
4913            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
4914                return false
4915            }
4916        }
4917        return true
4918    }
4919
4920    /**
4921     * Determines whether the specified callback function returns true for all elements of an array.
4922     *
4923     * @param predicate A function that accepts two arguments.
4924     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4925     * or until the end of the array.
4926     *
4927     * @returns true unless predicate function returns a false for an array element,
4928     * in which case false is immediately returned.
4929     */
4930    public every(predicate: (element: number, index: number) => boolean): boolean {
4931        return this.every((element: number, index: number, array: Int16Array): boolean => predicate(element, index))
4932    }
4933
4934    /**
4935     * Determines whether the specified callback function returns true for all elements of an array.
4936     *
4937     * @param predicate A function that accepts no arguments.
4938     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4939     * or until the end of the array.
4940     *
4941     * @returns true unless predicate function returns a false for an array element,
4942     * in which case false is immediately returned.
4943     */
4944    public every(predicate: () => boolean): boolean {
4945        return this.every((element: number, index: number, array: Int16Array): boolean => predicate())
4946    }
4947
4948    /**
4949     * Creates a new Int16Array from current Int16Array based on a condition fn.
4950     *
4951     * @param fn the condition to apply for each element
4952     *
4953     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4954     */
4955    public filter(fn: (val: number, index: number, array: Int16Array) => boolean): Int16Array {
4956        let markers = new boolean[this.lengthInt]
4957        let resLen = 0
4958        for (let i = 0; i < this.lengthInt; ++i) {
4959            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
4960            if (markers[i]) {
4961                ++resLen
4962            }
4963        }
4964        let resBuf = new ArrayBuffer(resLen * Int16Array.BYTES_PER_ELEMENT as int)
4965        let res = new Int16Array(resBuf, 0)
4966        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
4967            if (markers[i]) {
4968                res.set(j, this.getUnsafe(i))
4969                ++j
4970            }
4971        }
4972        return res
4973    }
4974
4975    /**
4976     * creates a new Int16Array from current Int16Array based on a condition fn
4977     *
4978     * @param fn the condition to apply for each element
4979     *
4980     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4981     */
4982    public filter(fn: (val: number, index: number) => boolean): Int16Array {
4983        let newF: (val: number, index: number, array: Int16Array) => boolean =
4984            (val: number, index: number, array: Int16Array): boolean => { return fn(val, index as number) }
4985        return this.filter(newF)
4986    }
4987
4988    /**
4989     * creates a new Int16Array from current Int16Array based on a condition fn
4990     *
4991     * @param fn the condition to apply for each element
4992     *
4993     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4994     */
4995    public filter(fn: () => boolean): Int16Array {
4996        let newF: (val: number, index: number, array: Int16Array) => boolean =
4997            (val: number, index: number, array: Int16Array): boolean => { return fn() }
4998        return this.filter(newF)
4999    }
5000
5001    /**
5002     * Returns the value of the first element in the array where predicate is true, and undefined
5003     * otherwise
5004     *
5005     * @param predicate find calls predicate once for each element of the array, in ascending
5006     * order, until it finds one where predicate returns true. If such an element is found, find
5007     * immediately returns that element value. Otherwise, find returns undefined
5008     *
5009     * @returns number | undefined
5010     */
5011    public find(predicate: (value: number, index: number, obj: Int16Array) => boolean): number | undefined {
5012        for (let i = 0; i < this.lengthInt; ++i) {
5013            let val = this.getUnsafe(i)
5014            if (predicate(val as number, i as number, this)) {
5015                return val as number
5016            }
5017        }
5018        return undefined
5019    }
5020
5021    /**
5022     * Returns the value of the first element in the array where predicate is true, and undefined
5023     * otherwise
5024     *
5025     * @param predicate find calls predicate once for each element of the array, in ascending
5026     * order, until it finds one where predicate returns true. If such an element is found, find
5027     * immediately returns that element value. Otherwise, find returns undefined
5028     *
5029     * @returns number | undefined
5030     */
5031    public find(predicate: (value: number, index: number) => boolean): number | undefined {
5032        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate(value, index))
5033    }
5034
5035    /**
5036     * Returns the index of the first element in the array where predicate is true, and -1
5037     * otherwise
5038     *
5039     * @param predicate find calls predicate once for each element of the array, in ascending
5040     * order, until it finds one where predicate returns true. If such an element is found,
5041     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
5042     *
5043     * @returns number
5044     */
5045    public findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean): number {
5046        for (let i = 0; i < this.lengthInt; ++i) {
5047            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
5048                return i as number
5049            }
5050        }
5051        return -1 as number
5052    }
5053
5054    /**
5055     * Returns the index of the first element in the array where predicate is true, and -1
5056     * otherwise
5057     *
5058     * @param predicate find calls predicate once for each element of the array, in ascending
5059     * order, until it finds one where predicate returns true. If such an element is found,
5060     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
5061     *
5062     * @returns number
5063     */
5064    public findIndex(predicate: (value: number, index: number) => boolean): number {
5065        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate(value, index as number)) as number
5066    }
5067
5068    /**
5069     * Returns the index of the first element in the array where predicate is true, and -1
5070     * otherwise
5071     *
5072     * @param predicate find calls predicate once for each element of the array, in ascending
5073     * order, until it finds one where predicate returns true. If such an element is found,
5074     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
5075     *
5076     * @returns number
5077     */
5078    public findIndex(predicate: () => boolean): number {
5079        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate()) as number
5080    }
5081
5082    /**
5083     * Finds the last element in the Int16Array that satisfies the condition
5084     *
5085     * @param fn condition
5086     *
5087     * @returns the last element that satisfies fn
5088     */
5089    public findLast(fn: (val: number, index: number, array: Int16Array) => boolean): short {
5090        for (let i = this.lengthInt - 1; i >= 0; --i) {
5091            let val = this.getUnsafe(i)
5092            if (fn(val as number, i as number, this)) {
5093                return val
5094            }
5095        }
5096        throw new Error("Int16Array.findLast: not implemented if an element was not found")
5097    }
5098
5099    /**
5100     * Finds the last element in the Int16Array that satisfies the condition
5101     *
5102     * @param fn condition
5103     *
5104     * @returns the last element that satisfies fn
5105     */
5106    public findLast(fn: (val: number, index: number) => boolean): short {
5107        let newF: (val: number, index: number, array: Int16Array) => boolean =
5108            (val: number, index: number, array: Int16Array): boolean => { return fn(val as number, index as number) }
5109        return this.findLast(newF)
5110    }
5111
5112    /**
5113     * Finds an index of the last element in the Int16Array that satisfies the condition
5114     *
5115     * @param fn condition
5116     *
5117     * @returns the index of the last element that satisfies fn, -1 otherwise
5118     */
5119    public findLastIndex(fn: (val: number, index: number, array: Int16Array) => boolean): number {
5120        for (let i = this.lengthInt - 1; i >= 0; --i) {
5121            let val = this.getUnsafe(i)
5122            if (fn(val as number, i as number, this)) {
5123                return i
5124            }
5125        }
5126        return -1 as number
5127    }
5128
5129    /**
5130     * Finds an index of the last element in the Int16Array that satisfies the condition
5131     *
5132     * @param fn condition
5133     *
5134     * @returns the index of the last element that satisfies fn, -1 otherwise
5135     */
5136    public findLastIndex(fn: (val: number, index: number) => boolean): number {
5137        let newF: (val: number, index: number, array: Int16Array) => boolean =
5138            (val: number, index: number, array: Int16Array): boolean => { return fn(val, index as number) }
5139        return this.findLastIndex(newF) as number
5140    }
5141
5142    /**
5143     * Performs the specified action for each element in Int16Array
5144     *
5145     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5146     * callbackfn function one time for each element in the array.
5147     *
5148     * @returns None
5149     */
5150    public forEach(callbackfn: (value: number, index: number, array: Int16Array) => void): void {
5151        for (let i = 0; i < this.lengthInt; ++i) {
5152            callbackfn(this.getUnsafe(i) as number, i as number, this)
5153        }
5154    }
5155
5156    /**
5157     * Performs the specified action for each element in Int16Array
5158     *
5159     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5160     * callbackfn function one time for each element in the array.
5161     *
5162     * @returns None
5163     */
5164    public forEach(callbackfn: (value: number, index: number) => void): void {
5165        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn(value, index))
5166    }
5167
5168    /**
5169     * Performs the specified action for each element in Int16Array
5170     *
5171     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5172     * callbackfn function one time for each element in the array.
5173     *
5174     * @returns None
5175     */
5176    public forEach(callbackfn: () => void): void {
5177        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn())
5178    }
5179
5180    /**
5181     * Returns the object itself
5182     *
5183     * @returns Int16Array
5184     */
5185    public valueOf(): Int16Array {
5186        return this
5187    }
5188
5189    internal getUnsafe(index: int): short {
5190        let byteIndex = index * Int16Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
5191        let res : short = 0
5192        let byteVal : short
5193        if (IS_LITTLE_ENDIAN) {
5194            if (this.buffer instanceof ArrayBuffer) {
5195                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5196                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
5197                    byteVal &= 0xff
5198                    res = (res | byteVal << (8 * i)) as short
5199                }
5200            } else if (this.buffer instanceof SharedArrayBuffer) {
5201                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5202                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
5203                    byteVal &= 0xff
5204                    res = (res | byteVal << (8 * i)) as short
5205                }
5206            } else {
5207                throw new Error("unexpected type of ArrayBufferLike")
5208            }
5209            return res
5210        } else {
5211            if (this.buffer instanceof ArrayBuffer) {
5212                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5213                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 1 - i)
5214                    byteVal &= 0xff
5215                    res = (res | byteVal << (8 * i)) as short
5216                }
5217            } else if (this.buffer instanceof SharedArrayBuffer) {
5218                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5219                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 1 - i)
5220                    byteVal &= 0xff
5221                    res = (res | byteVal << (8 * i)) as short
5222                }
5223            } else {
5224                throw new Error("unexpected type of ArrayBufferLike")
5225            }
5226            return res
5227        }
5228    }
5229
5230    internal setUnsafe(insertPos: int, val: short): void {
5231        let startByte = insertPos * Int16Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
5232        let bits = val
5233        if (IS_LITTLE_ENDIAN) {
5234            if (this.buffer instanceof ArrayBuffer) {
5235                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5236                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5237                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
5238                }
5239            } else if (this.buffer instanceof SharedArrayBuffer) {
5240                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5241                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5242                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
5243                }
5244            } else {
5245                throw new Error("unexpected type of ArrayBufferLike")
5246            }
5247        } else {
5248            if (this.buffer instanceof ArrayBuffer) {
5249                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; i++) {
5250                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5251                    (this.buffer as ArrayBuffer).set(startByte + 1 - i, byteVal)
5252                }
5253            } else if (this.buffer instanceof SharedArrayBuffer) {
5254                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; i++) {
5255                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5256                    (this.buffer as SharedArrayBuffer).set(startByte + 1 - i, byteVal)
5257                }
5258            } else {
5259                throw new Error("unexpected type of ArrayBufferLike")
5260            }
5261        }
5262    }
5263
5264    /** Underlying ArrayBufferLike */
5265    public readonly buffer: ArrayBufferLike
5266
5267    /** Byte offset within the underlying ArrayBufferLike */
5268    public readonly byteOffset: number
5269
5270    /** Number of bytes used */
5271    public readonly byteLength: number
5272
5273    /** String \"Int16Array\" */
5274    public readonly name = "Int16Array"
5275}
5276
5277class Int32ArrayIteratorKeys implements IterableIterator<number> {
5278    private length: int
5279    private idx: int = 0
5280
5281    constructor(parent: Int32Array) {
5282        this.length = parent.length as int
5283    }
5284
5285    public override $_iterator(): IterableIterator<number> {
5286        return this
5287    }
5288
5289    override next(): IteratorResult<number> {
5290        if (this.idx < 0 || this.idx >= this.length) {
5291            return new IteratorResult<number>()
5292        }
5293        return new IteratorResult<number>(false, this.idx++ as number)
5294    }
5295}
5296
5297class Int32ArrayIterator implements IterableIterator<Number> {
5298    private parent: Int32Array
5299    private idx: int = 0
5300
5301    constructor(parent: Int32Array) {
5302        this.parent = parent
5303    }
5304
5305    public override $_iterator(): IterableIterator<Number> {
5306        return this
5307    }
5308
5309    override next(): IteratorResult<Number> {
5310        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5311            return new IteratorResult<Number>()
5312        }
5313        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
5314    }
5315}
5316
5317class Int32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
5318    private parent: Int32Array
5319    private idx: int = 0
5320
5321    constructor(parent: Int32Array) {
5322        this.parent = parent
5323    }
5324
5325    public override $_iterator(): IterableIterator<[Number, Number]> {
5326        return this
5327    }
5328
5329    override next(): IteratorResult<[Number, Number]> {
5330        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5331            return new IteratorResult<[Number, Number]>()
5332        }
5333        return new IteratorResult<[Number, Number]>(
5334            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
5335        )
5336    }
5337}
5338
5339
5340/**
5341 * JS Int32Array API-compatible class
5342 */
5343export final class Int32Array implements Iterable<Number>, ArrayLike<Number> {
5344    public static readonly BYTES_PER_ELEMENT: number = 4
5345    internal readonly lengthInt: int
5346
5347    /**
5348     * Creates an empty Int32Array.
5349     */
5350    public constructor() {
5351        this(0 as int)
5352    }
5353
5354    /**
5355     * Creates an Int32Array with respect to data accessed via Iterable<Number> interface
5356     */
5357    public constructor(elements: Iterable<Number>) {
5358        const items: Object = elements as Object
5359        if (items instanceof ArrayLike) {
5360            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
5361            this.byteLength = arr.length as int * Int32Array.BYTES_PER_ELEMENT as int
5362            this.lengthInt = arr.length as int
5363            this.buffer = new ArrayBuffer(this.byteLength as int)
5364            this.byteOffset = 0
5365            for (let i: int = 0; i < this.lengthInt; ++i) {
5366                this.setUnsafe(i, arr.$_get(i).intValue())
5367            }
5368        } else {
5369          let x = Int32Array.from(elements)
5370          this.byteLength = x.byteLength
5371          this.lengthInt = x.lengthInt
5372          this.buffer = x.buffer
5373          this.byteOffset = x.byteOffset
5374        }
5375    }
5376
5377    /**
5378     * Creates an Int32Array with respect to data, byteOffset and length.
5379     *
5380     * @param buf data initializer
5381     *
5382     * @param byteOffset byte offset from begin of the buf
5383     *
5384     * @param length size of elements of type int in newly created Int32Array
5385     */
5386    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
5387        let intByteOffset: int = 0
5388        if (byteOffset != undefined) {
5389            intByteOffset = byteOffset.intValue()
5390            if (intByteOffset < 0) {
5391                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
5392            }
5393        }
5394        let intByteLength: int
5395        if (buf instanceof ArrayBuffer) {
5396            intByteLength = (buf as ArrayBuffer).getByteLength()
5397        } else if (buf instanceof SharedArrayBuffer) {
5398            intByteLength = (buf as SharedArrayBuffer).getByteLength()
5399        } else {
5400            throw new Error("unexpected type of ArrayBufferLike")
5401        }
5402        intByteLength = intByteLength - intByteOffset
5403        if (intByteLength < 0) {
5404            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5405        }
5406
5407        if (intByteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5408            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5409        }
5410        if (intByteOffset % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5411            throw new RangeError("byteOffset should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5412        }
5413
5414        let intLength: int
5415        if (length != undefined) {
5416            intLength = length.intValue()
5417            if (intLength > intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
5418                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5419            }
5420        } else {
5421            intLength = intByteLength / Int32Array.BYTES_PER_ELEMENT as int
5422        }
5423        if (intLength < 0) {
5424            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
5425        }
5426        if (intLength < intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
5427            intByteLength = intLength * Int32Array.BYTES_PER_ELEMENT as int
5428        }
5429        this.byteLength = intByteLength
5430        this.byteOffset = intByteOffset
5431        this.lengthInt = intLength
5432        this.buffer = buf
5433    }
5434
5435    /**
5436     * Creates an Int32Array with respect to data, byteOffset and length.
5437     *
5438     * @param buf data initializer
5439     *
5440     * @param byteOffset byte offset from begin of the buf
5441     *
5442     * @param length size of elements of type int in newly created Int32Array
5443     */
5444    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
5445        this(buf, byteOffset, undefined)
5446    }
5447
5448    /**
5449     * Creates an Int32Array with respect to data, byteOffset and length.
5450     *
5451     * @param buf data initializer
5452     *
5453     * @param byteOffset byte offset from begin of the buf
5454     *
5455     * @param length size of elements of type int in newly created Int32Array
5456     */
5457    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
5458        this(buf, new Number(byteOffset), new Number(length))
5459    }
5460
5461    /**
5462     * Creates an Int32Array with respect to data, byteOffset and length.
5463     *
5464     * @param buf data initializer
5465     *
5466     * @param byteOffset byte offset from begin of the buf
5467     *
5468     * @param length size of elements of type int in newly created Int32Array
5469     */
5470    public constructor(buf: ArrayBufferLike, byteOffset: number) {
5471        this(buf, new Number(byteOffset), undefined)
5472    }
5473
5474    /**
5475     * Creates an Int32Array with respect to data, byteOffset and length.
5476     *
5477     * @param buf data initializer
5478     *
5479     * @param byteOffset byte offset from begin of the buf
5480     *
5481     * @param length size of elements of type int in newly created Int32Array
5482     */
5483    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
5484        this(buf, new Number(byteOffset), new Number(length))
5485    }
5486
5487    /**
5488     * Creates an Int32Array with respect to buf and byteOffset.
5489     *
5490     * @param buf data initializer
5491     *
5492     * @param byteOffset byte offset from begin of the buf
5493     */
5494    public constructor(buf: ArrayBufferLike, byteOffset: int) {
5495        this(buf, new Number(byteOffset), undefined)
5496    }
5497
5498    /**
5499     * Creates an Int32Array with respect to buf.
5500     *
5501     * @param buf data initializer
5502     */
5503    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
5504        if (buf instanceof ArrayBuffer) {
5505            this.byteLength = (buf as ArrayBuffer).getByteLength()
5506            if (this.byteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5507               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5508            }
5509            this.lengthInt = this.byteLength / Int32Array.BYTES_PER_ELEMENT as int
5510            this.buffer = buf as ArrayBuffer
5511            this.byteOffset = 0
5512        } else if (buf instanceof SharedArrayBuffer) {
5513            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
5514            if (this.byteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5515               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5516            }
5517            this.lengthInt = this.byteLength / Int32Array.BYTES_PER_ELEMENT as int
5518            this.buffer = buf as SharedArrayBuffer
5519            this.byteOffset = 0
5520        } else if (buf instanceof ArrayLike) {
5521            // NOTE (ikorobkov): dealing with this overload is tricky
5522            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
5523            let arr = Array.from<Number>((buf as ArrayLike<Number>))
5524            this.byteLength = arr.length as int * Int32Array.BYTES_PER_ELEMENT as int
5525            this.lengthInt = arr.length as int
5526            this.buffer = new ArrayBuffer(this.byteLength as int)
5527            this.byteOffset = 0
5528            for (let i: int = 0; i < this.lengthInt; ++i) {
5529                this.setUnsafe(i, arr.$_get(i).intValue())
5530            }
5531        } else {
5532            throw new Error("unexpected type of buf")
5533        }
5534    }
5535
5536    /**
5537     * Creates an Int32Array with respect to length.
5538     *
5539     * @param length data initializer
5540     */
5541    public constructor(length: int) {
5542        if (length < 0) {
5543            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
5544        }
5545        this.lengthInt = length
5546        this.byteLength = length * Int32Array.BYTES_PER_ELEMENT as int
5547        this.byteOffset = 0
5548        this.buffer = new ArrayBuffer(this.byteLength as int)
5549    }
5550
5551    /**
5552     * Creates an Int32Array with respect to length.
5553     *
5554     * @param length data initializer
5555     */
5556    public constructor(length: number) {
5557        this(length as int)
5558    }
5559
5560    /**
5561     * Creates a copy of Int32Array.
5562     *
5563     * @param other data initializer
5564     */
5565    public constructor(other: Int32Array) {
5566        if (other.buffer instanceof ArrayBuffer) {
5567            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
5568        } else if (other.buffer instanceof SharedArrayBuffer) {
5569            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
5570        } else {
5571            throw new Error("unexpected type of buffer")
5572        }
5573        this.byteLength = other.byteLength
5574        this.lengthInt = other.length as int
5575        this.byteOffset = 0
5576    }
5577
5578    /**
5579     * Creates an Int32Array from number[]
5580     */
5581    public constructor(numbers: number[]) {
5582        this(numbers.length)
5583        for (let i: int = 0; i < this.lengthInt; ++i) {
5584            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
5585        }
5586    }
5587
5588    /**
5589     * Creates an Int32Array from int[]
5590     */
5591    public constructor(numbers: int[]) {
5592        this(numbers.length)
5593        for (let i: int = 0; i < this.lengthInt; ++i) {
5594            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
5595        }
5596    }
5597
5598    internal zeroIfInfinity(val: number): number {
5599        if ((val == Infinity) || (val == -Infinity)) {
5600            return 0 as number
5601        }
5602        return val as number
5603    }
5604
5605    internal zeroIfInfinity(val: int): int {
5606        if ((val == Infinity) || (val == -Infinity)) {
5607            return 0 as int
5608        }
5609        return val
5610    }
5611
5612    /**
5613     * Assigns val as element on index.
5614     *
5615     * @param val value to set
5616     *
5617     * @param index index to change
5618     */
5619    public $_set(index: number, val: number): void {
5620        this.$_set(index as int, val)
5621    }
5622
5623    /**
5624     * Assigns val as element on index.
5625     *
5626     * @param val value to set
5627     *
5628     * @param index index to change
5629     */
5630    public $_set(index: int, val: number): void {
5631        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
5632        if (index < 0 || index >= this.lengthInt) {
5633            throw new RangeError("invalid index")
5634        }
5635        let v = this.zeroIfInfinity(val)
5636        this.setUnsafe(index, v as int)
5637    }
5638
5639    /**
5640     * Assigns val as element on index.
5641     *
5642     * @param val value to set
5643     *
5644     * @param index index to change
5645     */
5646    public $_set(index: number, val: int): void {
5647        this.$_set(index as int, val)
5648    }
5649
5650    /**
5651     * Assigns val as element on index.
5652     *
5653     * @param val value to set
5654     *
5655     * @param index index to change
5656     */
5657    public $_set(index: int, val: int): void {
5658        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
5659        if (index < 0 || index >= this.lengthInt) {
5660            throw new RangeError("invalid index")
5661        }
5662        let v = this.zeroIfInfinity(val)
5663        this.setUnsafe(index, v)
5664    }
5665
5666    /** Number of int stored in Int32Array */
5667    public get length(): number {
5668        return this.lengthInt
5669    }
5670
5671    /**
5672     * Returns an instance of number at passed index.
5673     *
5674     * @param index index to look at
5675     *
5676     * @returns a primitive at index
5677     */
5678    public override $_get(index: number): Number {
5679        return this.$_get(index as int) as Number
5680    }
5681
5682    /**
5683     * Returns an instance of number at passed index.
5684     *
5685     * @param index index to look at
5686     *
5687     * @returns a primitive at index
5688     */
5689    public $_get(index: int): number {
5690        if (index < 0 || index >= this.lengthInt) {
5691            throw new RangeError("invalid index")
5692        }
5693        return this.getUnsafe(index) as number
5694    }
5695
5696    /**
5697     * Returns an instance of primitive type at passed index.
5698     *
5699     * @param index index to look at
5700     *
5701     * @returns a primitive at index
5702     */
5703    public at(index: number): Number | undefined {
5704        return this.at(index as int)
5705    }
5706
5707    /**
5708     * Returns an instance of primitive type at passed index.
5709     *
5710     * @param index index to look at
5711     *
5712     * @returns a primitive at index
5713     */
5714    public at(index: int): Number | undefined {
5715        let k: int
5716        if (index >= 0) {
5717            k = index
5718        } else {
5719            k = this.lengthInt + index
5720        }
5721        if (k < 0 || k >= this.lengthInt) {
5722            return undefined
5723        }
5724        return new Number(this.getUnsafe(k))
5725    }
5726
5727    /**
5728     * Makes a copy of internal elements to targetPos from startPos to endPos.
5729     *
5730     * @param target insert index to place copied elements
5731     *
5732     * @param start start index to begin copy from
5733     *
5734     * @param end last index to end copy from, excluded
5735     *
5736     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5737     */
5738    public copyWithin(target: number, start: number, end?: number): Int32Array {
5739        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5740    }
5741
5742    /**
5743     * Makes a copy of internal elements to targetPos from startPos to endPos.
5744     *
5745     * @param target insert index to place copied elements
5746     *
5747     * @param start start index to begin copy from
5748     *
5749     * @param end last index to end copy from, excluded
5750     *
5751     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5752     */
5753    public copyWithin(target: int, start: number, end?: number): Int32Array {
5754        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5755    }
5756
5757    /**
5758     * Makes a copy of internal elements to targetPos from startPos to endPos.
5759     *
5760     * @param target insert index to place copied elements
5761     *
5762     * @param start start index to begin copy from
5763     *
5764     * @param end last index to end copy from, excluded
5765     *
5766     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5767     */
5768    public copyWithin(target: number, start: int, end?: number): Int32Array {
5769        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5770    }
5771
5772    /**
5773     * Makes a copy of internal elements to targetPos from startPos to endPos.
5774     *
5775     * @param target insert index to place copied elements
5776     *
5777     * @param start start index to begin copy from
5778     *
5779     * @param end last index to end copy from, excluded
5780     *
5781     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5782     */
5783    public copyWithin(target: int, start: int, end?: number): Int32Array {
5784        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5785    }
5786
5787    /**
5788     * Makes a copy of internal elements to targetPos from startPos to endPos.
5789     *
5790     * @param target insert index to place copied elements
5791     *
5792     * @param start start index to begin copy from
5793     *
5794     * @param end last index to end copy from, excluded
5795     *
5796     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5797     */
5798    public copyWithin(target: int, start: int, end: int): Int32Array {
5799        let toPos = normalizeIndex(target, this.lengthInt)
5800        let fromPos = normalizeIndex(start, this.lengthInt)
5801        const finalPos = normalizeIndex(end, this.lengthInt)
5802        let count: int = finalPos - fromPos
5803        if (count > (this.lengthInt - toPos)) {
5804            count = this.lengthInt - toPos
5805        }
5806        let direction: int = 1
5807        if ((fromPos < toPos) && (toPos < fromPos + count)) {
5808            fromPos = fromPos + count - 1
5809            toPos   = toPos   + count - 1
5810            direction = -1
5811        }
5812        while (count > 0) {
5813            const value = this.getUnsafe(fromPos)
5814            this.setUnsafe(toPos, value)
5815            fromPos = fromPos + direction
5816            toPos = toPos + direction
5817            --count
5818        }
5819        return this
5820    }
5821
5822    /**
5823     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
5824     *
5825     * @param target insert index to place copied elements
5826     *
5827     * See rules of parameters normalization:
5828     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5829     */
5830    public copyWithin(target: number): Int32Array {
5831        return this.copyWithin(target as int)
5832    }
5833
5834    /**
5835     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
5836     *
5837     * @param target insert index to place copied elements
5838     *
5839     * See rules of parameters normalization:
5840     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5841     */
5842    public copyWithin(target: int): Int32Array {
5843        return this.copyWithin(target, 0, this.lengthInt)
5844    }
5845
5846    /**
5847     * Returns an array of key, value pairs for every entry in the Int32Array
5848     *
5849     * @returns key, value pairs for every entry in the array
5850     */
5851    public entries(): IterableIterator<[Number, Number]> {
5852        return new Int32ArrayIteratorEntries(this)
5853    }
5854
5855    /**
5856     * Fills the Int32Array with specified value
5857     *
5858     * @param value new valuy
5859     *
5860     * @returns modified Int32Array
5861     */
5862    public fill(value: number, start?: number, end?: number): this {
5863        value = this.zeroIfInfinity(value)
5864        this.fill(value as int, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
5865        return this
5866    }
5867
5868    /**
5869     * Fills the Int32Array with specified value
5870     *
5871     * @param value new valuy
5872     *
5873     * @returns modified Int32Array
5874     */
5875    public fill(value: number, start: int, end?: number): this {
5876        value = this.zeroIfInfinity(value)
5877        this.fill(value as int, start as int, asIntOrDefault(end, this.lengthInt))
5878        return this
5879    }
5880
5881    /**
5882     * Fills the Int32Array with specified value
5883     *
5884     * @param value new valuy
5885     *
5886     * @returns modified Int32Array
5887     */
5888    public fill(value: number, start: int, end: number): this {
5889        value = this.zeroIfInfinity(value)
5890        this.fill(value as int, start as int, end as int)
5891        return this
5892    }
5893
5894    /**
5895     * Fills the Int32Array with specified value
5896     *
5897     * @param value new valuy
5898     *
5899     * @returns modified Int32Array
5900     */
5901    public fill(value: number, start: number, end: int): this {
5902        value = this.zeroIfInfinity(value)
5903        this.fill(value as int, start as int, end as int)
5904        return this
5905    }
5906
5907    /**
5908     * Fills the Int32Array with specified value
5909     *
5910     * @param value new valuy
5911     *
5912     * @returns modified Int32Array
5913     */
5914    public fill(value: number, start: int, end: int): this {
5915        value = this.zeroIfInfinity(value)
5916        this.fill(value as int, start as int, end as int)
5917        return this
5918    }
5919
5920    /**
5921     * Fills the Int32Array with specified value
5922     *
5923     * @param value new valuy
5924     *
5925     * @returns modified Int32Array
5926     */
5927    public fill(value: int, start?: number, end?: number): this {
5928        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
5929        return this
5930    }
5931
5932    /**
5933     * Fills the Int32Array with specified value
5934     *
5935     * @param value new valuy
5936     *
5937     * @returns modified Int32Array
5938     */
5939    public fill(value: int, start: int, end?: number): this {
5940        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
5941        return this
5942    }
5943
5944    /**
5945     * Fills the Int32Array with specified value
5946     *
5947     * @param value new valuy
5948     *
5949     * @returns modified Int32Array
5950     */
5951    public fill(value: int, start: int, end: number): this {
5952        this.fill(value, start as int, end as int)
5953        return this
5954    }
5955
5956    /**
5957     * Fills the Int32Array with specified value
5958     *
5959     * @param value new valuy
5960     *
5961     * @returns modified Int32Array
5962     */
5963    public fill(value: int, start: number, end: int): this {
5964        this.fill(value, start as int, end as int)
5965        return this
5966    }
5967
5968    /**
5969     * Fills the Int32Array with specified value
5970     *
5971     * @param value new valuy
5972     *
5973     * @returns modified Int32Array
5974     */
5975    public fill(value: int, start: int, end: int): this {
5976        const k = normalizeIndex(start, this.lengthInt)
5977        const finalPos = normalizeIndex(end, this.lengthInt)
5978        for (let i: int = k; i < finalPos; ++i) {
5979            this.setUnsafe(i, value)
5980        }
5981        return this
5982    }
5983
5984    /**
5985     * Assigns val as element on insertPos.
5986     * @description Added to avoid (un)packing a single value into array to use overloaded set(int[], insertPos)
5987     *
5988     * @param val value to set
5989     *
5990     * @param insertPos index to change
5991     */
5992    public set(insertPos: number, val: number): void {
5993        this.$_set(insertPos, val)
5994    }
5995
5996    /**
5997     * Assigns val as element on insertPos.
5998     * @description Added to avoid (un)packing a single value into array to use overloaded set(int[], insertPos)
5999     *
6000     * @param val value to set
6001     *
6002     * @param insertPos index to change
6003     */
6004    public set(insertPos: int, val: int): void {
6005        this.$_set(insertPos, val)
6006    }
6007
6008    /**
6009     * Copies all elements of arr to the current Int32Array starting from insertPos.
6010     *
6011     * @param arr array to copy data from
6012     *
6013     * @param insertPos start index where data from arr will be inserted
6014     *
6015     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
6016     */
6017    public set(arr: number[], insertPos: number): void {
6018        const offset = insertPos as int
6019        if (offset < 0 || offset + arr.length > this.lengthInt) {
6020            throw new RangeError("offset is out of bounds")
6021        }
6022        for (let i = 0; i < arr.length as int; ++i) {
6023            let v = this.zeroIfInfinity(arr[i])
6024            this.setUnsafe(offset + i, v as int)
6025        }
6026    }
6027
6028    /**
6029     * Copies all elements of arr to the current Int32Array starting from insertPos.
6030     *
6031     * @param arr array to copy data from
6032     *
6033     * @param insertPos start index where data from arr will be inserted
6034     *
6035     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
6036     */
6037    public set(arr: int[], insertPos: int): void {
6038        const offset = insertPos as int
6039        if (offset < 0 || offset + arr.length > this.lengthInt) {
6040            throw new RangeError("offset is out of bounds")
6041        }
6042        for (let i = 0; i < arr.length as int; ++i) {
6043            let v = this.zeroIfInfinity(arr[i])
6044            this.setUnsafe(offset + i, v)
6045        }
6046    }
6047
6048    /**
6049     * Copies all elements of arr to the current Int32Array.
6050     *
6051     * @param arr array to copy data from
6052     */
6053    public set(arr: number[]): void {
6054        this.set(arr, 0 as number)
6055    }
6056
6057    /**
6058     * Copies all elements of arr to the current Int32Array.
6059     *
6060     * @param arr array to copy data from
6061     */
6062    public set(arr: int[]): void {
6063        this.set(arr, 0 as int)
6064    }
6065
6066    /**
6067     * Copies elements from an ArrayLike object to the Int32Array.
6068     *
6069     * @param array An ArrayLike object containing the elements to copy.
6070     *
6071     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
6072     */
6073    public set(array: ArrayLike<number>, offset: number = 0): void {
6074        const insertPos = offset as int
6075        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
6076            throw new RangeError("offset is out of bounds")
6077        }
6078        for (let i = 0; i < array.length as int; ++i) {
6079            let v = this.zeroIfInfinity(array[i])
6080            this.setUnsafe(insertPos + i, v as int)
6081        }
6082    }
6083
6084    /**
6085     * Returns a new array from a set of elements.
6086     *
6087     * @param items a set of elements to include in the new array object.
6088     *
6089     * @returns new Int32Array
6090     */
6091    public static of(...items: number[]): Int32Array {
6092        let res = new Int32Array(items.length as int)
6093        for (let i: int = 0; i < items.length; i++) {
6094            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as int)
6095        }
6096        return res
6097    }
6098
6099    /**
6100     * Returns a new array from a set of elements.
6101     *
6102     * @param items a set of elements to include in the new array object.
6103     *
6104     * @returns new Int32Array
6105     */
6106    public static of(...items: int[]): Int32Array {
6107        let res = new Int32Array(items.length as int)
6108        for (let i: int = 0; i < items.length; i++) {
6109            res.setUnsafe(i, items[i])
6110        }
6111        return res
6112    }
6113
6114    /**
6115     * Returns a new array from a set of elements.
6116     *
6117     * @param items a set of elements to include in the new array object.
6118     *
6119     * @returns new Int32Array
6120     */
6121    public static of(): Int32Array {
6122        return new Int32Array(0 as int)
6123    }
6124
6125    /**
6126     * Creates an array from an array-like or iterable object.
6127     *
6128     * @param arrayLike An array-like or iterable object to convert to an array.
6129     *
6130     * @returns new Int32Array
6131     */
6132    public static from(arrayLike: ArrayLike<number>): Int32Array {
6133        return Int32Array.from<number>(arrayLike, (x: number, k: number): number => x)
6134    }
6135
6136    /**
6137     * Creates an array from an array-like or iterable object.
6138     *
6139     * @param arrayLike An array-like or iterable object to convert to an array.
6140     *
6141     * @param mapfn A mapping function to call on every element of the array.
6142     *
6143     * @returns new Int32Array
6144     */
6145    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int32Array {
6146        if (mapfn == undefined) {
6147            mapfn = (v: number, k: number): number => { return v }
6148        }
6149
6150        let iter = arrayLike.$_iterator()
6151        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
6152        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
6153        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
6154        //  we can make one pass through the iterator without the need for memory reallocation.
6155        const maybeLength = tryGetIteratorLength(arrayLike)
6156        if (maybeLength) {
6157            const result = new Int32Array(maybeLength)
6158            for (let i = 0; i < maybeLength; ++i) {
6159                const x = iter.next()
6160                if (x.done) {
6161                    return new Int32Array(result.buffer, 0, i)
6162                }
6163                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as int)
6164            }
6165            return result
6166        }
6167
6168        // NOTE (templin.konstantin): Create builtin array as buffer
6169        let temp = new Int32Array(6)
6170        let index = new int[1]
6171        index[0] = 0
6172
6173        iteratorForEach<number>(iter, (x: number): void => {
6174            if (index[0] + 1 > temp.lengthInt) {
6175                // NOTE (templin.konstantin): Progressive reallocation
6176                const curLength = (temp.buffer as Buffer).getByteLength()
6177                const tb = new ArrayBuffer(curLength * 2)
6178                for (let i = 0; i < curLength; ++i) {
6179                    tb.set(i, (temp.buffer as Buffer).at(i))
6180                }
6181                temp = new Int32Array(tb)
6182            }
6183            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as int)
6184            index[0]++
6185        })
6186        return new Int32Array(temp.buffer, 0, index[0])
6187    }
6188
6189
6190    /**
6191     * Creates an array from an array-like or iterable object.
6192     *
6193     * @param arrayLike An array-like or iterable object to convert to an array.
6194     *
6195     * @param mapfn A mapping function to call on every element of the array.
6196     *
6197     * @returns new Int32Array
6198     */
6199    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int32Array {
6200        let res = new Int32Array(arrayLike.length)
6201        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
6202        const idx = new int[1]
6203        idx[0] = 0
6204        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
6205            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as int)
6206            idx[0] += 1
6207        })
6208        return res
6209    }
6210
6211    /**
6212     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6213     *
6214     * @param searchElement The element to search for
6215     *
6216     * @param fromIndex The position in this array at which to begin searching for searchElement
6217     *
6218     * @returns true if searchElement is in Int32Array, false otherwise
6219     */
6220    public includes(searchElement: number, fromIndex?: number): boolean {
6221        if (isNaN(searchElement)) {
6222            return false
6223        }
6224        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
6225    }
6226
6227    /**
6228     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6229     *
6230     * @param searchElement The element to search for
6231     *
6232     * @param fromIndex The position in this array at which to begin searching for searchElement
6233     *
6234     * @returns true if e is in Int32Array, false otherwise
6235     */
6236    public includes(searchElement: int, fromIndex: int): boolean {
6237        return this.indexOf(searchElement as int, fromIndex) != -1
6238    }
6239
6240    /**
6241     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6242     *
6243     * @param searchElement The element to search for
6244     *
6245     * @param fromIndex The position in this array at which to begin searching for searchElement
6246     *
6247     * @returns true if searchElement is in Int32Array, false otherwise
6248     */
6249    public includes(searchElement: int): boolean {
6250        return this.includes(searchElement, 0)
6251    }
6252
6253    /**
6254     * Returns the index of the first occurrence of a value in Int32Array.
6255     *
6256     * @param searchElement The value to locate in the array.
6257     *
6258     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6259     *  search starts at index 0.
6260     *
6261     * @returns index of element if it presents, -1 otherwise
6262     */
6263    public indexOf(searchElement: number, fromIndex?: number): number {
6264        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
6265    }
6266
6267    /**
6268     * Returns the index of the first occurrence of a value in Int32Array.
6269     *
6270     * @param searchElement The value to locate in the array.
6271     *
6272     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6273     *  search starts at index 0.
6274     *
6275     * @returns index of element if it presents, -1 otherwise
6276     */
6277    public indexOf(searchElement: number, fromIndex: int): number {
6278        if (isNaN(searchElement)) {
6279            return -1
6280        }
6281        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
6282        for (let i = fromIndex; i < this.lengthInt; i++) {
6283            if (this.getUnsafe(i) as number == searchElement) {
6284                return i
6285            }
6286        }
6287        return -1
6288    }
6289
6290    /**
6291     * Returns the index of the first occurrence of a value in Int32Array.
6292     *
6293     * @param searchElement The value to locate in the array.
6294     *
6295     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6296     *  search starts at index 0.
6297     *
6298     * @returns index of element if it presents, -1 otherwise
6299     */
6300    public indexOf(searchElement: int, fromIndex: int): number {
6301        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
6302        for (let i = fromIndex; i < this.lengthInt; i++) {
6303            if (this.getUnsafe(i) == searchElement) {
6304                return i
6305            }
6306        }
6307        return -1
6308    }
6309
6310    /**
6311     * Returns the index of the first occurrence of a value in Int32Array.
6312     *
6313     * @param searchElement The value to locate in the array.
6314     *
6315     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6316     *  search starts at index 0.
6317     *
6318     * @returns index of element if it presents, -1 otherwise
6319     */
6320    public indexOf(searchElement: int): number {
6321        return this.indexOf(searchElement, 0)
6322    }
6323
6324    /**
6325     * Adds all the elements of an array separated by the specified separator string
6326     *
6327     * @param separator A string used to separate one element of an array from the next in the
6328     * resulting String. If omitted, the array elements are separated with a comma
6329     *
6330     * @returns joined representation
6331     */
6332    public join(separator?: String): string {
6333        if (separator == undefined) {
6334            return this.join(",")
6335        }
6336        let res: StringBuilder = new StringBuilder("")
6337        for (let i = 0; i < this.lengthInt - 1; ++i) {
6338            res.append(this.getUnsafe(i) as number)
6339            res.append(separator)
6340        }
6341        if (this.lengthInt > 0) {
6342            res.append(this.getUnsafe(this.lengthInt - 1) as number)
6343        }
6344        return res.toString()
6345    }
6346
6347    /**
6348     * Returns an list of keys in Int32Array
6349     *
6350     * @returns iterator over keys
6351     */
6352    public keys(): IterableIterator<number> {
6353        return new Int32ArrayIteratorKeys(this)
6354    }
6355
6356    /**
6357     * Returns the index of the last occurrence of a value in Int32Array.
6358     *
6359     * @param searchElement The value to locate in the array.
6360     *
6361     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6362     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6363     *
6364     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6365     */
6366    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
6367        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
6368    }
6369
6370    /**
6371     * Returns the index of the last occurrence of a value in Int32Array.
6372     *
6373     * @param searchElement The value to locate in the array.
6374     *
6375     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6376     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6377     *
6378     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6379     */
6380    public lastIndexOf(searchElement: number): number {
6381        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6382    }
6383
6384    /**
6385     * Returns the index of the last occurrence of a value in Int32Array.
6386     *
6387     * @param searchElement The value to locate in the array.
6388     *
6389     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6390     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6391     *
6392     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6393     */
6394    public lastIndexOf(searchElement: number, fromIndex: int): number {
6395        if (isNaN(searchElement)) {
6396            return -1
6397        }
6398        if (this.lengthInt == 0) {
6399            return -1
6400        }
6401        let k: int = this.lengthInt + fromIndex
6402        if (fromIndex >= 0) {
6403            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
6404        }
6405        while (k >= 0) {
6406            if (this.getUnsafe(k) as number == searchElement) {
6407                return k
6408            }
6409            k--
6410        }
6411        return -1
6412    }
6413
6414    /**
6415     * Returns the index of the last occurrence of a value in Int32Array.
6416     *
6417     * @param searchElement The value to locate in the array.
6418     *
6419     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6420     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6421     *
6422     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6423     */
6424    public lastIndexOf(searchElement: int, fromIndex: int): number {
6425        if (this.lengthInt == 0) {
6426            return -1
6427        }
6428        let k: int = this.lengthInt + fromIndex
6429        if (fromIndex >= 0) {
6430            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
6431        }
6432        while (k >= 0) {
6433            if (this.getUnsafe(k) == searchElement) {
6434                return k
6435            }
6436            k--
6437        }
6438        return -1
6439    }
6440
6441    /**
6442     * Returns the index of the last occurrence of a value in Int32Array.
6443     *
6444     * @param searchElement The value to locate in the array.
6445     *
6446     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6447     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6448     *
6449     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6450     */
6451    public lastIndexOf(searchElement: int): number {
6452        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6453    }
6454
6455    /**
6456    * Creates a new Int32Array using initializer
6457    *
6458    * @param data initializer
6459    *
6460    * @returns a new Int32Array from data
6461    */
6462    public of(data: Object[]): Int32Array {
6463        throw new Error("Int32Array.of: not implemented")
6464    }
6465
6466    /**
6467     * Creates a new Int32Array using reversed data from the current one
6468     *
6469     * @returns a new Int32Array using reversed data from the current one
6470     */
6471    public reverse(): Int32Array {
6472        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
6473            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
6474            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
6475            this.setUnsafe(i, tmp)
6476        }
6477        return this
6478    }
6479
6480    /**
6481     * Creates a slice of current Int32Array using range [begin, end)
6482     *
6483     * @param begin start index to be taken into slice
6484     *
6485     * @param end last index to be taken into slice
6486     *
6487     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6488     *
6489     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6490     */
6491    public slice(begin?: number, end?: number): Int32Array {
6492        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6493    }
6494
6495    /**
6496     * Creates a slice of current Int32Array using range [begin, end)
6497     *
6498     * @param begin start index to be taken into slice
6499     *
6500     * @param end last index to be taken into slice
6501     *
6502     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6503     *
6504     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6505     */
6506    public slice(begin: number, end: number): Int32Array {
6507        return this.slice(begin as int, end as int)
6508    }
6509
6510    /**
6511     * Creates a slice of current Int32Array using range [begin, end)
6512     *
6513     * @param begin start index to be taken into slice
6514     *
6515     * @param end last index to be taken into slice
6516     *
6517     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6518     *
6519     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6520     */
6521    public slice(begin: number, end: int): Int32Array {
6522        return this.slice(begin as int, end as int)
6523    }
6524
6525    /**
6526     * Creates a slice of current Int32Array using range [begin, end)
6527     *
6528     * @param begin start index to be taken into slice
6529     *
6530     * @param end last index to be taken into slice
6531     *
6532     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6533     *
6534     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6535     */
6536    public slice(begin: int, end: number): Int32Array {
6537        return this.slice(begin as int, end as int)
6538    }
6539
6540    /**
6541     * Creates a slice of current Int32Array using range [begin, end)
6542     *
6543     * @param begin start index to be taken into slice
6544     *
6545     * @param end last index to be taken into slice
6546     *
6547     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6548     *
6549     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6550     */
6551    public slice(begin: int, end: int): Int32Array {
6552        const len: int = this.lengthInt
6553        const relStart = normalizeIndex(begin, len)
6554        const relEnd = normalizeIndex(end, len)
6555        let count = relEnd - relStart
6556        if (count < 0) {
6557            count = 0
6558        }
6559        if (this.buffer instanceof ArrayBuffer) {
6560            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int32Array.BYTES_PER_ELEMENT as int, relEnd * Int32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
6561            return new Int32Array(buf)
6562        } else if (this.buffer instanceof SharedArrayBuffer) {
6563            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int32Array.BYTES_PER_ELEMENT as int, relEnd * Int32Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
6564            return new Int32Array(buf)
6565        } else {
6566            throw new Error("unexpected type of buffer")
6567        }
6568    }
6569
6570    /**
6571     * Creates a slice of current Int32Array using range [begin, this.length).
6572     *
6573     * @param begin start index to be taken into slice
6574     *
6575     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
6576     */
6577    public slice(begin: number): Int32Array {
6578        return this.slice(begin as int)
6579    }
6580
6581    /**
6582     * Creates a slice of current Int32Array using range [begin, this.length).
6583     *
6584     * @param begin start index to be taken into slice
6585     *
6586     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
6587     */
6588    public slice(begin: int): Int32Array {
6589        return this.slice(begin, this.lengthInt)
6590    }
6591
6592    /**
6593     * Creates a Int32Array with the same underlying ArrayBufferLike
6594     *
6595     * @param begin start index, inclusive
6596     *
6597     * @param end last index, exclusive
6598     *
6599     * @returns new Int32Array with the same underlying ArrayBufferLike
6600     */
6601    public subarray(begin?: number, end?: number): Int32Array {
6602        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6603    }
6604
6605    /**
6606     * Creates a Int32Array with the same underlying ArrayBufferLike
6607     *
6608     * @param begin start index, inclusive
6609     *
6610     * @param end last index, exclusive
6611     *
6612     * @returns new Int32Array with the same underlying ArrayBufferLike
6613     */
6614    public subarray(begin: number, end: number): Int32Array {
6615        return this.subarray(begin as int, end as int)
6616    }
6617
6618    /**
6619     * Creates a Int32Array with the same underlying ArrayBufferLike
6620     *
6621     * @param begin start index, inclusive
6622     *
6623     * @param end last index, exclusive
6624     *
6625     * @returns new Int32Array with the same underlying ArrayBufferLike
6626     */
6627    public subarray(begin: number, end: int): Int32Array {
6628        return this.subarray(begin as int, end as int)
6629    }
6630
6631    /**
6632     * Creates a Int32Array with the same underlying ArrayBufferLike
6633     *
6634     * @param begin start index, inclusive
6635     *
6636     * @param end last index, exclusive
6637     *
6638     * @returns new Int32Array with the same underlying ArrayBufferLike
6639     */
6640    public subarray(begin: int, end: number): Int32Array {
6641        return this.subarray(begin as int, end as int)
6642    }
6643
6644    /**
6645     * Creates a Int32Array with the same underlying ArrayBufferLike
6646     *
6647     * @param begin start index, inclusive
6648     *
6649     * @param end last index, exclusive
6650     *
6651     * @returns new Int32Array with the same underlying ArrayBufferLike
6652     */
6653    public subarray(begin: int, end: int): Int32Array {
6654        const len: int = this.lengthInt
6655        const relStart = normalizeIndex(begin, len)
6656        const relEnd = normalizeIndex(end, len)
6657        let count = relEnd - relStart
6658        if (count < 0) {
6659            count = 0
6660        }
6661        return new Int32Array(this.buffer, relStart * Int32Array.BYTES_PER_ELEMENT as int, count)
6662    }
6663
6664    /**
6665     * Creates a Int32Array with the same ArrayBufferLike
6666     *
6667     * @param begin start index, inclusive
6668     *
6669     * @returns new Int32Array with the same ArrayBufferLike
6670     */
6671    public subarray(begin: number): Int32Array {
6672        return this.subarray(begin as int, this.lengthInt)
6673    }
6674
6675    /**
6676     * Creates a Int32Array with the same ArrayBufferLike
6677     *
6678     * @param begin start index, inclusive
6679     *
6680     * @returns new Int32Array with the same ArrayBufferLike
6681     */
6682    public subarray(begin: int): Int32Array {
6683        return this.subarray(begin as int, this.lengthInt)
6684    }
6685
6686    /**
6687     * Converts Int32Array to a string with respect to locale
6688     *
6689     * @param locales
6690     *
6691     * @param options
6692     *
6693     * @returns string representation
6694     */
6695    public toLocaleString(locales: Object, options: Object): string {
6696        throw new Error("Int32Array.toLocaleString: not implemented")
6697    }
6698
6699    /**
6700     * Converts Int32Array to a string with respect to locale
6701     *
6702     * @param locales
6703     *
6704     * @returns string representation
6705     */
6706    public toLocaleString(locales: Object): string {
6707        return this.toLocaleString(new Object(), new Object())
6708    }
6709
6710    /**
6711     * Converts Int32Array to a string with respect to locale
6712     *
6713     * @returns string representation
6714     */
6715    public toLocaleString(): string {
6716        let res: StringBuilder = new StringBuilder("")
6717        for (let i = 0; i < this.lengthInt - 1; ++i) {
6718            res.append((this.getUnsafe(i) as Number).toLocaleString())
6719            res.append(",")
6720        }
6721        if (this.lengthInt > 0) {
6722            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
6723        }
6724        return res.toString()
6725    }
6726
6727    /**
6728     * Creates a reversed copy
6729     *
6730     * @returns a reversed copy
6731     */
6732    public toReversed(): Int32Array {
6733        return new Int32Array(this).reverse()
6734    }
6735
6736    /**
6737     * Creates a sorted copy
6738     *
6739     * @returns a sorted copy
6740     */
6741    public toSorted(): Int32Array {
6742        return new Int32Array(this).sort()
6743    }
6744
6745    /**
6746     * Returns a string representation of the Int32Array
6747     *
6748     * @returns a string representation of the Int32Array
6749     */
6750    public override toString(): string {
6751        return this.join(",")
6752    }
6753
6754    /**
6755     * Returns array values iterator
6756     *
6757     * @returns an iterator
6758     */
6759    public values(): IterableIterator<Number> {
6760        return new Int32ArrayIterator(this)
6761    }
6762
6763    /**
6764     * Iteratorable interface implementation
6765     *
6766     * @returns iterator over all elements
6767     */
6768    public override $_iterator(): IterableIterator<Number> {
6769        return this.values()
6770    }
6771
6772    /**
6773     * Creates a copy with replaced value on index
6774     *
6775     * @param index
6776     *
6777     * @param value
6778     *
6779     * @returns an Int32Array with replaced value on index
6780     */
6781    public with(index: number, value: number): Int32Array {
6782        return this.with(index as int, value as int)
6783    }
6784
6785    /**
6786     * Creates a copy with replaced value on index
6787     *
6788     * @param index
6789     *
6790     * @param value
6791     *
6792     * @returns an Int32Array with replaced value on index
6793     */
6794    public with(index: int, value: int): Int32Array {
6795        let res = new Int32Array(this)
6796        res.set(index, value)
6797        return res
6798    }
6799
6800    /// === with element lambda functions ===
6801    /**
6802     * Determines whether the specified callback function returns true for all elements of an array.
6803     *
6804     * @param predicate A function that accepts one argument.
6805     * The every method calls the predicate function for each element in the array until the predicate returns a false,
6806     * or until the end of the array.
6807     *
6808     * @returns true unless predicate function returns a false for an array element,
6809     * in which case false is immediately returned.
6810     */
6811    public every(predicate: (element: number) => boolean): boolean {
6812        return this.every((element: number, index: number, array: Int32Array): boolean => predicate(element))
6813    }
6814
6815    /**
6816     * creates a new Int32Array from current Int32Array based on a condition fn
6817     *
6818     * @param fn the condition to apply for each element
6819     *
6820     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
6821     */
6822    public filter(fn: (val: number) => boolean): Int32Array {
6823        let newF: (val: number, index: number, array: Int32Array) => boolean =
6824            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6825        return this.filter(newF)
6826    }
6827
6828    /**
6829     * Returns the value of the first element in the array where predicate is true, and undefined
6830     * otherwise
6831     *
6832     * @param predicate find calls predicate once for each element of the array, in ascending
6833     * order, until it finds one where predicate returns true. If such an element is found, find
6834     * immediately returns that element value. Otherwise, find returns undefined
6835     *
6836     * @returns number | undefined
6837     */
6838    public find(predicate: () => boolean): number | undefined {
6839        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate())
6840    }
6841
6842    /**
6843     * Returns the value of the first element in the array where predicate is true, and undefined
6844     * otherwise
6845     *
6846     * @param predicate find calls predicate once for each element of the array, in ascending
6847     * order, until it finds one where predicate returns true. If such an element is found, find
6848     * immediately returns that element value. Otherwise, find returns undefined
6849     *
6850     * @returns number | undefined
6851     */
6852    public find(predicate: (value: number) => boolean): number | undefined {
6853        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate(value))
6854    }
6855
6856    /**
6857     * Returns the index of the first element in the array where predicate is true, and -1
6858     * otherwise
6859     *
6860     * @param predicate find calls predicate once for each element of the array, in ascending
6861     * order, until it finds one where predicate returns true. If such an element is found,
6862     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
6863     *
6864     * @returns number
6865     */
6866    public findIndex(predicate: (value: number) => boolean): number {
6867        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate(value)) as number
6868    }
6869
6870    /**
6871     * Finds the last element in the Int32Array that satisfies the condition
6872     *
6873     * @param fn condition
6874     *
6875     * @returns the last element that satisfies fn
6876     */
6877    public findLast(fn: (val: number) => boolean): number {
6878        let newF: (val: number, index: number, array: Int32Array) => boolean =
6879            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6880        return this.findLast(newF) as number
6881    }
6882
6883    /**
6884     * Finds an index of the last element in the Int32Array that satisfies the condition
6885     *
6886     * @param fn condition
6887     *
6888     * @returns the index of the last element that satisfies fn, -1 otherwise
6889     */
6890    public findLastIndex(fn: (val: number) => boolean): number {
6891        let newF: (val: number, index: number, array: Int32Array) => boolean =
6892            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6893        return this.findLastIndex(newF) as number
6894    }
6895
6896    /**
6897     * Performs the specified action for each element in Int32Array
6898     *
6899     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
6900     * callbackfn function one time for each element in the array.
6901     *
6902     * @returns None
6903     */
6904    public forEach(callbackfn: (value: number) => void): void {
6905        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn(value))
6906    }
6907
6908    /**
6909     * Determines whether the specified callback function returns true for any element of an array.
6910     *
6911     * @param predicate A function that accepts one argument.
6912     * The some method calls the predicate function for each element in the array
6913     * until the predicate returns a true or until the end of the array.
6914     *
6915     * @returns false unless predicate function returns true for an array element,
6916     * in which case true is immediately returned.
6917     */
6918    public some(predicate: (element: number) => boolean): boolean {
6919        return this.some((element: number, index: number, array: Int32Array): boolean => predicate(element))
6920    }
6921
6922    // NOTE (kprokopenko): this may be not skipped
6923    /**
6924     * Sorts in-place
6925     *
6926     * @param compareFn comparator —  used to determine the order of the elements.
6927     * compareFn returns a negative value if first argument is less than second argument,
6928     * zero if they're equal and a positive value otherwise.
6929     * If omitted, the elements are sorted in ascending order.
6930     *
6931     * @returns sorted Int32Array
6932     */
6933    public sort(compareFn?: (a: number, b: number) => number): this {
6934        let arr: int[] = new int[this.lengthInt]
6935        for (let i = 0; i < this.lengthInt; ++i) {
6936            arr[i] = this.getUnsafe(i)
6937        }
6938        let cmp = (l: int, r: int): number => {
6939                return (l - r) as number
6940            }
6941        if (compareFn != undefined) {
6942            cmp = (l: int, r: int): number => {
6943                return compareFn!(l as number, r as number)
6944            }
6945        }
6946        sort(arr, cmp)
6947        for (let i = 0; i < this.lengthInt; ++i) {
6948            this.setUnsafe(i, arr[i])
6949        }
6950        return this
6951    }
6952
6953    /**
6954     * Sorts in-place
6955     *
6956     * @param compareFn comparator —  used to determine the order of the elements.
6957     * compareFn returns a negative value if first argument is less than second argument,
6958     * zero if they're equal and a positive value otherwise.
6959     *
6960     * @returns sorted Int32Array
6961     */
6962    public sort(compareFn: (a: number) => number): this {
6963        let cmp = (a: number, b: number) => { return compareFn(a)}
6964        this.sort(cmp)
6965        return this
6966    }
6967
6968    /**
6969     * Sorts in-place
6970     *
6971     * @param fn compareFn —  used to determine the order of the elements.
6972     * compareFn returns a negative value if first argument is less than second argument,
6973     * zero if they're equal and a positive value otherwise.
6974     *
6975     * @returns sorted Int32Array
6976     */
6977    public sort(compareFn: () => number): this {
6978        let cmp = (a: number, b: number) => { return compareFn()}
6979        this.sort(cmp)
6980        return this
6981    }
6982
6983    /**
6984     * Determines whether the specified callback function returns true for any element of an array.
6985     *
6986     * @param predicate A function that accepts three arguments.
6987     * The some method calls the predicate function for each element in the array
6988     * until the predicate returns a true or until the end of the array.
6989     *
6990     * @returns false unless predicate function returns true for an array element,
6991     * in which case true is immediately returned.
6992     */
6993    public some(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
6994        for (let i = 0; i < this.lengthInt; ++i) {
6995            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
6996                return true
6997            }
6998        }
6999        return false
7000    }
7001
7002    /**
7003     * Determines whether the specified callback function returns true for any element of an array.
7004     *
7005     * @param predicate A function that accepts two arguments.
7006     * The some method calls the predicate function for each element in the array
7007     * until the predicate returns a true or until the end of the array.
7008     *
7009     * @returns false unless predicate function returns true for an array element,
7010     * in which case true is immediately returned.
7011     */
7012    public some(predicate: (element: number, index: number) => boolean): boolean {
7013        return this.some((element: number, index: number, array: Int32Array): boolean => predicate(element, index as number))
7014    }
7015
7016    /**
7017     * Determines whether the specified callback function returns true for any element of an array.
7018     *
7019     * @param predicate A function that accepts no arguments.
7020     * The some method calls the predicate function for each element in the array
7021     * until the predicate returns a true or until the end of the array.
7022     *
7023     * @returns false unless predicate function returns true for an array element,
7024     * in which case true is immediately returned.
7025     */
7026    public some(predicate: () => boolean): boolean {
7027        return this.some((element: number, index: number, array: Int32Array): boolean => predicate())
7028    }
7029
7030    /**
7031     * Calls the specified callback function for all the elements in an array.
7032     * The return value of the callback function is the accumulated result,
7033     * and is provided as an argument in the next call to the callback function.
7034     *
7035     * @param callbackfn A function that accepts four arguments.
7036     * The reduce method calls the callbackfn function one time for each element in the array.
7037     *
7038     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7039     * The first call to the callbackfn function provides this value as an argument.
7040     *
7041     * @returns The value that results from running the callback function to completion over the entire typed array.
7042     */
7043    public reduce<U = number>(
7044                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
7045                initialValue: U): U {
7046        let accumulatedValue = initialValue
7047        for (let i = 0; i < this.lengthInt; ++i) {
7048            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7049        }
7050        return accumulatedValue
7051    }
7052
7053    /**
7054     * Calls the specified callback function for all the elements in an array.
7055     * The return value of the callback function is the accumulated result,
7056     * and is provided as an argument in the next call to the callback function.
7057     *
7058     * @param callbackfn A function that accepts three arguments.
7059     * The reduce method calls the callbackfn function one time for each element in the array.
7060     *
7061     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7062     * The first call to the callbackfn function provides this value as an argument.
7063     *
7064     * @returns The value that results from running the callback function to completion over the entire typed array.
7065     */
7066    public reduce<U = number>(
7067                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
7068                initialValue: U): U {
7069        return this.reduce(
7070                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7071                        callbackfn(prevVal, currVal, currIndex), initialValue)
7072    }
7073
7074    /**
7075     * Calls the specified callback function for all the elements in an array.
7076     * The return value of the callback function is the accumulated result,
7077     * and is provided as an argument in the next call to the callback function.
7078     *
7079     * @param callbackfn A function that accepts two arguments.
7080     * The reduce method calls the callbackfn function one time for each element in the array.
7081     *
7082     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7083     * The first call to the callbackfn function provides this value as an argument.
7084     *
7085     * @returns The value that results from running the callback function to completion over the entire typed array.
7086     */
7087    public reduce<U = number>(
7088                callbackfn: (previousValue: U, currentValue: number) => U,
7089                initialValue: U): U {
7090        return this.reduce(
7091                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7092                        callbackfn(prevVal, currVal), initialValue)
7093    }
7094
7095    /**
7096     * Calls the specified callback function for all the elements in an array.
7097     * The return value of the callback function is the accumulated result,
7098     * and is provided as an argument in the next call to the callback function.
7099     *
7100     * @param callbackfn A function that accepts one argument
7101     * The reduce method calls the callbackfn function one time for each element in the array.
7102     *
7103     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7104     * The first call to the callbackfn function provides this value as an argument.
7105     *
7106     * @returns The value that results from running the callback function to completion over the entire typed array.
7107     */
7108    public reduce<U = number>(
7109                callbackfn: (previousValue: U) => U,
7110                initialValue: U): U {
7111        return this.reduce(
7112                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7113                        callbackfn(prevVal), initialValue)
7114    }
7115
7116    /**
7117     * Calls the specified callback function for all the elements in an array.
7118     * The return value of the callback function is the accumulated result,
7119     * and is provided as an argument in the next call to the callback function.
7120     *
7121     * @param callbackfn A function that accepts no arguments
7122     * The reduce method calls the callbackfn function one time for each element in the array.
7123     *
7124     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7125     * The first call to the callbackfn function provides this value as an argument.
7126     *
7127     * @returns The value that results from running the callback function to completion over the entire typed array.
7128     */
7129    public reduce<U = number>(
7130                callbackfn: () => U,
7131                initialValue: U): U {
7132        return this.reduce(
7133                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7134                        callbackfn(), initialValue)
7135    }
7136
7137    /**
7138     * Calls the specified callback function for all the elements in an array.
7139     * The return value of the callback function is the accumulated result,
7140     * and is provided as an argument in the next call to the callback function.
7141     *
7142     * @param callbackfn A function that accepts four arguments.
7143     * The reduce method calls the callbackfn function one time for each element in the array.
7144     * The first call to the callbackfn function provides array first element value as an argument
7145     *
7146     * @returns The value that results from running the callback function to completion over the entire typed array.
7147     * calling reduce method on an empty array without an initial value creates a TypeError
7148     */
7149    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
7150        if (this.lengthInt == 0) {
7151            throw new TypeError("Reduce of empty array with no initial value")
7152        }
7153
7154        let accumulatedValue = this.getUnsafe(0) as number
7155        for (let i = 1; i < this.lengthInt; ++i) {
7156            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7157        }
7158        return accumulatedValue
7159    }
7160
7161    /**
7162     * Calls the specified callback function for all the elements in an array.
7163     * The return value of the callback function is the accumulated result,
7164     * and is provided as an argument in the next call to the callback function.
7165     *
7166     * @param callbackfn A function that accepts three arguments.
7167     * The reduce method calls the callbackfn function one time for each element in the array.
7168     * The first call to the callbackfn function provides array first element value as an argument
7169     *
7170     * @returns The value that results from running the callback function to completion over the entire typed array.
7171     * calling reduce method on an empty array without an initial value creates a TypeError
7172     */
7173    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
7174        return this.reduce(
7175                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7176                        callbackfn(prevVal, currVal, currIndex))
7177    }
7178
7179    /**
7180     * Calls the specified callback function for all the elements in an array.
7181     * The return value of the callback function is the accumulated result,
7182     * and is provided as an argument in the next call to the callback function.
7183     *
7184     * @param callbackfn A function that accepts two arguments.
7185     * The reduce method calls the callbackfn function one time for each element in the array.
7186     * The first call to the callbackfn function provides array first element value as an argument
7187     *
7188     * @returns The value that results from running the callback function to completion over the entire typed array.
7189     * calling reduce method on an empty array without an initial value creates a TypeError
7190     */
7191    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
7192        return this.reduce(
7193                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7194                        callbackfn(prevVal, currVal))
7195    }
7196
7197    /**
7198     * Calls the specified callback function for all the elements in an array.
7199     * The return value of the callback function is the accumulated result,
7200     * and is provided as an argument in the next call to the callback function.
7201     *
7202     * @param callbackfn A function that accepts one argument.
7203     * The reduce method calls the callbackfn function one time for each element in the array.
7204     * The first call to the callbackfn function provides array first element value as an argument
7205     *
7206     * @returns The value that results from running the callback function to completion over the entire typed array.
7207     * calling reduce method on an empty array without an initial value creates a TypeError
7208     */
7209    public reduce(callbackfn: (previousValue: number) => number): number {
7210        return this.reduce(
7211                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7212                        callbackfn(prevVal))
7213    }
7214
7215    /**
7216     * Calls the specified callback function for all the elements in an array.
7217     * The return value of the callback function is the accumulated result,
7218     * and is provided as an argument in the next call to the callback function.
7219     *
7220     * @param callbackfn A function that accepts no arguments.
7221     * The reduce method calls the callbackfn function one time for each element in the array.
7222     * The first call to the callbackfn function provides array first element value as an argument
7223     *
7224     * @returns The value that results from running the callback function to completion over the entire typed array.
7225     * calling reduce method on an empty array without an initial value creates a TypeError
7226     */
7227    public reduce(callbackfn: () => number): number {
7228        return this.reduce(
7229                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7230                        callbackfn())
7231    }
7232
7233
7234    /**
7235     * Calls the specified callback function for all the elements in an array, in descending order.
7236     * The return value of the callback function is the accumulated result,
7237     * and is provided as an argument in the next call to the callback function.
7238     *
7239     * @param callbackfn A function that accepts four arguments.
7240     * The reduceRight method calls the callbackfn function one time for each element in the array.
7241     *
7242     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7243     * The first call to the callbackfn function provides this value as an argument.
7244     *
7245     * @returns The value that results from running the callback function to completion over the entire typed array.
7246     */
7247    public reduceRight<U = number>(
7248                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
7249                initialValue: U): U {
7250        let accumulatedValue = initialValue
7251        for (let i = this.lengthInt - 1; i >= 0; --i) {
7252            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7253        }
7254        return accumulatedValue
7255    }
7256
7257    /**
7258     * Calls the specified callback function for all the elements in an array, in descending order.
7259     * The return value of the callback function is the accumulated result,
7260     * and is provided as an argument in the next call to the callback function.
7261     *
7262     * @param callbackfn A function that accepts three arguments.
7263     * The reduceRight method calls the callbackfn function one time for each element in the array.
7264     *
7265     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7266     * The first call to the callbackfn function provides this value as an argument.
7267     *
7268     * @returns The value that results from running the callback function to completion over the entire typed array.
7269     */
7270    public reduceRight<U = number>(
7271                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
7272                initialValue: U): U {
7273        return this.reduceRight(
7274                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7275                        callbackfn(prevVal, currVal, currIndex), initialValue)
7276    }
7277
7278    /**
7279     * Calls the specified callback function for all the elements in an array, in descending order.
7280     * The return value of the callback function is the accumulated result,
7281     * and is provided as an argument in the next call to the callback function.
7282     *
7283     * @param callbackfn A function that accepts two arguments.
7284     * The reduceRight method calls the callbackfn function one time for each element in the array.
7285     *
7286     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7287     * The first call to the callbackfn function provides this value as an argument.
7288     *
7289     * @returns The value that results from running the callback function to completion over the entire typed array.
7290     */
7291    public reduceRight<U = number>(
7292                callbackfn: (previousValue: U, currentValue: number) => U,
7293                initialValue: U): U {
7294        return this.reduceRight(
7295                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7296                        callbackfn(prevVal, currVal), initialValue)
7297    }
7298
7299    /**
7300     * Calls the specified callback function for all the elements in an array, in descending order.
7301     * The return value of the callback function is the accumulated result,
7302     * and is provided as an argument in the next call to the callback function.
7303     *
7304     * @param callbackfn A function that accepts one argument.
7305     * The reduceRight method calls the callbackfn function one time for each element in the array.
7306     *
7307     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7308     * The first call to the callbackfn function provides this value as an argument.
7309     *
7310     * @returns The value that results from running the callback function to completion over the entire typed array.
7311     */
7312    public reduceRight<U = number>(
7313                callbackfn: (previousValue: U) => U,
7314                initialValue: U): U {
7315        return this.reduceRight(
7316                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7317                        callbackfn(prevVal), initialValue)
7318    }
7319
7320    /**
7321     * Calls the specified callback function for all the elements in an array, in descending order.
7322     * The return value of the callback function is the accumulated result,
7323     * and is provided as an argument in the next call to the callback function.
7324     *
7325     * @param callbackfn A function that accepts no arguments.
7326     * The reduceRight method calls the callbackfn function one time for each element in the array.
7327     *
7328     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7329     * The first call to the callbackfn function provides this value as an argument.
7330     *
7331     * @returns The value that results from running the callback function to completion over the entire typed array.
7332     */
7333    public reduceRight<U = number>(
7334                callbackfn: () => U,
7335                initialValue: U): U {
7336        return this.reduceRight(
7337                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7338                        callbackfn(), initialValue)
7339    }
7340
7341    /**
7342     * Calls the specified callback function for all the elements in an array, in descending order.
7343     * The return value of the callback function is the accumulated result,
7344     * and is provided as an argument in the next call to the callback function.
7345     *
7346     * @param callbackfn A function that accepts four arguments.
7347     * The reduceRight method calls the callbackfn function one time for each element in the array.
7348     * The first call to the callbackfn function provides array last element value as an argument
7349     *
7350     * @returns The value that results from running the callback function to completion over the entire typed array.
7351     * calling reduceRight method on an empty array without an initial value creates a TypeError
7352     */
7353    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
7354        if (this.lengthInt == 0) {
7355            throw new TypeError("Reduce of empty array with no initial value")
7356        }
7357
7358        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
7359        for (let i = this.lengthInt - 2; i >= 0; --i) {
7360            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7361        }
7362        return accumulatedValue
7363    }
7364
7365    /**
7366     * Calls the specified callback function for all the elements in an array, in descending order.
7367     * The return value of the callback function is the accumulated result,
7368     * and is provided as an argument in the next call to the callback function.
7369     *
7370     * @param callbackfn A function that accepts three arguments.
7371     * The reduceRight method calls the callbackfn function one time for each element in the array.
7372     * The first call to the callbackfn function provides array last element value as an argument
7373     *
7374     * @returns The value that results from running the callback function to completion over the entire typed array.
7375     * calling reduceRight method on an empty array without an initial value creates a TypeError
7376     */
7377    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
7378        return this.reduceRight(
7379                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7380                        callbackfn(prevValue, currValue, currIndex))
7381    }
7382
7383    /**
7384     * Calls the specified callback function for all the elements in an array, in descending order.
7385     * The return value of the callback function is the accumulated result,
7386     * and is provided as an argument in the next call to the callback function.
7387     *
7388     * @param callbackfn A function that accepts two arguments.
7389     * The reduceRight method calls the callbackfn function one time for each element in the array.
7390     * The first call to the callbackfn function provides array last element value as an argument
7391     *
7392     * @returns The value that results from running the callback function to completion over the entire typed array.
7393     * calling reduceRight method on an empty array without an initial value creates a TypeError
7394     */
7395    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
7396        return this.reduceRight(
7397                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7398                        callbackfn(prevValue, currValue))
7399    }
7400
7401    /**
7402     * Calls the specified callback function for all the elements in an array, in descending order.
7403     * The return value of the callback function is the accumulated result,
7404     * and is provided as an argument in the next call to the callback function.
7405     *
7406     * @param callbackfn A function that accepts one argument.
7407     * The reduceRight method calls the callbackfn function one time for each element in the array.
7408     * The first call to the callbackfn function provides array last element value as an argument
7409     *
7410     * @returns The value that results from running the callback function to completion over the entire typed array.
7411     * calling reduceRight method on an empty array without an initial value creates a TypeError
7412     */
7413    public reduceRight(callbackfn: (previousValue: number) => number): number {
7414        return this.reduceRight(
7415                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7416                        callbackfn(prevValue))
7417    }
7418
7419    /**
7420     * Calls the specified callback function for all the elements in an array, in descending order.
7421     * The return value of the callback function is the accumulated result,
7422     * and is provided as an argument in the next call to the callback function.
7423     *
7424     * @param callbackfn A function that accepts no arguments.
7425     * The reduceRight method calls the callbackfn function one time for each element in the array.
7426     * The first call to the callbackfn function provides array last element value as an argument
7427     *
7428     * @returns The value that results from running the callback function to completion over the entire typed array.
7429     * calling reduceRight method on an empty array without an initial value creates a TypeError
7430     */
7431    public reduceRight(callbackfn: () => number): number {
7432        return this.reduceRight(
7433                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7434                        callbackfn())
7435    }
7436
7437   /**
7438    * Creates a new Int32Array using fn(arr[i]) over all elements of current Int32Array.
7439    *
7440    * @param fn a function to apply for each element of current Int32Array
7441    *
7442    * @returns a new Int32Array where for each element from current Int32Array fn was applied
7443    */
7444    public map(fn: (val: number, index: number, array: Int32Array) => number): Int32Array {
7445        let resBuf = new ArrayBuffer(this.lengthInt * Int32Array.BYTES_PER_ELEMENT as int)
7446        let res = new Int32Array(resBuf, 0, resBuf.getByteLength() / Int32Array.BYTES_PER_ELEMENT as int)
7447        for (let i = 0; i < this.lengthInt; ++i) {
7448            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as int)
7449        }
7450        return res
7451    }
7452
7453    /**
7454     * Creates a new Int32Array using fn(arr[i], i) over all elements of current Int32Array
7455     *
7456     * @param fn a function to apply for each element of current Int32Array
7457     *
7458     * @returns a new Int32Array where for each element from current Int32Array fn was applied
7459     */
7460    public map(fn: (val: number, index: number) => number): Int32Array {
7461        let newF: (val: number, index: number, array: Int32Array) => number =
7462            (val: number, index: number, array: Int32Array): number => { return fn(val, index) }
7463        return this.map(newF)
7464    }
7465
7466    /**
7467     * Creates a new Int32Array using fn(arr[i]) over all elements of current Int32Array
7468     *
7469     * @param fn a function to apply for each element of current Int32Array
7470     *
7471     * @returns a new Int32Array where for each element from current Int32Array fn was applied
7472     */
7473    public map(fn: (val: number) => number): Int32Array {
7474        let newF: (val: number, index: number, array: Int32Array) => number =
7475            (val: number, index: number, array: Int32Array): number => { return fn(val) }
7476        return this.map(newF)
7477    }
7478
7479    /**
7480     * Creates a new Int32Array using fn() over all elements of current Int32Array
7481     *
7482     * @param fn a function to apply for each element of current Int32Array
7483     *
7484     * @returns a new Int32Array where for each element from current Int32Array fn was applied
7485     */
7486    public map(fn: () => number): Int32Array {
7487        let newF: (val: number, index: number, array: Int32Array) => number =
7488            (val: number, index: number, array: Int32Array): number => { return fn() }
7489        return this.map(newF)
7490    }
7491
7492
7493    /**
7494     * Determines whether the specified callback function returns true for all elements of an array.
7495     *
7496     * @param predicate A function that accepts three arguments.
7497     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7498     * or until the end of the array.
7499     *
7500     * @returns true unless predicate function returns a false for an array element,
7501     * in which case false is immediately returned.
7502     */
7503    public every(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
7504        for (let i = 0; i < this.lengthInt; ++i) {
7505            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
7506                return false
7507            }
7508        }
7509        return true
7510    }
7511
7512    /**
7513     * Determines whether the specified callback function returns true for all elements of an array.
7514     *
7515     * @param predicate A function that accepts two arguments.
7516     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7517     * or until the end of the array.
7518     *
7519     * @returns true unless predicate function returns a false for an array element,
7520     * in which case false is immediately returned.
7521     */
7522    public every(predicate: (element: number, index: number) => boolean): boolean {
7523        return this.every((element: number, index: number, array: Int32Array): boolean => predicate(element, index))
7524    }
7525
7526    /**
7527     * Determines whether the specified callback function returns true for all elements of an array.
7528     *
7529     * @param predicate A function that accepts no arguments.
7530     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7531     * or until the end of the array.
7532     *
7533     * @returns true unless predicate function returns a false for an array element,
7534     * in which case false is immediately returned.
7535     */
7536    public every(predicate: () => boolean): boolean {
7537        return this.every((element: number, index: number, array: Int32Array): boolean => predicate())
7538    }
7539
7540    /**
7541     * Creates a new Int32Array from current Int32Array based on a condition fn.
7542     *
7543     * @param fn the condition to apply for each element
7544     *
7545     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7546     */
7547    public filter(fn: (val: number, index: number, array: Int32Array) => boolean): Int32Array {
7548        let markers = new boolean[this.lengthInt]
7549        let resLen = 0
7550        for (let i = 0; i < this.lengthInt; ++i) {
7551            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
7552            if (markers[i]) {
7553                ++resLen
7554            }
7555        }
7556        let resBuf = new ArrayBuffer(resLen * Int32Array.BYTES_PER_ELEMENT as int)
7557        let res = new Int32Array(resBuf, 0)
7558        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
7559            if (markers[i]) {
7560                res.set(j, this.getUnsafe(i))
7561                ++j
7562            }
7563        }
7564        return res
7565    }
7566
7567    /**
7568     * creates a new Int32Array from current Int32Array based on a condition fn
7569     *
7570     * @param fn the condition to apply for each element
7571     *
7572     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7573     */
7574    public filter(fn: (val: number, index: number) => boolean): Int32Array {
7575        let newF: (val: number, index: number, array: Int32Array) => boolean =
7576            (val: number, index: number, array: Int32Array): boolean => { return fn(val, index as number) }
7577        return this.filter(newF)
7578    }
7579
7580    /**
7581     * creates a new Int32Array from current Int32Array based on a condition fn
7582     *
7583     * @param fn the condition to apply for each element
7584     *
7585     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7586     */
7587    public filter(fn: () => boolean): Int32Array {
7588        let newF: (val: number, index: number, array: Int32Array) => boolean =
7589            (val: number, index: number, array: Int32Array): boolean => { return fn() }
7590        return this.filter(newF)
7591    }
7592
7593    /**
7594     * Returns the value of the first element in the array where predicate is true, and undefined
7595     * otherwise
7596     *
7597     * @param predicate find calls predicate once for each element of the array, in ascending
7598     * order, until it finds one where predicate returns true. If such an element is found, find
7599     * immediately returns that element value. Otherwise, find returns undefined
7600     *
7601     * @returns number | undefined
7602     */
7603    public find(predicate: (value: number, index: number, obj: Int32Array) => boolean): number | undefined {
7604        for (let i = 0; i < this.lengthInt; ++i) {
7605            let val = this.getUnsafe(i)
7606            if (predicate(val as number, i as number, this)) {
7607                return val as number
7608            }
7609        }
7610        return undefined
7611    }
7612
7613    /**
7614     * Returns the value of the first element in the array where predicate is true, and undefined
7615     * otherwise
7616     *
7617     * @param predicate find calls predicate once for each element of the array, in ascending
7618     * order, until it finds one where predicate returns true. If such an element is found, find
7619     * immediately returns that element value. Otherwise, find returns undefined
7620     *
7621     * @returns number | undefined
7622     */
7623    public find(predicate: (value: number, index: number) => boolean): number | undefined {
7624        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate(value, index))
7625    }
7626
7627    /**
7628     * Returns the index of the first element in the array where predicate is true, and -1
7629     * otherwise
7630     *
7631     * @param predicate find calls predicate once for each element of the array, in ascending
7632     * order, until it finds one where predicate returns true. If such an element is found,
7633     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7634     *
7635     * @returns number
7636     */
7637    public findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean): number {
7638        for (let i = 0; i < this.lengthInt; ++i) {
7639            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
7640                return i as number
7641            }
7642        }
7643        return -1 as number
7644    }
7645
7646    /**
7647     * Returns the index of the first element in the array where predicate is true, and -1
7648     * otherwise
7649     *
7650     * @param predicate find calls predicate once for each element of the array, in ascending
7651     * order, until it finds one where predicate returns true. If such an element is found,
7652     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7653     *
7654     * @returns number
7655     */
7656    public findIndex(predicate: (value: number, index: number) => boolean): number {
7657        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate(value, index as number)) as number
7658    }
7659
7660    /**
7661     * Returns the index of the first element in the array where predicate is true, and -1
7662     * otherwise
7663     *
7664     * @param predicate find calls predicate once for each element of the array, in ascending
7665     * order, until it finds one where predicate returns true. If such an element is found,
7666     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7667     *
7668     * @returns number
7669     */
7670    public findIndex(predicate: () => boolean): number {
7671        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate()) as number
7672    }
7673
7674    /**
7675     * Finds the last element in the Int32Array that satisfies the condition
7676     *
7677     * @param fn condition
7678     *
7679     * @returns the last element that satisfies fn
7680     */
7681    public findLast(fn: (val: number, index: number, array: Int32Array) => boolean): int {
7682        for (let i = this.lengthInt - 1; i >= 0; --i) {
7683            let val = this.getUnsafe(i)
7684            if (fn(val as number, i as number, this)) {
7685                return val
7686            }
7687        }
7688        throw new Error("Int32Array.findLast: not implemented if an element was not found")
7689    }
7690
7691    /**
7692     * Finds the last element in the Int32Array that satisfies the condition
7693     *
7694     * @param fn condition
7695     *
7696     * @returns the last element that satisfies fn
7697     */
7698    public findLast(fn: (val: number, index: number) => boolean): int {
7699        let newF: (val: number, index: number, array: Int32Array) => boolean =
7700            (val: number, index: number, array: Int32Array): boolean => { return fn(val as number, index as number) }
7701        return this.findLast(newF)
7702    }
7703
7704    /**
7705     * Finds an index of the last element in the Int32Array that satisfies the condition
7706     *
7707     * @param fn condition
7708     *
7709     * @returns the index of the last element that satisfies fn, -1 otherwise
7710     */
7711    public findLastIndex(fn: (val: number, index: number, array: Int32Array) => boolean): number {
7712        for (let i = this.lengthInt - 1; i >= 0; --i) {
7713            let val = this.getUnsafe(i)
7714            if (fn(val as number, i as number, this)) {
7715                return i
7716            }
7717        }
7718        return -1 as number
7719    }
7720
7721    /**
7722     * Finds an index of the last element in the Int32Array that satisfies the condition
7723     *
7724     * @param fn condition
7725     *
7726     * @returns the index of the last element that satisfies fn, -1 otherwise
7727     */
7728    public findLastIndex(fn: (val: number, index: number) => boolean): number {
7729        let newF: (val: number, index: number, array: Int32Array) => boolean =
7730            (val: number, index: number, array: Int32Array): boolean => { return fn(val, index as number) }
7731        return this.findLastIndex(newF) as number
7732    }
7733
7734    /**
7735     * Performs the specified action for each element in Int32Array
7736     *
7737     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7738     * callbackfn function one time for each element in the array.
7739     *
7740     * @returns None
7741     */
7742    public forEach(callbackfn: (value: number, index: number, array: Int32Array) => void): void {
7743        for (let i = 0; i < this.lengthInt; ++i) {
7744            callbackfn(this.getUnsafe(i) as number, i as number, this)
7745        }
7746    }
7747
7748    /**
7749     * Performs the specified action for each element in Int32Array
7750     *
7751     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7752     * callbackfn function one time for each element in the array.
7753     *
7754     * @returns None
7755     */
7756    public forEach(callbackfn: (value: number, index: number) => void): void {
7757        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn(value, index))
7758    }
7759
7760    /**
7761     * Performs the specified action for each element in Int32Array
7762     *
7763     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7764     * callbackfn function one time for each element in the array.
7765     *
7766     * @returns None
7767     */
7768    public forEach(callbackfn: () => void): void {
7769        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn())
7770    }
7771
7772    /**
7773     * Returns the object itself
7774     *
7775     * @returns Int32Array
7776     */
7777    public valueOf(): Int32Array {
7778        return this
7779    }
7780
7781    internal getUnsafe(index: int): int {
7782        let byteIndex = index * Int32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
7783        let res : int = 0
7784        let byteVal : int
7785        if (IS_LITTLE_ENDIAN) {
7786            if (this.buffer instanceof ArrayBuffer) {
7787                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7788                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
7789                    byteVal &= 0xff
7790                    res = (res | byteVal << (8 * i)) as int
7791                }
7792            } else if (this.buffer instanceof SharedArrayBuffer) {
7793                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7794                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
7795                    byteVal &= 0xff
7796                    res = (res | byteVal << (8 * i)) as int
7797                }
7798            } else {
7799                throw new Error("unexpected type of ArrayBufferLike")
7800            }
7801            return res
7802        } else {
7803            if (this.buffer instanceof ArrayBuffer) {
7804                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7805                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 3 - i)
7806                    byteVal &= 0xff
7807                    res = (res | byteVal << (8 * i)) as int
7808                }
7809            } else if (this.buffer instanceof SharedArrayBuffer) {
7810                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7811                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 3 - i)
7812                    byteVal &= 0xff
7813                    res = (res | byteVal << (8 * i)) as int
7814                }
7815            } else {
7816                throw new Error("unexpected type of ArrayBufferLike")
7817            }
7818            return res
7819        }
7820    }
7821
7822    internal setUnsafe(insertPos: int, val: int): void {
7823        let startByte = insertPos * Int32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
7824        let bits = val
7825        if (IS_LITTLE_ENDIAN) {
7826            if (this.buffer instanceof ArrayBuffer) {
7827                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7828                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7829                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
7830                }
7831            } else if (this.buffer instanceof SharedArrayBuffer) {
7832                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7833                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7834                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
7835                }
7836            } else {
7837                throw new Error("unexpected type of ArrayBufferLike")
7838            }
7839        } else {
7840            if (this.buffer instanceof ArrayBuffer) {
7841                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; i++) {
7842                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7843                    (this.buffer as ArrayBuffer).set(startByte + 3 - i, byteVal)
7844                }
7845            } else if (this.buffer instanceof SharedArrayBuffer) {
7846                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; i++) {
7847                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7848                    (this.buffer as SharedArrayBuffer).set(startByte + 3 - i, byteVal)
7849                }
7850            } else {
7851                throw new Error("unexpected type of ArrayBufferLike")
7852            }
7853        }
7854    }
7855
7856    /** Underlying ArrayBufferLike */
7857    public readonly buffer: ArrayBufferLike
7858
7859    /** Byte offset within the underlying ArrayBufferLike */
7860    public readonly byteOffset: number
7861
7862    /** Number of bytes used */
7863    public readonly byteLength: number
7864
7865    /** String \"Int32Array\" */
7866    public readonly name = "Int32Array"
7867}
7868
7869class BigInt64ArrayIteratorKeys implements IterableIterator<number> {
7870    private length: int
7871    private idx: int = 0
7872
7873    constructor(parent: BigInt64Array) {
7874        this.length = parent.length as int
7875    }
7876
7877    public override $_iterator(): IterableIterator<number> {
7878        return this
7879    }
7880
7881    override next(): IteratorResult<number> {
7882        if (this.idx < 0 || this.idx >= this.length) {
7883            return new IteratorResult<number>()
7884        }
7885        return new IteratorResult<number>(false, this.idx++ as number)
7886    }
7887}
7888
7889class BigInt64ArrayIterator implements IterableIterator<BigInt> {
7890    private parent: BigInt64Array
7891    private idx: int = 0
7892
7893    constructor(parent: BigInt64Array) {
7894        this.parent = parent
7895    }
7896
7897    public override $_iterator(): IterableIterator<BigInt> {
7898        return this
7899    }
7900
7901    override next(): IteratorResult<BigInt> {
7902        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7903            return new IteratorResult<BigInt>()
7904        }
7905        return new IteratorResult<BigInt>(false, new BigInt(this.parent[this.idx++]))
7906    }
7907}
7908
7909class BigInt64ArrayIteratorEntries implements IterableIterator<[Number, BigInt]> {
7910    private parent: BigInt64Array
7911    private idx: int = 0
7912
7913    constructor(parent: BigInt64Array) {
7914        this.parent = parent
7915    }
7916
7917    public override $_iterator(): IterableIterator<[Number, BigInt]> {
7918        return this
7919    }
7920
7921    override next(): IteratorResult<[Number, BigInt]> {
7922        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7923            return new IteratorResult<[Number, BigInt]>()
7924        }
7925        return new IteratorResult<[Number, BigInt]>(
7926            false, [new Number(this.idx), new BigInt(this.parent[this.idx++])] as [Number, BigInt]
7927        )
7928    }
7929}
7930
7931
7932/**
7933 * JS BigInt64Array API-compatible class
7934 */
7935export final class BigInt64Array implements Iterable<BigInt>, ArrayLike<BigInt> {
7936    public static readonly BYTES_PER_ELEMENT: number = 8
7937    internal readonly lengthInt: int
7938
7939    /**
7940     * Creates an empty BigInt64Array.
7941     */
7942    public constructor() {
7943        this(0 as int)
7944    }
7945
7946    /**
7947     * Creates an BigInt64Array with respect to data accessed via Iterable<Number> interface
7948     */
7949    public constructor(elements: Iterable<BigInt>) {
7950        const items: Object = elements as Object
7951        if (items instanceof ArrayLike) {
7952            const arr = Types.identity_cast<BigInt>(items as ArrayLike<BigInt>)
7953            this.byteLength = arr.length as int * BigInt64Array.BYTES_PER_ELEMENT as int
7954            this.lengthInt = arr.length as int
7955            this.buffer = new ArrayBuffer(this.byteLength as int)
7956            this.byteOffset = 0
7957            for (let i: int = 0; i < this.lengthInt; ++i) {
7958                this.setUnsafe(i, this.zeroIfInfinity(arr.$_get(i)).getLong())
7959            }
7960        } else {
7961          let x = BigInt64Array.from(elements)
7962          this.byteLength = x.byteLength
7963          this.lengthInt = x.lengthInt
7964          this.buffer = x.buffer
7965          this.byteOffset = x.byteOffset
7966        }
7967    }
7968
7969    /**
7970     * Creates an BigInt64Array with respect to data, byteOffset and length.
7971     *
7972     * @param buf data initializer
7973     *
7974     * @param byteOffset byte offset from begin of the buf
7975     *
7976     * @param length size of elements of type long in newly created BigInt64Array
7977     */
7978    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
7979        let intByteOffset: int = 0
7980        if (byteOffset != undefined) {
7981            intByteOffset = byteOffset.intValue()
7982            if (intByteOffset < 0) {
7983                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
7984            }
7985        }
7986        let intByteLength: int
7987        if (buf instanceof ArrayBuffer) {
7988            intByteLength = (buf as ArrayBuffer).getByteLength()
7989        } else if (buf instanceof SharedArrayBuffer) {
7990            intByteLength = (buf as SharedArrayBuffer).getByteLength()
7991        } else {
7992            throw new Error("unexpected type of ArrayBufferLike")
7993        }
7994        intByteLength = intByteLength - intByteOffset
7995        if (intByteLength < 0) {
7996            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
7997        }
7998
7999        if (intByteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
8000            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
8001        }
8002        if (intByteOffset % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
8003            throw new RangeError("byteOffset should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
8004        }
8005
8006        let intLength: int
8007        if (length != undefined) {
8008            intLength = length.intValue()
8009            if (intLength > intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
8010                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
8011            }
8012        } else {
8013            intLength = intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int
8014        }
8015        if (intLength < 0) {
8016            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
8017        }
8018        if (intLength < intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
8019            intByteLength = intLength * BigInt64Array.BYTES_PER_ELEMENT as int
8020        }
8021        this.byteLength = intByteLength
8022        this.byteOffset = intByteOffset
8023        this.lengthInt = intLength
8024        this.buffer = buf
8025    }
8026
8027    /**
8028     * Creates an BigInt64Array with respect to data, byteOffset and length.
8029     *
8030     * @param buf data initializer
8031     *
8032     * @param byteOffset byte offset from begin of the buf
8033     *
8034     * @param length size of elements of type long in newly created BigInt64Array
8035     */
8036    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
8037        this(buf, byteOffset, undefined)
8038    }
8039
8040    /**
8041     * Creates an BigInt64Array with respect to data, byteOffset and length.
8042     *
8043     * @param buf data initializer
8044     *
8045     * @param byteOffset byte offset from begin of the buf
8046     *
8047     * @param length size of elements of type long in newly created BigInt64Array
8048     */
8049    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
8050        this(buf, new Number(byteOffset), new Number(length))
8051    }
8052
8053    /**
8054     * Creates an BigInt64Array with respect to data, byteOffset and length.
8055     *
8056     * @param buf data initializer
8057     *
8058     * @param byteOffset byte offset from begin of the buf
8059     *
8060     * @param length size of elements of type long in newly created BigInt64Array
8061     */
8062    public constructor(buf: ArrayBufferLike, byteOffset: number) {
8063        this(buf, new Number(byteOffset), undefined)
8064    }
8065
8066    /**
8067     * Creates an BigInt64Array with respect to data, byteOffset and length.
8068     *
8069     * @param buf data initializer
8070     *
8071     * @param byteOffset byte offset from begin of the buf
8072     *
8073     * @param length size of elements of type long in newly created BigInt64Array
8074     */
8075    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
8076        this(buf, new Number(byteOffset), new Number(length))
8077    }
8078
8079    /**
8080     * Creates an BigInt64Array with respect to buf and byteOffset.
8081     *
8082     * @param buf data initializer
8083     *
8084     * @param byteOffset byte offset from begin of the buf
8085     */
8086    public constructor(buf: ArrayBufferLike, byteOffset: int) {
8087        this(buf, new Number(byteOffset), undefined)
8088    }
8089
8090    /**
8091     * Creates an BigInt64Array with respect to buf.
8092     *
8093     * @param buf data initializer
8094     */
8095    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
8096        if (buf instanceof ArrayBuffer) {
8097            this.byteLength = (buf as ArrayBuffer).getByteLength()
8098            if (this.byteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
8099               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
8100            }
8101            this.lengthInt = this.byteLength / BigInt64Array.BYTES_PER_ELEMENT as int
8102            this.buffer = buf as ArrayBuffer
8103            this.byteOffset = 0
8104        } else if (buf instanceof SharedArrayBuffer) {
8105            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
8106            if (this.byteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
8107               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
8108            }
8109            this.lengthInt = this.byteLength / BigInt64Array.BYTES_PER_ELEMENT as int
8110            this.buffer = buf as SharedArrayBuffer
8111            this.byteOffset = 0
8112        } else if (buf instanceof ArrayLike) {
8113            // NOTE (ikorobkov): dealing with this overload is tricky
8114            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
8115            let arr = Array.from<Number>((buf as ArrayLike<Number>))
8116            this.byteLength = arr.length as int * BigInt64Array.BYTES_PER_ELEMENT as int
8117            this.lengthInt = arr.length as int
8118            this.buffer = new ArrayBuffer(this.byteLength as int)
8119            this.byteOffset = 0
8120            for (let i: int = 0; i < this.lengthInt; ++i) {
8121                this.setUnsafe(i, arr.$_get(i).longValue())
8122            }
8123        } else {
8124            throw new Error("unexpected type of buf")
8125        }
8126    }
8127
8128    /**
8129     * Creates an BigInt64Array with respect to length.
8130     *
8131     * @param length data initializer
8132     */
8133    public constructor(length: int) {
8134        if (length < 0) {
8135            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
8136        }
8137        this.lengthInt = length
8138        this.byteLength = length * BigInt64Array.BYTES_PER_ELEMENT as int
8139        this.byteOffset = 0
8140        this.buffer = new ArrayBuffer(this.byteLength as int)
8141    }
8142
8143    /**
8144     * Creates an BigInt64Array with respect to length.
8145     *
8146     * @param length data initializer
8147     */
8148    public constructor(length: number) {
8149        this(length as int)
8150    }
8151
8152    /**
8153     * Creates a copy of BigInt64Array.
8154     *
8155     * @param other data initializer
8156     */
8157    public constructor(other: BigInt64Array) {
8158        if (other.buffer instanceof ArrayBuffer) {
8159            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
8160        } else if (other.buffer instanceof SharedArrayBuffer) {
8161            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
8162        } else {
8163            throw new Error("unexpected type of buffer")
8164        }
8165        this.byteLength = other.byteLength
8166        this.lengthInt = other.length as int
8167        this.byteOffset = 0
8168    }
8169
8170    /**
8171     * Creates an BigInt64Array from number[]
8172     */
8173    public constructor(numbers: number[]) {
8174        this(numbers.length)
8175        for (let i: int = 0; i < this.lengthInt; ++i) {
8176            this.setUnsafe(i, this.zeroIfInfinity(numbers[i] as long))
8177        }
8178    }
8179
8180    /**
8181     * Creates an BigInt64Array from int[]
8182     */
8183    public constructor(numbers: int[]) {
8184        this(numbers.length)
8185        for (let i: int = 0; i < this.lengthInt; ++i) {
8186            this.setUnsafe(i, this.zeroIfInfinity(numbers[i] as long))
8187        }
8188    }
8189
8190    /**
8191     * Creates an BigInt64Array from bigint[]
8192     */
8193    public constructor(numbers: bigint[]) {
8194        this(numbers.length)
8195        for (let i: int = 0; i < this.lengthInt; ++i) {
8196            this.setUnsafe(i, numbers[i].getLong())
8197        }
8198    }
8199
8200    internal zeroIfInfinity(val: BigInt): BigInt {
8201        if ((val.getLong() == Infinity) || (val.getLong() == -Infinity)) {
8202            return new BigInt(0)
8203        }
8204        return new BigInt(val)
8205    }
8206
8207    internal zeroIfInfinity(val: long): long {
8208        if ((val == Infinity) || (val == -Infinity)) {
8209            return 0 as long
8210        }
8211        return val
8212    }
8213
8214    /**
8215     * Assigns val as element on index.
8216     *
8217     * @param val value to set
8218     *
8219     * @param index index to change
8220     */
8221    public $_set(index: number, val: BigInt): void {
8222        this.$_set(index as int, val)
8223    }
8224
8225    /**
8226     * Assigns val as element on index.
8227     *
8228     * @param val value to set
8229     *
8230     * @param index index to change
8231     */
8232    public $_set(index: int, val: BigInt): void {
8233        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8234        if (index < 0 || index >= this.lengthInt) {
8235            throw new RangeError("invalid index")
8236        }
8237        let v = this.zeroIfInfinity(val)
8238        this.setUnsafe(index, v.getLong())
8239    }
8240
8241    /**
8242     * Assigns val as element on index.
8243     *
8244     * @param val value to set
8245     *
8246     * @param index index to change
8247     */
8248    public $_set(index: number, val: int): void {
8249        this.$_set(index as int, val)
8250    }
8251
8252    /**
8253     * Assigns val as element on index.
8254     *
8255     * @param val value to set
8256     *
8257     * @param index index to change
8258     */
8259    public $_set(index: int, val: int): void {
8260        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8261        if (index < 0 || index >= this.lengthInt) {
8262            throw new RangeError("invalid index")
8263        }
8264        let v = this.zeroIfInfinity(val as long)
8265        this.setUnsafe(index, v as long)
8266    }
8267
8268    /**
8269     * Assigns val as element on index.
8270     *
8271     * @param val value to set
8272     *
8273     * @param index index to change
8274     */
8275    public $_set(index: number, val: long): void {
8276        this.$_set(index as int, val)
8277    }
8278
8279    /**
8280     * Assigns val as element on index.
8281     *
8282     * @param val value to set
8283     *
8284     * @param index index to change
8285     */
8286    public $_set(index: int, val: long): void {
8287        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8288        if (index < 0 || index >= this.lengthInt) {
8289            throw new RangeError("invalid index")
8290        }
8291        let v = this.zeroIfInfinity(val)
8292        this.setUnsafe(index, v)
8293    }
8294
8295    /** Number of long stored in BigInt64Array */
8296    public get length(): number {
8297        return this.lengthInt
8298    }
8299
8300    /**
8301     * Returns an instance of BigInt at passed index.
8302     *
8303     * @param index index to look at
8304     *
8305     * @returns a primitive at index
8306     */
8307    public override $_get(index: number): BigInt {
8308        return this.$_get(index as int) as BigInt
8309    }
8310
8311    /**
8312     * Returns an instance of BigInt at passed index.
8313     *
8314     * @param index index to look at
8315     *
8316     * @returns a primitive at index
8317     */
8318    public $_get(index: int): BigInt {
8319        if (index < 0 || index >= this.lengthInt) {
8320            throw new RangeError("invalid index")
8321        }
8322        return new BigInt(this.getUnsafe(index))
8323    }
8324
8325    /**
8326     * Returns an instance of primitive type at passed index.
8327     *
8328     * @param index index to look at
8329     *
8330     * @returns a primitive at index
8331     */
8332    public at(index: number): BigInt | undefined {
8333        return this.at(index as int)
8334    }
8335
8336    /**
8337     * Returns an instance of primitive type at passed index.
8338     *
8339     * @param index index to look at
8340     *
8341     * @returns a primitive at index
8342     */
8343    public at(index: int): BigInt | undefined {
8344        let k: int
8345        if (index >= 0) {
8346            k = index
8347        } else {
8348            k = this.lengthInt + index
8349        }
8350        if (k < 0 || k >= this.lengthInt) {
8351            return undefined
8352        }
8353        return new BigInt(this.getUnsafe(k))
8354    }
8355
8356    /**
8357     * Makes a copy of internal elements to targetPos from startPos to endPos.
8358     *
8359     * @param target insert index to place copied elements
8360     *
8361     * @param start start index to begin copy from
8362     *
8363     * @param end last index to end copy from, excluded
8364     *
8365     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8366     */
8367    public copyWithin(target: number, start: number, end?: number): BigInt64Array {
8368        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8369    }
8370
8371    /**
8372     * Makes a copy of internal elements to targetPos from startPos to endPos.
8373     *
8374     * @param target insert index to place copied elements
8375     *
8376     * @param start start index to begin copy from
8377     *
8378     * @param end last index to end copy from, excluded
8379     *
8380     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8381     */
8382    public copyWithin(target: int, start: number, end?: number): BigInt64Array {
8383        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8384    }
8385
8386    /**
8387     * Makes a copy of internal elements to targetPos from startPos to endPos.
8388     *
8389     * @param target insert index to place copied elements
8390     *
8391     * @param start start index to begin copy from
8392     *
8393     * @param end last index to end copy from, excluded
8394     *
8395     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8396     */
8397    public copyWithin(target: number, start: int, end?: number): BigInt64Array {
8398        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8399    }
8400
8401    /**
8402     * Makes a copy of internal elements to targetPos from startPos to endPos.
8403     *
8404     * @param target insert index to place copied elements
8405     *
8406     * @param start start index to begin copy from
8407     *
8408     * @param end last index to end copy from, excluded
8409     *
8410     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8411     */
8412    public copyWithin(target: int, start: int, end?: number): BigInt64Array {
8413        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8414    }
8415
8416    /**
8417     * Makes a copy of internal elements to targetPos from startPos to endPos.
8418     *
8419     * @param target insert index to place copied elements
8420     *
8421     * @param start start index to begin copy from
8422     *
8423     * @param end last index to end copy from, excluded
8424     *
8425     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8426     */
8427    public copyWithin(target: int, start: int, end: int): BigInt64Array {
8428        let toPos = normalizeIndex(target, this.lengthInt)
8429        let fromPos = normalizeIndex(start, this.lengthInt)
8430        const finalPos = normalizeIndex(end, this.lengthInt)
8431        let count: int = finalPos - fromPos
8432        if (count > (this.lengthInt - toPos)) {
8433            count = this.lengthInt - toPos
8434        }
8435        let direction: int = 1
8436        if ((fromPos < toPos) && (toPos < fromPos + count)) {
8437            fromPos = fromPos + count - 1
8438            toPos   = toPos   + count - 1
8439            direction = -1
8440        }
8441        while (count > 0) {
8442            const value = this.getUnsafe(fromPos)
8443            this.setUnsafe(toPos, value)
8444            fromPos = fromPos + direction
8445            toPos = toPos + direction
8446            --count
8447        }
8448        return this
8449    }
8450
8451    /**
8452     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
8453     *
8454     * @param target insert index to place copied elements
8455     *
8456     * See rules of parameters normalization:
8457     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
8458     */
8459    public copyWithin(target: number): BigInt64Array {
8460        return this.copyWithin(target as int)
8461    }
8462
8463    /**
8464     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
8465     *
8466     * @param target insert index to place copied elements
8467     *
8468     * See rules of parameters normalization:
8469     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
8470     */
8471    public copyWithin(target: int): BigInt64Array {
8472        return this.copyWithin(target, 0, this.lengthInt)
8473    }
8474
8475    /**
8476     * Returns an array of key, value pairs for every entry in the BigInt64Array
8477     *
8478     * @returns key, value pairs for every entry in the array
8479     */
8480    public entries(): IterableIterator<[Number, BigInt]> {
8481        return new BigInt64ArrayIteratorEntries(this)
8482    }
8483
8484    /**
8485     * Fills the BigInt64Array with specified value
8486     *
8487     * @param value new valuy
8488     *
8489     * @returns modified BigInt64Array
8490     */
8491    public fill(value: BigInt, start?: number, end?: number): this {
8492        value = this.zeroIfInfinity(value)
8493        this.fill(value.getLong(), asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
8494        return this
8495    }
8496
8497    /**
8498     * Fills the BigInt64Array with specified value
8499     *
8500     * @param value new valuy
8501     *
8502     * @returns modified BigInt64Array
8503     */
8504    public fill(value: BigInt, start: int, end?: number): this {
8505        value = this.zeroIfInfinity(value)
8506        this.fill(value.getLong(), start as int, asIntOrDefault(end, this.lengthInt))
8507        return this
8508    }
8509
8510    /**
8511     * Fills the BigInt64Array with specified value
8512     *
8513     * @param value new valuy
8514     *
8515     * @returns modified BigInt64Array
8516     */
8517    public fill(value: BigInt, start: int, end: number): this {
8518        value = this.zeroIfInfinity(value)
8519        this.fill(value.getLong(), start as int, end as int)
8520        return this
8521    }
8522
8523    /**
8524     * Fills the BigInt64Array with specified value
8525     *
8526     * @param value new valuy
8527     *
8528     * @returns modified BigInt64Array
8529     */
8530    public fill(value: BigInt, start: number, end: int): this {
8531        value = this.zeroIfInfinity(value)
8532        this.fill(value.getLong(), start as int, end as int)
8533        return this
8534    }
8535
8536    /**
8537     * Fills the BigInt64Array with specified value
8538     *
8539     * @param value new valuy
8540     *
8541     * @returns modified BigInt64Array
8542     */
8543    public fill(value: BigInt, start: int, end: int): this {
8544        value = this.zeroIfInfinity(value)
8545        this.fill(value.getLong(), start as int, end as int)
8546        return this
8547    }
8548
8549    /**
8550     * Fills the BigInt64Array with specified value
8551     *
8552     * @param value new valuy
8553     *
8554     * @returns modified BigInt64Array
8555     */
8556    public fill(value: long, start?: number, end?: number): this {
8557        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
8558        return this
8559    }
8560
8561    /**
8562     * Fills the BigInt64Array with specified value
8563     *
8564     * @param value new valuy
8565     *
8566     * @returns modified BigInt64Array
8567     */
8568    public fill(value: long, start: int, end?: number): this {
8569        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
8570        return this
8571    }
8572
8573    /**
8574     * Fills the BigInt64Array with specified value
8575     *
8576     * @param value new valuy
8577     *
8578     * @returns modified BigInt64Array
8579     */
8580    public fill(value: long, start: int, end: number): this {
8581        this.fill(value, start as int, end as int)
8582        return this
8583    }
8584
8585    /**
8586     * Fills the BigInt64Array with specified value
8587     *
8588     * @param value new valuy
8589     *
8590     * @returns modified BigInt64Array
8591     */
8592    public fill(value: long, start: number, end: int): this {
8593        this.fill(value, start as int, end as int)
8594        return this
8595    }
8596
8597    /**
8598     * Fills the BigInt64Array with specified value
8599     *
8600     * @param value new valuy
8601     *
8602     * @returns modified BigInt64Array
8603     */
8604    public fill(value: long, start: int, end: int): this {
8605        const k = normalizeIndex(start, this.lengthInt)
8606        const finalPos = normalizeIndex(end, this.lengthInt)
8607        for (let i: int = k; i < finalPos; ++i) {
8608            this.setUnsafe(i, value)
8609        }
8610        return this
8611    }
8612
8613    /**
8614     * Assigns val as element on insertPos.
8615     * @description Added to avoid (un)packing a single value into array to use overloaded set(long[], insertPos)
8616     *
8617     * @param val value to set
8618     *
8619     * @param insertPos index to change
8620     */
8621    public set(insertPos: number, val: BigInt): void {
8622        this.$_set(insertPos, val)
8623    }
8624
8625    /**
8626     * Assigns val as element on insertPos.
8627     * @description Added to avoid (un)packing a single value into array to use overloaded set(long[], insertPos)
8628     *
8629     * @param val value to set
8630     *
8631     * @param insertPos index to change
8632     */
8633    public set(insertPos: int, val: long): void {
8634        this.$_set(insertPos, val)
8635    }
8636
8637    /**
8638     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
8639     *
8640     * @param arr array to copy data from
8641     *
8642     * @param insertPos start index where data from arr will be inserted
8643     *
8644     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
8645     */
8646    public set(arr: BigInt[], insertPos: number): void {
8647        const offset = insertPos as int
8648        if (offset < 0 || offset + arr.length > this.lengthInt) {
8649            throw new RangeError("offset is out of bounds")
8650        }
8651        for (let i = 0; i < arr.length as int; ++i) {
8652            let v = this.zeroIfInfinity(arr[i])
8653            this.setUnsafe(offset + i, v.getLong())
8654        }
8655    }
8656
8657    /**
8658     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
8659     *
8660     * @param arr array to copy data from
8661     *
8662     * @param insertPos start index where data from arr will be inserted
8663     *
8664     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
8665     */
8666    public set(arr: long[], insertPos: int): void {
8667        const offset = insertPos as int
8668        if (offset < 0 || offset + arr.length > this.lengthInt) {
8669            throw new RangeError("offset is out of bounds")
8670        }
8671        for (let i = 0; i < arr.length as int; ++i) {
8672            let v = this.zeroIfInfinity(arr[i])
8673            this.setUnsafe(offset + i, v)
8674        }
8675    }
8676
8677    /**
8678     * Copies all elements of arr to the current BigInt64Array.
8679     *
8680     * @param arr array to copy data from
8681     */
8682    public set(arr: BigInt[]): void {
8683        this.set(arr, 0 as number)
8684    }
8685
8686    /**
8687     * Copies all elements of arr to the current BigInt64Array.
8688     *
8689     * @param arr array to copy data from
8690     */
8691    public set(arr: long[]): void {
8692        this.set(arr, 0 as int)
8693    }
8694
8695    /**
8696     * Copies elements from an ArrayLike object to the BigInt64Array.
8697     *
8698     * @param array An ArrayLike object containing the elements to copy.
8699     *
8700     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
8701     */
8702    public set(array: ArrayLike<BigInt>, offset: number = 0): void {
8703        const insertPos = offset as int
8704        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
8705            throw new RangeError("offset is out of bounds")
8706        }
8707        for (let i = 0; i < array.length as int; ++i) {
8708            let v = this.zeroIfInfinity(array[i])
8709            this.setUnsafe(insertPos + i, v.getLong())
8710        }
8711    }
8712
8713    /**
8714     * Returns a new array from a set of elements.
8715     *
8716     * @param items a set of elements to include in the new array object.
8717     *
8718     * @returns new BigInt64Array
8719     */
8720    public static of(...items: number[]): BigInt64Array {
8721        let res = new BigInt64Array(items.length as int)
8722        for (let i: int = 0; i < items.length; i++) {
8723            const isInfinity = (items[i] == Infinity) || (items[i] == -Infinity)
8724            res.setUnsafe(i, (isInfinity ? 0 : items[i]) as long)
8725        }
8726        return res
8727    }
8728
8729    /**
8730     * Returns a new array from a set of elements.
8731     *
8732     * @param items a set of elements to include in the new array object.
8733     *
8734     * @returns new BigInt64Array
8735     */
8736    public static of(...items: int[]): BigInt64Array {
8737        let res = new BigInt64Array(items.length as int)
8738        for (let i: int = 0; i < items.length; i++) {
8739            res.setUnsafe(i, items[i] as long)
8740        }
8741        return res
8742    }
8743
8744    /**
8745     * Returns a new array from a set of elements.
8746     *
8747     * @param items a set of elements to include in the new array object.
8748     *
8749     * @returns new BigInt64Array
8750     */
8751    public static of(...items: long[]): BigInt64Array {
8752        let res = new BigInt64Array(items.length as int)
8753        for (let i: int = 0; i < items.length; i++) {
8754            res.setUnsafe(i, items[i])
8755        }
8756        return res
8757    }
8758
8759    /**
8760     * Returns a new array from a set of elements.
8761     *
8762     * @param items a set of elements to include in the new array object.
8763     *
8764     * @returns new BigInt64Array
8765     */
8766    public static of(...items: bigint[]): BigInt64Array {
8767        let res = new BigInt64Array(items.length as int)
8768        for (let i: int = 0; i < items.length; i++) {
8769            res.setUnsafe(i, items[i].getLong())
8770        }
8771        return res
8772    }
8773
8774    /**
8775     * Returns a new array from a set of elements.
8776     *
8777     * @param items a set of elements to include in the new array object.
8778     *
8779     * @returns new BigInt64Array
8780     */
8781    public static of(): BigInt64Array {
8782        return new BigInt64Array(0 as int)
8783    }
8784
8785    /**
8786     * Creates an array from an array-like or iterable object.
8787     *
8788     * @param arrayLike An array-like or iterable object to convert to an array.
8789     *
8790     * @returns new BigInt64Array
8791     */
8792    public static from(arrayLike: ArrayLike<number>): BigInt64Array {
8793        throw new Error("BigInt64Array.from: not implemented")
8794    }
8795
8796    /**
8797     * Creates an array from an array-like or iterable object.
8798     *
8799     * @param arrayLike An array-like or iterable object to convert to an array.
8800     *
8801     * @param mapfn A mapping function to call on every element of the array.
8802     *
8803     * @returns new BigInt64Array
8804     */
8805    public static from(arrayLike: Iterable<BigInt>, mapfn?: (v: BigInt, k: number) => BigInt): BigInt64Array {
8806        if (mapfn == undefined) {
8807            mapfn = (v: BigInt, k: number): BigInt => { return v }
8808        }
8809
8810        let iter = arrayLike.$_iterator()
8811        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
8812        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
8813        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
8814        //  we can make one pass through the iterator without the need for memory reallocation.
8815        const maybeLength = tryGetIteratorLength(arrayLike)
8816        if (maybeLength) {
8817            const result = new BigInt64Array(maybeLength)
8818            for (let i = 0; i < maybeLength; ++i) {
8819                const x = iter.next()
8820                if (x.done) {
8821                    return new BigInt64Array(result.buffer, 0, i)
8822                }
8823                result.setUnsafe(i, (mapfn)!(x.value!, i).getLong())
8824            }
8825            return result
8826        }
8827
8828        // NOTE (templin.konstantin): Create builtin array as buffer
8829        let temp = new BigInt64Array(6)
8830        let index = new int[1]
8831        index[0] = 0
8832
8833        iteratorForEach<BigInt>(iter, (x: BigInt): void => {
8834            if (index[0] + 1 > temp.lengthInt) {
8835                // NOTE (templin.konstantin): Progressive reallocation
8836                const curLength = (temp.buffer as Buffer).getByteLength()
8837                const tb = new ArrayBuffer(curLength * 2)
8838                for (let i = 0; i < curLength; ++i) {
8839                    tb.set(i, (temp.buffer as Buffer).at(i))
8840                }
8841                temp = new BigInt64Array(tb)
8842            }
8843            temp.setUnsafe(index[0], (mapfn)!(x, index[0]).getLong())
8844            index[0]++
8845        })
8846        return new BigInt64Array(temp.buffer, 0, index[0])
8847    }
8848
8849
8850    /**
8851     * Creates an array from an array-like or iterable object.
8852     *
8853     * @param arrayLike An array-like or iterable object to convert to an array.
8854     *
8855     * @param mapfn A mapping function to call on every element of the array.
8856     *
8857     * @returns new BigInt64Array
8858     */
8859    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => BigInt): BigInt64Array {
8860        let res = new BigInt64Array(arrayLike.length)
8861        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
8862        const idx = new int[1]
8863        idx[0] = 0
8864        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
8865            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number).getLong())
8866            idx[0] += 1
8867        })
8868        return res
8869    }
8870
8871    /**
8872     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8873     *
8874     * @param searchElement The element to search for
8875     *
8876     * @param fromIndex The position in this array at which to begin searching for searchElement
8877     *
8878     * @returns true if searchElement is in BigInt64Array, false otherwise
8879     */
8880    public includes(searchElement: BigInt, fromIndex?: number): boolean {
8881        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
8882    }
8883
8884    /**
8885     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8886     *
8887     * @param searchElement The element to search for
8888     *
8889     * @param fromIndex The position in this array at which to begin searching for searchElement
8890     *
8891     * @returns true if e is in BigInt64Array, false otherwise
8892     */
8893    public includes(searchElement: long, fromIndex: int): boolean {
8894        return this.indexOf(searchElement as int, fromIndex) != -1
8895    }
8896
8897    /**
8898     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8899     *
8900     * @param searchElement The element to search for
8901     *
8902     * @param fromIndex The position in this array at which to begin searching for searchElement
8903     *
8904     * @returns true if searchElement is in BigInt64Array, false otherwise
8905     */
8906    public includes(searchElement: long): boolean {
8907        return this.includes(searchElement, 0)
8908    }
8909
8910    /**
8911     * Returns the index of the first occurrence of a value in BigInt64Array.
8912     *
8913     * @param searchElement The value to locate in the array.
8914     *
8915     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8916     *  search starts at index 0.
8917     *
8918     * @returns index of element if it presents, -1 otherwise
8919     */
8920    public indexOf(searchElement: BigInt, fromIndex?: number): number {
8921        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
8922    }
8923
8924    /**
8925     * Returns the index of the first occurrence of a value in BigInt64Array.
8926     *
8927     * @param searchElement The value to locate in the array.
8928     *
8929     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8930     *  search starts at index 0.
8931     *
8932     * @returns index of element if it presents, -1 otherwise
8933     */
8934    public indexOf(searchElement: BigInt, fromIndex: int): number {
8935        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
8936        for (let i = fromIndex; i < this.lengthInt; i++) {
8937            if (new BigInt(this.getUnsafe(i)) == searchElement) {
8938                return i
8939            }
8940        }
8941        return -1
8942    }
8943
8944    /**
8945     * Returns the index of the first occurrence of a value in BigInt64Array.
8946     *
8947     * @param searchElement The value to locate in the array.
8948     *
8949     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8950     *  search starts at index 0.
8951     *
8952     * @returns index of element if it presents, -1 otherwise
8953     */
8954    public indexOf(searchElement: int, fromIndex: int): number {
8955        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
8956        for (let i = fromIndex; i < this.lengthInt; i++) {
8957            if (this.getUnsafe(i) == searchElement as long) {
8958                return i
8959            }
8960        }
8961        return -1
8962    }
8963
8964    /**
8965     * Returns the index of the first occurrence of a value in BigInt64Array.
8966     *
8967     * @param searchElement The value to locate in the array.
8968     *
8969     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8970     *  search starts at index 0.
8971     *
8972     * @returns index of element if it presents, -1 otherwise
8973     */
8974    public indexOf(searchElement: int): number {
8975        return this.indexOf(searchElement, 0)
8976    }
8977
8978    /**
8979     * Adds all the elements of an array separated by the specified separator string
8980     *
8981     * @param separator A string used to separate one element of an array from the next in the
8982     * resulting String. If omitted, the array elements are separated with a comma
8983     *
8984     * @returns joined representation
8985     */
8986    public join(separator?: String): string {
8987        if (separator == undefined) {
8988            return this.join(",")
8989        }
8990        let res: StringBuilder = new StringBuilder("")
8991        for (let i = 0; i < this.lengthInt - 1; ++i) {
8992            res.append(new BigInt(this.getUnsafe(i)))
8993            res.append(separator)
8994        }
8995        if (this.lengthInt > 0) {
8996            res.append(new BigInt(this.getUnsafe(this.lengthInt - 1)))
8997        }
8998        return res.toString()
8999    }
9000
9001    /**
9002     * Returns an list of keys in BigInt64Array
9003     *
9004     * @returns iterator over keys
9005     */
9006    public keys(): IterableIterator<number> {
9007        return new BigInt64ArrayIteratorKeys(this)
9008    }
9009
9010    /**
9011     * Returns the index of the last occurrence of a value in BigInt64Array.
9012     *
9013     * @param searchElement The value to locate in the array.
9014     *
9015     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9016     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9017     *
9018     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9019     */
9020    public lastIndexOf(searchElement: BigInt, fromIndex: number|undefined): number {
9021        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
9022    }
9023
9024    /**
9025     * Returns the index of the last occurrence of a value in BigInt64Array.
9026     *
9027     * @param searchElement The value to locate in the array.
9028     *
9029     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9030     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9031     *
9032     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9033     */
9034    public lastIndexOf(searchElement: BigInt): number {
9035        return this.lastIndexOf(searchElement, this.lengthInt - 1)
9036    }
9037
9038    /**
9039     * Returns the index of the last occurrence of a value in BigInt64Array.
9040     *
9041     * @param searchElement The value to locate in the array.
9042     *
9043     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9044     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9045     *
9046     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9047     */
9048    public lastIndexOf(searchElement: BigInt, fromIndex: int): number {
9049        if (this.lengthInt == 0) {
9050            return -1
9051        }
9052        let k: int = this.lengthInt + fromIndex
9053        if (fromIndex >= 0) {
9054            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
9055        }
9056        while (k >= 0) {
9057            if (new BigInt(this.getUnsafe(k)) == searchElement) {
9058                return k
9059            }
9060            k--
9061        }
9062        return -1
9063    }
9064
9065    /**
9066     * Returns the index of the last occurrence of a value in BigInt64Array.
9067     *
9068     * @param searchElement The value to locate in the array.
9069     *
9070     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9071     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9072     *
9073     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9074     */
9075    public lastIndexOf(searchElement: int, fromIndex: int): number {
9076        if (this.lengthInt == 0) {
9077            return -1
9078        }
9079        let k: int = this.lengthInt + fromIndex
9080        if (fromIndex >= 0) {
9081            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
9082        }
9083        while (k >= 0) {
9084            if (this.getUnsafe(k) == searchElement as long) {
9085                return k
9086            }
9087            k--
9088        }
9089        return -1
9090    }
9091
9092    /**
9093     * Returns the index of the last occurrence of a value in BigInt64Array.
9094     *
9095     * @param searchElement The value to locate in the array.
9096     *
9097     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9098     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9099     *
9100     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9101     */
9102    public lastIndexOf(searchElement: int): number {
9103        return this.lastIndexOf(searchElement, this.lengthInt - 1)
9104    }
9105
9106    /**
9107    * Creates a new BigInt64Array using initializer
9108    *
9109    * @param data initializer
9110    *
9111    * @returns a new BigInt64Array from data
9112    */
9113    public of(data: Object[]): BigInt64Array {
9114        throw new Error("BigInt64Array.of: not implemented")
9115    }
9116
9117    /**
9118     * Creates a new BigInt64Array using reversed data from the current one
9119     *
9120     * @returns a new BigInt64Array using reversed data from the current one
9121     */
9122    public reverse(): BigInt64Array {
9123        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
9124            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
9125            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
9126            this.setUnsafe(i, tmp)
9127        }
9128        return this
9129    }
9130
9131    /**
9132     * Creates a slice of current BigInt64Array using range [begin, end)
9133     *
9134     * @param begin start index to be taken into slice
9135     *
9136     * @param end last index to be taken into slice
9137     *
9138     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
9139     *
9140     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
9141     */
9142    public slice(begin?: number, end?: number): BigInt64Array {
9143        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
9144    }
9145
9146    /**
9147     * Creates a slice of current BigInt64Array using range [begin, end)
9148     *
9149     * @param begin start index to be taken into slice
9150     *
9151     * @param end last index to be taken into slice
9152     *
9153     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
9154     *
9155     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
9156     */
9157    public slice(begin: number, end: number): BigInt64Array {
9158        return this.slice(begin as int, end as int)
9159    }
9160
9161    /**
9162     * Creates a slice of current BigInt64Array using range [begin, end)
9163     *
9164     * @param begin start index to be taken into slice
9165     *
9166     * @param end last index to be taken into slice
9167     *
9168     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
9169     *
9170     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
9171     */
9172    public slice(begin: number, end: int): BigInt64Array {
9173        return this.slice(begin as int, end as int)
9174    }
9175
9176    /**
9177     * Creates a slice of current BigInt64Array using range [begin, end)
9178     *
9179     * @param begin start index to be taken into slice
9180     *
9181     * @param end last index to be taken into slice
9182     *
9183     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
9184     *
9185     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
9186     */
9187    public slice(begin: int, end: number): BigInt64Array {
9188        return this.slice(begin as int, end as int)
9189    }
9190
9191    /**
9192     * Creates a slice of current BigInt64Array using range [begin, end)
9193     *
9194     * @param begin start index to be taken into slice
9195     *
9196     * @param end last index to be taken into slice
9197     *
9198     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
9199     *
9200     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
9201     */
9202    public slice(begin: int, end: int): BigInt64Array {
9203        const len: int = this.lengthInt
9204        const relStart = normalizeIndex(begin, len)
9205        const relEnd = normalizeIndex(end, len)
9206        let count = relEnd - relStart
9207        if (count < 0) {
9208            count = 0
9209        }
9210        if (this.buffer instanceof ArrayBuffer) {
9211            let buf = (this.buffer as ArrayBuffer).slice(relStart * BigInt64Array.BYTES_PER_ELEMENT as int, relEnd * BigInt64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
9212            return new BigInt64Array(buf)
9213        } else if (this.buffer instanceof SharedArrayBuffer) {
9214            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * BigInt64Array.BYTES_PER_ELEMENT as int, relEnd * BigInt64Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
9215            return new BigInt64Array(buf)
9216        } else {
9217            throw new Error("unexpected type of buffer")
9218        }
9219    }
9220
9221    /**
9222     * Creates a slice of current BigInt64Array using range [begin, this.length).
9223     *
9224     * @param begin start index to be taken into slice
9225     *
9226     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
9227     */
9228    public slice(begin: number): BigInt64Array {
9229        return this.slice(begin as int)
9230    }
9231
9232    /**
9233     * Creates a slice of current BigInt64Array using range [begin, this.length).
9234     *
9235     * @param begin start index to be taken into slice
9236     *
9237     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
9238     */
9239    public slice(begin: int): BigInt64Array {
9240        return this.slice(begin, this.lengthInt)
9241    }
9242
9243    /**
9244     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9245     *
9246     * @param begin start index, inclusive
9247     *
9248     * @param end last index, exclusive
9249     *
9250     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9251     */
9252    public subarray(begin?: number, end?: number): BigInt64Array {
9253        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
9254    }
9255
9256    /**
9257     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9258     *
9259     * @param begin start index, inclusive
9260     *
9261     * @param end last index, exclusive
9262     *
9263     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9264     */
9265    public subarray(begin: number, end: number): BigInt64Array {
9266        return this.subarray(begin as int, end as int)
9267    }
9268
9269    /**
9270     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9271     *
9272     * @param begin start index, inclusive
9273     *
9274     * @param end last index, exclusive
9275     *
9276     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9277     */
9278    public subarray(begin: number, end: int): BigInt64Array {
9279        return this.subarray(begin as int, end as int)
9280    }
9281
9282    /**
9283     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9284     *
9285     * @param begin start index, inclusive
9286     *
9287     * @param end last index, exclusive
9288     *
9289     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9290     */
9291    public subarray(begin: int, end: number): BigInt64Array {
9292        return this.subarray(begin as int, end as int)
9293    }
9294
9295    /**
9296     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9297     *
9298     * @param begin start index, inclusive
9299     *
9300     * @param end last index, exclusive
9301     *
9302     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9303     */
9304    public subarray(begin: int, end: int): BigInt64Array {
9305        const len: int = this.lengthInt
9306        const relStart = normalizeIndex(begin, len)
9307        const relEnd = normalizeIndex(end, len)
9308        let count = relEnd - relStart
9309        if (count < 0) {
9310            count = 0
9311        }
9312        return new BigInt64Array(this.buffer, relStart * BigInt64Array.BYTES_PER_ELEMENT as int, count)
9313    }
9314
9315    /**
9316     * Creates a BigInt64Array with the same ArrayBufferLike
9317     *
9318     * @param begin start index, inclusive
9319     *
9320     * @returns new BigInt64Array with the same ArrayBufferLike
9321     */
9322    public subarray(begin: number): BigInt64Array {
9323        return this.subarray(begin as int, this.lengthInt)
9324    }
9325
9326    /**
9327     * Creates a BigInt64Array with the same ArrayBufferLike
9328     *
9329     * @param begin start index, inclusive
9330     *
9331     * @returns new BigInt64Array with the same ArrayBufferLike
9332     */
9333    public subarray(begin: int): BigInt64Array {
9334        return this.subarray(begin as int, this.lengthInt)
9335    }
9336
9337    /**
9338     * Converts BigInt64Array to a string with respect to locale
9339     *
9340     * @param locales
9341     *
9342     * @param options
9343     *
9344     * @returns string representation
9345     */
9346    public toLocaleString(locales: Object, options: Object): string {
9347        throw new Error("BigInt64Array.toLocaleString: not implemented")
9348    }
9349
9350    /**
9351     * Converts BigInt64Array to a string with respect to locale
9352     *
9353     * @param locales
9354     *
9355     * @returns string representation
9356     */
9357    public toLocaleString(locales: Object): string {
9358        return this.toLocaleString(new Object(), new Object())
9359    }
9360
9361    /**
9362     * Converts BigInt64Array to a string with respect to locale
9363     *
9364     * @returns string representation
9365     */
9366    public toLocaleString(): string {
9367        let res: StringBuilder = new StringBuilder("")
9368        for (let i = 0; i < this.lengthInt - 1; ++i) {
9369            res.append(new BigInt(this.getUnsafe(i)).toLocaleString())
9370            res.append(",")
9371        }
9372        if (this.lengthInt > 0) {
9373            res.append(new BigInt(this.getUnsafe(this.lengthInt - 1)).toLocaleString())
9374        }
9375        return res.toString()
9376    }
9377
9378    /**
9379     * Creates a reversed copy
9380     *
9381     * @returns a reversed copy
9382     */
9383    public toReversed(): BigInt64Array {
9384        return new BigInt64Array(this).reverse()
9385    }
9386
9387    /**
9388     * Creates a sorted copy
9389     *
9390     * @returns a sorted copy
9391     */
9392    public toSorted(): BigInt64Array {
9393        return new BigInt64Array(this).sort()
9394    }
9395
9396    /**
9397     * Returns a string representation of the BigInt64Array
9398     *
9399     * @returns a string representation of the BigInt64Array
9400     */
9401    public override toString(): string {
9402        return this.join(",")
9403    }
9404
9405    /**
9406     * Returns array values iterator
9407     *
9408     * @returns an iterator
9409     */
9410    public values(): IterableIterator<BigInt> {
9411        return new BigInt64ArrayIterator(this)
9412    }
9413
9414    /**
9415     * Iteratorable interface implementation
9416     *
9417     * @returns iterator over all elements
9418     */
9419    public override $_iterator(): IterableIterator<BigInt> {
9420        return this.values()
9421    }
9422
9423    /**
9424     * Creates a copy with replaced value on index
9425     *
9426     * @param index
9427     *
9428     * @param value
9429     *
9430     * @returns an BigInt64Array with replaced value on index
9431     */
9432    public with(index: number, value: BigInt): BigInt64Array {
9433        return this.with(index as int, value.getLong())
9434    }
9435
9436    /**
9437     * Creates a copy with replaced value on index
9438     *
9439     * @param index
9440     *
9441     * @param value
9442     *
9443     * @returns an BigInt64Array with replaced value on index
9444     */
9445    public with(index: int, value: long): BigInt64Array {
9446        let res = new BigInt64Array(this)
9447        res.set(index, value)
9448        return res
9449    }
9450
9451    /// === with element lambda functions ===
9452    /**
9453     * Determines whether the specified callback function returns true for all elements of an array.
9454     *
9455     * @param predicate A function that accepts one argument.
9456     * The every method calls the predicate function for each element in the array until the predicate returns a false,
9457     * or until the end of the array.
9458     *
9459     * @returns true unless predicate function returns a false for an array element,
9460     * in which case false is immediately returned.
9461     */
9462    public every(predicate: (element: BigInt) => boolean): boolean {
9463        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element))
9464    }
9465
9466    /**
9467     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
9468     *
9469     * @param fn the condition to apply for each element
9470     *
9471     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
9472     */
9473    public filter(fn: (val: BigInt) => boolean): BigInt64Array {
9474        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9475            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9476        return this.filter(newF)
9477    }
9478
9479    /**
9480     * Returns the value of the first element in the array where predicate is true, and undefined
9481     * otherwise
9482     *
9483     * @param predicate find calls predicate once for each element of the array, in ascending
9484     * order, until it finds one where predicate returns true. If such an element is found, find
9485     * immediately returns that element value. Otherwise, find returns undefined
9486     *
9487     * @returns BigInt | undefined
9488     */
9489    public find(predicate: () => boolean): BigInt | undefined {
9490        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate())
9491    }
9492
9493    /**
9494     * Returns the value of the first element in the array where predicate is true, and undefined
9495     * otherwise
9496     *
9497     * @param predicate find calls predicate once for each element of the array, in ascending
9498     * order, until it finds one where predicate returns true. If such an element is found, find
9499     * immediately returns that element value. Otherwise, find returns undefined
9500     *
9501     * @returns BigInt | undefined
9502     */
9503    public find(predicate: (value: BigInt) => boolean): BigInt | undefined {
9504        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value))
9505    }
9506
9507    /**
9508     * Returns the index of the first element in the array where predicate is true, and -1
9509     * otherwise
9510     *
9511     * @param predicate find calls predicate once for each element of the array, in ascending
9512     * order, until it finds one where predicate returns true. If such an element is found,
9513     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
9514     *
9515     * @returns number
9516     */
9517    public findIndex(predicate: (value: BigInt) => boolean): number {
9518        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value)) as number
9519    }
9520
9521    /**
9522     * Finds the last element in the BigInt64Array that satisfies the condition
9523     *
9524     * @param fn condition
9525     *
9526     * @returns the last element that satisfies fn
9527     */
9528    public findLast(fn: (val: BigInt) => boolean): BigInt {
9529        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9530            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9531        return new BigInt(this.findLast(newF))
9532    }
9533
9534    /**
9535     * Finds an index of the last element in the BigInt64Array that satisfies the condition
9536     *
9537     * @param fn condition
9538     *
9539     * @returns the index of the last element that satisfies fn, -1 otherwise
9540     */
9541    public findLastIndex(fn: (val: BigInt) => boolean): number {
9542        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9543            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9544        return this.findLastIndex(newF) as number
9545    }
9546
9547    /**
9548     * Performs the specified action for each element in BigInt64Array
9549     *
9550     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
9551     * callbackfn function one time for each element in the array.
9552     *
9553     * @returns None
9554     */
9555    public forEach(callbackfn: (value: BigInt) => void): void {
9556        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn(value))
9557    }
9558
9559    /**
9560     * Determines whether the specified callback function returns true for any element of an array.
9561     *
9562     * @param predicate A function that accepts one argument.
9563     * The some method calls the predicate function for each element in the array
9564     * until the predicate returns a true or until the end of the array.
9565     *
9566     * @returns false unless predicate function returns true for an array element,
9567     * in which case true is immediately returned.
9568     */
9569    public some(predicate: (element: BigInt) => boolean): boolean {
9570        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element))
9571    }
9572
9573    // NOTE (kprokopenko): this may be not skipped
9574    /**
9575     * Sorts in-place
9576     *
9577     * @param compareFn comparator —  used to determine the order of the elements.
9578     * compareFn returns a negative value if first argument is less than second argument,
9579     * zero if they're equal and a positive value otherwise.
9580     * If omitted, the elements are sorted in ascending order.
9581     *
9582     * @returns sorted BigInt64Array
9583     */
9584    public sort(compareFn?: (a: BigInt, b: BigInt) => number): this {
9585        let arr: long[] = new long[this.lengthInt]
9586        for (let i = 0; i < this.lengthInt; ++i) {
9587            arr[i] = this.getUnsafe(i)
9588        }
9589        let cmp = (l: long, r: long): number => {
9590                return (l - r) as number
9591            }
9592        if (compareFn != undefined) {
9593            cmp = (l: long, r: long): number => {
9594                return compareFn!(new BigInt(l), new BigInt(r))
9595            }
9596        }
9597        sort(arr, cmp)
9598        for (let i = 0; i < this.lengthInt; ++i) {
9599            this.setUnsafe(i, arr[i])
9600        }
9601        return this
9602    }
9603
9604    /**
9605     * Sorts in-place
9606     *
9607     * @param compareFn comparator —  used to determine the order of the elements.
9608     * compareFn returns a negative value if first argument is less than second argument,
9609     * zero if they're equal and a positive value otherwise.
9610     *
9611     * @returns sorted BigInt64Array
9612     */
9613    public sort(compareFn: (a: BigInt) => number): this {
9614        let cmp = (a: BigInt, b: BigInt) => { return compareFn(a)}
9615        this.sort(cmp)
9616        return this
9617    }
9618
9619    /**
9620     * Sorts in-place
9621     *
9622     * @param fn compareFn —  used to determine the order of the elements.
9623     * compareFn returns a negative value if first argument is less than second argument,
9624     * zero if they're equal and a positive value otherwise.
9625     *
9626     * @returns sorted BigInt64Array
9627     */
9628    public sort(compareFn: () => number): this {
9629        let cmp = (a: BigInt, b: BigInt) => { return compareFn()}
9630        this.sort(cmp)
9631        return this
9632    }
9633
9634    /**
9635     * Determines whether the specified callback function returns true for any element of an array.
9636     *
9637     * @param predicate A function that accepts three arguments.
9638     * The some method calls the predicate function for each element in the array
9639     * until the predicate returns a true or until the end of the array.
9640     *
9641     * @returns false unless predicate function returns true for an array element,
9642     * in which case true is immediately returned.
9643     */
9644    public some(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
9645        for (let i = 0; i < this.lengthInt; ++i) {
9646            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
9647                return true
9648            }
9649        }
9650        return false
9651    }
9652
9653    /**
9654     * Determines whether the specified callback function returns true for any element of an array.
9655     *
9656     * @param predicate A function that accepts two arguments.
9657     * The some method calls the predicate function for each element in the array
9658     * until the predicate returns a true or until the end of the array.
9659     *
9660     * @returns false unless predicate function returns true for an array element,
9661     * in which case true is immediately returned.
9662     */
9663    public some(predicate: (element: BigInt, index: number) => boolean): boolean {
9664        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element, index as number))
9665    }
9666
9667    /**
9668     * Determines whether the specified callback function returns true for any element of an array.
9669     *
9670     * @param predicate A function that accepts no arguments.
9671     * The some method calls the predicate function for each element in the array
9672     * until the predicate returns a true or until the end of the array.
9673     *
9674     * @returns false unless predicate function returns true for an array element,
9675     * in which case true is immediately returned.
9676     */
9677    public some(predicate: () => boolean): boolean {
9678        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate())
9679    }
9680
9681    /**
9682     * Calls the specified callback function for all the elements in an array.
9683     * The return value of the callback function is the accumulated result,
9684     * and is provided as an argument in the next call to the callback function.
9685     *
9686     * @param callbackfn A function that accepts four arguments.
9687     * The reduce method calls the callbackfn function one time for each element in the array.
9688     *
9689     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9690     * The first call to the callbackfn function provides this value as an argument.
9691     *
9692     * @returns The value that results from running the callback function to completion over the entire typed array.
9693     */
9694    public reduce<U = BigInt>(
9695                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
9696                initialValue: U): U {
9697        let accumulatedValue = initialValue
9698        for (let i = 0; i < this.lengthInt; ++i) {
9699            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9700        }
9701        return accumulatedValue
9702    }
9703
9704    /**
9705     * Calls the specified callback function for all the elements in an array.
9706     * The return value of the callback function is the accumulated result,
9707     * and is provided as an argument in the next call to the callback function.
9708     *
9709     * @param callbackfn A function that accepts three arguments.
9710     * The reduce method calls the callbackfn function one time for each element in the array.
9711     *
9712     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9713     * The first call to the callbackfn function provides this value as an argument.
9714     *
9715     * @returns The value that results from running the callback function to completion over the entire typed array.
9716     */
9717    public reduce<U = BigInt>(
9718                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number) => U,
9719                initialValue: U): U {
9720        return this.reduce(
9721                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9722                        callbackfn(prevVal, currVal, currIndex), initialValue)
9723    }
9724
9725    /**
9726     * Calls the specified callback function for all the elements in an array.
9727     * The return value of the callback function is the accumulated result,
9728     * and is provided as an argument in the next call to the callback function.
9729     *
9730     * @param callbackfn A function that accepts two arguments.
9731     * The reduce method calls the callbackfn function one time for each element in the array.
9732     *
9733     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9734     * The first call to the callbackfn function provides this value as an argument.
9735     *
9736     * @returns The value that results from running the callback function to completion over the entire typed array.
9737     */
9738    public reduce<U = BigInt>(
9739                callbackfn: (previousValue: U, currentValue: BigInt) => U,
9740                initialValue: U): U {
9741        return this.reduce(
9742                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9743                        callbackfn(prevVal, currVal), initialValue)
9744    }
9745
9746    /**
9747     * Calls the specified callback function for all the elements in an array.
9748     * The return value of the callback function is the accumulated result,
9749     * and is provided as an argument in the next call to the callback function.
9750     *
9751     * @param callbackfn A function that accepts one argument
9752     * The reduce method calls the callbackfn function one time for each element in the array.
9753     *
9754     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9755     * The first call to the callbackfn function provides this value as an argument.
9756     *
9757     * @returns The value that results from running the callback function to completion over the entire typed array.
9758     */
9759    public reduce<U = BigInt>(
9760                callbackfn: (previousValue: U) => U,
9761                initialValue: U): U {
9762        return this.reduce(
9763                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9764                        callbackfn(prevVal), initialValue)
9765    }
9766
9767    /**
9768     * Calls the specified callback function for all the elements in an array.
9769     * The return value of the callback function is the accumulated result,
9770     * and is provided as an argument in the next call to the callback function.
9771     *
9772     * @param callbackfn A function that accepts no arguments
9773     * The reduce method calls the callbackfn function one time for each element in the array.
9774     *
9775     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9776     * The first call to the callbackfn function provides this value as an argument.
9777     *
9778     * @returns The value that results from running the callback function to completion over the entire typed array.
9779     */
9780    public reduce<U = BigInt>(
9781                callbackfn: () => U,
9782                initialValue: U): U {
9783        return this.reduce(
9784                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9785                        callbackfn(), initialValue)
9786    }
9787
9788    /**
9789     * Calls the specified callback function for all the elements in an array.
9790     * The return value of the callback function is the accumulated result,
9791     * and is provided as an argument in the next call to the callback function.
9792     *
9793     * @param callbackfn A function that accepts four arguments.
9794     * The reduce method calls the callbackfn function one time for each element in the array.
9795     * The first call to the callbackfn function provides array first element value as an argument
9796     *
9797     * @returns The value that results from running the callback function to completion over the entire typed array.
9798     * calling reduce method on an empty array without an initial value creates a TypeError
9799     */
9800    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
9801        if (this.lengthInt == 0) {
9802            throw new TypeError("Reduce of empty array with no initial value")
9803        }
9804
9805        let accumulatedValue = new BigInt(this.getUnsafe(0))
9806        for (let i = 1; i < this.lengthInt; ++i) {
9807            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9808        }
9809        return accumulatedValue
9810    }
9811
9812    /**
9813     * Calls the specified callback function for all the elements in an array.
9814     * The return value of the callback function is the accumulated result,
9815     * and is provided as an argument in the next call to the callback function.
9816     *
9817     * @param callbackfn A function that accepts three arguments.
9818     * The reduce method calls the callbackfn function one time for each element in the array.
9819     * The first call to the callbackfn function provides array first element value as an argument
9820     *
9821     * @returns The value that results from running the callback function to completion over the entire typed array.
9822     * calling reduce method on an empty array without an initial value creates a TypeError
9823     */
9824    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number) => BigInt): BigInt {
9825        return this.reduce(
9826                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9827                        callbackfn(prevVal, currVal, currIndex))
9828    }
9829
9830    /**
9831     * Calls the specified callback function for all the elements in an array.
9832     * The return value of the callback function is the accumulated result,
9833     * and is provided as an argument in the next call to the callback function.
9834     *
9835     * @param callbackfn A function that accepts two arguments.
9836     * The reduce method calls the callbackfn function one time for each element in the array.
9837     * The first call to the callbackfn function provides array first element value as an argument
9838     *
9839     * @returns The value that results from running the callback function to completion over the entire typed array.
9840     * calling reduce method on an empty array without an initial value creates a TypeError
9841     */
9842    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt) => BigInt): BigInt {
9843        return this.reduce(
9844                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9845                        callbackfn(prevVal, currVal))
9846    }
9847
9848    /**
9849     * Calls the specified callback function for all the elements in an array.
9850     * The return value of the callback function is the accumulated result,
9851     * and is provided as an argument in the next call to the callback function.
9852     *
9853     * @param callbackfn A function that accepts one argument.
9854     * The reduce method calls the callbackfn function one time for each element in the array.
9855     * The first call to the callbackfn function provides array first element value as an argument
9856     *
9857     * @returns The value that results from running the callback function to completion over the entire typed array.
9858     * calling reduce method on an empty array without an initial value creates a TypeError
9859     */
9860    public reduce(callbackfn: (previousValue: BigInt) => BigInt): BigInt {
9861        return this.reduce(
9862                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9863                        callbackfn(prevVal))
9864    }
9865
9866    /**
9867     * Calls the specified callback function for all the elements in an array.
9868     * The return value of the callback function is the accumulated result,
9869     * and is provided as an argument in the next call to the callback function.
9870     *
9871     * @param callbackfn A function that accepts no arguments.
9872     * The reduce method calls the callbackfn function one time for each element in the array.
9873     * The first call to the callbackfn function provides array first element value as an argument
9874     *
9875     * @returns The value that results from running the callback function to completion over the entire typed array.
9876     * calling reduce method on an empty array without an initial value creates a TypeError
9877     */
9878    public reduce(callbackfn: () => BigInt): BigInt {
9879        return this.reduce(
9880                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9881                        callbackfn())
9882    }
9883
9884
9885    /**
9886     * Calls the specified callback function for all the elements in an array, in descending order.
9887     * The return value of the callback function is the accumulated result,
9888     * and is provided as an argument in the next call to the callback function.
9889     *
9890     * @param callbackfn A function that accepts four arguments.
9891     * The reduceRight method calls the callbackfn function one time for each element in the array.
9892     *
9893     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9894     * The first call to the callbackfn function provides this value as an argument.
9895     *
9896     * @returns The value that results from running the callback function to completion over the entire typed array.
9897     */
9898    public reduceRight<U = BigInt>(
9899                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
9900                initialValue: U): U {
9901        let accumulatedValue = initialValue
9902        for (let i = this.lengthInt - 1; i >= 0; --i) {
9903            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9904        }
9905        return accumulatedValue
9906    }
9907
9908    /**
9909     * Calls the specified callback function for all the elements in an array, in descending order.
9910     * The return value of the callback function is the accumulated result,
9911     * and is provided as an argument in the next call to the callback function.
9912     *
9913     * @param callbackfn A function that accepts three arguments.
9914     * The reduceRight method calls the callbackfn function one time for each element in the array.
9915     *
9916     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9917     * The first call to the callbackfn function provides this value as an argument.
9918     *
9919     * @returns The value that results from running the callback function to completion over the entire typed array.
9920     */
9921    public reduceRight<U = BigInt>(
9922                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number) => U,
9923                initialValue: U): U {
9924        return this.reduceRight(
9925                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9926                        callbackfn(prevVal, currVal, currIndex), initialValue)
9927    }
9928
9929    /**
9930     * Calls the specified callback function for all the elements in an array, in descending order.
9931     * The return value of the callback function is the accumulated result,
9932     * and is provided as an argument in the next call to the callback function.
9933     *
9934     * @param callbackfn A function that accepts two arguments.
9935     * The reduceRight method calls the callbackfn function one time for each element in the array.
9936     *
9937     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9938     * The first call to the callbackfn function provides this value as an argument.
9939     *
9940     * @returns The value that results from running the callback function to completion over the entire typed array.
9941     */
9942    public reduceRight<U = BigInt>(
9943                callbackfn: (previousValue: U, currentValue: BigInt) => U,
9944                initialValue: U): U {
9945        return this.reduceRight(
9946                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9947                        callbackfn(prevVal, currVal), initialValue)
9948    }
9949
9950    /**
9951     * Calls the specified callback function for all the elements in an array, in descending order.
9952     * The return value of the callback function is the accumulated result,
9953     * and is provided as an argument in the next call to the callback function.
9954     *
9955     * @param callbackfn A function that accepts one argument.
9956     * The reduceRight method calls the callbackfn function one time for each element in the array.
9957     *
9958     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9959     * The first call to the callbackfn function provides this value as an argument.
9960     *
9961     * @returns The value that results from running the callback function to completion over the entire typed array.
9962     */
9963    public reduceRight<U = BigInt>(
9964                callbackfn: (previousValue: U) => U,
9965                initialValue: U): U {
9966        return this.reduceRight(
9967                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9968                        callbackfn(prevVal), initialValue)
9969    }
9970
9971    /**
9972     * Calls the specified callback function for all the elements in an array, in descending order.
9973     * The return value of the callback function is the accumulated result,
9974     * and is provided as an argument in the next call to the callback function.
9975     *
9976     * @param callbackfn A function that accepts no arguments.
9977     * The reduceRight method calls the callbackfn function one time for each element in the array.
9978     *
9979     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9980     * The first call to the callbackfn function provides this value as an argument.
9981     *
9982     * @returns The value that results from running the callback function to completion over the entire typed array.
9983     */
9984    public reduceRight<U = BigInt>(
9985                callbackfn: () => U,
9986                initialValue: U): U {
9987        return this.reduceRight(
9988                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9989                        callbackfn(), initialValue)
9990    }
9991
9992    /**
9993     * Calls the specified callback function for all the elements in an array, in descending order.
9994     * The return value of the callback function is the accumulated result,
9995     * and is provided as an argument in the next call to the callback function.
9996     *
9997     * @param callbackfn A function that accepts four arguments.
9998     * The reduceRight method calls the callbackfn function one time for each element in the array.
9999     * The first call to the callbackfn function provides array last element value as an argument
10000     *
10001     * @returns The value that results from running the callback function to completion over the entire typed array.
10002     * calling reduceRight method on an empty array without an initial value creates a TypeError
10003     */
10004    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
10005        if (this.lengthInt == 0) {
10006            throw new TypeError("Reduce of empty array with no initial value")
10007        }
10008
10009        let accumulatedValue: BigInt = new BigInt(this.getUnsafe(this.lengthInt - 1))
10010        for (let i = this.lengthInt - 2; i >= 0; --i) {
10011            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
10012        }
10013        return accumulatedValue
10014    }
10015
10016    /**
10017     * Calls the specified callback function for all the elements in an array, in descending order.
10018     * The return value of the callback function is the accumulated result,
10019     * and is provided as an argument in the next call to the callback function.
10020     *
10021     * @param callbackfn A function that accepts three arguments.
10022     * The reduceRight method calls the callbackfn function one time for each element in the array.
10023     * The first call to the callbackfn function provides array last element value as an argument
10024     *
10025     * @returns The value that results from running the callback function to completion over the entire typed array.
10026     * calling reduceRight method on an empty array without an initial value creates a TypeError
10027     */
10028    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number) => BigInt): BigInt {
10029        return this.reduceRight(
10030                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
10031                        callbackfn(prevValue, currValue, currIndex))
10032    }
10033
10034    /**
10035     * Calls the specified callback function for all the elements in an array, in descending order.
10036     * The return value of the callback function is the accumulated result,
10037     * and is provided as an argument in the next call to the callback function.
10038     *
10039     * @param callbackfn A function that accepts two arguments.
10040     * The reduceRight method calls the callbackfn function one time for each element in the array.
10041     * The first call to the callbackfn function provides array last element value as an argument
10042     *
10043     * @returns The value that results from running the callback function to completion over the entire typed array.
10044     * calling reduceRight method on an empty array without an initial value creates a TypeError
10045     */
10046    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt) => BigInt): BigInt {
10047        return this.reduceRight(
10048                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
10049                        callbackfn(prevValue, currValue))
10050    }
10051
10052    /**
10053     * Calls the specified callback function for all the elements in an array, in descending order.
10054     * The return value of the callback function is the accumulated result,
10055     * and is provided as an argument in the next call to the callback function.
10056     *
10057     * @param callbackfn A function that accepts one argument.
10058     * The reduceRight method calls the callbackfn function one time for each element in the array.
10059     * The first call to the callbackfn function provides array last element value as an argument
10060     *
10061     * @returns The value that results from running the callback function to completion over the entire typed array.
10062     * calling reduceRight method on an empty array without an initial value creates a TypeError
10063     */
10064    public reduceRight(callbackfn: (previousValue: BigInt) => BigInt): BigInt {
10065        return this.reduceRight(
10066                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
10067                        callbackfn(prevValue))
10068    }
10069
10070    /**
10071     * Calls the specified callback function for all the elements in an array, in descending order.
10072     * The return value of the callback function is the accumulated result,
10073     * and is provided as an argument in the next call to the callback function.
10074     *
10075     * @param callbackfn A function that accepts no arguments.
10076     * The reduceRight method calls the callbackfn function one time for each element in the array.
10077     * The first call to the callbackfn function provides array last element value as an argument
10078     *
10079     * @returns The value that results from running the callback function to completion over the entire typed array.
10080     * calling reduceRight method on an empty array without an initial value creates a TypeError
10081     */
10082    public reduceRight(callbackfn: () => BigInt): BigInt {
10083        return this.reduceRight(
10084                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
10085                        callbackfn())
10086    }
10087
10088   /**
10089    * Creates a new BigInt64Array using fn(arr[i]) over all elements of current BigInt64Array.
10090    *
10091    * @param fn a function to apply for each element of current BigInt64Array
10092    *
10093    * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
10094    */
10095    public map(fn: (val: BigInt, index: number, array: BigInt64Array) => BigInt): BigInt64Array {
10096        let resBuf = new ArrayBuffer(this.lengthInt * BigInt64Array.BYTES_PER_ELEMENT as int)
10097        let res = new BigInt64Array(resBuf, 0, resBuf.getByteLength() / BigInt64Array.BYTES_PER_ELEMENT as int)
10098        for (let i = 0; i < this.lengthInt; ++i) {
10099            res.set(i, fn(new BigInt(this.getUnsafe(i)), i as number, this).getLong())
10100        }
10101        return res
10102    }
10103
10104    /**
10105     * Creates a new BigInt64Array using fn(arr[i], i) over all elements of current BigInt64Array
10106     *
10107     * @param fn a function to apply for each element of current BigInt64Array
10108     *
10109     * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
10110     */
10111    public map(fn: (val: BigInt, index: number) => BigInt): BigInt64Array {
10112        let newF: (val: BigInt, index: number, array: BigInt64Array) => BigInt =
10113            (val: BigInt, index: number, array: BigInt64Array): BigInt => { return fn(val, index) }
10114        return this.map(newF)
10115    }
10116
10117    /**
10118     * Creates a new BigInt64Array using fn(arr[i]) over all elements of current BigInt64Array
10119     *
10120     * @param fn a function to apply for each element of current BigInt64Array
10121     *
10122     * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
10123     */
10124    public map(fn: (val: BigInt) => BigInt): BigInt64Array {
10125        let newF: (val: BigInt, index: number, array: BigInt64Array) => BigInt =
10126            (val: BigInt, index: number, array: BigInt64Array): BigInt => { return fn(val) }
10127        return this.map(newF)
10128    }
10129
10130    /**
10131     * Creates a new BigInt64Array using fn() over all elements of current BigInt64Array
10132     *
10133     * @param fn a function to apply for each element of current BigInt64Array
10134     *
10135     * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
10136     */
10137    public map(fn: () => BigInt): BigInt64Array {
10138        let newF: (val: BigInt, index: number, array: BigInt64Array) => BigInt =
10139            (val: BigInt, index: number, array: BigInt64Array): BigInt => { return fn() }
10140        return this.map(newF)
10141    }
10142
10143
10144    /**
10145     * Determines whether the specified callback function returns true for all elements of an array.
10146     *
10147     * @param predicate A function that accepts three arguments.
10148     * The every method calls the predicate function for each element in the array until the predicate returns a false,
10149     * or until the end of the array.
10150     *
10151     * @returns true unless predicate function returns a false for an array element,
10152     * in which case false is immediately returned.
10153     */
10154    public every(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
10155        for (let i = 0; i < this.lengthInt; ++i) {
10156            if (!predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
10157                return false
10158            }
10159        }
10160        return true
10161    }
10162
10163    /**
10164     * Determines whether the specified callback function returns true for all elements of an array.
10165     *
10166     * @param predicate A function that accepts two arguments.
10167     * The every method calls the predicate function for each element in the array until the predicate returns a false,
10168     * or until the end of the array.
10169     *
10170     * @returns true unless predicate function returns a false for an array element,
10171     * in which case false is immediately returned.
10172     */
10173    public every(predicate: (element: BigInt, index: number) => boolean): boolean {
10174        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element, index))
10175    }
10176
10177    /**
10178     * Determines whether the specified callback function returns true for all elements of an array.
10179     *
10180     * @param predicate A function that accepts no arguments.
10181     * The every method calls the predicate function for each element in the array until the predicate returns a false,
10182     * or until the end of the array.
10183     *
10184     * @returns true unless predicate function returns a false for an array element,
10185     * in which case false is immediately returned.
10186     */
10187    public every(predicate: () => boolean): boolean {
10188        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate())
10189    }
10190
10191    /**
10192     * Creates a new BigInt64Array from current BigInt64Array based on a condition fn.
10193     *
10194     * @param fn the condition to apply for each element
10195     *
10196     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
10197     */
10198    public filter(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): BigInt64Array {
10199        let markers = new boolean[this.lengthInt]
10200        let resLen = 0
10201        for (let i = 0; i < this.lengthInt; ++i) {
10202            markers[i] = fn(new BigInt(this.getUnsafe(i)), i as number, this)
10203            if (markers[i]) {
10204                ++resLen
10205            }
10206        }
10207        let resBuf = new ArrayBuffer(resLen * BigInt64Array.BYTES_PER_ELEMENT as int)
10208        let res = new BigInt64Array(resBuf, 0)
10209        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
10210            if (markers[i]) {
10211                res.set(j, this.getUnsafe(i))
10212                ++j
10213            }
10214        }
10215        return res
10216    }
10217
10218    /**
10219     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
10220     *
10221     * @param fn the condition to apply for each element
10222     *
10223     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
10224     */
10225    public filter(fn: (val: BigInt, index: number) => boolean): BigInt64Array {
10226        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10227            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val, index as number) }
10228        return this.filter(newF)
10229    }
10230
10231    /**
10232     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
10233     *
10234     * @param fn the condition to apply for each element
10235     *
10236     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
10237     */
10238    public filter(fn: () => boolean): BigInt64Array {
10239        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10240            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn() }
10241        return this.filter(newF)
10242    }
10243
10244    /**
10245     * Returns the value of the first element in the array where predicate is true, and undefined
10246     * otherwise
10247     *
10248     * @param predicate find calls predicate once for each element of the array, in ascending
10249     * order, until it finds one where predicate returns true. If such an element is found, find
10250     * immediately returns that element value. Otherwise, find returns undefined
10251     *
10252     * @returns BigInt | undefined
10253     */
10254    public find(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): BigInt | undefined {
10255        for (let i = 0; i < this.lengthInt; ++i) {
10256            let val = this.getUnsafe(i)
10257            if (predicate(new BigInt(val), i as number, this)) {
10258                return new BigInt(val)
10259            }
10260        }
10261        return undefined
10262    }
10263
10264    /**
10265     * Returns the value of the first element in the array where predicate is true, and undefined
10266     * otherwise
10267     *
10268     * @param predicate find calls predicate once for each element of the array, in ascending
10269     * order, until it finds one where predicate returns true. If such an element is found, find
10270     * immediately returns that element value. Otherwise, find returns undefined
10271     *
10272     * @returns BigInt | undefined
10273     */
10274    public find(predicate: (value: BigInt, index: number) => boolean): BigInt | undefined {
10275        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value, index))
10276    }
10277
10278    /**
10279     * Returns the index of the first element in the array where predicate is true, and -1
10280     * otherwise
10281     *
10282     * @param predicate find calls predicate once for each element of the array, in ascending
10283     * order, until it finds one where predicate returns true. If such an element is found,
10284     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10285     *
10286     * @returns number
10287     */
10288    public findIndex(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): number {
10289        for (let i = 0; i < this.lengthInt; ++i) {
10290            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
10291                return i as number
10292            }
10293        }
10294        return -1 as number
10295    }
10296
10297    /**
10298     * Returns the index of the first element in the array where predicate is true, and -1
10299     * otherwise
10300     *
10301     * @param predicate find calls predicate once for each element of the array, in ascending
10302     * order, until it finds one where predicate returns true. If such an element is found,
10303     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10304     *
10305     * @returns number
10306     */
10307    public findIndex(predicate: (value: BigInt, index: number) => boolean): number {
10308        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value, index as number)) as number
10309    }
10310
10311    /**
10312     * Returns the index of the first element in the array where predicate is true, and -1
10313     * otherwise
10314     *
10315     * @param predicate find calls predicate once for each element of the array, in ascending
10316     * order, until it finds one where predicate returns true. If such an element is found,
10317     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10318     *
10319     * @returns number
10320     */
10321    public findIndex(predicate: () => boolean): number {
10322        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate()) as number
10323    }
10324
10325    /**
10326     * Finds the last element in the BigInt64Array that satisfies the condition
10327     *
10328     * @param fn condition
10329     *
10330     * @returns the last element that satisfies fn
10331     */
10332    public findLast(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): long {
10333        for (let i = this.lengthInt - 1; i >= 0; --i) {
10334            let val = this.getUnsafe(i)
10335            if (fn(new BigInt(val), i as number, this)) {
10336                return val
10337            }
10338        }
10339        throw new Error("BigInt64Array.findLast: not implemented if an element was not found")
10340    }
10341
10342    /**
10343     * Finds the last element in the BigInt64Array that satisfies the condition
10344     *
10345     * @param fn condition
10346     *
10347     * @returns the last element that satisfies fn
10348     */
10349    public findLast(fn: (val: BigInt, index: number) => boolean): long {
10350        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10351            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(new BigInt(val), index as number) }
10352        return this.findLast(newF)
10353    }
10354
10355    /**
10356     * Finds an index of the last element in the BigInt64Array that satisfies the condition
10357     *
10358     * @param fn condition
10359     *
10360     * @returns the index of the last element that satisfies fn, -1 otherwise
10361     */
10362    public findLastIndex(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): number {
10363        for (let i = this.lengthInt - 1; i >= 0; --i) {
10364            let val = this.getUnsafe(i)
10365            if (fn(new BigInt(val), i as number, this)) {
10366                return i
10367            }
10368        }
10369        return -1 as number
10370    }
10371
10372    /**
10373     * Finds an index of the last element in the BigInt64Array that satisfies the condition
10374     *
10375     * @param fn condition
10376     *
10377     * @returns the index of the last element that satisfies fn, -1 otherwise
10378     */
10379    public findLastIndex(fn: (val: BigInt, index: number) => boolean): number {
10380        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10381            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val, index as number) }
10382        return this.findLastIndex(newF) as number
10383    }
10384
10385    /**
10386     * Performs the specified action for each element in BigInt64Array
10387     *
10388     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10389     * callbackfn function one time for each element in the array.
10390     *
10391     * @returns None
10392     */
10393    public forEach(callbackfn: (value: BigInt, index: number, array: BigInt64Array) => void): void {
10394        for (let i = 0; i < this.lengthInt; ++i) {
10395            callbackfn(new BigInt(this.getUnsafe(i)), i as number, this)
10396        }
10397    }
10398
10399    /**
10400     * Performs the specified action for each element in BigInt64Array
10401     *
10402     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10403     * callbackfn function one time for each element in the array.
10404     *
10405     * @returns None
10406     */
10407    public forEach(callbackfn: (value: BigInt, index: number) => void): void {
10408        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn(value, index))
10409    }
10410
10411    /**
10412     * Performs the specified action for each element in BigInt64Array
10413     *
10414     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10415     * callbackfn function one time for each element in the array.
10416     *
10417     * @returns None
10418     */
10419    public forEach(callbackfn: () => void): void {
10420        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn())
10421    }
10422
10423    /**
10424     * Returns the object itself
10425     *
10426     * @returns BigInt64Array
10427     */
10428    public valueOf(): BigInt64Array {
10429        return this
10430    }
10431
10432    internal getUnsafe(index: int): long {
10433        let byteIndex = index * BigInt64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
10434        let res : long = 0
10435        let byteVal : long
10436        if (IS_LITTLE_ENDIAN) {
10437            if (this.buffer instanceof ArrayBuffer) {
10438                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10439                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
10440                    byteVal &= 0xff
10441                    res = (res | byteVal << (8 * i)) as long
10442                }
10443            } else if (this.buffer instanceof SharedArrayBuffer) {
10444                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10445                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
10446                    byteVal &= 0xff
10447                    res = (res | byteVal << (8 * i)) as long
10448                }
10449            } else {
10450                throw new Error("unexpected type of ArrayBufferLike")
10451            }
10452            return res
10453        } else {
10454            if (this.buffer instanceof ArrayBuffer) {
10455                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10456                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 7 - i)
10457                    byteVal &= 0xff
10458                    res = (res | byteVal << (8 * i)) as long
10459                }
10460            } else if (this.buffer instanceof SharedArrayBuffer) {
10461                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10462                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 7 - i)
10463                    byteVal &= 0xff
10464                    res = (res | byteVal << (8 * i)) as long
10465                }
10466            } else {
10467                throw new Error("unexpected type of ArrayBufferLike")
10468            }
10469            return res
10470        }
10471    }
10472
10473    internal setUnsafe(insertPos: int, val: long): void {
10474        let startByte = insertPos * BigInt64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
10475        let bits = val
10476        if (IS_LITTLE_ENDIAN) {
10477            if (this.buffer instanceof ArrayBuffer) {
10478                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10479                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10480                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
10481                }
10482            } else if (this.buffer instanceof SharedArrayBuffer) {
10483                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10484                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10485                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
10486                }
10487            } else {
10488                throw new Error("unexpected type of ArrayBufferLike")
10489            }
10490        } else {
10491            if (this.buffer instanceof ArrayBuffer) {
10492                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; i++) {
10493                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10494                    (this.buffer as ArrayBuffer).set(startByte + 7 - i, byteVal)
10495                }
10496            } else if (this.buffer instanceof SharedArrayBuffer) {
10497                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; i++) {
10498                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10499                    (this.buffer as SharedArrayBuffer).set(startByte + 7 - i, byteVal)
10500                }
10501            } else {
10502                throw new Error("unexpected type of ArrayBufferLike")
10503            }
10504        }
10505    }
10506
10507    /** Underlying ArrayBufferLike */
10508    public readonly buffer: ArrayBufferLike
10509
10510    /** Byte offset within the underlying ArrayBufferLike */
10511    public readonly byteOffset: number
10512
10513    /** Number of bytes used */
10514    public readonly byteLength: number
10515
10516    /** String \"BigInt64Array\" */
10517    public readonly name = "BigInt64Array"
10518}
10519
10520class Float32ArrayIteratorKeys implements IterableIterator<number> {
10521    private length: int
10522    private idx: int = 0
10523
10524    constructor(parent: Float32Array) {
10525        this.length = parent.length as int
10526    }
10527
10528    public override $_iterator(): IterableIterator<number> {
10529        return this
10530    }
10531
10532    override next(): IteratorResult<number> {
10533        if (this.idx < 0 || this.idx >= this.length) {
10534            return new IteratorResult<number>()
10535        }
10536        return new IteratorResult<number>(false, this.idx++ as number)
10537    }
10538}
10539
10540class Float32ArrayIterator implements IterableIterator<Number> {
10541    private parent: Float32Array
10542    private idx: int = 0
10543
10544    constructor(parent: Float32Array) {
10545        this.parent = parent
10546    }
10547
10548    public override $_iterator(): IterableIterator<Number> {
10549        return this
10550    }
10551
10552    override next(): IteratorResult<Number> {
10553        if (this.idx < 0 || this.idx >= this.parent.length as int) {
10554            return new IteratorResult<Number>()
10555        }
10556        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
10557    }
10558}
10559
10560class Float32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
10561    private parent: Float32Array
10562    private idx: int = 0
10563
10564    constructor(parent: Float32Array) {
10565        this.parent = parent
10566    }
10567
10568    public override $_iterator(): IterableIterator<[Number, Number]> {
10569        return this
10570    }
10571
10572    override next(): IteratorResult<[Number, Number]> {
10573        if (this.idx < 0 || this.idx >= this.parent.length as int) {
10574            return new IteratorResult<[Number, Number]>()
10575        }
10576        return new IteratorResult<[Number, Number]>(
10577            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
10578        )
10579    }
10580}
10581
10582
10583/**
10584 * JS Float32Array API-compatible class
10585 */
10586export final class Float32Array implements Iterable<Number>, ArrayLike<Number> {
10587    public static readonly BYTES_PER_ELEMENT: number = 4
10588    internal readonly lengthInt: int
10589
10590    /**
10591     * Creates an empty Float32Array.
10592     */
10593    public constructor() {
10594        this(0 as int)
10595    }
10596
10597    /**
10598     * Creates an Float32Array with respect to data accessed via Iterable<Number> interface
10599     */
10600    public constructor(elements: Iterable<Number>) {
10601        const items: Object = elements as Object
10602        if (items instanceof ArrayLike) {
10603            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
10604            this.byteLength = arr.length as int * Float32Array.BYTES_PER_ELEMENT as int
10605            this.lengthInt = arr.length as int
10606            this.buffer = new ArrayBuffer(this.byteLength as int)
10607            this.byteOffset = 0
10608            for (let i: int = 0; i < this.lengthInt; ++i) {
10609                this.setUnsafe(i, arr.$_get(i).floatValue())
10610            }
10611        } else {
10612          let x = Float32Array.from(elements)
10613          this.byteLength = x.byteLength
10614          this.lengthInt = x.lengthInt
10615          this.buffer = x.buffer
10616          this.byteOffset = x.byteOffset
10617        }
10618    }
10619
10620    /**
10621     * Creates an Float32Array with respect to data, byteOffset and length.
10622     *
10623     * @param buf data initializer
10624     *
10625     * @param byteOffset byte offset from begin of the buf
10626     *
10627     * @param length size of elements of type float in newly created Float32Array
10628     */
10629    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
10630        let intByteOffset: int = 0
10631        if (byteOffset != undefined) {
10632            intByteOffset = byteOffset.intValue()
10633            if (intByteOffset < 0) {
10634                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
10635            }
10636        }
10637        let intByteLength: int
10638        if (buf instanceof ArrayBuffer) {
10639            intByteLength = (buf as ArrayBuffer).getByteLength()
10640        } else if (buf instanceof SharedArrayBuffer) {
10641            intByteLength = (buf as SharedArrayBuffer).getByteLength()
10642        } else {
10643            throw new Error("unexpected type of ArrayBufferLike")
10644        }
10645        intByteLength = intByteLength - intByteOffset
10646        if (intByteLength < 0) {
10647            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
10648        }
10649
10650        if (intByteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10651            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10652        }
10653        if (intByteOffset % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10654            throw new RangeError("byteOffset should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10655        }
10656
10657        let intLength: int
10658        if (length != undefined) {
10659            intLength = length.intValue()
10660            if (intLength > intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
10661                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
10662            }
10663        } else {
10664            intLength = intByteLength / Float32Array.BYTES_PER_ELEMENT as int
10665        }
10666        if (intLength < 0) {
10667            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
10668        }
10669        if (intLength < intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
10670            intByteLength = intLength * Float32Array.BYTES_PER_ELEMENT as int
10671        }
10672        this.byteLength = intByteLength
10673        this.byteOffset = intByteOffset
10674        this.lengthInt = intLength
10675        this.buffer = buf
10676    }
10677
10678    /**
10679     * Creates an Float32Array with respect to data, byteOffset and length.
10680     *
10681     * @param buf data initializer
10682     *
10683     * @param byteOffset byte offset from begin of the buf
10684     *
10685     * @param length size of elements of type float in newly created Float32Array
10686     */
10687    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
10688        this(buf, byteOffset, undefined)
10689    }
10690
10691    /**
10692     * Creates an Float32Array with respect to data, byteOffset and length.
10693     *
10694     * @param buf data initializer
10695     *
10696     * @param byteOffset byte offset from begin of the buf
10697     *
10698     * @param length size of elements of type float in newly created Float32Array
10699     */
10700    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
10701        this(buf, new Number(byteOffset), new Number(length))
10702    }
10703
10704    /**
10705     * Creates an Float32Array with respect to data, byteOffset and length.
10706     *
10707     * @param buf data initializer
10708     *
10709     * @param byteOffset byte offset from begin of the buf
10710     *
10711     * @param length size of elements of type float in newly created Float32Array
10712     */
10713    public constructor(buf: ArrayBufferLike, byteOffset: number) {
10714        this(buf, new Number(byteOffset), undefined)
10715    }
10716
10717    /**
10718     * Creates an Float32Array with respect to data, byteOffset and length.
10719     *
10720     * @param buf data initializer
10721     *
10722     * @param byteOffset byte offset from begin of the buf
10723     *
10724     * @param length size of elements of type float in newly created Float32Array
10725     */
10726    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
10727        this(buf, new Number(byteOffset), new Number(length))
10728    }
10729
10730    /**
10731     * Creates an Float32Array with respect to buf and byteOffset.
10732     *
10733     * @param buf data initializer
10734     *
10735     * @param byteOffset byte offset from begin of the buf
10736     */
10737    public constructor(buf: ArrayBufferLike, byteOffset: int) {
10738        this(buf, new Number(byteOffset), undefined)
10739    }
10740
10741    /**
10742     * Creates an Float32Array with respect to buf.
10743     *
10744     * @param buf data initializer
10745     */
10746    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
10747        if (buf instanceof ArrayBuffer) {
10748            this.byteLength = (buf as ArrayBuffer).getByteLength()
10749            if (this.byteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10750               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10751            }
10752            this.lengthInt = this.byteLength / Float32Array.BYTES_PER_ELEMENT as int
10753            this.buffer = buf as ArrayBuffer
10754            this.byteOffset = 0
10755        } else if (buf instanceof SharedArrayBuffer) {
10756            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
10757            if (this.byteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10758               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10759            }
10760            this.lengthInt = this.byteLength / Float32Array.BYTES_PER_ELEMENT as int
10761            this.buffer = buf as SharedArrayBuffer
10762            this.byteOffset = 0
10763        } else if (buf instanceof ArrayLike) {
10764            // NOTE (ikorobkov): dealing with this overload is tricky
10765            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
10766            let arr = Array.from<Number>((buf as ArrayLike<Number>))
10767            this.byteLength = arr.length as int * Float32Array.BYTES_PER_ELEMENT as int
10768            this.lengthInt = arr.length as int
10769            this.buffer = new ArrayBuffer(this.byteLength as int)
10770            this.byteOffset = 0
10771            for (let i: int = 0; i < this.lengthInt; ++i) {
10772                this.setUnsafe(i, arr.$_get(i).floatValue())
10773            }
10774        } else {
10775            throw new Error("unexpected type of buf")
10776        }
10777    }
10778
10779    /**
10780     * Creates an Float32Array with respect to length.
10781     *
10782     * @param length data initializer
10783     */
10784    public constructor(length: int) {
10785        if (length < 0) {
10786            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
10787        }
10788        this.lengthInt = length
10789        this.byteLength = length * Float32Array.BYTES_PER_ELEMENT as int
10790        this.byteOffset = 0
10791        this.buffer = new ArrayBuffer(this.byteLength as int)
10792    }
10793
10794    /**
10795     * Creates an Float32Array with respect to length.
10796     *
10797     * @param length data initializer
10798     */
10799    public constructor(length: number) {
10800        this(length as int)
10801    }
10802
10803    /**
10804     * Creates a copy of Float32Array.
10805     *
10806     * @param other data initializer
10807     */
10808    public constructor(other: Float32Array) {
10809        if (other.buffer instanceof ArrayBuffer) {
10810            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
10811        } else if (other.buffer instanceof SharedArrayBuffer) {
10812            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
10813        } else {
10814            throw new Error("unexpected type of buffer")
10815        }
10816        this.byteLength = other.byteLength
10817        this.lengthInt = other.length as int
10818        this.byteOffset = 0
10819    }
10820
10821    /**
10822     * Creates an Float32Array from number[]
10823     */
10824    public constructor(numbers: number[]) {
10825        this(numbers.length)
10826        for (let i: int = 0; i < this.lengthInt; ++i) {
10827            this.setUnsafe(i, numbers[i] as float)
10828        }
10829    }
10830
10831    /**
10832     * Creates an Float32Array from int[]
10833     */
10834    public constructor(numbers: int[]) {
10835        this(numbers.length)
10836        for (let i: int = 0; i < this.lengthInt; ++i) {
10837            this.setUnsafe(i, numbers[i] as float)
10838        }
10839    }
10840
10841    /**
10842     * Assigns val as element on index.
10843     *
10844     * @param val value to set
10845     *
10846     * @param index index to change
10847     */
10848    public $_set(index: number, val: number): void {
10849        this.$_set(index as int, val)
10850    }
10851
10852    /**
10853     * Assigns val as element on index.
10854     *
10855     * @param val value to set
10856     *
10857     * @param index index to change
10858     */
10859    public $_set(index: int, val: number): void {
10860        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10861        if (index < 0 || index >= this.lengthInt) {
10862            throw new RangeError("invalid index")
10863        }
10864        this.setUnsafe(index, val as float)
10865    }
10866
10867    /**
10868     * Assigns val as element on index.
10869     *
10870     * @param val value to set
10871     *
10872     * @param index index to change
10873     */
10874    public $_set(index: number, val: int): void {
10875        this.$_set(index as int, val)
10876    }
10877
10878    /**
10879     * Assigns val as element on index.
10880     *
10881     * @param val value to set
10882     *
10883     * @param index index to change
10884     */
10885    public $_set(index: int, val: int): void {
10886        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10887        if (index < 0 || index >= this.lengthInt) {
10888            throw new RangeError("invalid index")
10889        }
10890        this.setUnsafe(index, val as float)
10891    }
10892
10893    /**
10894     * Assigns val as element on index.
10895     *
10896     * @param val value to set
10897     *
10898     * @param index index to change
10899     */
10900    public $_set(index: number, val: float): void {
10901        this.$_set(index as int, val)
10902    }
10903
10904    /**
10905     * Assigns val as element on index.
10906     *
10907     * @param val value to set
10908     *
10909     * @param index index to change
10910     */
10911    public $_set(index: int, val: float): void {
10912        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10913        if (index < 0 || index >= this.lengthInt) {
10914            throw new RangeError("invalid index")
10915        }
10916        this.setUnsafe(index, val)
10917    }
10918
10919    /** Number of float stored in Float32Array */
10920    public get length(): number {
10921        return this.lengthInt
10922    }
10923
10924    /**
10925     * Returns an instance of number at passed index.
10926     *
10927     * @param index index to look at
10928     *
10929     * @returns a primitive at index
10930     */
10931    public override $_get(index: number): Number {
10932        return this.$_get(index as int) as Number
10933    }
10934
10935    /**
10936     * Returns an instance of number at passed index.
10937     *
10938     * @param index index to look at
10939     *
10940     * @returns a primitive at index
10941     */
10942    public $_get(index: int): number {
10943        if (index < 0 || index >= this.lengthInt) {
10944            throw new RangeError("invalid index")
10945        }
10946        return this.getUnsafe(index) as number
10947    }
10948
10949    /**
10950     * Returns an instance of primitive type at passed index.
10951     *
10952     * @param index index to look at
10953     *
10954     * @returns a primitive at index
10955     */
10956    public at(index: number): Number | undefined {
10957        return this.at(index as int)
10958    }
10959
10960    /**
10961     * Returns an instance of primitive type at passed index.
10962     *
10963     * @param index index to look at
10964     *
10965     * @returns a primitive at index
10966     */
10967    public at(index: int): Number | undefined {
10968        let k: int
10969        if (index >= 0) {
10970            k = index
10971        } else {
10972            k = this.lengthInt + index
10973        }
10974        if (k < 0 || k >= this.lengthInt) {
10975            return undefined
10976        }
10977        return new Number(this.getUnsafe(k))
10978    }
10979
10980    /**
10981     * Makes a copy of internal elements to targetPos from startPos to endPos.
10982     *
10983     * @param target insert index to place copied elements
10984     *
10985     * @param start start index to begin copy from
10986     *
10987     * @param end last index to end copy from, excluded
10988     *
10989     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10990     */
10991    public copyWithin(target: number, start: number, end?: number): Float32Array {
10992        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
10993    }
10994
10995    /**
10996     * Makes a copy of internal elements to targetPos from startPos to endPos.
10997     *
10998     * @param target insert index to place copied elements
10999     *
11000     * @param start start index to begin copy from
11001     *
11002     * @param end last index to end copy from, excluded
11003     *
11004     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
11005     */
11006    public copyWithin(target: int, start: number, end?: number): Float32Array {
11007        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
11008    }
11009
11010    /**
11011     * Makes a copy of internal elements to targetPos from startPos to endPos.
11012     *
11013     * @param target insert index to place copied elements
11014     *
11015     * @param start start index to begin copy from
11016     *
11017     * @param end last index to end copy from, excluded
11018     *
11019     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
11020     */
11021    public copyWithin(target: number, start: int, end?: number): Float32Array {
11022        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
11023    }
11024
11025    /**
11026     * Makes a copy of internal elements to targetPos from startPos to endPos.
11027     *
11028     * @param target insert index to place copied elements
11029     *
11030     * @param start start index to begin copy from
11031     *
11032     * @param end last index to end copy from, excluded
11033     *
11034     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
11035     */
11036    public copyWithin(target: int, start: int, end?: number): Float32Array {
11037        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
11038    }
11039
11040    /**
11041     * Makes a copy of internal elements to targetPos from startPos to endPos.
11042     *
11043     * @param target insert index to place copied elements
11044     *
11045     * @param start start index to begin copy from
11046     *
11047     * @param end last index to end copy from, excluded
11048     *
11049     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
11050     */
11051    public copyWithin(target: int, start: int, end: int): Float32Array {
11052        let toPos = normalizeIndex(target, this.lengthInt)
11053        let fromPos = normalizeIndex(start, this.lengthInt)
11054        const finalPos = normalizeIndex(end, this.lengthInt)
11055        let count: int = finalPos - fromPos
11056        if (count > (this.lengthInt - toPos)) {
11057            count = this.lengthInt - toPos
11058        }
11059        let direction: int = 1
11060        if ((fromPos < toPos) && (toPos < fromPos + count)) {
11061            fromPos = fromPos + count - 1
11062            toPos   = toPos   + count - 1
11063            direction = -1
11064        }
11065        while (count > 0) {
11066            const value = this.getUnsafe(fromPos)
11067            this.setUnsafe(toPos, value)
11068            fromPos = fromPos + direction
11069            toPos = toPos + direction
11070            --count
11071        }
11072        return this
11073    }
11074
11075    /**
11076     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
11077     *
11078     * @param target insert index to place copied elements
11079     *
11080     * See rules of parameters normalization:
11081     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
11082     */
11083    public copyWithin(target: number): Float32Array {
11084        return this.copyWithin(target as int)
11085    }
11086
11087    /**
11088     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
11089     *
11090     * @param target insert index to place copied elements
11091     *
11092     * See rules of parameters normalization:
11093     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
11094     */
11095    public copyWithin(target: int): Float32Array {
11096        return this.copyWithin(target, 0, this.lengthInt)
11097    }
11098
11099    /**
11100     * Returns an array of key, value pairs for every entry in the Float32Array
11101     *
11102     * @returns key, value pairs for every entry in the array
11103     */
11104    public entries(): IterableIterator<[Number, Number]> {
11105        return new Float32ArrayIteratorEntries(this)
11106    }
11107
11108    /**
11109     * Fills the Float32Array with specified value
11110     *
11111     * @param value new valuy
11112     *
11113     * @returns modified Float32Array
11114     */
11115    public fill(value: number, start?: number, end?: number): this {
11116        this.fill(value as float, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
11117        return this
11118    }
11119
11120    /**
11121     * Fills the Float32Array with specified value
11122     *
11123     * @param value new valuy
11124     *
11125     * @returns modified Float32Array
11126     */
11127    public fill(value: number, start: int, end?: number): this {
11128        this.fill(value as float, start as int, asIntOrDefault(end, this.lengthInt))
11129        return this
11130    }
11131
11132    /**
11133     * Fills the Float32Array with specified value
11134     *
11135     * @param value new valuy
11136     *
11137     * @returns modified Float32Array
11138     */
11139    public fill(value: number, start: int, end: number): this {
11140        this.fill(value as float, start as int, end as int)
11141        return this
11142    }
11143
11144    /**
11145     * Fills the Float32Array with specified value
11146     *
11147     * @param value new valuy
11148     *
11149     * @returns modified Float32Array
11150     */
11151    public fill(value: number, start: number, end: int): this {
11152        this.fill(value as float, start as int, end as int)
11153        return this
11154    }
11155
11156    /**
11157     * Fills the Float32Array with specified value
11158     *
11159     * @param value new valuy
11160     *
11161     * @returns modified Float32Array
11162     */
11163    public fill(value: number, start: int, end: int): this {
11164        this.fill(value as float, start as int, end as int)
11165        return this
11166    }
11167
11168    /**
11169     * Fills the Float32Array with specified value
11170     *
11171     * @param value new valuy
11172     *
11173     * @returns modified Float32Array
11174     */
11175    public fill(value: float, start?: number, end?: number): this {
11176        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
11177        return this
11178    }
11179
11180    /**
11181     * Fills the Float32Array with specified value
11182     *
11183     * @param value new valuy
11184     *
11185     * @returns modified Float32Array
11186     */
11187    public fill(value: float, start: int, end?: number): this {
11188        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
11189        return this
11190    }
11191
11192    /**
11193     * Fills the Float32Array with specified value
11194     *
11195     * @param value new valuy
11196     *
11197     * @returns modified Float32Array
11198     */
11199    public fill(value: float, start: int, end: number): this {
11200        this.fill(value, start as int, end as int)
11201        return this
11202    }
11203
11204    /**
11205     * Fills the Float32Array with specified value
11206     *
11207     * @param value new valuy
11208     *
11209     * @returns modified Float32Array
11210     */
11211    public fill(value: float, start: number, end: int): this {
11212        this.fill(value, start as int, end as int)
11213        return this
11214    }
11215
11216    /**
11217     * Fills the Float32Array with specified value
11218     *
11219     * @param value new valuy
11220     *
11221     * @returns modified Float32Array
11222     */
11223    public fill(value: float, start: int, end: int): this {
11224        const k = normalizeIndex(start, this.lengthInt)
11225        const finalPos = normalizeIndex(end, this.lengthInt)
11226        for (let i: int = k; i < finalPos; ++i) {
11227            this.setUnsafe(i, value)
11228        }
11229        return this
11230    }
11231
11232    /**
11233     * Assigns val as element on insertPos.
11234     * @description Added to avoid (un)packing a single value into array to use overloaded set(float[], insertPos)
11235     *
11236     * @param val value to set
11237     *
11238     * @param insertPos index to change
11239     */
11240    public set(insertPos: number, val: number): void {
11241        this.$_set(insertPos, val)
11242    }
11243
11244    /**
11245     * Assigns val as element on insertPos.
11246     * @description Added to avoid (un)packing a single value into array to use overloaded set(float[], insertPos)
11247     *
11248     * @param val value to set
11249     *
11250     * @param insertPos index to change
11251     */
11252    public set(insertPos: int, val: float): void {
11253        this.$_set(insertPos, val)
11254    }
11255
11256    /**
11257     * Copies all elements of arr to the current Float32Array starting from insertPos.
11258     *
11259     * @param arr array to copy data from
11260     *
11261     * @param insertPos start index where data from arr will be inserted
11262     *
11263     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
11264     */
11265    public set(arr: number[], insertPos: number): void {
11266        const offset = insertPos as int
11267        if (offset < 0 || offset + arr.length > this.lengthInt) {
11268            throw new RangeError("offset is out of bounds")
11269        }
11270        for (let i = 0; i < arr.length as int; ++i) {
11271            this.setUnsafe(offset + i, arr[i] as float)
11272        }
11273    }
11274
11275    /**
11276     * Copies all elements of arr to the current Float32Array starting from insertPos.
11277     *
11278     * @param arr array to copy data from
11279     *
11280     * @param insertPos start index where data from arr will be inserted
11281     *
11282     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
11283     */
11284    public set(arr: float[], insertPos: int): void {
11285        const offset = insertPos as int
11286        if (offset < 0 || offset + arr.length > this.lengthInt) {
11287            throw new RangeError("offset is out of bounds")
11288        }
11289        for (let i = 0; i < arr.length as int; ++i) {
11290            this.setUnsafe(offset + i, arr[i])
11291        }
11292    }
11293
11294    /**
11295     * Copies all elements of arr to the current Float32Array.
11296     *
11297     * @param arr array to copy data from
11298     */
11299    public set(arr: number[]): void {
11300        this.set(arr, 0 as number)
11301    }
11302
11303    /**
11304     * Copies all elements of arr to the current Float32Array.
11305     *
11306     * @param arr array to copy data from
11307     */
11308    public set(arr: float[]): void {
11309        this.set(arr, 0 as int)
11310    }
11311
11312    /**
11313     * Copies elements from an ArrayLike object to the Float32Array.
11314     *
11315     * @param array An ArrayLike object containing the elements to copy.
11316     *
11317     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
11318     */
11319    public set(array: ArrayLike<number>, offset: number = 0): void {
11320        const insertPos = offset as int
11321        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
11322            throw new RangeError("offset is out of bounds")
11323        }
11324        for (let i = 0; i < array.length as int; ++i) {
11325            this.setUnsafe(insertPos + i, array[i] as float)
11326        }
11327    }
11328
11329    /**
11330     * Returns a new array from a set of elements.
11331     *
11332     * @param items a set of elements to include in the new array object.
11333     *
11334     * @returns new Float32Array
11335     */
11336    public static of(...items: number[]): Float32Array {
11337        let res = new Float32Array(items.length as int)
11338        for (let i: int = 0; i < items.length; i++) {
11339            res.setUnsafe(i, items[i] as float)
11340        }
11341        return res
11342    }
11343
11344    /**
11345     * Returns a new array from a set of elements.
11346     *
11347     * @param items a set of elements to include in the new array object.
11348     *
11349     * @returns new Float32Array
11350     */
11351    public static of(...items: int[]): Float32Array {
11352        let res = new Float32Array(items.length as int)
11353        for (let i: int = 0; i < items.length; i++) {
11354            res.setUnsafe(i, items[i] as float)
11355        }
11356        return res
11357    }
11358
11359    /**
11360     * Returns a new array from a set of elements.
11361     *
11362     * @param items a set of elements to include in the new array object.
11363     *
11364     * @returns new Float32Array
11365     */
11366    public static of(...items: float[]): Float32Array {
11367        let res = new Float32Array(items.length as int)
11368        for (let i: int = 0; i < items.length; i++) {
11369            res.setUnsafe(i, items[i])
11370        }
11371        return res
11372    }
11373
11374    /**
11375     * Returns a new array from a set of elements.
11376     *
11377     * @param items a set of elements to include in the new array object.
11378     *
11379     * @returns new Float32Array
11380     */
11381    public static of(): Float32Array {
11382        return new Float32Array(0 as int)
11383    }
11384
11385    /**
11386     * Creates an array from an array-like or iterable object.
11387     *
11388     * @param arrayLike An array-like or iterable object to convert to an array.
11389     *
11390     * @returns new Float32Array
11391     */
11392    public static from(arrayLike: ArrayLike<number>): Float32Array {
11393        return Float32Array.from<number>(arrayLike, (x: number, k: number): number => x)
11394    }
11395
11396    /**
11397     * Creates an array from an array-like or iterable object.
11398     *
11399     * @param arrayLike An array-like or iterable object to convert to an array.
11400     *
11401     * @param mapfn A mapping function to call on every element of the array.
11402     *
11403     * @returns new Float32Array
11404     */
11405    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float32Array {
11406        if (mapfn == undefined) {
11407            mapfn = (v: number, k: number): number => { return v }
11408        }
11409
11410        let iter = arrayLike.$_iterator()
11411        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
11412        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
11413        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
11414        //  we can make one pass through the iterator without the need for memory reallocation.
11415        const maybeLength = tryGetIteratorLength(arrayLike)
11416        if (maybeLength) {
11417            const result = new Float32Array(maybeLength)
11418            for (let i = 0; i < maybeLength; ++i) {
11419                const x = iter.next()
11420                if (x.done) {
11421                    return new Float32Array(result.buffer, 0, i)
11422                }
11423                result.setUnsafe(i, (mapfn)!(x.value!, i) as float)
11424            }
11425            return result
11426        }
11427
11428        // NOTE (templin.konstantin): Create builtin array as buffer
11429        let temp = new Float32Array(6)
11430        let index = new int[1]
11431        index[0] = 0
11432
11433        iteratorForEach<number>(iter, (x: number): void => {
11434            if (index[0] + 1 > temp.lengthInt) {
11435                // NOTE (templin.konstantin): Progressive reallocation
11436                const curLength = (temp.buffer as Buffer).getByteLength()
11437                const tb = new ArrayBuffer(curLength * 2)
11438                for (let i = 0; i < curLength; ++i) {
11439                    tb.set(i, (temp.buffer as Buffer).at(i))
11440                }
11441                temp = new Float32Array(tb)
11442            }
11443            temp.setUnsafe(index[0], (mapfn)!(x, index[0]) as float)
11444            index[0]++
11445        })
11446        return new Float32Array(temp.buffer, 0, index[0])
11447    }
11448
11449
11450    /**
11451     * Creates an array from an array-like or iterable object.
11452     *
11453     * @param arrayLike An array-like or iterable object to convert to an array.
11454     *
11455     * @param mapfn A mapping function to call on every element of the array.
11456     *
11457     * @returns new Float32Array
11458     */
11459    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Float32Array {
11460        let res = new Float32Array(arrayLike.length)
11461        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
11462        const idx = new int[1]
11463        idx[0] = 0
11464        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
11465            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as float)
11466            idx[0] += 1
11467        })
11468        return res
11469    }
11470
11471    /**
11472     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11473     *
11474     * @param searchElement The element to search for
11475     *
11476     * @param fromIndex The position in this array at which to begin searching for searchElement
11477     *
11478     * @returns true if searchElement is in Float32Array, false otherwise
11479     */
11480    public includes(searchElement: number, fromIndex?: number): boolean {
11481        if (isNaN(searchElement)) {
11482            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
11483            for (let i = fromIndexInt; i < this.lengthInt; i++) {
11484                if (isNaN(this.getUnsafe(i))) {
11485                    return true
11486                }
11487            }
11488            return false
11489        }
11490        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
11491    }
11492
11493    /**
11494     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11495     *
11496     * @param searchElement The element to search for
11497     *
11498     * @param fromIndex The position in this array at which to begin searching for searchElement
11499     *
11500     * @returns true if e is in Float32Array, false otherwise
11501     */
11502    public includes(searchElement: float, fromIndex: int): boolean {
11503        return this.indexOf(searchElement as int, fromIndex) != -1
11504    }
11505
11506    /**
11507     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11508     *
11509     * @param searchElement The element to search for
11510     *
11511     * @param fromIndex The position in this array at which to begin searching for searchElement
11512     *
11513     * @returns true if searchElement is in Float32Array, false otherwise
11514     */
11515    public includes(searchElement: float): boolean {
11516        return this.includes(searchElement, 0)
11517    }
11518
11519    /**
11520     * Returns the index of the first occurrence of a value in Float32Array.
11521     *
11522     * @param searchElement The value to locate in the array.
11523     *
11524     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11525     *  search starts at index 0.
11526     *
11527     * @returns index of element if it presents, -1 otherwise
11528     */
11529    public indexOf(searchElement: number, fromIndex?: number): number {
11530        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
11531    }
11532
11533    /**
11534     * Returns the index of the first occurrence of a value in Float32Array.
11535     *
11536     * @param searchElement The value to locate in the array.
11537     *
11538     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11539     *  search starts at index 0.
11540     *
11541     * @returns index of element if it presents, -1 otherwise
11542     */
11543    public indexOf(searchElement: number, fromIndex: int): number {
11544        if (isNaN(searchElement)) {
11545            return -1
11546        }
11547        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
11548        for (let i = fromIndex; i < this.lengthInt; i++) {
11549            if (this.getUnsafe(i) as number == searchElement) {
11550                return i
11551            }
11552        }
11553        return -1
11554    }
11555
11556    /**
11557     * Returns the index of the first occurrence of a value in Float32Array.
11558     *
11559     * @param searchElement The value to locate in the array.
11560     *
11561     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11562     *  search starts at index 0.
11563     *
11564     * @returns index of element if it presents, -1 otherwise
11565     */
11566    public indexOf(searchElement: int, fromIndex: int): number {
11567        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
11568        for (let i = fromIndex; i < this.lengthInt; i++) {
11569            if (this.getUnsafe(i) == searchElement as float) {
11570                return i
11571            }
11572        }
11573        return -1
11574    }
11575
11576    /**
11577     * Returns the index of the first occurrence of a value in Float32Array.
11578     *
11579     * @param searchElement The value to locate in the array.
11580     *
11581     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11582     *  search starts at index 0.
11583     *
11584     * @returns index of element if it presents, -1 otherwise
11585     */
11586    public indexOf(searchElement: int): number {
11587        return this.indexOf(searchElement, 0)
11588    }
11589
11590    /**
11591     * Adds all the elements of an array separated by the specified separator string
11592     *
11593     * @param separator A string used to separate one element of an array from the next in the
11594     * resulting String. If omitted, the array elements are separated with a comma
11595     *
11596     * @returns joined representation
11597     */
11598    public join(separator?: String): string {
11599        if (separator == undefined) {
11600            return this.join(",")
11601        }
11602        let res: StringBuilder = new StringBuilder("")
11603        for (let i = 0; i < this.lengthInt - 1; ++i) {
11604            res.append(this.getUnsafe(i) as number)
11605            res.append(separator)
11606        }
11607        if (this.lengthInt > 0) {
11608            res.append(this.getUnsafe(this.lengthInt - 1) as number)
11609        }
11610        return res.toString()
11611    }
11612
11613    /**
11614     * Returns an list of keys in Float32Array
11615     *
11616     * @returns iterator over keys
11617     */
11618    public keys(): IterableIterator<number> {
11619        return new Float32ArrayIteratorKeys(this)
11620    }
11621
11622    /**
11623     * Returns the index of the last occurrence of a value in Float32Array.
11624     *
11625     * @param searchElement The value to locate in the array.
11626     *
11627     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11628     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11629     *
11630     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11631     */
11632    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
11633        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
11634    }
11635
11636    /**
11637     * Returns the index of the last occurrence of a value in Float32Array.
11638     *
11639     * @param searchElement The value to locate in the array.
11640     *
11641     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11642     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11643     *
11644     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11645     */
11646    public lastIndexOf(searchElement: number): number {
11647        return this.lastIndexOf(searchElement, this.lengthInt - 1)
11648    }
11649
11650    /**
11651     * Returns the index of the last occurrence of a value in Float32Array.
11652     *
11653     * @param searchElement The value to locate in the array.
11654     *
11655     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11656     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11657     *
11658     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11659     */
11660    public lastIndexOf(searchElement: number, fromIndex: int): number {
11661        if (isNaN(searchElement)) {
11662            return -1
11663        }
11664        if (this.lengthInt == 0) {
11665            return -1
11666        }
11667        let k: int = this.lengthInt + fromIndex
11668        if (fromIndex >= 0) {
11669            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
11670        }
11671        while (k >= 0) {
11672            if (this.getUnsafe(k) as number == searchElement) {
11673                return k
11674            }
11675            k--
11676        }
11677        return -1
11678    }
11679
11680    /**
11681     * Returns the index of the last occurrence of a value in Float32Array.
11682     *
11683     * @param searchElement The value to locate in the array.
11684     *
11685     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11686     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11687     *
11688     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11689     */
11690    public lastIndexOf(searchElement: int, fromIndex: int): number {
11691        if (this.lengthInt == 0) {
11692            return -1
11693        }
11694        let k: int = this.lengthInt + fromIndex
11695        if (fromIndex >= 0) {
11696            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
11697        }
11698        while (k >= 0) {
11699            if (this.getUnsafe(k) == searchElement as float) {
11700                return k
11701            }
11702            k--
11703        }
11704        return -1
11705    }
11706
11707    /**
11708     * Returns the index of the last occurrence of a value in Float32Array.
11709     *
11710     * @param searchElement The value to locate in the array.
11711     *
11712     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11713     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11714     *
11715     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11716     */
11717    public lastIndexOf(searchElement: int): number {
11718        return this.lastIndexOf(searchElement, this.lengthInt - 1)
11719    }
11720
11721    /**
11722    * Creates a new Float32Array using initializer
11723    *
11724    * @param data initializer
11725    *
11726    * @returns a new Float32Array from data
11727    */
11728    public of(data: Object[]): Float32Array {
11729        throw new Error("Float32Array.of: not implemented")
11730    }
11731
11732    /**
11733     * Creates a new Float32Array using reversed data from the current one
11734     *
11735     * @returns a new Float32Array using reversed data from the current one
11736     */
11737    public reverse(): Float32Array {
11738        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
11739            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
11740            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
11741            this.setUnsafe(i, tmp)
11742        }
11743        return this
11744    }
11745
11746    /**
11747     * Creates a slice of current Float32Array using range [begin, end)
11748     *
11749     * @param begin start index to be taken into slice
11750     *
11751     * @param end last index to be taken into slice
11752     *
11753     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11754     *
11755     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11756     */
11757    public slice(begin?: number, end?: number): Float32Array {
11758        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
11759    }
11760
11761    /**
11762     * Creates a slice of current Float32Array using range [begin, end)
11763     *
11764     * @param begin start index to be taken into slice
11765     *
11766     * @param end last index to be taken into slice
11767     *
11768     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11769     *
11770     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11771     */
11772    public slice(begin: number, end: number): Float32Array {
11773        return this.slice(begin as int, end as int)
11774    }
11775
11776    /**
11777     * Creates a slice of current Float32Array using range [begin, end)
11778     *
11779     * @param begin start index to be taken into slice
11780     *
11781     * @param end last index to be taken into slice
11782     *
11783     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11784     *
11785     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11786     */
11787    public slice(begin: number, end: int): Float32Array {
11788        return this.slice(begin as int, end as int)
11789    }
11790
11791    /**
11792     * Creates a slice of current Float32Array using range [begin, end)
11793     *
11794     * @param begin start index to be taken into slice
11795     *
11796     * @param end last index to be taken into slice
11797     *
11798     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11799     *
11800     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11801     */
11802    public slice(begin: int, end: number): Float32Array {
11803        return this.slice(begin as int, end as int)
11804    }
11805
11806    /**
11807     * Creates a slice of current Float32Array using range [begin, end)
11808     *
11809     * @param begin start index to be taken into slice
11810     *
11811     * @param end last index to be taken into slice
11812     *
11813     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11814     *
11815     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11816     */
11817    public slice(begin: int, end: int): Float32Array {
11818        const len: int = this.lengthInt
11819        const relStart = normalizeIndex(begin, len)
11820        const relEnd = normalizeIndex(end, len)
11821        let count = relEnd - relStart
11822        if (count < 0) {
11823            count = 0
11824        }
11825        if (this.buffer instanceof ArrayBuffer) {
11826            let buf = (this.buffer as ArrayBuffer).slice(relStart * Float32Array.BYTES_PER_ELEMENT as int, relEnd * Float32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
11827            return new Float32Array(buf)
11828        } else if (this.buffer instanceof SharedArrayBuffer) {
11829            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Float32Array.BYTES_PER_ELEMENT as int, relEnd * Float32Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
11830            return new Float32Array(buf)
11831        } else {
11832            throw new Error("unexpected type of buffer")
11833        }
11834    }
11835
11836    /**
11837     * Creates a slice of current Float32Array using range [begin, this.length).
11838     *
11839     * @param begin start index to be taken into slice
11840     *
11841     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
11842     */
11843    public slice(begin: number): Float32Array {
11844        return this.slice(begin as int)
11845    }
11846
11847    /**
11848     * Creates a slice of current Float32Array using range [begin, this.length).
11849     *
11850     * @param begin start index to be taken into slice
11851     *
11852     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
11853     */
11854    public slice(begin: int): Float32Array {
11855        return this.slice(begin, this.lengthInt)
11856    }
11857
11858    /**
11859     * Creates a Float32Array with the same underlying ArrayBufferLike
11860     *
11861     * @param begin start index, inclusive
11862     *
11863     * @param end last index, exclusive
11864     *
11865     * @returns new Float32Array with the same underlying ArrayBufferLike
11866     */
11867    public subarray(begin?: number, end?: number): Float32Array {
11868        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
11869    }
11870
11871    /**
11872     * Creates a Float32Array with the same underlying ArrayBufferLike
11873     *
11874     * @param begin start index, inclusive
11875     *
11876     * @param end last index, exclusive
11877     *
11878     * @returns new Float32Array with the same underlying ArrayBufferLike
11879     */
11880    public subarray(begin: number, end: number): Float32Array {
11881        return this.subarray(begin as int, end as int)
11882    }
11883
11884    /**
11885     * Creates a Float32Array with the same underlying ArrayBufferLike
11886     *
11887     * @param begin start index, inclusive
11888     *
11889     * @param end last index, exclusive
11890     *
11891     * @returns new Float32Array with the same underlying ArrayBufferLike
11892     */
11893    public subarray(begin: number, end: int): Float32Array {
11894        return this.subarray(begin as int, end as int)
11895    }
11896
11897    /**
11898     * Creates a Float32Array with the same underlying ArrayBufferLike
11899     *
11900     * @param begin start index, inclusive
11901     *
11902     * @param end last index, exclusive
11903     *
11904     * @returns new Float32Array with the same underlying ArrayBufferLike
11905     */
11906    public subarray(begin: int, end: number): Float32Array {
11907        return this.subarray(begin as int, end as int)
11908    }
11909
11910    /**
11911     * Creates a Float32Array with the same underlying ArrayBufferLike
11912     *
11913     * @param begin start index, inclusive
11914     *
11915     * @param end last index, exclusive
11916     *
11917     * @returns new Float32Array with the same underlying ArrayBufferLike
11918     */
11919    public subarray(begin: int, end: int): Float32Array {
11920        const len: int = this.lengthInt
11921        const relStart = normalizeIndex(begin, len)
11922        const relEnd = normalizeIndex(end, len)
11923        let count = relEnd - relStart
11924        if (count < 0) {
11925            count = 0
11926        }
11927        return new Float32Array(this.buffer, relStart * Float32Array.BYTES_PER_ELEMENT as int, count)
11928    }
11929
11930    /**
11931     * Creates a Float32Array with the same ArrayBufferLike
11932     *
11933     * @param begin start index, inclusive
11934     *
11935     * @returns new Float32Array with the same ArrayBufferLike
11936     */
11937    public subarray(begin: number): Float32Array {
11938        return this.subarray(begin as int, this.lengthInt)
11939    }
11940
11941    /**
11942     * Creates a Float32Array with the same ArrayBufferLike
11943     *
11944     * @param begin start index, inclusive
11945     *
11946     * @returns new Float32Array with the same ArrayBufferLike
11947     */
11948    public subarray(begin: int): Float32Array {
11949        return this.subarray(begin as int, this.lengthInt)
11950    }
11951
11952    /**
11953     * Converts Float32Array to a string with respect to locale
11954     *
11955     * @param locales
11956     *
11957     * @param options
11958     *
11959     * @returns string representation
11960     */
11961    public toLocaleString(locales: Object, options: Object): string {
11962        throw new Error("Float32Array.toLocaleString: not implemented")
11963    }
11964
11965    /**
11966     * Converts Float32Array to a string with respect to locale
11967     *
11968     * @param locales
11969     *
11970     * @returns string representation
11971     */
11972    public toLocaleString(locales: Object): string {
11973        return this.toLocaleString(new Object(), new Object())
11974    }
11975
11976    /**
11977     * Converts Float32Array to a string with respect to locale
11978     *
11979     * @returns string representation
11980     */
11981    public toLocaleString(): string {
11982        let res: StringBuilder = new StringBuilder("")
11983        for (let i = 0; i < this.lengthInt - 1; ++i) {
11984            res.append((this.getUnsafe(i) as Number).toLocaleString())
11985            res.append(",")
11986        }
11987        if (this.lengthInt > 0) {
11988            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
11989        }
11990        return res.toString()
11991    }
11992
11993    /**
11994     * Creates a reversed copy
11995     *
11996     * @returns a reversed copy
11997     */
11998    public toReversed(): Float32Array {
11999        return new Float32Array(this).reverse()
12000    }
12001
12002    /**
12003     * Creates a sorted copy
12004     *
12005     * @returns a sorted copy
12006     */
12007    public toSorted(): Float32Array {
12008        return new Float32Array(this).sort()
12009    }
12010
12011    /**
12012     * Returns a string representation of the Float32Array
12013     *
12014     * @returns a string representation of the Float32Array
12015     */
12016    public override toString(): string {
12017        return this.join(",")
12018    }
12019
12020    /**
12021     * Returns array values iterator
12022     *
12023     * @returns an iterator
12024     */
12025    public values(): IterableIterator<Number> {
12026        return new Float32ArrayIterator(this)
12027    }
12028
12029    /**
12030     * Iteratorable interface implementation
12031     *
12032     * @returns iterator over all elements
12033     */
12034    public override $_iterator(): IterableIterator<Number> {
12035        return this.values()
12036    }
12037
12038    /**
12039     * Creates a copy with replaced value on index
12040     *
12041     * @param index
12042     *
12043     * @param value
12044     *
12045     * @returns an Float32Array with replaced value on index
12046     */
12047    public with(index: number, value: number): Float32Array {
12048        return this.with(index as int, value as float)
12049    }
12050
12051    /**
12052     * Creates a copy with replaced value on index
12053     *
12054     * @param index
12055     *
12056     * @param value
12057     *
12058     * @returns an Float32Array with replaced value on index
12059     */
12060    public with(index: int, value: float): Float32Array {
12061        let res = new Float32Array(this)
12062        res.set(index, value)
12063        return res
12064    }
12065
12066    /// === with element lambda functions ===
12067    /**
12068     * Determines whether the specified callback function returns true for all elements of an array.
12069     *
12070     * @param predicate A function that accepts one argument.
12071     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12072     * or until the end of the array.
12073     *
12074     * @returns true unless predicate function returns a false for an array element,
12075     * in which case false is immediately returned.
12076     */
12077    public every(predicate: (element: number) => boolean): boolean {
12078        return this.every((element: number, index: number, array: Float32Array): boolean => predicate(element))
12079    }
12080
12081    /**
12082     * creates a new Float32Array from current Float32Array based on a condition fn
12083     *
12084     * @param fn the condition to apply for each element
12085     *
12086     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12087     */
12088    public filter(fn: (val: number) => boolean): Float32Array {
12089        let newF: (val: number, index: number, array: Float32Array) => boolean =
12090            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
12091        return this.filter(newF)
12092    }
12093
12094    /**
12095     * Returns the value of the first element in the array where predicate is true, and undefined
12096     * otherwise
12097     *
12098     * @param predicate find calls predicate once for each element of the array, in ascending
12099     * order, until it finds one where predicate returns true. If such an element is found, find
12100     * immediately returns that element value. Otherwise, find returns undefined
12101     *
12102     * @returns number | undefined
12103     */
12104    public find(predicate: () => boolean): number | undefined {
12105        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate())
12106    }
12107
12108    /**
12109     * Returns the value of the first element in the array where predicate is true, and undefined
12110     * otherwise
12111     *
12112     * @param predicate find calls predicate once for each element of the array, in ascending
12113     * order, until it finds one where predicate returns true. If such an element is found, find
12114     * immediately returns that element value. Otherwise, find returns undefined
12115     *
12116     * @returns number | undefined
12117     */
12118    public find(predicate: (value: number) => boolean): number | undefined {
12119        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate(value))
12120    }
12121
12122    /**
12123     * Returns the index of the first element in the array where predicate is true, and -1
12124     * otherwise
12125     *
12126     * @param predicate find calls predicate once for each element of the array, in ascending
12127     * order, until it finds one where predicate returns true. If such an element is found,
12128     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12129     *
12130     * @returns number
12131     */
12132    public findIndex(predicate: (value: number) => boolean): number {
12133        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate(value)) as number
12134    }
12135
12136    /**
12137     * Finds the last element in the Float32Array that satisfies the condition
12138     *
12139     * @param fn condition
12140     *
12141     * @returns the last element that satisfies fn
12142     */
12143    public findLast(fn: (val: number) => boolean): number {
12144        let newF: (val: number, index: number, array: Float32Array) => boolean =
12145            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
12146        return this.findLast(newF) as number
12147    }
12148
12149    /**
12150     * Finds an index of the last element in the Float32Array that satisfies the condition
12151     *
12152     * @param fn condition
12153     *
12154     * @returns the index of the last element that satisfies fn, -1 otherwise
12155     */
12156    public findLastIndex(fn: (val: number) => boolean): number {
12157        let newF: (val: number, index: number, array: Float32Array) => boolean =
12158            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
12159        return this.findLastIndex(newF) as number
12160    }
12161
12162    /**
12163     * Performs the specified action for each element in Float32Array
12164     *
12165     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
12166     * callbackfn function one time for each element in the array.
12167     *
12168     * @returns None
12169     */
12170    public forEach(callbackfn: (value: number) => void): void {
12171        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn(value))
12172    }
12173
12174    /**
12175     * Determines whether the specified callback function returns true for any element of an array.
12176     *
12177     * @param predicate A function that accepts one argument.
12178     * The some method calls the predicate function for each element in the array
12179     * until the predicate returns a true or until the end of the array.
12180     *
12181     * @returns false unless predicate function returns true for an array element,
12182     * in which case true is immediately returned.
12183     */
12184    public some(predicate: (element: number) => boolean): boolean {
12185        return this.some((element: number, index: number, array: Float32Array): boolean => predicate(element))
12186    }
12187
12188    // NOTE (kprokopenko): this may be not skipped
12189    /**
12190     * Sorts in-place
12191     *
12192     * @param compareFn comparator —  used to determine the order of the elements.
12193     * compareFn returns a negative value if first argument is less than second argument,
12194     * zero if they're equal and a positive value otherwise.
12195     * If omitted, the elements are sorted in ascending order.
12196     *
12197     * @returns sorted Float32Array
12198     */
12199    public sort(compareFn?: (a: number, b: number) => number): this {
12200        let arr: float[] = new float[this.lengthInt]
12201        for (let i = 0; i < this.lengthInt; ++i) {
12202            arr[i] = this.getUnsafe(i)
12203        }
12204        let cmp = (l: float, r: float): number => {
12205                return (l - r) as number
12206            }
12207        if (compareFn != undefined) {
12208            cmp = (l: float, r: float): number => {
12209                return compareFn!(l as number, r as number)
12210            }
12211        }
12212        sort(arr, cmp)
12213        for (let i = 0; i < this.lengthInt; ++i) {
12214            this.setUnsafe(i, arr[i])
12215        }
12216        return this
12217    }
12218
12219    /**
12220     * Sorts in-place
12221     *
12222     * @param compareFn comparator —  used to determine the order of the elements.
12223     * compareFn returns a negative value if first argument is less than second argument,
12224     * zero if they're equal and a positive value otherwise.
12225     *
12226     * @returns sorted Float32Array
12227     */
12228    public sort(compareFn: (a: number) => number): this {
12229        let cmp = (a: number, b: number) => { return compareFn(a)}
12230        this.sort(cmp)
12231        return this
12232    }
12233
12234    /**
12235     * Sorts in-place
12236     *
12237     * @param fn compareFn —  used to determine the order of the elements.
12238     * compareFn returns a negative value if first argument is less than second argument,
12239     * zero if they're equal and a positive value otherwise.
12240     *
12241     * @returns sorted Float32Array
12242     */
12243    public sort(compareFn: () => number): this {
12244        let cmp = (a: number, b: number) => { return compareFn()}
12245        this.sort(cmp)
12246        return this
12247    }
12248
12249    /**
12250     * Determines whether the specified callback function returns true for any element of an array.
12251     *
12252     * @param predicate A function that accepts three arguments.
12253     * The some method calls the predicate function for each element in the array
12254     * until the predicate returns a true or until the end of the array.
12255     *
12256     * @returns false unless predicate function returns true for an array element,
12257     * in which case true is immediately returned.
12258     */
12259    public some(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
12260        for (let i = 0; i < this.lengthInt; ++i) {
12261            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
12262                return true
12263            }
12264        }
12265        return false
12266    }
12267
12268    /**
12269     * Determines whether the specified callback function returns true for any element of an array.
12270     *
12271     * @param predicate A function that accepts two arguments.
12272     * The some method calls the predicate function for each element in the array
12273     * until the predicate returns a true or until the end of the array.
12274     *
12275     * @returns false unless predicate function returns true for an array element,
12276     * in which case true is immediately returned.
12277     */
12278    public some(predicate: (element: number, index: number) => boolean): boolean {
12279        return this.some((element: number, index: number, array: Float32Array): boolean => predicate(element, index as number))
12280    }
12281
12282    /**
12283     * Determines whether the specified callback function returns true for any element of an array.
12284     *
12285     * @param predicate A function that accepts no arguments.
12286     * The some method calls the predicate function for each element in the array
12287     * until the predicate returns a true or until the end of the array.
12288     *
12289     * @returns false unless predicate function returns true for an array element,
12290     * in which case true is immediately returned.
12291     */
12292    public some(predicate: () => boolean): boolean {
12293        return this.some((element: number, index: number, array: Float32Array): boolean => predicate())
12294    }
12295
12296    /**
12297     * Calls the specified callback function for all the elements in an array.
12298     * The return value of the callback function is the accumulated result,
12299     * and is provided as an argument in the next call to the callback function.
12300     *
12301     * @param callbackfn A function that accepts four arguments.
12302     * The reduce method calls the callbackfn function one time for each element in the array.
12303     *
12304     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12305     * The first call to the callbackfn function provides this value as an argument.
12306     *
12307     * @returns The value that results from running the callback function to completion over the entire typed array.
12308     */
12309    public reduce<U = number>(
12310                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
12311                initialValue: U): U {
12312        let accumulatedValue = initialValue
12313        for (let i = 0; i < this.lengthInt; ++i) {
12314            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12315        }
12316        return accumulatedValue
12317    }
12318
12319    /**
12320     * Calls the specified callback function for all the elements in an array.
12321     * The return value of the callback function is the accumulated result,
12322     * and is provided as an argument in the next call to the callback function.
12323     *
12324     * @param callbackfn A function that accepts three arguments.
12325     * The reduce method calls the callbackfn function one time for each element in the array.
12326     *
12327     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12328     * The first call to the callbackfn function provides this value as an argument.
12329     *
12330     * @returns The value that results from running the callback function to completion over the entire typed array.
12331     */
12332    public reduce<U = number>(
12333                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
12334                initialValue: U): U {
12335        return this.reduce(
12336                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12337                        callbackfn(prevVal, currVal, currIndex), initialValue)
12338    }
12339
12340    /**
12341     * Calls the specified callback function for all the elements in an array.
12342     * The return value of the callback function is the accumulated result,
12343     * and is provided as an argument in the next call to the callback function.
12344     *
12345     * @param callbackfn A function that accepts two arguments.
12346     * The reduce method calls the callbackfn function one time for each element in the array.
12347     *
12348     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12349     * The first call to the callbackfn function provides this value as an argument.
12350     *
12351     * @returns The value that results from running the callback function to completion over the entire typed array.
12352     */
12353    public reduce<U = number>(
12354                callbackfn: (previousValue: U, currentValue: number) => U,
12355                initialValue: U): U {
12356        return this.reduce(
12357                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12358                        callbackfn(prevVal, currVal), initialValue)
12359    }
12360
12361    /**
12362     * Calls the specified callback function for all the elements in an array.
12363     * The return value of the callback function is the accumulated result,
12364     * and is provided as an argument in the next call to the callback function.
12365     *
12366     * @param callbackfn A function that accepts one argument
12367     * The reduce method calls the callbackfn function one time for each element in the array.
12368     *
12369     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12370     * The first call to the callbackfn function provides this value as an argument.
12371     *
12372     * @returns The value that results from running the callback function to completion over the entire typed array.
12373     */
12374    public reduce<U = number>(
12375                callbackfn: (previousValue: U) => U,
12376                initialValue: U): U {
12377        return this.reduce(
12378                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12379                        callbackfn(prevVal), initialValue)
12380    }
12381
12382    /**
12383     * Calls the specified callback function for all the elements in an array.
12384     * The return value of the callback function is the accumulated result,
12385     * and is provided as an argument in the next call to the callback function.
12386     *
12387     * @param callbackfn A function that accepts no arguments
12388     * The reduce method calls the callbackfn function one time for each element in the array.
12389     *
12390     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12391     * The first call to the callbackfn function provides this value as an argument.
12392     *
12393     * @returns The value that results from running the callback function to completion over the entire typed array.
12394     */
12395    public reduce<U = number>(
12396                callbackfn: () => U,
12397                initialValue: U): U {
12398        return this.reduce(
12399                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12400                        callbackfn(), initialValue)
12401    }
12402
12403    /**
12404     * Calls the specified callback function for all the elements in an array.
12405     * The return value of the callback function is the accumulated result,
12406     * and is provided as an argument in the next call to the callback function.
12407     *
12408     * @param callbackfn A function that accepts four arguments.
12409     * The reduce method calls the callbackfn function one time for each element in the array.
12410     * The first call to the callbackfn function provides array first element value as an argument
12411     *
12412     * @returns The value that results from running the callback function to completion over the entire typed array.
12413     * calling reduce method on an empty array without an initial value creates a TypeError
12414     */
12415    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
12416        if (this.lengthInt == 0) {
12417            throw new TypeError("Reduce of empty array with no initial value")
12418        }
12419
12420        let accumulatedValue = this.getUnsafe(0) as number
12421        for (let i = 1; i < this.lengthInt; ++i) {
12422            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12423        }
12424        return accumulatedValue
12425    }
12426
12427    /**
12428     * Calls the specified callback function for all the elements in an array.
12429     * The return value of the callback function is the accumulated result,
12430     * and is provided as an argument in the next call to the callback function.
12431     *
12432     * @param callbackfn A function that accepts three arguments.
12433     * The reduce method calls the callbackfn function one time for each element in the array.
12434     * The first call to the callbackfn function provides array first element value as an argument
12435     *
12436     * @returns The value that results from running the callback function to completion over the entire typed array.
12437     * calling reduce method on an empty array without an initial value creates a TypeError
12438     */
12439    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
12440        return this.reduce(
12441                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12442                        callbackfn(prevVal, currVal, currIndex))
12443    }
12444
12445    /**
12446     * Calls the specified callback function for all the elements in an array.
12447     * The return value of the callback function is the accumulated result,
12448     * and is provided as an argument in the next call to the callback function.
12449     *
12450     * @param callbackfn A function that accepts two arguments.
12451     * The reduce method calls the callbackfn function one time for each element in the array.
12452     * The first call to the callbackfn function provides array first element value as an argument
12453     *
12454     * @returns The value that results from running the callback function to completion over the entire typed array.
12455     * calling reduce method on an empty array without an initial value creates a TypeError
12456     */
12457    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
12458        return this.reduce(
12459                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12460                        callbackfn(prevVal, currVal))
12461    }
12462
12463    /**
12464     * Calls the specified callback function for all the elements in an array.
12465     * The return value of the callback function is the accumulated result,
12466     * and is provided as an argument in the next call to the callback function.
12467     *
12468     * @param callbackfn A function that accepts one argument.
12469     * The reduce method calls the callbackfn function one time for each element in the array.
12470     * The first call to the callbackfn function provides array first element value as an argument
12471     *
12472     * @returns The value that results from running the callback function to completion over the entire typed array.
12473     * calling reduce method on an empty array without an initial value creates a TypeError
12474     */
12475    public reduce(callbackfn: (previousValue: number) => number): number {
12476        return this.reduce(
12477                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12478                        callbackfn(prevVal))
12479    }
12480
12481    /**
12482     * Calls the specified callback function for all the elements in an array.
12483     * The return value of the callback function is the accumulated result,
12484     * and is provided as an argument in the next call to the callback function.
12485     *
12486     * @param callbackfn A function that accepts no arguments.
12487     * The reduce method calls the callbackfn function one time for each element in the array.
12488     * The first call to the callbackfn function provides array first element value as an argument
12489     *
12490     * @returns The value that results from running the callback function to completion over the entire typed array.
12491     * calling reduce method on an empty array without an initial value creates a TypeError
12492     */
12493    public reduce(callbackfn: () => number): number {
12494        return this.reduce(
12495                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12496                        callbackfn())
12497    }
12498
12499
12500    /**
12501     * Calls the specified callback function for all the elements in an array, in descending order.
12502     * The return value of the callback function is the accumulated result,
12503     * and is provided as an argument in the next call to the callback function.
12504     *
12505     * @param callbackfn A function that accepts four arguments.
12506     * The reduceRight method calls the callbackfn function one time for each element in the array.
12507     *
12508     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12509     * The first call to the callbackfn function provides this value as an argument.
12510     *
12511     * @returns The value that results from running the callback function to completion over the entire typed array.
12512     */
12513    public reduceRight<U = number>(
12514                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
12515                initialValue: U): U {
12516        let accumulatedValue = initialValue
12517        for (let i = this.lengthInt - 1; i >= 0; --i) {
12518            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12519        }
12520        return accumulatedValue
12521    }
12522
12523    /**
12524     * Calls the specified callback function for all the elements in an array, in descending order.
12525     * The return value of the callback function is the accumulated result,
12526     * and is provided as an argument in the next call to the callback function.
12527     *
12528     * @param callbackfn A function that accepts three arguments.
12529     * The reduceRight method calls the callbackfn function one time for each element in the array.
12530     *
12531     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12532     * The first call to the callbackfn function provides this value as an argument.
12533     *
12534     * @returns The value that results from running the callback function to completion over the entire typed array.
12535     */
12536    public reduceRight<U = number>(
12537                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
12538                initialValue: U): U {
12539        return this.reduceRight(
12540                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12541                        callbackfn(prevVal, currVal, currIndex), initialValue)
12542    }
12543
12544    /**
12545     * Calls the specified callback function for all the elements in an array, in descending order.
12546     * The return value of the callback function is the accumulated result,
12547     * and is provided as an argument in the next call to the callback function.
12548     *
12549     * @param callbackfn A function that accepts two arguments.
12550     * The reduceRight method calls the callbackfn function one time for each element in the array.
12551     *
12552     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12553     * The first call to the callbackfn function provides this value as an argument.
12554     *
12555     * @returns The value that results from running the callback function to completion over the entire typed array.
12556     */
12557    public reduceRight<U = number>(
12558                callbackfn: (previousValue: U, currentValue: number) => U,
12559                initialValue: U): U {
12560        return this.reduceRight(
12561                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12562                        callbackfn(prevVal, currVal), initialValue)
12563    }
12564
12565    /**
12566     * Calls the specified callback function for all the elements in an array, in descending order.
12567     * The return value of the callback function is the accumulated result,
12568     * and is provided as an argument in the next call to the callback function.
12569     *
12570     * @param callbackfn A function that accepts one argument.
12571     * The reduceRight method calls the callbackfn function one time for each element in the array.
12572     *
12573     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12574     * The first call to the callbackfn function provides this value as an argument.
12575     *
12576     * @returns The value that results from running the callback function to completion over the entire typed array.
12577     */
12578    public reduceRight<U = number>(
12579                callbackfn: (previousValue: U) => U,
12580                initialValue: U): U {
12581        return this.reduceRight(
12582                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12583                        callbackfn(prevVal), initialValue)
12584    }
12585
12586    /**
12587     * Calls the specified callback function for all the elements in an array, in descending order.
12588     * The return value of the callback function is the accumulated result,
12589     * and is provided as an argument in the next call to the callback function.
12590     *
12591     * @param callbackfn A function that accepts no arguments.
12592     * The reduceRight method calls the callbackfn function one time for each element in the array.
12593     *
12594     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12595     * The first call to the callbackfn function provides this value as an argument.
12596     *
12597     * @returns The value that results from running the callback function to completion over the entire typed array.
12598     */
12599    public reduceRight<U = number>(
12600                callbackfn: () => U,
12601                initialValue: U): U {
12602        return this.reduceRight(
12603                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12604                        callbackfn(), initialValue)
12605    }
12606
12607    /**
12608     * Calls the specified callback function for all the elements in an array, in descending order.
12609     * The return value of the callback function is the accumulated result,
12610     * and is provided as an argument in the next call to the callback function.
12611     *
12612     * @param callbackfn A function that accepts four arguments.
12613     * The reduceRight method calls the callbackfn function one time for each element in the array.
12614     * The first call to the callbackfn function provides array last element value as an argument
12615     *
12616     * @returns The value that results from running the callback function to completion over the entire typed array.
12617     * calling reduceRight method on an empty array without an initial value creates a TypeError
12618     */
12619    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
12620        if (this.lengthInt == 0) {
12621            throw new TypeError("Reduce of empty array with no initial value")
12622        }
12623
12624        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
12625        for (let i = this.lengthInt - 2; i >= 0; --i) {
12626            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12627        }
12628        return accumulatedValue
12629    }
12630
12631    /**
12632     * Calls the specified callback function for all the elements in an array, in descending order.
12633     * The return value of the callback function is the accumulated result,
12634     * and is provided as an argument in the next call to the callback function.
12635     *
12636     * @param callbackfn A function that accepts three arguments.
12637     * The reduceRight method calls the callbackfn function one time for each element in the array.
12638     * The first call to the callbackfn function provides array last element value as an argument
12639     *
12640     * @returns The value that results from running the callback function to completion over the entire typed array.
12641     * calling reduceRight method on an empty array without an initial value creates a TypeError
12642     */
12643    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
12644        return this.reduceRight(
12645                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12646                        callbackfn(prevValue, currValue, currIndex))
12647    }
12648
12649    /**
12650     * Calls the specified callback function for all the elements in an array, in descending order.
12651     * The return value of the callback function is the accumulated result,
12652     * and is provided as an argument in the next call to the callback function.
12653     *
12654     * @param callbackfn A function that accepts two arguments.
12655     * The reduceRight method calls the callbackfn function one time for each element in the array.
12656     * The first call to the callbackfn function provides array last element value as an argument
12657     *
12658     * @returns The value that results from running the callback function to completion over the entire typed array.
12659     * calling reduceRight method on an empty array without an initial value creates a TypeError
12660     */
12661    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
12662        return this.reduceRight(
12663                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12664                        callbackfn(prevValue, currValue))
12665    }
12666
12667    /**
12668     * Calls the specified callback function for all the elements in an array, in descending order.
12669     * The return value of the callback function is the accumulated result,
12670     * and is provided as an argument in the next call to the callback function.
12671     *
12672     * @param callbackfn A function that accepts one argument.
12673     * The reduceRight method calls the callbackfn function one time for each element in the array.
12674     * The first call to the callbackfn function provides array last element value as an argument
12675     *
12676     * @returns The value that results from running the callback function to completion over the entire typed array.
12677     * calling reduceRight method on an empty array without an initial value creates a TypeError
12678     */
12679    public reduceRight(callbackfn: (previousValue: number) => number): number {
12680        return this.reduceRight(
12681                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12682                        callbackfn(prevValue))
12683    }
12684
12685    /**
12686     * Calls the specified callback function for all the elements in an array, in descending order.
12687     * The return value of the callback function is the accumulated result,
12688     * and is provided as an argument in the next call to the callback function.
12689     *
12690     * @param callbackfn A function that accepts no arguments.
12691     * The reduceRight method calls the callbackfn function one time for each element in the array.
12692     * The first call to the callbackfn function provides array last element value as an argument
12693     *
12694     * @returns The value that results from running the callback function to completion over the entire typed array.
12695     * calling reduceRight method on an empty array without an initial value creates a TypeError
12696     */
12697    public reduceRight(callbackfn: () => number): number {
12698        return this.reduceRight(
12699                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12700                        callbackfn())
12701    }
12702
12703   /**
12704    * Creates a new Float32Array using fn(arr[i]) over all elements of current Float32Array.
12705    *
12706    * @param fn a function to apply for each element of current Float32Array
12707    *
12708    * @returns a new Float32Array where for each element from current Float32Array fn was applied
12709    */
12710    public map(fn: (val: number, index: number, array: Float32Array) => number): Float32Array {
12711        let resBuf = new ArrayBuffer(this.lengthInt * Float32Array.BYTES_PER_ELEMENT as int)
12712        let res = new Float32Array(resBuf, 0, resBuf.getByteLength() / Float32Array.BYTES_PER_ELEMENT as int)
12713        for (let i = 0; i < this.lengthInt; ++i) {
12714            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as float)
12715        }
12716        return res
12717    }
12718
12719    /**
12720     * Creates a new Float32Array using fn(arr[i], i) over all elements of current Float32Array
12721     *
12722     * @param fn a function to apply for each element of current Float32Array
12723     *
12724     * @returns a new Float32Array where for each element from current Float32Array fn was applied
12725     */
12726    public map(fn: (val: number, index: number) => number): Float32Array {
12727        let newF: (val: number, index: number, array: Float32Array) => number =
12728            (val: number, index: number, array: Float32Array): number => { return fn(val, index) }
12729        return this.map(newF)
12730    }
12731
12732    /**
12733     * Creates a new Float32Array using fn(arr[i]) over all elements of current Float32Array
12734     *
12735     * @param fn a function to apply for each element of current Float32Array
12736     *
12737     * @returns a new Float32Array where for each element from current Float32Array fn was applied
12738     */
12739    public map(fn: (val: number) => number): Float32Array {
12740        let newF: (val: number, index: number, array: Float32Array) => number =
12741            (val: number, index: number, array: Float32Array): number => { return fn(val) }
12742        return this.map(newF)
12743    }
12744
12745    /**
12746     * Creates a new Float32Array using fn() over all elements of current Float32Array
12747     *
12748     * @param fn a function to apply for each element of current Float32Array
12749     *
12750     * @returns a new Float32Array where for each element from current Float32Array fn was applied
12751     */
12752    public map(fn: () => number): Float32Array {
12753        let newF: (val: number, index: number, array: Float32Array) => number =
12754            (val: number, index: number, array: Float32Array): number => { return fn() }
12755        return this.map(newF)
12756    }
12757
12758
12759    /**
12760     * Determines whether the specified callback function returns true for all elements of an array.
12761     *
12762     * @param predicate A function that accepts three arguments.
12763     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12764     * or until the end of the array.
12765     *
12766     * @returns true unless predicate function returns a false for an array element,
12767     * in which case false is immediately returned.
12768     */
12769    public every(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
12770        for (let i = 0; i < this.lengthInt; ++i) {
12771            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
12772                return false
12773            }
12774        }
12775        return true
12776    }
12777
12778    /**
12779     * Determines whether the specified callback function returns true for all elements of an array.
12780     *
12781     * @param predicate A function that accepts two arguments.
12782     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12783     * or until the end of the array.
12784     *
12785     * @returns true unless predicate function returns a false for an array element,
12786     * in which case false is immediately returned.
12787     */
12788    public every(predicate: (element: number, index: number) => boolean): boolean {
12789        return this.every((element: number, index: number, array: Float32Array): boolean => predicate(element, index))
12790    }
12791
12792    /**
12793     * Determines whether the specified callback function returns true for all elements of an array.
12794     *
12795     * @param predicate A function that accepts no arguments.
12796     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12797     * or until the end of the array.
12798     *
12799     * @returns true unless predicate function returns a false for an array element,
12800     * in which case false is immediately returned.
12801     */
12802    public every(predicate: () => boolean): boolean {
12803        return this.every((element: number, index: number, array: Float32Array): boolean => predicate())
12804    }
12805
12806    /**
12807     * Creates a new Float32Array from current Float32Array based on a condition fn.
12808     *
12809     * @param fn the condition to apply for each element
12810     *
12811     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12812     */
12813    public filter(fn: (val: number, index: number, array: Float32Array) => boolean): Float32Array {
12814        let markers = new boolean[this.lengthInt]
12815        let resLen = 0
12816        for (let i = 0; i < this.lengthInt; ++i) {
12817            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
12818            if (markers[i]) {
12819                ++resLen
12820            }
12821        }
12822        let resBuf = new ArrayBuffer(resLen * Float32Array.BYTES_PER_ELEMENT as int)
12823        let res = new Float32Array(resBuf, 0)
12824        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
12825            if (markers[i]) {
12826                res.set(j, this.getUnsafe(i))
12827                ++j
12828            }
12829        }
12830        return res
12831    }
12832
12833    /**
12834     * creates a new Float32Array from current Float32Array based on a condition fn
12835     *
12836     * @param fn the condition to apply for each element
12837     *
12838     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12839     */
12840    public filter(fn: (val: number, index: number) => boolean): Float32Array {
12841        let newF: (val: number, index: number, array: Float32Array) => boolean =
12842            (val: number, index: number, array: Float32Array): boolean => { return fn(val, index as number) }
12843        return this.filter(newF)
12844    }
12845
12846    /**
12847     * creates a new Float32Array from current Float32Array based on a condition fn
12848     *
12849     * @param fn the condition to apply for each element
12850     *
12851     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12852     */
12853    public filter(fn: () => boolean): Float32Array {
12854        let newF: (val: number, index: number, array: Float32Array) => boolean =
12855            (val: number, index: number, array: Float32Array): boolean => { return fn() }
12856        return this.filter(newF)
12857    }
12858
12859    /**
12860     * Returns the value of the first element in the array where predicate is true, and undefined
12861     * otherwise
12862     *
12863     * @param predicate find calls predicate once for each element of the array, in ascending
12864     * order, until it finds one where predicate returns true. If such an element is found, find
12865     * immediately returns that element value. Otherwise, find returns undefined
12866     *
12867     * @returns number | undefined
12868     */
12869    public find(predicate: (value: number, index: number, obj: Float32Array) => boolean): number | undefined {
12870        for (let i = 0; i < this.lengthInt; ++i) {
12871            let val = this.getUnsafe(i)
12872            if (predicate(val as number, i as number, this)) {
12873                return val as number
12874            }
12875        }
12876        return undefined
12877    }
12878
12879    /**
12880     * Returns the value of the first element in the array where predicate is true, and undefined
12881     * otherwise
12882     *
12883     * @param predicate find calls predicate once for each element of the array, in ascending
12884     * order, until it finds one where predicate returns true. If such an element is found, find
12885     * immediately returns that element value. Otherwise, find returns undefined
12886     *
12887     * @returns number | undefined
12888     */
12889    public find(predicate: (value: number, index: number) => boolean): number | undefined {
12890        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate(value, index))
12891    }
12892
12893    /**
12894     * Returns the index of the first element in the array where predicate is true, and -1
12895     * otherwise
12896     *
12897     * @param predicate find calls predicate once for each element of the array, in ascending
12898     * order, until it finds one where predicate returns true. If such an element is found,
12899     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12900     *
12901     * @returns number
12902     */
12903    public findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean): number {
12904        for (let i = 0; i < this.lengthInt; ++i) {
12905            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
12906                return i as number
12907            }
12908        }
12909        return -1 as number
12910    }
12911
12912    /**
12913     * Returns the index of the first element in the array where predicate is true, and -1
12914     * otherwise
12915     *
12916     * @param predicate find calls predicate once for each element of the array, in ascending
12917     * order, until it finds one where predicate returns true. If such an element is found,
12918     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12919     *
12920     * @returns number
12921     */
12922    public findIndex(predicate: (value: number, index: number) => boolean): number {
12923        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate(value, index as number)) as number
12924    }
12925
12926    /**
12927     * Returns the index of the first element in the array where predicate is true, and -1
12928     * otherwise
12929     *
12930     * @param predicate find calls predicate once for each element of the array, in ascending
12931     * order, until it finds one where predicate returns true. If such an element is found,
12932     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12933     *
12934     * @returns number
12935     */
12936    public findIndex(predicate: () => boolean): number {
12937        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate()) as number
12938    }
12939
12940    /**
12941     * Finds the last element in the Float32Array that satisfies the condition
12942     *
12943     * @param fn condition
12944     *
12945     * @returns the last element that satisfies fn
12946     */
12947    public findLast(fn: (val: number, index: number, array: Float32Array) => boolean): float {
12948        for (let i = this.lengthInt - 1; i >= 0; --i) {
12949            let val = this.getUnsafe(i)
12950            if (fn(val as number, i as number, this)) {
12951                return val
12952            }
12953        }
12954        throw new Error("Float32Array.findLast: not implemented if an element was not found")
12955    }
12956
12957    /**
12958     * Finds the last element in the Float32Array that satisfies the condition
12959     *
12960     * @param fn condition
12961     *
12962     * @returns the last element that satisfies fn
12963     */
12964    public findLast(fn: (val: number, index: number) => boolean): float {
12965        let newF: (val: number, index: number, array: Float32Array) => boolean =
12966            (val: number, index: number, array: Float32Array): boolean => { return fn(val as number, index as number) }
12967        return this.findLast(newF)
12968    }
12969
12970    /**
12971     * Finds an index of the last element in the Float32Array that satisfies the condition
12972     *
12973     * @param fn condition
12974     *
12975     * @returns the index of the last element that satisfies fn, -1 otherwise
12976     */
12977    public findLastIndex(fn: (val: number, index: number, array: Float32Array) => boolean): number {
12978        for (let i = this.lengthInt - 1; i >= 0; --i) {
12979            let val = this.getUnsafe(i)
12980            if (fn(val as number, i as number, this)) {
12981                return i
12982            }
12983        }
12984        return -1 as number
12985    }
12986
12987    /**
12988     * Finds an index of the last element in the Float32Array that satisfies the condition
12989     *
12990     * @param fn condition
12991     *
12992     * @returns the index of the last element that satisfies fn, -1 otherwise
12993     */
12994    public findLastIndex(fn: (val: number, index: number) => boolean): number {
12995        let newF: (val: number, index: number, array: Float32Array) => boolean =
12996            (val: number, index: number, array: Float32Array): boolean => { return fn(val, index as number) }
12997        return this.findLastIndex(newF) as number
12998    }
12999
13000    /**
13001     * Performs the specified action for each element in Float32Array
13002     *
13003     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
13004     * callbackfn function one time for each element in the array.
13005     *
13006     * @returns None
13007     */
13008    public forEach(callbackfn: (value: number, index: number, array: Float32Array) => void): void {
13009        for (let i = 0; i < this.lengthInt; ++i) {
13010            callbackfn(this.getUnsafe(i) as number, i as number, this)
13011        }
13012    }
13013
13014    /**
13015     * Performs the specified action for each element in Float32Array
13016     *
13017     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
13018     * callbackfn function one time for each element in the array.
13019     *
13020     * @returns None
13021     */
13022    public forEach(callbackfn: (value: number, index: number) => void): void {
13023        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn(value, index))
13024    }
13025
13026    /**
13027     * Performs the specified action for each element in Float32Array
13028     *
13029     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
13030     * callbackfn function one time for each element in the array.
13031     *
13032     * @returns None
13033     */
13034    public forEach(callbackfn: () => void): void {
13035        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn())
13036    }
13037
13038    /**
13039     * Returns the object itself
13040     *
13041     * @returns Float32Array
13042     */
13043    public valueOf(): Float32Array {
13044        return this
13045    }
13046
13047    internal getUnsafe(index: int): float {
13048        let byteIndex = index * Float32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
13049        let res : int = 0
13050        let byteVal : int
13051        if (IS_LITTLE_ENDIAN) {
13052            if (this.buffer instanceof ArrayBuffer) {
13053                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13054                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
13055                    byteVal &= 0xff
13056                    res = (res | byteVal << (8 * i)) as int
13057                }
13058            } else if (this.buffer instanceof SharedArrayBuffer) {
13059                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13060                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
13061                    byteVal &= 0xff
13062                    res = (res | byteVal << (8 * i)) as int
13063                }
13064            } else {
13065                throw new Error("unexpected type of ArrayBufferLike")
13066            }
13067            return Float.bitCastFromInt(res)
13068        } else {
13069            if (this.buffer instanceof ArrayBuffer) {
13070                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13071                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 3 - i)
13072                    byteVal &= 0xff
13073                    res = (res | byteVal << (8 * i)) as int
13074                }
13075            } else if (this.buffer instanceof SharedArrayBuffer) {
13076                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13077                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 3 - i)
13078                    byteVal &= 0xff
13079                    res = (res | byteVal << (8 * i)) as int
13080                }
13081            } else {
13082                throw new Error("unexpected type of ArrayBufferLike")
13083            }
13084            return Float.bitCastFromInt(res)
13085        }
13086    }
13087
13088    internal setUnsafe(insertPos: int, val: float): void {
13089        let startByte = insertPos * Float32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
13090        let bits = Float.bitCastToInt(val)
13091        if (IS_LITTLE_ENDIAN) {
13092            if (this.buffer instanceof ArrayBuffer) {
13093                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13094                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
13095                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
13096                }
13097            } else if (this.buffer instanceof SharedArrayBuffer) {
13098                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
13099                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
13100                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
13101                }
13102            } else {
13103                throw new Error("unexpected type of ArrayBufferLike")
13104            }
13105        } else {
13106            if (this.buffer instanceof ArrayBuffer) {
13107                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; i++) {
13108                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
13109                    (this.buffer as ArrayBuffer).set(startByte + 3 - i, byteVal)
13110                }
13111            } else if (this.buffer instanceof SharedArrayBuffer) {
13112                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; i++) {
13113                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
13114                    (this.buffer as SharedArrayBuffer).set(startByte + 3 - i, byteVal)
13115                }
13116            } else {
13117                throw new Error("unexpected type of ArrayBufferLike")
13118            }
13119        }
13120    }
13121
13122    /** Underlying ArrayBufferLike */
13123    public readonly buffer: ArrayBufferLike
13124
13125    /** Byte offset within the underlying ArrayBufferLike */
13126    public readonly byteOffset: number
13127
13128    /** Number of bytes used */
13129    public readonly byteLength: number
13130
13131    /** String \"Float32Array\" */
13132    public readonly name = "Float32Array"
13133}
13134
13135class Float64ArrayIteratorKeys implements IterableIterator<number> {
13136    private length: int
13137    private idx: int = 0
13138
13139    constructor(parent: Float64Array) {
13140        this.length = parent.length as int
13141    }
13142
13143    public override $_iterator(): IterableIterator<number> {
13144        return this
13145    }
13146
13147    override next(): IteratorResult<number> {
13148        if (this.idx < 0 || this.idx >= this.length) {
13149            return new IteratorResult<number>()
13150        }
13151        return new IteratorResult<number>(false, this.idx++ as number)
13152    }
13153}
13154
13155class Float64ArrayIterator implements IterableIterator<Number> {
13156    private parent: Float64Array
13157    private idx: int = 0
13158
13159    constructor(parent: Float64Array) {
13160        this.parent = parent
13161    }
13162
13163    public override $_iterator(): IterableIterator<Number> {
13164        return this
13165    }
13166
13167    override next(): IteratorResult<Number> {
13168        if (this.idx < 0 || this.idx >= this.parent.length as int) {
13169            return new IteratorResult<Number>()
13170        }
13171        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
13172    }
13173}
13174
13175class Float64ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
13176    private parent: Float64Array
13177    private idx: int = 0
13178
13179    constructor(parent: Float64Array) {
13180        this.parent = parent
13181    }
13182
13183    public override $_iterator(): IterableIterator<[Number, Number]> {
13184        return this
13185    }
13186
13187    override next(): IteratorResult<[Number, Number]> {
13188        if (this.idx < 0 || this.idx >= this.parent.length as int) {
13189            return new IteratorResult<[Number, Number]>()
13190        }
13191        return new IteratorResult<[Number, Number]>(
13192            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
13193        )
13194    }
13195}
13196
13197
13198/**
13199 * JS Float64Array API-compatible class
13200 */
13201export final class Float64Array implements Iterable<Number>, ArrayLike<Number> {
13202    public static readonly BYTES_PER_ELEMENT: number = 8
13203    internal readonly lengthInt: int
13204
13205    /**
13206     * Creates an empty Float64Array.
13207     */
13208    public constructor() {
13209        this(0 as int)
13210    }
13211
13212    /**
13213     * Creates an Float64Array with respect to data accessed via Iterable<Number> interface
13214     */
13215    public constructor(elements: Iterable<Number>) {
13216        const items: Object = elements as Object
13217        if (items instanceof ArrayLike) {
13218            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
13219            this.byteLength = arr.length as int * Float64Array.BYTES_PER_ELEMENT as int
13220            this.lengthInt = arr.length as int
13221            this.buffer = new ArrayBuffer(this.byteLength as int)
13222            this.byteOffset = 0
13223            for (let i: int = 0; i < this.lengthInt; ++i) {
13224                this.setUnsafe(i, arr.$_get(i).doubleValue())
13225            }
13226        } else {
13227          let x = Float64Array.from(elements)
13228          this.byteLength = x.byteLength
13229          this.lengthInt = x.lengthInt
13230          this.buffer = x.buffer
13231          this.byteOffset = x.byteOffset
13232        }
13233    }
13234
13235    /**
13236     * Creates an Float64Array with respect to data, byteOffset and length.
13237     *
13238     * @param buf data initializer
13239     *
13240     * @param byteOffset byte offset from begin of the buf
13241     *
13242     * @param length size of elements of type double in newly created Float64Array
13243     */
13244    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
13245        let intByteOffset: int = 0
13246        if (byteOffset != undefined) {
13247            intByteOffset = byteOffset.intValue()
13248            if (intByteOffset < 0) {
13249                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
13250            }
13251        }
13252        let intByteLength: int
13253        if (buf instanceof ArrayBuffer) {
13254            intByteLength = (buf as ArrayBuffer).getByteLength()
13255        } else if (buf instanceof SharedArrayBuffer) {
13256            intByteLength = (buf as SharedArrayBuffer).getByteLength()
13257        } else {
13258            throw new Error("unexpected type of ArrayBufferLike")
13259        }
13260        intByteLength = intByteLength - intByteOffset
13261        if (intByteLength < 0) {
13262            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
13263        }
13264
13265        if (intByteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13266            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13267        }
13268        if (intByteOffset % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13269            throw new RangeError("byteOffset should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13270        }
13271
13272        let intLength: int
13273        if (length != undefined) {
13274            intLength = length.intValue()
13275            if (intLength > intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
13276                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
13277            }
13278        } else {
13279            intLength = intByteLength / Float64Array.BYTES_PER_ELEMENT as int
13280        }
13281        if (intLength < 0) {
13282            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
13283        }
13284        if (intLength < intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
13285            intByteLength = intLength * Float64Array.BYTES_PER_ELEMENT as int
13286        }
13287        this.byteLength = intByteLength
13288        this.byteOffset = intByteOffset
13289        this.lengthInt = intLength
13290        this.buffer = buf
13291    }
13292
13293    /**
13294     * Creates an Float64Array with respect to data, byteOffset and length.
13295     *
13296     * @param buf data initializer
13297     *
13298     * @param byteOffset byte offset from begin of the buf
13299     *
13300     * @param length size of elements of type double in newly created Float64Array
13301     */
13302    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
13303        this(buf, byteOffset, undefined)
13304    }
13305
13306    /**
13307     * Creates an Float64Array with respect to data, byteOffset and length.
13308     *
13309     * @param buf data initializer
13310     *
13311     * @param byteOffset byte offset from begin of the buf
13312     *
13313     * @param length size of elements of type double in newly created Float64Array
13314     */
13315    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
13316        this(buf, new Number(byteOffset), new Number(length))
13317    }
13318
13319    /**
13320     * Creates an Float64Array with respect to data, byteOffset and length.
13321     *
13322     * @param buf data initializer
13323     *
13324     * @param byteOffset byte offset from begin of the buf
13325     *
13326     * @param length size of elements of type double in newly created Float64Array
13327     */
13328    public constructor(buf: ArrayBufferLike, byteOffset: number) {
13329        this(buf, new Number(byteOffset), undefined)
13330    }
13331
13332    /**
13333     * Creates an Float64Array with respect to data, byteOffset and length.
13334     *
13335     * @param buf data initializer
13336     *
13337     * @param byteOffset byte offset from begin of the buf
13338     *
13339     * @param length size of elements of type double in newly created Float64Array
13340     */
13341    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
13342        this(buf, new Number(byteOffset), new Number(length))
13343    }
13344
13345    /**
13346     * Creates an Float64Array with respect to buf and byteOffset.
13347     *
13348     * @param buf data initializer
13349     *
13350     * @param byteOffset byte offset from begin of the buf
13351     */
13352    public constructor(buf: ArrayBufferLike, byteOffset: int) {
13353        this(buf, new Number(byteOffset), undefined)
13354    }
13355
13356    /**
13357     * Creates an Float64Array with respect to buf.
13358     *
13359     * @param buf data initializer
13360     */
13361    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
13362        if (buf instanceof ArrayBuffer) {
13363            this.byteLength = (buf as ArrayBuffer).getByteLength()
13364            if (this.byteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13365               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13366            }
13367            this.lengthInt = this.byteLength / Float64Array.BYTES_PER_ELEMENT as int
13368            this.buffer = buf as ArrayBuffer
13369            this.byteOffset = 0
13370        } else if (buf instanceof SharedArrayBuffer) {
13371            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
13372            if (this.byteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13373               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13374            }
13375            this.lengthInt = this.byteLength / Float64Array.BYTES_PER_ELEMENT as int
13376            this.buffer = buf as SharedArrayBuffer
13377            this.byteOffset = 0
13378        } else if (buf instanceof ArrayLike) {
13379            // NOTE (ikorobkov): dealing with this overload is tricky
13380            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
13381            let arr = Array.from<Number>((buf as ArrayLike<Number>))
13382            this.byteLength = arr.length as int * Float64Array.BYTES_PER_ELEMENT as int
13383            this.lengthInt = arr.length as int
13384            this.buffer = new ArrayBuffer(this.byteLength as int)
13385            this.byteOffset = 0
13386            for (let i: int = 0; i < this.lengthInt; ++i) {
13387                this.setUnsafe(i, arr.$_get(i).doubleValue())
13388            }
13389        } else {
13390            throw new Error("unexpected type of buf")
13391        }
13392    }
13393
13394    /**
13395     * Creates an Float64Array with respect to length.
13396     *
13397     * @param length data initializer
13398     */
13399    public constructor(length: int) {
13400        if (length < 0) {
13401            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
13402        }
13403        this.lengthInt = length
13404        this.byteLength = length * Float64Array.BYTES_PER_ELEMENT as int
13405        this.byteOffset = 0
13406        this.buffer = new ArrayBuffer(this.byteLength as int)
13407    }
13408
13409    /**
13410     * Creates an Float64Array with respect to length.
13411     *
13412     * @param length data initializer
13413     */
13414    public constructor(length: number) {
13415        this(length as int)
13416    }
13417
13418    /**
13419     * Creates a copy of Float64Array.
13420     *
13421     * @param other data initializer
13422     */
13423    public constructor(other: Float64Array) {
13424        if (other.buffer instanceof ArrayBuffer) {
13425            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
13426        } else if (other.buffer instanceof SharedArrayBuffer) {
13427            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
13428        } else {
13429            throw new Error("unexpected type of buffer")
13430        }
13431        this.byteLength = other.byteLength
13432        this.lengthInt = other.length as int
13433        this.byteOffset = 0
13434    }
13435
13436    /**
13437     * Creates an Float64Array from number[]
13438     */
13439    public constructor(numbers: number[]) {
13440        this(numbers.length)
13441        for (let i: int = 0; i < this.lengthInt; ++i) {
13442            this.setUnsafe(i, numbers[i] as double)
13443        }
13444    }
13445
13446    /**
13447     * Creates an Float64Array from int[]
13448     */
13449    public constructor(numbers: int[]) {
13450        this(numbers.length)
13451        for (let i: int = 0; i < this.lengthInt; ++i) {
13452            this.setUnsafe(i, numbers[i] as double)
13453        }
13454    }
13455
13456    /**
13457     * Assigns val as element on index.
13458     *
13459     * @param val value to set
13460     *
13461     * @param index index to change
13462     */
13463    public $_set(index: number, val: number): void {
13464        this.$_set(index as int, val)
13465    }
13466
13467    /**
13468     * Assigns val as element on index.
13469     *
13470     * @param val value to set
13471     *
13472     * @param index index to change
13473     */
13474    public $_set(index: int, val: number): void {
13475        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
13476        if (index < 0 || index >= this.lengthInt) {
13477            throw new RangeError("invalid index")
13478        }
13479        this.setUnsafe(index, val as double)
13480    }
13481
13482    /**
13483     * Assigns val as element on index.
13484     *
13485     * @param val value to set
13486     *
13487     * @param index index to change
13488     */
13489    public $_set(index: number, val: int): void {
13490        this.$_set(index as int, val)
13491    }
13492
13493    /**
13494     * Assigns val as element on index.
13495     *
13496     * @param val value to set
13497     *
13498     * @param index index to change
13499     */
13500    public $_set(index: int, val: int): void {
13501        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
13502        if (index < 0 || index >= this.lengthInt) {
13503            throw new RangeError("invalid index")
13504        }
13505        this.setUnsafe(index, val as double)
13506    }
13507
13508    /** Number of double stored in Float64Array */
13509    public get length(): number {
13510        return this.lengthInt
13511    }
13512
13513    /**
13514     * Returns an instance of number at passed index.
13515     *
13516     * @param index index to look at
13517     *
13518     * @returns a primitive at index
13519     */
13520    public override $_get(index: number): Number {
13521        return this.$_get(index as int) as Number
13522    }
13523
13524    /**
13525     * Returns an instance of number at passed index.
13526     *
13527     * @param index index to look at
13528     *
13529     * @returns a primitive at index
13530     */
13531    public $_get(index: int): number {
13532        if (index < 0 || index >= this.lengthInt) {
13533            throw new RangeError("invalid index")
13534        }
13535        return this.getUnsafe(index) as number
13536    }
13537
13538    /**
13539     * Returns an instance of primitive type at passed index.
13540     *
13541     * @param index index to look at
13542     *
13543     * @returns a primitive at index
13544     */
13545    public at(index: number): Number | undefined {
13546        return this.at(index as int)
13547    }
13548
13549    /**
13550     * Returns an instance of primitive type at passed index.
13551     *
13552     * @param index index to look at
13553     *
13554     * @returns a primitive at index
13555     */
13556    public at(index: int): Number | undefined {
13557        let k: int
13558        if (index >= 0) {
13559            k = index
13560        } else {
13561            k = this.lengthInt + index
13562        }
13563        if (k < 0 || k >= this.lengthInt) {
13564            return undefined
13565        }
13566        return new Number(this.getUnsafe(k))
13567    }
13568
13569    /**
13570     * Makes a copy of internal elements to targetPos from startPos to endPos.
13571     *
13572     * @param target insert index to place copied elements
13573     *
13574     * @param start start index to begin copy from
13575     *
13576     * @param end last index to end copy from, excluded
13577     *
13578     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13579     */
13580    public copyWithin(target: number, start: number, end?: number): Float64Array {
13581        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13582    }
13583
13584    /**
13585     * Makes a copy of internal elements to targetPos from startPos to endPos.
13586     *
13587     * @param target insert index to place copied elements
13588     *
13589     * @param start start index to begin copy from
13590     *
13591     * @param end last index to end copy from, excluded
13592     *
13593     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13594     */
13595    public copyWithin(target: int, start: number, end?: number): Float64Array {
13596        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13597    }
13598
13599    /**
13600     * Makes a copy of internal elements to targetPos from startPos to endPos.
13601     *
13602     * @param target insert index to place copied elements
13603     *
13604     * @param start start index to begin copy from
13605     *
13606     * @param end last index to end copy from, excluded
13607     *
13608     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13609     */
13610    public copyWithin(target: number, start: int, end?: number): Float64Array {
13611        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13612    }
13613
13614    /**
13615     * Makes a copy of internal elements to targetPos from startPos to endPos.
13616     *
13617     * @param target insert index to place copied elements
13618     *
13619     * @param start start index to begin copy from
13620     *
13621     * @param end last index to end copy from, excluded
13622     *
13623     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13624     */
13625    public copyWithin(target: int, start: int, end?: number): Float64Array {
13626        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13627    }
13628
13629    /**
13630     * Makes a copy of internal elements to targetPos from startPos to endPos.
13631     *
13632     * @param target insert index to place copied elements
13633     *
13634     * @param start start index to begin copy from
13635     *
13636     * @param end last index to end copy from, excluded
13637     *
13638     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13639     */
13640    public copyWithin(target: int, start: int, end: int): Float64Array {
13641        let toPos = normalizeIndex(target, this.lengthInt)
13642        let fromPos = normalizeIndex(start, this.lengthInt)
13643        const finalPos = normalizeIndex(end, this.lengthInt)
13644        let count: int = finalPos - fromPos
13645        if (count > (this.lengthInt - toPos)) {
13646            count = this.lengthInt - toPos
13647        }
13648        let direction: int = 1
13649        if ((fromPos < toPos) && (toPos < fromPos + count)) {
13650            fromPos = fromPos + count - 1
13651            toPos   = toPos   + count - 1
13652            direction = -1
13653        }
13654        while (count > 0) {
13655            const value = this.getUnsafe(fromPos)
13656            this.setUnsafe(toPos, value)
13657            fromPos = fromPos + direction
13658            toPos = toPos + direction
13659            --count
13660        }
13661        return this
13662    }
13663
13664    /**
13665     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
13666     *
13667     * @param target insert index to place copied elements
13668     *
13669     * See rules of parameters normalization:
13670     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
13671     */
13672    public copyWithin(target: number): Float64Array {
13673        return this.copyWithin(target as int)
13674    }
13675
13676    /**
13677     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
13678     *
13679     * @param target insert index to place copied elements
13680     *
13681     * See rules of parameters normalization:
13682     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
13683     */
13684    public copyWithin(target: int): Float64Array {
13685        return this.copyWithin(target, 0, this.lengthInt)
13686    }
13687
13688    /**
13689     * Returns an array of key, value pairs for every entry in the Float64Array
13690     *
13691     * @returns key, value pairs for every entry in the array
13692     */
13693    public entries(): IterableIterator<[Number, Number]> {
13694        return new Float64ArrayIteratorEntries(this)
13695    }
13696
13697    /**
13698     * Fills the Float64Array with specified value
13699     *
13700     * @param value new valuy
13701     *
13702     * @returns modified Float64Array
13703     */
13704    public fill(value: number, start?: number, end?: number): this {
13705        this.fill(value as double, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
13706        return this
13707    }
13708
13709    /**
13710     * Fills the Float64Array with specified value
13711     *
13712     * @param value new valuy
13713     *
13714     * @returns modified Float64Array
13715     */
13716    public fill(value: number, start: int, end?: number): this {
13717        this.fill(value as double, start as int, asIntOrDefault(end, this.lengthInt))
13718        return this
13719    }
13720
13721    /**
13722     * Fills the Float64Array with specified value
13723     *
13724     * @param value new valuy
13725     *
13726     * @returns modified Float64Array
13727     */
13728    public fill(value: number, start: int, end: number): this {
13729        this.fill(value as double, start as int, end as int)
13730        return this
13731    }
13732
13733    /**
13734     * Fills the Float64Array with specified value
13735     *
13736     * @param value new valuy
13737     *
13738     * @returns modified Float64Array
13739     */
13740    public fill(value: number, start: number, end: int): this {
13741        this.fill(value as double, start as int, end as int)
13742        return this
13743    }
13744
13745    /**
13746     * Fills the Float64Array with specified value
13747     *
13748     * @param value new valuy
13749     *
13750     * @returns modified Float64Array
13751     */
13752    public fill(value: number, start: int, end: int): this {
13753        const k = normalizeIndex(start, this.lengthInt)
13754        const finalPos = normalizeIndex(end, this.lengthInt)
13755        for (let i: int = k; i < finalPos; ++i) {
13756            this.setUnsafe(i, value)
13757        }
13758        return this
13759    }
13760
13761    /**
13762     * Assigns val as element on insertPos.
13763     * @description Added to avoid (un)packing a single value into array to use overloaded set(double[], insertPos)
13764     *
13765     * @param val value to set
13766     *
13767     * @param insertPos index to change
13768     */
13769    public set(insertPos: number, val: number): void {
13770        this.$_set(insertPos, val)
13771    }
13772
13773    /**
13774     * Assigns val as element on insertPos.
13775     * @description Added to avoid (un)packing a single value into array to use overloaded set(double[], insertPos)
13776     *
13777     * @param val value to set
13778     *
13779     * @param insertPos index to change
13780     */
13781    public set(insertPos: int, val: double): void {
13782        this.$_set(insertPos, val)
13783    }
13784
13785    /**
13786     * Copies all elements of arr to the current Float64Array starting from insertPos.
13787     *
13788     * @param arr array to copy data from
13789     *
13790     * @param insertPos start index where data from arr will be inserted
13791     *
13792     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
13793     */
13794    public set(arr: number[], insertPos: number): void {
13795        const offset = insertPos as int
13796        if (offset < 0 || offset + arr.length > this.lengthInt) {
13797            throw new RangeError("offset is out of bounds")
13798        }
13799        for (let i = 0; i < arr.length as int; ++i) {
13800            this.setUnsafe(offset + i, arr[i] as double)
13801        }
13802    }
13803
13804    /**
13805     * Copies all elements of arr to the current Float64Array starting from insertPos.
13806     *
13807     * @param arr array to copy data from
13808     *
13809     * @param insertPos start index where data from arr will be inserted
13810     *
13811     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
13812     */
13813    public set(arr: double[], insertPos: int): void {
13814        const offset = insertPos as int
13815        if (offset < 0 || offset + arr.length > this.lengthInt) {
13816            throw new RangeError("offset is out of bounds")
13817        }
13818        for (let i = 0; i < arr.length as int; ++i) {
13819            this.setUnsafe(offset + i, arr[i])
13820        }
13821    }
13822
13823    /**
13824     * Copies all elements of arr to the current Float64Array.
13825     *
13826     * @param arr array to copy data from
13827     */
13828    public set(arr: double[]): void {
13829        this.set(arr, 0 as int)
13830    }
13831
13832    /**
13833     * Copies elements from an ArrayLike object to the Float64Array.
13834     *
13835     * @param array An ArrayLike object containing the elements to copy.
13836     *
13837     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
13838     */
13839    public set(array: ArrayLike<number>, offset: number = 0): void {
13840        const insertPos = offset as int
13841        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
13842            throw new RangeError("offset is out of bounds")
13843        }
13844        for (let i = 0; i < array.length as int; ++i) {
13845            this.setUnsafe(insertPos + i, array[i] as double)
13846        }
13847    }
13848
13849    /**
13850     * Returns a new array from a set of elements.
13851     *
13852     * @param items a set of elements to include in the new array object.
13853     *
13854     * @returns new Float64Array
13855     */
13856    public static of(...items: number[]): Float64Array {
13857        let res = new Float64Array(items.length as int)
13858        for (let i: int = 0; i < items.length; i++) {
13859            res.setUnsafe(i, items[i])
13860        }
13861        return res
13862    }
13863
13864    /**
13865     * Returns a new array from a set of elements.
13866     *
13867     * @param items a set of elements to include in the new array object.
13868     *
13869     * @returns new Float64Array
13870     */
13871    public static of(...items: int[]): Float64Array {
13872        let res = new Float64Array(items.length as int)
13873        for (let i: int = 0; i < items.length; i++) {
13874            res.setUnsafe(i, items[i] as double)
13875        }
13876        return res
13877    }
13878
13879    /**
13880     * Returns a new array from a set of elements.
13881     *
13882     * @param items a set of elements to include in the new array object.
13883     *
13884     * @returns new Float64Array
13885     */
13886    public static of(): Float64Array {
13887        return new Float64Array(0 as int)
13888    }
13889
13890    /**
13891     * Creates an array from an array-like or iterable object.
13892     *
13893     * @param arrayLike An array-like or iterable object to convert to an array.
13894     *
13895     * @returns new Float64Array
13896     */
13897    public static from(arrayLike: ArrayLike<number>): Float64Array {
13898        return Float64Array.from<number>(arrayLike, (x: number, k: number): number => x)
13899    }
13900
13901    /**
13902     * Creates an array from an array-like or iterable object.
13903     *
13904     * @param arrayLike An array-like or iterable object to convert to an array.
13905     *
13906     * @param mapfn A mapping function to call on every element of the array.
13907     *
13908     * @returns new Float64Array
13909     */
13910    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float64Array {
13911        if (mapfn == undefined) {
13912            mapfn = (v: number, k: number): number => { return v }
13913        }
13914
13915        let iter = arrayLike.$_iterator()
13916        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
13917        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
13918        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
13919        //  we can make one pass through the iterator without the need for memory reallocation.
13920        const maybeLength = tryGetIteratorLength(arrayLike)
13921        if (maybeLength) {
13922            const result = new Float64Array(maybeLength)
13923            for (let i = 0; i < maybeLength; ++i) {
13924                const x = iter.next()
13925                if (x.done) {
13926                    return new Float64Array(result.buffer, 0, i)
13927                }
13928                result.setUnsafe(i, (mapfn)!(x.value!, i) as double)
13929            }
13930            return result
13931        }
13932
13933        // NOTE (templin.konstantin): Create builtin array as buffer
13934        let temp = new Float64Array(6)
13935        let index = new int[1]
13936        index[0] = 0
13937
13938        iteratorForEach<number>(iter, (x: number): void => {
13939            if (index[0] + 1 > temp.lengthInt) {
13940                // NOTE (templin.konstantin): Progressive reallocation
13941                const curLength = (temp.buffer as Buffer).getByteLength()
13942                const tb = new ArrayBuffer(curLength * 2)
13943                for (let i = 0; i < curLength; ++i) {
13944                    tb.set(i, (temp.buffer as Buffer).at(i))
13945                }
13946                temp = new Float64Array(tb)
13947            }
13948            temp.setUnsafe(index[0], (mapfn)!(x, index[0]) as double)
13949            index[0]++
13950        })
13951        return new Float64Array(temp.buffer, 0, index[0])
13952    }
13953
13954
13955    /**
13956     * Creates an array from an array-like or iterable object.
13957     *
13958     * @param arrayLike An array-like or iterable object to convert to an array.
13959     *
13960     * @param mapfn A mapping function to call on every element of the array.
13961     *
13962     * @returns new Float64Array
13963     */
13964    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Float64Array {
13965        let res = new Float64Array(arrayLike.length)
13966        // NOTE (ikorobkov): Please don't replace idx as int[1] with int-variable, because of value of single variable doesn't change (idx++) into lambda call by unknown reason
13967        const idx = new int[1]
13968        idx[0] = 0
13969        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
13970            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as double)
13971            idx[0] += 1
13972        })
13973        return res
13974    }
13975
13976    /**
13977     * Determines whether Float64Array includes a certain element, returning true or false as appropriate
13978     *
13979     * @param searchElement The element to search for
13980     *
13981     * @param fromIndex The position in this array at which to begin searching for searchElement
13982     *
13983     * @returns true if searchElement is in Float64Array, false otherwise
13984     */
13985    public includes(searchElement: number, fromIndex?: number): boolean {
13986        if (isNaN(searchElement)) {
13987            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
13988            for (let i = fromIndexInt; i < this.lengthInt; i++) {
13989                if (isNaN(this.getUnsafe(i))) {
13990                    return true
13991                }
13992            }
13993            return false
13994        }
13995        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
13996    }
13997
13998    /**
13999     * Returns the index of the first occurrence of a value in Float64Array.
14000     *
14001     * @param searchElement The value to locate in the array.
14002     *
14003     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
14004     *  search starts at index 0.
14005     *
14006     * @returns index of element if it presents, -1 otherwise
14007     */
14008    public indexOf(searchElement: number, fromIndex?: number): number {
14009        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
14010    }
14011
14012    /**
14013     * Returns the index of the first occurrence of a value in Float64Array.
14014     *
14015     * @param searchElement The value to locate in the array.
14016     *
14017     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
14018     *  search starts at index 0.
14019     *
14020     * @returns index of element if it presents, -1 otherwise
14021     */
14022    public indexOf(searchElement: number, fromIndex: int): number {
14023        if (isNaN(searchElement)) {
14024            return -1
14025        }
14026        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
14027        for (let i = fromIndex; i < this.lengthInt; i++) {
14028            if (this.getUnsafe(i) == searchElement) {
14029                return i
14030            }
14031        }
14032        return -1
14033    }
14034
14035    /**
14036     * Returns the index of the first occurrence of a value in Float64Array.
14037     *
14038     * @param searchElement The value to locate in the array.
14039     *
14040     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
14041     *  search starts at index 0.
14042     *
14043     * @returns index of element if it presents, -1 otherwise
14044     */
14045    public indexOf(searchElement: int, fromIndex: int): number {
14046        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
14047        for (let i = fromIndex; i < this.lengthInt; i++) {
14048            if (this.getUnsafe(i) == searchElement as double) {
14049                return i
14050            }
14051        }
14052        return -1
14053    }
14054
14055    /**
14056     * Returns the index of the first occurrence of a value in Float64Array.
14057     *
14058     * @param searchElement The value to locate in the array.
14059     *
14060     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
14061     *  search starts at index 0.
14062     *
14063     * @returns index of element if it presents, -1 otherwise
14064     */
14065    public indexOf(searchElement: int): number {
14066        return this.indexOf(searchElement, 0)
14067    }
14068
14069    /**
14070     * Adds all the elements of an array separated by the specified separator string
14071     *
14072     * @param separator A string used to separate one element of an array from the next in the
14073     * resulting String. If omitted, the array elements are separated with a comma
14074     *
14075     * @returns joined representation
14076     */
14077    public join(separator?: String): string {
14078        if (separator == undefined) {
14079            return this.join(",")
14080        }
14081        let res: StringBuilder = new StringBuilder("")
14082        for (let i = 0; i < this.lengthInt - 1; ++i) {
14083            res.append(this.getUnsafe(i) as number)
14084            res.append(separator)
14085        }
14086        if (this.lengthInt > 0) {
14087            res.append(this.getUnsafe(this.lengthInt - 1) as number)
14088        }
14089        return res.toString()
14090    }
14091
14092    /**
14093     * Returns an list of keys in Float64Array
14094     *
14095     * @returns iterator over keys
14096     */
14097    public keys(): IterableIterator<number> {
14098        return new Float64ArrayIteratorKeys(this)
14099    }
14100
14101    /**
14102     * Returns the index of the last occurrence of a value in Float64Array.
14103     *
14104     * @param searchElement The value to locate in the array.
14105     *
14106     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
14107     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
14108     *
14109     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
14110     */
14111    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
14112        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
14113    }
14114
14115    /**
14116     * Returns the index of the last occurrence of a value in Float64Array.
14117     *
14118     * @param searchElement The value to locate in the array.
14119     *
14120     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
14121     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
14122     *
14123     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
14124     */
14125    public lastIndexOf(searchElement: number): number {
14126        return this.lastIndexOf(searchElement, this.lengthInt - 1)
14127    }
14128
14129    /**
14130     * Returns the index of the last occurrence of a value in Float64Array.
14131     *
14132     * @param searchElement The value to locate in the array.
14133     *
14134     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
14135     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
14136     *
14137     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
14138     */
14139    public lastIndexOf(searchElement: number, fromIndex: int): number {
14140        if (isNaN(searchElement)) {
14141            return -1
14142        }
14143        if (this.lengthInt == 0) {
14144            return -1
14145        }
14146        let k: int = this.lengthInt + fromIndex
14147        if (fromIndex >= 0) {
14148            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
14149        }
14150        while (k >= 0) {
14151            if (this.getUnsafe(k) == searchElement) {
14152                return k
14153            }
14154            k--
14155        }
14156        return -1
14157    }
14158
14159    /**
14160     * Returns the index of the last occurrence of a value in Float64Array.
14161     *
14162     * @param searchElement The value to locate in the array.
14163     *
14164     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
14165     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
14166     *
14167     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
14168     */
14169    public lastIndexOf(searchElement: int, fromIndex: int): number {
14170        if (this.lengthInt == 0) {
14171            return -1
14172        }
14173        let k: int = this.lengthInt + fromIndex
14174        if (fromIndex >= 0) {
14175            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
14176        }
14177        while (k >= 0) {
14178            if (this.getUnsafe(k) == searchElement as double) {
14179                return k
14180            }
14181            k--
14182        }
14183        return -1
14184    }
14185
14186    /**
14187     * Returns the index of the last occurrence of a value in Float64Array.
14188     *
14189     * @param searchElement The value to locate in the array.
14190     *
14191     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
14192     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
14193     *
14194     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
14195     */
14196    public lastIndexOf(searchElement: int): number {
14197        return this.lastIndexOf(searchElement, this.lengthInt - 1)
14198    }
14199
14200    /**
14201    * Creates a new Float64Array using initializer
14202    *
14203    * @param data initializer
14204    *
14205    * @returns a new Float64Array from data
14206    */
14207    public of(data: Object[]): Float64Array {
14208        throw new Error("Float64Array.of: not implemented")
14209    }
14210
14211    /**
14212     * Creates a new Float64Array using reversed data from the current one
14213     *
14214     * @returns a new Float64Array using reversed data from the current one
14215     */
14216    public reverse(): Float64Array {
14217        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
14218            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
14219            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
14220            this.setUnsafe(i, tmp)
14221        }
14222        return this
14223    }
14224
14225    /**
14226     * Creates a slice of current Float64Array using range [begin, end)
14227     *
14228     * @param begin start index to be taken into slice
14229     *
14230     * @param end last index to be taken into slice
14231     *
14232     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
14233     *
14234     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
14235     */
14236    public slice(begin?: number, end?: number): Float64Array {
14237        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
14238    }
14239
14240    /**
14241     * Creates a slice of current Float64Array using range [begin, end)
14242     *
14243     * @param begin start index to be taken into slice
14244     *
14245     * @param end last index to be taken into slice
14246     *
14247     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
14248     *
14249     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
14250     */
14251    public slice(begin: number, end: number): Float64Array {
14252        return this.slice(begin as int, end as int)
14253    }
14254
14255    /**
14256     * Creates a slice of current Float64Array using range [begin, end)
14257     *
14258     * @param begin start index to be taken into slice
14259     *
14260     * @param end last index to be taken into slice
14261     *
14262     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
14263     *
14264     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
14265     */
14266    public slice(begin: number, end: int): Float64Array {
14267        return this.slice(begin as int, end as int)
14268    }
14269
14270    /**
14271     * Creates a slice of current Float64Array using range [begin, end)
14272     *
14273     * @param begin start index to be taken into slice
14274     *
14275     * @param end last index to be taken into slice
14276     *
14277     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
14278     *
14279     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
14280     */
14281    public slice(begin: int, end: number): Float64Array {
14282        return this.slice(begin as int, end as int)
14283    }
14284
14285    /**
14286     * Creates a slice of current Float64Array using range [begin, end)
14287     *
14288     * @param begin start index to be taken into slice
14289     *
14290     * @param end last index to be taken into slice
14291     *
14292     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
14293     *
14294     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
14295     */
14296    public slice(begin: int, end: int): Float64Array {
14297        const len: int = this.lengthInt
14298        const relStart = normalizeIndex(begin, len)
14299        const relEnd = normalizeIndex(end, len)
14300        let count = relEnd - relStart
14301        if (count < 0) {
14302            count = 0
14303        }
14304        if (this.buffer instanceof ArrayBuffer) {
14305            let buf = (this.buffer as ArrayBuffer).slice(relStart * Float64Array.BYTES_PER_ELEMENT as int, relEnd * Float64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
14306            return new Float64Array(buf)
14307        } else if (this.buffer instanceof SharedArrayBuffer) {
14308            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Float64Array.BYTES_PER_ELEMENT as int, relEnd * Float64Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
14309            return new Float64Array(buf)
14310        } else {
14311            throw new Error("unexpected type of buffer")
14312        }
14313    }
14314
14315    /**
14316     * Creates a slice of current Float64Array using range [begin, this.length).
14317     *
14318     * @param begin start index to be taken into slice
14319     *
14320     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
14321     */
14322    public slice(begin: number): Float64Array {
14323        return this.slice(begin as int)
14324    }
14325
14326    /**
14327     * Creates a slice of current Float64Array using range [begin, this.length).
14328     *
14329     * @param begin start index to be taken into slice
14330     *
14331     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
14332     */
14333    public slice(begin: int): Float64Array {
14334        return this.slice(begin, this.lengthInt)
14335    }
14336
14337    /**
14338     * Creates a Float64Array with the same underlying ArrayBufferLike
14339     *
14340     * @param begin start index, inclusive
14341     *
14342     * @param end last index, exclusive
14343     *
14344     * @returns new Float64Array with the same underlying ArrayBufferLike
14345     */
14346    public subarray(begin?: number, end?: number): Float64Array {
14347        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
14348    }
14349
14350    /**
14351     * Creates a Float64Array with the same underlying ArrayBufferLike
14352     *
14353     * @param begin start index, inclusive
14354     *
14355     * @param end last index, exclusive
14356     *
14357     * @returns new Float64Array with the same underlying ArrayBufferLike
14358     */
14359    public subarray(begin: number, end: number): Float64Array {
14360        return this.subarray(begin as int, end as int)
14361    }
14362
14363    /**
14364     * Creates a Float64Array with the same underlying ArrayBufferLike
14365     *
14366     * @param begin start index, inclusive
14367     *
14368     * @param end last index, exclusive
14369     *
14370     * @returns new Float64Array with the same underlying ArrayBufferLike
14371     */
14372    public subarray(begin: number, end: int): Float64Array {
14373        return this.subarray(begin as int, end as int)
14374    }
14375
14376    /**
14377     * Creates a Float64Array with the same underlying ArrayBufferLike
14378     *
14379     * @param begin start index, inclusive
14380     *
14381     * @param end last index, exclusive
14382     *
14383     * @returns new Float64Array with the same underlying ArrayBufferLike
14384     */
14385    public subarray(begin: int, end: number): Float64Array {
14386        return this.subarray(begin as int, end as int)
14387    }
14388
14389    /**
14390     * Creates a Float64Array with the same underlying ArrayBufferLike
14391     *
14392     * @param begin start index, inclusive
14393     *
14394     * @param end last index, exclusive
14395     *
14396     * @returns new Float64Array with the same underlying ArrayBufferLike
14397     */
14398    public subarray(begin: int, end: int): Float64Array {
14399        const len: int = this.lengthInt
14400        const relStart = normalizeIndex(begin, len)
14401        const relEnd = normalizeIndex(end, len)
14402        let count = relEnd - relStart
14403        if (count < 0) {
14404            count = 0
14405        }
14406        return new Float64Array(this.buffer, relStart * Float64Array.BYTES_PER_ELEMENT as int, count)
14407    }
14408
14409    /**
14410     * Creates a Float64Array with the same ArrayBufferLike
14411     *
14412     * @param begin start index, inclusive
14413     *
14414     * @returns new Float64Array with the same ArrayBufferLike
14415     */
14416    public subarray(begin: number): Float64Array {
14417        return this.subarray(begin as int, this.lengthInt)
14418    }
14419
14420    /**
14421     * Creates a Float64Array with the same ArrayBufferLike
14422     *
14423     * @param begin start index, inclusive
14424     *
14425     * @returns new Float64Array with the same ArrayBufferLike
14426     */
14427    public subarray(begin: int): Float64Array {
14428        return this.subarray(begin as int, this.lengthInt)
14429    }
14430
14431    /**
14432     * Converts Float64Array to a string with respect to locale
14433     *
14434     * @param locales
14435     *
14436     * @param options
14437     *
14438     * @returns string representation
14439     */
14440    public toLocaleString(locales: Object, options: Object): string {
14441        throw new Error("Float64Array.toLocaleString: not implemented")
14442    }
14443
14444    /**
14445     * Converts Float64Array to a string with respect to locale
14446     *
14447     * @param locales
14448     *
14449     * @returns string representation
14450     */
14451    public toLocaleString(locales: Object): string {
14452        return this.toLocaleString(new Object(), new Object())
14453    }
14454
14455    /**
14456     * Converts Float64Array to a string with respect to locale
14457     *
14458     * @returns string representation
14459     */
14460    public toLocaleString(): string {
14461        let res: StringBuilder = new StringBuilder("")
14462        for (let i = 0; i < this.lengthInt - 1; ++i) {
14463            res.append((this.getUnsafe(i) as Number).toLocaleString())
14464            res.append(",")
14465        }
14466        if (this.lengthInt > 0) {
14467            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
14468        }
14469        return res.toString()
14470    }
14471
14472    /**
14473     * Creates a reversed copy
14474     *
14475     * @returns a reversed copy
14476     */
14477    public toReversed(): Float64Array {
14478        return new Float64Array(this).reverse()
14479    }
14480
14481    /**
14482     * Creates a sorted copy
14483     *
14484     * @returns a sorted copy
14485     */
14486    public toSorted(): Float64Array {
14487        return new Float64Array(this).sort()
14488    }
14489
14490    /**
14491     * Returns a string representation of the Float64Array
14492     *
14493     * @returns a string representation of the Float64Array
14494     */
14495    public override toString(): string {
14496        return this.join(",")
14497    }
14498
14499    /**
14500     * Returns array values iterator
14501     *
14502     * @returns an iterator
14503     */
14504    public values(): IterableIterator<Number> {
14505        return new Float64ArrayIterator(this)
14506    }
14507
14508    /**
14509     * Iteratorable interface implementation
14510     *
14511     * @returns iterator over all elements
14512     */
14513    public override $_iterator(): IterableIterator<Number> {
14514        return this.values()
14515    }
14516
14517    /**
14518     * Creates a copy with replaced value on index
14519     *
14520     * @param index
14521     *
14522     * @param value
14523     *
14524     * @returns an Float64Array with replaced value on index
14525     */
14526    public with(index: number, value: number): Float64Array {
14527        return this.with(index as int, value as double)
14528    }
14529
14530    /**
14531     * Creates a copy with replaced value on index
14532     *
14533     * @param index
14534     *
14535     * @param value
14536     *
14537     * @returns an Float64Array with replaced value on index
14538     */
14539    public with(index: int, value: double): Float64Array {
14540        let res = new Float64Array(this)
14541        res.set(index, value)
14542        return res
14543    }
14544
14545    /// === with element lambda functions ===
14546    /**
14547     * Determines whether the specified callback function returns true for all elements of an array.
14548     *
14549     * @param predicate A function that accepts one argument.
14550     * The every method calls the predicate function for each element in the array until the predicate returns a false,
14551     * or until the end of the array.
14552     *
14553     * @returns true unless predicate function returns a false for an array element,
14554     * in which case false is immediately returned.
14555     */
14556    public every(predicate: (element: number) => boolean): boolean {
14557        return this.every((element: number, index: number, array: Float64Array): boolean => predicate(element))
14558    }
14559
14560    /**
14561     * creates a new Float64Array from current Float64Array based on a condition fn
14562     *
14563     * @param fn the condition to apply for each element
14564     *
14565     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
14566     */
14567    public filter(fn: (val: number) => boolean): Float64Array {
14568        let newF: (val: number, index: number, array: Float64Array) => boolean =
14569            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14570        return this.filter(newF)
14571    }
14572
14573    /**
14574     * Returns the value of the first element in the array where predicate is true, and undefined
14575     * otherwise
14576     *
14577     * @param predicate find calls predicate once for each element of the array, in ascending
14578     * order, until it finds one where predicate returns true. If such an element is found, find
14579     * immediately returns that element value. Otherwise, find returns undefined
14580     *
14581     * @returns number | undefined
14582     */
14583    public find(predicate: () => boolean): number | undefined {
14584        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate())
14585    }
14586
14587    /**
14588     * Returns the value of the first element in the array where predicate is true, and undefined
14589     * otherwise
14590     *
14591     * @param predicate find calls predicate once for each element of the array, in ascending
14592     * order, until it finds one where predicate returns true. If such an element is found, find
14593     * immediately returns that element value. Otherwise, find returns undefined
14594     *
14595     * @returns number | undefined
14596     */
14597    public find(predicate: (value: number) => boolean): number | undefined {
14598        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate(value))
14599    }
14600
14601    /**
14602     * Returns the index of the first element in the array where predicate is true, and -1
14603     * otherwise
14604     *
14605     * @param predicate find calls predicate once for each element of the array, in ascending
14606     * order, until it finds one where predicate returns true. If such an element is found,
14607     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
14608     *
14609     * @returns number
14610     */
14611    public findIndex(predicate: (value: number) => boolean): number {
14612        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate(value)) as number
14613    }
14614
14615    /**
14616     * Finds the last element in the Float64Array that satisfies the condition
14617     *
14618     * @param fn condition
14619     *
14620     * @returns the last element that satisfies fn
14621     */
14622    public findLast(fn: (val: number) => boolean): number {
14623        let newF: (val: number, index: number, array: Float64Array) => boolean =
14624            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14625        return this.findLast(newF) as number
14626    }
14627
14628    /**
14629     * Finds an index of the last element in the Float64Array that satisfies the condition
14630     *
14631     * @param fn condition
14632     *
14633     * @returns the index of the last element that satisfies fn, -1 otherwise
14634     */
14635    public findLastIndex(fn: (val: number) => boolean): number {
14636        let newF: (val: number, index: number, array: Float64Array) => boolean =
14637            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14638        return this.findLastIndex(newF) as number
14639    }
14640
14641    /**
14642     * Performs the specified action for each element in Float64Array
14643     *
14644     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
14645     * callbackfn function one time for each element in the array.
14646     *
14647     * @returns None
14648     */
14649    public forEach(callbackfn: (value: number) => void): void {
14650        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn(value))
14651    }
14652
14653    /**
14654     * Determines whether the specified callback function returns true for any element of an array.
14655     *
14656     * @param predicate A function that accepts one argument.
14657     * The some method calls the predicate function for each element in the array
14658     * until the predicate returns a true or until the end of the array.
14659     *
14660     * @returns false unless predicate function returns true for an array element,
14661     * in which case true is immediately returned.
14662     */
14663    public some(predicate: (element: number) => boolean): boolean {
14664        return this.some((element: number, index: number, array: Float64Array): boolean => predicate(element))
14665    }
14666
14667    // NOTE (kprokopenko): this may be not skipped
14668    /**
14669     * Sorts in-place
14670     *
14671     * @param compareFn comparator —  used to determine the order of the elements.
14672     * compareFn returns a negative value if first argument is less than second argument,
14673     * zero if they're equal and a positive value otherwise.
14674     * If omitted, the elements are sorted in ascending order.
14675     *
14676     * @returns sorted Float64Array
14677     */
14678    public sort(compareFn?: (a: number, b: number) => number): this {
14679        let arr: double[] = new double[this.lengthInt]
14680        for (let i = 0; i < this.lengthInt; ++i) {
14681            arr[i] = this.getUnsafe(i)
14682        }
14683        let cmp = (l: double, r: double): number => {
14684                return (l - r) as number
14685            }
14686        if (compareFn != undefined) {
14687            cmp = (l: double, r: double): number => {
14688                return compareFn!(l as number, r as number)
14689            }
14690        }
14691        sort(arr, cmp)
14692        for (let i = 0; i < this.lengthInt; ++i) {
14693            this.setUnsafe(i, arr[i])
14694        }
14695        return this
14696    }
14697
14698    /**
14699     * Sorts in-place
14700     *
14701     * @param compareFn comparator —  used to determine the order of the elements.
14702     * compareFn returns a negative value if first argument is less than second argument,
14703     * zero if they're equal and a positive value otherwise.
14704     *
14705     * @returns sorted Float64Array
14706     */
14707    public sort(compareFn: (a: number) => number): this {
14708        let cmp = (a: number, b: number) => { return compareFn(a)}
14709        this.sort(cmp)
14710        return this
14711    }
14712
14713    /**
14714     * Sorts in-place
14715     *
14716     * @param fn compareFn —  used to determine the order of the elements.
14717     * compareFn returns a negative value if first argument is less than second argument,
14718     * zero if they're equal and a positive value otherwise.
14719     *
14720     * @returns sorted Float64Array
14721     */
14722    public sort(compareFn: () => number): this {
14723        let cmp = (a: number, b: number) => { return compareFn()}
14724        this.sort(cmp)
14725        return this
14726    }
14727
14728    /**
14729     * Determines whether the specified callback function returns true for any element of an array.
14730     *
14731     * @param predicate A function that accepts three arguments.
14732     * The some method calls the predicate function for each element in the array
14733     * until the predicate returns a true or until the end of the array.
14734     *
14735     * @returns false unless predicate function returns true for an array element,
14736     * in which case true is immediately returned.
14737     */
14738    public some(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
14739        for (let i = 0; i < this.lengthInt; ++i) {
14740            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
14741                return true
14742            }
14743        }
14744        return false
14745    }
14746
14747    /**
14748     * Determines whether the specified callback function returns true for any element of an array.
14749     *
14750     * @param predicate A function that accepts two arguments.
14751     * The some method calls the predicate function for each element in the array
14752     * until the predicate returns a true or until the end of the array.
14753     *
14754     * @returns false unless predicate function returns true for an array element,
14755     * in which case true is immediately returned.
14756     */
14757    public some(predicate: (element: number, index: number) => boolean): boolean {
14758        return this.some((element: number, index: number, array: Float64Array): boolean => predicate(element, index as number))
14759    }
14760
14761    /**
14762     * Determines whether the specified callback function returns true for any element of an array.
14763     *
14764     * @param predicate A function that accepts no arguments.
14765     * The some method calls the predicate function for each element in the array
14766     * until the predicate returns a true or until the end of the array.
14767     *
14768     * @returns false unless predicate function returns true for an array element,
14769     * in which case true is immediately returned.
14770     */
14771    public some(predicate: () => boolean): boolean {
14772        return this.some((element: number, index: number, array: Float64Array): boolean => predicate())
14773    }
14774
14775    /**
14776     * Calls the specified callback function for all the elements in an array.
14777     * The return value of the callback function is the accumulated result,
14778     * and is provided as an argument in the next call to the callback function.
14779     *
14780     * @param callbackfn A function that accepts four arguments.
14781     * The reduce method calls the callbackfn function one time for each element in the array.
14782     *
14783     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14784     * The first call to the callbackfn function provides this value as an argument.
14785     *
14786     * @returns The value that results from running the callback function to completion over the entire typed array.
14787     */
14788    public reduce<U = number>(
14789                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
14790                initialValue: U): U {
14791        let accumulatedValue = initialValue
14792        for (let i = 0; i < this.lengthInt; ++i) {
14793            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14794        }
14795        return accumulatedValue
14796    }
14797
14798    /**
14799     * Calls the specified callback function for all the elements in an array.
14800     * The return value of the callback function is the accumulated result,
14801     * and is provided as an argument in the next call to the callback function.
14802     *
14803     * @param callbackfn A function that accepts three arguments.
14804     * The reduce method calls the callbackfn function one time for each element in the array.
14805     *
14806     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14807     * The first call to the callbackfn function provides this value as an argument.
14808     *
14809     * @returns The value that results from running the callback function to completion over the entire typed array.
14810     */
14811    public reduce<U = number>(
14812                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
14813                initialValue: U): U {
14814        return this.reduce(
14815                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14816                        callbackfn(prevVal, currVal, currIndex), initialValue)
14817    }
14818
14819    /**
14820     * Calls the specified callback function for all the elements in an array.
14821     * The return value of the callback function is the accumulated result,
14822     * and is provided as an argument in the next call to the callback function.
14823     *
14824     * @param callbackfn A function that accepts two arguments.
14825     * The reduce method calls the callbackfn function one time for each element in the array.
14826     *
14827     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14828     * The first call to the callbackfn function provides this value as an argument.
14829     *
14830     * @returns The value that results from running the callback function to completion over the entire typed array.
14831     */
14832    public reduce<U = number>(
14833                callbackfn: (previousValue: U, currentValue: number) => U,
14834                initialValue: U): U {
14835        return this.reduce(
14836                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14837                        callbackfn(prevVal, currVal), initialValue)
14838    }
14839
14840    /**
14841     * Calls the specified callback function for all the elements in an array.
14842     * The return value of the callback function is the accumulated result,
14843     * and is provided as an argument in the next call to the callback function.
14844     *
14845     * @param callbackfn A function that accepts one argument
14846     * The reduce method calls the callbackfn function one time for each element in the array.
14847     *
14848     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14849     * The first call to the callbackfn function provides this value as an argument.
14850     *
14851     * @returns The value that results from running the callback function to completion over the entire typed array.
14852     */
14853    public reduce<U = number>(
14854                callbackfn: (previousValue: U) => U,
14855                initialValue: U): U {
14856        return this.reduce(
14857                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14858                        callbackfn(prevVal), initialValue)
14859    }
14860
14861    /**
14862     * Calls the specified callback function for all the elements in an array.
14863     * The return value of the callback function is the accumulated result,
14864     * and is provided as an argument in the next call to the callback function.
14865     *
14866     * @param callbackfn A function that accepts no arguments
14867     * The reduce method calls the callbackfn function one time for each element in the array.
14868     *
14869     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14870     * The first call to the callbackfn function provides this value as an argument.
14871     *
14872     * @returns The value that results from running the callback function to completion over the entire typed array.
14873     */
14874    public reduce<U = number>(
14875                callbackfn: () => U,
14876                initialValue: U): U {
14877        return this.reduce(
14878                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14879                        callbackfn(), initialValue)
14880    }
14881
14882    /**
14883     * Calls the specified callback function for all the elements in an array.
14884     * The return value of the callback function is the accumulated result,
14885     * and is provided as an argument in the next call to the callback function.
14886     *
14887     * @param callbackfn A function that accepts four arguments.
14888     * The reduce method calls the callbackfn function one time for each element in the array.
14889     * The first call to the callbackfn function provides array first element value as an argument
14890     *
14891     * @returns The value that results from running the callback function to completion over the entire typed array.
14892     * calling reduce method on an empty array without an initial value creates a TypeError
14893     */
14894    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
14895        if (this.lengthInt == 0) {
14896            throw new TypeError("Reduce of empty array with no initial value")
14897        }
14898
14899        let accumulatedValue = this.getUnsafe(0) as number
14900        for (let i = 1; i < this.lengthInt; ++i) {
14901            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14902        }
14903        return accumulatedValue
14904    }
14905
14906    /**
14907     * Calls the specified callback function for all the elements in an array.
14908     * The return value of the callback function is the accumulated result,
14909     * and is provided as an argument in the next call to the callback function.
14910     *
14911     * @param callbackfn A function that accepts three arguments.
14912     * The reduce method calls the callbackfn function one time for each element in the array.
14913     * The first call to the callbackfn function provides array first element value as an argument
14914     *
14915     * @returns The value that results from running the callback function to completion over the entire typed array.
14916     * calling reduce method on an empty array without an initial value creates a TypeError
14917     */
14918    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
14919        return this.reduce(
14920                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14921                        callbackfn(prevVal, currVal, currIndex))
14922    }
14923
14924    /**
14925     * Calls the specified callback function for all the elements in an array.
14926     * The return value of the callback function is the accumulated result,
14927     * and is provided as an argument in the next call to the callback function.
14928     *
14929     * @param callbackfn A function that accepts two arguments.
14930     * The reduce method calls the callbackfn function one time for each element in the array.
14931     * The first call to the callbackfn function provides array first element value as an argument
14932     *
14933     * @returns The value that results from running the callback function to completion over the entire typed array.
14934     * calling reduce method on an empty array without an initial value creates a TypeError
14935     */
14936    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
14937        return this.reduce(
14938                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14939                        callbackfn(prevVal, currVal))
14940    }
14941
14942    /**
14943     * Calls the specified callback function for all the elements in an array.
14944     * The return value of the callback function is the accumulated result,
14945     * and is provided as an argument in the next call to the callback function.
14946     *
14947     * @param callbackfn A function that accepts one argument.
14948     * The reduce method calls the callbackfn function one time for each element in the array.
14949     * The first call to the callbackfn function provides array first element value as an argument
14950     *
14951     * @returns The value that results from running the callback function to completion over the entire typed array.
14952     * calling reduce method on an empty array without an initial value creates a TypeError
14953     */
14954    public reduce(callbackfn: (previousValue: number) => number): number {
14955        return this.reduce(
14956                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14957                        callbackfn(prevVal))
14958    }
14959
14960    /**
14961     * Calls the specified callback function for all the elements in an array.
14962     * The return value of the callback function is the accumulated result,
14963     * and is provided as an argument in the next call to the callback function.
14964     *
14965     * @param callbackfn A function that accepts no arguments.
14966     * The reduce method calls the callbackfn function one time for each element in the array.
14967     * The first call to the callbackfn function provides array first element value as an argument
14968     *
14969     * @returns The value that results from running the callback function to completion over the entire typed array.
14970     * calling reduce method on an empty array without an initial value creates a TypeError
14971     */
14972    public reduce(callbackfn: () => number): number {
14973        return this.reduce(
14974                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14975                        callbackfn())
14976    }
14977
14978
14979    /**
14980     * Calls the specified callback function for all the elements in an array, in descending order.
14981     * The return value of the callback function is the accumulated result,
14982     * and is provided as an argument in the next call to the callback function.
14983     *
14984     * @param callbackfn A function that accepts four arguments.
14985     * The reduceRight method calls the callbackfn function one time for each element in the array.
14986     *
14987     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14988     * The first call to the callbackfn function provides this value as an argument.
14989     *
14990     * @returns The value that results from running the callback function to completion over the entire typed array.
14991     */
14992    public reduceRight<U = number>(
14993                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
14994                initialValue: U): U {
14995        let accumulatedValue = initialValue
14996        for (let i = this.lengthInt - 1; i >= 0; --i) {
14997            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14998        }
14999        return accumulatedValue
15000    }
15001
15002    /**
15003     * Calls the specified callback function for all the elements in an array, in descending order.
15004     * The return value of the callback function is the accumulated result,
15005     * and is provided as an argument in the next call to the callback function.
15006     *
15007     * @param callbackfn A function that accepts three arguments.
15008     * The reduceRight method calls the callbackfn function one time for each element in the array.
15009     *
15010     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
15011     * The first call to the callbackfn function provides this value as an argument.
15012     *
15013     * @returns The value that results from running the callback function to completion over the entire typed array.
15014     */
15015    public reduceRight<U = number>(
15016                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
15017                initialValue: U): U {
15018        return this.reduceRight(
15019                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
15020                        callbackfn(prevVal, currVal, currIndex), initialValue)
15021    }
15022
15023    /**
15024     * Calls the specified callback function for all the elements in an array, in descending order.
15025     * The return value of the callback function is the accumulated result,
15026     * and is provided as an argument in the next call to the callback function.
15027     *
15028     * @param callbackfn A function that accepts two arguments.
15029     * The reduceRight method calls the callbackfn function one time for each element in the array.
15030     *
15031     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
15032     * The first call to the callbackfn function provides this value as an argument.
15033     *
15034     * @returns The value that results from running the callback function to completion over the entire typed array.
15035     */
15036    public reduceRight<U = number>(
15037                callbackfn: (previousValue: U, currentValue: number) => U,
15038                initialValue: U): U {
15039        return this.reduceRight(
15040                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
15041                        callbackfn(prevVal, currVal), initialValue)
15042    }
15043
15044    /**
15045     * Calls the specified callback function for all the elements in an array, in descending order.
15046     * The return value of the callback function is the accumulated result,
15047     * and is provided as an argument in the next call to the callback function.
15048     *
15049     * @param callbackfn A function that accepts one argument.
15050     * The reduceRight method calls the callbackfn function one time for each element in the array.
15051     *
15052     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
15053     * The first call to the callbackfn function provides this value as an argument.
15054     *
15055     * @returns The value that results from running the callback function to completion over the entire typed array.
15056     */
15057    public reduceRight<U = number>(
15058                callbackfn: (previousValue: U) => U,
15059                initialValue: U): U {
15060        return this.reduceRight(
15061                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
15062                        callbackfn(prevVal), initialValue)
15063    }
15064
15065    /**
15066     * Calls the specified callback function for all the elements in an array, in descending order.
15067     * The return value of the callback function is the accumulated result,
15068     * and is provided as an argument in the next call to the callback function.
15069     *
15070     * @param callbackfn A function that accepts no arguments.
15071     * The reduceRight method calls the callbackfn function one time for each element in the array.
15072     *
15073     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
15074     * The first call to the callbackfn function provides this value as an argument.
15075     *
15076     * @returns The value that results from running the callback function to completion over the entire typed array.
15077     */
15078    public reduceRight<U = number>(
15079                callbackfn: () => U,
15080                initialValue: U): U {
15081        return this.reduceRight(
15082                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
15083                        callbackfn(), initialValue)
15084    }
15085
15086    /**
15087     * Calls the specified callback function for all the elements in an array, in descending order.
15088     * The return value of the callback function is the accumulated result,
15089     * and is provided as an argument in the next call to the callback function.
15090     *
15091     * @param callbackfn A function that accepts four arguments.
15092     * The reduceRight method calls the callbackfn function one time for each element in the array.
15093     * The first call to the callbackfn function provides array last element value as an argument
15094     *
15095     * @returns The value that results from running the callback function to completion over the entire typed array.
15096     * calling reduceRight method on an empty array without an initial value creates a TypeError
15097     */
15098    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
15099        if (this.lengthInt == 0) {
15100            throw new TypeError("Reduce of empty array with no initial value")
15101        }
15102
15103        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
15104        for (let i = this.lengthInt - 2; i >= 0; --i) {
15105            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
15106        }
15107        return accumulatedValue
15108    }
15109
15110    /**
15111     * Calls the specified callback function for all the elements in an array, in descending order.
15112     * The return value of the callback function is the accumulated result,
15113     * and is provided as an argument in the next call to the callback function.
15114     *
15115     * @param callbackfn A function that accepts three arguments.
15116     * The reduceRight method calls the callbackfn function one time for each element in the array.
15117     * The first call to the callbackfn function provides array last element value as an argument
15118     *
15119     * @returns The value that results from running the callback function to completion over the entire typed array.
15120     * calling reduceRight method on an empty array without an initial value creates a TypeError
15121     */
15122    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
15123        return this.reduceRight(
15124                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
15125                        callbackfn(prevValue, currValue, currIndex))
15126    }
15127
15128    /**
15129     * Calls the specified callback function for all the elements in an array, in descending order.
15130     * The return value of the callback function is the accumulated result,
15131     * and is provided as an argument in the next call to the callback function.
15132     *
15133     * @param callbackfn A function that accepts two arguments.
15134     * The reduceRight method calls the callbackfn function one time for each element in the array.
15135     * The first call to the callbackfn function provides array last element value as an argument
15136     *
15137     * @returns The value that results from running the callback function to completion over the entire typed array.
15138     * calling reduceRight method on an empty array without an initial value creates a TypeError
15139     */
15140    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
15141        return this.reduceRight(
15142                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
15143                        callbackfn(prevValue, currValue))
15144    }
15145
15146    /**
15147     * Calls the specified callback function for all the elements in an array, in descending order.
15148     * The return value of the callback function is the accumulated result,
15149     * and is provided as an argument in the next call to the callback function.
15150     *
15151     * @param callbackfn A function that accepts one argument.
15152     * The reduceRight method calls the callbackfn function one time for each element in the array.
15153     * The first call to the callbackfn function provides array last element value as an argument
15154     *
15155     * @returns The value that results from running the callback function to completion over the entire typed array.
15156     * calling reduceRight method on an empty array without an initial value creates a TypeError
15157     */
15158    public reduceRight(callbackfn: (previousValue: number) => number): number {
15159        return this.reduceRight(
15160                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
15161                        callbackfn(prevValue))
15162    }
15163
15164    /**
15165     * Calls the specified callback function for all the elements in an array, in descending order.
15166     * The return value of the callback function is the accumulated result,
15167     * and is provided as an argument in the next call to the callback function.
15168     *
15169     * @param callbackfn A function that accepts no arguments.
15170     * The reduceRight method calls the callbackfn function one time for each element in the array.
15171     * The first call to the callbackfn function provides array last element value as an argument
15172     *
15173     * @returns The value that results from running the callback function to completion over the entire typed array.
15174     * calling reduceRight method on an empty array without an initial value creates a TypeError
15175     */
15176    public reduceRight(callbackfn: () => number): number {
15177        return this.reduceRight(
15178                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
15179                        callbackfn())
15180    }
15181
15182   /**
15183    * Creates a new Float64Array using fn(arr[i]) over all elements of current Float64Array.
15184    *
15185    * @param fn a function to apply for each element of current Float64Array
15186    *
15187    * @returns a new Float64Array where for each element from current Float64Array fn was applied
15188    */
15189    public map(fn: (val: number, index: number, array: Float64Array) => number): Float64Array {
15190        let resBuf = new ArrayBuffer(this.lengthInt * Float64Array.BYTES_PER_ELEMENT as int)
15191        let res = new Float64Array(resBuf, 0, resBuf.getByteLength() / Float64Array.BYTES_PER_ELEMENT as int)
15192        for (let i = 0; i < this.lengthInt; ++i) {
15193            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as double)
15194        }
15195        return res
15196    }
15197
15198    /**
15199     * Creates a new Float64Array using fn(arr[i], i) over all elements of current Float64Array
15200     *
15201     * @param fn a function to apply for each element of current Float64Array
15202     *
15203     * @returns a new Float64Array where for each element from current Float64Array fn was applied
15204     */
15205    public map(fn: (val: number, index: number) => number): Float64Array {
15206        let newF: (val: number, index: number, array: Float64Array) => number =
15207            (val: number, index: number, array: Float64Array): number => { return fn(val, index) }
15208        return this.map(newF)
15209    }
15210
15211    /**
15212     * Creates a new Float64Array using fn(arr[i]) over all elements of current Float64Array
15213     *
15214     * @param fn a function to apply for each element of current Float64Array
15215     *
15216     * @returns a new Float64Array where for each element from current Float64Array fn was applied
15217     */
15218    public map(fn: (val: number) => number): Float64Array {
15219        let newF: (val: number, index: number, array: Float64Array) => number =
15220            (val: number, index: number, array: Float64Array): number => { return fn(val) }
15221        return this.map(newF)
15222    }
15223
15224    /**
15225     * Creates a new Float64Array using fn() over all elements of current Float64Array
15226     *
15227     * @param fn a function to apply for each element of current Float64Array
15228     *
15229     * @returns a new Float64Array where for each element from current Float64Array fn was applied
15230     */
15231    public map(fn: () => number): Float64Array {
15232        let newF: (val: number, index: number, array: Float64Array) => number =
15233            (val: number, index: number, array: Float64Array): number => { return fn() }
15234        return this.map(newF)
15235    }
15236
15237
15238    /**
15239     * Determines whether the specified callback function returns true for all elements of an array.
15240     *
15241     * @param predicate A function that accepts three arguments.
15242     * The every method calls the predicate function for each element in the array until the predicate returns a false,
15243     * or until the end of the array.
15244     *
15245     * @returns true unless predicate function returns a false for an array element,
15246     * in which case false is immediately returned.
15247     */
15248    public every(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
15249        for (let i = 0; i < this.lengthInt; ++i) {
15250            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
15251                return false
15252            }
15253        }
15254        return true
15255    }
15256
15257    /**
15258     * Determines whether the specified callback function returns true for all elements of an array.
15259     *
15260     * @param predicate A function that accepts two arguments.
15261     * The every method calls the predicate function for each element in the array until the predicate returns a false,
15262     * or until the end of the array.
15263     *
15264     * @returns true unless predicate function returns a false for an array element,
15265     * in which case false is immediately returned.
15266     */
15267    public every(predicate: (element: number, index: number) => boolean): boolean {
15268        return this.every((element: number, index: number, array: Float64Array): boolean => predicate(element, index))
15269    }
15270
15271    /**
15272     * Determines whether the specified callback function returns true for all elements of an array.
15273     *
15274     * @param predicate A function that accepts no arguments.
15275     * The every method calls the predicate function for each element in the array until the predicate returns a false,
15276     * or until the end of the array.
15277     *
15278     * @returns true unless predicate function returns a false for an array element,
15279     * in which case false is immediately returned.
15280     */
15281    public every(predicate: () => boolean): boolean {
15282        return this.every((element: number, index: number, array: Float64Array): boolean => predicate())
15283    }
15284
15285    /**
15286     * Creates a new Float64Array from current Float64Array based on a condition fn.
15287     *
15288     * @param fn the condition to apply for each element
15289     *
15290     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
15291     */
15292    public filter(fn: (val: number, index: number, array: Float64Array) => boolean): Float64Array {
15293        let markers = new boolean[this.lengthInt]
15294        let resLen = 0
15295        for (let i = 0; i < this.lengthInt; ++i) {
15296            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
15297            if (markers[i]) {
15298                ++resLen
15299            }
15300        }
15301        let resBuf = new ArrayBuffer(resLen * Float64Array.BYTES_PER_ELEMENT as int)
15302        let res = new Float64Array(resBuf, 0)
15303        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
15304            if (markers[i]) {
15305                res.set(j, this.getUnsafe(i))
15306                ++j
15307            }
15308        }
15309        return res
15310    }
15311
15312    /**
15313     * creates a new Float64Array from current Float64Array based on a condition fn
15314     *
15315     * @param fn the condition to apply for each element
15316     *
15317     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
15318     */
15319    public filter(fn: (val: number, index: number) => boolean): Float64Array {
15320        let newF: (val: number, index: number, array: Float64Array) => boolean =
15321            (val: number, index: number, array: Float64Array): boolean => { return fn(val, index as number) }
15322        return this.filter(newF)
15323    }
15324
15325    /**
15326     * creates a new Float64Array from current Float64Array based on a condition fn
15327     *
15328     * @param fn the condition to apply for each element
15329     *
15330     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
15331     */
15332    public filter(fn: () => boolean): Float64Array {
15333        let newF: (val: number, index: number, array: Float64Array) => boolean =
15334            (val: number, index: number, array: Float64Array): boolean => { return fn() }
15335        return this.filter(newF)
15336    }
15337
15338    /**
15339     * Returns the value of the first element in the array where predicate is true, and undefined
15340     * otherwise
15341     *
15342     * @param predicate find calls predicate once for each element of the array, in ascending
15343     * order, until it finds one where predicate returns true. If such an element is found, find
15344     * immediately returns that element value. Otherwise, find returns undefined
15345     *
15346     * @returns number | undefined
15347     */
15348    public find(predicate: (value: number, index: number, obj: Float64Array) => boolean): number | undefined {
15349        for (let i = 0; i < this.lengthInt; ++i) {
15350            let val = this.getUnsafe(i)
15351            if (predicate(val as number, i as number, this)) {
15352                return val as number
15353            }
15354        }
15355        return undefined
15356    }
15357
15358    /**
15359     * Returns the value of the first element in the array where predicate is true, and undefined
15360     * otherwise
15361     *
15362     * @param predicate find calls predicate once for each element of the array, in ascending
15363     * order, until it finds one where predicate returns true. If such an element is found, find
15364     * immediately returns that element value. Otherwise, find returns undefined
15365     *
15366     * @returns number | undefined
15367     */
15368    public find(predicate: (value: number, index: number) => boolean): number | undefined {
15369        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate(value, index))
15370    }
15371
15372    /**
15373     * Returns the index of the first element in the array where predicate is true, and -1
15374     * otherwise
15375     *
15376     * @param predicate find calls predicate once for each element of the array, in ascending
15377     * order, until it finds one where predicate returns true. If such an element is found,
15378     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15379     *
15380     * @returns number
15381     */
15382    public findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean): number {
15383        for (let i = 0; i < this.lengthInt; ++i) {
15384            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
15385                return i as number
15386            }
15387        }
15388        return -1 as number
15389    }
15390
15391    /**
15392     * Returns the index of the first element in the array where predicate is true, and -1
15393     * otherwise
15394     *
15395     * @param predicate find calls predicate once for each element of the array, in ascending
15396     * order, until it finds one where predicate returns true. If such an element is found,
15397     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15398     *
15399     * @returns number
15400     */
15401    public findIndex(predicate: (value: number, index: number) => boolean): number {
15402        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate(value, index as number)) as number
15403    }
15404
15405    /**
15406     * Returns the index of the first element in the array where predicate is true, and -1
15407     * otherwise
15408     *
15409     * @param predicate find calls predicate once for each element of the array, in ascending
15410     * order, until it finds one where predicate returns true. If such an element is found,
15411     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15412     *
15413     * @returns number
15414     */
15415    public findIndex(predicate: () => boolean): number {
15416        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate()) as number
15417    }
15418
15419    /**
15420     * Finds the last element in the Float64Array that satisfies the condition
15421     *
15422     * @param fn condition
15423     *
15424     * @returns the last element that satisfies fn
15425     */
15426    public findLast(fn: (val: number, index: number, array: Float64Array) => boolean): double {
15427        for (let i = this.lengthInt - 1; i >= 0; --i) {
15428            let val = this.getUnsafe(i)
15429            if (fn(val as number, i as number, this)) {
15430                return val
15431            }
15432        }
15433        throw new Error("Float64Array.findLast: not implemented if an element was not found")
15434    }
15435
15436    /**
15437     * Finds the last element in the Float64Array that satisfies the condition
15438     *
15439     * @param fn condition
15440     *
15441     * @returns the last element that satisfies fn
15442     */
15443    public findLast(fn: (val: number, index: number) => boolean): double {
15444        let newF: (val: number, index: number, array: Float64Array) => boolean =
15445            (val: number, index: number, array: Float64Array): boolean => { return fn(val as number, index as number) }
15446        return this.findLast(newF)
15447    }
15448
15449    /**
15450     * Finds an index of the last element in the Float64Array that satisfies the condition
15451     *
15452     * @param fn condition
15453     *
15454     * @returns the index of the last element that satisfies fn, -1 otherwise
15455     */
15456    public findLastIndex(fn: (val: number, index: number, array: Float64Array) => boolean): number {
15457        for (let i = this.lengthInt - 1; i >= 0; --i) {
15458            let val = this.getUnsafe(i)
15459            if (fn(val as number, i as number, this)) {
15460                return i
15461            }
15462        }
15463        return -1 as number
15464    }
15465
15466    /**
15467     * Finds an index of the last element in the Float64Array that satisfies the condition
15468     *
15469     * @param fn condition
15470     *
15471     * @returns the index of the last element that satisfies fn, -1 otherwise
15472     */
15473    public findLastIndex(fn: (val: number, index: number) => boolean): number {
15474        let newF: (val: number, index: number, array: Float64Array) => boolean =
15475            (val: number, index: number, array: Float64Array): boolean => { return fn(val, index as number) }
15476        return this.findLastIndex(newF) as number
15477    }
15478
15479    /**
15480     * Performs the specified action for each element in Float64Array
15481     *
15482     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15483     * callbackfn function one time for each element in the array.
15484     *
15485     * @returns None
15486     */
15487    public forEach(callbackfn: (value: number, index: number, array: Float64Array) => void): void {
15488        for (let i = 0; i < this.lengthInt; ++i) {
15489            callbackfn(this.getUnsafe(i) as number, i as number, this)
15490        }
15491    }
15492
15493    /**
15494     * Performs the specified action for each element in Float64Array
15495     *
15496     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15497     * callbackfn function one time for each element in the array.
15498     *
15499     * @returns None
15500     */
15501    public forEach(callbackfn: (value: number, index: number) => void): void {
15502        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn(value, index))
15503    }
15504
15505    /**
15506     * Performs the specified action for each element in Float64Array
15507     *
15508     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15509     * callbackfn function one time for each element in the array.
15510     *
15511     * @returns None
15512     */
15513    public forEach(callbackfn: () => void): void {
15514        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn())
15515    }
15516
15517    /**
15518     * Returns the object itself
15519     *
15520     * @returns Float64Array
15521     */
15522    public valueOf(): Float64Array {
15523        return this
15524    }
15525
15526    internal getUnsafe(index: int): double {
15527        let byteIndex = index * Float64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
15528        let res : long = 0
15529        let byteVal : long
15530        if (IS_LITTLE_ENDIAN) {
15531            if (this.buffer instanceof ArrayBuffer) {
15532                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15533                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
15534                    byteVal &= 0xff
15535                    res = (res | byteVal << (8 * i)) as long
15536                }
15537            } else if (this.buffer instanceof SharedArrayBuffer) {
15538                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15539                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
15540                    byteVal &= 0xff
15541                    res = (res | byteVal << (8 * i)) as long
15542                }
15543            } else {
15544                throw new Error("unexpected type of ArrayBufferLike")
15545            }
15546            return Double.bitCastFromLong(res)
15547        } else {
15548            if (this.buffer instanceof ArrayBuffer) {
15549                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15550                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 7 - i)
15551                    byteVal &= 0xff
15552                    res = (res | byteVal << (8 * i)) as long
15553                }
15554            } else if (this.buffer instanceof SharedArrayBuffer) {
15555                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15556                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 7 - i)
15557                    byteVal &= 0xff
15558                    res = (res | byteVal << (8 * i)) as long
15559                }
15560            } else {
15561                throw new Error("unexpected type of ArrayBufferLike")
15562            }
15563            return Double.bitCastFromLong(res)
15564        }
15565    }
15566
15567    internal setUnsafe(insertPos: int, val: double): void {
15568        let startByte = insertPos * Float64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
15569        let bits = Double.bitCastToLong(val)
15570        if (IS_LITTLE_ENDIAN) {
15571            if (this.buffer instanceof ArrayBuffer) {
15572                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15573                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15574                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
15575                }
15576            } else if (this.buffer instanceof SharedArrayBuffer) {
15577                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15578                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15579                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
15580                }
15581            } else {
15582                throw new Error("unexpected type of ArrayBufferLike")
15583            }
15584        } else {
15585            if (this.buffer instanceof ArrayBuffer) {
15586                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; i++) {
15587                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15588                    (this.buffer as ArrayBuffer).set(startByte + 7 - i, byteVal)
15589                }
15590            } else if (this.buffer instanceof SharedArrayBuffer) {
15591                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; i++) {
15592                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15593                    (this.buffer as SharedArrayBuffer).set(startByte + 7 - i, byteVal)
15594                }
15595            } else {
15596                throw new Error("unexpected type of ArrayBufferLike")
15597            }
15598        }
15599    }
15600
15601    /** Underlying ArrayBufferLike */
15602    public readonly buffer: ArrayBufferLike
15603
15604    /** Byte offset within the underlying ArrayBufferLike */
15605    public readonly byteOffset: number
15606
15607    /** Number of bytes used */
15608    public readonly byteLength: number
15609
15610    /** String \"Float64Array\" */
15611    public readonly name = "Float64Array"
15612}
15613