• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2025 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    public readonly BYTES_PER_ELEMENT: number = Int8Array.BYTES_PER_ELEMENT
89    internal readonly lengthInt: int
90
91    /**
92     * Creates an empty Int8Array.
93     */
94    public constructor() {
95        this(0 as int)
96    }
97
98    /**
99     * Creates an Int8Array with respect to data accessed via Iterable<Number> interface
100     */
101    public constructor(elements: Iterable<Number>) {
102        const items: Object = elements as Object
103        if (items instanceof ArrayLike) {
104            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
105            this.byteLength = arr.length as int * Int8Array.BYTES_PER_ELEMENT as int
106            this.lengthInt = arr.length as int
107            this.buffer = new ArrayBuffer(this.byteLength as int)
108            this.byteOffset = 0
109            for (let i: int = 0; i < this.lengthInt; ++i) {
110                this.setUnsafe(i, arr.$_get(i).toByte())
111            }
112        } else {
113          let x = Int8Array.from(elements)
114          this.byteLength = x.byteLength
115          this.lengthInt = x.lengthInt
116          this.buffer = x.buffer
117          this.byteOffset = x.byteOffset
118        }
119    }
120
121    /**
122     * Creates an Int8Array with respect to data, byteOffset and length.
123     *
124     * @param buf data initializer
125     *
126     * @param byteOffset byte offset from begin of the buf
127     *
128     * @param length size of elements of type byte in newly created Int8Array
129     */
130    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
131        let intByteOffset: int = 0
132        if (byteOffset != undefined) {
133            intByteOffset = byteOffset.toInt()
134            if (intByteOffset < 0) {
135                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
136            }
137        }
138        let intByteLength: int = buf.getByteLength() - intByteOffset
139        if (intByteLength < 0) {
140            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
141        }
142
143        let intLength: int
144        if (length != undefined) {
145            intLength = length.toInt()
146            if (intLength > intByteLength / Int8Array.BYTES_PER_ELEMENT as int) {
147                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
148            }
149        } else {
150            intLength = intByteLength / Int8Array.BYTES_PER_ELEMENT as int
151        }
152        if (intLength < 0) {
153            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
154        }
155        if (intLength < intByteLength / Int8Array.BYTES_PER_ELEMENT as int) {
156            intByteLength = intLength * Int8Array.BYTES_PER_ELEMENT as int
157        }
158        this.byteLength = intByteLength
159        this.byteOffset = intByteOffset
160        this.lengthInt = intLength
161        this.buffer = buf
162    }
163
164    /**
165     * Creates an Int8Array with respect to data, byteOffset and length.
166     *
167     * @param buf data initializer
168     *
169     * @param byteOffset byte offset from begin of the buf
170     *
171     * @param length size of elements of type byte in newly created Int8Array
172     */
173    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
174        this(buf, byteOffset, undefined)
175    }
176
177    /**
178     * Creates an Int8Array with respect to data, byteOffset and length.
179     *
180     * @param buf data initializer
181     *
182     * @param byteOffset byte offset from begin of the buf
183     *
184     * @param length size of elements of type byte in newly created Int8Array
185     */
186    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
187        this(buf, new Number(byteOffset), new Number(length))
188    }
189
190    /**
191     * Creates an Int8Array with respect to data, byteOffset and length.
192     *
193     * @param buf data initializer
194     *
195     * @param byteOffset byte offset from begin of the buf
196     *
197     * @param length size of elements of type byte in newly created Int8Array
198     */
199    public constructor(buf: ArrayBuffer, byteOffset: number) {
200        this(buf, new Number(byteOffset), undefined)
201    }
202
203    /**
204     * Creates an Int8Array with respect to data, byteOffset and length.
205     *
206     * @param buf data initializer
207     *
208     * @param byteOffset byte offset from begin of the buf
209     *
210     * @param length size of elements of type byte in newly created Int8Array
211     */
212    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
213        this(buf, new Number(byteOffset), new Number(length))
214    }
215
216    /**
217     * Creates an Int8Array with respect to buf and byteOffset.
218     *
219     * @param buf data initializer
220     *
221     * @param byteOffset byte offset from begin of the buf
222     */
223    public constructor(buf: ArrayBuffer, byteOffset: int) {
224        this(buf, new Number(byteOffset), undefined)
225    }
226
227    /**
228     * Creates an Int8Array with respect to buf.
229     *
230     * @param buf data initializer
231     */
232    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
233        if (buf instanceof ArrayBuffer) {
234            this.byteLength = (buf as ArrayBuffer).getByteLength()
235            if (this.byteLength % Int8Array.BYTES_PER_ELEMENT as int != 0) {
236               throw new RangeError("ArrayBuffer.byteLength should be multiple of 1 as Int8Array.BYTES_PER_ELEMENT")
237            }
238            this.lengthInt = this.byteLength / Int8Array.BYTES_PER_ELEMENT as int
239            this.buffer = buf as ArrayBuffer
240            this.byteOffset = 0
241        } else if (buf instanceof ArrayLike) {
242            // NOTE (ikorobkov): dealing with this overload is tricky
243            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
244            let arr = Array.from<Number>((buf as ArrayLike<Number>))
245            this.byteLength = arr.length as int * Int8Array.BYTES_PER_ELEMENT as int
246            this.lengthInt = arr.length as int
247            this.buffer = new ArrayBuffer(this.byteLength as int)
248            this.byteOffset = 0
249            for (let i: int = 0; i < this.lengthInt; ++i) {
250                this.setUnsafe(i, arr.$_get(i).toByte())
251            }
252        } else {
253            throw new Error("unexpected type of buf")
254        }
255    }
256
257    /**
258     * Creates an Int8Array with respect to length.
259     *
260     * @param length data initializer
261     */
262    public constructor(length: int) {
263        this(length as number)
264    }
265
266    /**
267     * Creates an Int8Array with respect to length.
268     *
269     * @param length data initializer
270     */
271    public constructor(length: number) {
272        if (length < 0 || length > (Int.MAX_VALUE / Int8Array.BYTES_PER_ELEMENT)) {
273            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
274        }
275        this.lengthInt = length as int
276        this.byteLength = this.lengthInt * Int8Array.BYTES_PER_ELEMENT as int
277        this.byteOffset = 0
278        this.buffer = new ArrayBuffer(this.byteLength as int)
279    }
280
281    /**
282     * Creates a copy of Int8Array.
283     *
284     * @param other data initializer
285     */
286    public constructor(other: Int8Array) {
287        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
288        this.byteLength = other.byteLength
289        this.lengthInt = other.length as int
290        this.byteOffset = 0
291    }
292
293    /**
294     * Creates an Int8Array from FixedArray<number>
295     */
296    public constructor(numbers: FixedArray<number>) {
297        this(numbers.length)
298        for (let i: int = 0; i < this.lengthInt; ++i) {
299            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
300        }
301    }
302
303    /**
304     * Creates an Int8Array from FixedArray<int>
305     */
306    public constructor(numbers: FixedArray<int>) {
307        this(numbers.length)
308        for (let i: int = 0; i < this.lengthInt; ++i) {
309            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
310        }
311    }
312
313    internal zeroIfInfinity(val: number): number {
314        if ((val == Infinity) || (val == -Infinity)) {
315            return 0 as number
316        }
317        return val as number
318    }
319
320    internal zeroIfInfinity(val: byte): byte {
321        if ((val == Infinity) || (val == -Infinity)) {
322            return 0 as byte
323        }
324        return val
325    }
326
327    /**
328     * Assigns val as element on index.
329     *
330     * @param val value to set
331     *
332     * @param index index to change
333     */
334    public $_set(index: number, val: number): void {
335        this.$_set(index as int, val)
336    }
337
338    /**
339     * Assigns val as element on index.
340     *
341     * @param val value to set
342     *
343     * @param index index to change
344     */
345    public $_set(index: int, val: number): void {
346        let v = this.zeroIfInfinity(val)
347        this.$_set(index, v as byte)
348    }
349
350    /**
351     * Assigns val as element on index.
352     *
353     * @param val value to set
354     *
355     * @param index index to change
356     */
357    public $_set(index: number, val: int): void {
358        this.$_set(index as int, val)
359    }
360
361    /**
362     * Assigns val as element on index.
363     *
364     * @param val value to set
365     *
366     * @param index index to change
367     */
368    public native $_set(index: int, val: int): void
369
370    /**
371     * Assigns val as element on index.
372     *
373     * @param val value to set
374     *
375     * @param index index to change
376     */
377    public $_set(index: number, val: byte): void {
378        this.$_set(index as int, val)
379    }
380
381    /**
382     * Assigns val as element on index.
383     *
384     * @param val value to set
385     *
386     * @param index index to change
387     */
388    public native $_set(index: int, val: byte): void
389
390    /** Number of byte stored in Int8Array */
391    public get length(): number {
392        return this.lengthInt
393    }
394
395    /**
396     * Returns an instance of number at passed index.
397     *
398     * @param index index to look at
399     *
400     * @returns a primitive at index
401     */
402    public override $_get(index: number): Number {
403        return this.$_get(index as int) as Number
404    }
405
406    /**
407     * Returns an instance of number at passed index.
408     *
409     * @param index index to look at
410     *
411     * @returns a primitive at index
412     */
413    public native $_get(index: int): number
414
415    /**
416     * Returns an instance of primitive type at passed index.
417     *
418     * @param index index to look at
419     *
420     * @returns a primitive at index
421     */
422    public at(index: number): Number | undefined {
423        return this.at(index as int)
424    }
425
426    /**
427     * Returns an instance of primitive type at passed index.
428     *
429     * @param index index to look at
430     *
431     * @returns a primitive at index
432     */
433    public at(index: int): Number | undefined {
434        let k: int
435        if (index >= 0) {
436            k = index
437        } else {
438            k = this.lengthInt + index
439        }
440        if (k < 0 || k >= this.lengthInt) {
441            return undefined
442        }
443        return new Number(this.getUnsafe(k))
444    }
445
446    /**
447     * Makes a copy of internal elements to targetPos from startPos to endPos.
448     *
449     * @param target insert index to place copied elements
450     *
451     * @param start start index to begin copy from
452     *
453     * @param end last index to end copy from, excluded
454     *
455     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
456     */
457    public copyWithin(target: number, start: number, end?: number): Int8Array {
458        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
459    }
460
461    /**
462     * Makes a copy of internal elements to targetPos from startPos to endPos.
463     *
464     * @param target insert index to place copied elements
465     *
466     * @param start start index to begin copy from
467     *
468     * @param end last index to end copy from, excluded
469     *
470     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
471     */
472    public copyWithin(target: int, start: number, end?: number): Int8Array {
473        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
474    }
475
476    /**
477     * Makes a copy of internal elements to targetPos from startPos to endPos.
478     *
479     * @param target insert index to place copied elements
480     *
481     * @param start start index to begin copy from
482     *
483     * @param end last index to end copy from, excluded
484     *
485     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
486     */
487    public copyWithin(target: number, start: int, end?: number): Int8Array {
488        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
489    }
490
491    /**
492     * Makes a copy of internal elements to targetPos from startPos to endPos.
493     *
494     * @param target insert index to place copied elements
495     *
496     * @param start start index to begin copy from
497     *
498     * @param end last index to end copy from, excluded
499     *
500     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
501     */
502    public copyWithin(target: int, start: int, end?: number): Int8Array {
503        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
504    }
505
506    /**
507     * Makes a copy of internal elements to targetPos from startPos to endPos.
508     *
509     * @param target insert index to place copied elements
510     *
511     * @param start start index to begin copy from
512     *
513     * @param end last index to end copy from, excluded
514     *
515     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
516     */
517    public native copyWithin(target: int, start: int, end: int): Int8Array
518
519    /**
520     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
521     *
522     * @param target insert index to place copied elements
523     *
524     * See rules of parameters normalization:
525     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
526     */
527    public copyWithin(target: number): Int8Array {
528        return this.copyWithin(target as int)
529    }
530
531    /**
532     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
533     *
534     * @param target insert index to place copied elements
535     *
536     * See rules of parameters normalization:
537     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
538     */
539    public copyWithin(target: int): Int8Array {
540        return this.copyWithin(target, 0, this.lengthInt)
541    }
542
543    /**
544     * Returns an array of key, value pairs for every entry in the Int8Array
545     *
546     * @returns key, value pairs for every entry in the array
547     */
548    public entries(): IterableIterator<[Number, Number]> {
549        return new Int8ArrayIteratorEntries(this)
550    }
551
552    /**
553     * Fills the Int8Array with specified value
554     *
555     * @param value new valuy
556     *
557     * @returns modified Int8Array
558     */
559    public fill(value: number, start?: number, end?: number): this {
560        value = this.zeroIfInfinity(value)
561        this.fill(value as byte, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
562        return this
563    }
564
565    /**
566     * Fills the Int8Array with specified value
567     *
568     * @param value new valuy
569     *
570     * @returns modified Int8Array
571     */
572    public fill(value: number, start: int, end?: number): this {
573        value = this.zeroIfInfinity(value)
574        this.fill(value as byte, start as int, asIntOrDefault(end, this.lengthInt))
575        return this
576    }
577
578    /**
579     * Fills the Int8Array with specified value
580     *
581     * @param value new valuy
582     *
583     * @returns modified Int8Array
584     */
585    public fill(value: number, start: int, end: number): this {
586        value = this.zeroIfInfinity(value)
587        this.fill(value as byte, start as int, end as int)
588        return this
589    }
590
591    /**
592     * Fills the Int8Array with specified value
593     *
594     * @param value new valuy
595     *
596     * @returns modified Int8Array
597     */
598    public fill(value: number, start: number, end: int): this {
599        value = this.zeroIfInfinity(value)
600        this.fill(value as byte, start as int, end as int)
601        return this
602    }
603
604    /**
605     * Fills the Int8Array with specified value
606     *
607     * @param value new valuy
608     *
609     * @returns modified Int8Array
610     */
611    public fill(value: number, start: int, end: int): this {
612        value = this.zeroIfInfinity(value)
613        this.fill(value as byte, start as int, end as int)
614        return this
615    }
616
617    /**
618     * Fills the Int8Array with specified value
619     *
620     * @param value new valuy
621     *
622     * @returns modified Int8Array
623     */
624    public fill(value: byte, start?: number, end?: number): this {
625        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
626        return this
627    }
628
629    /**
630     * Fills the Int8Array with specified value
631     *
632     * @param value new valuy
633     *
634     * @returns modified Int8Array
635     */
636    public fill(value: byte, start: int, end?: number): this {
637        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
638        return this
639    }
640
641    /**
642     * Fills the Int8Array with specified value
643     *
644     * @param value new valuy
645     *
646     * @returns modified Int8Array
647     */
648    public fill(value: byte, start: int, end: number): this {
649        this.fill(value, start as int, end as int)
650        return this
651    }
652
653    /**
654     * Fills the Int8Array with specified value
655     *
656     * @param value new valuy
657     *
658     * @returns modified Int8Array
659     */
660    public fill(value: byte, start: number, end: int): this {
661        this.fill(value, start as int, end as int)
662        return this
663    }
664
665    /**
666     * Fills the Int8Array with specified value
667     *
668     * @param value new valuy
669     *
670     * @returns modified Int8Array
671     */
672    public fill(value: byte, start: int, end: int): this {
673        const k = normalizeIndex(start, this.lengthInt)
674        const finalPos = normalizeIndex(end, this.lengthInt)
675        this.fillInternal(value, k, finalPos)
676        return this
677    }
678
679    private final native fillInternal(value: byte, start: int, end: int): void
680
681    /**
682     * Assigns val as element on insertPos.
683     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<byte>, insertPos)
684     *
685     * @param val value to set
686     *
687     * @param insertPos index to change
688     */
689    public set(insertPos: number, val: number): void {
690        this.$_set(insertPos, val)
691    }
692
693    /**
694     * Assigns val as element on insertPos.
695     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<byte>, insertPos)
696     *
697     * @param val value to set
698     *
699     * @param insertPos index to change
700     */
701    public set(insertPos: int, val: byte): void {
702        this.$_set(insertPos, val)
703    }
704
705    /**
706     * Copies all elements of arr to the current Int8Array starting from insertPos.
707     *
708     * @param arr array to copy data from
709     *
710     * @param insertPos start index where data from arr will be inserted
711     *
712     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
713     */
714    public set(arr: FixedArray<number>, insertPos: number): void {
715        const offset = insertPos as int
716        if (offset < 0 || offset + arr.length > this.lengthInt) {
717            throw new RangeError("offset is out of bounds")
718        }
719        for (let i = 0; i < arr.length as int; ++i) {
720            let v = this.zeroIfInfinity(arr[i])
721            this.$_set(offset + i, v as byte)
722        }
723    }
724
725    /**
726     * Copies all elements of arr to the current Int8Array starting from insertPos.
727     *
728     * @param arr array to copy data from
729     *
730     * @param insertPos start index where data from arr will be inserted
731     *
732     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
733     */
734    public set(arr: FixedArray<byte>, insertPos: int): void {
735        const offset = insertPos as int
736        if (offset < 0 || offset + arr.length > this.lengthInt) {
737            throw new RangeError("offset is out of bounds")
738        }
739        for (let i = 0; i < arr.length as int; ++i) {
740            let v = this.zeroIfInfinity(arr[i])
741            this.$_set(offset + i, v)
742        }
743    }
744
745    /**
746     * Copies all elements of arr to the current Int8Array.
747     *
748     * @param arr array to copy data from
749     */
750    public set(arr: FixedArray<number>): void {
751        this.set(arr, 0 as number)
752    }
753
754    /**
755     * Copies all elements of arr to the current Int8Array.
756     *
757     * @param arr array to copy data from
758     */
759    public set(arr: FixedArray<byte>): void {
760        this.set(arr, 0 as int)
761    }
762
763    public native set(array: Int8Array): void
764
765    public native set(array: Int8Array, offset: number): void
766
767    /**
768     * Copies elements from an ArrayLike object to the Int8Array.
769     *
770     * @param array An ArrayLike object containing the elements to copy.
771     *
772     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
773     */
774    public set(array: ArrayLike<number>, offset: number = 0): void {
775        const insertPos = offset as int
776        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
777            throw new RangeError("offset is out of bounds")
778        }
779        for (let i = array.length - 1 as int; i >= 0; --i) {
780            let v = this.zeroIfInfinity(array[i])
781            this.$_set(insertPos + i, v as byte)
782        }
783    }
784
785    /**
786     * Returns a new array from a set of elements.
787     *
788     * @param items a set of elements to include in the new array object.
789     *
790     * @returns new Int8Array
791     */
792    public static of(...items: FixedArray<number>): Int8Array {
793        let res = new Int8Array(items.length as int)
794        for (let i: int = 0; i < items.length; i++) {
795            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as byte)
796        }
797        return res
798    }
799
800    /**
801     * Returns a new array from a set of elements.
802     *
803     * @param items a set of elements to include in the new array object.
804     *
805     * @returns new Int8Array
806     */
807    public static of(...items: FixedArray<int>): Int8Array {
808        let res = new Int8Array(items.length as int)
809        for (let i: int = 0; i < items.length; i++) {
810            res.setUnsafe(i, items[i] as byte)
811        }
812        return res
813    }
814
815    /**
816     * Returns a new array from a set of elements.
817     *
818     * @param items a set of elements to include in the new array object.
819     *
820     * @returns new Int8Array
821     */
822    public static of(...items: FixedArray<byte>): Int8Array {
823        let res = new Int8Array(items.length as int)
824        for (let i: int = 0; i < items.length; i++) {
825            res.setUnsafe(i, items[i])
826        }
827        return res
828    }
829
830    /**
831     * Returns a new array from a set of elements.
832     *
833     * @param items a set of elements to include in the new array object.
834     *
835     * @returns new Int8Array
836     */
837    public static of(): Int8Array {
838        return new Int8Array(0 as int)
839    }
840
841    /**
842     * Creates an array from an array-like or iterable object.
843     *
844     * @param arrayLike An array-like or iterable object to convert to an array.
845     *
846     * @returns new Int8Array
847     */
848    public static from(arrayLike: ArrayLike<number>): Int8Array {
849        return Int8Array.from<number>(arrayLike, (x: number, k: number): number => x)
850    }
851
852    /**
853     * Creates an array from an array-like or iterable object.
854     *
855     * @param arrayLike An array-like or iterable object to convert to an array.
856     *
857     * @param mapfn A mapping function to call on every element of the array.
858     *
859     * @returns new Int8Array
860     */
861    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int8Array {
862        if (mapfn == undefined) {
863            mapfn = (v: number, k: number): number => { return v }
864        }
865
866        let iter = arrayLike.$_iterator()
867        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
868        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
869        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
870        //  we can make one pass through the iterator without the need for memory reallocation.
871        const maybeLength = tryGetIteratorLength(arrayLike)
872        if (maybeLength) {
873            const result = new Int8Array(maybeLength)
874            for (let i = 0; i < maybeLength; ++i) {
875                const x = iter.next()
876                if (x.done) {
877                    return new Int8Array(result.buffer, 0, i)
878                }
879                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as byte)
880            }
881            return result
882        }
883
884        // NOTE (templin.konstantin): Create builtin array as buffer
885        let temp = new Int8Array(6)
886        let index : FixedArray<int> = new int[1]
887        index[0] = 0
888
889        iteratorForEach<number>(iter, (x: number): void => {
890            if (index[0] + 1 > temp.lengthInt) {
891                // NOTE (templin.konstantin): Progressive reallocation
892                const curLength = (temp.buffer as Buffer).getByteLength()
893                const tb = new ArrayBuffer(curLength * 2)
894                for (let i = 0; i < curLength; ++i) {
895                    tb.set(i, (temp.buffer as Buffer).at(i))
896                }
897                temp = new Int8Array(tb)
898            }
899            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as byte)
900            index[0]++
901        })
902        return new Int8Array(temp.buffer, 0, index[0])
903    }
904
905
906    /**
907     * Creates an array from an array-like or iterable object.
908     *
909     * @param arrayLike An array-like or iterable object to convert to an array.
910     *
911     * @param mapfn A mapping function to call on every element of the array.
912     *
913     * @returns new Int8Array
914     */
915    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int8Array {
916        let res = new Int8Array(arrayLike.length)
917        // 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
918        const idx : FixedArray<int> = new int[1]
919        idx[0] = 0
920        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
921            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as byte)
922            idx[0] += 1
923        })
924        return res
925    }
926
927    /**
928     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
929     *
930     * @param searchElement The element to search for
931     *
932     * @param fromIndex The position in this array at which to begin searching for searchElement
933     *
934     * @returns true if searchElement is in Int8Array, false otherwise
935     */
936    public includes(searchElement: number, fromIndex?: number): boolean {
937        if (isNaN(searchElement)) {
938            return false
939        }
940        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
941    }
942
943    /**
944     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
945     *
946     * @param searchElement The element to search for
947     *
948     * @param fromIndex The position in this array at which to begin searching for searchElement
949     *
950     * @returns true if e is in Int8Array, false otherwise
951     */
952    public includes(searchElement: byte, fromIndex: int): boolean {
953        return this.indexOf(searchElement as int, fromIndex) != -1
954    }
955
956    /**
957     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
958     *
959     * @param searchElement The element to search for
960     *
961     * @param fromIndex The position in this array at which to begin searching for searchElement
962     *
963     * @returns true if searchElement is in Int8Array, false otherwise
964     */
965    public includes(searchElement: byte): boolean {
966        return this.includes(searchElement, 0)
967    }
968
969    /**
970     * Returns the index of the first occurrence of a value in Int8Array.
971     *
972     * @param searchElement The value to locate in the array.
973     *
974     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
975     *  search starts at index 0.
976     *
977     * @returns index of element if it presents, -1 otherwise
978     */
979    public indexOf(searchElement: number, fromIndex?: number): number {
980        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
981    }
982
983    /**
984     * Returns the index of the first occurrence of a value in Int8Array.
985     *
986     * @param searchElement The value to locate in the array.
987     *
988     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
989     *  search starts at index 0.
990     *
991     * @returns index of element if it presents, -1 otherwise
992     */
993    public indexOf(searchElement: number, fromIndex: int): number {
994            return this.indexOfImpl(searchElement, fromIndex)
995    }
996
997    /**
998     * Returns the index of the first occurrence of a value in Int8Array.
999     *
1000     * @param searchElement The value to locate in the array.
1001     *
1002     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1003     *  search starts at index 0.
1004     *
1005     * @returns index of element if it presents, -1 otherwise
1006     */
1007    public indexOf(searchElement: int, fromIndex: int): number {
1008        return this.indexOfImpl(searchElement as long, fromIndex)
1009    }
1010
1011    /**
1012     * Returns the index of the first occurrence of a value in Int8Array.
1013     *
1014     * @param searchElement The value to locate in the array.
1015     *
1016     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1017     *  search starts at index 0.
1018     *
1019     * @returns index of element if it presents, -1 otherwise
1020     */
1021    private final native indexOfImpl(searchElement: number, fromIndex: int): number
1022
1023    /**
1024     * Returns the index of the first occurrence of a value in Int8Array.
1025     *
1026     * @param searchElement The value to locate in the array.
1027     *
1028     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1029     *  search starts at index 0.
1030     *
1031     * @returns index of element if it presents, -1 otherwise
1032     */
1033    private final native indexOfImpl(searchElement: long, fromIndex: int): number
1034
1035    /**
1036     * Returns the index of the first occurrence of a value in Int8Array.
1037     *
1038     * @param searchElement The value to locate in the array.
1039     *
1040     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1041     *  search starts at index 0.
1042     *
1043     * @returns index of element if it presents, -1 otherwise
1044     */
1045    public indexOf(searchElement: int): number {
1046        return this.indexOf(searchElement, 0)
1047    }
1048
1049    /**
1050     * Converts all elements of an array to strings and joins them using the specified separator.
1051     *
1052     * @param separator - separates one element of an array from the next in the resulting String.
1053     *
1054     * @returns joined representation
1055     */
1056    private final native joinInternal(separator: String): string;
1057
1058    /**
1059     * Adds all the elements of an array separated by the specified separator string
1060     *
1061     * @param separator A string used to separate one element of an array from the next in the
1062     * resulting String. If omitted, the array elements are separated with a comma.
1063     *
1064     * @returns joined representation
1065     */
1066    public join(separator?: String): string {
1067        if (separator == undefined) {
1068            return this.joinInternal(",")
1069        }
1070        return this.joinInternal(separator)
1071    }
1072
1073    /**
1074     * Returns an list of keys in Int8Array
1075     *
1076     * @returns iterator over keys
1077     */
1078    public keys(): IterableIterator<number> {
1079        return new Int8ArrayIteratorKeys(this)
1080    }
1081
1082    /**
1083     * Returns the index of the last occurrence of a value in Int8Array.
1084     *
1085     * @param searchElement The value to locate in the array.
1086     *
1087     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1088     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1089     *
1090     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1091     */
1092    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
1093        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
1094    }
1095
1096    /**
1097     * Returns the index of the last occurrence of a value in Int8Array.
1098     *
1099     * @param searchElement The value to locate in the array.
1100     *
1101     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1102     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1103     *
1104     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1105     */
1106    public lastIndexOf(searchElement: number): number {
1107        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1108    }
1109
1110    /**
1111     * Returns the index of the last occurrence of a value in Int8Array.
1112     *
1113     * @param searchElement The value to locate in the array.
1114     *
1115     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1116     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1117     *
1118     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1119     */
1120    public lastIndexOf(searchElement: number, fromIndex: int): number {
1121            return this.lastIndexOfImpl(searchElement, fromIndex)
1122    }
1123
1124    /**
1125     * Returns the index of the last occurrence of a value in Int8Array.
1126     *
1127     * @param searchElement The value to locate in the array.
1128     *
1129     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1130     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1131     *
1132     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1133     */
1134    public lastIndexOf(searchElement: int, fromIndex: int): number {
1135        return this.lastIndexOfImpl(searchElement as long, fromIndex)
1136    }
1137
1138    /**
1139     * Returns the index of the last occurrence of a value in Int8Array.
1140     *
1141     * @param searchElement The value to locate in the array.
1142     *
1143     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1144     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1145     *
1146     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1147     */
1148    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
1149
1150    /**
1151     * Returns the index of the last occurrence of a value in Int8Array.
1152     *
1153     * @param searchElement The value to locate in the array.
1154     *
1155     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1156     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1157     *
1158     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1159     */
1160    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
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: int): number {
1173        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1174    }
1175
1176    /**
1177    * Creates a new Int8Array using initializer
1178    *
1179    * @param data initializer
1180    *
1181    * @returns a new Int8Array from data
1182    */
1183    public of(data: FixedArray<Object>): Int8Array {
1184        throw new Error("Int8Array.of: not implemented")
1185    }
1186
1187    /**
1188     * Creates a new Int8Array using reversed data from the current one
1189     *
1190     * @returns a new Int8Array using reversed data from the current one
1191     */
1192    public native reverse(): Int8Array
1193
1194    /**
1195     * Creates a slice of current Int8Array using range [begin, end)
1196     *
1197     * @param begin start index to be taken into slice
1198     *
1199     * @param end last index to be taken into slice
1200     *
1201     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1202     *
1203     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1204     */
1205    public slice(begin?: number, end?: number): Int8Array {
1206        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1207    }
1208
1209    /**
1210     * Creates a slice of current Int8Array using range [begin, end)
1211     *
1212     * @param begin start index to be taken into slice
1213     *
1214     * @param end last index to be taken into slice
1215     *
1216     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1217     *
1218     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1219     */
1220    public slice(begin: number, end: number): Int8Array {
1221        return this.slice(begin as int, end as int)
1222    }
1223
1224    /**
1225     * Creates a slice of current Int8Array using range [begin, end)
1226     *
1227     * @param begin start index to be taken into slice
1228     *
1229     * @param end last index to be taken into slice
1230     *
1231     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1232     *
1233     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1234     */
1235    public slice(begin: number, end: int): Int8Array {
1236        return this.slice(begin as int, end as int)
1237    }
1238
1239    /**
1240     * Creates a slice of current Int8Array using range [begin, end)
1241     *
1242     * @param begin start index to be taken into slice
1243     *
1244     * @param end last index to be taken into slice
1245     *
1246     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1247     *
1248     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1249     */
1250    public slice(begin: int, end: number): Int8Array {
1251        return this.slice(begin as int, end as int)
1252    }
1253
1254    /**
1255     * Creates a slice of current Int8Array using range [begin, end)
1256     *
1257     * @param begin start index to be taken into slice
1258     *
1259     * @param end last index to be taken into slice
1260     *
1261     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1262     *
1263     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1264     */
1265    public slice(begin: int, end: int): Int8Array {
1266        const len: int = this.lengthInt
1267        const relStart = normalizeIndex(begin, len)
1268        const relEnd = normalizeIndex(end, len)
1269        let count = relEnd - relStart
1270        if (count < 0) {
1271            count = 0
1272        }
1273        let buf = this.buffer.slice(relStart * Int8Array.BYTES_PER_ELEMENT as int, relEnd * Int8Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
1274        return new Int8Array(buf)
1275    }
1276
1277    /**
1278     * Creates a slice of current Int8Array using range [begin, this.length).
1279     *
1280     * @param begin start index to be taken into slice
1281     *
1282     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1283     */
1284    public slice(begin: number): Int8Array {
1285        return this.slice(begin as int)
1286    }
1287
1288    /**
1289     * Creates a slice of current Int8Array using range [begin, this.length).
1290     *
1291     * @param begin start index to be taken into slice
1292     *
1293     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1294     */
1295    public slice(begin: int): Int8Array {
1296        return this.slice(begin, this.lengthInt)
1297    }
1298
1299    /**
1300     * Creates a Int8Array with the same underlying ArrayBuffer
1301     *
1302     * @param begin start index, inclusive
1303     *
1304     * @param end last index, exclusive
1305     *
1306     * @returns new Int8Array with the same underlying ArrayBuffer
1307     */
1308    public subarray(begin?: number, end?: number): Int8Array {
1309        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1310    }
1311
1312    /**
1313     * Creates a Int8Array with the same underlying ArrayBuffer
1314     *
1315     * @param begin start index, inclusive
1316     *
1317     * @param end last index, exclusive
1318     *
1319     * @returns new Int8Array with the same underlying ArrayBuffer
1320     */
1321    public subarray(begin: number, end: number): Int8Array {
1322        return this.subarray(begin as int, end as int)
1323    }
1324
1325    /**
1326     * Creates a Int8Array with the same underlying ArrayBuffer
1327     *
1328     * @param begin start index, inclusive
1329     *
1330     * @param end last index, exclusive
1331     *
1332     * @returns new Int8Array with the same underlying ArrayBuffer
1333     */
1334    public subarray(begin: number, end: int): Int8Array {
1335        return this.subarray(begin as int, end as int)
1336    }
1337
1338    /**
1339     * Creates a Int8Array with the same underlying ArrayBuffer
1340     *
1341     * @param begin start index, inclusive
1342     *
1343     * @param end last index, exclusive
1344     *
1345     * @returns new Int8Array with the same underlying ArrayBuffer
1346     */
1347    public subarray(begin: int, end: number): Int8Array {
1348        return this.subarray(begin as int, end as int)
1349    }
1350
1351    /**
1352     * Creates a Int8Array with the same underlying ArrayBuffer
1353     *
1354     * @param begin start index, inclusive
1355     *
1356     * @param end last index, exclusive
1357     *
1358     * @returns new Int8Array with the same underlying ArrayBuffer
1359     */
1360    public subarray(begin: int, end: int | undefined = this.lengthInt): Int8Array {
1361        const len: int = this.lengthInt
1362        const relStart = normalizeIndex(begin, len)
1363        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
1364        let count = relEnd - relStart
1365        if (count < 0) {
1366            count = 0
1367        }
1368        return new Int8Array(this.buffer, relStart * Int8Array.BYTES_PER_ELEMENT as int, count)
1369    }
1370
1371    /**
1372     * Converts Int8Array to a string with respect to locale
1373     *
1374     * @param locales
1375     *
1376     * @param options
1377     *
1378     * @returns string representation
1379     */
1380    public toLocaleString(locales: Object, options: Object): string {
1381        throw new Error("Int8Array.toLocaleString: not implemented")
1382    }
1383
1384    /**
1385     * Converts Int8Array to a string with respect to locale
1386     *
1387     * @param locales
1388     *
1389     * @returns string representation
1390     */
1391    public toLocaleString(locales: Object): string {
1392        return this.toLocaleString(new Object(), new Object())
1393    }
1394
1395    /**
1396     * Converts Int8Array to a string with respect to locale
1397     *
1398     * @returns string representation
1399     */
1400    public toLocaleString(): string {
1401        let res: StringBuilder = new StringBuilder("")
1402        for (let i = 0; i < this.lengthInt - 1; ++i) {
1403            res.append((this.getUnsafe(i) as Number).toLocaleString())
1404            res.append(",")
1405        }
1406        if (this.lengthInt > 0) {
1407            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
1408        }
1409        return res.toString()
1410    }
1411
1412    /**
1413     * Creates a reversed copy
1414     *
1415     * @returns a reversed copy
1416     */
1417    public final native toReversed(): Int8Array
1418
1419    /**
1420     * Creates a sorted copy
1421     *
1422     * @returns a sorted copy
1423     */
1424    public toSorted(): Int8Array {
1425        return new Int8Array(this).sort()
1426    }
1427
1428    /**
1429     * Returns a string representation of the Int8Array
1430     *
1431     * @returns a string representation of the Int8Array
1432     */
1433    public override toString(): string {
1434        return this.join(",")
1435    }
1436
1437    /**
1438     * Returns array values iterator
1439     *
1440     * @returns an iterator
1441     */
1442    public values(): IterableIterator<Number> {
1443        return new Int8ArrayIterator(this)
1444    }
1445
1446    /**
1447     * Iteratorable interface implementation
1448     *
1449     * @returns iterator over all elements
1450     */
1451    public override $_iterator(): IterableIterator<Number> {
1452        return this.values()
1453    }
1454
1455    /**
1456     * Creates a copy with replaced value on index
1457     *
1458     * @param index
1459     *
1460     * @param value
1461     *
1462     * @returns an Int8Array with replaced value on index
1463     */
1464    public with(index: number, value: number): Int8Array {
1465        return this.with(index as int, value as byte)
1466    }
1467
1468    /**
1469     * Creates a copy with replaced value on index
1470     *
1471     * @param index
1472     *
1473     * @param value
1474     *
1475     * @returns an Int8Array with replaced value on index
1476     */
1477    public with(index: int, value: byte): Int8Array {
1478        let res = new Int8Array(this)
1479        res.set(index, value)
1480        return res
1481    }
1482
1483    /// === with element lambda functions ===
1484
1485    /**
1486     * Finds the last element in the Int8Array that satisfies the condition
1487     *
1488     * @param fn condition
1489     *
1490     * @returns the last element that satisfies fn
1491     */
1492    public findLast(fn: (val: number) => boolean): number {
1493        let newF: (val: number, index: number, array: Int8Array) => boolean =
1494            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1495        return this.findLast(newF) as number
1496    }
1497
1498    /**
1499     * Sorts in-place by numeric value in ascending order.
1500     *
1501     * @returns sorted Int8Array
1502     */
1503    public native sort(): this;
1504
1505    /**
1506     * Sorts in-place
1507     *
1508     * @param compareFn comparator _  used to determine the order of the elements.
1509     * compareFn returns a negative value if first argument is less than second argument,
1510     * zero if they're equal and a positive value otherwise.
1511     *
1512     * @returns sorted Int8Array
1513     */
1514    public sort(compareFn?: (a: number, b: number) => number): this {
1515        if (compareFn == undefined) {
1516            this.sort()
1517            return this
1518        }
1519        let arr: FixedArray<byte> = new byte[this.lengthInt]
1520        for (let i = 0; i < this.lengthInt; ++i) {
1521            arr[i] = this.getUnsafe(i)
1522        }
1523
1524        let cmp = (l: byte, r: byte): number => {
1525            const result = compareFn!(l as number, r as number)
1526            return result
1527        }
1528        const MAX_SHORT_LENGTH = 24
1529        if (arr.length > MAX_SHORT_LENGTH) {
1530            arr = mergeSort(arr, cmp)
1531        } else {
1532            sort(arr, cmp)
1533        }
1534        for (let i = 0; i < arr.length; ++i) {
1535            this.setUnsafe(i, arr[i])
1536        }
1537        return this
1538    }
1539
1540    /**
1541     * Determines whether the specified callback function returns true for any element of an array.
1542     *
1543     * @param predicate A function that accepts three arguments.
1544     * The some method calls the predicate function for each element in the array
1545     * until the predicate returns a true or until the end of the array.
1546     *
1547     * @returns false unless predicate function returns true for an array element,
1548     * in which case true is immediately returned.
1549     */
1550    public some(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
1551        for (let i = 0; i < this.lengthInt; ++i) {
1552            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
1553                return true
1554            }
1555        }
1556        return false
1557    }
1558
1559    /**
1560     * Calls the specified callback function for all the elements in an array.
1561     * The return value of the callback function is the accumulated result,
1562     * and is provided as an argument in the next call to the callback function.
1563     *
1564     * @param callbackfn A function that accepts four arguments.
1565     * The reduce method calls the callbackfn function one time for each element in the array.
1566     *
1567     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1568     * The first call to the callbackfn function provides this value as an argument.
1569     *
1570     * @returns The value that results from running the callback function to completion over the entire typed array.
1571     */
1572    public reduce<U = number>(
1573                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
1574                initialValue: U): U {
1575        let accumulatedValue = initialValue
1576        for (let i = 0; i < this.lengthInt; ++i) {
1577            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1578        }
1579        return accumulatedValue
1580    }
1581
1582    /**
1583     * Calls the specified callback function for all the elements in an array.
1584     * The return value of the callback function is the accumulated result,
1585     * and is provided as an argument in the next call to the callback function.
1586     *
1587     * @param callbackfn A function that accepts four arguments.
1588     * The reduce method calls the callbackfn function one time for each element in the array.
1589     * The first call to the callbackfn function provides array first element value as an argument
1590     *
1591     * @returns The value that results from running the callback function to completion over the entire typed array.
1592     * calling reduce method on an empty array without an initial value creates a TypeError
1593     */
1594    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
1595        if (this.lengthInt == 0) {
1596            throw new TypeError("Reduce of empty array with no initial value")
1597        }
1598
1599        let accumulatedValue = this.getUnsafe(0) as number
1600        for (let i = 1; i < this.lengthInt; ++i) {
1601            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1602        }
1603        return accumulatedValue
1604    }
1605
1606    /**
1607     * Calls the specified callback function for all the elements in an array, in descending order.
1608     * The return value of the callback function is the accumulated result,
1609     * and is provided as an argument in the next call to the callback function.
1610     *
1611     * @param callbackfn A function that accepts four arguments.
1612     * The reduceRight method calls the callbackfn function one time for each element in the array.
1613     *
1614     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1615     * The first call to the callbackfn function provides this value as an argument.
1616     *
1617     * @returns The value that results from running the callback function to completion over the entire typed array.
1618     */
1619    public reduceRight<U = number>(
1620                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
1621                initialValue: U): U {
1622        let accumulatedValue = initialValue
1623        for (let i = this.lengthInt - 1; i >= 0; --i) {
1624            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1625        }
1626        return accumulatedValue
1627    }
1628
1629
1630    /**
1631     * Calls the specified callback function for all the elements in an array, in descending order.
1632     * The return value of the callback function is the accumulated result,
1633     * and is provided as an argument in the next call to the callback function.
1634     *
1635     * @param callbackfn A function that accepts four arguments.
1636     * The reduceRight method calls the callbackfn function one time for each element in the array.
1637     * The first call to the callbackfn function provides array last element value as an argument
1638     *
1639     * @returns The value that results from running the callback function to completion over the entire typed array.
1640     * calling reduceRight method on an empty array without an initial value creates a TypeError
1641     */
1642    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
1643        if (this.lengthInt == 0) {
1644            throw new TypeError("Reduce of empty array with no initial value")
1645        }
1646
1647        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
1648        for (let i = this.lengthInt - 2; i >= 0; --i) {
1649            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1650        }
1651        return accumulatedValue
1652    }
1653
1654   /**
1655    * Creates a new Int8Array using fn(arr[i]) over all elements of current Int8Array.
1656    *
1657    * @param fn a function to apply for each element of current Int8Array
1658    *
1659    * @returns a new Int8Array where for each element from current Int8Array fn was applied
1660    */
1661    public map(fn: (val: number, index: number, array: Int8Array) => number): Int8Array {
1662        let resBuf = new ArrayBuffer(this.lengthInt * Int8Array.BYTES_PER_ELEMENT as int)
1663        let res = new Int8Array(resBuf, 0, resBuf.getByteLength() / Int8Array.BYTES_PER_ELEMENT as int)
1664        for (let i = 0; i < this.lengthInt; ++i) {
1665            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as byte)
1666        }
1667        return res
1668    }
1669
1670    /**
1671     * Determines whether the specified callback function returns true for all elements of an array.
1672     *
1673     * @param predicate A function that accepts three arguments.
1674     * The every method calls the predicate function for each element in the array until the predicate returns a false,
1675     * or until the end of the array.
1676     *
1677     * @returns true unless predicate function returns a false for an array element,
1678     * in which case false is immediately returned.
1679     */
1680    public every(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
1681        for (let i = 0; i < this.lengthInt; ++i) {
1682            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
1683                return false
1684            }
1685        }
1686        return true
1687    }
1688
1689    /**
1690     * Creates a new Int8Array from current Int8Array based on a condition fn.
1691     *
1692     * @param fn the condition to apply for each element
1693     *
1694     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
1695     */
1696    public filter(fn: (val: number, index: number, array: Int8Array) => boolean): Int8Array {
1697        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
1698        let resLen = 0
1699        for (let i = 0; i < this.lengthInt; ++i) {
1700            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
1701            if (markers[i]) {
1702                ++resLen
1703            }
1704        }
1705        let resBuf = new ArrayBuffer(resLen * Int8Array.BYTES_PER_ELEMENT as int)
1706        let res = new Int8Array(resBuf, 0)
1707        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
1708            if (markers[i]) {
1709                res.set(j, this.getUnsafe(i))
1710                ++j
1711            }
1712        }
1713        return res
1714    }
1715
1716    /**
1717     * Returns the value of the first element in the array where predicate is true, and undefined
1718     * otherwise
1719     *
1720     * @param predicate find calls predicate once for each element of the array, in ascending
1721     * order, until it finds one where predicate returns true. If such an element is found, find
1722     * immediately returns that element value. Otherwise, find returns undefined
1723     *
1724     * @returns number | undefined
1725     */
1726    public find(predicate: (value: number, index: number, obj: Int8Array) => boolean): number | undefined {
1727        for (let i = 0; i < this.lengthInt; ++i) {
1728            let val = this.getUnsafe(i)
1729            if (predicate(val as number, i as number, this)) {
1730                return val as number
1731            }
1732        }
1733        return undefined
1734    }
1735
1736    /**
1737     * Returns the index of the first element in the array where predicate is true, and -1
1738     * otherwise
1739     *
1740     * @param predicate find calls predicate once for each element of the array, in ascending
1741     * order, until it finds one where predicate returns true. If such an element is found,
1742     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
1743     *
1744     * @returns number
1745     */
1746    public findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean): number {
1747        for (let i = 0; i < this.lengthInt; ++i) {
1748            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
1749                return i as number
1750            }
1751        }
1752        return -1 as number
1753    }
1754
1755    /**
1756     * Finds the last element in the Int8Array that satisfies the condition
1757     *
1758     * @param fn condition
1759     *
1760     * @returns the last element that satisfies fn
1761     */
1762    public findLast(fn: (val: number, index: number, array: Int8Array) => boolean): byte {
1763        for (let i = this.lengthInt - 1; i >= 0; --i) {
1764            let val = this.getUnsafe(i)
1765            if (fn(val as number, i as number, this)) {
1766                return val
1767            }
1768        }
1769        throw new Error("Int8Array.findLast: not implemented if an element was not found")
1770    }
1771
1772    /**
1773     * Finds an index of the last element in the Int8Array that satisfies the condition
1774     *
1775     * @param fn condition
1776     *
1777     * @returns the index of the last element that satisfies fn, -1 otherwise
1778     */
1779    public findLastIndex(fn: (val: number, index: number, array: Int8Array) => boolean): number {
1780        for (let i = this.lengthInt - 1; i >= 0; --i) {
1781            let val = this.getUnsafe(i)
1782            if (fn(val as number, i as number, this)) {
1783                return i
1784            }
1785        }
1786        return -1 as number
1787    }
1788
1789    /**
1790     * Performs the specified action for each element in Int8Array
1791     *
1792     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
1793     * callbackfn function one time for each element in the array.
1794     *
1795     * @returns None
1796     */
1797    public forEach(callbackfn: (value: number, index: number, array: Int8Array) => void): void {
1798        for (let i = 0; i < this.lengthInt; ++i) {
1799            callbackfn(this.getUnsafe(i) as number, i as number, this)
1800        }
1801    }
1802
1803    /**
1804     * Returns the object itself
1805     *
1806     * @returns Int8Array
1807     */
1808    public valueOf(): Int8Array {
1809        return this
1810    }
1811
1812    private final native getUnsafe(index: int): byte
1813
1814    internal setUnsafe(insertPos: int, val: byte): void {
1815        let startByte = insertPos * Int8Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
1816        let bits = val
1817        if (IS_LITTLE_ENDIAN) {
1818            for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
1819                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
1820                this.buffer.set(startByte + i, byteVal)
1821            }
1822        } else {
1823            for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; i++) {
1824                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
1825                this.buffer.set(startByte + 0 - i, byteVal)
1826            }
1827        }
1828    }
1829
1830    /** Underlying ArrayBuffer */
1831    public readonly buffer: ArrayBuffer
1832
1833    /** Byte offset within the underlying ArrayBuffer */
1834    public readonly byteOffset: number
1835
1836    /** Number of bytes used */
1837    public readonly byteLength: number
1838
1839    /** String \"Int8Array\" */
1840    public readonly name = "Int8Array"
1841}
1842
1843class Int16ArrayIteratorKeys implements IterableIterator<number> {
1844    private length: int
1845    private idx: int = 0
1846
1847    constructor(parent: Int16Array) {
1848        this.length = parent.length as int
1849    }
1850
1851    public override $_iterator(): IterableIterator<number> {
1852        return this
1853    }
1854
1855    override next(): IteratorResult<number> {
1856        if (this.idx < 0 || this.idx >= this.length) {
1857            return new IteratorResult<number>()
1858        }
1859        return new IteratorResult<number>(false, this.idx++ as number)
1860    }
1861}
1862
1863class Int16ArrayIterator implements IterableIterator<Number> {
1864    private parent: Int16Array
1865    private idx: int = 0
1866
1867    constructor(parent: Int16Array) {
1868        this.parent = parent
1869    }
1870
1871    public override $_iterator(): IterableIterator<Number> {
1872        return this
1873    }
1874
1875    override next(): IteratorResult<Number> {
1876        if (this.idx < 0 || this.idx >= this.parent.length as int) {
1877            return new IteratorResult<Number>()
1878        }
1879        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
1880    }
1881}
1882
1883class Int16ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
1884    private parent: Int16Array
1885    private idx: int = 0
1886
1887    constructor(parent: Int16Array) {
1888        this.parent = parent
1889    }
1890
1891    public override $_iterator(): IterableIterator<[Number, Number]> {
1892        return this
1893    }
1894
1895    override next(): IteratorResult<[Number, Number]> {
1896        if (this.idx < 0 || this.idx >= this.parent.length as int) {
1897            return new IteratorResult<[Number, Number]>()
1898        }
1899        return new IteratorResult<[Number, Number]>(
1900            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
1901        )
1902    }
1903}
1904
1905
1906/**
1907 * JS Int16Array API-compatible class
1908 */
1909export final class Int16Array implements Iterable<Number>, ArrayLike<Number> {
1910    public static readonly BYTES_PER_ELEMENT: number = 2
1911    public readonly BYTES_PER_ELEMENT: number = Int16Array.BYTES_PER_ELEMENT
1912    internal readonly lengthInt: int
1913
1914    /**
1915     * Creates an empty Int16Array.
1916     */
1917    public constructor() {
1918        this(0 as int)
1919    }
1920
1921    /**
1922     * Creates an Int16Array with respect to data accessed via Iterable<Number> interface
1923     */
1924    public constructor(elements: Iterable<Number>) {
1925        const items: Object = elements as Object
1926        if (items instanceof ArrayLike) {
1927            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
1928            this.byteLength = arr.length as int * Int16Array.BYTES_PER_ELEMENT as int
1929            this.lengthInt = arr.length as int
1930            this.buffer = new ArrayBuffer(this.byteLength as int)
1931            this.byteOffset = 0
1932            for (let i: int = 0; i < this.lengthInt; ++i) {
1933                this.setUnsafe(i, arr.$_get(i).toShort())
1934            }
1935        } else {
1936          let x = Int16Array.from(elements)
1937          this.byteLength = x.byteLength
1938          this.lengthInt = x.lengthInt
1939          this.buffer = x.buffer
1940          this.byteOffset = x.byteOffset
1941        }
1942    }
1943
1944    /**
1945     * Creates an Int16Array with respect to data, byteOffset and length.
1946     *
1947     * @param buf data initializer
1948     *
1949     * @param byteOffset byte offset from begin of the buf
1950     *
1951     * @param length size of elements of type short in newly created Int16Array
1952     */
1953    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
1954        let intByteOffset: int = 0
1955        if (byteOffset != undefined) {
1956            intByteOffset = byteOffset.toInt()
1957            if (intByteOffset < 0) {
1958                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
1959            }
1960        }
1961        let intByteLength: int = buf.getByteLength() - intByteOffset
1962        if (intByteLength < 0) {
1963            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
1964        }
1965
1966        if (intByteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
1967            throw new RangeError("ArrayBuffer.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
1968        }
1969        if (intByteOffset % Int16Array.BYTES_PER_ELEMENT as int != 0) {
1970            throw new RangeError("byteOffset should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
1971        }
1972
1973        let intLength: int
1974        if (length != undefined) {
1975            intLength = length.toInt()
1976            if (intLength > intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
1977                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
1978            }
1979        } else {
1980            intLength = intByteLength / Int16Array.BYTES_PER_ELEMENT as int
1981        }
1982        if (intLength < 0) {
1983            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
1984        }
1985        if (intLength < intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
1986            intByteLength = intLength * Int16Array.BYTES_PER_ELEMENT as int
1987        }
1988        this.byteLength = intByteLength
1989        this.byteOffset = intByteOffset
1990        this.lengthInt = intLength
1991        this.buffer = buf
1992    }
1993
1994    /**
1995     * Creates an Int16Array with respect to data, byteOffset and length.
1996     *
1997     * @param buf data initializer
1998     *
1999     * @param byteOffset byte offset from begin of the buf
2000     *
2001     * @param length size of elements of type short in newly created Int16Array
2002     */
2003    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
2004        this(buf, byteOffset, undefined)
2005    }
2006
2007    /**
2008     * Creates an Int16Array with respect to data, byteOffset and length.
2009     *
2010     * @param buf data initializer
2011     *
2012     * @param byteOffset byte offset from begin of the buf
2013     *
2014     * @param length size of elements of type short in newly created Int16Array
2015     */
2016    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
2017        this(buf, new Number(byteOffset), new Number(length))
2018    }
2019
2020    /**
2021     * Creates an Int16Array with respect to data, byteOffset and length.
2022     *
2023     * @param buf data initializer
2024     *
2025     * @param byteOffset byte offset from begin of the buf
2026     *
2027     * @param length size of elements of type short in newly created Int16Array
2028     */
2029    public constructor(buf: ArrayBuffer, byteOffset: number) {
2030        this(buf, new Number(byteOffset), undefined)
2031    }
2032
2033    /**
2034     * Creates an Int16Array with respect to data, byteOffset and length.
2035     *
2036     * @param buf data initializer
2037     *
2038     * @param byteOffset byte offset from begin of the buf
2039     *
2040     * @param length size of elements of type short in newly created Int16Array
2041     */
2042    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
2043        this(buf, new Number(byteOffset), new Number(length))
2044    }
2045
2046    /**
2047     * Creates an Int16Array with respect to buf and byteOffset.
2048     *
2049     * @param buf data initializer
2050     *
2051     * @param byteOffset byte offset from begin of the buf
2052     */
2053    public constructor(buf: ArrayBuffer, byteOffset: int) {
2054        this(buf, new Number(byteOffset), undefined)
2055    }
2056
2057    /**
2058     * Creates an Int16Array with respect to buf.
2059     *
2060     * @param buf data initializer
2061     */
2062    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
2063        if (buf instanceof ArrayBuffer) {
2064            this.byteLength = (buf as ArrayBuffer).getByteLength()
2065            if (this.byteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2066               throw new RangeError("ArrayBuffer.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2067            }
2068            this.lengthInt = this.byteLength / Int16Array.BYTES_PER_ELEMENT as int
2069            this.buffer = buf as ArrayBuffer
2070            this.byteOffset = 0
2071        } else if (buf instanceof ArrayLike) {
2072            // NOTE (ikorobkov): dealing with this overload is tricky
2073            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
2074            let arr = Array.from<Number>((buf as ArrayLike<Number>))
2075            this.byteLength = arr.length as int * Int16Array.BYTES_PER_ELEMENT as int
2076            this.lengthInt = arr.length as int
2077            this.buffer = new ArrayBuffer(this.byteLength as int)
2078            this.byteOffset = 0
2079            for (let i: int = 0; i < this.lengthInt; ++i) {
2080                this.setUnsafe(i, arr.$_get(i).toShort())
2081            }
2082        } else {
2083            throw new Error("unexpected type of buf")
2084        }
2085    }
2086
2087    /**
2088     * Creates an Int16Array with respect to length.
2089     *
2090     * @param length data initializer
2091     */
2092    public constructor(length: int) {
2093        this(length as number)
2094    }
2095
2096    /**
2097     * Creates an Int16Array with respect to length.
2098     *
2099     * @param length data initializer
2100     */
2101    public constructor(length: number) {
2102        if (length < 0 || length > (Int.MAX_VALUE / Int16Array.BYTES_PER_ELEMENT)) {
2103            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
2104        }
2105        this.lengthInt = length as int
2106        this.byteLength = this.lengthInt * Int16Array.BYTES_PER_ELEMENT as int
2107        this.byteOffset = 0
2108        this.buffer = new ArrayBuffer(this.byteLength as int)
2109    }
2110
2111    /**
2112     * Creates a copy of Int16Array.
2113     *
2114     * @param other data initializer
2115     */
2116    public constructor(other: Int16Array) {
2117        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
2118        this.byteLength = other.byteLength
2119        this.lengthInt = other.length as int
2120        this.byteOffset = 0
2121    }
2122
2123    /**
2124     * Creates an Int16Array from FixedArray<number>
2125     */
2126    public constructor(numbers: FixedArray<number>) {
2127        this(numbers.length)
2128        for (let i: int = 0; i < this.lengthInt; ++i) {
2129            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2130        }
2131    }
2132
2133    /**
2134     * Creates an Int16Array from FixedArray<int>
2135     */
2136    public constructor(numbers: FixedArray<int>) {
2137        this(numbers.length)
2138        for (let i: int = 0; i < this.lengthInt; ++i) {
2139            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2140        }
2141    }
2142
2143    internal zeroIfInfinity(val: number): number {
2144        if ((val == Infinity) || (val == -Infinity)) {
2145            return 0 as number
2146        }
2147        return val as number
2148    }
2149
2150    internal zeroIfInfinity(val: short): short {
2151        if ((val == Infinity) || (val == -Infinity)) {
2152            return 0 as short
2153        }
2154        return val
2155    }
2156
2157    /**
2158     * Assigns val as element on index.
2159     *
2160     * @param val value to set
2161     *
2162     * @param index index to change
2163     */
2164    public $_set(index: number, val: number): void {
2165        this.$_set(index as int, val)
2166    }
2167
2168    /**
2169     * Assigns val as element on index.
2170     *
2171     * @param val value to set
2172     *
2173     * @param index index to change
2174     */
2175    public $_set(index: int, val: number): void {
2176        let v = this.zeroIfInfinity(val)
2177        this.$_set(index, v as short)
2178    }
2179
2180    /**
2181     * Assigns val as element on index.
2182     *
2183     * @param val value to set
2184     *
2185     * @param index index to change
2186     */
2187    public $_set(index: number, val: int): void {
2188        this.$_set(index as int, val)
2189    }
2190
2191    /**
2192     * Assigns val as element on index.
2193     *
2194     * @param val value to set
2195     *
2196     * @param index index to change
2197     */
2198    public native $_set(index: int, val: int): void
2199
2200    /**
2201     * Assigns val as element on index.
2202     *
2203     * @param val value to set
2204     *
2205     * @param index index to change
2206     */
2207    public $_set(index: number, val: short): void {
2208        this.$_set(index as int, val)
2209    }
2210
2211    /**
2212     * Assigns val as element on index.
2213     *
2214     * @param val value to set
2215     *
2216     * @param index index to change
2217     */
2218    public native $_set(index: int, val: short): void
2219
2220    /** Number of short stored in Int16Array */
2221    public get length(): number {
2222        return this.lengthInt
2223    }
2224
2225    /**
2226     * Returns an instance of number at passed index.
2227     *
2228     * @param index index to look at
2229     *
2230     * @returns a primitive at index
2231     */
2232    public override $_get(index: number): Number {
2233        return this.$_get(index as int) as Number
2234    }
2235
2236    /**
2237     * Returns an instance of number at passed index.
2238     *
2239     * @param index index to look at
2240     *
2241     * @returns a primitive at index
2242     */
2243    public native $_get(index: int): number
2244
2245    /**
2246     * Returns an instance of primitive type at passed index.
2247     *
2248     * @param index index to look at
2249     *
2250     * @returns a primitive at index
2251     */
2252    public at(index: number): Number | undefined {
2253        return this.at(index as int)
2254    }
2255
2256    /**
2257     * Returns an instance of primitive type at passed index.
2258     *
2259     * @param index index to look at
2260     *
2261     * @returns a primitive at index
2262     */
2263    public at(index: int): Number | undefined {
2264        let k: int
2265        if (index >= 0) {
2266            k = index
2267        } else {
2268            k = this.lengthInt + index
2269        }
2270        if (k < 0 || k >= this.lengthInt) {
2271            return undefined
2272        }
2273        return new Number(this.getUnsafe(k))
2274    }
2275
2276    /**
2277     * Makes a copy of internal elements to targetPos from startPos to endPos.
2278     *
2279     * @param target insert index to place copied elements
2280     *
2281     * @param start start index to begin copy from
2282     *
2283     * @param end last index to end copy from, excluded
2284     *
2285     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
2286     */
2287    public copyWithin(target: number, start: number, end?: number): Int16Array {
2288        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
2289    }
2290
2291    /**
2292     * Makes a copy of internal elements to targetPos from startPos to endPos.
2293     *
2294     * @param target insert index to place copied elements
2295     *
2296     * @param start start index to begin copy from
2297     *
2298     * @param end last index to end copy from, excluded
2299     *
2300     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
2301     */
2302    public copyWithin(target: int, start: number, end?: number): Int16Array {
2303        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
2304    }
2305
2306    /**
2307     * Makes a copy of internal elements to targetPos from startPos to endPos.
2308     *
2309     * @param target insert index to place copied elements
2310     *
2311     * @param start start index to begin copy from
2312     *
2313     * @param end last index to end copy from, excluded
2314     *
2315     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
2316     */
2317    public copyWithin(target: number, start: int, end?: number): Int16Array {
2318        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
2319    }
2320
2321    /**
2322     * Makes a copy of internal elements to targetPos from startPos to endPos.
2323     *
2324     * @param target insert index to place copied elements
2325     *
2326     * @param start start index to begin copy from
2327     *
2328     * @param end last index to end copy from, excluded
2329     *
2330     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
2331     */
2332    public copyWithin(target: int, start: int, end?: number): Int16Array {
2333        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
2334    }
2335
2336    /**
2337     * Makes a copy of internal elements to targetPos from startPos to endPos.
2338     *
2339     * @param target insert index to place copied elements
2340     *
2341     * @param start start index to begin copy from
2342     *
2343     * @param end last index to end copy from, excluded
2344     *
2345     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
2346     */
2347    public native copyWithin(target: int, start: int, end: int): Int16Array
2348
2349    /**
2350     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
2351     *
2352     * @param target insert index to place copied elements
2353     *
2354     * See rules of parameters normalization:
2355     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
2356     */
2357    public copyWithin(target: number): Int16Array {
2358        return this.copyWithin(target as int)
2359    }
2360
2361    /**
2362     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
2363     *
2364     * @param target insert index to place copied elements
2365     *
2366     * See rules of parameters normalization:
2367     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
2368     */
2369    public copyWithin(target: int): Int16Array {
2370        return this.copyWithin(target, 0, this.lengthInt)
2371    }
2372
2373    /**
2374     * Returns an array of key, value pairs for every entry in the Int16Array
2375     *
2376     * @returns key, value pairs for every entry in the array
2377     */
2378    public entries(): IterableIterator<[Number, Number]> {
2379        return new Int16ArrayIteratorEntries(this)
2380    }
2381
2382    /**
2383     * Fills the Int16Array with specified value
2384     *
2385     * @param value new valuy
2386     *
2387     * @returns modified Int16Array
2388     */
2389    public fill(value: number, start?: number, end?: number): this {
2390        value = this.zeroIfInfinity(value)
2391        this.fill(value as short, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
2392        return this
2393    }
2394
2395    /**
2396     * Fills the Int16Array with specified value
2397     *
2398     * @param value new valuy
2399     *
2400     * @returns modified Int16Array
2401     */
2402    public fill(value: number, start: int, end?: number): this {
2403        value = this.zeroIfInfinity(value)
2404        this.fill(value as short, start as int, asIntOrDefault(end, this.lengthInt))
2405        return this
2406    }
2407
2408    /**
2409     * Fills the Int16Array with specified value
2410     *
2411     * @param value new valuy
2412     *
2413     * @returns modified Int16Array
2414     */
2415    public fill(value: number, start: int, end: number): this {
2416        value = this.zeroIfInfinity(value)
2417        this.fill(value as short, start as int, end as int)
2418        return this
2419    }
2420
2421    /**
2422     * Fills the Int16Array with specified value
2423     *
2424     * @param value new valuy
2425     *
2426     * @returns modified Int16Array
2427     */
2428    public fill(value: number, start: number, end: int): this {
2429        value = this.zeroIfInfinity(value)
2430        this.fill(value as short, start as int, end as int)
2431        return this
2432    }
2433
2434    /**
2435     * Fills the Int16Array with specified value
2436     *
2437     * @param value new valuy
2438     *
2439     * @returns modified Int16Array
2440     */
2441    public fill(value: number, start: int, end: int): this {
2442        value = this.zeroIfInfinity(value)
2443        this.fill(value as short, start as int, end as int)
2444        return this
2445    }
2446
2447    /**
2448     * Fills the Int16Array with specified value
2449     *
2450     * @param value new valuy
2451     *
2452     * @returns modified Int16Array
2453     */
2454    public fill(value: short, start?: number, end?: number): this {
2455        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
2456        return this
2457    }
2458
2459    /**
2460     * Fills the Int16Array with specified value
2461     *
2462     * @param value new valuy
2463     *
2464     * @returns modified Int16Array
2465     */
2466    public fill(value: short, start: int, end?: number): this {
2467        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
2468        return this
2469    }
2470
2471    /**
2472     * Fills the Int16Array with specified value
2473     *
2474     * @param value new valuy
2475     *
2476     * @returns modified Int16Array
2477     */
2478    public fill(value: short, start: int, end: number): this {
2479        this.fill(value, start as int, end as int)
2480        return this
2481    }
2482
2483    /**
2484     * Fills the Int16Array with specified value
2485     *
2486     * @param value new valuy
2487     *
2488     * @returns modified Int16Array
2489     */
2490    public fill(value: short, start: number, end: int): this {
2491        this.fill(value, start as int, end as int)
2492        return this
2493    }
2494
2495    /**
2496     * Fills the Int16Array with specified value
2497     *
2498     * @param value new valuy
2499     *
2500     * @returns modified Int16Array
2501     */
2502    public fill(value: short, start: int, end: int): this {
2503        const k = normalizeIndex(start, this.lengthInt)
2504        const finalPos = normalizeIndex(end, this.lengthInt)
2505        this.fillInternal(value, k, finalPos)
2506        return this
2507    }
2508
2509    private final native fillInternal(value: short, start: int, end: int): void
2510
2511    /**
2512     * Assigns val as element on insertPos.
2513     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<short>, insertPos)
2514     *
2515     * @param val value to set
2516     *
2517     * @param insertPos index to change
2518     */
2519    public set(insertPos: number, val: number): void {
2520        this.$_set(insertPos, val)
2521    }
2522
2523    /**
2524     * Assigns val as element on insertPos.
2525     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<short>, insertPos)
2526     *
2527     * @param val value to set
2528     *
2529     * @param insertPos index to change
2530     */
2531    public set(insertPos: int, val: short): void {
2532        this.$_set(insertPos, val)
2533    }
2534
2535    /**
2536     * Copies all elements of arr to the current Int16Array starting from insertPos.
2537     *
2538     * @param arr array to copy data from
2539     *
2540     * @param insertPos start index where data from arr will be inserted
2541     *
2542     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
2543     */
2544    public set(arr: FixedArray<number>, insertPos: number): void {
2545        const offset = insertPos as int
2546        if (offset < 0 || offset + arr.length > this.lengthInt) {
2547            throw new RangeError("offset is out of bounds")
2548        }
2549        for (let i = 0; i < arr.length as int; ++i) {
2550            let v = this.zeroIfInfinity(arr[i])
2551            this.$_set(offset + i, v as short)
2552        }
2553    }
2554
2555    /**
2556     * Copies all elements of arr to the current Int16Array starting from insertPos.
2557     *
2558     * @param arr array to copy data from
2559     *
2560     * @param insertPos start index where data from arr will be inserted
2561     *
2562     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
2563     */
2564    public set(arr: FixedArray<short>, insertPos: int): void {
2565        const offset = insertPos as int
2566        if (offset < 0 || offset + arr.length > this.lengthInt) {
2567            throw new RangeError("offset is out of bounds")
2568        }
2569        for (let i = 0; i < arr.length as int; ++i) {
2570            let v = this.zeroIfInfinity(arr[i])
2571            this.$_set(offset + i, v)
2572        }
2573    }
2574
2575    /**
2576     * Copies all elements of arr to the current Int16Array.
2577     *
2578     * @param arr array to copy data from
2579     */
2580    public set(arr: FixedArray<number>): void {
2581        this.set(arr, 0 as number)
2582    }
2583
2584    /**
2585     * Copies all elements of arr to the current Int16Array.
2586     *
2587     * @param arr array to copy data from
2588     */
2589    public set(arr: FixedArray<short>): void {
2590        this.set(arr, 0 as int)
2591    }
2592
2593    public native set(array: Int16Array): void
2594
2595    public native set(array: Int16Array, offset: number): void
2596
2597    /**
2598     * Copies elements from an ArrayLike object to the Int16Array.
2599     *
2600     * @param array An ArrayLike object containing the elements to copy.
2601     *
2602     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
2603     */
2604    public set(array: ArrayLike<number>, offset: number = 0): void {
2605        const insertPos = offset as int
2606        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
2607            throw new RangeError("offset is out of bounds")
2608        }
2609        for (let i = array.length - 1 as int; i >= 0; --i) {
2610            let v = this.zeroIfInfinity(array[i])
2611            this.$_set(insertPos + i, v as short)
2612        }
2613    }
2614
2615    /**
2616     * Returns a new array from a set of elements.
2617     *
2618     * @param items a set of elements to include in the new array object.
2619     *
2620     * @returns new Int16Array
2621     */
2622    public static of(...items: FixedArray<number>): Int16Array {
2623        let res = new Int16Array(items.length as int)
2624        for (let i: int = 0; i < items.length; i++) {
2625            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as short)
2626        }
2627        return res
2628    }
2629
2630    /**
2631     * Returns a new array from a set of elements.
2632     *
2633     * @param items a set of elements to include in the new array object.
2634     *
2635     * @returns new Int16Array
2636     */
2637    public static of(...items: FixedArray<int>): Int16Array {
2638        let res = new Int16Array(items.length as int)
2639        for (let i: int = 0; i < items.length; i++) {
2640            res.setUnsafe(i, items[i] as short)
2641        }
2642        return res
2643    }
2644
2645    /**
2646     * Returns a new array from a set of elements.
2647     *
2648     * @param items a set of elements to include in the new array object.
2649     *
2650     * @returns new Int16Array
2651     */
2652    public static of(...items: FixedArray<short>): Int16Array {
2653        let res = new Int16Array(items.length as int)
2654        for (let i: int = 0; i < items.length; i++) {
2655            res.setUnsafe(i, items[i])
2656        }
2657        return res
2658    }
2659
2660    /**
2661     * Returns a new array from a set of elements.
2662     *
2663     * @param items a set of elements to include in the new array object.
2664     *
2665     * @returns new Int16Array
2666     */
2667    public static of(): Int16Array {
2668        return new Int16Array(0 as int)
2669    }
2670
2671    /**
2672     * Creates an array from an array-like or iterable object.
2673     *
2674     * @param arrayLike An array-like or iterable object to convert to an array.
2675     *
2676     * @returns new Int16Array
2677     */
2678    public static from(arrayLike: ArrayLike<number>): Int16Array {
2679        return Int16Array.from<number>(arrayLike, (x: number, k: number): number => x)
2680    }
2681
2682    /**
2683     * Creates an array from an array-like or iterable object.
2684     *
2685     * @param arrayLike An array-like or iterable object to convert to an array.
2686     *
2687     * @param mapfn A mapping function to call on every element of the array.
2688     *
2689     * @returns new Int16Array
2690     */
2691    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int16Array {
2692        if (mapfn == undefined) {
2693            mapfn = (v: number, k: number): number => { return v }
2694        }
2695
2696        let iter = arrayLike.$_iterator()
2697        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
2698        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
2699        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
2700        //  we can make one pass through the iterator without the need for memory reallocation.
2701        const maybeLength = tryGetIteratorLength(arrayLike)
2702        if (maybeLength) {
2703            const result = new Int16Array(maybeLength)
2704            for (let i = 0; i < maybeLength; ++i) {
2705                const x = iter.next()
2706                if (x.done) {
2707                    return new Int16Array(result.buffer, 0, i)
2708                }
2709                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as short)
2710            }
2711            return result
2712        }
2713
2714        // NOTE (templin.konstantin): Create builtin array as buffer
2715        let temp = new Int16Array(6)
2716        let index : FixedArray<int> = new int[1]
2717        index[0] = 0
2718
2719        iteratorForEach<number>(iter, (x: number): void => {
2720            if (index[0] + 1 > temp.lengthInt) {
2721                // NOTE (templin.konstantin): Progressive reallocation
2722                const curLength = (temp.buffer as Buffer).getByteLength()
2723                const tb = new ArrayBuffer(curLength * 2)
2724                for (let i = 0; i < curLength; ++i) {
2725                    tb.set(i, (temp.buffer as Buffer).at(i))
2726                }
2727                temp = new Int16Array(tb)
2728            }
2729            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as short)
2730            index[0]++
2731        })
2732        return new Int16Array(temp.buffer, 0, index[0])
2733    }
2734
2735
2736    /**
2737     * Creates an array from an array-like or iterable object.
2738     *
2739     * @param arrayLike An array-like or iterable object to convert to an array.
2740     *
2741     * @param mapfn A mapping function to call on every element of the array.
2742     *
2743     * @returns new Int16Array
2744     */
2745    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int16Array {
2746        let res = new Int16Array(arrayLike.length)
2747        // 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
2748        const idx : FixedArray<int> = new int[1]
2749        idx[0] = 0
2750        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
2751            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as short)
2752            idx[0] += 1
2753        })
2754        return res
2755    }
2756
2757    /**
2758     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
2759     *
2760     * @param searchElement The element to search for
2761     *
2762     * @param fromIndex The position in this array at which to begin searching for searchElement
2763     *
2764     * @returns true if searchElement is in Int16Array, false otherwise
2765     */
2766    public includes(searchElement: number, fromIndex?: number): boolean {
2767        if (isNaN(searchElement)) {
2768            return false
2769        }
2770        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
2771    }
2772
2773    /**
2774     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
2775     *
2776     * @param searchElement The element to search for
2777     *
2778     * @param fromIndex The position in this array at which to begin searching for searchElement
2779     *
2780     * @returns true if e is in Int16Array, false otherwise
2781     */
2782    public includes(searchElement: short, fromIndex: int): boolean {
2783        return this.indexOf(searchElement as int, fromIndex) != -1
2784    }
2785
2786    /**
2787     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
2788     *
2789     * @param searchElement The element to search for
2790     *
2791     * @param fromIndex The position in this array at which to begin searching for searchElement
2792     *
2793     * @returns true if searchElement is in Int16Array, false otherwise
2794     */
2795    public includes(searchElement: short): boolean {
2796        return this.includes(searchElement, 0)
2797    }
2798
2799    /**
2800     * Returns the index of the first occurrence of a value in Int16Array.
2801     *
2802     * @param searchElement The value to locate in the array.
2803     *
2804     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2805     *  search starts at index 0.
2806     *
2807     * @returns index of element if it presents, -1 otherwise
2808     */
2809    public indexOf(searchElement: number, fromIndex?: number): number {
2810        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
2811    }
2812
2813    /**
2814     * Returns the index of the first occurrence of a value in Int16Array.
2815     *
2816     * @param searchElement The value to locate in the array.
2817     *
2818     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2819     *  search starts at index 0.
2820     *
2821     * @returns index of element if it presents, -1 otherwise
2822     */
2823    public indexOf(searchElement: number, fromIndex: int): number {
2824            return this.indexOfImpl(searchElement, fromIndex)
2825    }
2826
2827    /**
2828     * Returns the index of the first occurrence of a value in Int16Array.
2829     *
2830     * @param searchElement The value to locate in the array.
2831     *
2832     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2833     *  search starts at index 0.
2834     *
2835     * @returns index of element if it presents, -1 otherwise
2836     */
2837    public indexOf(searchElement: int, fromIndex: int): number {
2838        return this.indexOfImpl(searchElement as long, fromIndex)
2839    }
2840
2841    /**
2842     * Returns the index of the first occurrence of a value in Int16Array.
2843     *
2844     * @param searchElement The value to locate in the array.
2845     *
2846     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2847     *  search starts at index 0.
2848     *
2849     * @returns index of element if it presents, -1 otherwise
2850     */
2851    private final native indexOfImpl(searchElement: number, fromIndex: int): number
2852
2853    /**
2854     * Returns the index of the first occurrence of a value in Int16Array.
2855     *
2856     * @param searchElement The value to locate in the array.
2857     *
2858     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2859     *  search starts at index 0.
2860     *
2861     * @returns index of element if it presents, -1 otherwise
2862     */
2863    private final native indexOfImpl(searchElement: long, fromIndex: int): number
2864
2865    /**
2866     * Returns the index of the first occurrence of a value in Int16Array.
2867     *
2868     * @param searchElement The value to locate in the array.
2869     *
2870     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
2871     *  search starts at index 0.
2872     *
2873     * @returns index of element if it presents, -1 otherwise
2874     */
2875    public indexOf(searchElement: int): number {
2876        return this.indexOf(searchElement, 0)
2877    }
2878
2879    /**
2880     * Converts all elements of an array to strings and joins them using the specified separator.
2881     *
2882     * @param separator - separates one element of an array from the next in the resulting String.
2883     *
2884     * @returns joined representation
2885     */
2886    private final native joinInternal(separator: String): string;
2887
2888    /**
2889     * Adds all the elements of an array separated by the specified separator string
2890     *
2891     * @param separator A string used to separate one element of an array from the next in the
2892     * resulting String. If omitted, the array elements are separated with a comma.
2893     *
2894     * @returns joined representation
2895     */
2896    public join(separator?: String): string {
2897        if (separator == undefined) {
2898            return this.joinInternal(",")
2899        }
2900        return this.joinInternal(separator)
2901    }
2902
2903    /**
2904     * Returns an list of keys in Int16Array
2905     *
2906     * @returns iterator over keys
2907     */
2908    public keys(): IterableIterator<number> {
2909        return new Int16ArrayIteratorKeys(this)
2910    }
2911
2912    /**
2913     * Returns the index of the last occurrence of a value in Int16Array.
2914     *
2915     * @param searchElement The value to locate in the array.
2916     *
2917     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2918     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2919     *
2920     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2921     */
2922    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
2923        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
2924    }
2925
2926    /**
2927     * Returns the index of the last occurrence of a value in Int16Array.
2928     *
2929     * @param searchElement The value to locate in the array.
2930     *
2931     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2932     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2933     *
2934     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2935     */
2936    public lastIndexOf(searchElement: number): number {
2937        return this.lastIndexOf(searchElement, this.lengthInt - 1)
2938    }
2939
2940    /**
2941     * Returns the index of the last occurrence of a value in Int16Array.
2942     *
2943     * @param searchElement The value to locate in the array.
2944     *
2945     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2946     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2947     *
2948     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2949     */
2950    public lastIndexOf(searchElement: number, fromIndex: int): number {
2951            return this.lastIndexOfImpl(searchElement, fromIndex)
2952    }
2953
2954    /**
2955     * Returns the index of the last occurrence of a value in Int16Array.
2956     *
2957     * @param searchElement The value to locate in the array.
2958     *
2959     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2960     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2961     *
2962     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2963     */
2964    public lastIndexOf(searchElement: int, fromIndex: int): number {
2965        return this.lastIndexOfImpl(searchElement as long, fromIndex)
2966    }
2967
2968    /**
2969     * Returns the index of the last occurrence of a value in Int16Array.
2970     *
2971     * @param searchElement The value to locate in the array.
2972     *
2973     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2974     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2975     *
2976     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2977     */
2978    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
2979
2980    /**
2981     * Returns the index of the last occurrence of a value in Int16Array.
2982     *
2983     * @param searchElement The value to locate in the array.
2984     *
2985     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2986     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2987     *
2988     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
2989     */
2990    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
2991
2992    /**
2993     * Returns the index of the last occurrence of a value in Int16Array.
2994     *
2995     * @param searchElement The value to locate in the array.
2996     *
2997     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
2998     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
2999     *
3000     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3001     */
3002    public lastIndexOf(searchElement: int): number {
3003        return this.lastIndexOf(searchElement, this.lengthInt - 1)
3004    }
3005
3006    /**
3007    * Creates a new Int16Array using initializer
3008    *
3009    * @param data initializer
3010    *
3011    * @returns a new Int16Array from data
3012    */
3013    public of(data: FixedArray<Object>): Int16Array {
3014        throw new Error("Int16Array.of: not implemented")
3015    }
3016
3017    /**
3018     * Creates a new Int16Array using reversed data from the current one
3019     *
3020     * @returns a new Int16Array using reversed data from the current one
3021     */
3022    public native reverse(): Int16Array
3023
3024    /**
3025     * Creates a slice of current Int16Array using range [begin, end)
3026     *
3027     * @param begin start index to be taken into slice
3028     *
3029     * @param end last index to be taken into slice
3030     *
3031     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3032     *
3033     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3034     */
3035    public slice(begin?: number, end?: number): Int16Array {
3036        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
3037    }
3038
3039    /**
3040     * Creates a slice of current Int16Array using range [begin, end)
3041     *
3042     * @param begin start index to be taken into slice
3043     *
3044     * @param end last index to be taken into slice
3045     *
3046     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3047     *
3048     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3049     */
3050    public slice(begin: number, end: number): Int16Array {
3051        return this.slice(begin as int, end as int)
3052    }
3053
3054    /**
3055     * Creates a slice of current Int16Array using range [begin, end)
3056     *
3057     * @param begin start index to be taken into slice
3058     *
3059     * @param end last index to be taken into slice
3060     *
3061     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3062     *
3063     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3064     */
3065    public slice(begin: number, end: int): Int16Array {
3066        return this.slice(begin as int, end as int)
3067    }
3068
3069    /**
3070     * Creates a slice of current Int16Array using range [begin, end)
3071     *
3072     * @param begin start index to be taken into slice
3073     *
3074     * @param end last index to be taken into slice
3075     *
3076     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3077     *
3078     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3079     */
3080    public slice(begin: int, end: number): Int16Array {
3081        return this.slice(begin as int, end as int)
3082    }
3083
3084    /**
3085     * Creates a slice of current Int16Array using range [begin, end)
3086     *
3087     * @param begin start index to be taken into slice
3088     *
3089     * @param end last index to be taken into slice
3090     *
3091     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3092     *
3093     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3094     */
3095    public slice(begin: int, end: int): Int16Array {
3096        const len: int = this.lengthInt
3097        const relStart = normalizeIndex(begin, len)
3098        const relEnd = normalizeIndex(end, len)
3099        let count = relEnd - relStart
3100        if (count < 0) {
3101            count = 0
3102        }
3103        let buf = this.buffer.slice(relStart * Int16Array.BYTES_PER_ELEMENT as int, relEnd * Int16Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
3104        return new Int16Array(buf)
3105    }
3106
3107    /**
3108     * Creates a slice of current Int16Array using range [begin, this.length).
3109     *
3110     * @param begin start index to be taken into slice
3111     *
3112     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3113     */
3114    public slice(begin: number): Int16Array {
3115        return this.slice(begin as int)
3116    }
3117
3118    /**
3119     * Creates a slice of current Int16Array using range [begin, this.length).
3120     *
3121     * @param begin start index to be taken into slice
3122     *
3123     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3124     */
3125    public slice(begin: int): Int16Array {
3126        return this.slice(begin, this.lengthInt)
3127    }
3128
3129    /**
3130     * Creates a Int16Array with the same underlying ArrayBuffer
3131     *
3132     * @param begin start index, inclusive
3133     *
3134     * @param end last index, exclusive
3135     *
3136     * @returns new Int16Array with the same underlying ArrayBuffer
3137     */
3138    public subarray(begin?: number, end?: number): Int16Array {
3139        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
3140    }
3141
3142    /**
3143     * Creates a Int16Array with the same underlying ArrayBuffer
3144     *
3145     * @param begin start index, inclusive
3146     *
3147     * @param end last index, exclusive
3148     *
3149     * @returns new Int16Array with the same underlying ArrayBuffer
3150     */
3151    public subarray(begin: number, end: number): Int16Array {
3152        return this.subarray(begin as int, end as int)
3153    }
3154
3155    /**
3156     * Creates a Int16Array with the same underlying ArrayBuffer
3157     *
3158     * @param begin start index, inclusive
3159     *
3160     * @param end last index, exclusive
3161     *
3162     * @returns new Int16Array with the same underlying ArrayBuffer
3163     */
3164    public subarray(begin: number, end: int): Int16Array {
3165        return this.subarray(begin as int, end as int)
3166    }
3167
3168    /**
3169     * Creates a Int16Array with the same underlying ArrayBuffer
3170     *
3171     * @param begin start index, inclusive
3172     *
3173     * @param end last index, exclusive
3174     *
3175     * @returns new Int16Array with the same underlying ArrayBuffer
3176     */
3177    public subarray(begin: int, end: number): Int16Array {
3178        return this.subarray(begin as int, end as int)
3179    }
3180
3181    /**
3182     * Creates a Int16Array with the same underlying ArrayBuffer
3183     *
3184     * @param begin start index, inclusive
3185     *
3186     * @param end last index, exclusive
3187     *
3188     * @returns new Int16Array with the same underlying ArrayBuffer
3189     */
3190    public subarray(begin: int, end: int | undefined = this.lengthInt): Int16Array {
3191        const len: int = this.lengthInt
3192        const relStart = normalizeIndex(begin, len)
3193        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
3194        let count = relEnd - relStart
3195        if (count < 0) {
3196            count = 0
3197        }
3198        return new Int16Array(this.buffer, relStart * Int16Array.BYTES_PER_ELEMENT as int, count)
3199    }
3200
3201    /**
3202     * Converts Int16Array to a string with respect to locale
3203     *
3204     * @param locales
3205     *
3206     * @param options
3207     *
3208     * @returns string representation
3209     */
3210    public toLocaleString(locales: Object, options: Object): string {
3211        throw new Error("Int16Array.toLocaleString: not implemented")
3212    }
3213
3214    /**
3215     * Converts Int16Array to a string with respect to locale
3216     *
3217     * @param locales
3218     *
3219     * @returns string representation
3220     */
3221    public toLocaleString(locales: Object): string {
3222        return this.toLocaleString(new Object(), new Object())
3223    }
3224
3225    /**
3226     * Converts Int16Array to a string with respect to locale
3227     *
3228     * @returns string representation
3229     */
3230    public toLocaleString(): string {
3231        let res: StringBuilder = new StringBuilder("")
3232        for (let i = 0; i < this.lengthInt - 1; ++i) {
3233            res.append((this.getUnsafe(i) as Number).toLocaleString())
3234            res.append(",")
3235        }
3236        if (this.lengthInt > 0) {
3237            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
3238        }
3239        return res.toString()
3240    }
3241
3242    /**
3243     * Creates a reversed copy
3244     *
3245     * @returns a reversed copy
3246     */
3247    public final native toReversed(): Int16Array
3248
3249    /**
3250     * Creates a sorted copy
3251     *
3252     * @returns a sorted copy
3253     */
3254    public toSorted(): Int16Array {
3255        return new Int16Array(this).sort()
3256    }
3257
3258    /**
3259     * Returns a string representation of the Int16Array
3260     *
3261     * @returns a string representation of the Int16Array
3262     */
3263    public override toString(): string {
3264        return this.join(",")
3265    }
3266
3267    /**
3268     * Returns array values iterator
3269     *
3270     * @returns an iterator
3271     */
3272    public values(): IterableIterator<Number> {
3273        return new Int16ArrayIterator(this)
3274    }
3275
3276    /**
3277     * Iteratorable interface implementation
3278     *
3279     * @returns iterator over all elements
3280     */
3281    public override $_iterator(): IterableIterator<Number> {
3282        return this.values()
3283    }
3284
3285    /**
3286     * Creates a copy with replaced value on index
3287     *
3288     * @param index
3289     *
3290     * @param value
3291     *
3292     * @returns an Int16Array with replaced value on index
3293     */
3294    public with(index: number, value: number): Int16Array {
3295        return this.with(index as int, value as short)
3296    }
3297
3298    /**
3299     * Creates a copy with replaced value on index
3300     *
3301     * @param index
3302     *
3303     * @param value
3304     *
3305     * @returns an Int16Array with replaced value on index
3306     */
3307    public with(index: int, value: short): Int16Array {
3308        let res = new Int16Array(this)
3309        res.set(index, value)
3310        return res
3311    }
3312
3313    /// === with element lambda functions ===
3314
3315    /**
3316     * Finds the last element in the Int16Array that satisfies the condition
3317     *
3318     * @param fn condition
3319     *
3320     * @returns the last element that satisfies fn
3321     */
3322    public findLast(fn: (val: number) => boolean): number {
3323        let newF: (val: number, index: number, array: Int16Array) => boolean =
3324            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
3325        return this.findLast(newF) as number
3326    }
3327
3328    /**
3329     * Sorts in-place by numeric value in ascending order.
3330     *
3331     * @returns sorted Int16Array
3332     */
3333    public native sort(): this;
3334
3335    /**
3336     * Sorts in-place
3337     *
3338     * @param compareFn comparator _  used to determine the order of the elements.
3339     * compareFn returns a negative value if first argument is less than second argument,
3340     * zero if they're equal and a positive value otherwise.
3341     *
3342     * @returns sorted Int16Array
3343     */
3344    public sort(compareFn?: (a: number, b: number) => number): this {
3345        if (compareFn == undefined) {
3346            this.sort()
3347            return this
3348        }
3349        let arr: FixedArray<short> = new short[this.lengthInt]
3350        for (let i = 0; i < this.lengthInt; ++i) {
3351            arr[i] = this.getUnsafe(i)
3352        }
3353
3354        let cmp = (l: short, r: short): number => {
3355            const result = compareFn!(l as number, r as number)
3356            return result
3357        }
3358        const MAX_SHORT_LENGTH = 24
3359        if (arr.length > MAX_SHORT_LENGTH) {
3360            arr = mergeSort(arr, cmp)
3361        } else {
3362            sort(arr, cmp)
3363        }
3364        for (let i = 0; i < arr.length; ++i) {
3365            this.setUnsafe(i, arr[i])
3366        }
3367        return this
3368    }
3369
3370    /**
3371     * Determines whether the specified callback function returns true for any element of an array.
3372     *
3373     * @param predicate A function that accepts three arguments.
3374     * The some method calls the predicate function for each element in the array
3375     * until the predicate returns a true or until the end of the array.
3376     *
3377     * @returns false unless predicate function returns true for an array element,
3378     * in which case true is immediately returned.
3379     */
3380    public some(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
3381        for (let i = 0; i < this.lengthInt; ++i) {
3382            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
3383                return true
3384            }
3385        }
3386        return false
3387    }
3388
3389    /**
3390     * Calls the specified callback function for all the elements in an array.
3391     * The return value of the callback function is the accumulated result,
3392     * and is provided as an argument in the next call to the callback function.
3393     *
3394     * @param callbackfn A function that accepts four arguments.
3395     * The reduce method calls the callbackfn function one time for each element in the array.
3396     *
3397     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
3398     * The first call to the callbackfn function provides this value as an argument.
3399     *
3400     * @returns The value that results from running the callback function to completion over the entire typed array.
3401     */
3402    public reduce<U = number>(
3403                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
3404                initialValue: U): U {
3405        let accumulatedValue = initialValue
3406        for (let i = 0; i < this.lengthInt; ++i) {
3407            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
3408        }
3409        return accumulatedValue
3410    }
3411
3412    /**
3413     * Calls the specified callback function for all the elements in an array.
3414     * The return value of the callback function is the accumulated result,
3415     * and is provided as an argument in the next call to the callback function.
3416     *
3417     * @param callbackfn A function that accepts four arguments.
3418     * The reduce method calls the callbackfn function one time for each element in the array.
3419     * The first call to the callbackfn function provides array first element value as an argument
3420     *
3421     * @returns The value that results from running the callback function to completion over the entire typed array.
3422     * calling reduce method on an empty array without an initial value creates a TypeError
3423     */
3424    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
3425        if (this.lengthInt == 0) {
3426            throw new TypeError("Reduce of empty array with no initial value")
3427        }
3428
3429        let accumulatedValue = this.getUnsafe(0) as number
3430        for (let i = 1; i < this.lengthInt; ++i) {
3431            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
3432        }
3433        return accumulatedValue
3434    }
3435
3436    /**
3437     * Calls the specified callback function for all the elements in an array, in descending order.
3438     * The return value of the callback function is the accumulated result,
3439     * and is provided as an argument in the next call to the callback function.
3440     *
3441     * @param callbackfn A function that accepts four arguments.
3442     * The reduceRight method calls the callbackfn function one time for each element in the array.
3443     *
3444     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
3445     * The first call to the callbackfn function provides this value as an argument.
3446     *
3447     * @returns The value that results from running the callback function to completion over the entire typed array.
3448     */
3449    public reduceRight<U = number>(
3450                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
3451                initialValue: U): U {
3452        let accumulatedValue = initialValue
3453        for (let i = this.lengthInt - 1; i >= 0; --i) {
3454            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
3455        }
3456        return accumulatedValue
3457    }
3458
3459
3460    /**
3461     * Calls the specified callback function for all the elements in an array, in descending order.
3462     * The return value of the callback function is the accumulated result,
3463     * and is provided as an argument in the next call to the callback function.
3464     *
3465     * @param callbackfn A function that accepts four arguments.
3466     * The reduceRight method calls the callbackfn function one time for each element in the array.
3467     * The first call to the callbackfn function provides array last element value as an argument
3468     *
3469     * @returns The value that results from running the callback function to completion over the entire typed array.
3470     * calling reduceRight method on an empty array without an initial value creates a TypeError
3471     */
3472    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
3473        if (this.lengthInt == 0) {
3474            throw new TypeError("Reduce of empty array with no initial value")
3475        }
3476
3477        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
3478        for (let i = this.lengthInt - 2; i >= 0; --i) {
3479            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
3480        }
3481        return accumulatedValue
3482    }
3483
3484   /**
3485    * Creates a new Int16Array using fn(arr[i]) over all elements of current Int16Array.
3486    *
3487    * @param fn a function to apply for each element of current Int16Array
3488    *
3489    * @returns a new Int16Array where for each element from current Int16Array fn was applied
3490    */
3491    public map(fn: (val: number, index: number, array: Int16Array) => number): Int16Array {
3492        let resBuf = new ArrayBuffer(this.lengthInt * Int16Array.BYTES_PER_ELEMENT as int)
3493        let res = new Int16Array(resBuf, 0, resBuf.getByteLength() / Int16Array.BYTES_PER_ELEMENT as int)
3494        for (let i = 0; i < this.lengthInt; ++i) {
3495            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as short)
3496        }
3497        return res
3498    }
3499
3500    /**
3501     * Determines whether the specified callback function returns true for all elements of an array.
3502     *
3503     * @param predicate A function that accepts three arguments.
3504     * The every method calls the predicate function for each element in the array until the predicate returns a false,
3505     * or until the end of the array.
3506     *
3507     * @returns true unless predicate function returns a false for an array element,
3508     * in which case false is immediately returned.
3509     */
3510    public every(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
3511        for (let i = 0; i < this.lengthInt; ++i) {
3512            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
3513                return false
3514            }
3515        }
3516        return true
3517    }
3518
3519    /**
3520     * Creates a new Int16Array from current Int16Array based on a condition fn.
3521     *
3522     * @param fn the condition to apply for each element
3523     *
3524     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
3525     */
3526    public filter(fn: (val: number, index: number, array: Int16Array) => boolean): Int16Array {
3527        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
3528        let resLen = 0
3529        for (let i = 0; i < this.lengthInt; ++i) {
3530            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
3531            if (markers[i]) {
3532                ++resLen
3533            }
3534        }
3535        let resBuf = new ArrayBuffer(resLen * Int16Array.BYTES_PER_ELEMENT as int)
3536        let res = new Int16Array(resBuf, 0)
3537        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
3538            if (markers[i]) {
3539                res.set(j, this.getUnsafe(i))
3540                ++j
3541            }
3542        }
3543        return res
3544    }
3545
3546    /**
3547     * Returns the value of the first element in the array where predicate is true, and undefined
3548     * otherwise
3549     *
3550     * @param predicate find calls predicate once for each element of the array, in ascending
3551     * order, until it finds one where predicate returns true. If such an element is found, find
3552     * immediately returns that element value. Otherwise, find returns undefined
3553     *
3554     * @returns number | undefined
3555     */
3556    public find(predicate: (value: number, index: number, obj: Int16Array) => boolean): number | undefined {
3557        for (let i = 0; i < this.lengthInt; ++i) {
3558            let val = this.getUnsafe(i)
3559            if (predicate(val as number, i as number, this)) {
3560                return val as number
3561            }
3562        }
3563        return undefined
3564    }
3565
3566    /**
3567     * Returns the index of the first element in the array where predicate is true, and -1
3568     * otherwise
3569     *
3570     * @param predicate find calls predicate once for each element of the array, in ascending
3571     * order, until it finds one where predicate returns true. If such an element is found,
3572     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
3573     *
3574     * @returns number
3575     */
3576    public findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean): number {
3577        for (let i = 0; i < this.lengthInt; ++i) {
3578            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
3579                return i as number
3580            }
3581        }
3582        return -1 as number
3583    }
3584
3585    /**
3586     * Finds the last element in the Int16Array that satisfies the condition
3587     *
3588     * @param fn condition
3589     *
3590     * @returns the last element that satisfies fn
3591     */
3592    public findLast(fn: (val: number, index: number, array: Int16Array) => boolean): short {
3593        for (let i = this.lengthInt - 1; i >= 0; --i) {
3594            let val = this.getUnsafe(i)
3595            if (fn(val as number, i as number, this)) {
3596                return val
3597            }
3598        }
3599        throw new Error("Int16Array.findLast: not implemented if an element was not found")
3600    }
3601
3602    /**
3603     * Finds an index of the last element in the Int16Array that satisfies the condition
3604     *
3605     * @param fn condition
3606     *
3607     * @returns the index of the last element that satisfies fn, -1 otherwise
3608     */
3609    public findLastIndex(fn: (val: number, index: number, array: Int16Array) => boolean): number {
3610        for (let i = this.lengthInt - 1; i >= 0; --i) {
3611            let val = this.getUnsafe(i)
3612            if (fn(val as number, i as number, this)) {
3613                return i
3614            }
3615        }
3616        return -1 as number
3617    }
3618
3619    /**
3620     * Performs the specified action for each element in Int16Array
3621     *
3622     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
3623     * callbackfn function one time for each element in the array.
3624     *
3625     * @returns None
3626     */
3627    public forEach(callbackfn: (value: number, index: number, array: Int16Array) => void): void {
3628        for (let i = 0; i < this.lengthInt; ++i) {
3629            callbackfn(this.getUnsafe(i) as number, i as number, this)
3630        }
3631    }
3632
3633    /**
3634     * Returns the object itself
3635     *
3636     * @returns Int16Array
3637     */
3638    public valueOf(): Int16Array {
3639        return this
3640    }
3641
3642    private final native getUnsafe(index: int): short
3643
3644    internal setUnsafe(insertPos: int, val: short): void {
3645        let startByte = insertPos * Int16Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
3646        let bits = val
3647        if (IS_LITTLE_ENDIAN) {
3648            for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
3649                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
3650                this.buffer.set(startByte + i, byteVal)
3651            }
3652        } else {
3653            for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; i++) {
3654                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
3655                this.buffer.set(startByte + 1 - i, byteVal)
3656            }
3657        }
3658    }
3659
3660    /** Underlying ArrayBuffer */
3661    public readonly buffer: ArrayBuffer
3662
3663    /** Byte offset within the underlying ArrayBuffer */
3664    public readonly byteOffset: number
3665
3666    /** Number of bytes used */
3667    public readonly byteLength: number
3668
3669    /** String \"Int16Array\" */
3670    public readonly name = "Int16Array"
3671}
3672
3673class Int32ArrayIteratorKeys implements IterableIterator<number> {
3674    private length: int
3675    private idx: int = 0
3676
3677    constructor(parent: Int32Array) {
3678        this.length = parent.length as int
3679    }
3680
3681    public override $_iterator(): IterableIterator<number> {
3682        return this
3683    }
3684
3685    override next(): IteratorResult<number> {
3686        if (this.idx < 0 || this.idx >= this.length) {
3687            return new IteratorResult<number>()
3688        }
3689        return new IteratorResult<number>(false, this.idx++ as number)
3690    }
3691}
3692
3693class Int32ArrayIterator implements IterableIterator<Number> {
3694    private parent: Int32Array
3695    private idx: int = 0
3696
3697    constructor(parent: Int32Array) {
3698        this.parent = parent
3699    }
3700
3701    public override $_iterator(): IterableIterator<Number> {
3702        return this
3703    }
3704
3705    override next(): IteratorResult<Number> {
3706        if (this.idx < 0 || this.idx >= this.parent.length as int) {
3707            return new IteratorResult<Number>()
3708        }
3709        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
3710    }
3711}
3712
3713class Int32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
3714    private parent: Int32Array
3715    private idx: int = 0
3716
3717    constructor(parent: Int32Array) {
3718        this.parent = parent
3719    }
3720
3721    public override $_iterator(): IterableIterator<[Number, Number]> {
3722        return this
3723    }
3724
3725    override next(): IteratorResult<[Number, Number]> {
3726        if (this.idx < 0 || this.idx >= this.parent.length as int) {
3727            return new IteratorResult<[Number, Number]>()
3728        }
3729        return new IteratorResult<[Number, Number]>(
3730            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
3731        )
3732    }
3733}
3734
3735
3736/**
3737 * JS Int32Array API-compatible class
3738 */
3739export final class Int32Array implements Iterable<Number>, ArrayLike<Number> {
3740    public static readonly BYTES_PER_ELEMENT: number = 4
3741    public readonly BYTES_PER_ELEMENT: number = Int32Array.BYTES_PER_ELEMENT
3742    internal readonly lengthInt: int
3743
3744    /**
3745     * Creates an empty Int32Array.
3746     */
3747    public constructor() {
3748        this(0 as int)
3749    }
3750
3751    /**
3752     * Creates an Int32Array with respect to data accessed via Iterable<Number> interface
3753     */
3754    public constructor(elements: Iterable<Number>) {
3755        const items: Object = elements as Object
3756        if (items instanceof ArrayLike) {
3757            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
3758            this.byteLength = arr.length as int * Int32Array.BYTES_PER_ELEMENT as int
3759            this.lengthInt = arr.length as int
3760            this.buffer = new ArrayBuffer(this.byteLength as int)
3761            this.byteOffset = 0
3762            for (let i: int = 0; i < this.lengthInt; ++i) {
3763                this.setUnsafe(i, arr.$_get(i).toInt())
3764            }
3765        } else {
3766          let x = Int32Array.from(elements)
3767          this.byteLength = x.byteLength
3768          this.lengthInt = x.lengthInt
3769          this.buffer = x.buffer
3770          this.byteOffset = x.byteOffset
3771        }
3772    }
3773
3774    /**
3775     * Creates an Int32Array with respect to data, byteOffset and length.
3776     *
3777     * @param buf data initializer
3778     *
3779     * @param byteOffset byte offset from begin of the buf
3780     *
3781     * @param length size of elements of type int in newly created Int32Array
3782     */
3783    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
3784        let intByteOffset: int = 0
3785        if (byteOffset != undefined) {
3786            intByteOffset = byteOffset.toInt()
3787            if (intByteOffset < 0) {
3788                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
3789            }
3790        }
3791        let intByteLength: int = buf.getByteLength() - intByteOffset
3792        if (intByteLength < 0) {
3793            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
3794        }
3795
3796        if (intByteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
3797            throw new RangeError("ArrayBuffer.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
3798        }
3799        if (intByteOffset % Int32Array.BYTES_PER_ELEMENT as int != 0) {
3800            throw new RangeError("byteOffset should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
3801        }
3802
3803        let intLength: int
3804        if (length != undefined) {
3805            intLength = length.toInt()
3806            if (intLength > intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
3807                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
3808            }
3809        } else {
3810            intLength = intByteLength / Int32Array.BYTES_PER_ELEMENT as int
3811        }
3812        if (intLength < 0) {
3813            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
3814        }
3815        if (intLength < intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
3816            intByteLength = intLength * Int32Array.BYTES_PER_ELEMENT as int
3817        }
3818        this.byteLength = intByteLength
3819        this.byteOffset = intByteOffset
3820        this.lengthInt = intLength
3821        this.buffer = buf
3822    }
3823
3824    /**
3825     * Creates an Int32Array with respect to data, byteOffset and length.
3826     *
3827     * @param buf data initializer
3828     *
3829     * @param byteOffset byte offset from begin of the buf
3830     *
3831     * @param length size of elements of type int in newly created Int32Array
3832     */
3833    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
3834        this(buf, byteOffset, undefined)
3835    }
3836
3837    /**
3838     * Creates an Int32Array with respect to data, byteOffset and length.
3839     *
3840     * @param buf data initializer
3841     *
3842     * @param byteOffset byte offset from begin of the buf
3843     *
3844     * @param length size of elements of type int in newly created Int32Array
3845     */
3846    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
3847        this(buf, new Number(byteOffset), new Number(length))
3848    }
3849
3850    /**
3851     * Creates an Int32Array with respect to data, byteOffset and length.
3852     *
3853     * @param buf data initializer
3854     *
3855     * @param byteOffset byte offset from begin of the buf
3856     *
3857     * @param length size of elements of type int in newly created Int32Array
3858     */
3859    public constructor(buf: ArrayBuffer, byteOffset: number) {
3860        this(buf, new Number(byteOffset), undefined)
3861    }
3862
3863    /**
3864     * Creates an Int32Array with respect to data, byteOffset and length.
3865     *
3866     * @param buf data initializer
3867     *
3868     * @param byteOffset byte offset from begin of the buf
3869     *
3870     * @param length size of elements of type int in newly created Int32Array
3871     */
3872    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
3873        this(buf, new Number(byteOffset), new Number(length))
3874    }
3875
3876    /**
3877     * Creates an Int32Array with respect to buf and byteOffset.
3878     *
3879     * @param buf data initializer
3880     *
3881     * @param byteOffset byte offset from begin of the buf
3882     */
3883    public constructor(buf: ArrayBuffer, byteOffset: int) {
3884        this(buf, new Number(byteOffset), undefined)
3885    }
3886
3887    /**
3888     * Creates an Int32Array with respect to buf.
3889     *
3890     * @param buf data initializer
3891     */
3892    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
3893        if (buf instanceof ArrayBuffer) {
3894            this.byteLength = (buf as ArrayBuffer).getByteLength()
3895            if (this.byteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
3896               throw new RangeError("ArrayBuffer.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
3897            }
3898            this.lengthInt = this.byteLength / Int32Array.BYTES_PER_ELEMENT as int
3899            this.buffer = buf as ArrayBuffer
3900            this.byteOffset = 0
3901        } else if (buf instanceof ArrayLike) {
3902            // NOTE (ikorobkov): dealing with this overload is tricky
3903            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
3904            let arr = Array.from<Number>((buf as ArrayLike<Number>))
3905            this.byteLength = arr.length as int * Int32Array.BYTES_PER_ELEMENT as int
3906            this.lengthInt = arr.length as int
3907            this.buffer = new ArrayBuffer(this.byteLength as int)
3908            this.byteOffset = 0
3909            for (let i: int = 0; i < this.lengthInt; ++i) {
3910                this.setUnsafe(i, arr.$_get(i).toInt())
3911            }
3912        } else {
3913            throw new Error("unexpected type of buf")
3914        }
3915    }
3916
3917    /**
3918     * Creates an Int32Array with respect to length.
3919     *
3920     * @param length data initializer
3921     */
3922    public constructor(length: int) {
3923        this(length as number)
3924    }
3925
3926    /**
3927     * Creates an Int32Array with respect to length.
3928     *
3929     * @param length data initializer
3930     */
3931    public constructor(length: number) {
3932        if (length < 0 || length > (Int.MAX_VALUE / Int32Array.BYTES_PER_ELEMENT)) {
3933            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
3934        }
3935        this.lengthInt = length as int
3936        this.byteLength = this.lengthInt * Int32Array.BYTES_PER_ELEMENT as int
3937        this.byteOffset = 0
3938        this.buffer = new ArrayBuffer(this.byteLength as int)
3939    }
3940
3941    /**
3942     * Creates a copy of Int32Array.
3943     *
3944     * @param other data initializer
3945     */
3946    public constructor(other: Int32Array) {
3947        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
3948        this.byteLength = other.byteLength
3949        this.lengthInt = other.length as int
3950        this.byteOffset = 0
3951    }
3952
3953    /**
3954     * Creates an Int32Array from FixedArray<number>
3955     */
3956    public constructor(numbers: FixedArray<number>) {
3957        this(numbers.length)
3958        for (let i: int = 0; i < this.lengthInt; ++i) {
3959            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
3960        }
3961    }
3962
3963    /**
3964     * Creates an Int32Array from FixedArray<int>
3965     */
3966    public constructor(numbers: FixedArray<int>) {
3967        this(numbers.length)
3968        for (let i: int = 0; i < this.lengthInt; ++i) {
3969            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
3970        }
3971    }
3972
3973    internal zeroIfInfinity(val: number): number {
3974        if ((val == Infinity) || (val == -Infinity)) {
3975            return 0 as number
3976        }
3977        return val as number
3978    }
3979
3980    internal zeroIfInfinity(val: int): int {
3981        if ((val == Infinity) || (val == -Infinity)) {
3982            return 0 as int
3983        }
3984        return val
3985    }
3986
3987    /**
3988     * Assigns val as element on index.
3989     *
3990     * @param val value to set
3991     *
3992     * @param index index to change
3993     */
3994    public $_set(index: number, val: number): void {
3995        this.$_set(index as int, val)
3996    }
3997
3998    /**
3999     * Assigns val as element on index.
4000     *
4001     * @param val value to set
4002     *
4003     * @param index index to change
4004     */
4005    public $_set(index: int, val: number): void {
4006        let v = this.zeroIfInfinity(val)
4007        this.$_set(index, v as int)
4008    }
4009
4010    /**
4011     * Assigns val as element on index.
4012     *
4013     * @param val value to set
4014     *
4015     * @param index index to change
4016     */
4017    public $_set(index: number, val: int): void {
4018        this.$_set(index as int, val)
4019    }
4020
4021    /**
4022     * Assigns val as element on index.
4023     *
4024     * @param val value to set
4025     *
4026     * @param index index to change
4027     */
4028    public native $_set(index: int, val: int): void
4029
4030    /** Number of int stored in Int32Array */
4031    public get length(): number {
4032        return this.lengthInt
4033    }
4034
4035    /**
4036     * Returns an instance of number at passed index.
4037     *
4038     * @param index index to look at
4039     *
4040     * @returns a primitive at index
4041     */
4042    public override $_get(index: number): Number {
4043        return this.$_get(index as int) as Number
4044    }
4045
4046    /**
4047     * Returns an instance of number at passed index.
4048     *
4049     * @param index index to look at
4050     *
4051     * @returns a primitive at index
4052     */
4053    public native $_get(index: int): number
4054
4055    /**
4056     * Returns an instance of primitive type at passed index.
4057     *
4058     * @param index index to look at
4059     *
4060     * @returns a primitive at index
4061     */
4062    public at(index: number): Number | undefined {
4063        return this.at(index as int)
4064    }
4065
4066    /**
4067     * Returns an instance of primitive type at passed index.
4068     *
4069     * @param index index to look at
4070     *
4071     * @returns a primitive at index
4072     */
4073    public at(index: int): Number | undefined {
4074        let k: int
4075        if (index >= 0) {
4076            k = index
4077        } else {
4078            k = this.lengthInt + index
4079        }
4080        if (k < 0 || k >= this.lengthInt) {
4081            return undefined
4082        }
4083        return new Number(this.getUnsafe(k))
4084    }
4085
4086    /**
4087     * Makes a copy of internal elements to targetPos from startPos to endPos.
4088     *
4089     * @param target insert index to place copied elements
4090     *
4091     * @param start start index to begin copy from
4092     *
4093     * @param end last index to end copy from, excluded
4094     *
4095     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
4096     */
4097    public copyWithin(target: number, start: number, end?: number): Int32Array {
4098        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
4099    }
4100
4101    /**
4102     * Makes a copy of internal elements to targetPos from startPos to endPos.
4103     *
4104     * @param target insert index to place copied elements
4105     *
4106     * @param start start index to begin copy from
4107     *
4108     * @param end last index to end copy from, excluded
4109     *
4110     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
4111     */
4112    public copyWithin(target: int, start: number, end?: number): Int32Array {
4113        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
4114    }
4115
4116    /**
4117     * Makes a copy of internal elements to targetPos from startPos to endPos.
4118     *
4119     * @param target insert index to place copied elements
4120     *
4121     * @param start start index to begin copy from
4122     *
4123     * @param end last index to end copy from, excluded
4124     *
4125     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
4126     */
4127    public copyWithin(target: number, start: int, end?: number): Int32Array {
4128        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
4129    }
4130
4131    /**
4132     * Makes a copy of internal elements to targetPos from startPos to endPos.
4133     *
4134     * @param target insert index to place copied elements
4135     *
4136     * @param start start index to begin copy from
4137     *
4138     * @param end last index to end copy from, excluded
4139     *
4140     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
4141     */
4142    public copyWithin(target: int, start: int, end?: number): Int32Array {
4143        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
4144    }
4145
4146    /**
4147     * Makes a copy of internal elements to targetPos from startPos to endPos.
4148     *
4149     * @param target insert index to place copied elements
4150     *
4151     * @param start start index to begin copy from
4152     *
4153     * @param end last index to end copy from, excluded
4154     *
4155     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
4156     */
4157    public native copyWithin(target: int, start: int, end: int): Int32Array
4158
4159    /**
4160     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
4161     *
4162     * @param target insert index to place copied elements
4163     *
4164     * See rules of parameters normalization:
4165     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
4166     */
4167    public copyWithin(target: number): Int32Array {
4168        return this.copyWithin(target as int)
4169    }
4170
4171    /**
4172     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
4173     *
4174     * @param target insert index to place copied elements
4175     *
4176     * See rules of parameters normalization:
4177     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
4178     */
4179    public copyWithin(target: int): Int32Array {
4180        return this.copyWithin(target, 0, this.lengthInt)
4181    }
4182
4183    /**
4184     * Returns an array of key, value pairs for every entry in the Int32Array
4185     *
4186     * @returns key, value pairs for every entry in the array
4187     */
4188    public entries(): IterableIterator<[Number, Number]> {
4189        return new Int32ArrayIteratorEntries(this)
4190    }
4191
4192    /**
4193     * Fills the Int32Array with specified value
4194     *
4195     * @param value new valuy
4196     *
4197     * @returns modified Int32Array
4198     */
4199    public fill(value: number, start?: number, end?: number): this {
4200        value = this.zeroIfInfinity(value)
4201        this.fill(value as int, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
4202        return this
4203    }
4204
4205    /**
4206     * Fills the Int32Array with specified value
4207     *
4208     * @param value new valuy
4209     *
4210     * @returns modified Int32Array
4211     */
4212    public fill(value: number, start: int, end?: number): this {
4213        value = this.zeroIfInfinity(value)
4214        this.fill(value as int, start as int, asIntOrDefault(end, this.lengthInt))
4215        return this
4216    }
4217
4218    /**
4219     * Fills the Int32Array with specified value
4220     *
4221     * @param value new valuy
4222     *
4223     * @returns modified Int32Array
4224     */
4225    public fill(value: number, start: int, end: number): this {
4226        value = this.zeroIfInfinity(value)
4227        this.fill(value as int, start as int, end as int)
4228        return this
4229    }
4230
4231    /**
4232     * Fills the Int32Array with specified value
4233     *
4234     * @param value new valuy
4235     *
4236     * @returns modified Int32Array
4237     */
4238    public fill(value: number, start: number, end: int): this {
4239        value = this.zeroIfInfinity(value)
4240        this.fill(value as int, start as int, end as int)
4241        return this
4242    }
4243
4244    /**
4245     * Fills the Int32Array with specified value
4246     *
4247     * @param value new valuy
4248     *
4249     * @returns modified Int32Array
4250     */
4251    public fill(value: number, start: int, end: int): this {
4252        value = this.zeroIfInfinity(value)
4253        this.fill(value as int, start as int, end as int)
4254        return this
4255    }
4256
4257    /**
4258     * Fills the Int32Array with specified value
4259     *
4260     * @param value new valuy
4261     *
4262     * @returns modified Int32Array
4263     */
4264    public fill(value: int, start?: number, end?: number): this {
4265        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
4266        return this
4267    }
4268
4269    /**
4270     * Fills the Int32Array with specified value
4271     *
4272     * @param value new valuy
4273     *
4274     * @returns modified Int32Array
4275     */
4276    public fill(value: int, start: int, end?: number): this {
4277        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
4278        return this
4279    }
4280
4281    /**
4282     * Fills the Int32Array with specified value
4283     *
4284     * @param value new valuy
4285     *
4286     * @returns modified Int32Array
4287     */
4288    public fill(value: int, start: int, end: number): this {
4289        this.fill(value, start as int, end as int)
4290        return this
4291    }
4292
4293    /**
4294     * Fills the Int32Array with specified value
4295     *
4296     * @param value new valuy
4297     *
4298     * @returns modified Int32Array
4299     */
4300    public fill(value: int, start: number, end: int): this {
4301        this.fill(value, start as int, end as int)
4302        return this
4303    }
4304
4305    /**
4306     * Fills the Int32Array with specified value
4307     *
4308     * @param value new valuy
4309     *
4310     * @returns modified Int32Array
4311     */
4312    public fill(value: int, start: int, end: int): this {
4313        const k = normalizeIndex(start, this.lengthInt)
4314        const finalPos = normalizeIndex(end, this.lengthInt)
4315        this.fillInternal(value, k, finalPos)
4316        return this
4317    }
4318
4319    private final native fillInternal(value: int, start: int, end: int): void
4320
4321    /**
4322     * Assigns val as element on insertPos.
4323     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<int>, insertPos)
4324     *
4325     * @param val value to set
4326     *
4327     * @param insertPos index to change
4328     */
4329    public set(insertPos: number, val: number): void {
4330        this.$_set(insertPos, val)
4331    }
4332
4333    /**
4334     * Assigns val as element on insertPos.
4335     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<int>, insertPos)
4336     *
4337     * @param val value to set
4338     *
4339     * @param insertPos index to change
4340     */
4341    public set(insertPos: int, val: int): void {
4342        this.$_set(insertPos, val)
4343    }
4344
4345    /**
4346     * Copies all elements of arr to the current Int32Array starting from insertPos.
4347     *
4348     * @param arr array to copy data from
4349     *
4350     * @param insertPos start index where data from arr will be inserted
4351     *
4352     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
4353     */
4354    public set(arr: FixedArray<number>, insertPos: number): void {
4355        const offset = insertPos as int
4356        if (offset < 0 || offset + arr.length > this.lengthInt) {
4357            throw new RangeError("offset is out of bounds")
4358        }
4359        for (let i = 0; i < arr.length as int; ++i) {
4360            let v = this.zeroIfInfinity(arr[i])
4361            this.$_set(offset + i, v as int)
4362        }
4363    }
4364
4365    /**
4366     * Copies all elements of arr to the current Int32Array starting from insertPos.
4367     *
4368     * @param arr array to copy data from
4369     *
4370     * @param insertPos start index where data from arr will be inserted
4371     *
4372     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
4373     */
4374    public set(arr: FixedArray<int>, insertPos: int): void {
4375        const offset = insertPos as int
4376        if (offset < 0 || offset + arr.length > this.lengthInt) {
4377            throw new RangeError("offset is out of bounds")
4378        }
4379        for (let i = 0; i < arr.length as int; ++i) {
4380            let v = this.zeroIfInfinity(arr[i])
4381            this.$_set(offset + i, v)
4382        }
4383    }
4384
4385    /**
4386     * Copies all elements of arr to the current Int32Array.
4387     *
4388     * @param arr array to copy data from
4389     */
4390    public set(arr: FixedArray<number>): void {
4391        this.set(arr, 0 as number)
4392    }
4393
4394    /**
4395     * Copies all elements of arr to the current Int32Array.
4396     *
4397     * @param arr array to copy data from
4398     */
4399    public set(arr: FixedArray<int>): void {
4400        this.set(arr, 0 as int)
4401    }
4402
4403    public native set(array: Int32Array): void
4404
4405    public native set(array: Int32Array, offset: number): void
4406
4407    /**
4408     * Copies elements from an ArrayLike object to the Int32Array.
4409     *
4410     * @param array An ArrayLike object containing the elements to copy.
4411     *
4412     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
4413     */
4414    public set(array: ArrayLike<number>, offset: number = 0): void {
4415        const insertPos = offset as int
4416        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
4417            throw new RangeError("offset is out of bounds")
4418        }
4419        for (let i = array.length - 1 as int; i >= 0; --i) {
4420            let v = this.zeroIfInfinity(array[i])
4421            this.$_set(insertPos + i, v as int)
4422        }
4423    }
4424
4425    /**
4426     * Returns a new array from a set of elements.
4427     *
4428     * @param items a set of elements to include in the new array object.
4429     *
4430     * @returns new Int32Array
4431     */
4432    public static of(...items: FixedArray<number>): Int32Array {
4433        let res = new Int32Array(items.length as int)
4434        for (let i: int = 0; i < items.length; i++) {
4435            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as int)
4436        }
4437        return res
4438    }
4439
4440    /**
4441     * Returns a new array from a set of elements.
4442     *
4443     * @param items a set of elements to include in the new array object.
4444     *
4445     * @returns new Int32Array
4446     */
4447    public static of(...items: FixedArray<int>): Int32Array {
4448        let res = new Int32Array(items.length as int)
4449        for (let i: int = 0; i < items.length; i++) {
4450            res.setUnsafe(i, items[i])
4451        }
4452        return res
4453    }
4454
4455    /**
4456     * Returns a new array from a set of elements.
4457     *
4458     * @param items a set of elements to include in the new array object.
4459     *
4460     * @returns new Int32Array
4461     */
4462    public static of(): Int32Array {
4463        return new Int32Array(0 as int)
4464    }
4465
4466    /**
4467     * Creates an array from an array-like or iterable object.
4468     *
4469     * @param arrayLike An array-like or iterable object to convert to an array.
4470     *
4471     * @returns new Int32Array
4472     */
4473    public static from(arrayLike: ArrayLike<number>): Int32Array {
4474        return Int32Array.from<number>(arrayLike, (x: number, k: number): number => x)
4475    }
4476
4477    /**
4478     * Creates an array from an array-like or iterable object.
4479     *
4480     * @param arrayLike An array-like or iterable object to convert to an array.
4481     *
4482     * @param mapfn A mapping function to call on every element of the array.
4483     *
4484     * @returns new Int32Array
4485     */
4486    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int32Array {
4487        if (mapfn == undefined) {
4488            mapfn = (v: number, k: number): number => { return v }
4489        }
4490
4491        let iter = arrayLike.$_iterator()
4492        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
4493        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
4494        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
4495        //  we can make one pass through the iterator without the need for memory reallocation.
4496        const maybeLength = tryGetIteratorLength(arrayLike)
4497        if (maybeLength) {
4498            const result = new Int32Array(maybeLength)
4499            for (let i = 0; i < maybeLength; ++i) {
4500                const x = iter.next()
4501                if (x.done) {
4502                    return new Int32Array(result.buffer, 0, i)
4503                }
4504                result.setUnsafe(i, result.zeroIfInfinity((mapfn)!(x.value!, i)) as int)
4505            }
4506            return result
4507        }
4508
4509        // NOTE (templin.konstantin): Create builtin array as buffer
4510        let temp = new Int32Array(6)
4511        let index : FixedArray<int> = new int[1]
4512        index[0] = 0
4513
4514        iteratorForEach<number>(iter, (x: number): void => {
4515            if (index[0] + 1 > temp.lengthInt) {
4516                // NOTE (templin.konstantin): Progressive reallocation
4517                const curLength = (temp.buffer as Buffer).getByteLength()
4518                const tb = new ArrayBuffer(curLength * 2)
4519                for (let i = 0; i < curLength; ++i) {
4520                    tb.set(i, (temp.buffer as Buffer).at(i))
4521                }
4522                temp = new Int32Array(tb)
4523            }
4524            temp.setUnsafe(index[0], temp.zeroIfInfinity((mapfn)!(x, index[0])) as int)
4525            index[0]++
4526        })
4527        return new Int32Array(temp.buffer, 0, index[0])
4528    }
4529
4530
4531    /**
4532     * Creates an array from an array-like or iterable object.
4533     *
4534     * @param arrayLike An array-like or iterable object to convert to an array.
4535     *
4536     * @param mapfn A mapping function to call on every element of the array.
4537     *
4538     * @returns new Int32Array
4539     */
4540    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Int32Array {
4541        let res = new Int32Array(arrayLike.length)
4542        // 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
4543        const idx : FixedArray<int> = new int[1]
4544        idx[0] = 0
4545        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
4546            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as int)
4547            idx[0] += 1
4548        })
4549        return res
4550    }
4551
4552    /**
4553     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
4554     *
4555     * @param searchElement The element to search for
4556     *
4557     * @param fromIndex The position in this array at which to begin searching for searchElement
4558     *
4559     * @returns true if searchElement is in Int32Array, false otherwise
4560     */
4561    public includes(searchElement: number, fromIndex?: number): boolean {
4562        if (isNaN(searchElement)) {
4563            return false
4564        }
4565        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
4566    }
4567
4568    /**
4569     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
4570     *
4571     * @param searchElement The element to search for
4572     *
4573     * @param fromIndex The position in this array at which to begin searching for searchElement
4574     *
4575     * @returns true if e is in Int32Array, false otherwise
4576     */
4577    public includes(searchElement: int, fromIndex: int): boolean {
4578        return this.indexOf(searchElement as int, fromIndex) != -1
4579    }
4580
4581    /**
4582     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
4583     *
4584     * @param searchElement The element to search for
4585     *
4586     * @param fromIndex The position in this array at which to begin searching for searchElement
4587     *
4588     * @returns true if searchElement is in Int32Array, false otherwise
4589     */
4590    public includes(searchElement: int): boolean {
4591        return this.includes(searchElement, 0)
4592    }
4593
4594    /**
4595     * Returns the index of the first occurrence of a value in Int32Array.
4596     *
4597     * @param searchElement The value to locate in the array.
4598     *
4599     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4600     *  search starts at index 0.
4601     *
4602     * @returns index of element if it presents, -1 otherwise
4603     */
4604    public indexOf(searchElement: number, fromIndex?: number): number {
4605        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
4606    }
4607
4608    /**
4609     * Returns the index of the first occurrence of a value in Int32Array.
4610     *
4611     * @param searchElement The value to locate in the array.
4612     *
4613     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4614     *  search starts at index 0.
4615     *
4616     * @returns index of element if it presents, -1 otherwise
4617     */
4618    public indexOf(searchElement: number, fromIndex: int): number {
4619            return this.indexOfImpl(searchElement, fromIndex)
4620    }
4621
4622    /**
4623     * Returns the index of the first occurrence of a value in Int32Array.
4624     *
4625     * @param searchElement The value to locate in the array.
4626     *
4627     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4628     *  search starts at index 0.
4629     *
4630     * @returns index of element if it presents, -1 otherwise
4631     */
4632    public indexOf(searchElement: int, fromIndex: int): number {
4633        return this.indexOfImpl(searchElement as long, fromIndex)
4634    }
4635
4636    /**
4637     * Returns the index of the first occurrence of a value in Int32Array.
4638     *
4639     * @param searchElement The value to locate in the array.
4640     *
4641     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4642     *  search starts at index 0.
4643     *
4644     * @returns index of element if it presents, -1 otherwise
4645     */
4646    private final native indexOfImpl(searchElement: number, fromIndex: int): number
4647
4648    /**
4649     * Returns the index of the first occurrence of a value in Int32Array.
4650     *
4651     * @param searchElement The value to locate in the array.
4652     *
4653     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4654     *  search starts at index 0.
4655     *
4656     * @returns index of element if it presents, -1 otherwise
4657     */
4658    private final native indexOfImpl(searchElement: long, fromIndex: int): number
4659
4660    /**
4661     * Returns the index of the first occurrence of a value in Int32Array.
4662     *
4663     * @param searchElement The value to locate in the array.
4664     *
4665     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
4666     *  search starts at index 0.
4667     *
4668     * @returns index of element if it presents, -1 otherwise
4669     */
4670    public indexOf(searchElement: int): number {
4671        return this.indexOf(searchElement, 0)
4672    }
4673
4674    /**
4675     * Converts all elements of an array to strings and joins them using the specified separator.
4676     *
4677     * @param separator - separates one element of an array from the next in the resulting String.
4678     *
4679     * @returns joined representation
4680     */
4681    private final native joinInternal(separator: String): string;
4682
4683    /**
4684     * Adds all the elements of an array separated by the specified separator string
4685     *
4686     * @param separator A string used to separate one element of an array from the next in the
4687     * resulting String. If omitted, the array elements are separated with a comma.
4688     *
4689     * @returns joined representation
4690     */
4691    public join(separator?: String): string {
4692        if (separator == undefined) {
4693            return this.joinInternal(",")
4694        }
4695        return this.joinInternal(separator)
4696    }
4697
4698    /**
4699     * Returns an list of keys in Int32Array
4700     *
4701     * @returns iterator over keys
4702     */
4703    public keys(): IterableIterator<number> {
4704        return new Int32ArrayIteratorKeys(this)
4705    }
4706
4707    /**
4708     * Returns the index of the last occurrence of a value in Int32Array.
4709     *
4710     * @param searchElement The value to locate in the array.
4711     *
4712     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4713     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4714     *
4715     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4716     */
4717    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
4718        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
4719    }
4720
4721    /**
4722     * Returns the index of the last occurrence of a value in Int32Array.
4723     *
4724     * @param searchElement The value to locate in the array.
4725     *
4726     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4727     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4728     *
4729     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4730     */
4731    public lastIndexOf(searchElement: number): number {
4732        return this.lastIndexOf(searchElement, this.lengthInt - 1)
4733    }
4734
4735    /**
4736     * Returns the index of the last occurrence of a value in Int32Array.
4737     *
4738     * @param searchElement The value to locate in the array.
4739     *
4740     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4741     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4742     *
4743     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4744     */
4745    public lastIndexOf(searchElement: number, fromIndex: int): number {
4746            return this.lastIndexOfImpl(searchElement, fromIndex)
4747    }
4748
4749    /**
4750     * Returns the index of the last occurrence of a value in Int32Array.
4751     *
4752     * @param searchElement The value to locate in the array.
4753     *
4754     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4755     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4756     *
4757     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4758     */
4759    public lastIndexOf(searchElement: int, fromIndex: int): number {
4760        return this.lastIndexOfImpl(searchElement as long, fromIndex)
4761    }
4762
4763    /**
4764     * Returns the index of the last occurrence of a value in Int32Array.
4765     *
4766     * @param searchElement The value to locate in the array.
4767     *
4768     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4769     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4770     *
4771     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4772     */
4773    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
4774
4775    /**
4776     * Returns the index of the last occurrence of a value in Int32Array.
4777     *
4778     * @param searchElement The value to locate in the array.
4779     *
4780     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4781     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4782     *
4783     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4784     */
4785    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
4786
4787    /**
4788     * Returns the index of the last occurrence of a value in Int32Array.
4789     *
4790     * @param searchElement The value to locate in the array.
4791     *
4792     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
4793     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
4794     *
4795     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
4796     */
4797    public lastIndexOf(searchElement: int): number {
4798        return this.lastIndexOf(searchElement, this.lengthInt - 1)
4799    }
4800
4801    /**
4802    * Creates a new Int32Array using initializer
4803    *
4804    * @param data initializer
4805    *
4806    * @returns a new Int32Array from data
4807    */
4808    public of(data: FixedArray<Object>): Int32Array {
4809        throw new Error("Int32Array.of: not implemented")
4810    }
4811
4812    /**
4813     * Creates a new Int32Array using reversed data from the current one
4814     *
4815     * @returns a new Int32Array using reversed data from the current one
4816     */
4817    public native reverse(): Int32Array
4818
4819    /**
4820     * Creates a slice of current Int32Array using range [begin, end)
4821     *
4822     * @param begin start index to be taken into slice
4823     *
4824     * @param end last index to be taken into slice
4825     *
4826     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
4827     *
4828     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
4829     */
4830    public slice(begin?: number, end?: number): Int32Array {
4831        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
4832    }
4833
4834    /**
4835     * Creates a slice of current Int32Array using range [begin, end)
4836     *
4837     * @param begin start index to be taken into slice
4838     *
4839     * @param end last index to be taken into slice
4840     *
4841     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
4842     *
4843     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
4844     */
4845    public slice(begin: number, end: number): Int32Array {
4846        return this.slice(begin as int, end as int)
4847    }
4848
4849    /**
4850     * Creates a slice of current Int32Array using range [begin, end)
4851     *
4852     * @param begin start index to be taken into slice
4853     *
4854     * @param end last index to be taken into slice
4855     *
4856     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
4857     *
4858     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
4859     */
4860    public slice(begin: number, end: int): Int32Array {
4861        return this.slice(begin as int, end as int)
4862    }
4863
4864    /**
4865     * Creates a slice of current Int32Array using range [begin, end)
4866     *
4867     * @param begin start index to be taken into slice
4868     *
4869     * @param end last index to be taken into slice
4870     *
4871     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
4872     *
4873     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
4874     */
4875    public slice(begin: int, end: number): Int32Array {
4876        return this.slice(begin as int, end as int)
4877    }
4878
4879    /**
4880     * Creates a slice of current Int32Array using range [begin, end)
4881     *
4882     * @param begin start index to be taken into slice
4883     *
4884     * @param end last index to be taken into slice
4885     *
4886     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
4887     *
4888     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
4889     */
4890    public slice(begin: int, end: int): Int32Array {
4891        const len: int = this.lengthInt
4892        const relStart = normalizeIndex(begin, len)
4893        const relEnd = normalizeIndex(end, len)
4894        let count = relEnd - relStart
4895        if (count < 0) {
4896            count = 0
4897        }
4898        let buf = this.buffer.slice(relStart * Int32Array.BYTES_PER_ELEMENT as int, relEnd * Int32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
4899        return new Int32Array(buf)
4900    }
4901
4902    /**
4903     * Creates a slice of current Int32Array using range [begin, this.length).
4904     *
4905     * @param begin start index to be taken into slice
4906     *
4907     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
4908     */
4909    public slice(begin: number): Int32Array {
4910        return this.slice(begin as int)
4911    }
4912
4913    /**
4914     * Creates a slice of current Int32Array using range [begin, this.length).
4915     *
4916     * @param begin start index to be taken into slice
4917     *
4918     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
4919     */
4920    public slice(begin: int): Int32Array {
4921        return this.slice(begin, this.lengthInt)
4922    }
4923
4924    /**
4925     * Creates a Int32Array with the same underlying ArrayBuffer
4926     *
4927     * @param begin start index, inclusive
4928     *
4929     * @param end last index, exclusive
4930     *
4931     * @returns new Int32Array with the same underlying ArrayBuffer
4932     */
4933    public subarray(begin?: number, end?: number): Int32Array {
4934        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
4935    }
4936
4937    /**
4938     * Creates a Int32Array with the same underlying ArrayBuffer
4939     *
4940     * @param begin start index, inclusive
4941     *
4942     * @param end last index, exclusive
4943     *
4944     * @returns new Int32Array with the same underlying ArrayBuffer
4945     */
4946    public subarray(begin: number, end: number): Int32Array {
4947        return this.subarray(begin as int, end as int)
4948    }
4949
4950    /**
4951     * Creates a Int32Array with the same underlying ArrayBuffer
4952     *
4953     * @param begin start index, inclusive
4954     *
4955     * @param end last index, exclusive
4956     *
4957     * @returns new Int32Array with the same underlying ArrayBuffer
4958     */
4959    public subarray(begin: number, end: int): Int32Array {
4960        return this.subarray(begin as int, end as int)
4961    }
4962
4963    /**
4964     * Creates a Int32Array with the same underlying ArrayBuffer
4965     *
4966     * @param begin start index, inclusive
4967     *
4968     * @param end last index, exclusive
4969     *
4970     * @returns new Int32Array with the same underlying ArrayBuffer
4971     */
4972    public subarray(begin: int, end: number): Int32Array {
4973        return this.subarray(begin as int, end as int)
4974    }
4975
4976    /**
4977     * Creates a Int32Array with the same underlying ArrayBuffer
4978     *
4979     * @param begin start index, inclusive
4980     *
4981     * @param end last index, exclusive
4982     *
4983     * @returns new Int32Array with the same underlying ArrayBuffer
4984     */
4985    public subarray(begin: int, end: int | undefined = this.lengthInt): Int32Array {
4986        const len: int = this.lengthInt
4987        const relStart = normalizeIndex(begin, len)
4988        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
4989        let count = relEnd - relStart
4990        if (count < 0) {
4991            count = 0
4992        }
4993        return new Int32Array(this.buffer, relStart * Int32Array.BYTES_PER_ELEMENT as int, count)
4994    }
4995
4996    /**
4997     * Converts Int32Array to a string with respect to locale
4998     *
4999     * @param locales
5000     *
5001     * @param options
5002     *
5003     * @returns string representation
5004     */
5005    public toLocaleString(locales: Object, options: Object): string {
5006        throw new Error("Int32Array.toLocaleString: not implemented")
5007    }
5008
5009    /**
5010     * Converts Int32Array to a string with respect to locale
5011     *
5012     * @param locales
5013     *
5014     * @returns string representation
5015     */
5016    public toLocaleString(locales: Object): string {
5017        return this.toLocaleString(new Object(), new Object())
5018    }
5019
5020    /**
5021     * Converts Int32Array to a string with respect to locale
5022     *
5023     * @returns string representation
5024     */
5025    public toLocaleString(): string {
5026        let res: StringBuilder = new StringBuilder("")
5027        for (let i = 0; i < this.lengthInt - 1; ++i) {
5028            res.append((this.getUnsafe(i) as Number).toLocaleString())
5029            res.append(",")
5030        }
5031        if (this.lengthInt > 0) {
5032            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
5033        }
5034        return res.toString()
5035    }
5036
5037    /**
5038     * Creates a reversed copy
5039     *
5040     * @returns a reversed copy
5041     */
5042    public final native toReversed(): Int32Array
5043
5044    /**
5045     * Creates a sorted copy
5046     *
5047     * @returns a sorted copy
5048     */
5049    public toSorted(): Int32Array {
5050        return new Int32Array(this).sort()
5051    }
5052
5053    /**
5054     * Returns a string representation of the Int32Array
5055     *
5056     * @returns a string representation of the Int32Array
5057     */
5058    public override toString(): string {
5059        return this.join(",")
5060    }
5061
5062    /**
5063     * Returns array values iterator
5064     *
5065     * @returns an iterator
5066     */
5067    public values(): IterableIterator<Number> {
5068        return new Int32ArrayIterator(this)
5069    }
5070
5071    /**
5072     * Iteratorable interface implementation
5073     *
5074     * @returns iterator over all elements
5075     */
5076    public override $_iterator(): IterableIterator<Number> {
5077        return this.values()
5078    }
5079
5080    /**
5081     * Creates a copy with replaced value on index
5082     *
5083     * @param index
5084     *
5085     * @param value
5086     *
5087     * @returns an Int32Array with replaced value on index
5088     */
5089    public with(index: number, value: number): Int32Array {
5090        return this.with(index as int, value as int)
5091    }
5092
5093    /**
5094     * Creates a copy with replaced value on index
5095     *
5096     * @param index
5097     *
5098     * @param value
5099     *
5100     * @returns an Int32Array with replaced value on index
5101     */
5102    public with(index: int, value: int): Int32Array {
5103        let res = new Int32Array(this)
5104        res.set(index, value)
5105        return res
5106    }
5107
5108    /// === with element lambda functions ===
5109
5110    /**
5111     * Finds the last element in the Int32Array that satisfies the condition
5112     *
5113     * @param fn condition
5114     *
5115     * @returns the last element that satisfies fn
5116     */
5117    public findLast(fn: (val: number) => boolean): number {
5118        let newF: (val: number, index: number, array: Int32Array) => boolean =
5119            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
5120        return this.findLast(newF) as number
5121    }
5122
5123    /**
5124     * Sorts in-place by numeric value in ascending order.
5125     *
5126     * @returns sorted Int32Array
5127     */
5128    public native sort(): this;
5129
5130    /**
5131     * Sorts in-place
5132     *
5133     * @param compareFn comparator _  used to determine the order of the elements.
5134     * compareFn returns a negative value if first argument is less than second argument,
5135     * zero if they're equal and a positive value otherwise.
5136     *
5137     * @returns sorted Int32Array
5138     */
5139    public sort(compareFn?: (a: number, b: number) => number): this {
5140        if (compareFn == undefined) {
5141            this.sort()
5142            return this
5143        }
5144        let arr: FixedArray<int> = new int[this.lengthInt]
5145        for (let i = 0; i < this.lengthInt; ++i) {
5146            arr[i] = this.getUnsafe(i)
5147        }
5148
5149        let cmp = (l: int, r: int): number => {
5150            const result = compareFn!(l as number, r as number)
5151            return result
5152        }
5153        const MAX_SHORT_LENGTH = 24
5154        if (arr.length > MAX_SHORT_LENGTH) {
5155            arr = mergeSort(arr, cmp)
5156        } else {
5157            sort(arr, cmp)
5158        }
5159        for (let i = 0; i < arr.length; ++i) {
5160            this.setUnsafe(i, arr[i])
5161        }
5162        return this
5163    }
5164
5165    /**
5166     * Determines whether the specified callback function returns true for any element of an array.
5167     *
5168     * @param predicate A function that accepts three arguments.
5169     * The some method calls the predicate function for each element in the array
5170     * until the predicate returns a true or until the end of the array.
5171     *
5172     * @returns false unless predicate function returns true for an array element,
5173     * in which case true is immediately returned.
5174     */
5175    public some(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
5176        for (let i = 0; i < this.lengthInt; ++i) {
5177            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
5178                return true
5179            }
5180        }
5181        return false
5182    }
5183
5184    /**
5185     * Calls the specified callback function for all the elements in an array.
5186     * The return value of the callback function is the accumulated result,
5187     * and is provided as an argument in the next call to the callback function.
5188     *
5189     * @param callbackfn A function that accepts four arguments.
5190     * The reduce method calls the callbackfn function one time for each element in the array.
5191     *
5192     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
5193     * The first call to the callbackfn function provides this value as an argument.
5194     *
5195     * @returns The value that results from running the callback function to completion over the entire typed array.
5196     */
5197    public reduce<U = number>(
5198                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
5199                initialValue: U): U {
5200        let accumulatedValue = initialValue
5201        for (let i = 0; i < this.lengthInt; ++i) {
5202            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
5203        }
5204        return accumulatedValue
5205    }
5206
5207    /**
5208     * Calls the specified callback function for all the elements in an array.
5209     * The return value of the callback function is the accumulated result,
5210     * and is provided as an argument in the next call to the callback function.
5211     *
5212     * @param callbackfn A function that accepts four arguments.
5213     * The reduce method calls the callbackfn function one time for each element in the array.
5214     * The first call to the callbackfn function provides array first element value as an argument
5215     *
5216     * @returns The value that results from running the callback function to completion over the entire typed array.
5217     * calling reduce method on an empty array without an initial value creates a TypeError
5218     */
5219    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
5220        if (this.lengthInt == 0) {
5221            throw new TypeError("Reduce of empty array with no initial value")
5222        }
5223
5224        let accumulatedValue = this.getUnsafe(0) as number
5225        for (let i = 1; i < this.lengthInt; ++i) {
5226            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
5227        }
5228        return accumulatedValue
5229    }
5230
5231    /**
5232     * Calls the specified callback function for all the elements in an array, in descending order.
5233     * The return value of the callback function is the accumulated result,
5234     * and is provided as an argument in the next call to the callback function.
5235     *
5236     * @param callbackfn A function that accepts four arguments.
5237     * The reduceRight method calls the callbackfn function one time for each element in the array.
5238     *
5239     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
5240     * The first call to the callbackfn function provides this value as an argument.
5241     *
5242     * @returns The value that results from running the callback function to completion over the entire typed array.
5243     */
5244    public reduceRight<U = number>(
5245                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
5246                initialValue: U): U {
5247        let accumulatedValue = initialValue
5248        for (let i = this.lengthInt - 1; i >= 0; --i) {
5249            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
5250        }
5251        return accumulatedValue
5252    }
5253
5254
5255    /**
5256     * Calls the specified callback function for all the elements in an array, in descending order.
5257     * The return value of the callback function is the accumulated result,
5258     * and is provided as an argument in the next call to the callback function.
5259     *
5260     * @param callbackfn A function that accepts four arguments.
5261     * The reduceRight method calls the callbackfn function one time for each element in the array.
5262     * The first call to the callbackfn function provides array last element value as an argument
5263     *
5264     * @returns The value that results from running the callback function to completion over the entire typed array.
5265     * calling reduceRight method on an empty array without an initial value creates a TypeError
5266     */
5267    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
5268        if (this.lengthInt == 0) {
5269            throw new TypeError("Reduce of empty array with no initial value")
5270        }
5271
5272        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
5273        for (let i = this.lengthInt - 2; i >= 0; --i) {
5274            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
5275        }
5276        return accumulatedValue
5277    }
5278
5279   /**
5280    * Creates a new Int32Array using fn(arr[i]) over all elements of current Int32Array.
5281    *
5282    * @param fn a function to apply for each element of current Int32Array
5283    *
5284    * @returns a new Int32Array where for each element from current Int32Array fn was applied
5285    */
5286    public map(fn: (val: number, index: number, array: Int32Array) => number): Int32Array {
5287        let resBuf = new ArrayBuffer(this.lengthInt * Int32Array.BYTES_PER_ELEMENT as int)
5288        let res = new Int32Array(resBuf, 0, resBuf.getByteLength() / Int32Array.BYTES_PER_ELEMENT as int)
5289        for (let i = 0; i < this.lengthInt; ++i) {
5290            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as int)
5291        }
5292        return res
5293    }
5294
5295    /**
5296     * Determines whether the specified callback function returns true for all elements of an array.
5297     *
5298     * @param predicate A function that accepts three arguments.
5299     * The every method calls the predicate function for each element in the array until the predicate returns a false,
5300     * or until the end of the array.
5301     *
5302     * @returns true unless predicate function returns a false for an array element,
5303     * in which case false is immediately returned.
5304     */
5305    public every(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
5306        for (let i = 0; i < this.lengthInt; ++i) {
5307            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
5308                return false
5309            }
5310        }
5311        return true
5312    }
5313
5314    /**
5315     * Creates a new Int32Array from current Int32Array based on a condition fn.
5316     *
5317     * @param fn the condition to apply for each element
5318     *
5319     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
5320     */
5321    public filter(fn: (val: number, index: number, array: Int32Array) => boolean): Int32Array {
5322        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
5323        let resLen = 0
5324        for (let i = 0; i < this.lengthInt; ++i) {
5325            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
5326            if (markers[i]) {
5327                ++resLen
5328            }
5329        }
5330        let resBuf = new ArrayBuffer(resLen * Int32Array.BYTES_PER_ELEMENT as int)
5331        let res = new Int32Array(resBuf, 0)
5332        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
5333            if (markers[i]) {
5334                res.set(j, this.getUnsafe(i))
5335                ++j
5336            }
5337        }
5338        return res
5339    }
5340
5341    /**
5342     * Returns the value of the first element in the array where predicate is true, and undefined
5343     * otherwise
5344     *
5345     * @param predicate find calls predicate once for each element of the array, in ascending
5346     * order, until it finds one where predicate returns true. If such an element is found, find
5347     * immediately returns that element value. Otherwise, find returns undefined
5348     *
5349     * @returns number | undefined
5350     */
5351    public find(predicate: (value: number, index: number, obj: Int32Array) => boolean): number | undefined {
5352        for (let i = 0; i < this.lengthInt; ++i) {
5353            let val = this.getUnsafe(i)
5354            if (predicate(val as number, i as number, this)) {
5355                return val as number
5356            }
5357        }
5358        return undefined
5359    }
5360
5361    /**
5362     * Returns the index of the first element in the array where predicate is true, and -1
5363     * otherwise
5364     *
5365     * @param predicate find calls predicate once for each element of the array, in ascending
5366     * order, until it finds one where predicate returns true. If such an element is found,
5367     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
5368     *
5369     * @returns number
5370     */
5371    public findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean): number {
5372        for (let i = 0; i < this.lengthInt; ++i) {
5373            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
5374                return i as number
5375            }
5376        }
5377        return -1 as number
5378    }
5379
5380    /**
5381     * Finds the last element in the Int32Array that satisfies the condition
5382     *
5383     * @param fn condition
5384     *
5385     * @returns the last element that satisfies fn
5386     */
5387    public findLast(fn: (val: number, index: number, array: Int32Array) => boolean): int {
5388        for (let i = this.lengthInt - 1; i >= 0; --i) {
5389            let val = this.getUnsafe(i)
5390            if (fn(val as number, i as number, this)) {
5391                return val
5392            }
5393        }
5394        throw new Error("Int32Array.findLast: not implemented if an element was not found")
5395    }
5396
5397    /**
5398     * Finds an index of the last element in the Int32Array that satisfies the condition
5399     *
5400     * @param fn condition
5401     *
5402     * @returns the index of the last element that satisfies fn, -1 otherwise
5403     */
5404    public findLastIndex(fn: (val: number, index: number, array: Int32Array) => boolean): number {
5405        for (let i = this.lengthInt - 1; i >= 0; --i) {
5406            let val = this.getUnsafe(i)
5407            if (fn(val as number, i as number, this)) {
5408                return i
5409            }
5410        }
5411        return -1 as number
5412    }
5413
5414    /**
5415     * Performs the specified action for each element in Int32Array
5416     *
5417     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5418     * callbackfn function one time for each element in the array.
5419     *
5420     * @returns None
5421     */
5422    public forEach(callbackfn: (value: number, index: number, array: Int32Array) => void): void {
5423        for (let i = 0; i < this.lengthInt; ++i) {
5424            callbackfn(this.getUnsafe(i) as number, i as number, this)
5425        }
5426    }
5427
5428    /**
5429     * Returns the object itself
5430     *
5431     * @returns Int32Array
5432     */
5433    public valueOf(): Int32Array {
5434        return this
5435    }
5436
5437    private final native getUnsafe(index: int): int
5438
5439    internal setUnsafe(insertPos: int, val: int): void {
5440        let startByte = insertPos * Int32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
5441        let bits = val
5442        if (IS_LITTLE_ENDIAN) {
5443            for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
5444                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5445                this.buffer.set(startByte + i, byteVal)
5446            }
5447        } else {
5448            for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; i++) {
5449                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5450                this.buffer.set(startByte + 3 - i, byteVal)
5451            }
5452        }
5453    }
5454
5455    /** Underlying ArrayBuffer */
5456    public readonly buffer: ArrayBuffer
5457
5458    /** Byte offset within the underlying ArrayBuffer */
5459    public readonly byteOffset: number
5460
5461    /** Number of bytes used */
5462    public readonly byteLength: number
5463
5464    /** String \"Int32Array\" */
5465    public readonly name = "Int32Array"
5466}
5467
5468class BigInt64ArrayIteratorKeys implements IterableIterator<number> {
5469    private length: int
5470    private idx: int = 0
5471
5472    constructor(parent: BigInt64Array) {
5473        this.length = parent.length as int
5474    }
5475
5476    public override $_iterator(): IterableIterator<number> {
5477        return this
5478    }
5479
5480    override next(): IteratorResult<number> {
5481        if (this.idx < 0 || this.idx >= this.length) {
5482            return new IteratorResult<number>()
5483        }
5484        return new IteratorResult<number>(false, this.idx++ as number)
5485    }
5486}
5487
5488class BigInt64ArrayIterator implements IterableIterator<BigInt> {
5489    private parent: BigInt64Array
5490    private idx: int = 0
5491
5492    constructor(parent: BigInt64Array) {
5493        this.parent = parent
5494    }
5495
5496    public override $_iterator(): IterableIterator<BigInt> {
5497        return this
5498    }
5499
5500    override next(): IteratorResult<BigInt> {
5501        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5502            return new IteratorResult<BigInt>()
5503        }
5504        return new IteratorResult<BigInt>(false, new BigInt(this.parent[this.idx++]))
5505    }
5506}
5507
5508class BigInt64ArrayIteratorEntries implements IterableIterator<[Number, BigInt]> {
5509    private parent: BigInt64Array
5510    private idx: int = 0
5511
5512    constructor(parent: BigInt64Array) {
5513        this.parent = parent
5514    }
5515
5516    public override $_iterator(): IterableIterator<[Number, BigInt]> {
5517        return this
5518    }
5519
5520    override next(): IteratorResult<[Number, BigInt]> {
5521        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5522            return new IteratorResult<[Number, BigInt]>()
5523        }
5524        return new IteratorResult<[Number, BigInt]>(
5525            false, [new Number(this.idx), new BigInt(this.parent[this.idx++])] as [Number, BigInt]
5526        )
5527    }
5528}
5529
5530
5531/**
5532 * JS BigInt64Array API-compatible class
5533 */
5534export final class BigInt64Array implements Iterable<BigInt>, ArrayLike<BigInt> {
5535    public static readonly BYTES_PER_ELEMENT: number = 8
5536    public readonly BYTES_PER_ELEMENT: number = BigInt64Array.BYTES_PER_ELEMENT
5537    internal readonly lengthInt: int
5538
5539    /**
5540     * Creates an empty BigInt64Array.
5541     */
5542    public constructor() {
5543        this(0 as int)
5544    }
5545
5546    /**
5547     * Creates an BigInt64Array with respect to data accessed via Iterable<Number> interface
5548     */
5549    public constructor(elements: Iterable<BigInt>) {
5550        const items: Object = elements as Object
5551        if (items instanceof ArrayLike) {
5552            const arr = Types.identity_cast<BigInt>(items as ArrayLike<BigInt>)
5553            this.byteLength = arr.length as int * BigInt64Array.BYTES_PER_ELEMENT as int
5554            this.lengthInt = arr.length as int
5555            this.buffer = new ArrayBuffer(this.byteLength as int)
5556            this.byteOffset = 0
5557            for (let i: int = 0; i < this.lengthInt; ++i) {
5558                this.setUnsafe(i, arr.$_get(i).getLong())
5559            }
5560        } else {
5561          let x = BigInt64Array.from(elements)
5562          this.byteLength = x.byteLength
5563          this.lengthInt = x.lengthInt
5564          this.buffer = x.buffer
5565          this.byteOffset = x.byteOffset
5566        }
5567    }
5568
5569    /**
5570     * Creates an BigInt64Array with respect to data, byteOffset and length.
5571     *
5572     * @param buf data initializer
5573     *
5574     * @param byteOffset byte offset from begin of the buf
5575     *
5576     * @param length size of elements of type long in newly created BigInt64Array
5577     */
5578    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
5579        let intByteOffset: int = 0
5580        if (byteOffset != undefined) {
5581            intByteOffset = byteOffset.toInt()
5582            if (intByteOffset < 0) {
5583                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
5584            }
5585        }
5586        let intByteLength: int = buf.getByteLength() - intByteOffset
5587        if (intByteLength < 0) {
5588            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5589        }
5590
5591        if (intByteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
5592            throw new RangeError("ArrayBuffer.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
5593        }
5594        if (intByteOffset % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
5595            throw new RangeError("byteOffset should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
5596        }
5597
5598        let intLength: int
5599        if (length != undefined) {
5600            intLength = length.toInt()
5601            if (intLength > intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
5602                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5603            }
5604        } else {
5605            intLength = intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int
5606        }
5607        if (intLength < 0) {
5608            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
5609        }
5610        if (intLength < intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
5611            intByteLength = intLength * BigInt64Array.BYTES_PER_ELEMENT as int
5612        }
5613        this.byteLength = intByteLength
5614        this.byteOffset = intByteOffset
5615        this.lengthInt = intLength
5616        this.buffer = buf
5617    }
5618
5619    /**
5620     * Creates an BigInt64Array with respect to data, byteOffset and length.
5621     *
5622     * @param buf data initializer
5623     *
5624     * @param byteOffset byte offset from begin of the buf
5625     *
5626     * @param length size of elements of type long in newly created BigInt64Array
5627     */
5628    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
5629        this(buf, byteOffset, undefined)
5630    }
5631
5632    /**
5633     * Creates an BigInt64Array with respect to data, byteOffset and length.
5634     *
5635     * @param buf data initializer
5636     *
5637     * @param byteOffset byte offset from begin of the buf
5638     *
5639     * @param length size of elements of type long in newly created BigInt64Array
5640     */
5641    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
5642        this(buf, new Number(byteOffset), new Number(length))
5643    }
5644
5645    /**
5646     * Creates an BigInt64Array with respect to data, byteOffset and length.
5647     *
5648     * @param buf data initializer
5649     *
5650     * @param byteOffset byte offset from begin of the buf
5651     *
5652     * @param length size of elements of type long in newly created BigInt64Array
5653     */
5654    public constructor(buf: ArrayBuffer, byteOffset: number) {
5655        this(buf, new Number(byteOffset), undefined)
5656    }
5657
5658    /**
5659     * Creates an BigInt64Array with respect to data, byteOffset and length.
5660     *
5661     * @param buf data initializer
5662     *
5663     * @param byteOffset byte offset from begin of the buf
5664     *
5665     * @param length size of elements of type long in newly created BigInt64Array
5666     */
5667    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
5668        this(buf, new Number(byteOffset), new Number(length))
5669    }
5670
5671    /**
5672     * Creates an BigInt64Array with respect to buf and byteOffset.
5673     *
5674     * @param buf data initializer
5675     *
5676     * @param byteOffset byte offset from begin of the buf
5677     */
5678    public constructor(buf: ArrayBuffer, byteOffset: int) {
5679        this(buf, new Number(byteOffset), undefined)
5680    }
5681
5682    /**
5683     * Creates an BigInt64Array with respect to buf.
5684     *
5685     * @param buf data initializer
5686     */
5687    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
5688        if (buf instanceof ArrayBuffer) {
5689            this.byteLength = (buf as ArrayBuffer).getByteLength()
5690            if (this.byteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
5691               throw new RangeError("ArrayBuffer.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
5692            }
5693            this.lengthInt = this.byteLength / BigInt64Array.BYTES_PER_ELEMENT as int
5694            this.buffer = buf as ArrayBuffer
5695            this.byteOffset = 0
5696        } else if (buf instanceof ArrayLike) {
5697            // NOTE (ikorobkov): dealing with this overload is tricky
5698            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
5699            let arr = Array.from<Number>((buf as ArrayLike<Number>))
5700            this.byteLength = arr.length as int * BigInt64Array.BYTES_PER_ELEMENT as int
5701            this.lengthInt = arr.length as int
5702            this.buffer = new ArrayBuffer(this.byteLength as int)
5703            this.byteOffset = 0
5704            for (let i: int = 0; i < this.lengthInt; ++i) {
5705                this.setUnsafe(i, arr.$_get(i).toLong())
5706            }
5707        } else {
5708            throw new Error("unexpected type of buf")
5709        }
5710    }
5711
5712    /**
5713     * Creates an BigInt64Array with respect to length.
5714     *
5715     * @param length data initializer
5716     */
5717    public constructor(length: int) {
5718        this(length as number)
5719    }
5720
5721    /**
5722     * Creates an BigInt64Array with respect to length.
5723     *
5724     * @param length data initializer
5725     */
5726    public constructor(length: number) {
5727        if (length < 0 || length > (Int.MAX_VALUE / BigInt64Array.BYTES_PER_ELEMENT)) {
5728            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
5729        }
5730        this.lengthInt = length as int
5731        this.byteLength = this.lengthInt * BigInt64Array.BYTES_PER_ELEMENT as int
5732        this.byteOffset = 0
5733        this.buffer = new ArrayBuffer(this.byteLength as int)
5734    }
5735
5736    /**
5737     * Creates a copy of BigInt64Array.
5738     *
5739     * @param other data initializer
5740     */
5741    public constructor(other: BigInt64Array) {
5742        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
5743        this.byteLength = other.byteLength
5744        this.lengthInt = other.length as int
5745        this.byteOffset = 0
5746    }
5747
5748    /**
5749     * Creates an BigInt64Array from FixedArray<number>
5750     */
5751    public constructor(numbers: FixedArray<number>) {
5752        this(numbers.length)
5753        for (let i: int = 0; i < this.lengthInt; ++i) {
5754            this.setUnsafe(i, numbers[i] as long)
5755        }
5756    }
5757
5758    /**
5759     * Creates an BigInt64Array from FixedArray<int>
5760     */
5761    public constructor(numbers: FixedArray<int>) {
5762        this(numbers.length)
5763        for (let i: int = 0; i < this.lengthInt; ++i) {
5764            this.setUnsafe(i, numbers[i] as long)
5765        }
5766    }
5767
5768    /**
5769     * Creates an BigInt64Array from FixedArray<bigint>
5770     */
5771    public constructor(numbers: FixedArray<bigint>) {
5772        this(numbers.length)
5773        for (let i: int = 0; i < this.lengthInt; ++i) {
5774            this.setUnsafe(i, numbers[i].getLong())
5775        }
5776    }
5777
5778    /**
5779     * Assigns val as element on index.
5780     *
5781     * @param val value to set
5782     *
5783     * @param index index to change
5784     */
5785    public $_set(index: number, val: BigInt): void {
5786        this.$_set(index as int, val)
5787    }
5788
5789    /**
5790     * Assigns val as element on index.
5791     *
5792     * @param val value to set
5793     *
5794     * @param index index to change
5795     */
5796    public $_set(index: int, val: BigInt): void {
5797        this.$_set(index, val.getLong())
5798    }
5799
5800    /**
5801     * Assigns val as element on index.
5802     *
5803     * @param val value to set
5804     *
5805     * @param index index to change
5806     */
5807    public $_set(index: number, val: long): void {
5808        this.$_set(index as int, val)
5809    }
5810
5811    /**
5812     * Assigns val as element on index.
5813     *
5814     * @param val value to set
5815     *
5816     * @param index index to change
5817     */
5818    public native $_set(index: int, val: long): void
5819
5820    /** Number of long stored in BigInt64Array */
5821    public get length(): number {
5822        return this.lengthInt
5823    }
5824
5825    /**
5826     * Returns an instance of BigInt at passed index.
5827     *
5828     * @param index index to look at
5829     *
5830     * @returns a primitive at index
5831     */
5832    public override $_get(index: number): BigInt {
5833        return this.$_get(index as int) as BigInt
5834    }
5835
5836    /**
5837     * Returns an instance of BigInt at passed index.
5838     *
5839     * @param index index to look at
5840     *
5841     * @returns a primitive at index
5842     */
5843    public $_get(index: int): BigInt {
5844        return new BigInt(this.getLong(index))
5845    }
5846
5847    private native getLong(index: int): long
5848
5849    /**
5850     * Returns an instance of primitive type at passed index.
5851     *
5852     * @param index index to look at
5853     *
5854     * @returns a primitive at index
5855     */
5856    public at(index: number): BigInt | undefined {
5857        return this.at(index as int)
5858    }
5859
5860    /**
5861     * Returns an instance of primitive type at passed index.
5862     *
5863     * @param index index to look at
5864     *
5865     * @returns a primitive at index
5866     */
5867    public at(index: int): BigInt | undefined {
5868        let k: int
5869        if (index >= 0) {
5870            k = index
5871        } else {
5872            k = this.lengthInt + index
5873        }
5874        if (k < 0 || k >= this.lengthInt) {
5875            return undefined
5876        }
5877        return new BigInt(this.getUnsafe(k))
5878    }
5879
5880    /**
5881     * Makes a copy of internal elements to targetPos from startPos to endPos.
5882     *
5883     * @param target insert index to place copied elements
5884     *
5885     * @param start start index to begin copy from
5886     *
5887     * @param end last index to end copy from, excluded
5888     *
5889     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5890     */
5891    public copyWithin(target: number, start: number, end?: number): BigInt64Array {
5892        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5893    }
5894
5895    /**
5896     * Makes a copy of internal elements to targetPos from startPos to endPos.
5897     *
5898     * @param target insert index to place copied elements
5899     *
5900     * @param start start index to begin copy from
5901     *
5902     * @param end last index to end copy from, excluded
5903     *
5904     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5905     */
5906    public copyWithin(target: int, start: number, end?: number): BigInt64Array {
5907        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5908    }
5909
5910    /**
5911     * Makes a copy of internal elements to targetPos from startPos to endPos.
5912     *
5913     * @param target insert index to place copied elements
5914     *
5915     * @param start start index to begin copy from
5916     *
5917     * @param end last index to end copy from, excluded
5918     *
5919     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5920     */
5921    public copyWithin(target: number, start: int, end?: number): BigInt64Array {
5922        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5923    }
5924
5925    /**
5926     * Makes a copy of internal elements to targetPos from startPos to endPos.
5927     *
5928     * @param target insert index to place copied elements
5929     *
5930     * @param start start index to begin copy from
5931     *
5932     * @param end last index to end copy from, excluded
5933     *
5934     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5935     */
5936    public copyWithin(target: int, start: int, end?: number): BigInt64Array {
5937        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5938    }
5939
5940    /**
5941     * Makes a copy of internal elements to targetPos from startPos to endPos.
5942     *
5943     * @param target insert index to place copied elements
5944     *
5945     * @param start start index to begin copy from
5946     *
5947     * @param end last index to end copy from, excluded
5948     *
5949     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5950     */
5951    public native copyWithin(target: int, start: int, end: int): BigInt64Array
5952
5953    /**
5954     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
5955     *
5956     * @param target insert index to place copied elements
5957     *
5958     * See rules of parameters normalization:
5959     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5960     */
5961    public copyWithin(target: number): BigInt64Array {
5962        return this.copyWithin(target as int)
5963    }
5964
5965    /**
5966     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
5967     *
5968     * @param target insert index to place copied elements
5969     *
5970     * See rules of parameters normalization:
5971     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5972     */
5973    public copyWithin(target: int): BigInt64Array {
5974        return this.copyWithin(target, 0, this.lengthInt)
5975    }
5976
5977    /**
5978     * Returns an array of key, value pairs for every entry in the BigInt64Array
5979     *
5980     * @returns key, value pairs for every entry in the array
5981     */
5982    public entries(): IterableIterator<[Number, BigInt]> {
5983        return new BigInt64ArrayIteratorEntries(this)
5984    }
5985
5986    /**
5987     * Fills the BigInt64Array with specified value
5988     *
5989     * @param value new valuy
5990     *
5991     * @returns modified BigInt64Array
5992     */
5993    public fill(value: BigInt, start?: number, end?: number): this {
5994        this.fill(value.getLong(), asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
5995        return this
5996    }
5997
5998    /**
5999     * Fills the BigInt64Array with specified value
6000     *
6001     * @param value new valuy
6002     *
6003     * @returns modified BigInt64Array
6004     */
6005    public fill(value: BigInt, start: int, end?: number): this {
6006        this.fill(value.getLong(), start as int, asIntOrDefault(end, this.lengthInt))
6007        return this
6008    }
6009
6010    /**
6011     * Fills the BigInt64Array with specified value
6012     *
6013     * @param value new valuy
6014     *
6015     * @returns modified BigInt64Array
6016     */
6017    public fill(value: BigInt, start: int, end: number): this {
6018        this.fill(value.getLong(), start as int, end as int)
6019        return this
6020    }
6021
6022    /**
6023     * Fills the BigInt64Array with specified value
6024     *
6025     * @param value new valuy
6026     *
6027     * @returns modified BigInt64Array
6028     */
6029    public fill(value: BigInt, start: number, end: int): this {
6030        this.fill(value.getLong(), start as int, end as int)
6031        return this
6032    }
6033
6034    /**
6035     * Fills the BigInt64Array with specified value
6036     *
6037     * @param value new valuy
6038     *
6039     * @returns modified BigInt64Array
6040     */
6041    public fill(value: BigInt, start: int, end: int): this {
6042        this.fill(value.getLong(), start as int, end as int)
6043        return this
6044    }
6045
6046    /**
6047     * Fills the BigInt64Array with specified value
6048     *
6049     * @param value new valuy
6050     *
6051     * @returns modified BigInt64Array
6052     */
6053    public fill(value: long, start?: number, end?: number): this {
6054        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
6055        return this
6056    }
6057
6058    /**
6059     * Fills the BigInt64Array with specified value
6060     *
6061     * @param value new valuy
6062     *
6063     * @returns modified BigInt64Array
6064     */
6065    public fill(value: long, start: int, end?: number): this {
6066        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
6067        return this
6068    }
6069
6070    /**
6071     * Fills the BigInt64Array with specified value
6072     *
6073     * @param value new valuy
6074     *
6075     * @returns modified BigInt64Array
6076     */
6077    public fill(value: long, start: int, end: number): this {
6078        this.fill(value, start as int, end as int)
6079        return this
6080    }
6081
6082    /**
6083     * Fills the BigInt64Array with specified value
6084     *
6085     * @param value new valuy
6086     *
6087     * @returns modified BigInt64Array
6088     */
6089    public fill(value: long, start: number, end: int): this {
6090        this.fill(value, start as int, end as int)
6091        return this
6092    }
6093
6094    /**
6095     * Fills the BigInt64Array with specified value
6096     *
6097     * @param value new valuy
6098     *
6099     * @returns modified BigInt64Array
6100     */
6101    public fill(value: long, start: int, end: int): this {
6102        const k = normalizeIndex(start, this.lengthInt)
6103        const finalPos = normalizeIndex(end, this.lengthInt)
6104        this.fillInternal(value, k, finalPos)
6105        return this
6106    }
6107
6108    private final native fillInternal(value: long, start: int, end: int): void
6109
6110    /**
6111     * Assigns val as element on insertPos.
6112     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<long>, insertPos)
6113     *
6114     * @param val value to set
6115     *
6116     * @param insertPos index to change
6117     */
6118    public set(insertPos: number, val: BigInt): void {
6119        this.$_set(insertPos, val)
6120    }
6121
6122    /**
6123     * Assigns val as element on insertPos.
6124     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<long>, insertPos)
6125     *
6126     * @param val value to set
6127     *
6128     * @param insertPos index to change
6129     */
6130    public set(insertPos: int, val: long): void {
6131        this.$_set(insertPos, val)
6132    }
6133
6134    /**
6135     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
6136     *
6137     * @param arr array to copy data from
6138     *
6139     * @param insertPos start index where data from arr will be inserted
6140     *
6141     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
6142     */
6143    public set(arr: FixedArray<BigInt>, insertPos: number): void {
6144        const offset = insertPos as int
6145        if (offset < 0 || offset + arr.length > this.lengthInt) {
6146            throw new RangeError("offset is out of bounds")
6147        }
6148        for (let i = 0; i < arr.length as int; ++i) {
6149            let truncatedVal: BigInt = BigInt.asIntN(64, arr[i])
6150            this.$_set(offset + i, truncatedVal.getLong())
6151        }
6152    }
6153
6154    /**
6155     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
6156     *
6157     * @param arr array to copy data from
6158     *
6159     * @param insertPos start index where data from arr will be inserted
6160     *
6161     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
6162     */
6163    public set(arr: FixedArray<long>, insertPos: int): void {
6164        const offset = insertPos as int
6165        if (offset < 0 || offset + arr.length > this.lengthInt) {
6166            throw new RangeError("offset is out of bounds")
6167        }
6168        for (let i = 0; i < arr.length as int; ++i) {
6169            this.$_set(offset + i, arr[i])
6170        }
6171    }
6172
6173    /**
6174     * Copies all elements of arr to the current BigInt64Array.
6175     *
6176     * @param arr array to copy data from
6177     */
6178    public set(arr: FixedArray<BigInt>): void {
6179        this.set(arr, 0 as number)
6180    }
6181
6182    /**
6183     * Copies all elements of arr to the current BigInt64Array.
6184     *
6185     * @param arr array to copy data from
6186     */
6187    public set(arr: FixedArray<long>): void {
6188        this.set(arr, 0 as int)
6189    }
6190
6191    public native set(array: BigInt64Array): void
6192
6193    public native set(array: BigInt64Array, offset: number): void
6194
6195    /**
6196     * Copies elements from an ArrayLike object to the BigInt64Array.
6197     *
6198     * @param array An ArrayLike object containing the elements to copy.
6199     *
6200     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
6201     */
6202    public set(array: ArrayLike<BigInt>, offset: number = 0): void {
6203        const insertPos = offset as int
6204        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
6205            throw new RangeError("offset is out of bounds")
6206        }
6207        for (let i = array.length - 1 as int; i >= 0; --i) {
6208            let truncatedVal: BigInt = BigInt.asIntN(64, array[i])
6209            this.$_set(offset + i, truncatedVal.getLong())
6210        }
6211    }
6212
6213    /**
6214     * Returns a new array from a set of elements.
6215     *
6216     * @param items a set of elements to include in the new array object.
6217     *
6218     * @returns new BigInt64Array
6219     */
6220    public static of(...items: FixedArray<number>): BigInt64Array {
6221        let res = new BigInt64Array(items.length as int)
6222        for (let i: int = 0; i < items.length; i++) {
6223            res.setUnsafe(i, items[i] as long)
6224        }
6225        return res
6226    }
6227
6228    /**
6229     * Returns a new array from a set of elements.
6230     *
6231     * @param items a set of elements to include in the new array object.
6232     *
6233     * @returns new BigInt64Array
6234     */
6235    public static of(...items: FixedArray<int>): BigInt64Array {
6236        let res = new BigInt64Array(items.length as int)
6237        for (let i: int = 0; i < items.length; i++) {
6238            res.setUnsafe(i, items[i] as long)
6239        }
6240        return res
6241    }
6242
6243    /**
6244     * Returns a new array from a set of elements.
6245     *
6246     * @param items a set of elements to include in the new array object.
6247     *
6248     * @returns new BigInt64Array
6249     */
6250    public static of(...items: FixedArray<long>): BigInt64Array {
6251        let res = new BigInt64Array(items.length as int)
6252        for (let i: int = 0; i < items.length; i++) {
6253            res.setUnsafe(i, items[i])
6254        }
6255        return res
6256    }
6257
6258    /**
6259     * Returns a new array from a set of elements.
6260     *
6261     * @param items a set of elements to include in the new array object.
6262     *
6263     * @returns new BigInt64Array
6264     */
6265    public static of(...items: FixedArray<bigint>): BigInt64Array {
6266        let res = new BigInt64Array(items.length as int)
6267        for (let i: int = 0; i < items.length; i++) {
6268            res.setUnsafe(i, items[i].getLong())
6269        }
6270        return res
6271    }
6272
6273    /**
6274     * Returns a new array from a set of elements.
6275     *
6276     * @param items a set of elements to include in the new array object.
6277     *
6278     * @returns new BigInt64Array
6279     */
6280    public static of(): BigInt64Array {
6281        return new BigInt64Array(0 as int)
6282    }
6283
6284    /**
6285     * Creates an array from an array-like or iterable object.
6286     *
6287     * @param arrayLike An array-like or iterable object to convert to an array.
6288     *
6289     * @returns new BigInt64Array
6290     */
6291    public static from(arrayLike: ArrayLike<number>): BigInt64Array {
6292        throw new Error("BigInt64Array.from: not implemented")
6293    }
6294
6295    /**
6296     * Creates an array from an array-like or iterable object.
6297     *
6298     * @param arrayLike An array-like or iterable object to convert to an array.
6299     *
6300     * @param mapfn A mapping function to call on every element of the array.
6301     *
6302     * @returns new BigInt64Array
6303     */
6304    public static from(arrayLike: Iterable<BigInt>, mapfn?: (v: BigInt, k: number) => BigInt): BigInt64Array {
6305        if (mapfn == undefined) {
6306            mapfn = (v: BigInt, k: number): BigInt => { return v }
6307        }
6308
6309        let iter = arrayLike.$_iterator()
6310        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
6311        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
6312        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
6313        //  we can make one pass through the iterator without the need for memory reallocation.
6314        const maybeLength = tryGetIteratorLength(arrayLike)
6315        if (maybeLength) {
6316            const result = new BigInt64Array(maybeLength)
6317            for (let i = 0; i < maybeLength; ++i) {
6318                const x = iter.next()
6319                if (x.done) {
6320                    return new BigInt64Array(result.buffer, 0, i)
6321                }
6322                result.setUnsafe(i, (mapfn)!(x.value!, i).getLong())
6323            }
6324            return result
6325        }
6326
6327        // NOTE (templin.konstantin): Create builtin array as buffer
6328        let temp = new BigInt64Array(6)
6329        let index : FixedArray<int> = new int[1]
6330        index[0] = 0
6331
6332        iteratorForEach<BigInt>(iter, (x: BigInt): void => {
6333            if (index[0] + 1 > temp.lengthInt) {
6334                // NOTE (templin.konstantin): Progressive reallocation
6335                const curLength = (temp.buffer as Buffer).getByteLength()
6336                const tb = new ArrayBuffer(curLength * 2)
6337                for (let i = 0; i < curLength; ++i) {
6338                    tb.set(i, (temp.buffer as Buffer).at(i))
6339                }
6340                temp = new BigInt64Array(tb)
6341            }
6342            temp.setUnsafe(index[0], (mapfn)!(x, index[0]).getLong())
6343            index[0]++
6344        })
6345        return new BigInt64Array(temp.buffer, 0, index[0])
6346    }
6347
6348
6349    /**
6350     * Creates an array from an array-like or iterable object.
6351     *
6352     * @param arrayLike An array-like or iterable object to convert to an array.
6353     *
6354     * @param mapfn A mapping function to call on every element of the array.
6355     *
6356     * @returns new BigInt64Array
6357     */
6358    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => BigInt): BigInt64Array {
6359        let res = new BigInt64Array(arrayLike.length)
6360        // 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
6361        const idx : FixedArray<int> = new int[1]
6362        idx[0] = 0
6363        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
6364            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number).getLong())
6365            idx[0] += 1
6366        })
6367        return res
6368    }
6369
6370    /**
6371     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
6372     *
6373     * @param searchElement The element to search for
6374     *
6375     * @param fromIndex The position in this array at which to begin searching for searchElement
6376     *
6377     * @returns true if searchElement is in BigInt64Array, false otherwise
6378     */
6379    public includes(searchElement: BigInt, fromIndex?: number): boolean {
6380        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
6381    }
6382
6383    /**
6384     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
6385     *
6386     * @param searchElement The element to search for
6387     *
6388     * @param fromIndex The position in this array at which to begin searching for searchElement
6389     *
6390     * @returns true if e is in BigInt64Array, false otherwise
6391     */
6392    public includes(searchElement: long, fromIndex: int): boolean {
6393        return this.indexOf(searchElement as int, fromIndex) != -1
6394    }
6395
6396    /**
6397     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
6398     *
6399     * @param searchElement The element to search for
6400     *
6401     * @param fromIndex The position in this array at which to begin searching for searchElement
6402     *
6403     * @returns true if searchElement is in BigInt64Array, false otherwise
6404     */
6405    public includes(searchElement: long): boolean {
6406        return this.includes(searchElement, 0)
6407    }
6408
6409    /**
6410     * Returns the index of the first occurrence of a value in BigInt64Array.
6411     *
6412     * @param searchElement The value to locate in the array.
6413     *
6414     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6415     *  search starts at index 0.
6416     *
6417     * @returns index of element if it presents, -1 otherwise
6418     */
6419    public indexOf(searchElement: BigInt, fromIndex?: number): number {
6420        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
6421    }
6422
6423    /**
6424     * Returns the index of the first occurrence of a value in BigInt64Array.
6425     *
6426     * @param searchElement The value to locate in the array.
6427     *
6428     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6429     *  search starts at index 0.
6430     *
6431     * @returns index of element if it presents, -1 otherwise
6432     */
6433    public indexOf(searchElement: BigInt, fromIndex: int): number {
6434            return this.indexOfImpl(searchElement.getLong(), fromIndex)
6435    }
6436
6437    /**
6438     * Returns the index of the first occurrence of a value in BigInt64Array.
6439     *
6440     * @param searchElement The value to locate in the array.
6441     *
6442     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6443     *  search starts at index 0.
6444     *
6445     * @returns index of element if it presents, -1 otherwise
6446     */
6447    public indexOf(searchElement: int, fromIndex: int): number {
6448        return this.indexOfImpl(searchElement as long, fromIndex)
6449    }
6450
6451    /**
6452     * Returns the index of the first occurrence of a value in BigInt64Array.
6453     *
6454     * @param searchElement The value to locate in the array.
6455     *
6456     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6457     *  search starts at index 0.
6458     *
6459     * @returns index of element if it presents, -1 otherwise
6460     */
6461    private final native indexOfImpl(searchElement: number, fromIndex: int): number
6462
6463    /**
6464     * Returns the index of the first occurrence of a value in BigInt64Array.
6465     *
6466     * @param searchElement The value to locate in the array.
6467     *
6468     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6469     *  search starts at index 0.
6470     *
6471     * @returns index of element if it presents, -1 otherwise
6472     */
6473    private final native indexOfImpl(searchElement: long, fromIndex: int): number
6474
6475    /**
6476     * Returns the index of the first occurrence of a value in BigInt64Array.
6477     *
6478     * @param searchElement The value to locate in the array.
6479     *
6480     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6481     *  search starts at index 0.
6482     *
6483     * @returns index of element if it presents, -1 otherwise
6484     */
6485    public indexOf(searchElement: int): number {
6486        return this.indexOf(searchElement, 0)
6487    }
6488
6489    /**
6490     * Converts all elements of an array to strings and joins them using the specified separator.
6491     *
6492     * @param separator - separates one element of an array from the next in the resulting String.
6493     *
6494     * @returns joined representation
6495     */
6496    private final native joinInternal(separator: String): string;
6497
6498    /**
6499     * Adds all the elements of an array separated by the specified separator string
6500     *
6501     * @param separator A string used to separate one element of an array from the next in the
6502     * resulting String. If omitted, the array elements are separated with a comma.
6503     *
6504     * @returns joined representation
6505     */
6506    public join(separator?: String): string {
6507        if (separator == undefined) {
6508            return this.joinInternal(",")
6509        }
6510        return this.joinInternal(separator)
6511    }
6512
6513    /**
6514     * Returns an list of keys in BigInt64Array
6515     *
6516     * @returns iterator over keys
6517     */
6518    public keys(): IterableIterator<number> {
6519        return new BigInt64ArrayIteratorKeys(this)
6520    }
6521
6522    /**
6523     * Returns the index of the last occurrence of a value in BigInt64Array.
6524     *
6525     * @param searchElement The value to locate in the array.
6526     *
6527     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6528     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6529     *
6530     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6531     */
6532    public lastIndexOf(searchElement: BigInt, fromIndex: number|undefined): number {
6533        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
6534    }
6535
6536    /**
6537     * Returns the index of the last occurrence of a value in BigInt64Array.
6538     *
6539     * @param searchElement The value to locate in the array.
6540     *
6541     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6542     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6543     *
6544     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6545     */
6546    public lastIndexOf(searchElement: BigInt): number {
6547        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6548    }
6549
6550    /**
6551     * Returns the index of the last occurrence of a value in BigInt64Array.
6552     *
6553     * @param searchElement The value to locate in the array.
6554     *
6555     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6556     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6557     *
6558     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6559     */
6560    public lastIndexOf(searchElement: BigInt, fromIndex: int): number {
6561            return this.lastIndexOfImpl(searchElement.getLong(), fromIndex)
6562    }
6563
6564    /**
6565     * Returns the index of the last occurrence of a value in BigInt64Array.
6566     *
6567     * @param searchElement The value to locate in the array.
6568     *
6569     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6570     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6571     *
6572     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6573     */
6574    public lastIndexOf(searchElement: int, fromIndex: int): number {
6575        return this.lastIndexOfImpl(searchElement as long, fromIndex)
6576    }
6577
6578    /**
6579     * Returns the index of the last occurrence of a value in BigInt64Array.
6580     *
6581     * @param searchElement The value to locate in the array.
6582     *
6583     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6584     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6585     *
6586     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6587     */
6588    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
6589
6590    /**
6591     * Returns the index of the last occurrence of a value in BigInt64Array.
6592     *
6593     * @param searchElement The value to locate in the array.
6594     *
6595     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6596     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6597     *
6598     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6599     */
6600    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
6601
6602    /**
6603     * Returns the index of the last occurrence of a value in BigInt64Array.
6604     *
6605     * @param searchElement The value to locate in the array.
6606     *
6607     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6608     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6609     *
6610     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6611     */
6612    public lastIndexOf(searchElement: int): number {
6613        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6614    }
6615
6616    /**
6617    * Creates a new BigInt64Array using initializer
6618    *
6619    * @param data initializer
6620    *
6621    * @returns a new BigInt64Array from data
6622    */
6623    public of(data: FixedArray<Object>): BigInt64Array {
6624        throw new Error("BigInt64Array.of: not implemented")
6625    }
6626
6627    /**
6628     * Creates a new BigInt64Array using reversed data from the current one
6629     *
6630     * @returns a new BigInt64Array using reversed data from the current one
6631     */
6632    public native reverse(): BigInt64Array
6633
6634    /**
6635     * Creates a slice of current BigInt64Array using range [begin, end)
6636     *
6637     * @param begin start index to be taken into slice
6638     *
6639     * @param end last index to be taken into slice
6640     *
6641     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
6642     *
6643     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6644     */
6645    public slice(begin?: number, end?: number): BigInt64Array {
6646        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6647    }
6648
6649    /**
6650     * Creates a slice of current BigInt64Array using range [begin, end)
6651     *
6652     * @param begin start index to be taken into slice
6653     *
6654     * @param end last index to be taken into slice
6655     *
6656     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
6657     *
6658     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6659     */
6660    public slice(begin: number, end: number): BigInt64Array {
6661        return this.slice(begin as int, end as int)
6662    }
6663
6664    /**
6665     * Creates a slice of current BigInt64Array using range [begin, end)
6666     *
6667     * @param begin start index to be taken into slice
6668     *
6669     * @param end last index to be taken into slice
6670     *
6671     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
6672     *
6673     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6674     */
6675    public slice(begin: number, end: int): BigInt64Array {
6676        return this.slice(begin as int, end as int)
6677    }
6678
6679    /**
6680     * Creates a slice of current BigInt64Array using range [begin, end)
6681     *
6682     * @param begin start index to be taken into slice
6683     *
6684     * @param end last index to be taken into slice
6685     *
6686     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
6687     *
6688     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6689     */
6690    public slice(begin: int, end: number): BigInt64Array {
6691        return this.slice(begin as int, end as int)
6692    }
6693
6694    /**
6695     * Creates a slice of current BigInt64Array using range [begin, end)
6696     *
6697     * @param begin start index to be taken into slice
6698     *
6699     * @param end last index to be taken into slice
6700     *
6701     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
6702     *
6703     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6704     */
6705    public slice(begin: int, end: int): BigInt64Array {
6706        const len: int = this.lengthInt
6707        const relStart = normalizeIndex(begin, len)
6708        const relEnd = normalizeIndex(end, len)
6709        let count = relEnd - relStart
6710        if (count < 0) {
6711            count = 0
6712        }
6713        let buf = this.buffer.slice(relStart * BigInt64Array.BYTES_PER_ELEMENT as int, relEnd * BigInt64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
6714        return new BigInt64Array(buf)
6715    }
6716
6717    /**
6718     * Creates a slice of current BigInt64Array using range [begin, this.length).
6719     *
6720     * @param begin start index to be taken into slice
6721     *
6722     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
6723     */
6724    public slice(begin: number): BigInt64Array {
6725        return this.slice(begin as int)
6726    }
6727
6728    /**
6729     * Creates a slice of current BigInt64Array using range [begin, this.length).
6730     *
6731     * @param begin start index to be taken into slice
6732     *
6733     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
6734     */
6735    public slice(begin: int): BigInt64Array {
6736        return this.slice(begin, this.lengthInt)
6737    }
6738
6739    /**
6740     * Creates a BigInt64Array with the same underlying ArrayBuffer
6741     *
6742     * @param begin start index, inclusive
6743     *
6744     * @param end last index, exclusive
6745     *
6746     * @returns new BigInt64Array with the same underlying ArrayBuffer
6747     */
6748    public subarray(begin?: number, end?: number): BigInt64Array {
6749        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6750    }
6751
6752    /**
6753     * Creates a BigInt64Array with the same underlying ArrayBuffer
6754     *
6755     * @param begin start index, inclusive
6756     *
6757     * @param end last index, exclusive
6758     *
6759     * @returns new BigInt64Array with the same underlying ArrayBuffer
6760     */
6761    public subarray(begin: number, end: number): BigInt64Array {
6762        return this.subarray(begin as int, end as int)
6763    }
6764
6765    /**
6766     * Creates a BigInt64Array with the same underlying ArrayBuffer
6767     *
6768     * @param begin start index, inclusive
6769     *
6770     * @param end last index, exclusive
6771     *
6772     * @returns new BigInt64Array with the same underlying ArrayBuffer
6773     */
6774    public subarray(begin: number, end: int): BigInt64Array {
6775        return this.subarray(begin as int, end as int)
6776    }
6777
6778    /**
6779     * Creates a BigInt64Array with the same underlying ArrayBuffer
6780     *
6781     * @param begin start index, inclusive
6782     *
6783     * @param end last index, exclusive
6784     *
6785     * @returns new BigInt64Array with the same underlying ArrayBuffer
6786     */
6787    public subarray(begin: int, end: number): BigInt64Array {
6788        return this.subarray(begin as int, end as int)
6789    }
6790
6791    /**
6792     * Creates a BigInt64Array with the same underlying ArrayBuffer
6793     *
6794     * @param begin start index, inclusive
6795     *
6796     * @param end last index, exclusive
6797     *
6798     * @returns new BigInt64Array with the same underlying ArrayBuffer
6799     */
6800    public subarray(begin: int, end: int | undefined = this.lengthInt): BigInt64Array {
6801        const len: int = this.lengthInt
6802        const relStart = normalizeIndex(begin, len)
6803        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
6804        let count = relEnd - relStart
6805        if (count < 0) {
6806            count = 0
6807        }
6808        return new BigInt64Array(this.buffer, relStart * BigInt64Array.BYTES_PER_ELEMENT as int, count)
6809    }
6810
6811    /**
6812     * Converts BigInt64Array to a string with respect to locale
6813     *
6814     * @param locales
6815     *
6816     * @param options
6817     *
6818     * @returns string representation
6819     */
6820    public toLocaleString(locales: Object, options: Object): string {
6821        throw new Error("BigInt64Array.toLocaleString: not implemented")
6822    }
6823
6824    /**
6825     * Converts BigInt64Array to a string with respect to locale
6826     *
6827     * @param locales
6828     *
6829     * @returns string representation
6830     */
6831    public toLocaleString(locales: Object): string {
6832        return this.toLocaleString(new Object(), new Object())
6833    }
6834
6835    /**
6836     * Converts BigInt64Array to a string with respect to locale
6837     *
6838     * @returns string representation
6839     */
6840    public toLocaleString(): string {
6841        let res: StringBuilder = new StringBuilder("")
6842        for (let i = 0; i < this.lengthInt - 1; ++i) {
6843            res.append(new BigInt(this.getUnsafe(i)).toLocaleString())
6844            res.append(",")
6845        }
6846        if (this.lengthInt > 0) {
6847            res.append(new BigInt(this.getUnsafe(this.lengthInt - 1)).toLocaleString())
6848        }
6849        return res.toString()
6850    }
6851
6852    /**
6853     * Creates a reversed copy
6854     *
6855     * @returns a reversed copy
6856     */
6857    public final native toReversed(): BigInt64Array
6858
6859    /**
6860     * Creates a sorted copy
6861     *
6862     * @returns a sorted copy
6863     */
6864    public toSorted(): BigInt64Array {
6865        return new BigInt64Array(this).sort()
6866    }
6867
6868    /**
6869     * Returns a string representation of the BigInt64Array
6870     *
6871     * @returns a string representation of the BigInt64Array
6872     */
6873    public override toString(): string {
6874        return this.join(",")
6875    }
6876
6877    /**
6878     * Returns array values iterator
6879     *
6880     * @returns an iterator
6881     */
6882    public values(): IterableIterator<BigInt> {
6883        return new BigInt64ArrayIterator(this)
6884    }
6885
6886    /**
6887     * Iteratorable interface implementation
6888     *
6889     * @returns iterator over all elements
6890     */
6891    public override $_iterator(): IterableIterator<BigInt> {
6892        return this.values()
6893    }
6894
6895    /**
6896     * Creates a copy with replaced value on index
6897     *
6898     * @param index
6899     *
6900     * @param value
6901     *
6902     * @returns an BigInt64Array with replaced value on index
6903     */
6904    public with(index: number, value: BigInt): BigInt64Array {
6905        return this.with(index as int, value.getLong())
6906    }
6907
6908    /**
6909     * Creates a copy with replaced value on index
6910     *
6911     * @param index
6912     *
6913     * @param value
6914     *
6915     * @returns an BigInt64Array with replaced value on index
6916     */
6917    public with(index: int, value: long): BigInt64Array {
6918        let res = new BigInt64Array(this)
6919        res.set(index, value)
6920        return res
6921    }
6922
6923    /// === with element lambda functions ===
6924
6925    /**
6926     * Finds the last element in the BigInt64Array that satisfies the condition
6927     *
6928     * @param fn condition
6929     *
6930     * @returns the last element that satisfies fn
6931     */
6932    public findLast(fn: (val: BigInt) => boolean): BigInt {
6933        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
6934            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
6935        return new BigInt(this.findLast(newF))
6936    }
6937
6938    /**
6939     * Sorts in-place by numeric value in ascending order.
6940     *
6941     * @returns sorted BigInt64Array
6942     */
6943    public native sort(): this;
6944
6945    /**
6946     * Sorts in-place
6947     *
6948     * @param compareFn comparator _  used to determine the order of the elements.
6949     * compareFn returns a negative value if first argument is less than second argument,
6950     * zero if they're equal and a positive value otherwise.
6951     *
6952     * @returns sorted BigInt64Array
6953     */
6954    public sort(compareFn?: (a: BigInt, b: BigInt) => number | BigInt): this {
6955        if (compareFn == undefined) {
6956            this.sort()
6957            return this
6958        }
6959        let arr: FixedArray<long> = new long[this.lengthInt]
6960        for (let i = 0; i < this.lengthInt; ++i) {
6961            arr[i] = this.getUnsafe(i)
6962        }
6963
6964        let cmp = (l: long, r: long): number => {
6965            const result = compareFn!(new BigInt(l), new BigInt(r))
6966            if (result instanceof BigInt) {
6967                return (result as BigInt).getLong()
6968            } else {
6969                return result as number
6970            }
6971        }
6972        const MAX_SHORT_LENGTH = 24
6973        if (arr.length > MAX_SHORT_LENGTH) {
6974            arr = mergeSort(arr, cmp)
6975        } else {
6976            sort(arr, cmp)
6977        }
6978        for (let i = 0; i < arr.length; ++i) {
6979            this.setUnsafe(i, arr[i])
6980        }
6981        return this
6982    }
6983
6984    /**
6985     * Determines whether the specified callback function returns true for any element of an array.
6986     *
6987     * @param predicate A function that accepts three arguments.
6988     * The some method calls the predicate function for each element in the array
6989     * until the predicate returns a true or until the end of the array.
6990     *
6991     * @returns false unless predicate function returns true for an array element,
6992     * in which case true is immediately returned.
6993     */
6994    public some(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
6995        for (let i = 0; i < this.lengthInt; ++i) {
6996            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
6997                return true
6998            }
6999        }
7000        return false
7001    }
7002
7003    /**
7004     * Calls the specified callback function for all the elements in an array.
7005     * The return value of the callback function is the accumulated result,
7006     * and is provided as an argument in the next call to the callback function.
7007     *
7008     * @param callbackfn A function that accepts four arguments.
7009     * The reduce method calls the callbackfn function one time for each element in the array.
7010     *
7011     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7012     * The first call to the callbackfn function provides this value as an argument.
7013     *
7014     * @returns The value that results from running the callback function to completion over the entire typed array.
7015     */
7016    public reduce<U = BigInt>(
7017                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
7018                initialValue: U): U {
7019        let accumulatedValue = initialValue
7020        for (let i = 0; i < this.lengthInt; ++i) {
7021            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
7022        }
7023        return accumulatedValue
7024    }
7025
7026    /**
7027     * Calls the specified callback function for all the elements in an array.
7028     * The return value of the callback function is the accumulated result,
7029     * and is provided as an argument in the next call to the callback function.
7030     *
7031     * @param callbackfn A function that accepts four arguments.
7032     * The reduce method calls the callbackfn function one time for each element in the array.
7033     * The first call to the callbackfn function provides array first element value as an argument
7034     *
7035     * @returns The value that results from running the callback function to completion over the entire typed array.
7036     * calling reduce method on an empty array without an initial value creates a TypeError
7037     */
7038    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
7039        if (this.lengthInt == 0) {
7040            throw new TypeError("Reduce of empty array with no initial value")
7041        }
7042
7043        let accumulatedValue = new BigInt(this.getUnsafe(0))
7044        for (let i = 1; i < this.lengthInt; ++i) {
7045            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
7046        }
7047        return accumulatedValue
7048    }
7049
7050    /**
7051     * Calls the specified callback function for all the elements in an array, in descending order.
7052     * The return value of the callback function is the accumulated result,
7053     * and is provided as an argument in the next call to the callback function.
7054     *
7055     * @param callbackfn A function that accepts four arguments.
7056     * The reduceRight method calls the callbackfn function one time for each element in the array.
7057     *
7058     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7059     * The first call to the callbackfn function provides this value as an argument.
7060     *
7061     * @returns The value that results from running the callback function to completion over the entire typed array.
7062     */
7063    public reduceRight<U = BigInt>(
7064                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
7065                initialValue: U): U {
7066        let accumulatedValue = initialValue
7067        for (let i = this.lengthInt - 1; i >= 0; --i) {
7068            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
7069        }
7070        return accumulatedValue
7071    }
7072
7073
7074    /**
7075     * Calls the specified callback function for all the elements in an array, in descending order.
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 four arguments.
7080     * The reduceRight method calls the callbackfn function one time for each element in the array.
7081     * The first call to the callbackfn function provides array last element value as an argument
7082     *
7083     * @returns The value that results from running the callback function to completion over the entire typed array.
7084     * calling reduceRight method on an empty array without an initial value creates a TypeError
7085     */
7086    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
7087        if (this.lengthInt == 0) {
7088            throw new TypeError("Reduce of empty array with no initial value")
7089        }
7090
7091        let accumulatedValue: BigInt = new BigInt(this.getUnsafe(this.lengthInt - 1))
7092        for (let i = this.lengthInt - 2; i >= 0; --i) {
7093            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
7094        }
7095        return accumulatedValue
7096    }
7097
7098   /**
7099    * Creates a new BigInt64Array using fn(arr[i]) over all elements of current BigInt64Array.
7100    *
7101    * @param fn a function to apply for each element of current BigInt64Array
7102    *
7103    * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
7104    */
7105    public map(fn: (val: BigInt, index: number, array: BigInt64Array) => BigInt): BigInt64Array {
7106        let resBuf = new ArrayBuffer(this.lengthInt * BigInt64Array.BYTES_PER_ELEMENT as int)
7107        let res = new BigInt64Array(resBuf, 0, resBuf.getByteLength() / BigInt64Array.BYTES_PER_ELEMENT as int)
7108        for (let i = 0; i < this.lengthInt; ++i) {
7109            res.set(i, fn(new BigInt(this.getUnsafe(i)), i as number, this).getLong())
7110        }
7111        return res
7112    }
7113
7114    /**
7115     * Determines whether the specified callback function returns true for all elements of an array.
7116     *
7117     * @param predicate A function that accepts three arguments.
7118     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7119     * or until the end of the array.
7120     *
7121     * @returns true unless predicate function returns a false for an array element,
7122     * in which case false is immediately returned.
7123     */
7124    public every(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
7125        for (let i = 0; i < this.lengthInt; ++i) {
7126            if (!predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
7127                return false
7128            }
7129        }
7130        return true
7131    }
7132
7133    /**
7134     * Creates a new BigInt64Array from current BigInt64Array based on a condition fn.
7135     *
7136     * @param fn the condition to apply for each element
7137     *
7138     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
7139     */
7140    public filter(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): BigInt64Array {
7141        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
7142        let resLen = 0
7143        for (let i = 0; i < this.lengthInt; ++i) {
7144            markers[i] = fn(new BigInt(this.getUnsafe(i)), i as number, this)
7145            if (markers[i]) {
7146                ++resLen
7147            }
7148        }
7149        let resBuf = new ArrayBuffer(resLen * BigInt64Array.BYTES_PER_ELEMENT as int)
7150        let res = new BigInt64Array(resBuf, 0)
7151        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
7152            if (markers[i]) {
7153                res.set(j, this.getUnsafe(i))
7154                ++j
7155            }
7156        }
7157        return res
7158    }
7159
7160    /**
7161     * Returns the value of the first element in the array where predicate is true, and undefined
7162     * otherwise
7163     *
7164     * @param predicate find calls predicate once for each element of the array, in ascending
7165     * order, until it finds one where predicate returns true. If such an element is found, find
7166     * immediately returns that element value. Otherwise, find returns undefined
7167     *
7168     * @returns BigInt | undefined
7169     */
7170    public find(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): BigInt | undefined {
7171        for (let i = 0; i < this.lengthInt; ++i) {
7172            let val = this.getUnsafe(i)
7173            if (predicate(new BigInt(val), i as number, this)) {
7174                return new BigInt(val)
7175            }
7176        }
7177        return undefined
7178    }
7179
7180    /**
7181     * Returns the index of the first element in the array where predicate is true, and -1
7182     * otherwise
7183     *
7184     * @param predicate find calls predicate once for each element of the array, in ascending
7185     * order, until it finds one where predicate returns true. If such an element is found,
7186     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7187     *
7188     * @returns number
7189     */
7190    public findIndex(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): number {
7191        for (let i = 0; i < this.lengthInt; ++i) {
7192            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
7193                return i as number
7194            }
7195        }
7196        return -1 as number
7197    }
7198
7199    /**
7200     * Finds the last element in the BigInt64Array that satisfies the condition
7201     *
7202     * @param fn condition
7203     *
7204     * @returns the last element that satisfies fn
7205     */
7206    public findLast(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): long {
7207        for (let i = this.lengthInt - 1; i >= 0; --i) {
7208            let val = this.getUnsafe(i)
7209            if (fn(new BigInt(val), i as number, this)) {
7210                return val
7211            }
7212        }
7213        throw new Error("BigInt64Array.findLast: not implemented if an element was not found")
7214    }
7215
7216    /**
7217     * Finds an index of the last element in the BigInt64Array that satisfies the condition
7218     *
7219     * @param fn condition
7220     *
7221     * @returns the index of the last element that satisfies fn, -1 otherwise
7222     */
7223    public findLastIndex(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): number {
7224        for (let i = this.lengthInt - 1; i >= 0; --i) {
7225            let val = this.getUnsafe(i)
7226            if (fn(new BigInt(val), i as number, this)) {
7227                return i
7228            }
7229        }
7230        return -1 as number
7231    }
7232
7233    /**
7234     * Performs the specified action for each element in BigInt64Array
7235     *
7236     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7237     * callbackfn function one time for each element in the array.
7238     *
7239     * @returns None
7240     */
7241    public forEach(callbackfn: (value: BigInt, index: number, array: BigInt64Array) => void): void {
7242        for (let i = 0; i < this.lengthInt; ++i) {
7243            callbackfn(new BigInt(this.getUnsafe(i)), i as number, this)
7244        }
7245    }
7246
7247    /**
7248     * Returns the object itself
7249     *
7250     * @returns BigInt64Array
7251     */
7252    public valueOf(): BigInt64Array {
7253        return this
7254    }
7255
7256    private final native getUnsafe(index: int): long
7257
7258    internal setUnsafe(insertPos: int, val: long): void {
7259        let startByte = insertPos * BigInt64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
7260        let bits = val
7261        if (IS_LITTLE_ENDIAN) {
7262            for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
7263                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7264                this.buffer.set(startByte + i, byteVal)
7265            }
7266        } else {
7267            for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; i++) {
7268                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7269                this.buffer.set(startByte + 7 - i, byteVal)
7270            }
7271        }
7272    }
7273
7274    /** Underlying ArrayBuffer */
7275    public readonly buffer: ArrayBuffer
7276
7277    /** Byte offset within the underlying ArrayBuffer */
7278    public readonly byteOffset: number
7279
7280    /** Number of bytes used */
7281    public readonly byteLength: number
7282
7283    /** String \"BigInt64Array\" */
7284    public readonly name = "BigInt64Array"
7285}
7286
7287class Float32ArrayIteratorKeys implements IterableIterator<number> {
7288    private length: int
7289    private idx: int = 0
7290
7291    constructor(parent: Float32Array) {
7292        this.length = parent.length as int
7293    }
7294
7295    public override $_iterator(): IterableIterator<number> {
7296        return this
7297    }
7298
7299    override next(): IteratorResult<number> {
7300        if (this.idx < 0 || this.idx >= this.length) {
7301            return new IteratorResult<number>()
7302        }
7303        return new IteratorResult<number>(false, this.idx++ as number)
7304    }
7305}
7306
7307class Float32ArrayIterator implements IterableIterator<Number> {
7308    private parent: Float32Array
7309    private idx: int = 0
7310
7311    constructor(parent: Float32Array) {
7312        this.parent = parent
7313    }
7314
7315    public override $_iterator(): IterableIterator<Number> {
7316        return this
7317    }
7318
7319    override next(): IteratorResult<Number> {
7320        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7321            return new IteratorResult<Number>()
7322        }
7323        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
7324    }
7325}
7326
7327class Float32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
7328    private parent: Float32Array
7329    private idx: int = 0
7330
7331    constructor(parent: Float32Array) {
7332        this.parent = parent
7333    }
7334
7335    public override $_iterator(): IterableIterator<[Number, Number]> {
7336        return this
7337    }
7338
7339    override next(): IteratorResult<[Number, Number]> {
7340        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7341            return new IteratorResult<[Number, Number]>()
7342        }
7343        return new IteratorResult<[Number, Number]>(
7344            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
7345        )
7346    }
7347}
7348
7349
7350/**
7351 * JS Float32Array API-compatible class
7352 */
7353export final class Float32Array implements Iterable<Number>, ArrayLike<Number> {
7354    public static readonly BYTES_PER_ELEMENT: number = 4
7355    public readonly BYTES_PER_ELEMENT: number = Float32Array.BYTES_PER_ELEMENT
7356    internal readonly lengthInt: int
7357
7358    /**
7359     * Creates an empty Float32Array.
7360     */
7361    public constructor() {
7362        this(0 as int)
7363    }
7364
7365    /**
7366     * Creates an Float32Array with respect to data accessed via Iterable<Number> interface
7367     */
7368    public constructor(elements: Iterable<Number>) {
7369        const items: Object = elements as Object
7370        if (items instanceof ArrayLike) {
7371            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
7372            this.byteLength = arr.length as int * Float32Array.BYTES_PER_ELEMENT as int
7373            this.lengthInt = arr.length as int
7374            this.buffer = new ArrayBuffer(this.byteLength as int)
7375            this.byteOffset = 0
7376            for (let i: int = 0; i < this.lengthInt; ++i) {
7377                this.setUnsafe(i, arr.$_get(i).toFloat())
7378            }
7379        } else {
7380          let x = Float32Array.from(elements)
7381          this.byteLength = x.byteLength
7382          this.lengthInt = x.lengthInt
7383          this.buffer = x.buffer
7384          this.byteOffset = x.byteOffset
7385        }
7386    }
7387
7388    /**
7389     * Creates an Float32Array with respect to data, byteOffset and length.
7390     *
7391     * @param buf data initializer
7392     *
7393     * @param byteOffset byte offset from begin of the buf
7394     *
7395     * @param length size of elements of type float in newly created Float32Array
7396     */
7397    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
7398        let intByteOffset: int = 0
7399        if (byteOffset != undefined) {
7400            intByteOffset = byteOffset.toInt()
7401            if (intByteOffset < 0) {
7402                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
7403            }
7404        }
7405        let intByteLength: int = buf.getByteLength() - intByteOffset
7406        if (intByteLength < 0) {
7407            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
7408        }
7409
7410        if (intByteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
7411            throw new RangeError("ArrayBuffer.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
7412        }
7413        if (intByteOffset % Float32Array.BYTES_PER_ELEMENT as int != 0) {
7414            throw new RangeError("byteOffset should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
7415        }
7416
7417        let intLength: int
7418        if (length != undefined) {
7419            intLength = length.toInt()
7420            if (intLength > intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
7421                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
7422            }
7423        } else {
7424            intLength = intByteLength / Float32Array.BYTES_PER_ELEMENT as int
7425        }
7426        if (intLength < 0) {
7427            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
7428        }
7429        if (intLength < intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
7430            intByteLength = intLength * Float32Array.BYTES_PER_ELEMENT as int
7431        }
7432        this.byteLength = intByteLength
7433        this.byteOffset = intByteOffset
7434        this.lengthInt = intLength
7435        this.buffer = buf
7436    }
7437
7438    /**
7439     * Creates an Float32Array with respect to data, byteOffset and length.
7440     *
7441     * @param buf data initializer
7442     *
7443     * @param byteOffset byte offset from begin of the buf
7444     *
7445     * @param length size of elements of type float in newly created Float32Array
7446     */
7447    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
7448        this(buf, byteOffset, undefined)
7449    }
7450
7451    /**
7452     * Creates an Float32Array with respect to data, byteOffset and length.
7453     *
7454     * @param buf data initializer
7455     *
7456     * @param byteOffset byte offset from begin of the buf
7457     *
7458     * @param length size of elements of type float in newly created Float32Array
7459     */
7460    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
7461        this(buf, new Number(byteOffset), new Number(length))
7462    }
7463
7464    /**
7465     * Creates an Float32Array with respect to data, byteOffset and length.
7466     *
7467     * @param buf data initializer
7468     *
7469     * @param byteOffset byte offset from begin of the buf
7470     *
7471     * @param length size of elements of type float in newly created Float32Array
7472     */
7473    public constructor(buf: ArrayBuffer, byteOffset: number) {
7474        this(buf, new Number(byteOffset), undefined)
7475    }
7476
7477    /**
7478     * Creates an Float32Array with respect to data, byteOffset and length.
7479     *
7480     * @param buf data initializer
7481     *
7482     * @param byteOffset byte offset from begin of the buf
7483     *
7484     * @param length size of elements of type float in newly created Float32Array
7485     */
7486    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
7487        this(buf, new Number(byteOffset), new Number(length))
7488    }
7489
7490    /**
7491     * Creates an Float32Array with respect to buf and byteOffset.
7492     *
7493     * @param buf data initializer
7494     *
7495     * @param byteOffset byte offset from begin of the buf
7496     */
7497    public constructor(buf: ArrayBuffer, byteOffset: int) {
7498        this(buf, new Number(byteOffset), undefined)
7499    }
7500
7501    /**
7502     * Creates an Float32Array with respect to buf.
7503     *
7504     * @param buf data initializer
7505     */
7506    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
7507        if (buf instanceof ArrayBuffer) {
7508            this.byteLength = (buf as ArrayBuffer).getByteLength()
7509            if (this.byteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
7510               throw new RangeError("ArrayBuffer.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
7511            }
7512            this.lengthInt = this.byteLength / Float32Array.BYTES_PER_ELEMENT as int
7513            this.buffer = buf as ArrayBuffer
7514            this.byteOffset = 0
7515        } else if (buf instanceof ArrayLike) {
7516            // NOTE (ikorobkov): dealing with this overload is tricky
7517            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
7518            let arr = Array.from<Number>((buf as ArrayLike<Number>))
7519            this.byteLength = arr.length as int * Float32Array.BYTES_PER_ELEMENT as int
7520            this.lengthInt = arr.length as int
7521            this.buffer = new ArrayBuffer(this.byteLength as int)
7522            this.byteOffset = 0
7523            for (let i: int = 0; i < this.lengthInt; ++i) {
7524                this.setUnsafe(i, arr.$_get(i).toFloat())
7525            }
7526        } else {
7527            throw new Error("unexpected type of buf")
7528        }
7529    }
7530
7531    /**
7532     * Creates an Float32Array with respect to length.
7533     *
7534     * @param length data initializer
7535     */
7536    public constructor(length: int) {
7537        this(length as number)
7538    }
7539
7540    /**
7541     * Creates an Float32Array with respect to length.
7542     *
7543     * @param length data initializer
7544     */
7545    public constructor(length: number) {
7546        if (length < 0 || length > (Int.MAX_VALUE / Float32Array.BYTES_PER_ELEMENT)) {
7547            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
7548        }
7549        this.lengthInt = length as int
7550        this.byteLength = this.lengthInt * Float32Array.BYTES_PER_ELEMENT as int
7551        this.byteOffset = 0
7552        this.buffer = new ArrayBuffer(this.byteLength as int)
7553    }
7554
7555    /**
7556     * Creates a copy of Float32Array.
7557     *
7558     * @param other data initializer
7559     */
7560    public constructor(other: Float32Array) {
7561        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
7562        this.byteLength = other.byteLength
7563        this.lengthInt = other.length as int
7564        this.byteOffset = 0
7565    }
7566
7567    /**
7568     * Creates an Float32Array from FixedArray<number>
7569     */
7570    public constructor(numbers: FixedArray<number>) {
7571        this(numbers.length)
7572        for (let i: int = 0; i < this.lengthInt; ++i) {
7573            this.setUnsafe(i, numbers[i] as float)
7574        }
7575    }
7576
7577    /**
7578     * Creates an Float32Array from FixedArray<int>
7579     */
7580    public constructor(numbers: FixedArray<int>) {
7581        this(numbers.length)
7582        for (let i: int = 0; i < this.lengthInt; ++i) {
7583            this.setUnsafe(i, numbers[i] as float)
7584        }
7585    }
7586
7587    /**
7588     * Assigns val as element on index.
7589     *
7590     * @param val value to set
7591     *
7592     * @param index index to change
7593     */
7594    public $_set(index: number, val: number): void {
7595        this.$_set(index as int, val)
7596    }
7597
7598    /**
7599     * Assigns val as element on index.
7600     *
7601     * @param val value to set
7602     *
7603     * @param index index to change
7604     */
7605    public $_set(index: int, val: number): void {
7606        this.$_set(index, val as float)
7607    }
7608
7609    /**
7610     * Assigns val as element on index.
7611     *
7612     * @param val value to set
7613     *
7614     * @param index index to change
7615     */
7616    public $_set(index: number, val: float): void {
7617        this.$_set(index as int, val)
7618    }
7619
7620    /**
7621     * Assigns val as element on index.
7622     *
7623     * @param val value to set
7624     *
7625     * @param index index to change
7626     */
7627    public native $_set(index: int, val: float): void
7628
7629    /** Number of float stored in Float32Array */
7630    public get length(): number {
7631        return this.lengthInt
7632    }
7633
7634    /**
7635     * Returns an instance of number at passed index.
7636     *
7637     * @param index index to look at
7638     *
7639     * @returns a primitive at index
7640     */
7641    public override $_get(index: number): Number {
7642        return this.$_get(index as int) as Number
7643    }
7644
7645    /**
7646     * Returns an instance of number at passed index.
7647     *
7648     * @param index index to look at
7649     *
7650     * @returns a primitive at index
7651     */
7652    public native $_get(index: int): number
7653
7654    /**
7655     * Returns an instance of primitive type at passed index.
7656     *
7657     * @param index index to look at
7658     *
7659     * @returns a primitive at index
7660     */
7661    public at(index: number): Number | undefined {
7662        return this.at(index as int)
7663    }
7664
7665    /**
7666     * Returns an instance of primitive type at passed index.
7667     *
7668     * @param index index to look at
7669     *
7670     * @returns a primitive at index
7671     */
7672    public at(index: int): Number | undefined {
7673        let k: int
7674        if (index >= 0) {
7675            k = index
7676        } else {
7677            k = this.lengthInt + index
7678        }
7679        if (k < 0 || k >= this.lengthInt) {
7680            return undefined
7681        }
7682        return new Number(this.getUnsafe(k))
7683    }
7684
7685    /**
7686     * Makes a copy of internal elements to targetPos from startPos to endPos.
7687     *
7688     * @param target insert index to place copied elements
7689     *
7690     * @param start start index to begin copy from
7691     *
7692     * @param end last index to end copy from, excluded
7693     *
7694     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
7695     */
7696    public copyWithin(target: number, start: number, end?: number): Float32Array {
7697        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
7698    }
7699
7700    /**
7701     * Makes a copy of internal elements to targetPos from startPos to endPos.
7702     *
7703     * @param target insert index to place copied elements
7704     *
7705     * @param start start index to begin copy from
7706     *
7707     * @param end last index to end copy from, excluded
7708     *
7709     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
7710     */
7711    public copyWithin(target: int, start: number, end?: number): Float32Array {
7712        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
7713    }
7714
7715    /**
7716     * Makes a copy of internal elements to targetPos from startPos to endPos.
7717     *
7718     * @param target insert index to place copied elements
7719     *
7720     * @param start start index to begin copy from
7721     *
7722     * @param end last index to end copy from, excluded
7723     *
7724     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
7725     */
7726    public copyWithin(target: number, start: int, end?: number): Float32Array {
7727        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
7728    }
7729
7730    /**
7731     * Makes a copy of internal elements to targetPos from startPos to endPos.
7732     *
7733     * @param target insert index to place copied elements
7734     *
7735     * @param start start index to begin copy from
7736     *
7737     * @param end last index to end copy from, excluded
7738     *
7739     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
7740     */
7741    public copyWithin(target: int, start: int, end?: number): Float32Array {
7742        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
7743    }
7744
7745    /**
7746     * Makes a copy of internal elements to targetPos from startPos to endPos.
7747     *
7748     * @param target insert index to place copied elements
7749     *
7750     * @param start start index to begin copy from
7751     *
7752     * @param end last index to end copy from, excluded
7753     *
7754     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
7755     */
7756    public native copyWithin(target: int, start: int, end: int): Float32Array
7757
7758    /**
7759     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
7760     *
7761     * @param target insert index to place copied elements
7762     *
7763     * See rules of parameters normalization:
7764     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
7765     */
7766    public copyWithin(target: number): Float32Array {
7767        return this.copyWithin(target as int)
7768    }
7769
7770    /**
7771     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
7772     *
7773     * @param target insert index to place copied elements
7774     *
7775     * See rules of parameters normalization:
7776     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
7777     */
7778    public copyWithin(target: int): Float32Array {
7779        return this.copyWithin(target, 0, this.lengthInt)
7780    }
7781
7782    /**
7783     * Returns an array of key, value pairs for every entry in the Float32Array
7784     *
7785     * @returns key, value pairs for every entry in the array
7786     */
7787    public entries(): IterableIterator<[Number, Number]> {
7788        return new Float32ArrayIteratorEntries(this)
7789    }
7790
7791    /**
7792     * Fills the Float32Array with specified value
7793     *
7794     * @param value new valuy
7795     *
7796     * @returns modified Float32Array
7797     */
7798    public fill(value: number, start?: number, end?: number): this {
7799        this.fill(value as float, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
7800        return this
7801    }
7802
7803    /**
7804     * Fills the Float32Array with specified value
7805     *
7806     * @param value new valuy
7807     *
7808     * @returns modified Float32Array
7809     */
7810    public fill(value: number, start: int, end?: number): this {
7811        this.fill(value as float, start as int, asIntOrDefault(end, this.lengthInt))
7812        return this
7813    }
7814
7815    /**
7816     * Fills the Float32Array with specified value
7817     *
7818     * @param value new valuy
7819     *
7820     * @returns modified Float32Array
7821     */
7822    public fill(value: number, start: int, end: number): this {
7823        this.fill(value as float, start as int, end as int)
7824        return this
7825    }
7826
7827    /**
7828     * Fills the Float32Array with specified value
7829     *
7830     * @param value new valuy
7831     *
7832     * @returns modified Float32Array
7833     */
7834    public fill(value: number, start: number, end: int): this {
7835        this.fill(value as float, start as int, end as int)
7836        return this
7837    }
7838
7839    /**
7840     * Fills the Float32Array with specified value
7841     *
7842     * @param value new valuy
7843     *
7844     * @returns modified Float32Array
7845     */
7846    public fill(value: number, start: int, end: int): this {
7847        this.fill(value as float, start as int, end as int)
7848        return this
7849    }
7850
7851    /**
7852     * Fills the Float32Array with specified value
7853     *
7854     * @param value new valuy
7855     *
7856     * @returns modified Float32Array
7857     */
7858    public fill(value: float, start?: number, end?: number): this {
7859        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
7860        return this
7861    }
7862
7863    /**
7864     * Fills the Float32Array with specified value
7865     *
7866     * @param value new valuy
7867     *
7868     * @returns modified Float32Array
7869     */
7870    public fill(value: float, start: int, end?: number): this {
7871        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
7872        return this
7873    }
7874
7875    /**
7876     * Fills the Float32Array with specified value
7877     *
7878     * @param value new valuy
7879     *
7880     * @returns modified Float32Array
7881     */
7882    public fill(value: float, start: int, end: number): this {
7883        this.fill(value, start as int, end as int)
7884        return this
7885    }
7886
7887    /**
7888     * Fills the Float32Array with specified value
7889     *
7890     * @param value new valuy
7891     *
7892     * @returns modified Float32Array
7893     */
7894    public fill(value: float, start: number, end: int): this {
7895        this.fill(value, start as int, end as int)
7896        return this
7897    }
7898
7899    /**
7900     * Fills the Float32Array with specified value
7901     *
7902     * @param value new valuy
7903     *
7904     * @returns modified Float32Array
7905     */
7906    public fill(value: float, start: int, end: int): this {
7907        const k = normalizeIndex(start, this.lengthInt)
7908        const finalPos = normalizeIndex(end, this.lengthInt)
7909        this.fillInternal(value, k, finalPos)
7910        return this
7911    }
7912
7913    private final native fillInternal(value: float, start: int, end: int): void
7914
7915    /**
7916     * Assigns val as element on insertPos.
7917     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<float>, insertPos)
7918     *
7919     * @param val value to set
7920     *
7921     * @param insertPos index to change
7922     */
7923    public set(insertPos: number, val: number): void {
7924        this.$_set(insertPos, val)
7925    }
7926
7927    /**
7928     * Assigns val as element on insertPos.
7929     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<float>, insertPos)
7930     *
7931     * @param val value to set
7932     *
7933     * @param insertPos index to change
7934     */
7935    public set(insertPos: int, val: float): void {
7936        this.$_set(insertPos, val)
7937    }
7938
7939    /**
7940     * Copies all elements of arr to the current Float32Array starting from insertPos.
7941     *
7942     * @param arr array to copy data from
7943     *
7944     * @param insertPos start index where data from arr will be inserted
7945     *
7946     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
7947     */
7948    public set(arr: FixedArray<number>, insertPos: number): void {
7949        const offset = insertPos as int
7950        if (offset < 0 || offset + arr.length > this.lengthInt) {
7951            throw new RangeError("offset is out of bounds")
7952        }
7953        for (let i = 0; i < arr.length as int; ++i) {
7954            this.$_set(offset + i, arr[i] as float)
7955        }
7956    }
7957
7958    /**
7959     * Copies all elements of arr to the current Float32Array starting from insertPos.
7960     *
7961     * @param arr array to copy data from
7962     *
7963     * @param insertPos start index where data from arr will be inserted
7964     *
7965     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
7966     */
7967    public set(arr: FixedArray<float>, insertPos: int): void {
7968        const offset = insertPos as int
7969        if (offset < 0 || offset + arr.length > this.lengthInt) {
7970            throw new RangeError("offset is out of bounds")
7971        }
7972        for (let i = 0; i < arr.length as int; ++i) {
7973            this.$_set(offset + i, arr[i])
7974        }
7975    }
7976
7977    /**
7978     * Copies all elements of arr to the current Float32Array.
7979     *
7980     * @param arr array to copy data from
7981     */
7982    public set(arr: FixedArray<number>): void {
7983        this.set(arr, 0 as number)
7984    }
7985
7986    /**
7987     * Copies all elements of arr to the current Float32Array.
7988     *
7989     * @param arr array to copy data from
7990     */
7991    public set(arr: FixedArray<float>): void {
7992        this.set(arr, 0 as int)
7993    }
7994
7995    public native set(array: Float32Array): void
7996
7997    public native set(array: Float32Array, offset: number): void
7998
7999    /**
8000     * Copies elements from an ArrayLike object to the Float32Array.
8001     *
8002     * @param array An ArrayLike object containing the elements to copy.
8003     *
8004     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
8005     */
8006    public set(array: ArrayLike<number>, offset: number = 0): void {
8007        const insertPos = offset as int
8008        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
8009            throw new RangeError("offset is out of bounds")
8010        }
8011        for (let i = array.length - 1 as int; i >= 0; --i) {
8012            this.$_set(insertPos + i, array[i] as float)
8013        }
8014    }
8015
8016    /**
8017     * Returns a new array from a set of elements.
8018     *
8019     * @param items a set of elements to include in the new array object.
8020     *
8021     * @returns new Float32Array
8022     */
8023    public static of(...items: FixedArray<number>): Float32Array {
8024        let res = new Float32Array(items.length as int)
8025        for (let i: int = 0; i < items.length; i++) {
8026            res.setUnsafe(i, items[i] as float)
8027        }
8028        return res
8029    }
8030
8031    /**
8032     * Returns a new array from a set of elements.
8033     *
8034     * @param items a set of elements to include in the new array object.
8035     *
8036     * @returns new Float32Array
8037     */
8038    public static of(...items: FixedArray<int>): Float32Array {
8039        let res = new Float32Array(items.length as int)
8040        for (let i: int = 0; i < items.length; i++) {
8041            res.setUnsafe(i, items[i] as float)
8042        }
8043        return res
8044    }
8045
8046    /**
8047     * Returns a new array from a set of elements.
8048     *
8049     * @param items a set of elements to include in the new array object.
8050     *
8051     * @returns new Float32Array
8052     */
8053    public static of(...items: FixedArray<float>): Float32Array {
8054        let res = new Float32Array(items.length as int)
8055        for (let i: int = 0; i < items.length; i++) {
8056            res.setUnsafe(i, items[i])
8057        }
8058        return res
8059    }
8060
8061    /**
8062     * Returns a new array from a set of elements.
8063     *
8064     * @param items a set of elements to include in the new array object.
8065     *
8066     * @returns new Float32Array
8067     */
8068    public static of(): Float32Array {
8069        return new Float32Array(0 as int)
8070    }
8071
8072    /**
8073     * Creates an array from an array-like or iterable object.
8074     *
8075     * @param arrayLike An array-like or iterable object to convert to an array.
8076     *
8077     * @returns new Float32Array
8078     */
8079    public static from(arrayLike: ArrayLike<number>): Float32Array {
8080        return Float32Array.from<number>(arrayLike, (x: number, k: number): number => x)
8081    }
8082
8083    /**
8084     * Creates an array from an array-like or iterable object.
8085     *
8086     * @param arrayLike An array-like or iterable object to convert to an array.
8087     *
8088     * @param mapfn A mapping function to call on every element of the array.
8089     *
8090     * @returns new Float32Array
8091     */
8092    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float32Array {
8093        if (mapfn == undefined) {
8094            mapfn = (v: number, k: number): number => { return v }
8095        }
8096
8097        let iter = arrayLike.$_iterator()
8098        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
8099        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
8100        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
8101        //  we can make one pass through the iterator without the need for memory reallocation.
8102        const maybeLength = tryGetIteratorLength(arrayLike)
8103        if (maybeLength) {
8104            const result = new Float32Array(maybeLength)
8105            for (let i = 0; i < maybeLength; ++i) {
8106                const x = iter.next()
8107                if (x.done) {
8108                    return new Float32Array(result.buffer, 0, i)
8109                }
8110                result.setUnsafe(i, (mapfn)!(x.value!, i) as float)
8111            }
8112            return result
8113        }
8114
8115        // NOTE (templin.konstantin): Create builtin array as buffer
8116        let temp = new Float32Array(6)
8117        let index : FixedArray<int> = new int[1]
8118        index[0] = 0
8119
8120        iteratorForEach<number>(iter, (x: number): void => {
8121            if (index[0] + 1 > temp.lengthInt) {
8122                // NOTE (templin.konstantin): Progressive reallocation
8123                const curLength = (temp.buffer as Buffer).getByteLength()
8124                const tb = new ArrayBuffer(curLength * 2)
8125                for (let i = 0; i < curLength; ++i) {
8126                    tb.set(i, (temp.buffer as Buffer).at(i))
8127                }
8128                temp = new Float32Array(tb)
8129            }
8130            temp.setUnsafe(index[0], (mapfn)!(x, index[0]) as float)
8131            index[0]++
8132        })
8133        return new Float32Array(temp.buffer, 0, index[0])
8134    }
8135
8136
8137    /**
8138     * Creates an array from an array-like or iterable object.
8139     *
8140     * @param arrayLike An array-like or iterable object to convert to an array.
8141     *
8142     * @param mapfn A mapping function to call on every element of the array.
8143     *
8144     * @returns new Float32Array
8145     */
8146    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Float32Array {
8147        let res = new Float32Array(arrayLike.length)
8148        // 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
8149        const idx : FixedArray<int> = new int[1]
8150        idx[0] = 0
8151        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
8152            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as float)
8153            idx[0] += 1
8154        })
8155        return res
8156    }
8157
8158    /**
8159     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
8160     *
8161     * @param searchElement The element to search for
8162     *
8163     * @param fromIndex The position in this array at which to begin searching for searchElement
8164     *
8165     * @returns true if searchElement is in Float32Array, false otherwise
8166     */
8167    public includes(searchElement: number, fromIndex?: number): boolean {
8168        if (isNaN(searchElement)) {
8169            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
8170            for (let i = fromIndexInt; i < this.lengthInt; i++) {
8171                if (isNaN(this.getUnsafe(i))) {
8172                    return true
8173                }
8174            }
8175            return false
8176        }
8177        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
8178    }
8179
8180    /**
8181     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
8182     *
8183     * @param searchElement The element to search for
8184     *
8185     * @param fromIndex The position in this array at which to begin searching for searchElement
8186     *
8187     * @returns true if e is in Float32Array, false otherwise
8188     */
8189    public includes(searchElement: float, fromIndex: int): boolean {
8190        return this.indexOf(searchElement as int, fromIndex) != -1
8191    }
8192
8193    /**
8194     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
8195     *
8196     * @param searchElement The element to search for
8197     *
8198     * @param fromIndex The position in this array at which to begin searching for searchElement
8199     *
8200     * @returns true if searchElement is in Float32Array, false otherwise
8201     */
8202    public includes(searchElement: float): boolean {
8203        return this.includes(searchElement, 0)
8204    }
8205
8206    /**
8207     * Returns the index of the first occurrence of a value in Float32Array.
8208     *
8209     * @param searchElement The value to locate in the array.
8210     *
8211     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8212     *  search starts at index 0.
8213     *
8214     * @returns index of element if it presents, -1 otherwise
8215     */
8216    public indexOf(searchElement: number, fromIndex?: number): number {
8217        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
8218    }
8219
8220    /**
8221     * Returns the index of the first occurrence of a value in Float32Array.
8222     *
8223     * @param searchElement The value to locate in the array.
8224     *
8225     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8226     *  search starts at index 0.
8227     *
8228     * @returns index of element if it presents, -1 otherwise
8229     */
8230    public indexOf(searchElement: number, fromIndex: int): number {
8231            return this.indexOfImpl(searchElement, fromIndex)
8232    }
8233
8234    /**
8235     * Returns the index of the first occurrence of a value in Float32Array.
8236     *
8237     * @param searchElement The value to locate in the array.
8238     *
8239     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8240     *  search starts at index 0.
8241     *
8242     * @returns index of element if it presents, -1 otherwise
8243     */
8244    public indexOf(searchElement: int, fromIndex: int): number {
8245        return this.indexOfImpl(searchElement as long, fromIndex)
8246    }
8247
8248    /**
8249     * Returns the index of the first occurrence of a value in Float32Array.
8250     *
8251     * @param searchElement The value to locate in the array.
8252     *
8253     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8254     *  search starts at index 0.
8255     *
8256     * @returns index of element if it presents, -1 otherwise
8257     */
8258    private final native indexOfImpl(searchElement: number, fromIndex: int): number
8259
8260    /**
8261     * Returns the index of the first occurrence of a value in Float32Array.
8262     *
8263     * @param searchElement The value to locate in the array.
8264     *
8265     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8266     *  search starts at index 0.
8267     *
8268     * @returns index of element if it presents, -1 otherwise
8269     */
8270    private final native indexOfImpl(searchElement: long, fromIndex: int): number
8271
8272    /**
8273     * Returns the index of the first occurrence of a value in Float32Array.
8274     *
8275     * @param searchElement The value to locate in the array.
8276     *
8277     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8278     *  search starts at index 0.
8279     *
8280     * @returns index of element if it presents, -1 otherwise
8281     */
8282    public indexOf(searchElement: int): number {
8283        return this.indexOf(searchElement, 0)
8284    }
8285
8286    /**
8287     * Converts all elements of an array to strings and joins them using the specified separator.
8288     *
8289     * @param separator - separates one element of an array from the next in the resulting String.
8290     *
8291     * @returns joined representation
8292     */
8293    private final native joinInternal(separator: String): string;
8294
8295    /**
8296     * Adds all the elements of an array separated by the specified separator string
8297     *
8298     * @param separator A string used to separate one element of an array from the next in the
8299     * resulting String. If omitted, the array elements are separated with a comma.
8300     *
8301     * @returns joined representation
8302     */
8303    public join(separator?: String): string {
8304        if (separator == undefined) {
8305            return this.joinInternal(",")
8306        }
8307        return this.joinInternal(separator)
8308    }
8309
8310    /**
8311     * Returns an list of keys in Float32Array
8312     *
8313     * @returns iterator over keys
8314     */
8315    public keys(): IterableIterator<number> {
8316        return new Float32ArrayIteratorKeys(this)
8317    }
8318
8319    /**
8320     * Returns the index of the last occurrence of a value in Float32Array.
8321     *
8322     * @param searchElement The value to locate in the array.
8323     *
8324     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8325     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8326     *
8327     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8328     */
8329    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
8330        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
8331    }
8332
8333    /**
8334     * Returns the index of the last occurrence of a value in Float32Array.
8335     *
8336     * @param searchElement The value to locate in the array.
8337     *
8338     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8339     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8340     *
8341     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8342     */
8343    public lastIndexOf(searchElement: number): number {
8344        return this.lastIndexOf(searchElement, this.lengthInt - 1)
8345    }
8346
8347    /**
8348     * Returns the index of the last occurrence of a value in Float32Array.
8349     *
8350     * @param searchElement The value to locate in the array.
8351     *
8352     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8353     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8354     *
8355     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8356     */
8357    public lastIndexOf(searchElement: number, fromIndex: int): number {
8358            return this.lastIndexOfImpl(searchElement, fromIndex)
8359    }
8360
8361    /**
8362     * Returns the index of the last occurrence of a value in Float32Array.
8363     *
8364     * @param searchElement The value to locate in the array.
8365     *
8366     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8367     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8368     *
8369     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8370     */
8371    public lastIndexOf(searchElement: int, fromIndex: int): number {
8372        return this.lastIndexOfImpl(searchElement as long, fromIndex)
8373    }
8374
8375    /**
8376     * Returns the index of the last occurrence of a value in Float32Array.
8377     *
8378     * @param searchElement The value to locate in the array.
8379     *
8380     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8381     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8382     *
8383     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8384     */
8385    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
8386
8387    /**
8388     * Returns the index of the last occurrence of a value in Float32Array.
8389     *
8390     * @param searchElement The value to locate in the array.
8391     *
8392     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8393     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8394     *
8395     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8396     */
8397    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
8398
8399    /**
8400     * Returns the index of the last occurrence of a value in Float32Array.
8401     *
8402     * @param searchElement The value to locate in the array.
8403     *
8404     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8405     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8406     *
8407     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8408     */
8409    public lastIndexOf(searchElement: int): number {
8410        return this.lastIndexOf(searchElement, this.lengthInt - 1)
8411    }
8412
8413    /**
8414    * Creates a new Float32Array using initializer
8415    *
8416    * @param data initializer
8417    *
8418    * @returns a new Float32Array from data
8419    */
8420    public of(data: FixedArray<Object>): Float32Array {
8421        throw new Error("Float32Array.of: not implemented")
8422    }
8423
8424    /**
8425     * Creates a new Float32Array using reversed data from the current one
8426     *
8427     * @returns a new Float32Array using reversed data from the current one
8428     */
8429    public native reverse(): Float32Array
8430
8431    /**
8432     * Creates a slice of current Float32Array using range [begin, end)
8433     *
8434     * @param begin start index to be taken into slice
8435     *
8436     * @param end last index to be taken into slice
8437     *
8438     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
8439     *
8440     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8441     */
8442    public slice(begin?: number, end?: number): Float32Array {
8443        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
8444    }
8445
8446    /**
8447     * Creates a slice of current Float32Array using range [begin, end)
8448     *
8449     * @param begin start index to be taken into slice
8450     *
8451     * @param end last index to be taken into slice
8452     *
8453     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
8454     *
8455     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8456     */
8457    public slice(begin: number, end: number): Float32Array {
8458        return this.slice(begin as int, end as int)
8459    }
8460
8461    /**
8462     * Creates a slice of current Float32Array using range [begin, end)
8463     *
8464     * @param begin start index to be taken into slice
8465     *
8466     * @param end last index to be taken into slice
8467     *
8468     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
8469     *
8470     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8471     */
8472    public slice(begin: number, end: int): Float32Array {
8473        return this.slice(begin as int, end as int)
8474    }
8475
8476    /**
8477     * Creates a slice of current Float32Array using range [begin, end)
8478     *
8479     * @param begin start index to be taken into slice
8480     *
8481     * @param end last index to be taken into slice
8482     *
8483     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
8484     *
8485     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8486     */
8487    public slice(begin: int, end: number): Float32Array {
8488        return this.slice(begin as int, end as int)
8489    }
8490
8491    /**
8492     * Creates a slice of current Float32Array using range [begin, end)
8493     *
8494     * @param begin start index to be taken into slice
8495     *
8496     * @param end last index to be taken into slice
8497     *
8498     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
8499     *
8500     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8501     */
8502    public slice(begin: int, end: int): Float32Array {
8503        const len: int = this.lengthInt
8504        const relStart = normalizeIndex(begin, len)
8505        const relEnd = normalizeIndex(end, len)
8506        let count = relEnd - relStart
8507        if (count < 0) {
8508            count = 0
8509        }
8510        let buf = this.buffer.slice(relStart * Float32Array.BYTES_PER_ELEMENT as int, relEnd * Float32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
8511        return new Float32Array(buf)
8512    }
8513
8514    /**
8515     * Creates a slice of current Float32Array using range [begin, this.length).
8516     *
8517     * @param begin start index to be taken into slice
8518     *
8519     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
8520     */
8521    public slice(begin: number): Float32Array {
8522        return this.slice(begin as int)
8523    }
8524
8525    /**
8526     * Creates a slice of current Float32Array using range [begin, this.length).
8527     *
8528     * @param begin start index to be taken into slice
8529     *
8530     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
8531     */
8532    public slice(begin: int): Float32Array {
8533        return this.slice(begin, this.lengthInt)
8534    }
8535
8536    /**
8537     * Creates a Float32Array with the same underlying ArrayBuffer
8538     *
8539     * @param begin start index, inclusive
8540     *
8541     * @param end last index, exclusive
8542     *
8543     * @returns new Float32Array with the same underlying ArrayBuffer
8544     */
8545    public subarray(begin?: number, end?: number): Float32Array {
8546        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
8547    }
8548
8549    /**
8550     * Creates a Float32Array with the same underlying ArrayBuffer
8551     *
8552     * @param begin start index, inclusive
8553     *
8554     * @param end last index, exclusive
8555     *
8556     * @returns new Float32Array with the same underlying ArrayBuffer
8557     */
8558    public subarray(begin: number, end: number): Float32Array {
8559        return this.subarray(begin as int, end as int)
8560    }
8561
8562    /**
8563     * Creates a Float32Array with the same underlying ArrayBuffer
8564     *
8565     * @param begin start index, inclusive
8566     *
8567     * @param end last index, exclusive
8568     *
8569     * @returns new Float32Array with the same underlying ArrayBuffer
8570     */
8571    public subarray(begin: number, end: int): Float32Array {
8572        return this.subarray(begin as int, end as int)
8573    }
8574
8575    /**
8576     * Creates a Float32Array with the same underlying ArrayBuffer
8577     *
8578     * @param begin start index, inclusive
8579     *
8580     * @param end last index, exclusive
8581     *
8582     * @returns new Float32Array with the same underlying ArrayBuffer
8583     */
8584    public subarray(begin: int, end: number): Float32Array {
8585        return this.subarray(begin as int, end as int)
8586    }
8587
8588    /**
8589     * Creates a Float32Array with the same underlying ArrayBuffer
8590     *
8591     * @param begin start index, inclusive
8592     *
8593     * @param end last index, exclusive
8594     *
8595     * @returns new Float32Array with the same underlying ArrayBuffer
8596     */
8597    public subarray(begin: int, end: int | undefined = this.lengthInt): Float32Array {
8598        const len: int = this.lengthInt
8599        const relStart = normalizeIndex(begin, len)
8600        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
8601        let count = relEnd - relStart
8602        if (count < 0) {
8603            count = 0
8604        }
8605        return new Float32Array(this.buffer, relStart * Float32Array.BYTES_PER_ELEMENT as int, count)
8606    }
8607
8608    /**
8609     * Converts Float32Array to a string with respect to locale
8610     *
8611     * @param locales
8612     *
8613     * @param options
8614     *
8615     * @returns string representation
8616     */
8617    public toLocaleString(locales: Object, options: Object): string {
8618        throw new Error("Float32Array.toLocaleString: not implemented")
8619    }
8620
8621    /**
8622     * Converts Float32Array to a string with respect to locale
8623     *
8624     * @param locales
8625     *
8626     * @returns string representation
8627     */
8628    public toLocaleString(locales: Object): string {
8629        return this.toLocaleString(new Object(), new Object())
8630    }
8631
8632    /**
8633     * Converts Float32Array to a string with respect to locale
8634     *
8635     * @returns string representation
8636     */
8637    public toLocaleString(): string {
8638        let res: StringBuilder = new StringBuilder("")
8639        for (let i = 0; i < this.lengthInt - 1; ++i) {
8640            res.append((this.getUnsafe(i) as Number).toLocaleString())
8641            res.append(",")
8642        }
8643        if (this.lengthInt > 0) {
8644            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
8645        }
8646        return res.toString()
8647    }
8648
8649    /**
8650     * Creates a reversed copy
8651     *
8652     * @returns a reversed copy
8653     */
8654    public final native toReversed(): Float32Array
8655
8656    /**
8657     * Creates a sorted copy
8658     *
8659     * @returns a sorted copy
8660     */
8661    public toSorted(): Float32Array {
8662        return new Float32Array(this).sort()
8663    }
8664
8665    /**
8666     * Returns a string representation of the Float32Array
8667     *
8668     * @returns a string representation of the Float32Array
8669     */
8670    public override toString(): string {
8671        return this.join(",")
8672    }
8673
8674    /**
8675     * Returns array values iterator
8676     *
8677     * @returns an iterator
8678     */
8679    public values(): IterableIterator<Number> {
8680        return new Float32ArrayIterator(this)
8681    }
8682
8683    /**
8684     * Iteratorable interface implementation
8685     *
8686     * @returns iterator over all elements
8687     */
8688    public override $_iterator(): IterableIterator<Number> {
8689        return this.values()
8690    }
8691
8692    /**
8693     * Creates a copy with replaced value on index
8694     *
8695     * @param index
8696     *
8697     * @param value
8698     *
8699     * @returns an Float32Array with replaced value on index
8700     */
8701    public with(index: number, value: number): Float32Array {
8702        return this.with(index as int, value as float)
8703    }
8704
8705    /**
8706     * Creates a copy with replaced value on index
8707     *
8708     * @param index
8709     *
8710     * @param value
8711     *
8712     * @returns an Float32Array with replaced value on index
8713     */
8714    public with(index: int, value: float): Float32Array {
8715        let res = new Float32Array(this)
8716        res.set(index, value)
8717        return res
8718    }
8719
8720    /// === with element lambda functions ===
8721
8722    /**
8723     * Finds the last element in the Float32Array that satisfies the condition
8724     *
8725     * @param fn condition
8726     *
8727     * @returns the last element that satisfies fn
8728     */
8729    public findLast(fn: (val: number) => boolean): number {
8730        let newF: (val: number, index: number, array: Float32Array) => boolean =
8731            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
8732        return this.findLast(newF) as number
8733    }
8734
8735    /**
8736     * Sorts in-place by numeric value in ascending order.
8737     *
8738     * @returns sorted Float32Array
8739     */
8740    public native sort(): this;
8741
8742    /**
8743     * Sorts in-place
8744     *
8745     * @param compareFn comparator _  used to determine the order of the elements.
8746     * compareFn returns a negative value if first argument is less than second argument,
8747     * zero if they're equal and a positive value otherwise.
8748     *
8749     * @returns sorted Float32Array
8750     */
8751    public sort(compareFn?: (a: number, b: number) => number): this {
8752        if (compareFn == undefined) {
8753            this.sort()
8754            return this
8755        }
8756        let arr: FixedArray<float> = new float[this.lengthInt]
8757        for (let i = 0; i < this.lengthInt; ++i) {
8758            arr[i] = this.getUnsafe(i)
8759        }
8760
8761        let cmp = (l: float, r: float): number => {
8762            const result = compareFn!(l as number, r as number)
8763            return result
8764        }
8765        const MAX_SHORT_LENGTH = 24
8766        if (arr.length > MAX_SHORT_LENGTH) {
8767            arr = mergeSort(arr, cmp)
8768        } else {
8769            sort(arr, cmp)
8770        }
8771        for (let i = 0; i < arr.length; ++i) {
8772            this.setUnsafe(i, arr[i])
8773        }
8774        return this
8775    }
8776
8777    /**
8778     * Determines whether the specified callback function returns true for any element of an array.
8779     *
8780     * @param predicate A function that accepts three arguments.
8781     * The some method calls the predicate function for each element in the array
8782     * until the predicate returns a true or until the end of the array.
8783     *
8784     * @returns false unless predicate function returns true for an array element,
8785     * in which case true is immediately returned.
8786     */
8787    public some(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
8788        for (let i = 0; i < this.lengthInt; ++i) {
8789            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
8790                return true
8791            }
8792        }
8793        return false
8794    }
8795
8796    /**
8797     * Calls the specified callback function for all the elements in an array.
8798     * The return value of the callback function is the accumulated result,
8799     * and is provided as an argument in the next call to the callback function.
8800     *
8801     * @param callbackfn A function that accepts four arguments.
8802     * The reduce method calls the callbackfn function one time for each element in the array.
8803     *
8804     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
8805     * The first call to the callbackfn function provides this value as an argument.
8806     *
8807     * @returns The value that results from running the callback function to completion over the entire typed array.
8808     */
8809    public reduce<U = number>(
8810                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
8811                initialValue: U): U {
8812        let accumulatedValue = initialValue
8813        for (let i = 0; i < this.lengthInt; ++i) {
8814            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
8815        }
8816        return accumulatedValue
8817    }
8818
8819    /**
8820     * Calls the specified callback function for all the elements in an array.
8821     * The return value of the callback function is the accumulated result,
8822     * and is provided as an argument in the next call to the callback function.
8823     *
8824     * @param callbackfn A function that accepts four arguments.
8825     * The reduce method calls the callbackfn function one time for each element in the array.
8826     * The first call to the callbackfn function provides array first element value as an argument
8827     *
8828     * @returns The value that results from running the callback function to completion over the entire typed array.
8829     * calling reduce method on an empty array without an initial value creates a TypeError
8830     */
8831    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
8832        if (this.lengthInt == 0) {
8833            throw new TypeError("Reduce of empty array with no initial value")
8834        }
8835
8836        let accumulatedValue = this.getUnsafe(0) as number
8837        for (let i = 1; i < this.lengthInt; ++i) {
8838            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
8839        }
8840        return accumulatedValue
8841    }
8842
8843    /**
8844     * Calls the specified callback function for all the elements in an array, in descending order.
8845     * The return value of the callback function is the accumulated result,
8846     * and is provided as an argument in the next call to the callback function.
8847     *
8848     * @param callbackfn A function that accepts four arguments.
8849     * The reduceRight method calls the callbackfn function one time for each element in the array.
8850     *
8851     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
8852     * The first call to the callbackfn function provides this value as an argument.
8853     *
8854     * @returns The value that results from running the callback function to completion over the entire typed array.
8855     */
8856    public reduceRight<U = number>(
8857                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
8858                initialValue: U): U {
8859        let accumulatedValue = initialValue
8860        for (let i = this.lengthInt - 1; i >= 0; --i) {
8861            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
8862        }
8863        return accumulatedValue
8864    }
8865
8866
8867    /**
8868     * Calls the specified callback function for all the elements in an array, in descending order.
8869     * The return value of the callback function is the accumulated result,
8870     * and is provided as an argument in the next call to the callback function.
8871     *
8872     * @param callbackfn A function that accepts four arguments.
8873     * The reduceRight method calls the callbackfn function one time for each element in the array.
8874     * The first call to the callbackfn function provides array last element value as an argument
8875     *
8876     * @returns The value that results from running the callback function to completion over the entire typed array.
8877     * calling reduceRight method on an empty array without an initial value creates a TypeError
8878     */
8879    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
8880        if (this.lengthInt == 0) {
8881            throw new TypeError("Reduce of empty array with no initial value")
8882        }
8883
8884        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
8885        for (let i = this.lengthInt - 2; i >= 0; --i) {
8886            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
8887        }
8888        return accumulatedValue
8889    }
8890
8891   /**
8892    * Creates a new Float32Array using fn(arr[i]) over all elements of current Float32Array.
8893    *
8894    * @param fn a function to apply for each element of current Float32Array
8895    *
8896    * @returns a new Float32Array where for each element from current Float32Array fn was applied
8897    */
8898    public map(fn: (val: number, index: number, array: Float32Array) => number): Float32Array {
8899        let resBuf = new ArrayBuffer(this.lengthInt * Float32Array.BYTES_PER_ELEMENT as int)
8900        let res = new Float32Array(resBuf, 0, resBuf.getByteLength() / Float32Array.BYTES_PER_ELEMENT as int)
8901        for (let i = 0; i < this.lengthInt; ++i) {
8902            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as float)
8903        }
8904        return res
8905    }
8906
8907    /**
8908     * Determines whether the specified callback function returns true for all elements of an array.
8909     *
8910     * @param predicate A function that accepts three arguments.
8911     * The every method calls the predicate function for each element in the array until the predicate returns a false,
8912     * or until the end of the array.
8913     *
8914     * @returns true unless predicate function returns a false for an array element,
8915     * in which case false is immediately returned.
8916     */
8917    public every(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
8918        for (let i = 0; i < this.lengthInt; ++i) {
8919            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
8920                return false
8921            }
8922        }
8923        return true
8924    }
8925
8926    /**
8927     * Creates a new Float32Array from current Float32Array based on a condition fn.
8928     *
8929     * @param fn the condition to apply for each element
8930     *
8931     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
8932     */
8933    public filter(fn: (val: number, index: number, array: Float32Array) => boolean): Float32Array {
8934        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
8935        let resLen = 0
8936        for (let i = 0; i < this.lengthInt; ++i) {
8937            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
8938            if (markers[i]) {
8939                ++resLen
8940            }
8941        }
8942        let resBuf = new ArrayBuffer(resLen * Float32Array.BYTES_PER_ELEMENT as int)
8943        let res = new Float32Array(resBuf, 0)
8944        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
8945            if (markers[i]) {
8946                res.set(j, this.getUnsafe(i))
8947                ++j
8948            }
8949        }
8950        return res
8951    }
8952
8953    /**
8954     * Returns the value of the first element in the array where predicate is true, and undefined
8955     * otherwise
8956     *
8957     * @param predicate find calls predicate once for each element of the array, in ascending
8958     * order, until it finds one where predicate returns true. If such an element is found, find
8959     * immediately returns that element value. Otherwise, find returns undefined
8960     *
8961     * @returns number | undefined
8962     */
8963    public find(predicate: (value: number, index: number, obj: Float32Array) => boolean): number | undefined {
8964        for (let i = 0; i < this.lengthInt; ++i) {
8965            let val = this.getUnsafe(i)
8966            if (predicate(val as number, i as number, this)) {
8967                return val as number
8968            }
8969        }
8970        return undefined
8971    }
8972
8973    /**
8974     * Returns the index of the first element in the array where predicate is true, and -1
8975     * otherwise
8976     *
8977     * @param predicate find calls predicate once for each element of the array, in ascending
8978     * order, until it finds one where predicate returns true. If such an element is found,
8979     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
8980     *
8981     * @returns number
8982     */
8983    public findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean): number {
8984        for (let i = 0; i < this.lengthInt; ++i) {
8985            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
8986                return i as number
8987            }
8988        }
8989        return -1 as number
8990    }
8991
8992    /**
8993     * Finds the last element in the Float32Array that satisfies the condition
8994     *
8995     * @param fn condition
8996     *
8997     * @returns the last element that satisfies fn
8998     */
8999    public findLast(fn: (val: number, index: number, array: Float32Array) => boolean): float {
9000        for (let i = this.lengthInt - 1; i >= 0; --i) {
9001            let val = this.getUnsafe(i)
9002            if (fn(val as number, i as number, this)) {
9003                return val
9004            }
9005        }
9006        throw new Error("Float32Array.findLast: not implemented if an element was not found")
9007    }
9008
9009    /**
9010     * Finds an index of the last element in the Float32Array that satisfies the condition
9011     *
9012     * @param fn condition
9013     *
9014     * @returns the index of the last element that satisfies fn, -1 otherwise
9015     */
9016    public findLastIndex(fn: (val: number, index: number, array: Float32Array) => boolean): number {
9017        for (let i = this.lengthInt - 1; i >= 0; --i) {
9018            let val = this.getUnsafe(i)
9019            if (fn(val as number, i as number, this)) {
9020                return i
9021            }
9022        }
9023        return -1 as number
9024    }
9025
9026    /**
9027     * Performs the specified action for each element in Float32Array
9028     *
9029     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
9030     * callbackfn function one time for each element in the array.
9031     *
9032     * @returns None
9033     */
9034    public forEach(callbackfn: (value: number, index: number, array: Float32Array) => void): void {
9035        for (let i = 0; i < this.lengthInt; ++i) {
9036            callbackfn(this.getUnsafe(i) as number, i as number, this)
9037        }
9038    }
9039
9040    /**
9041     * Returns the object itself
9042     *
9043     * @returns Float32Array
9044     */
9045    public valueOf(): Float32Array {
9046        return this
9047    }
9048
9049    private final native getUnsafe(index: int): float
9050
9051    internal setUnsafe(insertPos: int, val: float): void {
9052        let startByte = insertPos * Float32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
9053        let bits = Float.bitCastToInt(val)
9054        if (IS_LITTLE_ENDIAN) {
9055            for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
9056                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
9057                this.buffer.set(startByte + i, byteVal)
9058            }
9059        } else {
9060            for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; i++) {
9061                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
9062                this.buffer.set(startByte + 3 - i, byteVal)
9063            }
9064        }
9065    }
9066
9067    /** Underlying ArrayBuffer */
9068    public readonly buffer: ArrayBuffer
9069
9070    /** Byte offset within the underlying ArrayBuffer */
9071    public readonly byteOffset: number
9072
9073    /** Number of bytes used */
9074    public readonly byteLength: number
9075
9076    /** String \"Float32Array\" */
9077    public readonly name = "Float32Array"
9078}
9079
9080class Float64ArrayIteratorKeys implements IterableIterator<number> {
9081    private length: int
9082    private idx: int = 0
9083
9084    constructor(parent: Float64Array) {
9085        this.length = parent.length as int
9086    }
9087
9088    public override $_iterator(): IterableIterator<number> {
9089        return this
9090    }
9091
9092    override next(): IteratorResult<number> {
9093        if (this.idx < 0 || this.idx >= this.length) {
9094            return new IteratorResult<number>()
9095        }
9096        return new IteratorResult<number>(false, this.idx++ as number)
9097    }
9098}
9099
9100class Float64ArrayIterator implements IterableIterator<Number> {
9101    private parent: Float64Array
9102    private idx: int = 0
9103
9104    constructor(parent: Float64Array) {
9105        this.parent = parent
9106    }
9107
9108    public override $_iterator(): IterableIterator<Number> {
9109        return this
9110    }
9111
9112    override next(): IteratorResult<Number> {
9113        if (this.idx < 0 || this.idx >= this.parent.length as int) {
9114            return new IteratorResult<Number>()
9115        }
9116        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
9117    }
9118}
9119
9120class Float64ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
9121    private parent: Float64Array
9122    private idx: int = 0
9123
9124    constructor(parent: Float64Array) {
9125        this.parent = parent
9126    }
9127
9128    public override $_iterator(): IterableIterator<[Number, Number]> {
9129        return this
9130    }
9131
9132    override next(): IteratorResult<[Number, Number]> {
9133        if (this.idx < 0 || this.idx >= this.parent.length as int) {
9134            return new IteratorResult<[Number, Number]>()
9135        }
9136        return new IteratorResult<[Number, Number]>(
9137            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
9138        )
9139    }
9140}
9141
9142
9143/**
9144 * JS Float64Array API-compatible class
9145 */
9146export final class Float64Array implements Iterable<Number>, ArrayLike<Number> {
9147    public static readonly BYTES_PER_ELEMENT: number = 8
9148    public readonly BYTES_PER_ELEMENT: number = Float64Array.BYTES_PER_ELEMENT
9149    internal readonly lengthInt: int
9150
9151    /**
9152     * Creates an empty Float64Array.
9153     */
9154    public constructor() {
9155        this(0 as int)
9156    }
9157
9158    /**
9159     * Creates an Float64Array with respect to data accessed via Iterable<Number> interface
9160     */
9161    public constructor(elements: Iterable<Number>) {
9162        const items: Object = elements as Object
9163        if (items instanceof ArrayLike) {
9164            const arr = Types.identity_cast<Number>(items as ArrayLike<Number>)
9165            this.byteLength = arr.length as int * Float64Array.BYTES_PER_ELEMENT as int
9166            this.lengthInt = arr.length as int
9167            this.buffer = new ArrayBuffer(this.byteLength as int)
9168            this.byteOffset = 0
9169            for (let i: int = 0; i < this.lengthInt; ++i) {
9170                this.setUnsafe(i, arr.$_get(i).toDouble())
9171            }
9172        } else {
9173          let x = Float64Array.from(elements)
9174          this.byteLength = x.byteLength
9175          this.lengthInt = x.lengthInt
9176          this.buffer = x.buffer
9177          this.byteOffset = x.byteOffset
9178        }
9179    }
9180
9181    /**
9182     * Creates an Float64Array with respect to data, byteOffset and length.
9183     *
9184     * @param buf data initializer
9185     *
9186     * @param byteOffset byte offset from begin of the buf
9187     *
9188     * @param length size of elements of type double in newly created Float64Array
9189     */
9190    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined, length: Number | undefined) {
9191        let intByteOffset: int = 0
9192        if (byteOffset != undefined) {
9193            intByteOffset = byteOffset.toInt()
9194            if (intByteOffset < 0) {
9195                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
9196            }
9197        }
9198        let intByteLength: int = buf.getByteLength() - intByteOffset
9199        if (intByteLength < 0) {
9200            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
9201        }
9202
9203        if (intByteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
9204            throw new RangeError("ArrayBuffer.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
9205        }
9206        if (intByteOffset % Float64Array.BYTES_PER_ELEMENT as int != 0) {
9207            throw new RangeError("byteOffset should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
9208        }
9209
9210        let intLength: int
9211        if (length != undefined) {
9212            intLength = length.toInt()
9213            if (intLength > intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
9214                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
9215            }
9216        } else {
9217            intLength = intByteLength / Float64Array.BYTES_PER_ELEMENT as int
9218        }
9219        if (intLength < 0) {
9220            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
9221        }
9222        if (intLength < intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
9223            intByteLength = intLength * Float64Array.BYTES_PER_ELEMENT as int
9224        }
9225        this.byteLength = intByteLength
9226        this.byteOffset = intByteOffset
9227        this.lengthInt = intLength
9228        this.buffer = buf
9229    }
9230
9231    /**
9232     * Creates an Float64Array with respect to data, byteOffset and length.
9233     *
9234     * @param buf data initializer
9235     *
9236     * @param byteOffset byte offset from begin of the buf
9237     *
9238     * @param length size of elements of type double in newly created Float64Array
9239     */
9240    public constructor(buf: ArrayBuffer, byteOffset: Number | undefined) {
9241        this(buf, byteOffset, undefined)
9242    }
9243
9244    /**
9245     * Creates an Float64Array with respect to data, byteOffset and length.
9246     *
9247     * @param buf data initializer
9248     *
9249     * @param byteOffset byte offset from begin of the buf
9250     *
9251     * @param length size of elements of type double in newly created Float64Array
9252     */
9253    public constructor(buf: ArrayBuffer, byteOffset: number, length: number) {
9254        this(buf, new Number(byteOffset), new Number(length))
9255    }
9256
9257    /**
9258     * Creates an Float64Array with respect to data, byteOffset and length.
9259     *
9260     * @param buf data initializer
9261     *
9262     * @param byteOffset byte offset from begin of the buf
9263     *
9264     * @param length size of elements of type double in newly created Float64Array
9265     */
9266    public constructor(buf: ArrayBuffer, byteOffset: number) {
9267        this(buf, new Number(byteOffset), undefined)
9268    }
9269
9270    /**
9271     * Creates an Float64Array with respect to data, byteOffset and length.
9272     *
9273     * @param buf data initializer
9274     *
9275     * @param byteOffset byte offset from begin of the buf
9276     *
9277     * @param length size of elements of type double in newly created Float64Array
9278     */
9279    public constructor(buf: ArrayBuffer, byteOffset: int, length: int) {
9280        this(buf, new Number(byteOffset), new Number(length))
9281    }
9282
9283    /**
9284     * Creates an Float64Array with respect to buf and byteOffset.
9285     *
9286     * @param buf data initializer
9287     *
9288     * @param byteOffset byte offset from begin of the buf
9289     */
9290    public constructor(buf: ArrayBuffer, byteOffset: int) {
9291        this(buf, new Number(byteOffset), undefined)
9292    }
9293
9294    /**
9295     * Creates an Float64Array with respect to buf.
9296     *
9297     * @param buf data initializer
9298     */
9299    public constructor(buf: ArrayLike<Number> | ArrayBuffer) {
9300        if (buf instanceof ArrayBuffer) {
9301            this.byteLength = (buf as ArrayBuffer).getByteLength()
9302            if (this.byteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
9303               throw new RangeError("ArrayBuffer.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
9304            }
9305            this.lengthInt = this.byteLength / Float64Array.BYTES_PER_ELEMENT as int
9306            this.buffer = buf as ArrayBuffer
9307            this.byteOffset = 0
9308        } else if (buf instanceof ArrayLike) {
9309            // NOTE (ikorobkov): dealing with this overload is tricky
9310            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.ets
9311            let arr = Array.from<Number>((buf as ArrayLike<Number>))
9312            this.byteLength = arr.length as int * Float64Array.BYTES_PER_ELEMENT as int
9313            this.lengthInt = arr.length as int
9314            this.buffer = new ArrayBuffer(this.byteLength as int)
9315            this.byteOffset = 0
9316            for (let i: int = 0; i < this.lengthInt; ++i) {
9317                this.setUnsafe(i, arr.$_get(i).toDouble())
9318            }
9319        } else {
9320            throw new Error("unexpected type of buf")
9321        }
9322    }
9323
9324    /**
9325     * Creates an Float64Array with respect to length.
9326     *
9327     * @param length data initializer
9328     */
9329    public constructor(length: int) {
9330        this(length as number)
9331    }
9332
9333    /**
9334     * Creates an Float64Array with respect to length.
9335     *
9336     * @param length data initializer
9337     */
9338    public constructor(length: number) {
9339        if (length < 0 || length > (Int.MAX_VALUE / Float64Array.BYTES_PER_ELEMENT)) {
9340            throw new TypeError("Type Error: length " + length + " is outside the bounds of the buffer")
9341        }
9342        this.lengthInt = length as int
9343        this.byteLength = this.lengthInt * Float64Array.BYTES_PER_ELEMENT as int
9344        this.byteOffset = 0
9345        this.buffer = new ArrayBuffer(this.byteLength as int)
9346    }
9347
9348    /**
9349     * Creates a copy of Float64Array.
9350     *
9351     * @param other data initializer
9352     */
9353    public constructor(other: Float64Array) {
9354        this.buffer = other.buffer.slice(other.byteOffset as int, (other.byteOffset + other.byteLength) as int) as ArrayBuffer
9355        this.byteLength = other.byteLength
9356        this.lengthInt = other.length as int
9357        this.byteOffset = 0
9358    }
9359
9360    /**
9361     * Creates an Float64Array from FixedArray<number>
9362     */
9363    public constructor(numbers: FixedArray<number>) {
9364        this(numbers.length)
9365        for (let i: int = 0; i < this.lengthInt; ++i) {
9366            this.setUnsafe(i, numbers[i] as double)
9367        }
9368    }
9369
9370    /**
9371     * Creates an Float64Array from FixedArray<int>
9372     */
9373    public constructor(numbers: FixedArray<int>) {
9374        this(numbers.length)
9375        for (let i: int = 0; i < this.lengthInt; ++i) {
9376            this.setUnsafe(i, numbers[i] as double)
9377        }
9378    }
9379
9380    /**
9381     * Assigns val as element on index.
9382     *
9383     * @param val value to set
9384     *
9385     * @param index index to change
9386     */
9387    public $_set(index: number, val: double): void {
9388        this.$_set(index as int, val)
9389    }
9390
9391    /**
9392     * Assigns val as element on index.
9393     *
9394     * @param val value to set
9395     *
9396     * @param index index to change
9397     */
9398    public native $_set(index: int, val: double): void
9399
9400    /** Number of double stored in Float64Array */
9401    public get length(): number {
9402        return this.lengthInt
9403    }
9404
9405    /**
9406     * Returns an instance of number at passed index.
9407     *
9408     * @param index index to look at
9409     *
9410     * @returns a primitive at index
9411     */
9412    public override $_get(index: number): Number {
9413        return this.$_get(index as int) as Number
9414    }
9415
9416    /**
9417     * Returns an instance of number at passed index.
9418     *
9419     * @param index index to look at
9420     *
9421     * @returns a primitive at index
9422     */
9423    public native $_get(index: int): number
9424
9425    /**
9426     * Returns an instance of primitive type at passed index.
9427     *
9428     * @param index index to look at
9429     *
9430     * @returns a primitive at index
9431     */
9432    public at(index: number): Number | undefined {
9433        return this.at(index as int)
9434    }
9435
9436    /**
9437     * Returns an instance of primitive type at passed index.
9438     *
9439     * @param index index to look at
9440     *
9441     * @returns a primitive at index
9442     */
9443    public at(index: int): Number | undefined {
9444        let k: int
9445        if (index >= 0) {
9446            k = index
9447        } else {
9448            k = this.lengthInt + index
9449        }
9450        if (k < 0 || k >= this.lengthInt) {
9451            return undefined
9452        }
9453        return new Number(this.getUnsafe(k))
9454    }
9455
9456    /**
9457     * Makes a copy of internal elements to targetPos from startPos to endPos.
9458     *
9459     * @param target insert index to place copied elements
9460     *
9461     * @param start start index to begin copy from
9462     *
9463     * @param end last index to end copy from, excluded
9464     *
9465     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
9466     */
9467    public copyWithin(target: number, start: number, end?: number): Float64Array {
9468        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
9469    }
9470
9471    /**
9472     * Makes a copy of internal elements to targetPos from startPos to endPos.
9473     *
9474     * @param target insert index to place copied elements
9475     *
9476     * @param start start index to begin copy from
9477     *
9478     * @param end last index to end copy from, excluded
9479     *
9480     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
9481     */
9482    public copyWithin(target: int, start: number, end?: number): Float64Array {
9483        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
9484    }
9485
9486    /**
9487     * Makes a copy of internal elements to targetPos from startPos to endPos.
9488     *
9489     * @param target insert index to place copied elements
9490     *
9491     * @param start start index to begin copy from
9492     *
9493     * @param end last index to end copy from, excluded
9494     *
9495     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
9496     */
9497    public copyWithin(target: number, start: int, end?: number): Float64Array {
9498        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
9499    }
9500
9501    /**
9502     * Makes a copy of internal elements to targetPos from startPos to endPos.
9503     *
9504     * @param target insert index to place copied elements
9505     *
9506     * @param start start index to begin copy from
9507     *
9508     * @param end last index to end copy from, excluded
9509     *
9510     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
9511     */
9512    public copyWithin(target: int, start: int, end?: number): Float64Array {
9513        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
9514    }
9515
9516    /**
9517     * Makes a copy of internal elements to targetPos from startPos to endPos.
9518     *
9519     * @param target insert index to place copied elements
9520     *
9521     * @param start start index to begin copy from
9522     *
9523     * @param end last index to end copy from, excluded
9524     *
9525     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
9526     */
9527    public native copyWithin(target: int, start: int, end: int): Float64Array
9528
9529    /**
9530     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
9531     *
9532     * @param target insert index to place copied elements
9533     *
9534     * See rules of parameters normalization:
9535     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
9536     */
9537    public copyWithin(target: number): Float64Array {
9538        return this.copyWithin(target as int)
9539    }
9540
9541    /**
9542     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
9543     *
9544     * @param target insert index to place copied elements
9545     *
9546     * See rules of parameters normalization:
9547     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
9548     */
9549    public copyWithin(target: int): Float64Array {
9550        return this.copyWithin(target, 0, this.lengthInt)
9551    }
9552
9553    /**
9554     * Returns an array of key, value pairs for every entry in the Float64Array
9555     *
9556     * @returns key, value pairs for every entry in the array
9557     */
9558    public entries(): IterableIterator<[Number, Number]> {
9559        return new Float64ArrayIteratorEntries(this)
9560    }
9561
9562    /**
9563     * Fills the Float64Array with specified value
9564     *
9565     * @param value new valuy
9566     *
9567     * @returns modified Float64Array
9568     */
9569    public fill(value: number, start?: number, end?: number): this {
9570        this.fill(value as double, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
9571        return this
9572    }
9573
9574    /**
9575     * Fills the Float64Array with specified value
9576     *
9577     * @param value new valuy
9578     *
9579     * @returns modified Float64Array
9580     */
9581    public fill(value: number, start: int, end?: number): this {
9582        this.fill(value as double, start as int, asIntOrDefault(end, this.lengthInt))
9583        return this
9584    }
9585
9586    /**
9587     * Fills the Float64Array with specified value
9588     *
9589     * @param value new valuy
9590     *
9591     * @returns modified Float64Array
9592     */
9593    public fill(value: number, start: int, end: number): this {
9594        this.fill(value as double, start as int, end as int)
9595        return this
9596    }
9597
9598    /**
9599     * Fills the Float64Array with specified value
9600     *
9601     * @param value new valuy
9602     *
9603     * @returns modified Float64Array
9604     */
9605    public fill(value: number, start: number, end: int): this {
9606        this.fill(value as double, start as int, end as int)
9607        return this
9608    }
9609
9610    /**
9611     * Fills the Float64Array with specified value
9612     *
9613     * @param value new valuy
9614     *
9615     * @returns modified Float64Array
9616     */
9617    public fill(value: double, start: int, end: int): this {
9618        const k = normalizeIndex(start, this.lengthInt)
9619        const finalPos = normalizeIndex(end, this.lengthInt)
9620        this.fillInternal(value, k, finalPos)
9621        return this
9622    }
9623
9624    private final native fillInternal(value: double, start: int, end: int): void
9625
9626    /**
9627     * Assigns val as element on insertPos.
9628     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<double>, insertPos)
9629     *
9630     * @param val value to set
9631     *
9632     * @param insertPos index to change
9633     */
9634    public set(insertPos: number, val: number): void {
9635        this.$_set(insertPos, val)
9636    }
9637
9638    /**
9639     * Assigns val as element on insertPos.
9640     * @description Added to avoid (un)packing a single value into array to use overloaded set(FixedArray<double>, insertPos)
9641     *
9642     * @param val value to set
9643     *
9644     * @param insertPos index to change
9645     */
9646    public set(insertPos: int, val: double): void {
9647        this.$_set(insertPos, val)
9648    }
9649
9650    /**
9651     * Copies all elements of arr to the current Float64Array starting from insertPos.
9652     *
9653     * @param arr array to copy data from
9654     *
9655     * @param insertPos start index where data from arr will be inserted
9656     *
9657     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
9658     */
9659    public set(arr: FixedArray<number>, insertPos: number): void {
9660        const offset = insertPos as int
9661        if (offset < 0 || offset + arr.length > this.lengthInt) {
9662            throw new RangeError("offset is out of bounds")
9663        }
9664        for (let i = 0; i < arr.length as int; ++i) {
9665            this.$_set(offset + i, arr[i] as double)
9666        }
9667    }
9668
9669    /**
9670     * Copies all elements of arr to the current Float64Array starting from insertPos.
9671     *
9672     * @param arr array to copy data from
9673     *
9674     * @param insertPos start index where data from arr will be inserted
9675     *
9676     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
9677     */
9678    public set(arr: FixedArray<double>, insertPos: int): void {
9679        const offset = insertPos as int
9680        if (offset < 0 || offset + arr.length > this.lengthInt) {
9681            throw new RangeError("offset is out of bounds")
9682        }
9683        for (let i = 0; i < arr.length as int; ++i) {
9684            this.$_set(offset + i, arr[i])
9685        }
9686    }
9687
9688    /**
9689     * Copies all elements of arr to the current Float64Array.
9690     *
9691     * @param arr array to copy data from
9692     */
9693    public set(arr: FixedArray<double>): void {
9694        this.set(arr, 0 as int)
9695    }
9696
9697    public native set(array: Float64Array): void
9698
9699    public native set(array: Float64Array, offset: number): void
9700
9701    /**
9702     * Copies elements from an ArrayLike object to the Float64Array.
9703     *
9704     * @param array An ArrayLike object containing the elements to copy.
9705     *
9706     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
9707     */
9708    public set(array: ArrayLike<number>, offset: number = 0): void {
9709        const insertPos = offset as int
9710        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
9711            throw new RangeError("offset is out of bounds")
9712        }
9713        for (let i = array.length - 1 as int; i >= 0; --i) {
9714            this.$_set(insertPos + i, array[i] as double)
9715        }
9716    }
9717
9718    /**
9719     * Returns a new array from a set of elements.
9720     *
9721     * @param items a set of elements to include in the new array object.
9722     *
9723     * @returns new Float64Array
9724     */
9725    public static of(...items: FixedArray<number>): Float64Array {
9726        let res = new Float64Array(items.length as int)
9727        for (let i: int = 0; i < items.length; i++) {
9728            res.setUnsafe(i, items[i])
9729        }
9730        return res
9731    }
9732
9733    /**
9734     * Returns a new array from a set of elements.
9735     *
9736     * @param items a set of elements to include in the new array object.
9737     *
9738     * @returns new Float64Array
9739     */
9740    public static of(...items: FixedArray<int>): Float64Array {
9741        let res = new Float64Array(items.length as int)
9742        for (let i: int = 0; i < items.length; i++) {
9743            res.setUnsafe(i, items[i] as double)
9744        }
9745        return res
9746    }
9747
9748    /**
9749     * Returns a new array from a set of elements.
9750     *
9751     * @param items a set of elements to include in the new array object.
9752     *
9753     * @returns new Float64Array
9754     */
9755    public static of(): Float64Array {
9756        return new Float64Array(0 as int)
9757    }
9758
9759    /**
9760     * Creates an array from an array-like or iterable object.
9761     *
9762     * @param arrayLike An array-like or iterable object to convert to an array.
9763     *
9764     * @returns new Float64Array
9765     */
9766    public static from(arrayLike: ArrayLike<number>): Float64Array {
9767        return Float64Array.from<number>(arrayLike, (x: number, k: number): number => x)
9768    }
9769
9770    /**
9771     * Creates an array from an array-like or iterable object.
9772     *
9773     * @param arrayLike An array-like or iterable object to convert to an array.
9774     *
9775     * @param mapfn A mapping function to call on every element of the array.
9776     *
9777     * @returns new Float64Array
9778     */
9779    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float64Array {
9780        if (mapfn == undefined) {
9781            mapfn = (v: number, k: number): number => { return v }
9782        }
9783
9784        let iter = arrayLike.$_iterator()
9785        // NOTE (templin.konstantin): This code section is responsible for optimizing for some types
9786        //  of iterators that we can learn the length of (e.g. ArrayValuesIterator).
9787        //  We are trying to use "reflection" to find the "__Iterator_getLength" method and if it exists,
9788        //  we can make one pass through the iterator without the need for memory reallocation.
9789        const maybeLength = tryGetIteratorLength(arrayLike)
9790        if (maybeLength) {
9791            const result = new Float64Array(maybeLength)
9792            for (let i = 0; i < maybeLength; ++i) {
9793                const x = iter.next()
9794                if (x.done) {
9795                    return new Float64Array(result.buffer, 0, i)
9796                }
9797                result.setUnsafe(i, (mapfn)!(x.value!, i) as double)
9798            }
9799            return result
9800        }
9801
9802        // NOTE (templin.konstantin): Create builtin array as buffer
9803        let temp = new Float64Array(6)
9804        let index : FixedArray<int> = new int[1]
9805        index[0] = 0
9806
9807        iteratorForEach<number>(iter, (x: number): void => {
9808            if (index[0] + 1 > temp.lengthInt) {
9809                // NOTE (templin.konstantin): Progressive reallocation
9810                const curLength = (temp.buffer as Buffer).getByteLength()
9811                const tb = new ArrayBuffer(curLength * 2)
9812                for (let i = 0; i < curLength; ++i) {
9813                    tb.set(i, (temp.buffer as Buffer).at(i))
9814                }
9815                temp = new Float64Array(tb)
9816            }
9817            temp.setUnsafe(index[0], (mapfn)!(x, index[0]) as double)
9818            index[0]++
9819        })
9820        return new Float64Array(temp.buffer, 0, index[0])
9821    }
9822
9823
9824    /**
9825     * Creates an array from an array-like or iterable object.
9826     *
9827     * @param arrayLike An array-like or iterable object to convert to an array.
9828     *
9829     * @param mapfn A mapping function to call on every element of the array.
9830     *
9831     * @returns new Float64Array
9832     */
9833    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number): Float64Array {
9834        let res = new Float64Array(arrayLike.length)
9835        // 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
9836        const idx : FixedArray<int> = new int[1]
9837        idx[0] = 0
9838        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
9839            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as double)
9840            idx[0] += 1
9841        })
9842        return res
9843    }
9844
9845    /**
9846     * Determines whether Float64Array includes a certain element, returning true or false as appropriate
9847     *
9848     * @param searchElement The element to search for
9849     *
9850     * @param fromIndex The position in this array at which to begin searching for searchElement
9851     *
9852     * @returns true if searchElement is in Float64Array, false otherwise
9853     */
9854    public includes(searchElement: number, fromIndex?: number): boolean {
9855        if (isNaN(searchElement)) {
9856            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
9857            for (let i = fromIndexInt; i < this.lengthInt; i++) {
9858                if (isNaN(this.getUnsafe(i))) {
9859                    return true
9860                }
9861            }
9862            return false
9863        }
9864        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
9865    }
9866
9867    /**
9868     * Returns the index of the first occurrence of a value in Float64Array.
9869     *
9870     * @param searchElement The value to locate in the array.
9871     *
9872     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9873     *  search starts at index 0.
9874     *
9875     * @returns index of element if it presents, -1 otherwise
9876     */
9877    public indexOf(searchElement: number, fromIndex?: number): number {
9878        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
9879    }
9880
9881    /**
9882     * Returns the index of the first occurrence of a value in Float64Array.
9883     *
9884     * @param searchElement The value to locate in the array.
9885     *
9886     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9887     *  search starts at index 0.
9888     *
9889     * @returns index of element if it presents, -1 otherwise
9890     */
9891    public indexOf(searchElement: number, fromIndex: int): number {
9892            return this.indexOfImpl(searchElement, fromIndex)
9893    }
9894
9895    /**
9896     * Returns the index of the first occurrence of a value in Float64Array.
9897     *
9898     * @param searchElement The value to locate in the array.
9899     *
9900     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9901     *  search starts at index 0.
9902     *
9903     * @returns index of element if it presents, -1 otherwise
9904     */
9905    public indexOf(searchElement: int, fromIndex: int): number {
9906        return this.indexOfImpl(searchElement as long, fromIndex)
9907    }
9908
9909    /**
9910     * Returns the index of the first occurrence of a value in Float64Array.
9911     *
9912     * @param searchElement The value to locate in the array.
9913     *
9914     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9915     *  search starts at index 0.
9916     *
9917     * @returns index of element if it presents, -1 otherwise
9918     */
9919    private final native indexOfImpl(searchElement: number, fromIndex: int): number
9920
9921    /**
9922     * Returns the index of the first occurrence of a value in Float64Array.
9923     *
9924     * @param searchElement The value to locate in the array.
9925     *
9926     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9927     *  search starts at index 0.
9928     *
9929     * @returns index of element if it presents, -1 otherwise
9930     */
9931    private final native indexOfImpl(searchElement: long, fromIndex: int): number
9932
9933    /**
9934     * Returns the index of the first occurrence of a value in Float64Array.
9935     *
9936     * @param searchElement The value to locate in the array.
9937     *
9938     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
9939     *  search starts at index 0.
9940     *
9941     * @returns index of element if it presents, -1 otherwise
9942     */
9943    public indexOf(searchElement: int): number {
9944        return this.indexOf(searchElement, 0)
9945    }
9946
9947    /**
9948     * Converts all elements of an array to strings and joins them using the specified separator.
9949     *
9950     * @param separator - separates one element of an array from the next in the resulting String.
9951     *
9952     * @returns joined representation
9953     */
9954    private final native joinInternal(separator: String): string;
9955
9956    /**
9957     * Adds all the elements of an array separated by the specified separator string
9958     *
9959     * @param separator A string used to separate one element of an array from the next in the
9960     * resulting String. If omitted, the array elements are separated with a comma.
9961     *
9962     * @returns joined representation
9963     */
9964    public join(separator?: String): string {
9965        if (separator == undefined) {
9966            return this.joinInternal(",")
9967        }
9968        return this.joinInternal(separator)
9969    }
9970
9971    /**
9972     * Returns an list of keys in Float64Array
9973     *
9974     * @returns iterator over keys
9975     */
9976    public keys(): IterableIterator<number> {
9977        return new Float64ArrayIteratorKeys(this)
9978    }
9979
9980    /**
9981     * Returns the index of the last occurrence of a value in Float64Array.
9982     *
9983     * @param searchElement The value to locate in the array.
9984     *
9985     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
9986     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
9987     *
9988     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
9989     */
9990    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
9991        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
9992    }
9993
9994    /**
9995     * Returns the index of the last occurrence of a value in Float64Array.
9996     *
9997     * @param searchElement The value to locate in the array.
9998     *
9999     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10000     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10001     *
10002     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10003     */
10004    public lastIndexOf(searchElement: number): number {
10005        return this.lastIndexOf(searchElement, this.lengthInt - 1)
10006    }
10007
10008    /**
10009     * Returns the index of the last occurrence of a value in Float64Array.
10010     *
10011     * @param searchElement The value to locate in the array.
10012     *
10013     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10014     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10015     *
10016     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10017     */
10018    public lastIndexOf(searchElement: number, fromIndex: int): number {
10019            return this.lastIndexOfImpl(searchElement, fromIndex)
10020    }
10021
10022    /**
10023     * Returns the index of the last occurrence of a value in Float64Array.
10024     *
10025     * @param searchElement The value to locate in the array.
10026     *
10027     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10028     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10029     *
10030     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10031     */
10032    public lastIndexOf(searchElement: int, fromIndex: int): number {
10033        return this.lastIndexOfImpl(searchElement as long, fromIndex)
10034    }
10035
10036    /**
10037     * Returns the index of the last occurrence of a value in Float64Array.
10038     *
10039     * @param searchElement The value to locate in the array.
10040     *
10041     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10042     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10043     *
10044     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10045     */
10046    private final native lastIndexOfImpl(searchElement: number, fromIndex: int): number
10047
10048    /**
10049     * Returns the index of the last occurrence of a value in Float64Array.
10050     *
10051     * @param searchElement The value to locate in the array.
10052     *
10053     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10054     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10055     *
10056     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10057     */
10058    private final native lastIndexOfImpl(searchElement: long, fromIndex: int): number
10059
10060    /**
10061     * Returns the index of the last occurrence of a value in Float64Array.
10062     *
10063     * @param searchElement The value to locate in the array.
10064     *
10065     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
10066     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
10067     *
10068     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
10069     */
10070    public lastIndexOf(searchElement: int): number {
10071        return this.lastIndexOf(searchElement, this.lengthInt - 1)
10072    }
10073
10074    /**
10075    * Creates a new Float64Array using initializer
10076    *
10077    * @param data initializer
10078    *
10079    * @returns a new Float64Array from data
10080    */
10081    public of(data: FixedArray<Object>): Float64Array {
10082        throw new Error("Float64Array.of: not implemented")
10083    }
10084
10085    /**
10086     * Creates a new Float64Array using reversed data from the current one
10087     *
10088     * @returns a new Float64Array using reversed data from the current one
10089     */
10090    public native reverse(): Float64Array
10091
10092    /**
10093     * Creates a slice of current Float64Array using range [begin, end)
10094     *
10095     * @param begin start index to be taken into slice
10096     *
10097     * @param end last index to be taken into slice
10098     *
10099     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
10100     *
10101     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
10102     */
10103    public slice(begin?: number, end?: number): Float64Array {
10104        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
10105    }
10106
10107    /**
10108     * Creates a slice of current Float64Array using range [begin, end)
10109     *
10110     * @param begin start index to be taken into slice
10111     *
10112     * @param end last index to be taken into slice
10113     *
10114     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
10115     *
10116     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
10117     */
10118    public slice(begin: number, end: number): Float64Array {
10119        return this.slice(begin as int, end as int)
10120    }
10121
10122    /**
10123     * Creates a slice of current Float64Array using range [begin, end)
10124     *
10125     * @param begin start index to be taken into slice
10126     *
10127     * @param end last index to be taken into slice
10128     *
10129     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
10130     *
10131     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
10132     */
10133    public slice(begin: number, end: int): Float64Array {
10134        return this.slice(begin as int, end as int)
10135    }
10136
10137    /**
10138     * Creates a slice of current Float64Array using range [begin, end)
10139     *
10140     * @param begin start index to be taken into slice
10141     *
10142     * @param end last index to be taken into slice
10143     *
10144     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
10145     *
10146     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
10147     */
10148    public slice(begin: int, end: number): Float64Array {
10149        return this.slice(begin as int, end as int)
10150    }
10151
10152    /**
10153     * Creates a slice of current Float64Array using range [begin, end)
10154     *
10155     * @param begin start index to be taken into slice
10156     *
10157     * @param end last index to be taken into slice
10158     *
10159     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
10160     *
10161     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
10162     */
10163    public slice(begin: int, end: int): Float64Array {
10164        const len: int = this.lengthInt
10165        const relStart = normalizeIndex(begin, len)
10166        const relEnd = normalizeIndex(end, len)
10167        let count = relEnd - relStart
10168        if (count < 0) {
10169            count = 0
10170        }
10171        let buf = this.buffer.slice(relStart * Float64Array.BYTES_PER_ELEMENT as int, relEnd * Float64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
10172        return new Float64Array(buf)
10173    }
10174
10175    /**
10176     * Creates a slice of current Float64Array using range [begin, this.length).
10177     *
10178     * @param begin start index to be taken into slice
10179     *
10180     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
10181     */
10182    public slice(begin: number): Float64Array {
10183        return this.slice(begin as int)
10184    }
10185
10186    /**
10187     * Creates a slice of current Float64Array using range [begin, this.length).
10188     *
10189     * @param begin start index to be taken into slice
10190     *
10191     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
10192     */
10193    public slice(begin: int): Float64Array {
10194        return this.slice(begin, this.lengthInt)
10195    }
10196
10197    /**
10198     * Creates a Float64Array with the same underlying ArrayBuffer
10199     *
10200     * @param begin start index, inclusive
10201     *
10202     * @param end last index, exclusive
10203     *
10204     * @returns new Float64Array with the same underlying ArrayBuffer
10205     */
10206    public subarray(begin?: number, end?: number): Float64Array {
10207        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
10208    }
10209
10210    /**
10211     * Creates a Float64Array with the same underlying ArrayBuffer
10212     *
10213     * @param begin start index, inclusive
10214     *
10215     * @param end last index, exclusive
10216     *
10217     * @returns new Float64Array with the same underlying ArrayBuffer
10218     */
10219    public subarray(begin: number, end: number): Float64Array {
10220        return this.subarray(begin as int, end as int)
10221    }
10222
10223    /**
10224     * Creates a Float64Array with the same underlying ArrayBuffer
10225     *
10226     * @param begin start index, inclusive
10227     *
10228     * @param end last index, exclusive
10229     *
10230     * @returns new Float64Array with the same underlying ArrayBuffer
10231     */
10232    public subarray(begin: number, end: int): Float64Array {
10233        return this.subarray(begin as int, end as int)
10234    }
10235
10236    /**
10237     * Creates a Float64Array with the same underlying ArrayBuffer
10238     *
10239     * @param begin start index, inclusive
10240     *
10241     * @param end last index, exclusive
10242     *
10243     * @returns new Float64Array with the same underlying ArrayBuffer
10244     */
10245    public subarray(begin: int, end: number): Float64Array {
10246        return this.subarray(begin as int, end as int)
10247    }
10248
10249    /**
10250     * Creates a Float64Array with the same underlying ArrayBuffer
10251     *
10252     * @param begin start index, inclusive
10253     *
10254     * @param end last index, exclusive
10255     *
10256     * @returns new Float64Array with the same underlying ArrayBuffer
10257     */
10258    public subarray(begin: int, end: int | undefined = this.lengthInt): Float64Array {
10259        const len: int = this.lengthInt
10260        const relStart = normalizeIndex(begin, len)
10261        const relEnd = normalizeIndex(end ?? this.lengthInt, len)
10262        let count = relEnd - relStart
10263        if (count < 0) {
10264            count = 0
10265        }
10266        return new Float64Array(this.buffer, relStart * Float64Array.BYTES_PER_ELEMENT as int, count)
10267    }
10268
10269    /**
10270     * Converts Float64Array to a string with respect to locale
10271     *
10272     * @param locales
10273     *
10274     * @param options
10275     *
10276     * @returns string representation
10277     */
10278    public toLocaleString(locales: Object, options: Object): string {
10279        throw new Error("Float64Array.toLocaleString: not implemented")
10280    }
10281
10282    /**
10283     * Converts Float64Array to a string with respect to locale
10284     *
10285     * @param locales
10286     *
10287     * @returns string representation
10288     */
10289    public toLocaleString(locales: Object): string {
10290        return this.toLocaleString(new Object(), new Object())
10291    }
10292
10293    /**
10294     * Converts Float64Array to a string with respect to locale
10295     *
10296     * @returns string representation
10297     */
10298    public toLocaleString(): string {
10299        let res: StringBuilder = new StringBuilder("")
10300        for (let i = 0; i < this.lengthInt - 1; ++i) {
10301            res.append((this.getUnsafe(i) as Number).toLocaleString())
10302            res.append(",")
10303        }
10304        if (this.lengthInt > 0) {
10305            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
10306        }
10307        return res.toString()
10308    }
10309
10310    /**
10311     * Creates a reversed copy
10312     *
10313     * @returns a reversed copy
10314     */
10315    public final native toReversed(): Float64Array
10316
10317    /**
10318     * Creates a sorted copy
10319     *
10320     * @returns a sorted copy
10321     */
10322    public toSorted(): Float64Array {
10323        return new Float64Array(this).sort()
10324    }
10325
10326    /**
10327     * Returns a string representation of the Float64Array
10328     *
10329     * @returns a string representation of the Float64Array
10330     */
10331    public override toString(): string {
10332        return this.join(",")
10333    }
10334
10335    /**
10336     * Returns array values iterator
10337     *
10338     * @returns an iterator
10339     */
10340    public values(): IterableIterator<Number> {
10341        return new Float64ArrayIterator(this)
10342    }
10343
10344    /**
10345     * Iteratorable interface implementation
10346     *
10347     * @returns iterator over all elements
10348     */
10349    public override $_iterator(): IterableIterator<Number> {
10350        return this.values()
10351    }
10352
10353    /**
10354     * Creates a copy with replaced value on index
10355     *
10356     * @param index
10357     *
10358     * @param value
10359     *
10360     * @returns an Float64Array with replaced value on index
10361     */
10362    public with(index: number, value: number): Float64Array {
10363        return this.with(index as int, value as double)
10364    }
10365
10366    /**
10367     * Creates a copy with replaced value on index
10368     *
10369     * @param index
10370     *
10371     * @param value
10372     *
10373     * @returns an Float64Array with replaced value on index
10374     */
10375    public with(index: int, value: double): Float64Array {
10376        let res = new Float64Array(this)
10377        res.set(index, value)
10378        return res
10379    }
10380
10381    /// === with element lambda functions ===
10382
10383    /**
10384     * Finds the last element in the Float64Array that satisfies the condition
10385     *
10386     * @param fn condition
10387     *
10388     * @returns the last element that satisfies fn
10389     */
10390    public findLast(fn: (val: number) => boolean): number {
10391        let newF: (val: number, index: number, array: Float64Array) => boolean =
10392            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
10393        return this.findLast(newF) as number
10394    }
10395
10396    /**
10397     * Sorts in-place by numeric value in ascending order.
10398     *
10399     * @returns sorted Float64Array
10400     */
10401    public native sort(): this;
10402
10403    /**
10404     * Sorts in-place
10405     *
10406     * @param compareFn comparator _  used to determine the order of the elements.
10407     * compareFn returns a negative value if first argument is less than second argument,
10408     * zero if they're equal and a positive value otherwise.
10409     *
10410     * @returns sorted Float64Array
10411     */
10412    public sort(compareFn?: (a: number, b: number) => number): this {
10413        if (compareFn == undefined) {
10414            this.sort()
10415            return this
10416        }
10417        let arr: FixedArray<double> = new double[this.lengthInt]
10418        for (let i = 0; i < this.lengthInt; ++i) {
10419            arr[i] = this.getUnsafe(i)
10420        }
10421
10422        let cmp = (l: double, r: double): number => {
10423            const result = compareFn!(l as number, r as number)
10424            return result
10425        }
10426        const MAX_SHORT_LENGTH = 24
10427        if (arr.length > MAX_SHORT_LENGTH) {
10428            arr = mergeSort(arr, cmp)
10429        } else {
10430            sort(arr, cmp)
10431        }
10432        for (let i = 0; i < arr.length; ++i) {
10433            this.setUnsafe(i, arr[i])
10434        }
10435        return this
10436    }
10437
10438    /**
10439     * Determines whether the specified callback function returns true for any element of an array.
10440     *
10441     * @param predicate A function that accepts three arguments.
10442     * The some method calls the predicate function for each element in the array
10443     * until the predicate returns a true or until the end of the array.
10444     *
10445     * @returns false unless predicate function returns true for an array element,
10446     * in which case true is immediately returned.
10447     */
10448    public some(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
10449        for (let i = 0; i < this.lengthInt; ++i) {
10450            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
10451                return true
10452            }
10453        }
10454        return false
10455    }
10456
10457    /**
10458     * Calls the specified callback function for all the elements in an array.
10459     * The return value of the callback function is the accumulated result,
10460     * and is provided as an argument in the next call to the callback function.
10461     *
10462     * @param callbackfn A function that accepts four arguments.
10463     * The reduce method calls the callbackfn function one time for each element in the array.
10464     *
10465     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
10466     * The first call to the callbackfn function provides this value as an argument.
10467     *
10468     * @returns The value that results from running the callback function to completion over the entire typed array.
10469     */
10470    public reduce<U = number>(
10471                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
10472                initialValue: U): U {
10473        let accumulatedValue = initialValue
10474        for (let i = 0; i < this.lengthInt; ++i) {
10475            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
10476        }
10477        return accumulatedValue
10478    }
10479
10480    /**
10481     * Calls the specified callback function for all the elements in an array.
10482     * The return value of the callback function is the accumulated result,
10483     * and is provided as an argument in the next call to the callback function.
10484     *
10485     * @param callbackfn A function that accepts four arguments.
10486     * The reduce method calls the callbackfn function one time for each element in the array.
10487     * The first call to the callbackfn function provides array first element value as an argument
10488     *
10489     * @returns The value that results from running the callback function to completion over the entire typed array.
10490     * calling reduce method on an empty array without an initial value creates a TypeError
10491     */
10492    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
10493        if (this.lengthInt == 0) {
10494            throw new TypeError("Reduce of empty array with no initial value")
10495        }
10496
10497        let accumulatedValue = this.getUnsafe(0) as number
10498        for (let i = 1; i < this.lengthInt; ++i) {
10499            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
10500        }
10501        return accumulatedValue
10502    }
10503
10504    /**
10505     * Calls the specified callback function for all the elements in an array, in descending order.
10506     * The return value of the callback function is the accumulated result,
10507     * and is provided as an argument in the next call to the callback function.
10508     *
10509     * @param callbackfn A function that accepts four arguments.
10510     * The reduceRight method calls the callbackfn function one time for each element in the array.
10511     *
10512     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
10513     * The first call to the callbackfn function provides this value as an argument.
10514     *
10515     * @returns The value that results from running the callback function to completion over the entire typed array.
10516     */
10517    public reduceRight<U = number>(
10518                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
10519                initialValue: U): U {
10520        let accumulatedValue = initialValue
10521        for (let i = this.lengthInt - 1; i >= 0; --i) {
10522            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
10523        }
10524        return accumulatedValue
10525    }
10526
10527
10528    /**
10529     * Calls the specified callback function for all the elements in an array, in descending order.
10530     * The return value of the callback function is the accumulated result,
10531     * and is provided as an argument in the next call to the callback function.
10532     *
10533     * @param callbackfn A function that accepts four arguments.
10534     * The reduceRight method calls the callbackfn function one time for each element in the array.
10535     * The first call to the callbackfn function provides array last element value as an argument
10536     *
10537     * @returns The value that results from running the callback function to completion over the entire typed array.
10538     * calling reduceRight method on an empty array without an initial value creates a TypeError
10539     */
10540    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
10541        if (this.lengthInt == 0) {
10542            throw new TypeError("Reduce of empty array with no initial value")
10543        }
10544
10545        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
10546        for (let i = this.lengthInt - 2; i >= 0; --i) {
10547            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
10548        }
10549        return accumulatedValue
10550    }
10551
10552   /**
10553    * Creates a new Float64Array using fn(arr[i]) over all elements of current Float64Array.
10554    *
10555    * @param fn a function to apply for each element of current Float64Array
10556    *
10557    * @returns a new Float64Array where for each element from current Float64Array fn was applied
10558    */
10559    public map(fn: (val: number, index: number, array: Float64Array) => number): Float64Array {
10560        let resBuf = new ArrayBuffer(this.lengthInt * Float64Array.BYTES_PER_ELEMENT as int)
10561        let res = new Float64Array(resBuf, 0, resBuf.getByteLength() / Float64Array.BYTES_PER_ELEMENT as int)
10562        for (let i = 0; i < this.lengthInt; ++i) {
10563            res.set(i, fn(this.getUnsafe(i) as number, i as number, this) as double)
10564        }
10565        return res
10566    }
10567
10568    /**
10569     * Determines whether the specified callback function returns true for all elements of an array.
10570     *
10571     * @param predicate A function that accepts three arguments.
10572     * The every method calls the predicate function for each element in the array until the predicate returns a false,
10573     * or until the end of the array.
10574     *
10575     * @returns true unless predicate function returns a false for an array element,
10576     * in which case false is immediately returned.
10577     */
10578    public every(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
10579        for (let i = 0; i < this.lengthInt; ++i) {
10580            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
10581                return false
10582            }
10583        }
10584        return true
10585    }
10586
10587    /**
10588     * Creates a new Float64Array from current Float64Array based on a condition fn.
10589     *
10590     * @param fn the condition to apply for each element
10591     *
10592     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
10593     */
10594    public filter(fn: (val: number, index: number, array: Float64Array) => boolean): Float64Array {
10595        let markers : FixedArray<boolean> = new boolean[this.lengthInt]
10596        let resLen = 0
10597        for (let i = 0; i < this.lengthInt; ++i) {
10598            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
10599            if (markers[i]) {
10600                ++resLen
10601            }
10602        }
10603        let resBuf = new ArrayBuffer(resLen * Float64Array.BYTES_PER_ELEMENT as int)
10604        let res = new Float64Array(resBuf, 0)
10605        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
10606            if (markers[i]) {
10607                res.set(j, this.getUnsafe(i))
10608                ++j
10609            }
10610        }
10611        return res
10612    }
10613
10614    /**
10615     * Returns the value of the first element in the array where predicate is true, and undefined
10616     * otherwise
10617     *
10618     * @param predicate find calls predicate once for each element of the array, in ascending
10619     * order, until it finds one where predicate returns true. If such an element is found, find
10620     * immediately returns that element value. Otherwise, find returns undefined
10621     *
10622     * @returns number | undefined
10623     */
10624    public find(predicate: (value: number, index: number, obj: Float64Array) => boolean): number | undefined {
10625        for (let i = 0; i < this.lengthInt; ++i) {
10626            let val = this.getUnsafe(i)
10627            if (predicate(val as number, i as number, this)) {
10628                return val as number
10629            }
10630        }
10631        return undefined
10632    }
10633
10634    /**
10635     * Returns the index of the first element in the array where predicate is true, and -1
10636     * otherwise
10637     *
10638     * @param predicate find calls predicate once for each element of the array, in ascending
10639     * order, until it finds one where predicate returns true. If such an element is found,
10640     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10641     *
10642     * @returns number
10643     */
10644    public findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean): number {
10645        for (let i = 0; i < this.lengthInt; ++i) {
10646            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
10647                return i as number
10648            }
10649        }
10650        return -1 as number
10651    }
10652
10653    /**
10654     * Finds the last element in the Float64Array that satisfies the condition
10655     *
10656     * @param fn condition
10657     *
10658     * @returns the last element that satisfies fn
10659     */
10660    public findLast(fn: (val: number, index: number, array: Float64Array) => boolean): double {
10661        for (let i = this.lengthInt - 1; i >= 0; --i) {
10662            let val = this.getUnsafe(i)
10663            if (fn(val as number, i as number, this)) {
10664                return val
10665            }
10666        }
10667        throw new Error("Float64Array.findLast: not implemented if an element was not found")
10668    }
10669
10670    /**
10671     * Finds an index of the last element in the Float64Array that satisfies the condition
10672     *
10673     * @param fn condition
10674     *
10675     * @returns the index of the last element that satisfies fn, -1 otherwise
10676     */
10677    public findLastIndex(fn: (val: number, index: number, array: Float64Array) => boolean): number {
10678        for (let i = this.lengthInt - 1; i >= 0; --i) {
10679            let val = this.getUnsafe(i)
10680            if (fn(val as number, i as number, this)) {
10681                return i
10682            }
10683        }
10684        return -1 as number
10685    }
10686
10687    /**
10688     * Performs the specified action for each element in Float64Array
10689     *
10690     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10691     * callbackfn function one time for each element in the array.
10692     *
10693     * @returns None
10694     */
10695    public forEach(callbackfn: (value: number, index: number, array: Float64Array) => void): void {
10696        for (let i = 0; i < this.lengthInt; ++i) {
10697            callbackfn(this.getUnsafe(i) as number, i as number, this)
10698        }
10699    }
10700
10701    /**
10702     * Returns the object itself
10703     *
10704     * @returns Float64Array
10705     */
10706    public valueOf(): Float64Array {
10707        return this
10708    }
10709
10710    private final native getUnsafe(index: int): double
10711
10712    internal setUnsafe(insertPos: int, val: double): void {
10713        let startByte = insertPos * Float64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
10714        let bits = Double.bitCastToLong(val)
10715        if (IS_LITTLE_ENDIAN) {
10716            for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
10717                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10718                this.buffer.set(startByte + i, byteVal)
10719            }
10720        } else {
10721            for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; i++) {
10722                let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10723                this.buffer.set(startByte + 7 - i, byteVal)
10724            }
10725        }
10726    }
10727
10728    /** Underlying ArrayBuffer */
10729    public readonly buffer: ArrayBuffer
10730
10731    /** Byte offset within the underlying ArrayBuffer */
10732    public readonly byteOffset: number
10733
10734    /** Number of bytes used */
10735    public readonly byteLength: number
10736
10737    /** String \"Float64Array\" */
10738    public readonly name = "Float64Array"
10739}
10740