• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16// Autogenerated file. DO NOT EDIT
17
18package escompat
19
20class Int8ArrayIteratorKeys implements IterableIterator<number> {
21    private length: int
22    private idx: int = 0
23
24    constructor(parent: Int8Array) {
25        this.length = parent.length as int
26    }
27
28    public override $_iterator(): IterableIterator<number> {
29        return this
30    }
31
32    override next(): IteratorResult<number> {
33        if (this.idx < 0 || this.idx >= this.length) {
34            return new IteratorResult<number>()
35        }
36        return new IteratorResult<number>(false, this.idx++ as number)
37    }
38}
39
40class Int8ArrayIterator implements IterableIterator<Number> {
41    private parent: Int8Array
42    private idx: int = 0
43
44    constructor(parent: Int8Array) {
45        this.parent = parent
46    }
47
48    public override $_iterator(): IterableIterator<Number> {
49        return this
50    }
51
52    override next(): IteratorResult<Number> {
53        if (this.idx < 0 || this.idx >= this.parent.length as int) {
54            return new IteratorResult<Number>()
55        }
56        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
57    }
58}
59
60class Int8ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
61    private parent: Int8Array
62    private idx: int = 0
63
64    constructor(parent: Int8Array) {
65        this.parent = parent
66    }
67
68    public override $_iterator(): IterableIterator<[Number, Number]> {
69        return this
70    }
71
72    override next(): IteratorResult<[Number, Number]> {
73        if (this.idx < 0 || this.idx >= this.parent.length as int) {
74            return new IteratorResult<[Number, Number]>()
75        }
76        return new IteratorResult<[Number, Number]>(
77            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
78        )
79    }
80}
81
82
83/**
84 * JS Int8Array API-compatible class
85 */
86export final class Int8Array implements Iterable<Number>, ArrayLike<Number> {
87    public static readonly BYTES_PER_ELEMENT: number = 1
88    internal readonly lengthInt: int
89
90    /**
91     * Creates an empty Int8Array.
92     */
93    public constructor() {
94        this(0 as int)
95    }
96
97    /**
98     * Creates an Int8Array with respect to data accessed via Iterable<Number> interface
99     */
100    public constructor(elements: Iterable<Number>) {
101        // NOTE (ikorobkov): dealing with this overload is tricky
102        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
103        let arr = Array.from<Number>(elements)
104        this.byteLength = arr.length * Int8Array.BYTES_PER_ELEMENT as int
105        this.lengthInt = arr.length as int
106        this.buffer = new ArrayBuffer(this.byteLength as int)
107        this.byteOffset = 0
108        for (let i: int = 0; i < this.lengthInt; ++i) {
109            this.setUnsafe(i, arr.$_get(i).byteValue())
110        }
111    }
112
113    /**
114     * Creates an Int8Array with respect to data, byteOffset and length.
115     *
116     * @param buf data initializer
117     *
118     * @param byteOffset byte offset from begin of the buf
119     *
120     * @param length size of elements of type byte in newly created Int8Array
121     */
122    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
123        let intByteOffset: int = 0
124        if (byteOffset != undefined) {
125            intByteOffset = byteOffset.intValue()
126            if (intByteOffset < 0) {
127                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
128            }
129        }
130        let intByteLength: int
131        if (buf instanceof ArrayBuffer) {
132            intByteLength = (buf as ArrayBuffer).getByteLength()
133        } else if (buf instanceof SharedArrayBuffer) {
134            intByteLength = (buf as SharedArrayBuffer).getByteLength()
135        } else {
136            throw new Error("unexpected type of ArrayBufferLike")
137        }
138        intByteLength = intByteLength - 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.intValue()
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: ArrayBufferLike, 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: ArrayBufferLike, 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: ArrayBufferLike, 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: ArrayBufferLike, 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: ArrayBufferLike, 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> | ArrayBufferLike) {
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("ArrayBufferLike.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 SharedArrayBuffer) {
242            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
243            if (this.byteLength % Int8Array.BYTES_PER_ELEMENT as int != 0) {
244               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 1 as Int8Array.BYTES_PER_ELEMENT")
245            }
246            this.lengthInt = this.byteLength / Int8Array.BYTES_PER_ELEMENT as int
247            this.buffer = buf as SharedArrayBuffer
248            this.byteOffset = 0
249        } else if (buf instanceof ArrayLike) {
250            // NOTE (ikorobkov): dealing with this overload is tricky
251            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
252            let arr = Array.from<Number>((buf as ArrayLike<Number>))
253            this.byteLength = arr.length as int * Int8Array.BYTES_PER_ELEMENT as int
254            this.lengthInt = arr.length as int
255            this.buffer = new ArrayBuffer(this.byteLength as int)
256            this.byteOffset = 0
257            for (let i: int = 0; i < this.lengthInt; ++i) {
258                this.setUnsafe(i, arr.$_get(i).byteValue())
259            }
260        } else {
261            throw new Error("unexpected type of buf")
262        }
263    }
264
265    /**
266     * Creates an Int8Array with respect to length.
267     *
268     * @param length data initializer
269     */
270    public constructor(length: int) {
271        if (length < 0) {
272            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
273        }
274        this.lengthInt = length
275        this.byteLength = length * Int8Array.BYTES_PER_ELEMENT as int
276        this.byteOffset = 0
277        this.buffer = new ArrayBuffer(this.byteLength as int)
278    }
279
280    /**
281     * Creates an Int8Array with respect to length.
282     *
283     * @param length data initializer
284     */
285    public constructor(length: number) {
286        this(length as int)
287    }
288
289    /**
290     * Creates a copy of Int8Array.
291     *
292     * @param other data initializer
293     */
294    public constructor(other: Int8Array) {
295        if (other.buffer instanceof ArrayBuffer) {
296            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
297        } else if (other.buffer instanceof SharedArrayBuffer) {
298            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
299        } else {
300            throw new Error("unexpected type of buffer")
301        }
302        this.byteLength = other.byteLength
303        this.lengthInt = other.length as int
304        this.byteOffset = 0
305    }
306
307    /**
308     * Creates an Int8Array from number[]
309     */
310    public constructor(numbers: number[]) {
311        this(numbers.length)
312        for (let i: int = 0; i < this.lengthInt; ++i) {
313            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
314        }
315    }
316
317    /**
318     * Creates an Int8Array from int[]
319     */
320    public constructor(numbers: int[]) {
321        this(numbers.length)
322        for (let i: int = 0; i < this.lengthInt; ++i) {
323            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as byte)
324        }
325    }
326
327    internal zeroIfInfinity(val: number): number {
328        if ((val == Infinity) || (val == -Infinity)) {
329            return 0 as number
330        }
331        return val as number
332    }
333
334    internal zeroIfInfinity(val: byte): byte {
335        if ((val == Infinity) || (val == -Infinity)) {
336            return 0 as byte
337        }
338        return val
339    }
340
341    /**
342     * Assigns val as element on index.
343     *
344     * @param val value to set
345     *
346     * @param index index to change
347     */
348    public $_set(index: number, val: number): void {
349        this.$_set(index as int, val)
350    }
351
352    /**
353     * Assigns val as element on index.
354     *
355     * @param val value to set
356     *
357     * @param index index to change
358     */
359    public $_set(index: int, val: number): void {
360        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
361        if (index < 0 || index >= this.lengthInt) {
362            throw new RangeError("invalid index")
363        }
364        let v = this.zeroIfInfinity(val)
365        this.setUnsafe(index, v as byte)
366    }
367
368    /**
369     * Assigns val as element on index.
370     *
371     * @param val value to set
372     *
373     * @param index index to change
374     */
375    public $_set(index: number, val: int): void {
376        this.$_set(index as int, val)
377    }
378
379    /**
380     * Assigns val as element on index.
381     *
382     * @param val value to set
383     *
384     * @param index index to change
385     */
386    public $_set(index: int, val: int): void {
387        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
388        if (index < 0 || index >= this.lengthInt) {
389            throw new RangeError("invalid index")
390        }
391        let v = this.zeroIfInfinity(val as byte)
392        this.setUnsafe(index, v as byte)
393    }
394
395    /**
396     * Assigns val as element on index.
397     *
398     * @param val value to set
399     *
400     * @param index index to change
401     */
402    public $_set(index: number, val: byte): void {
403        this.$_set(index as int, val)
404    }
405
406    /**
407     * Assigns val as element on index.
408     *
409     * @param val value to set
410     *
411     * @param index index to change
412     */
413    public $_set(index: int, val: byte): void {
414        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
415        if (index < 0 || index >= this.lengthInt) {
416            throw new RangeError("invalid index")
417        }
418        let v = this.zeroIfInfinity(val)
419        this.setUnsafe(index, v)
420    }
421
422    /** Number of byte stored in Int8Array */
423    public get length(): number {
424        return this.lengthInt
425    }
426
427    /**
428     * Returns an instance of number at passed index.
429     *
430     * @param index index to look at
431     *
432     * @returns a primitive at index
433     */
434    public override $_get(index: number): Number {
435        return this.$_get(index as int) as Number
436    }
437
438    /**
439     * Returns an instance of number at passed index.
440     *
441     * @param index index to look at
442     *
443     * @returns a primitive at index
444     */
445    public $_get(index: int): number {
446        if (index < 0 || index >= this.lengthInt) {
447            throw new RangeError("invalid index")
448        }
449        return this.getUnsafe(index) as number
450    }
451
452    /**
453     * Returns an instance of primitive type at passed index.
454     *
455     * @param index index to look at
456     *
457     * @returns a primitive at index
458     */
459    public at(index: number): Number | undefined {
460        return this.at(index as int)
461    }
462
463    /**
464     * Returns an instance of primitive type at passed index.
465     *
466     * @param index index to look at
467     *
468     * @returns a primitive at index
469     */
470    public at(index: int): Number | undefined {
471        let k: int
472        if (index >= 0) {
473            k = index
474        } else {
475            k = this.lengthInt + index
476        }
477        if (k < 0 || k >= this.lengthInt) {
478            return undefined
479        }
480        return new Number(this.getUnsafe(k))
481    }
482
483    /**
484     * Makes a copy of internal elements to targetPos from startPos to endPos.
485     *
486     * @param target insert index to place copied elements
487     *
488     * @param start start index to begin copy from
489     *
490     * @param end last index to end copy from, excluded
491     *
492     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
493     */
494    public copyWithin(target: number, start: number, end?: number): Int8Array {
495        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
496    }
497
498    /**
499     * Makes a copy of internal elements to targetPos from startPos to endPos.
500     *
501     * @param target insert index to place copied elements
502     *
503     * @param start start index to begin copy from
504     *
505     * @param end last index to end copy from, excluded
506     *
507     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
508     */
509    public copyWithin(target: int, start: number, end?: number): Int8Array {
510        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
511    }
512
513    /**
514     * Makes a copy of internal elements to targetPos from startPos to endPos.
515     *
516     * @param target insert index to place copied elements
517     *
518     * @param start start index to begin copy from
519     *
520     * @param end last index to end copy from, excluded
521     *
522     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
523     */
524    public copyWithin(target: number, start: int, end?: number): Int8Array {
525        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
526    }
527
528    /**
529     * Makes a copy of internal elements to targetPos from startPos to endPos.
530     *
531     * @param target insert index to place copied elements
532     *
533     * @param start start index to begin copy from
534     *
535     * @param end last index to end copy from, excluded
536     *
537     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
538     */
539    public copyWithin(target: int, start: int, end?: number): Int8Array {
540        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
541    }
542
543    /**
544     * Makes a copy of internal elements to targetPos from startPos to endPos.
545     *
546     * @param target insert index to place copied elements
547     *
548     * @param start start index to begin copy from
549     *
550     * @param end last index to end copy from, excluded
551     *
552     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
553     */
554    public copyWithin(target: int, start: int, end: int): Int8Array {
555        let toPos = normalizeIndex(target, this.lengthInt)
556        let fromPos = normalizeIndex(start, this.lengthInt)
557        const finalPos = normalizeIndex(end, this.lengthInt)
558        let count: int = finalPos - fromPos
559        if (count > (this.lengthInt - toPos)) {
560            count = this.lengthInt - toPos
561        }
562        let direction: int = 1
563        if ((fromPos < toPos) && (toPos < fromPos + count)) {
564            fromPos = fromPos + count - 1
565            toPos   = toPos   + count - 1
566            direction = -1
567        }
568        while (count > 0) {
569            const value = this.getUnsafe(fromPos)
570            this.setUnsafe(toPos, value)
571            fromPos = fromPos + direction
572            toPos = toPos + direction
573            --count
574        }
575        return this
576    }
577
578    /**
579     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
580     *
581     * @param target insert index to place copied elements
582     *
583     * See rules of parameters normalization:
584     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
585     */
586    public copyWithin(target: number): Int8Array {
587        return this.copyWithin(target as int)
588    }
589
590    /**
591     * Makes a copy of internal elements to targetPos from begin to end of Int8Array.
592     *
593     * @param target insert index to place copied elements
594     *
595     * See rules of parameters normalization:
596     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
597     */
598    public copyWithin(target: int): Int8Array {
599        return this.copyWithin(target, 0, this.lengthInt)
600    }
601
602    /**
603     * Returns an array of key, value pairs for every entry in the Int8Array
604     *
605     * @returns key, value pairs for every entry in the array
606     */
607    public entries(): IterableIterator<[Number, Number]> {
608        return new Int8ArrayIteratorEntries(this)
609    }
610
611    /**
612     * Fills the Int8Array with specified value
613     *
614     * @param value new valuy
615     *
616     * @returns modified Int8Array
617     */
618    public fill(value: number, start?: number, end?: number): this {
619        value = this.zeroIfInfinity(value)
620        this.fill(value as byte, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
621        return this
622    }
623
624    /**
625     * Fills the Int8Array with specified value
626     *
627     * @param value new valuy
628     *
629     * @returns modified Int8Array
630     */
631    public fill(value: number, start: int, end?: number): this {
632        value = this.zeroIfInfinity(value)
633        this.fill(value as byte, start as int, asIntOrDefault(end, this.lengthInt))
634        return this
635    }
636
637    /**
638     * Fills the Int8Array with specified value
639     *
640     * @param value new valuy
641     *
642     * @returns modified Int8Array
643     */
644    public fill(value: number, start: int, end: number): this {
645        value = this.zeroIfInfinity(value)
646        this.fill(value as byte, start as int, end as int)
647        return this
648    }
649
650    /**
651     * Fills the Int8Array with specified value
652     *
653     * @param value new valuy
654     *
655     * @returns modified Int8Array
656     */
657    public fill(value: number, start: number, end: int): this {
658        value = this.zeroIfInfinity(value)
659        this.fill(value as byte, start as int, end as int)
660        return this
661    }
662
663    /**
664     * Fills the Int8Array with specified value
665     *
666     * @param value new valuy
667     *
668     * @returns modified Int8Array
669     */
670    public fill(value: number, start: int, end: int): this {
671        value = this.zeroIfInfinity(value)
672        this.fill(value as byte, start as int, end as int)
673        return this
674    }
675
676    /**
677     * Fills the Int8Array with specified value
678     *
679     * @param value new valuy
680     *
681     * @returns modified Int8Array
682     */
683    public fill(value: byte, start?: number, end?: number): this {
684        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
685        return this
686    }
687
688    /**
689     * Fills the Int8Array with specified value
690     *
691     * @param value new valuy
692     *
693     * @returns modified Int8Array
694     */
695    public fill(value: byte, start: int, end?: number): this {
696        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
697        return this
698    }
699
700    /**
701     * Fills the Int8Array with specified value
702     *
703     * @param value new valuy
704     *
705     * @returns modified Int8Array
706     */
707    public fill(value: byte, start: int, end: number): this {
708        this.fill(value, start as int, end as int)
709        return this
710    }
711
712    /**
713     * Fills the Int8Array with specified value
714     *
715     * @param value new valuy
716     *
717     * @returns modified Int8Array
718     */
719    public fill(value: byte, start: number, end: int): this {
720        this.fill(value, start as int, end as int)
721        return this
722    }
723
724    /**
725     * Fills the Int8Array with specified value
726     *
727     * @param value new valuy
728     *
729     * @returns modified Int8Array
730     */
731    public fill(value: byte, start: int, end: int): this {
732        const k = normalizeIndex(start, this.lengthInt)
733        const finalPos = normalizeIndex(end, this.lengthInt)
734        for (let i: int = k; i < finalPos; ++i) {
735            this.setUnsafe(i, value)
736        }
737        return this
738    }
739
740    /**
741     * Assigns val as element on insertPos.
742     * @description Added to avoid (un)packing a single value into array to use overloaded set(byte[], insertPos)
743     *
744     * @param val value to set
745     *
746     * @param insertPos index to change
747     */
748    public set(insertPos: number, val: number): void {
749        this.$_set(insertPos, val)
750    }
751
752    /**
753     * Assigns val as element on insertPos.
754     * @description Added to avoid (un)packing a single value into array to use overloaded set(byte[], insertPos)
755     *
756     * @param val value to set
757     *
758     * @param insertPos index to change
759     */
760    public set(insertPos: int, val: byte): void {
761        this.$_set(insertPos, val)
762    }
763
764    /**
765     * Copies all elements of arr to the current Int8Array starting from insertPos.
766     *
767     * @param arr array to copy data from
768     *
769     * @param insertPos start index where data from arr will be inserted
770     *
771     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
772     */
773    public set(arr: number[], insertPos: number): void {
774        const offset = insertPos as int
775        if (offset < 0 || offset + arr.length > this.lengthInt) {
776            throw new RangeError("offset is out of bounds")
777        }
778        for (let i = 0; i < arr.length as int; ++i) {
779            let v = this.zeroIfInfinity(arr[i])
780            this.setUnsafe(offset + i, v as byte)
781        }
782    }
783
784    /**
785     * Copies all elements of arr to the current Int8Array starting from insertPos.
786     *
787     * @param arr array to copy data from
788     *
789     * @param insertPos start index where data from arr will be inserted
790     *
791     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
792     */
793    public set(arr: byte[], insertPos: int): void {
794        const offset = insertPos as int
795        if (offset < 0 || offset + arr.length > this.lengthInt) {
796            throw new RangeError("offset is out of bounds")
797        }
798        for (let i = 0; i < arr.length as int; ++i) {
799            let v = this.zeroIfInfinity(arr[i])
800            this.setUnsafe(offset + i, v)
801        }
802    }
803
804    /**
805     * Copies all elements of arr to the current Int8Array.
806     *
807     * @param arr array to copy data from
808     */
809    public set(arr: number[]): void {
810        this.set(arr, 0 as number)
811    }
812
813    /**
814     * Copies all elements of arr to the current Int8Array.
815     *
816     * @param arr array to copy data from
817     */
818    public set(arr: byte[]): void {
819        this.set(arr, 0 as int)
820    }
821
822    /**
823     * Copies elements from an ArrayLike object to the Int8Array.
824     *
825     * @param array An ArrayLike object containing the elements to copy.
826     *
827     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
828     */
829    public set(array: ArrayLike<number>, offset: number = 0): void {
830        const insertPos = offset as int
831        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
832            throw new RangeError("offset is out of bounds")
833        }
834        for (let i = 0; i < array.length as int; ++i) {
835            let v = this.zeroIfInfinity(array[i])
836            this.setUnsafe(insertPos + i, v as byte)
837        }
838    }
839
840    /**
841     * Returns a new array from a set of elements.
842     *
843     * @param items a set of elements to include in the new array object.
844     *
845     * @returns new Int8Array
846     */
847    public static of(...items: number[]): Int8Array {
848        let res = new Int8Array(items.length as int)
849        for (let i: int = 0; i < items.length; i++) {
850            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as byte)
851        }
852        return res
853    }
854
855    /**
856     * Returns a new array from a set of elements.
857     *
858     * @param items a set of elements to include in the new array object.
859     *
860     * @returns new Int8Array
861     */
862    public static of(...items: int[]): Int8Array {
863        let res = new Int8Array(items.length as int)
864        for (let i: int = 0; i < items.length; i++) {
865            res.setUnsafe(i, items[i] as byte)
866        }
867        return res
868    }
869
870    /**
871     * Returns a new array from a set of elements.
872     *
873     * @param items a set of elements to include in the new array object.
874     *
875     * @returns new Int8Array
876     */
877    public static of(...items: byte[]): Int8Array {
878        let res = new Int8Array(items.length as int)
879        for (let i: int = 0; i < items.length; i++) {
880            res.setUnsafe(i, items[i])
881        }
882        return res
883    }
884
885    /**
886     * Returns a new array from a set of elements.
887     *
888     * @param items a set of elements to include in the new array object.
889     *
890     * @returns new Int8Array
891     */
892    public static of(): Int8Array {
893        return new Int8Array(0 as int)
894    }
895
896    /**
897     * Creates an array from an array-like or iterable object.
898     *
899     * @param arrayLike An array-like or iterable object to convert to an array.
900     *
901     * @returns new Int8Array
902     */
903    public static from(arrayLike: ArrayLike<number>): Int8Array {
904        return Int8Array.from<number>(arrayLike, (x: number, k: number): number => x)
905    }
906
907    /**
908     * Creates an array from an array-like or iterable object.
909     *
910     * @param arrayLike An array-like or iterable object to convert to an array.
911     *
912     * @param mapfn A mapping function to call on every element of the array.
913     *
914     * @returns new Int8Array
915     */
916    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int8Array {
917        if (mapfn == undefined) {
918            mapfn = (v: number, k: number): number => { return v }
919        }
920        // Calc length of items inside arrayLike, save length into i variable
921        let i: long = 0
922        let iter = arrayLike.$_iterator()
923        while (true) {
924            const v = iter.next()
925            if (v.done) {
926                break
927            }
928            i++
929        }
930
931        let res = new Int8Array(i as int)
932        i = 0
933        iter = arrayLike.$_iterator()
934        while (true) {
935            const v = iter.next()
936            if (v.done) {
937                return res
938            }
939            res.setUnsafe(i as int, res.zeroIfInfinity((mapfn)!(v.value as number, i as number)) as byte)
940            i++
941        }
942    }
943
944
945    /**
946     * Creates an array from an array-like or iterable object.
947     *
948     * @param arrayLike An array-like or iterable object to convert to an array.
949     *
950     * @param mapfn A mapping function to call on every element of the array.
951     *
952     * @returns new Int8Array
953     */
954    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): Int8Array {
955        let res = new Int8Array(arrayLike.length)
956        // 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
957        const idx = new int[1]
958        idx[0] = 0
959        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
960            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as byte)
961            idx[0] += 1
962        })
963        return res
964    }
965
966    /**
967     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
968     *
969     * @param searchElement The element to search for
970     *
971     * @param fromIndex The position in this array at which to begin searching for searchElement
972     *
973     * @returns true if searchElement is in Int8Array, false otherwise
974     */
975    public includes(searchElement: number, fromIndex?: number): boolean {
976        if (isNaN(searchElement)) {
977            return false
978        }
979        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
980    }
981
982    /**
983     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
984     *
985     * @param searchElement The element to search for
986     *
987     * @param fromIndex The position in this array at which to begin searching for searchElement
988     *
989     * @returns true if e is in Int8Array, false otherwise
990     */
991    public includes(searchElement: byte, fromIndex: int): boolean {
992        return this.indexOf(searchElement as int, fromIndex) != -1
993    }
994
995    /**
996     * Determines whether Int8Array includes a certain element, returning true or false as appropriate
997     *
998     * @param searchElement The element to search for
999     *
1000     * @param fromIndex The position in this array at which to begin searching for searchElement
1001     *
1002     * @returns true if searchElement is in Int8Array, false otherwise
1003     */
1004    public includes(searchElement: byte): boolean {
1005        return this.includes(searchElement, 0)
1006    }
1007
1008    /**
1009     * Returns the index of the first occurrence of a value in Int8Array.
1010     *
1011     * @param searchElement The value to locate in the array.
1012     *
1013     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1014     *  search starts at index 0.
1015     *
1016     * @returns index of element if it presents, -1 otherwise
1017     */
1018    public indexOf(searchElement: number, fromIndex?: number): number {
1019        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
1020    }
1021
1022    /**
1023     * Returns the index of the first occurrence of a value in Int8Array.
1024     *
1025     * @param searchElement The value to locate in the array.
1026     *
1027     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1028     *  search starts at index 0.
1029     *
1030     * @returns index of element if it presents, -1 otherwise
1031     */
1032    public indexOf(searchElement: number, fromIndex: int): number {
1033        if (isNaN(searchElement)) {
1034            return -1
1035        }
1036        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
1037        for (let i = fromIndex; i < this.lengthInt; i++) {
1038            if (this.getUnsafe(i) as number == searchElement) {
1039                return i
1040            }
1041        }
1042        return -1
1043    }
1044
1045    /**
1046     * Returns the index of the first occurrence of a value in Int8Array.
1047     *
1048     * @param searchElement The value to locate in the array.
1049     *
1050     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1051     *  search starts at index 0.
1052     *
1053     * @returns index of element if it presents, -1 otherwise
1054     */
1055    public indexOf(searchElement: int, fromIndex: int): number {
1056        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
1057        for (let i = fromIndex; i < this.lengthInt; i++) {
1058            if (this.getUnsafe(i) == searchElement as byte) {
1059                return i
1060            }
1061        }
1062        return -1
1063    }
1064
1065    /**
1066     * Returns the index of the first occurrence of a value in Int8Array.
1067     *
1068     * @param searchElement The value to locate in the array.
1069     *
1070     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
1071     *  search starts at index 0.
1072     *
1073     * @returns index of element if it presents, -1 otherwise
1074     */
1075    public indexOf(searchElement: int): number {
1076        return this.indexOf(searchElement, 0)
1077    }
1078
1079    /**
1080     * Adds all the elements of an array separated by the specified separator string
1081     *
1082     * @param separator A string used to separate one element of an array from the next in the
1083     * resulting String. If omitted, the array elements are separated with a comma
1084     *
1085     * @returns joined representation
1086     */
1087    public join(separator?: String): string {
1088        if (separator == undefined) {
1089            return this.join(",")
1090        }
1091        let res: StringBuilder = new StringBuilder("")
1092        for (let i = 0; i < this.lengthInt - 1; ++i) {
1093            res.append(this.getUnsafe(i) as number)
1094            res.append(separator)
1095        }
1096        if (this.lengthInt > 0) {
1097            res.append(this.getUnsafe(this.lengthInt - 1) as number)
1098        }
1099        return res.toString()
1100    }
1101
1102    /**
1103     * Returns an list of keys in Int8Array
1104     *
1105     * @returns iterator over keys
1106     */
1107    public keys(): IterableIterator<number> {
1108        return new Int8ArrayIteratorKeys(this)
1109    }
1110
1111    /**
1112     * Returns the index of the last occurrence of a value in Int8Array.
1113     *
1114     * @param searchElement The value to locate in the array.
1115     *
1116     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1117     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1118     *
1119     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1120     */
1121    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
1122        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
1123    }
1124
1125    /**
1126     * Returns the index of the last occurrence of a value in Int8Array.
1127     *
1128     * @param searchElement The value to locate in the array.
1129     *
1130     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1131     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1132     *
1133     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1134     */
1135    public lastIndexOf(searchElement: number): number {
1136        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1137    }
1138
1139    /**
1140     * Returns the index of the last occurrence of a value in Int8Array.
1141     *
1142     * @param searchElement The value to locate in the array.
1143     *
1144     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1145     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1146     *
1147     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1148     */
1149    public lastIndexOf(searchElement: number, fromIndex: int): number {
1150        if (isNaN(searchElement)) {
1151            return -1
1152        }
1153        if (this.lengthInt == 0) {
1154            return -1
1155        }
1156        let k: int = this.lengthInt + fromIndex
1157        if (fromIndex >= 0) {
1158            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
1159        }
1160        while (k >= 0) {
1161            if (this.getUnsafe(k) as number == searchElement) {
1162                return k
1163            }
1164            k--
1165        }
1166        return -1
1167    }
1168
1169    /**
1170     * Returns the index of the last occurrence of a value in Int8Array.
1171     *
1172     * @param searchElement The value to locate in the array.
1173     *
1174     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1175     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1176     *
1177     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1178     */
1179    public lastIndexOf(searchElement: int, fromIndex: int): number {
1180        if (this.lengthInt == 0) {
1181            return -1
1182        }
1183        let k: int = this.lengthInt + fromIndex
1184        if (fromIndex >= 0) {
1185            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
1186        }
1187        while (k >= 0) {
1188            if (this.getUnsafe(k) == searchElement as byte) {
1189                return k
1190            }
1191            k--
1192        }
1193        return -1
1194    }
1195
1196    /**
1197     * Returns the index of the last occurrence of a value in Int8Array.
1198     *
1199     * @param searchElement The value to locate in the array.
1200     *
1201     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
1202     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
1203     *
1204     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
1205     */
1206    public lastIndexOf(searchElement: int): number {
1207        return this.lastIndexOf(searchElement, this.lengthInt - 1)
1208    }
1209
1210    /**
1211    * Creates a new Int8Array using initializer
1212    *
1213    * @param data initializer
1214    *
1215    * @returns a new Int8Array from data
1216    */
1217    public of(data: Object[]): Int8Array {
1218        throw new Error("Int8Array.of: not implemented")
1219    }
1220
1221    /**
1222     * Creates a new Int8Array using reversed data from the current one
1223     *
1224     * @returns a new Int8Array using reversed data from the current one
1225     */
1226    public reverse(): Int8Array {
1227        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
1228            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
1229            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
1230            this.setUnsafe(i, tmp)
1231        }
1232        return this
1233    }
1234
1235    /**
1236     * Creates a slice of current Int8Array using range [begin, end)
1237     *
1238     * @param begin start index to be taken into slice
1239     *
1240     * @param end last index to be taken into slice
1241     *
1242     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1243     *
1244     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1245     */
1246    public slice(begin?: number, end?: number): Int8Array {
1247        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1248    }
1249
1250    /**
1251     * Creates a slice of current Int8Array using range [begin, end)
1252     *
1253     * @param begin start index to be taken into slice
1254     *
1255     * @param end last index to be taken into slice
1256     *
1257     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1258     *
1259     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1260     */
1261    public slice(begin: number, end: number): Int8Array {
1262        return this.slice(begin as int, end as int)
1263    }
1264
1265    /**
1266     * Creates a slice of current Int8Array using range [begin, end)
1267     *
1268     * @param begin start index to be taken into slice
1269     *
1270     * @param end last index to be taken into slice
1271     *
1272     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1273     *
1274     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1275     */
1276    public slice(begin: number, end: int): Int8Array {
1277        return this.slice(begin as int, end as int)
1278    }
1279
1280    /**
1281     * Creates a slice of current Int8Array using range [begin, end)
1282     *
1283     * @param begin start index to be taken into slice
1284     *
1285     * @param end last index to be taken into slice
1286     *
1287     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1288     *
1289     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1290     */
1291    public slice(begin: int, end: number): Int8Array {
1292        return this.slice(begin as int, end as int)
1293    }
1294
1295    /**
1296     * Creates a slice of current Int8Array using range [begin, end)
1297     *
1298     * @param begin start index to be taken into slice
1299     *
1300     * @param end last index to be taken into slice
1301     *
1302     * @returns a new Int8Array with elements of current Int8Array[begin;end) where end index is excluded
1303     *
1304     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
1305     */
1306    public slice(begin: int, end: int): Int8Array {
1307        const len: int = this.lengthInt
1308        const relStart = normalizeIndex(begin, len)
1309        const relEnd = normalizeIndex(end, len)
1310        let count = relEnd - relStart
1311        if (count < 0) {
1312            count = 0
1313        }
1314        if (this.buffer instanceof ArrayBuffer) {
1315            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int8Array.BYTES_PER_ELEMENT as int, relEnd * Int8Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
1316            return new Int8Array(buf)
1317        } else if (this.buffer instanceof SharedArrayBuffer) {
1318            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int8Array.BYTES_PER_ELEMENT as int, relEnd * Int8Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
1319            return new Int8Array(buf)
1320        } else {
1321            throw new Error("unexpected type of buffer")
1322        }
1323    }
1324
1325    /**
1326     * Creates a slice of current Int8Array using range [begin, this.length).
1327     *
1328     * @param begin start index to be taken into slice
1329     *
1330     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1331     */
1332    public slice(begin: number): Int8Array {
1333        return this.slice(begin as int)
1334    }
1335
1336    /**
1337     * Creates a slice of current Int8Array using range [begin, this.length).
1338     *
1339     * @param begin start index to be taken into slice
1340     *
1341     * @returns a new Int8Array with elements of current Int8Array[begin, this.length)
1342     */
1343    public slice(begin: int): Int8Array {
1344        return this.slice(begin, this.lengthInt)
1345    }
1346
1347    /**
1348     * Creates a Int8Array with the same underlying ArrayBufferLike
1349     *
1350     * @param begin start index, inclusive
1351     *
1352     * @param end last index, exclusive
1353     *
1354     * @returns new Int8Array with the same underlying ArrayBufferLike
1355     */
1356    public subarray(begin?: number, end?: number): Int8Array {
1357        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
1358    }
1359
1360    /**
1361     * Creates a Int8Array with the same underlying ArrayBufferLike
1362     *
1363     * @param begin start index, inclusive
1364     *
1365     * @param end last index, exclusive
1366     *
1367     * @returns new Int8Array with the same underlying ArrayBufferLike
1368     */
1369    public subarray(begin: number, end: number): Int8Array {
1370        return this.subarray(begin as int, end as int)
1371    }
1372
1373    /**
1374     * Creates a Int8Array with the same underlying ArrayBufferLike
1375     *
1376     * @param begin start index, inclusive
1377     *
1378     * @param end last index, exclusive
1379     *
1380     * @returns new Int8Array with the same underlying ArrayBufferLike
1381     */
1382    public subarray(begin: number, end: int): Int8Array {
1383        return this.subarray(begin as int, end as int)
1384    }
1385
1386    /**
1387     * Creates a Int8Array with the same underlying ArrayBufferLike
1388     *
1389     * @param begin start index, inclusive
1390     *
1391     * @param end last index, exclusive
1392     *
1393     * @returns new Int8Array with the same underlying ArrayBufferLike
1394     */
1395    public subarray(begin: int, end: number): Int8Array {
1396        return this.subarray(begin as int, end as int)
1397    }
1398
1399    /**
1400     * Creates a Int8Array with the same underlying ArrayBufferLike
1401     *
1402     * @param begin start index, inclusive
1403     *
1404     * @param end last index, exclusive
1405     *
1406     * @returns new Int8Array with the same underlying ArrayBufferLike
1407     */
1408    public subarray(begin: int, end: int): Int8Array {
1409        const len: int = this.lengthInt
1410        const relStart = normalizeIndex(begin, len)
1411        const relEnd = normalizeIndex(end, len)
1412        let count = relEnd - relStart
1413        if (count < 0) {
1414            count = 0
1415        }
1416        return new Int8Array(this.buffer, relStart * Int8Array.BYTES_PER_ELEMENT as int, count)
1417    }
1418
1419    /**
1420     * Creates a Int8Array with the same ArrayBufferLike
1421     *
1422     * @param begin start index, inclusive
1423     *
1424     * @returns new Int8Array with the same ArrayBufferLike
1425     */
1426    public subarray(begin: number): Int8Array {
1427        return this.subarray(begin as int, this.lengthInt)
1428    }
1429
1430    /**
1431     * Creates a Int8Array with the same ArrayBufferLike
1432     *
1433     * @param begin start index, inclusive
1434     *
1435     * @returns new Int8Array with the same ArrayBufferLike
1436     */
1437    public subarray(begin: int): Int8Array {
1438        return this.subarray(begin as int, this.lengthInt)
1439    }
1440
1441    /**
1442     * Converts Int8Array to a string with respect to locale
1443     *
1444     * @param locales
1445     *
1446     * @param options
1447     *
1448     * @returns string representation
1449     */
1450    public toLocaleString(locales: Object, options: Object): string {
1451        throw new Error("Int8Array.toLocaleString: not implemented")
1452    }
1453
1454    /**
1455     * Converts Int8Array to a string with respect to locale
1456     *
1457     * @param locales
1458     *
1459     * @returns string representation
1460     */
1461    public toLocaleString(locales: Object): string {
1462        return this.toLocaleString(new Object(), new Object())
1463    }
1464
1465    /**
1466     * Converts Int8Array to a string with respect to locale
1467     *
1468     * @returns string representation
1469     */
1470    public toLocaleString(): string {
1471        let res: StringBuilder = new StringBuilder("")
1472        for (let i = 0; i < this.lengthInt - 1; ++i) {
1473            res.append((this.getUnsafe(i) as Number).toLocaleString())
1474            res.append(",")
1475        }
1476        if (this.lengthInt > 0) {
1477            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
1478        }
1479        return res.toString()
1480    }
1481
1482    /**
1483     * Creates a reversed copy
1484     *
1485     * @returns a reversed copy
1486     */
1487    public toReversed(): Int8Array {
1488        return new Int8Array(this).reverse()
1489    }
1490
1491    /**
1492     * Creates a sorted copy
1493     *
1494     * @returns a sorted copy
1495     */
1496    public toSorted(): Int8Array {
1497        return new Int8Array(this).sort()
1498    }
1499
1500    /**
1501     * Returns a string representation of the Int8Array
1502     *
1503     * @returns a string representation of the Int8Array
1504     */
1505    public override toString(): string {
1506        return this.join(",")
1507    }
1508
1509    /**
1510     * Returns array values iterator
1511     *
1512     * @returns an iterator
1513     */
1514    public values(): IterableIterator<Number> {
1515        return new Int8ArrayIterator(this)
1516    }
1517
1518    /**
1519     * Iteratorable interface implementation
1520     *
1521     * @returns iterator over all elements
1522     */
1523    public override $_iterator(): IterableIterator<Number> {
1524        return this.values()
1525    }
1526
1527    /**
1528     * Creates a copy with replaced value on index
1529     *
1530     * @param index
1531     *
1532     * @param value
1533     *
1534     * @returns an Int8Array with replaced value on index
1535     */
1536    public with(index: number, value: number): Int8Array {
1537        return this.with(index as int, value as byte)
1538    }
1539
1540    /**
1541     * Creates a copy with replaced value on index
1542     *
1543     * @param index
1544     *
1545     * @param value
1546     *
1547     * @returns an Int8Array with replaced value on index
1548     */
1549    public with(index: int, value: byte): Int8Array {
1550        let res = new Int8Array(this)
1551        res.set(index, value)
1552        return res
1553    }
1554
1555    /// === with element lambda functions ===
1556    /**
1557     * Determines whether the specified callback function returns true for all elements of an array.
1558     *
1559     * @param predicate A function that accepts one argument.
1560     * The every method calls the predicate function for each element in the array until the predicate returns a false,
1561     * or until the end of the array.
1562     *
1563     * @returns true unless predicate function returns a false for an array element,
1564     * in which case false is immediately returned.
1565     */
1566    public every(predicate: (element: number) => boolean): boolean {
1567        return this.every((element: number, index: number, array: Int8Array): boolean => predicate(element))
1568    }
1569
1570    /**
1571     * creates a new Int8Array from current Int8Array based on a condition fn
1572     *
1573     * @param fn the condition to apply for each element
1574     *
1575     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
1576     */
1577    public filter(fn: (val: number) => boolean): Int8Array {
1578        let newF: (val: number, index: number, array: Int8Array) => boolean =
1579            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1580        return this.filter(newF)
1581    }
1582
1583    /**
1584     * Returns the value of the first element in the array where predicate is true, and undefined
1585     * otherwise
1586     *
1587     * @param predicate find calls predicate once for each element of the array, in ascending
1588     * order, until it finds one where predicate returns true. If such an element is found, find
1589     * immediately returns that element value. Otherwise, find returns undefined
1590     *
1591     * @returns number | undefined
1592     */
1593    public find(predicate: () => boolean): number | undefined {
1594        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate())
1595    }
1596
1597    /**
1598     * Returns the value of the first element in the array where predicate is true, and undefined
1599     * otherwise
1600     *
1601     * @param predicate find calls predicate once for each element of the array, in ascending
1602     * order, until it finds one where predicate returns true. If such an element is found, find
1603     * immediately returns that element value. Otherwise, find returns undefined
1604     *
1605     * @returns number | undefined
1606     */
1607    public find(predicate: (value: number) => boolean): number | undefined {
1608        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate(value))
1609    }
1610
1611    /**
1612     * Returns the index of the first element in the array where predicate is true, and -1
1613     * otherwise
1614     *
1615     * @param predicate find calls predicate once for each element of the array, in ascending
1616     * order, until it finds one where predicate returns true. If such an element is found,
1617     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
1618     *
1619     * @returns number
1620     */
1621    public findIndex(predicate: (value: number) => boolean): number {
1622        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate(value)) as number
1623    }
1624
1625    /**
1626     * Finds the last element in the Int8Array that satisfies the condition
1627     *
1628     * @param fn condition
1629     *
1630     * @returns the last element that satisfies fn
1631     */
1632    public findLast(fn: (val: number) => boolean): number {
1633        let newF: (val: number, index: number, array: Int8Array) => boolean =
1634            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1635        return this.findLast(newF) as number
1636    }
1637
1638    /**
1639     * Finds an index of the last element in the Int8Array that satisfies the condition
1640     *
1641     * @param fn condition
1642     *
1643     * @returns the index of the last element that satisfies fn, -1 otherwise
1644     */
1645    public findLastIndex(fn: (val: number) => boolean): number {
1646        let newF: (val: number, index: number, array: Int8Array) => boolean =
1647            (val: number, index: number, array: Int8Array): boolean => { return fn(val) }
1648        return this.findLastIndex(newF) as number
1649    }
1650
1651    /**
1652     * Performs the specified action for each element in Int8Array
1653     *
1654     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
1655     * callbackfn function one time for each element in the array.
1656     *
1657     * @returns None
1658     */
1659    public forEach(callbackfn: (value: number) => void): void {
1660        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn(value))
1661    }
1662
1663    /**
1664     * Creates a new Int8Array using fn(arr[i]) over all elements of current Int8Array
1665     *
1666     * @param fn a function to apply for each element of current Int8Array
1667     *
1668     * @returns a new Int8Array where for each element from current Int8Array fn was applied
1669     */
1670    public map(fn: (val: number) => number): Int8Array {
1671        let newF: (val: number, index: number) => number =
1672            (val: number, index: number): number => { return fn(val) }
1673        return this.map(newF)
1674    }
1675
1676    /**
1677     * Determines whether the specified callback function returns true for any element of an array.
1678     *
1679     * @param predicate A function that accepts one argument.
1680     * The some method calls the predicate function for each element in the array
1681     * until the predicate returns a true or until the end of the array.
1682     *
1683     * @returns false unless predicate function returns true for an array element,
1684     * in which case true is immediately returned.
1685     */
1686    public some(predicate: (element: number) => boolean): boolean {
1687        return this.some((element: number, index: number, array: Int8Array): boolean => predicate(element))
1688    }
1689
1690    // NOTE (kprokopenko): this may be not skipped
1691    /**
1692     * Sorts in-place
1693     *
1694     * @param compareFn comparator —  used to determine the order of the elements.
1695     * compareFn returns a negative value if first argument is less than second argument,
1696     * zero if they're equal and a positive value otherwise.
1697     * If omitted, the elements are sorted in ascending order.
1698     *
1699     * @returns sorted Int8Array
1700     */
1701    public sort(compareFn?: (a: number, b: number) => number): this {
1702        let arr: byte[] = new byte[this.lengthInt]
1703        for (let i = 0; i < this.lengthInt; ++i) {
1704            arr[i] = this.getUnsafe(i)
1705        }
1706        let cmp = (l: byte, r: byte): number => {
1707                return (l - r) as number
1708            }
1709        if (compareFn != undefined) {
1710            cmp = (l: byte, r: byte): number => {
1711                return compareFn!(l as number, r as number)
1712            }
1713        }
1714        sort(arr, cmp)
1715        for (let i = 0; i < this.lengthInt; ++i) {
1716            this.setUnsafe(i, arr[i])
1717        }
1718        return this
1719    }
1720
1721    /**
1722     * Sorts in-place
1723     *
1724     * @param compareFn comparator —  used to determine the order of the elements.
1725     * compareFn returns a negative value if first argument is less than second argument,
1726     * zero if they're equal and a positive value otherwise.
1727     *
1728     * @returns sorted Int8Array
1729     */
1730    public sort(compareFn: (a: number) => number): this {
1731        let cmp = (a: number, b: number) => { return compareFn(a)}
1732        this.sort(cmp)
1733        return this
1734    }
1735
1736    /**
1737     * Sorts in-place
1738     *
1739     * @param fn compareFn —  used to determine the order of the elements.
1740     * compareFn returns a negative value if first argument is less than second argument,
1741     * zero if they're equal and a positive value otherwise.
1742     *
1743     * @returns sorted Int8Array
1744     */
1745    public sort(compareFn: () => number): this {
1746        let cmp = (a: number, b: number) => { return compareFn()}
1747        this.sort(cmp)
1748        return this
1749    }
1750
1751    /**
1752     * Determines whether the specified callback function returns true for any element of an array.
1753     *
1754     * @param predicate A function that accepts three arguments.
1755     * The some method calls the predicate function for each element in the array
1756     * until the predicate returns a true or until the end of the array.
1757     *
1758     * @returns false unless predicate function returns true for an array element,
1759     * in which case true is immediately returned.
1760     */
1761    public some(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
1762        for (let i = 0; i < this.lengthInt; ++i) {
1763            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
1764                return true
1765            }
1766        }
1767        return false
1768    }
1769
1770    /**
1771     * Determines whether the specified callback function returns true for any element of an array.
1772     *
1773     * @param predicate A function that accepts two arguments.
1774     * The some method calls the predicate function for each element in the array
1775     * until the predicate returns a true or until the end of the array.
1776     *
1777     * @returns false unless predicate function returns true for an array element,
1778     * in which case true is immediately returned.
1779     */
1780    public some(predicate: (element: number, index: number) => boolean): boolean {
1781        return this.some((element: number, index: number, array: Int8Array): boolean => predicate(element, index as number))
1782    }
1783
1784    /**
1785     * Determines whether the specified callback function returns true for any element of an array.
1786     *
1787     * @param predicate A function that accepts no arguments.
1788     * The some method calls the predicate function for each element in the array
1789     * until the predicate returns a true or until the end of the array.
1790     *
1791     * @returns false unless predicate function returns true for an array element,
1792     * in which case true is immediately returned.
1793     */
1794    public some(predicate: () => boolean): boolean {
1795        return this.some((element: number, index: number, array: Int8Array): boolean => predicate())
1796    }
1797
1798    /**
1799     * Calls the specified callback function for all the elements in an array.
1800     * The return value of the callback function is the accumulated result,
1801     * and is provided as an argument in the next call to the callback function.
1802     *
1803     * @param callbackfn A function that accepts four arguments.
1804     * The reduce method calls the callbackfn function one time for each element in the array.
1805     *
1806     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1807     * The first call to the callbackfn function provides this value as an argument.
1808     *
1809     * @returns The value that results from running the callback function to completion over the entire typed array.
1810     */
1811    public reduce<U = number>(
1812                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
1813                initialValue: U): U {
1814        let accumulatedValue = initialValue
1815        for (let i = 0; i < this.lengthInt; ++i) {
1816            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1817        }
1818        return accumulatedValue
1819    }
1820
1821    /**
1822     * Calls the specified callback function for all the elements in an array.
1823     * The return value of the callback function is the accumulated result,
1824     * and is provided as an argument in the next call to the callback function.
1825     *
1826     * @param callbackfn A function that accepts three arguments.
1827     * The reduce method calls the callbackfn function one time for each element in the array.
1828     *
1829     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1830     * The first call to the callbackfn function provides this value as an argument.
1831     *
1832     * @returns The value that results from running the callback function to completion over the entire typed array.
1833     */
1834    public reduce<U = number>(
1835                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
1836                initialValue: U): U {
1837        return this.reduce(
1838                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1839                        callbackfn(prevVal, currVal, currIndex), initialValue)
1840    }
1841
1842    /**
1843     * Calls the specified callback function for all the elements in an array.
1844     * The return value of the callback function is the accumulated result,
1845     * and is provided as an argument in the next call to the callback function.
1846     *
1847     * @param callbackfn A function that accepts two arguments.
1848     * The reduce method calls the callbackfn function one time for each element in the array.
1849     *
1850     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1851     * The first call to the callbackfn function provides this value as an argument.
1852     *
1853     * @returns The value that results from running the callback function to completion over the entire typed array.
1854     */
1855    public reduce<U = number>(
1856                callbackfn: (previousValue: U, currentValue: number) => U,
1857                initialValue: U): U {
1858        return this.reduce(
1859                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1860                        callbackfn(prevVal, currVal), initialValue)
1861    }
1862
1863    /**
1864     * Calls the specified callback function for all the elements in an array.
1865     * The return value of the callback function is the accumulated result,
1866     * and is provided as an argument in the next call to the callback function.
1867     *
1868     * @param callbackfn A function that accepts one argument
1869     * The reduce method calls the callbackfn function one time for each element in the array.
1870     *
1871     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1872     * The first call to the callbackfn function provides this value as an argument.
1873     *
1874     * @returns The value that results from running the callback function to completion over the entire typed array.
1875     */
1876    public reduce<U = number>(
1877                callbackfn: (previousValue: U) => U,
1878                initialValue: U): U {
1879        return this.reduce(
1880                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1881                        callbackfn(prevVal), initialValue)
1882    }
1883
1884    /**
1885     * Calls the specified callback function for all the elements in an array.
1886     * The return value of the callback function is the accumulated result,
1887     * and is provided as an argument in the next call to the callback function.
1888     *
1889     * @param callbackfn A function that accepts no arguments
1890     * The reduce method calls the callbackfn function one time for each element in the array.
1891     *
1892     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
1893     * The first call to the callbackfn function provides this value as an argument.
1894     *
1895     * @returns The value that results from running the callback function to completion over the entire typed array.
1896     */
1897    public reduce<U = number>(
1898                callbackfn: () => U,
1899                initialValue: U): U {
1900        return this.reduce(
1901                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
1902                        callbackfn(), initialValue)
1903    }
1904
1905    /**
1906     * Calls the specified callback function for all the elements in an array.
1907     * The return value of the callback function is the accumulated result,
1908     * and is provided as an argument in the next call to the callback function.
1909     *
1910     * @param callbackfn A function that accepts four arguments.
1911     * The reduce method calls the callbackfn function one time for each element in the array.
1912     * The first call to the callbackfn function provides array first element value as an argument
1913     *
1914     * @returns The value that results from running the callback function to completion over the entire typed array.
1915     * calling reduce method on an empty array without an initial value creates a TypeError
1916     */
1917    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
1918        if (this.lengthInt == 0) {
1919            throw new TypeError("Reduce of empty array with no initial value")
1920        }
1921
1922        let accumulatedValue = this.getUnsafe(0) as number
1923        for (let i = 1; i < this.lengthInt; ++i) {
1924            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
1925        }
1926        return accumulatedValue
1927    }
1928
1929    /**
1930     * Calls the specified callback function for all the elements in an array.
1931     * The return value of the callback function is the accumulated result,
1932     * and is provided as an argument in the next call to the callback function.
1933     *
1934     * @param callbackfn A function that accepts three arguments.
1935     * The reduce method calls the callbackfn function one time for each element in the array.
1936     * The first call to the callbackfn function provides array first element value as an argument
1937     *
1938     * @returns The value that results from running the callback function to completion over the entire typed array.
1939     * calling reduce method on an empty array without an initial value creates a TypeError
1940     */
1941    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
1942        return this.reduce(
1943                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1944                        callbackfn(prevVal, currVal, currIndex))
1945    }
1946
1947    /**
1948     * Calls the specified callback function for all the elements in an array.
1949     * The return value of the callback function is the accumulated result,
1950     * and is provided as an argument in the next call to the callback function.
1951     *
1952     * @param callbackfn A function that accepts two arguments.
1953     * The reduce method calls the callbackfn function one time for each element in the array.
1954     * The first call to the callbackfn function provides array first element value as an argument
1955     *
1956     * @returns The value that results from running the callback function to completion over the entire typed array.
1957     * calling reduce method on an empty array without an initial value creates a TypeError
1958     */
1959    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
1960        return this.reduce(
1961                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1962                        callbackfn(prevVal, currVal))
1963    }
1964
1965    /**
1966     * Calls the specified callback function for all the elements in an array.
1967     * The return value of the callback function is the accumulated result,
1968     * and is provided as an argument in the next call to the callback function.
1969     *
1970     * @param callbackfn A function that accepts one argument.
1971     * The reduce method calls the callbackfn function one time for each element in the array.
1972     * The first call to the callbackfn function provides array first element value as an argument
1973     *
1974     * @returns The value that results from running the callback function to completion over the entire typed array.
1975     * calling reduce method on an empty array without an initial value creates a TypeError
1976     */
1977    public reduce(callbackfn: (previousValue: number) => number): number {
1978        return this.reduce(
1979                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1980                        callbackfn(prevVal))
1981    }
1982
1983    /**
1984     * Calls the specified callback function for all the elements in an array.
1985     * The return value of the callback function is the accumulated result,
1986     * and is provided as an argument in the next call to the callback function.
1987     *
1988     * @param callbackfn A function that accepts no arguments.
1989     * The reduce method calls the callbackfn function one time for each element in the array.
1990     * The first call to the callbackfn function provides array first element value as an argument
1991     *
1992     * @returns The value that results from running the callback function to completion over the entire typed array.
1993     * calling reduce method on an empty array without an initial value creates a TypeError
1994     */
1995    public reduce(callbackfn: () => number): number {
1996        return this.reduce(
1997                (prevVal: number, currVal: number, currIndex: number, array: Int8Array) =>
1998                        callbackfn())
1999    }
2000
2001
2002    /**
2003     * Calls the specified callback function for all the elements in an array, in descending order.
2004     * The return value of the callback function is the accumulated result,
2005     * and is provided as an argument in the next call to the callback function.
2006     *
2007     * @param callbackfn A function that accepts four arguments.
2008     * The reduceRight method calls the callbackfn function one time for each element in the array.
2009     *
2010     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2011     * The first call to the callbackfn function provides this value as an argument.
2012     *
2013     * @returns The value that results from running the callback function to completion over the entire typed array.
2014     */
2015    public reduceRight<U = number>(
2016                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U,
2017                initialValue: U): U {
2018        let accumulatedValue = initialValue
2019        for (let i = this.lengthInt - 1; i >= 0; --i) {
2020            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
2021        }
2022        return accumulatedValue
2023    }
2024
2025    /**
2026     * Calls the specified callback function for all the elements in an array, in descending order.
2027     * The return value of the callback function is the accumulated result,
2028     * and is provided as an argument in the next call to the callback function.
2029     *
2030     * @param callbackfn A function that accepts three arguments.
2031     * The reduceRight method calls the callbackfn function one time for each element in the array.
2032     *
2033     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2034     * The first call to the callbackfn function provides this value as an argument.
2035     *
2036     * @returns The value that results from running the callback function to completion over the entire typed array.
2037     */
2038    public reduceRight<U = number>(
2039                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
2040                initialValue: U): U {
2041        return this.reduceRight(
2042                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2043                        callbackfn(prevVal, currVal, currIndex), initialValue)
2044    }
2045
2046    /**
2047     * Calls the specified callback function for all the elements in an array, in descending order.
2048     * The return value of the callback function is the accumulated result,
2049     * and is provided as an argument in the next call to the callback function.
2050     *
2051     * @param callbackfn A function that accepts two arguments.
2052     * The reduceRight method calls the callbackfn function one time for each element in the array.
2053     *
2054     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2055     * The first call to the callbackfn function provides this value as an argument.
2056     *
2057     * @returns The value that results from running the callback function to completion over the entire typed array.
2058     */
2059    public reduceRight<U = number>(
2060                callbackfn: (previousValue: U, currentValue: number) => U,
2061                initialValue: U): U {
2062        return this.reduceRight(
2063                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2064                        callbackfn(prevVal, currVal), initialValue)
2065    }
2066
2067    /**
2068     * Calls the specified callback function for all the elements in an array, in descending order.
2069     * The return value of the callback function is the accumulated result,
2070     * and is provided as an argument in the next call to the callback function.
2071     *
2072     * @param callbackfn A function that accepts one argument.
2073     * The reduceRight method calls the callbackfn function one time for each element in the array.
2074     *
2075     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2076     * The first call to the callbackfn function provides this value as an argument.
2077     *
2078     * @returns The value that results from running the callback function to completion over the entire typed array.
2079     */
2080    public reduceRight<U = number>(
2081                callbackfn: (previousValue: U) => U,
2082                initialValue: U): U {
2083        return this.reduceRight(
2084                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2085                        callbackfn(prevVal), initialValue)
2086    }
2087
2088    /**
2089     * Calls the specified callback function for all the elements in an array, in descending order.
2090     * The return value of the callback function is the accumulated result,
2091     * and is provided as an argument in the next call to the callback function.
2092     *
2093     * @param callbackfn A function that accepts no arguments.
2094     * The reduceRight method calls the callbackfn function one time for each element in the array.
2095     *
2096     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
2097     * The first call to the callbackfn function provides this value as an argument.
2098     *
2099     * @returns The value that results from running the callback function to completion over the entire typed array.
2100     */
2101    public reduceRight<U = number>(
2102                callbackfn: () => U,
2103                initialValue: U): U {
2104        return this.reduceRight(
2105                (prevVal: U, currVal: number, currIndex: number, array: Int8Array) =>
2106                        callbackfn(), initialValue)
2107    }
2108
2109    /**
2110     * Calls the specified callback function for all the elements in an array, in descending order.
2111     * The return value of the callback function is the accumulated result,
2112     * and is provided as an argument in the next call to the callback function.
2113     *
2114     * @param callbackfn A function that accepts four arguments.
2115     * The reduceRight method calls the callbackfn function one time for each element in the array.
2116     * The first call to the callbackfn function provides array last element value as an argument
2117     *
2118     * @returns The value that results from running the callback function to completion over the entire typed array.
2119     * calling reduceRight method on an empty array without an initial value creates a TypeError
2120     */
2121    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number {
2122        if (this.lengthInt == 0) {
2123            throw new TypeError("Reduce of empty array with no initial value")
2124        }
2125
2126        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
2127        for (let i = this.lengthInt - 2; i >= 0; --i) {
2128            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
2129        }
2130        return accumulatedValue
2131    }
2132
2133    /**
2134     * Calls the specified callback function for all the elements in an array, in descending order.
2135     * The return value of the callback function is the accumulated result,
2136     * and is provided as an argument in the next call to the callback function.
2137     *
2138     * @param callbackfn A function that accepts three arguments.
2139     * The reduceRight method calls the callbackfn function one time for each element in the array.
2140     * The first call to the callbackfn function provides array last element value as an argument
2141     *
2142     * @returns The value that results from running the callback function to completion over the entire typed array.
2143     * calling reduceRight method on an empty array without an initial value creates a TypeError
2144     */
2145    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
2146        return this.reduceRight(
2147                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2148                        callbackfn(prevValue, currValue, currIndex))
2149    }
2150
2151    /**
2152     * Calls the specified callback function for all the elements in an array, in descending order.
2153     * The return value of the callback function is the accumulated result,
2154     * and is provided as an argument in the next call to the callback function.
2155     *
2156     * @param callbackfn A function that accepts two arguments.
2157     * The reduceRight method calls the callbackfn function one time for each element in the array.
2158     * The first call to the callbackfn function provides array last element value as an argument
2159     *
2160     * @returns The value that results from running the callback function to completion over the entire typed array.
2161     * calling reduceRight method on an empty array without an initial value creates a TypeError
2162     */
2163    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
2164        return this.reduceRight(
2165                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2166                        callbackfn(prevValue, currValue))
2167    }
2168
2169    /**
2170     * Calls the specified callback function for all the elements in an array, in descending order.
2171     * The return value of the callback function is the accumulated result,
2172     * and is provided as an argument in the next call to the callback function.
2173     *
2174     * @param callbackfn A function that accepts one argument.
2175     * The reduceRight method calls the callbackfn function one time for each element in the array.
2176     * The first call to the callbackfn function provides array last element value as an argument
2177     *
2178     * @returns The value that results from running the callback function to completion over the entire typed array.
2179     * calling reduceRight method on an empty array without an initial value creates a TypeError
2180     */
2181    public reduceRight(callbackfn: (previousValue: number) => number): number {
2182        return this.reduceRight(
2183                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2184                        callbackfn(prevValue))
2185    }
2186
2187    /**
2188     * Calls the specified callback function for all the elements in an array, in descending order.
2189     * The return value of the callback function is the accumulated result,
2190     * and is provided as an argument in the next call to the callback function.
2191     *
2192     * @param callbackfn A function that accepts no arguments.
2193     * The reduceRight method calls the callbackfn function one time for each element in the array.
2194     * The first call to the callbackfn function provides array last element value as an argument
2195     *
2196     * @returns The value that results from running the callback function to completion over the entire typed array.
2197     * calling reduceRight method on an empty array without an initial value creates a TypeError
2198     */
2199    public reduceRight(callbackfn: () => number): number {
2200        return this.reduceRight(
2201                (prevValue: number, currValue: number, currIndex: number, array: Int8Array) =>
2202                        callbackfn())
2203    }
2204
2205   /**
2206    * Creates a new Int8Array using fn(arr[i]) over all elements of current Int8Array.
2207    *
2208    * @param fn a function to apply for each element of current Int8Array
2209    *
2210    * @returns a new Int8Array where for each element from current Int8Array fn was applied
2211    */
2212    public map(fn: (val: number, index: number) => number): Int8Array {
2213        let resBuf = new ArrayBuffer(this.lengthInt * Int8Array.BYTES_PER_ELEMENT as int)
2214        let res = new Int8Array(resBuf, 0, resBuf.getByteLength() / Int8Array.BYTES_PER_ELEMENT as int)
2215        for (let i = 0; i < this.lengthInt; ++i) {
2216            res.set(i, fn(this.getUnsafe(i) as number, i as number) as byte)
2217        }
2218        return res
2219    }
2220
2221    /**
2222     * Determines whether the specified callback function returns true for all elements of an array.
2223     *
2224     * @param predicate A function that accepts three arguments.
2225     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2226     * or until the end of the array.
2227     *
2228     * @returns true unless predicate function returns a false for an array element,
2229     * in which case false is immediately returned.
2230     */
2231    public every(predicate: (element: number, index: number, array: Int8Array) => boolean): boolean {
2232        for (let i = 0; i < this.lengthInt; ++i) {
2233            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
2234                return false
2235            }
2236        }
2237        return true
2238    }
2239
2240    /**
2241     * Determines whether the specified callback function returns true for all elements of an array.
2242     *
2243     * @param predicate A function that accepts two arguments.
2244     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2245     * or until the end of the array.
2246     *
2247     * @returns true unless predicate function returns a false for an array element,
2248     * in which case false is immediately returned.
2249     */
2250    public every(predicate: (element: number, index: number) => boolean): boolean {
2251        return this.every((element: number, index: number, array: Int8Array): boolean => predicate(element, index))
2252    }
2253
2254    /**
2255     * Determines whether the specified callback function returns true for all elements of an array.
2256     *
2257     * @param predicate A function that accepts no arguments.
2258     * The every method calls the predicate function for each element in the array until the predicate returns a false,
2259     * or until the end of the array.
2260     *
2261     * @returns true unless predicate function returns a false for an array element,
2262     * in which case false is immediately returned.
2263     */
2264    public every(predicate: () => boolean): boolean {
2265        return this.every((element: number, index: number, array: Int8Array): boolean => predicate())
2266    }
2267
2268    /**
2269     * Creates a new Int8Array from current Int8Array based on a condition fn.
2270     *
2271     * @param fn the condition to apply for each element
2272     *
2273     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2274     */
2275    public filter(fn: (val: number, index: number, array: Int8Array) => boolean): Int8Array {
2276        let markers = new boolean[this.lengthInt]
2277        let resLen = 0
2278        for (let i = 0; i < this.lengthInt; ++i) {
2279            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
2280            if (markers[i]) {
2281                ++resLen
2282            }
2283        }
2284        let resBuf = new ArrayBuffer(resLen * Int8Array.BYTES_PER_ELEMENT as int)
2285        let res = new Int8Array(resBuf, 0)
2286        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
2287            if (markers[i]) {
2288                res.set(j, this.getUnsafe(i))
2289                ++j
2290            }
2291        }
2292        return res
2293    }
2294
2295    /**
2296     * creates a new Int8Array from current Int8Array based on a condition fn
2297     *
2298     * @param fn the condition to apply for each element
2299     *
2300     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2301     */
2302    public filter(fn: (val: number, index: number) => boolean): Int8Array {
2303        let newF: (val: number, index: number, array: Int8Array) => boolean =
2304            (val: number, index: number, array: Int8Array): boolean => { return fn(val, index as number) }
2305        return this.filter(newF)
2306    }
2307
2308    /**
2309     * creates a new Int8Array from current Int8Array based on a condition fn
2310     *
2311     * @param fn the condition to apply for each element
2312     *
2313     * @returns a new Int8Array with elements from current Int8Array that satisfy condition fn
2314     */
2315    public filter(fn: () => boolean): Int8Array {
2316        let newF: (val: number, index: number, array: Int8Array) => boolean =
2317            (val: number, index: number, array: Int8Array): boolean => { return fn() }
2318        return this.filter(newF)
2319    }
2320
2321    /**
2322     * Returns the value of the first element in the array where predicate is true, and undefined
2323     * otherwise
2324     *
2325     * @param predicate find calls predicate once for each element of the array, in ascending
2326     * order, until it finds one where predicate returns true. If such an element is found, find
2327     * immediately returns that element value. Otherwise, find returns undefined
2328     *
2329     * @returns number | undefined
2330     */
2331    public find(predicate: (value: number, index: number, obj: Int8Array) => boolean): number | undefined {
2332        for (let i = 0; i < this.lengthInt; ++i) {
2333            let val = this.getUnsafe(i)
2334            if (predicate(val as number, i as number, this)) {
2335                return val as number
2336            }
2337        }
2338        return undefined
2339    }
2340
2341    /**
2342     * Returns the value of the first element in the array where predicate is true, and undefined
2343     * otherwise
2344     *
2345     * @param predicate find calls predicate once for each element of the array, in ascending
2346     * order, until it finds one where predicate returns true. If such an element is found, find
2347     * immediately returns that element value. Otherwise, find returns undefined
2348     *
2349     * @returns number | undefined
2350     */
2351    public find(predicate: (value: number, index: number) => boolean): number | undefined {
2352        return this.find((value: number, index: number, obj: Int8Array): boolean => predicate(value, index))
2353    }
2354
2355    /**
2356     * Returns the index of the first element in the array where predicate is true, and -1
2357     * otherwise
2358     *
2359     * @param predicate find calls predicate once for each element of the array, in ascending
2360     * order, until it finds one where predicate returns true. If such an element is found,
2361     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2362     *
2363     * @returns number
2364     */
2365    public findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean): number {
2366        for (let i = 0; i < this.lengthInt; ++i) {
2367            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
2368                return i as number
2369            }
2370        }
2371        return -1 as number
2372    }
2373
2374    /**
2375     * Returns the index of the first element in the array where predicate is true, and -1
2376     * otherwise
2377     *
2378     * @param predicate find calls predicate once for each element of the array, in ascending
2379     * order, until it finds one where predicate returns true. If such an element is found,
2380     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2381     *
2382     * @returns number
2383     */
2384    public findIndex(predicate: (value: number, index: number) => boolean): number {
2385        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate(value, index as number)) as number
2386    }
2387
2388    /**
2389     * Returns the index of the first element in the array where predicate is true, and -1
2390     * otherwise
2391     *
2392     * @param predicate find calls predicate once for each element of the array, in ascending
2393     * order, until it finds one where predicate returns true. If such an element is found,
2394     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
2395     *
2396     * @returns number
2397     */
2398    public findIndex(predicate: () => boolean): number {
2399        return this.findIndex((value: number, index: number, obj: Int8Array): boolean => predicate()) as number
2400    }
2401
2402    /**
2403     * Finds the last element in the Int8Array that satisfies the condition
2404     *
2405     * @param fn condition
2406     *
2407     * @returns the last element that satisfies fn
2408     */
2409    public findLast(fn: (val: number, index: number, array: Int8Array) => boolean): byte {
2410        for (let i = this.lengthInt - 1; i >= 0; --i) {
2411            let val = this.getUnsafe(i)
2412            if (fn(val as number, i as number, this)) {
2413                return val
2414            }
2415        }
2416        throw new Error("Int8Array.findLast: not implemented if an element was not found")
2417    }
2418
2419    /**
2420     * Finds the last element in the Int8Array that satisfies the condition
2421     *
2422     * @param fn condition
2423     *
2424     * @returns the last element that satisfies fn
2425     */
2426    public findLast(fn: (val: number, index: number) => boolean): byte {
2427        let newF: (val: number, index: number, array: Int8Array) => boolean =
2428            (val: number, index: number, array: Int8Array): boolean => { return fn(val as number, index as number) }
2429        return this.findLast(newF)
2430    }
2431
2432    /**
2433     * Finds an index of the last element in the Int8Array that satisfies the condition
2434     *
2435     * @param fn condition
2436     *
2437     * @returns the index of the last element that satisfies fn, -1 otherwise
2438     */
2439    public findLastIndex(fn: (val: number, index: number, array: Int8Array) => boolean): number {
2440        for (let i = this.lengthInt - 1; i >= 0; --i) {
2441            let val = this.getUnsafe(i)
2442            if (fn(val as number, i as number, this)) {
2443                return i
2444            }
2445        }
2446        return -1 as number
2447    }
2448
2449    /**
2450     * Finds an index of the last element in the Int8Array that satisfies the condition
2451     *
2452     * @param fn condition
2453     *
2454     * @returns the index of the last element that satisfies fn, -1 otherwise
2455     */
2456    public findLastIndex(fn: (val: number, index: number) => boolean): number {
2457        let newF: (val: number, index: number, array: Int8Array) => boolean =
2458            (val: number, index: number, array: Int8Array): boolean => { return fn(val, index as number) }
2459        return this.findLastIndex(newF) as number
2460    }
2461
2462    /**
2463     * Performs the specified action for each element in Int8Array
2464     *
2465     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2466     * callbackfn function one time for each element in the array.
2467     *
2468     * @returns None
2469     */
2470    public forEach(callbackfn: (value: number, index: number, array: Int8Array) => void): void {
2471        for (let i = 0; i < this.lengthInt; ++i) {
2472            callbackfn(this.getUnsafe(i) as number, i as number, this)
2473        }
2474    }
2475
2476    /**
2477     * Performs the specified action for each element in Int8Array
2478     *
2479     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2480     * callbackfn function one time for each element in the array.
2481     *
2482     * @returns None
2483     */
2484    public forEach(callbackfn: (value: number, index: number) => void): void {
2485        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn(value, index))
2486    }
2487
2488    /**
2489     * Performs the specified action for each element in Int8Array
2490     *
2491     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
2492     * callbackfn function one time for each element in the array.
2493     *
2494     * @returns None
2495     */
2496    public forEach(callbackfn: () => void): void {
2497        this.forEach((value: number, index: number, array: Int8Array): void => callbackfn())
2498    }
2499
2500    /**
2501     * Returns the object itself
2502     *
2503     * @returns Int8Array
2504     */
2505    public valueOf(): Int8Array {
2506        return this
2507    }
2508
2509    internal getUnsafe(index: int): byte {
2510        let byteIndex = index * Int8Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
2511        let res : byte = 0
2512        let byteVal : byte
2513        if (IS_LITTLE_ENDIAN) {
2514            if (this.buffer instanceof ArrayBuffer) {
2515                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2516                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
2517                    res = (res | byteVal << (8 * i)) as byte
2518                }
2519            } else if (this.buffer instanceof SharedArrayBuffer) {
2520                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2521                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
2522                    res = (res | byteVal << (8 * i)) as byte
2523                }
2524            } else {
2525                throw new Error("unexpected type of ArrayBufferLike")
2526            }
2527            return res
2528        } else {
2529            if (this.buffer instanceof ArrayBuffer) {
2530                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2531                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 0 - i)
2532                    res = (res | byteVal << (8 * i)) as byte
2533                }
2534            } else if (this.buffer instanceof SharedArrayBuffer) {
2535                for (let i: int = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2536                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 0 - i)
2537                    res = (res | byteVal << (8 * i)) as byte
2538                }
2539            } else {
2540                throw new Error("unexpected type of ArrayBufferLike")
2541            }
2542            return res
2543        }
2544    }
2545
2546    internal setUnsafe(insertPos: int, val: byte): void {
2547        let startByte = insertPos * Int8Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
2548        let bits = val
2549        if (IS_LITTLE_ENDIAN) {
2550            if (this.buffer instanceof ArrayBuffer) {
2551                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2552                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2553                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
2554                }
2555            } else if (this.buffer instanceof SharedArrayBuffer) {
2556                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; ++i) {
2557                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2558                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
2559                }
2560            } else {
2561                throw new Error("unexpected type of ArrayBufferLike")
2562            }
2563        } else {
2564            if (this.buffer instanceof ArrayBuffer) {
2565                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; i++) {
2566                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2567                    (this.buffer as ArrayBuffer).set(startByte + 0 - i, byteVal)
2568                }
2569            } else if (this.buffer instanceof SharedArrayBuffer) {
2570                for (let i = 0; i < Int8Array.BYTES_PER_ELEMENT as int; i++) {
2571                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
2572                    (this.buffer as SharedArrayBuffer).set(startByte + 0 - i, byteVal)
2573                }
2574            } else {
2575                throw new Error("unexpected type of ArrayBufferLike")
2576            }
2577        }
2578    }
2579
2580    /** Underlying ArrayBufferLike */
2581    public readonly buffer: ArrayBufferLike
2582
2583    /** Byte offset within the underlying ArrayBufferLike */
2584    public readonly byteOffset: number
2585
2586    /** Number of bytes used */
2587    public readonly byteLength: number
2588
2589    /** String \"Int8Array\" */
2590    public readonly name = "Int8Array"
2591}
2592
2593class Int16ArrayIteratorKeys implements IterableIterator<number> {
2594    private length: int
2595    private idx: int = 0
2596
2597    constructor(parent: Int16Array) {
2598        this.length = parent.length as int
2599    }
2600
2601    public override $_iterator(): IterableIterator<number> {
2602        return this
2603    }
2604
2605    override next(): IteratorResult<number> {
2606        if (this.idx < 0 || this.idx >= this.length) {
2607            return new IteratorResult<number>()
2608        }
2609        return new IteratorResult<number>(false, this.idx++ as number)
2610    }
2611}
2612
2613class Int16ArrayIterator implements IterableIterator<Number> {
2614    private parent: Int16Array
2615    private idx: int = 0
2616
2617    constructor(parent: Int16Array) {
2618        this.parent = parent
2619    }
2620
2621    public override $_iterator(): IterableIterator<Number> {
2622        return this
2623    }
2624
2625    override next(): IteratorResult<Number> {
2626        if (this.idx < 0 || this.idx >= this.parent.length as int) {
2627            return new IteratorResult<Number>()
2628        }
2629        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
2630    }
2631}
2632
2633class Int16ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
2634    private parent: Int16Array
2635    private idx: int = 0
2636
2637    constructor(parent: Int16Array) {
2638        this.parent = parent
2639    }
2640
2641    public override $_iterator(): IterableIterator<[Number, Number]> {
2642        return this
2643    }
2644
2645    override next(): IteratorResult<[Number, Number]> {
2646        if (this.idx < 0 || this.idx >= this.parent.length as int) {
2647            return new IteratorResult<[Number, Number]>()
2648        }
2649        return new IteratorResult<[Number, Number]>(
2650            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
2651        )
2652    }
2653}
2654
2655
2656/**
2657 * JS Int16Array API-compatible class
2658 */
2659export final class Int16Array implements Iterable<Number>, ArrayLike<Number> {
2660    public static readonly BYTES_PER_ELEMENT: number = 2
2661    internal readonly lengthInt: int
2662
2663    /**
2664     * Creates an empty Int16Array.
2665     */
2666    public constructor() {
2667        this(0 as int)
2668    }
2669
2670    /**
2671     * Creates an Int16Array with respect to data accessed via Iterable<Number> interface
2672     */
2673    public constructor(elements: Iterable<Number>) {
2674        // NOTE (ikorobkov): dealing with this overload is tricky
2675        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
2676        let arr = Array.from<Number>(elements)
2677        this.byteLength = arr.length * Int16Array.BYTES_PER_ELEMENT as int
2678        this.lengthInt = arr.length as int
2679        this.buffer = new ArrayBuffer(this.byteLength as int)
2680        this.byteOffset = 0
2681        for (let i: int = 0; i < this.lengthInt; ++i) {
2682            this.setUnsafe(i, arr.$_get(i).shortValue())
2683        }
2684    }
2685
2686    /**
2687     * Creates an Int16Array with respect to data, byteOffset and length.
2688     *
2689     * @param buf data initializer
2690     *
2691     * @param byteOffset byte offset from begin of the buf
2692     *
2693     * @param length size of elements of type short in newly created Int16Array
2694     */
2695    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
2696        let intByteOffset: int = 0
2697        if (byteOffset != undefined) {
2698            intByteOffset = byteOffset.intValue()
2699            if (intByteOffset < 0) {
2700                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
2701            }
2702        }
2703        let intByteLength: int
2704        if (buf instanceof ArrayBuffer) {
2705            intByteLength = (buf as ArrayBuffer).getByteLength()
2706        } else if (buf instanceof SharedArrayBuffer) {
2707            intByteLength = (buf as SharedArrayBuffer).getByteLength()
2708        } else {
2709            throw new Error("unexpected type of ArrayBufferLike")
2710        }
2711        intByteLength = intByteLength - intByteOffset
2712        if (intByteLength < 0) {
2713            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
2714        }
2715
2716        if (intByteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2717            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2718        }
2719        if (intByteOffset % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2720            throw new RangeError("byteOffset should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2721        }
2722
2723        let intLength: int
2724        if (length != undefined) {
2725            intLength = length.intValue()
2726            if (intLength > intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
2727                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
2728            }
2729        } else {
2730            intLength = intByteLength / Int16Array.BYTES_PER_ELEMENT as int
2731        }
2732        if (intLength < 0) {
2733            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
2734        }
2735        if (intLength < intByteLength / Int16Array.BYTES_PER_ELEMENT as int) {
2736            intByteLength = intLength * Int16Array.BYTES_PER_ELEMENT as int
2737        }
2738        this.byteLength = intByteLength
2739        this.byteOffset = intByteOffset
2740        this.lengthInt = intLength
2741        this.buffer = buf
2742    }
2743
2744    /**
2745     * Creates an Int16Array with respect to data, byteOffset and length.
2746     *
2747     * @param buf data initializer
2748     *
2749     * @param byteOffset byte offset from begin of the buf
2750     *
2751     * @param length size of elements of type short in newly created Int16Array
2752     */
2753    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
2754        this(buf, byteOffset, undefined)
2755    }
2756
2757    /**
2758     * Creates an Int16Array with respect to data, byteOffset and length.
2759     *
2760     * @param buf data initializer
2761     *
2762     * @param byteOffset byte offset from begin of the buf
2763     *
2764     * @param length size of elements of type short in newly created Int16Array
2765     */
2766    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
2767        this(buf, new Number(byteOffset), new Number(length))
2768    }
2769
2770    /**
2771     * Creates an Int16Array with respect to data, byteOffset and length.
2772     *
2773     * @param buf data initializer
2774     *
2775     * @param byteOffset byte offset from begin of the buf
2776     *
2777     * @param length size of elements of type short in newly created Int16Array
2778     */
2779    public constructor(buf: ArrayBufferLike, byteOffset: number) {
2780        this(buf, new Number(byteOffset), undefined)
2781    }
2782
2783    /**
2784     * Creates an Int16Array with respect to data, byteOffset and length.
2785     *
2786     * @param buf data initializer
2787     *
2788     * @param byteOffset byte offset from begin of the buf
2789     *
2790     * @param length size of elements of type short in newly created Int16Array
2791     */
2792    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
2793        this(buf, new Number(byteOffset), new Number(length))
2794    }
2795
2796    /**
2797     * Creates an Int16Array with respect to buf and byteOffset.
2798     *
2799     * @param buf data initializer
2800     *
2801     * @param byteOffset byte offset from begin of the buf
2802     */
2803    public constructor(buf: ArrayBufferLike, byteOffset: int) {
2804        this(buf, new Number(byteOffset), undefined)
2805    }
2806
2807    /**
2808     * Creates an Int16Array with respect to buf.
2809     *
2810     * @param buf data initializer
2811     */
2812    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
2813        if (buf instanceof ArrayBuffer) {
2814            this.byteLength = (buf as ArrayBuffer).getByteLength()
2815            if (this.byteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2816               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2817            }
2818            this.lengthInt = this.byteLength / Int16Array.BYTES_PER_ELEMENT as int
2819            this.buffer = buf as ArrayBuffer
2820            this.byteOffset = 0
2821        } else if (buf instanceof SharedArrayBuffer) {
2822            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
2823            if (this.byteLength % Int16Array.BYTES_PER_ELEMENT as int != 0) {
2824               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 2 as Int16Array.BYTES_PER_ELEMENT")
2825            }
2826            this.lengthInt = this.byteLength / Int16Array.BYTES_PER_ELEMENT as int
2827            this.buffer = buf as SharedArrayBuffer
2828            this.byteOffset = 0
2829        } else if (buf instanceof ArrayLike) {
2830            // NOTE (ikorobkov): dealing with this overload is tricky
2831            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
2832            let arr = Array.from<Number>((buf as ArrayLike<Number>))
2833            this.byteLength = arr.length as int * Int16Array.BYTES_PER_ELEMENT as int
2834            this.lengthInt = arr.length as int
2835            this.buffer = new ArrayBuffer(this.byteLength as int)
2836            this.byteOffset = 0
2837            for (let i: int = 0; i < this.lengthInt; ++i) {
2838                this.setUnsafe(i, arr.$_get(i).shortValue())
2839            }
2840        } else {
2841            throw new Error("unexpected type of buf")
2842        }
2843    }
2844
2845    /**
2846     * Creates an Int16Array with respect to length.
2847     *
2848     * @param length data initializer
2849     */
2850    public constructor(length: int) {
2851        if (length < 0) {
2852            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
2853        }
2854        this.lengthInt = length
2855        this.byteLength = length * Int16Array.BYTES_PER_ELEMENT as int
2856        this.byteOffset = 0
2857        this.buffer = new ArrayBuffer(this.byteLength as int)
2858    }
2859
2860    /**
2861     * Creates an Int16Array with respect to length.
2862     *
2863     * @param length data initializer
2864     */
2865    public constructor(length: number) {
2866        this(length as int)
2867    }
2868
2869    /**
2870     * Creates a copy of Int16Array.
2871     *
2872     * @param other data initializer
2873     */
2874    public constructor(other: Int16Array) {
2875        if (other.buffer instanceof ArrayBuffer) {
2876            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
2877        } else if (other.buffer instanceof SharedArrayBuffer) {
2878            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
2879        } else {
2880            throw new Error("unexpected type of buffer")
2881        }
2882        this.byteLength = other.byteLength
2883        this.lengthInt = other.length as int
2884        this.byteOffset = 0
2885    }
2886
2887    /**
2888     * Creates an Int16Array from number[]
2889     */
2890    public constructor(numbers: number[]) {
2891        this(numbers.length)
2892        for (let i: int = 0; i < this.lengthInt; ++i) {
2893            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2894        }
2895    }
2896
2897    /**
2898     * Creates an Int16Array from int[]
2899     */
2900    public constructor(numbers: int[]) {
2901        this(numbers.length)
2902        for (let i: int = 0; i < this.lengthInt; ++i) {
2903            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as short)
2904        }
2905    }
2906
2907    internal zeroIfInfinity(val: number): number {
2908        if ((val == Infinity) || (val == -Infinity)) {
2909            return 0 as number
2910        }
2911        return val as number
2912    }
2913
2914    internal zeroIfInfinity(val: short): short {
2915        if ((val == Infinity) || (val == -Infinity)) {
2916            return 0 as short
2917        }
2918        return val
2919    }
2920
2921    /**
2922     * Assigns val as element on index.
2923     *
2924     * @param val value to set
2925     *
2926     * @param index index to change
2927     */
2928    public $_set(index: number, val: number): void {
2929        this.$_set(index as int, val)
2930    }
2931
2932    /**
2933     * Assigns val as element on index.
2934     *
2935     * @param val value to set
2936     *
2937     * @param index index to change
2938     */
2939    public $_set(index: int, val: number): void {
2940        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
2941        if (index < 0 || index >= this.lengthInt) {
2942            throw new RangeError("invalid index")
2943        }
2944        let v = this.zeroIfInfinity(val)
2945        this.setUnsafe(index, v as short)
2946    }
2947
2948    /**
2949     * Assigns val as element on index.
2950     *
2951     * @param val value to set
2952     *
2953     * @param index index to change
2954     */
2955    public $_set(index: number, val: int): void {
2956        this.$_set(index as int, val)
2957    }
2958
2959    /**
2960     * Assigns val as element on index.
2961     *
2962     * @param val value to set
2963     *
2964     * @param index index to change
2965     */
2966    public $_set(index: int, val: int): void {
2967        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
2968        if (index < 0 || index >= this.lengthInt) {
2969            throw new RangeError("invalid index")
2970        }
2971        let v = this.zeroIfInfinity(val as short)
2972        this.setUnsafe(index, v as short)
2973    }
2974
2975    /**
2976     * Assigns val as element on index.
2977     *
2978     * @param val value to set
2979     *
2980     * @param index index to change
2981     */
2982    public $_set(index: number, val: short): void {
2983        this.$_set(index as int, val)
2984    }
2985
2986    /**
2987     * Assigns val as element on index.
2988     *
2989     * @param val value to set
2990     *
2991     * @param index index to change
2992     */
2993    public $_set(index: int, val: short): void {
2994        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
2995        if (index < 0 || index >= this.lengthInt) {
2996            throw new RangeError("invalid index")
2997        }
2998        let v = this.zeroIfInfinity(val)
2999        this.setUnsafe(index, v)
3000    }
3001
3002    /** Number of short stored in Int16Array */
3003    public get length(): number {
3004        return this.lengthInt
3005    }
3006
3007    /**
3008     * Returns an instance of number at passed index.
3009     *
3010     * @param index index to look at
3011     *
3012     * @returns a primitive at index
3013     */
3014    public override $_get(index: number): Number {
3015        return this.$_get(index as int) as Number
3016    }
3017
3018    /**
3019     * Returns an instance of number at passed index.
3020     *
3021     * @param index index to look at
3022     *
3023     * @returns a primitive at index
3024     */
3025    public $_get(index: int): number {
3026        if (index < 0 || index >= this.lengthInt) {
3027            throw new RangeError("invalid index")
3028        }
3029        return this.getUnsafe(index) as number
3030    }
3031
3032    /**
3033     * Returns an instance of primitive type at passed index.
3034     *
3035     * @param index index to look at
3036     *
3037     * @returns a primitive at index
3038     */
3039    public at(index: number): Number | undefined {
3040        return this.at(index as int)
3041    }
3042
3043    /**
3044     * Returns an instance of primitive type at passed index.
3045     *
3046     * @param index index to look at
3047     *
3048     * @returns a primitive at index
3049     */
3050    public at(index: int): Number | undefined {
3051        let k: int
3052        if (index >= 0) {
3053            k = index
3054        } else {
3055            k = this.lengthInt + index
3056        }
3057        if (k < 0 || k >= this.lengthInt) {
3058            return undefined
3059        }
3060        return new Number(this.getUnsafe(k))
3061    }
3062
3063    /**
3064     * Makes a copy of internal elements to targetPos from startPos to endPos.
3065     *
3066     * @param target insert index to place copied elements
3067     *
3068     * @param start start index to begin copy from
3069     *
3070     * @param end last index to end copy from, excluded
3071     *
3072     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3073     */
3074    public copyWithin(target: number, start: number, end?: number): Int16Array {
3075        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3076    }
3077
3078    /**
3079     * Makes a copy of internal elements to targetPos from startPos to endPos.
3080     *
3081     * @param target insert index to place copied elements
3082     *
3083     * @param start start index to begin copy from
3084     *
3085     * @param end last index to end copy from, excluded
3086     *
3087     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3088     */
3089    public copyWithin(target: int, start: number, end?: number): Int16Array {
3090        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3091    }
3092
3093    /**
3094     * Makes a copy of internal elements to targetPos from startPos to endPos.
3095     *
3096     * @param target insert index to place copied elements
3097     *
3098     * @param start start index to begin copy from
3099     *
3100     * @param end last index to end copy from, excluded
3101     *
3102     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3103     */
3104    public copyWithin(target: number, start: int, end?: number): Int16Array {
3105        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3106    }
3107
3108    /**
3109     * Makes a copy of internal elements to targetPos from startPos to endPos.
3110     *
3111     * @param target insert index to place copied elements
3112     *
3113     * @param start start index to begin copy from
3114     *
3115     * @param end last index to end copy from, excluded
3116     *
3117     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3118     */
3119    public copyWithin(target: int, start: int, end?: number): Int16Array {
3120        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
3121    }
3122
3123    /**
3124     * Makes a copy of internal elements to targetPos from startPos to endPos.
3125     *
3126     * @param target insert index to place copied elements
3127     *
3128     * @param start start index to begin copy from
3129     *
3130     * @param end last index to end copy from, excluded
3131     *
3132     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
3133     */
3134    public copyWithin(target: int, start: int, end: int): Int16Array {
3135        let toPos = normalizeIndex(target, this.lengthInt)
3136        let fromPos = normalizeIndex(start, this.lengthInt)
3137        const finalPos = normalizeIndex(end, this.lengthInt)
3138        let count: int = finalPos - fromPos
3139        if (count > (this.lengthInt - toPos)) {
3140            count = this.lengthInt - toPos
3141        }
3142        let direction: int = 1
3143        if ((fromPos < toPos) && (toPos < fromPos + count)) {
3144            fromPos = fromPos + count - 1
3145            toPos   = toPos   + count - 1
3146            direction = -1
3147        }
3148        while (count > 0) {
3149            const value = this.getUnsafe(fromPos)
3150            this.setUnsafe(toPos, value)
3151            fromPos = fromPos + direction
3152            toPos = toPos + direction
3153            --count
3154        }
3155        return this
3156    }
3157
3158    /**
3159     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
3160     *
3161     * @param target insert index to place copied elements
3162     *
3163     * See rules of parameters normalization:
3164     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
3165     */
3166    public copyWithin(target: number): Int16Array {
3167        return this.copyWithin(target as int)
3168    }
3169
3170    /**
3171     * Makes a copy of internal elements to targetPos from begin to end of Int16Array.
3172     *
3173     * @param target insert index to place copied elements
3174     *
3175     * See rules of parameters normalization:
3176     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
3177     */
3178    public copyWithin(target: int): Int16Array {
3179        return this.copyWithin(target, 0, this.lengthInt)
3180    }
3181
3182    /**
3183     * Returns an array of key, value pairs for every entry in the Int16Array
3184     *
3185     * @returns key, value pairs for every entry in the array
3186     */
3187    public entries(): IterableIterator<[Number, Number]> {
3188        return new Int16ArrayIteratorEntries(this)
3189    }
3190
3191    /**
3192     * Fills the Int16Array with specified value
3193     *
3194     * @param value new valuy
3195     *
3196     * @returns modified Int16Array
3197     */
3198    public fill(value: number, start?: number, end?: number): this {
3199        value = this.zeroIfInfinity(value)
3200        this.fill(value as short, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
3201        return this
3202    }
3203
3204    /**
3205     * Fills the Int16Array with specified value
3206     *
3207     * @param value new valuy
3208     *
3209     * @returns modified Int16Array
3210     */
3211    public fill(value: number, start: int, end?: number): this {
3212        value = this.zeroIfInfinity(value)
3213        this.fill(value as short, start as int, asIntOrDefault(end, this.lengthInt))
3214        return this
3215    }
3216
3217    /**
3218     * Fills the Int16Array with specified value
3219     *
3220     * @param value new valuy
3221     *
3222     * @returns modified Int16Array
3223     */
3224    public fill(value: number, start: int, end: number): this {
3225        value = this.zeroIfInfinity(value)
3226        this.fill(value as short, start as int, end as int)
3227        return this
3228    }
3229
3230    /**
3231     * Fills the Int16Array with specified value
3232     *
3233     * @param value new valuy
3234     *
3235     * @returns modified Int16Array
3236     */
3237    public fill(value: number, start: number, end: int): this {
3238        value = this.zeroIfInfinity(value)
3239        this.fill(value as short, start as int, end as int)
3240        return this
3241    }
3242
3243    /**
3244     * Fills the Int16Array with specified value
3245     *
3246     * @param value new valuy
3247     *
3248     * @returns modified Int16Array
3249     */
3250    public fill(value: number, start: int, end: int): this {
3251        value = this.zeroIfInfinity(value)
3252        this.fill(value as short, start as int, end as int)
3253        return this
3254    }
3255
3256    /**
3257     * Fills the Int16Array with specified value
3258     *
3259     * @param value new valuy
3260     *
3261     * @returns modified Int16Array
3262     */
3263    public fill(value: short, start?: number, end?: number): this {
3264        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
3265        return this
3266    }
3267
3268    /**
3269     * Fills the Int16Array with specified value
3270     *
3271     * @param value new valuy
3272     *
3273     * @returns modified Int16Array
3274     */
3275    public fill(value: short, start: int, end?: number): this {
3276        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
3277        return this
3278    }
3279
3280    /**
3281     * Fills the Int16Array with specified value
3282     *
3283     * @param value new valuy
3284     *
3285     * @returns modified Int16Array
3286     */
3287    public fill(value: short, start: int, end: number): this {
3288        this.fill(value, start as int, end as int)
3289        return this
3290    }
3291
3292    /**
3293     * Fills the Int16Array with specified value
3294     *
3295     * @param value new valuy
3296     *
3297     * @returns modified Int16Array
3298     */
3299    public fill(value: short, start: number, end: int): this {
3300        this.fill(value, start as int, end as int)
3301        return this
3302    }
3303
3304    /**
3305     * Fills the Int16Array with specified value
3306     *
3307     * @param value new valuy
3308     *
3309     * @returns modified Int16Array
3310     */
3311    public fill(value: short, start: int, end: int): this {
3312        const k = normalizeIndex(start, this.lengthInt)
3313        const finalPos = normalizeIndex(end, this.lengthInt)
3314        for (let i: int = k; i < finalPos; ++i) {
3315            this.setUnsafe(i, value)
3316        }
3317        return this
3318    }
3319
3320    /**
3321     * Assigns val as element on insertPos.
3322     * @description Added to avoid (un)packing a single value into array to use overloaded set(short[], insertPos)
3323     *
3324     * @param val value to set
3325     *
3326     * @param insertPos index to change
3327     */
3328    public set(insertPos: number, val: number): void {
3329        this.$_set(insertPos, val)
3330    }
3331
3332    /**
3333     * Assigns val as element on insertPos.
3334     * @description Added to avoid (un)packing a single value into array to use overloaded set(short[], insertPos)
3335     *
3336     * @param val value to set
3337     *
3338     * @param insertPos index to change
3339     */
3340    public set(insertPos: int, val: short): void {
3341        this.$_set(insertPos, val)
3342    }
3343
3344    /**
3345     * Copies all elements of arr to the current Int16Array starting from insertPos.
3346     *
3347     * @param arr array to copy data from
3348     *
3349     * @param insertPos start index where data from arr will be inserted
3350     *
3351     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
3352     */
3353    public set(arr: number[], insertPos: number): void {
3354        const offset = insertPos as int
3355        if (offset < 0 || offset + arr.length > this.lengthInt) {
3356            throw new RangeError("offset is out of bounds")
3357        }
3358        for (let i = 0; i < arr.length as int; ++i) {
3359            let v = this.zeroIfInfinity(arr[i])
3360            this.setUnsafe(offset + i, v as short)
3361        }
3362    }
3363
3364    /**
3365     * Copies all elements of arr to the current Int16Array starting from insertPos.
3366     *
3367     * @param arr array to copy data from
3368     *
3369     * @param insertPos start index where data from arr will be inserted
3370     *
3371     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
3372     */
3373    public set(arr: short[], insertPos: int): void {
3374        const offset = insertPos as int
3375        if (offset < 0 || offset + arr.length > this.lengthInt) {
3376            throw new RangeError("offset is out of bounds")
3377        }
3378        for (let i = 0; i < arr.length as int; ++i) {
3379            let v = this.zeroIfInfinity(arr[i])
3380            this.setUnsafe(offset + i, v)
3381        }
3382    }
3383
3384    /**
3385     * Copies all elements of arr to the current Int16Array.
3386     *
3387     * @param arr array to copy data from
3388     */
3389    public set(arr: number[]): void {
3390        this.set(arr, 0 as number)
3391    }
3392
3393    /**
3394     * Copies all elements of arr to the current Int16Array.
3395     *
3396     * @param arr array to copy data from
3397     */
3398    public set(arr: short[]): void {
3399        this.set(arr, 0 as int)
3400    }
3401
3402    /**
3403     * Copies elements from an ArrayLike object to the Int16Array.
3404     *
3405     * @param array An ArrayLike object containing the elements to copy.
3406     *
3407     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
3408     */
3409    public set(array: ArrayLike<number>, offset: number = 0): void {
3410        const insertPos = offset as int
3411        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
3412            throw new RangeError("offset is out of bounds")
3413        }
3414        for (let i = 0; i < array.length as int; ++i) {
3415            let v = this.zeroIfInfinity(array[i])
3416            this.setUnsafe(insertPos + i, v as short)
3417        }
3418    }
3419
3420    /**
3421     * Returns a new array from a set of elements.
3422     *
3423     * @param items a set of elements to include in the new array object.
3424     *
3425     * @returns new Int16Array
3426     */
3427    public static of(...items: number[]): Int16Array {
3428        let res = new Int16Array(items.length as int)
3429        for (let i: int = 0; i < items.length; i++) {
3430            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as short)
3431        }
3432        return res
3433    }
3434
3435    /**
3436     * Returns a new array from a set of elements.
3437     *
3438     * @param items a set of elements to include in the new array object.
3439     *
3440     * @returns new Int16Array
3441     */
3442    public static of(...items: int[]): Int16Array {
3443        let res = new Int16Array(items.length as int)
3444        for (let i: int = 0; i < items.length; i++) {
3445            res.setUnsafe(i, items[i] as short)
3446        }
3447        return res
3448    }
3449
3450    /**
3451     * Returns a new array from a set of elements.
3452     *
3453     * @param items a set of elements to include in the new array object.
3454     *
3455     * @returns new Int16Array
3456     */
3457    public static of(...items: short[]): Int16Array {
3458        let res = new Int16Array(items.length as int)
3459        for (let i: int = 0; i < items.length; i++) {
3460            res.setUnsafe(i, items[i])
3461        }
3462        return res
3463    }
3464
3465    /**
3466     * Returns a new array from a set of elements.
3467     *
3468     * @param items a set of elements to include in the new array object.
3469     *
3470     * @returns new Int16Array
3471     */
3472    public static of(): Int16Array {
3473        return new Int16Array(0 as int)
3474    }
3475
3476    /**
3477     * Creates an array from an array-like or iterable object.
3478     *
3479     * @param arrayLike An array-like or iterable object to convert to an array.
3480     *
3481     * @returns new Int16Array
3482     */
3483    public static from(arrayLike: ArrayLike<number>): Int16Array {
3484        return Int16Array.from<number>(arrayLike, (x: number, k: number): number => x)
3485    }
3486
3487    /**
3488     * Creates an array from an array-like or iterable object.
3489     *
3490     * @param arrayLike An array-like or iterable object to convert to an array.
3491     *
3492     * @param mapfn A mapping function to call on every element of the array.
3493     *
3494     * @returns new Int16Array
3495     */
3496    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int16Array {
3497        if (mapfn == undefined) {
3498            mapfn = (v: number, k: number): number => { return v }
3499        }
3500        // Calc length of items inside arrayLike, save length into i variable
3501        let i: long = 0
3502        let iter = arrayLike.$_iterator()
3503        while (true) {
3504            const v = iter.next()
3505            if (v.done) {
3506                break
3507            }
3508            i++
3509        }
3510
3511        let res = new Int16Array(i as int)
3512        i = 0
3513        iter = arrayLike.$_iterator()
3514        while (true) {
3515            const v = iter.next()
3516            if (v.done) {
3517                return res
3518            }
3519            res.setUnsafe(i as int, res.zeroIfInfinity((mapfn)!(v.value as number, i as number)) as short)
3520            i++
3521        }
3522    }
3523
3524
3525    /**
3526     * Creates an array from an array-like or iterable object.
3527     *
3528     * @param arrayLike An array-like or iterable object to convert to an array.
3529     *
3530     * @param mapfn A mapping function to call on every element of the array.
3531     *
3532     * @returns new Int16Array
3533     */
3534    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): Int16Array {
3535        let res = new Int16Array(arrayLike.length)
3536        // 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
3537        const idx = new int[1]
3538        idx[0] = 0
3539        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
3540            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as short)
3541            idx[0] += 1
3542        })
3543        return res
3544    }
3545
3546    /**
3547     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3548     *
3549     * @param searchElement The element to search for
3550     *
3551     * @param fromIndex The position in this array at which to begin searching for searchElement
3552     *
3553     * @returns true if searchElement is in Int16Array, false otherwise
3554     */
3555    public includes(searchElement: number, fromIndex?: number): boolean {
3556        if (isNaN(searchElement)) {
3557            return false
3558        }
3559        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
3560    }
3561
3562    /**
3563     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3564     *
3565     * @param searchElement The element to search for
3566     *
3567     * @param fromIndex The position in this array at which to begin searching for searchElement
3568     *
3569     * @returns true if e is in Int16Array, false otherwise
3570     */
3571    public includes(searchElement: short, fromIndex: int): boolean {
3572        return this.indexOf(searchElement as int, fromIndex) != -1
3573    }
3574
3575    /**
3576     * Determines whether Int16Array includes a certain element, returning true or false as appropriate
3577     *
3578     * @param searchElement The element to search for
3579     *
3580     * @param fromIndex The position in this array at which to begin searching for searchElement
3581     *
3582     * @returns true if searchElement is in Int16Array, false otherwise
3583     */
3584    public includes(searchElement: short): boolean {
3585        return this.includes(searchElement, 0)
3586    }
3587
3588    /**
3589     * Returns the index of the first occurrence of a value in Int16Array.
3590     *
3591     * @param searchElement The value to locate in the array.
3592     *
3593     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3594     *  search starts at index 0.
3595     *
3596     * @returns index of element if it presents, -1 otherwise
3597     */
3598    public indexOf(searchElement: number, fromIndex?: number): number {
3599        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
3600    }
3601
3602    /**
3603     * Returns the index of the first occurrence of a value in Int16Array.
3604     *
3605     * @param searchElement The value to locate in the array.
3606     *
3607     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3608     *  search starts at index 0.
3609     *
3610     * @returns index of element if it presents, -1 otherwise
3611     */
3612    public indexOf(searchElement: number, fromIndex: int): number {
3613        if (isNaN(searchElement)) {
3614            return -1
3615        }
3616        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
3617        for (let i = fromIndex; i < this.lengthInt; i++) {
3618            if (this.getUnsafe(i) as number == searchElement) {
3619                return i
3620            }
3621        }
3622        return -1
3623    }
3624
3625    /**
3626     * Returns the index of the first occurrence of a value in Int16Array.
3627     *
3628     * @param searchElement The value to locate in the array.
3629     *
3630     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3631     *  search starts at index 0.
3632     *
3633     * @returns index of element if it presents, -1 otherwise
3634     */
3635    public indexOf(searchElement: int, fromIndex: int): number {
3636        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
3637        for (let i = fromIndex; i < this.lengthInt; i++) {
3638            if (this.getUnsafe(i) == searchElement as short) {
3639                return i
3640            }
3641        }
3642        return -1
3643    }
3644
3645    /**
3646     * Returns the index of the first occurrence of a value in Int16Array.
3647     *
3648     * @param searchElement The value to locate in the array.
3649     *
3650     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
3651     *  search starts at index 0.
3652     *
3653     * @returns index of element if it presents, -1 otherwise
3654     */
3655    public indexOf(searchElement: int): number {
3656        return this.indexOf(searchElement, 0)
3657    }
3658
3659    /**
3660     * Adds all the elements of an array separated by the specified separator string
3661     *
3662     * @param separator A string used to separate one element of an array from the next in the
3663     * resulting String. If omitted, the array elements are separated with a comma
3664     *
3665     * @returns joined representation
3666     */
3667    public join(separator?: String): string {
3668        if (separator == undefined) {
3669            return this.join(",")
3670        }
3671        let res: StringBuilder = new StringBuilder("")
3672        for (let i = 0; i < this.lengthInt - 1; ++i) {
3673            res.append(this.getUnsafe(i) as number)
3674            res.append(separator)
3675        }
3676        if (this.lengthInt > 0) {
3677            res.append(this.getUnsafe(this.lengthInt - 1) as number)
3678        }
3679        return res.toString()
3680    }
3681
3682    /**
3683     * Returns an list of keys in Int16Array
3684     *
3685     * @returns iterator over keys
3686     */
3687    public keys(): IterableIterator<number> {
3688        return new Int16ArrayIteratorKeys(this)
3689    }
3690
3691    /**
3692     * Returns the index of the last occurrence of a value in Int16Array.
3693     *
3694     * @param searchElement The value to locate in the array.
3695     *
3696     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3697     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3698     *
3699     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3700     */
3701    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
3702        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
3703    }
3704
3705    /**
3706     * Returns the index of the last occurrence of a value in Int16Array.
3707     *
3708     * @param searchElement The value to locate in the array.
3709     *
3710     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3711     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3712     *
3713     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3714     */
3715    public lastIndexOf(searchElement: number): number {
3716        return this.lastIndexOf(searchElement, this.lengthInt - 1)
3717    }
3718
3719    /**
3720     * Returns the index of the last occurrence of a value in Int16Array.
3721     *
3722     * @param searchElement The value to locate in the array.
3723     *
3724     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3725     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3726     *
3727     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3728     */
3729    public lastIndexOf(searchElement: number, fromIndex: int): number {
3730        if (isNaN(searchElement)) {
3731            return -1
3732        }
3733        if (this.lengthInt == 0) {
3734            return -1
3735        }
3736        let k: int = this.lengthInt + fromIndex
3737        if (fromIndex >= 0) {
3738            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
3739        }
3740        while (k >= 0) {
3741            if (this.getUnsafe(k) as number == searchElement) {
3742                return k
3743            }
3744            k--
3745        }
3746        return -1
3747    }
3748
3749    /**
3750     * Returns the index of the last occurrence of a value in Int16Array.
3751     *
3752     * @param searchElement The value to locate in the array.
3753     *
3754     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3755     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3756     *
3757     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3758     */
3759    public lastIndexOf(searchElement: int, fromIndex: int): number {
3760        if (this.lengthInt == 0) {
3761            return -1
3762        }
3763        let k: int = this.lengthInt + fromIndex
3764        if (fromIndex >= 0) {
3765            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
3766        }
3767        while (k >= 0) {
3768            if (this.getUnsafe(k) == searchElement as short) {
3769                return k
3770            }
3771            k--
3772        }
3773        return -1
3774    }
3775
3776    /**
3777     * Returns the index of the last occurrence of a value in Int16Array.
3778     *
3779     * @param searchElement The value to locate in the array.
3780     *
3781     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
3782     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
3783     *
3784     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
3785     */
3786    public lastIndexOf(searchElement: int): number {
3787        return this.lastIndexOf(searchElement, this.lengthInt - 1)
3788    }
3789
3790    /**
3791    * Creates a new Int16Array using initializer
3792    *
3793    * @param data initializer
3794    *
3795    * @returns a new Int16Array from data
3796    */
3797    public of(data: Object[]): Int16Array {
3798        throw new Error("Int16Array.of: not implemented")
3799    }
3800
3801    /**
3802     * Creates a new Int16Array using reversed data from the current one
3803     *
3804     * @returns a new Int16Array using reversed data from the current one
3805     */
3806    public reverse(): Int16Array {
3807        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
3808            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
3809            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
3810            this.setUnsafe(i, tmp)
3811        }
3812        return this
3813    }
3814
3815    /**
3816     * Creates a slice of current Int16Array using range [begin, end)
3817     *
3818     * @param begin start index to be taken into slice
3819     *
3820     * @param end last index to be taken into slice
3821     *
3822     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3823     *
3824     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3825     */
3826    public slice(begin?: number, end?: number): Int16Array {
3827        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
3828    }
3829
3830    /**
3831     * Creates a slice of current Int16Array using range [begin, end)
3832     *
3833     * @param begin start index to be taken into slice
3834     *
3835     * @param end last index to be taken into slice
3836     *
3837     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3838     *
3839     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3840     */
3841    public slice(begin: number, end: number): Int16Array {
3842        return this.slice(begin as int, end as int)
3843    }
3844
3845    /**
3846     * Creates a slice of current Int16Array using range [begin, end)
3847     *
3848     * @param begin start index to be taken into slice
3849     *
3850     * @param end last index to be taken into slice
3851     *
3852     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3853     *
3854     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3855     */
3856    public slice(begin: number, end: int): Int16Array {
3857        return this.slice(begin as int, end as int)
3858    }
3859
3860    /**
3861     * Creates a slice of current Int16Array using range [begin, end)
3862     *
3863     * @param begin start index to be taken into slice
3864     *
3865     * @param end last index to be taken into slice
3866     *
3867     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3868     *
3869     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3870     */
3871    public slice(begin: int, end: number): Int16Array {
3872        return this.slice(begin as int, end as int)
3873    }
3874
3875    /**
3876     * Creates a slice of current Int16Array using range [begin, end)
3877     *
3878     * @param begin start index to be taken into slice
3879     *
3880     * @param end last index to be taken into slice
3881     *
3882     * @returns a new Int16Array with elements of current Int16Array[begin;end) where end index is excluded
3883     *
3884     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
3885     */
3886    public slice(begin: int, end: int): Int16Array {
3887        const len: int = this.lengthInt
3888        const relStart = normalizeIndex(begin, len)
3889        const relEnd = normalizeIndex(end, len)
3890        let count = relEnd - relStart
3891        if (count < 0) {
3892            count = 0
3893        }
3894        if (this.buffer instanceof ArrayBuffer) {
3895            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int16Array.BYTES_PER_ELEMENT as int, relEnd * Int16Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
3896            return new Int16Array(buf)
3897        } else if (this.buffer instanceof SharedArrayBuffer) {
3898            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int16Array.BYTES_PER_ELEMENT as int, relEnd * Int16Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
3899            return new Int16Array(buf)
3900        } else {
3901            throw new Error("unexpected type of buffer")
3902        }
3903    }
3904
3905    /**
3906     * Creates a slice of current Int16Array using range [begin, this.length).
3907     *
3908     * @param begin start index to be taken into slice
3909     *
3910     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3911     */
3912    public slice(begin: number): Int16Array {
3913        return this.slice(begin as int)
3914    }
3915
3916    /**
3917     * Creates a slice of current Int16Array using range [begin, this.length).
3918     *
3919     * @param begin start index to be taken into slice
3920     *
3921     * @returns a new Int16Array with elements of current Int16Array[begin, this.length)
3922     */
3923    public slice(begin: int): Int16Array {
3924        return this.slice(begin, this.lengthInt)
3925    }
3926
3927    /**
3928     * Creates a Int16Array with the same underlying ArrayBufferLike
3929     *
3930     * @param begin start index, inclusive
3931     *
3932     * @param end last index, exclusive
3933     *
3934     * @returns new Int16Array with the same underlying ArrayBufferLike
3935     */
3936    public subarray(begin?: number, end?: number): Int16Array {
3937        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
3938    }
3939
3940    /**
3941     * Creates a Int16Array with the same underlying ArrayBufferLike
3942     *
3943     * @param begin start index, inclusive
3944     *
3945     * @param end last index, exclusive
3946     *
3947     * @returns new Int16Array with the same underlying ArrayBufferLike
3948     */
3949    public subarray(begin: number, end: number): Int16Array {
3950        return this.subarray(begin as int, end as int)
3951    }
3952
3953    /**
3954     * Creates a Int16Array with the same underlying ArrayBufferLike
3955     *
3956     * @param begin start index, inclusive
3957     *
3958     * @param end last index, exclusive
3959     *
3960     * @returns new Int16Array with the same underlying ArrayBufferLike
3961     */
3962    public subarray(begin: number, end: int): Int16Array {
3963        return this.subarray(begin as int, end as int)
3964    }
3965
3966    /**
3967     * Creates a Int16Array with the same underlying ArrayBufferLike
3968     *
3969     * @param begin start index, inclusive
3970     *
3971     * @param end last index, exclusive
3972     *
3973     * @returns new Int16Array with the same underlying ArrayBufferLike
3974     */
3975    public subarray(begin: int, end: number): Int16Array {
3976        return this.subarray(begin as int, end as int)
3977    }
3978
3979    /**
3980     * Creates a Int16Array with the same underlying ArrayBufferLike
3981     *
3982     * @param begin start index, inclusive
3983     *
3984     * @param end last index, exclusive
3985     *
3986     * @returns new Int16Array with the same underlying ArrayBufferLike
3987     */
3988    public subarray(begin: int, end: int): Int16Array {
3989        const len: int = this.lengthInt
3990        const relStart = normalizeIndex(begin, len)
3991        const relEnd = normalizeIndex(end, len)
3992        let count = relEnd - relStart
3993        if (count < 0) {
3994            count = 0
3995        }
3996        return new Int16Array(this.buffer, relStart * Int16Array.BYTES_PER_ELEMENT as int, count)
3997    }
3998
3999    /**
4000     * Creates a Int16Array with the same ArrayBufferLike
4001     *
4002     * @param begin start index, inclusive
4003     *
4004     * @returns new Int16Array with the same ArrayBufferLike
4005     */
4006    public subarray(begin: number): Int16Array {
4007        return this.subarray(begin as int, this.lengthInt)
4008    }
4009
4010    /**
4011     * Creates a Int16Array with the same ArrayBufferLike
4012     *
4013     * @param begin start index, inclusive
4014     *
4015     * @returns new Int16Array with the same ArrayBufferLike
4016     */
4017    public subarray(begin: int): Int16Array {
4018        return this.subarray(begin as int, this.lengthInt)
4019    }
4020
4021    /**
4022     * Converts Int16Array to a string with respect to locale
4023     *
4024     * @param locales
4025     *
4026     * @param options
4027     *
4028     * @returns string representation
4029     */
4030    public toLocaleString(locales: Object, options: Object): string {
4031        throw new Error("Int16Array.toLocaleString: not implemented")
4032    }
4033
4034    /**
4035     * Converts Int16Array to a string with respect to locale
4036     *
4037     * @param locales
4038     *
4039     * @returns string representation
4040     */
4041    public toLocaleString(locales: Object): string {
4042        return this.toLocaleString(new Object(), new Object())
4043    }
4044
4045    /**
4046     * Converts Int16Array to a string with respect to locale
4047     *
4048     * @returns string representation
4049     */
4050    public toLocaleString(): string {
4051        let res: StringBuilder = new StringBuilder("")
4052        for (let i = 0; i < this.lengthInt - 1; ++i) {
4053            res.append((this.getUnsafe(i) as Number).toLocaleString())
4054            res.append(",")
4055        }
4056        if (this.lengthInt > 0) {
4057            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
4058        }
4059        return res.toString()
4060    }
4061
4062    /**
4063     * Creates a reversed copy
4064     *
4065     * @returns a reversed copy
4066     */
4067    public toReversed(): Int16Array {
4068        return new Int16Array(this).reverse()
4069    }
4070
4071    /**
4072     * Creates a sorted copy
4073     *
4074     * @returns a sorted copy
4075     */
4076    public toSorted(): Int16Array {
4077        return new Int16Array(this).sort()
4078    }
4079
4080    /**
4081     * Returns a string representation of the Int16Array
4082     *
4083     * @returns a string representation of the Int16Array
4084     */
4085    public override toString(): string {
4086        return this.join(",")
4087    }
4088
4089    /**
4090     * Returns array values iterator
4091     *
4092     * @returns an iterator
4093     */
4094    public values(): IterableIterator<Number> {
4095        return new Int16ArrayIterator(this)
4096    }
4097
4098    /**
4099     * Iteratorable interface implementation
4100     *
4101     * @returns iterator over all elements
4102     */
4103    public override $_iterator(): IterableIterator<Number> {
4104        return this.values()
4105    }
4106
4107    /**
4108     * Creates a copy with replaced value on index
4109     *
4110     * @param index
4111     *
4112     * @param value
4113     *
4114     * @returns an Int16Array with replaced value on index
4115     */
4116    public with(index: number, value: number): Int16Array {
4117        return this.with(index as int, value as short)
4118    }
4119
4120    /**
4121     * Creates a copy with replaced value on index
4122     *
4123     * @param index
4124     *
4125     * @param value
4126     *
4127     * @returns an Int16Array with replaced value on index
4128     */
4129    public with(index: int, value: short): Int16Array {
4130        let res = new Int16Array(this)
4131        res.set(index, value)
4132        return res
4133    }
4134
4135    /// === with element lambda functions ===
4136    /**
4137     * Determines whether the specified callback function returns true for all elements of an array.
4138     *
4139     * @param predicate A function that accepts one argument.
4140     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4141     * or until the end of the array.
4142     *
4143     * @returns true unless predicate function returns a false for an array element,
4144     * in which case false is immediately returned.
4145     */
4146    public every(predicate: (element: number) => boolean): boolean {
4147        return this.every((element: number, index: number, array: Int16Array): boolean => predicate(element))
4148    }
4149
4150    /**
4151     * creates a new Int16Array from current Int16Array based on a condition fn
4152     *
4153     * @param fn the condition to apply for each element
4154     *
4155     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4156     */
4157    public filter(fn: (val: number) => boolean): Int16Array {
4158        let newF: (val: number, index: number, array: Int16Array) => boolean =
4159            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4160        return this.filter(newF)
4161    }
4162
4163    /**
4164     * Returns the value of the first element in the array where predicate is true, and undefined
4165     * otherwise
4166     *
4167     * @param predicate find calls predicate once for each element of the array, in ascending
4168     * order, until it finds one where predicate returns true. If such an element is found, find
4169     * immediately returns that element value. Otherwise, find returns undefined
4170     *
4171     * @returns number | undefined
4172     */
4173    public find(predicate: () => boolean): number | undefined {
4174        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate())
4175    }
4176
4177    /**
4178     * Returns the value of the first element in the array where predicate is true, and undefined
4179     * otherwise
4180     *
4181     * @param predicate find calls predicate once for each element of the array, in ascending
4182     * order, until it finds one where predicate returns true. If such an element is found, find
4183     * immediately returns that element value. Otherwise, find returns undefined
4184     *
4185     * @returns number | undefined
4186     */
4187    public find(predicate: (value: number) => boolean): number | undefined {
4188        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate(value))
4189    }
4190
4191    /**
4192     * Returns the index of the first element in the array where predicate is true, and -1
4193     * otherwise
4194     *
4195     * @param predicate find calls predicate once for each element of the array, in ascending
4196     * order, until it finds one where predicate returns true. If such an element is found,
4197     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
4198     *
4199     * @returns number
4200     */
4201    public findIndex(predicate: (value: number) => boolean): number {
4202        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate(value)) as number
4203    }
4204
4205    /**
4206     * Finds the last element in the Int16Array that satisfies the condition
4207     *
4208     * @param fn condition
4209     *
4210     * @returns the last element that satisfies fn
4211     */
4212    public findLast(fn: (val: number) => boolean): number {
4213        let newF: (val: number, index: number, array: Int16Array) => boolean =
4214            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4215        return this.findLast(newF) as number
4216    }
4217
4218    /**
4219     * Finds an index of the last element in the Int16Array that satisfies the condition
4220     *
4221     * @param fn condition
4222     *
4223     * @returns the index of the last element that satisfies fn, -1 otherwise
4224     */
4225    public findLastIndex(fn: (val: number) => boolean): number {
4226        let newF: (val: number, index: number, array: Int16Array) => boolean =
4227            (val: number, index: number, array: Int16Array): boolean => { return fn(val) }
4228        return this.findLastIndex(newF) as number
4229    }
4230
4231    /**
4232     * Performs the specified action for each element in Int16Array
4233     *
4234     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
4235     * callbackfn function one time for each element in the array.
4236     *
4237     * @returns None
4238     */
4239    public forEach(callbackfn: (value: number) => void): void {
4240        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn(value))
4241    }
4242
4243    /**
4244     * Creates a new Int16Array using fn(arr[i]) over all elements of current Int16Array
4245     *
4246     * @param fn a function to apply for each element of current Int16Array
4247     *
4248     * @returns a new Int16Array where for each element from current Int16Array fn was applied
4249     */
4250    public map(fn: (val: number) => number): Int16Array {
4251        let newF: (val: number, index: number) => number =
4252            (val: number, index: number): number => { return fn(val) }
4253        return this.map(newF)
4254    }
4255
4256    /**
4257     * Determines whether the specified callback function returns true for any element of an array.
4258     *
4259     * @param predicate A function that accepts one argument.
4260     * The some method calls the predicate function for each element in the array
4261     * until the predicate returns a true or until the end of the array.
4262     *
4263     * @returns false unless predicate function returns true for an array element,
4264     * in which case true is immediately returned.
4265     */
4266    public some(predicate: (element: number) => boolean): boolean {
4267        return this.some((element: number, index: number, array: Int16Array): boolean => predicate(element))
4268    }
4269
4270    // NOTE (kprokopenko): this may be not skipped
4271    /**
4272     * Sorts in-place
4273     *
4274     * @param compareFn comparator —  used to determine the order of the elements.
4275     * compareFn returns a negative value if first argument is less than second argument,
4276     * zero if they're equal and a positive value otherwise.
4277     * If omitted, the elements are sorted in ascending order.
4278     *
4279     * @returns sorted Int16Array
4280     */
4281    public sort(compareFn?: (a: number, b: number) => number): this {
4282        let arr: short[] = new short[this.lengthInt]
4283        for (let i = 0; i < this.lengthInt; ++i) {
4284            arr[i] = this.getUnsafe(i)
4285        }
4286        let cmp = (l: short, r: short): number => {
4287                return (l - r) as number
4288            }
4289        if (compareFn != undefined) {
4290            cmp = (l: short, r: short): number => {
4291                return compareFn!(l as number, r as number)
4292            }
4293        }
4294        sort(arr, cmp)
4295        for (let i = 0; i < this.lengthInt; ++i) {
4296            this.setUnsafe(i, arr[i])
4297        }
4298        return this
4299    }
4300
4301    /**
4302     * Sorts in-place
4303     *
4304     * @param compareFn comparator —  used to determine the order of the elements.
4305     * compareFn returns a negative value if first argument is less than second argument,
4306     * zero if they're equal and a positive value otherwise.
4307     *
4308     * @returns sorted Int16Array
4309     */
4310    public sort(compareFn: (a: number) => number): this {
4311        let cmp = (a: number, b: number) => { return compareFn(a)}
4312        this.sort(cmp)
4313        return this
4314    }
4315
4316    /**
4317     * Sorts in-place
4318     *
4319     * @param fn compareFn —  used to determine the order of the elements.
4320     * compareFn returns a negative value if first argument is less than second argument,
4321     * zero if they're equal and a positive value otherwise.
4322     *
4323     * @returns sorted Int16Array
4324     */
4325    public sort(compareFn: () => number): this {
4326        let cmp = (a: number, b: number) => { return compareFn()}
4327        this.sort(cmp)
4328        return this
4329    }
4330
4331    /**
4332     * Determines whether the specified callback function returns true for any element of an array.
4333     *
4334     * @param predicate A function that accepts three arguments.
4335     * The some method calls the predicate function for each element in the array
4336     * until the predicate returns a true or until the end of the array.
4337     *
4338     * @returns false unless predicate function returns true for an array element,
4339     * in which case true is immediately returned.
4340     */
4341    public some(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
4342        for (let i = 0; i < this.lengthInt; ++i) {
4343            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
4344                return true
4345            }
4346        }
4347        return false
4348    }
4349
4350    /**
4351     * Determines whether the specified callback function returns true for any element of an array.
4352     *
4353     * @param predicate A function that accepts two arguments.
4354     * The some method calls the predicate function for each element in the array
4355     * until the predicate returns a true or until the end of the array.
4356     *
4357     * @returns false unless predicate function returns true for an array element,
4358     * in which case true is immediately returned.
4359     */
4360    public some(predicate: (element: number, index: number) => boolean): boolean {
4361        return this.some((element: number, index: number, array: Int16Array): boolean => predicate(element, index as number))
4362    }
4363
4364    /**
4365     * Determines whether the specified callback function returns true for any element of an array.
4366     *
4367     * @param predicate A function that accepts no arguments.
4368     * The some method calls the predicate function for each element in the array
4369     * until the predicate returns a true or until the end of the array.
4370     *
4371     * @returns false unless predicate function returns true for an array element,
4372     * in which case true is immediately returned.
4373     */
4374    public some(predicate: () => boolean): boolean {
4375        return this.some((element: number, index: number, array: Int16Array): boolean => predicate())
4376    }
4377
4378    /**
4379     * Calls the specified callback function for all the elements in an array.
4380     * The return value of the callback function is the accumulated result,
4381     * and is provided as an argument in the next call to the callback function.
4382     *
4383     * @param callbackfn A function that accepts four arguments.
4384     * The reduce method calls the callbackfn function one time for each element in the array.
4385     *
4386     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4387     * The first call to the callbackfn function provides this value as an argument.
4388     *
4389     * @returns The value that results from running the callback function to completion over the entire typed array.
4390     */
4391    public reduce<U = number>(
4392                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
4393                initialValue: U): U {
4394        let accumulatedValue = initialValue
4395        for (let i = 0; i < this.lengthInt; ++i) {
4396            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4397        }
4398        return accumulatedValue
4399    }
4400
4401    /**
4402     * Calls the specified callback function for all the elements in an array.
4403     * The return value of the callback function is the accumulated result,
4404     * and is provided as an argument in the next call to the callback function.
4405     *
4406     * @param callbackfn A function that accepts three arguments.
4407     * The reduce method calls the callbackfn function one time for each element in the array.
4408     *
4409     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4410     * The first call to the callbackfn function provides this value as an argument.
4411     *
4412     * @returns The value that results from running the callback function to completion over the entire typed array.
4413     */
4414    public reduce<U = number>(
4415                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
4416                initialValue: U): U {
4417        return this.reduce(
4418                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4419                        callbackfn(prevVal, currVal, currIndex), initialValue)
4420    }
4421
4422    /**
4423     * Calls the specified callback function for all the elements in an array.
4424     * The return value of the callback function is the accumulated result,
4425     * and is provided as an argument in the next call to the callback function.
4426     *
4427     * @param callbackfn A function that accepts two arguments.
4428     * The reduce method calls the callbackfn function one time for each element in the array.
4429     *
4430     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4431     * The first call to the callbackfn function provides this value as an argument.
4432     *
4433     * @returns The value that results from running the callback function to completion over the entire typed array.
4434     */
4435    public reduce<U = number>(
4436                callbackfn: (previousValue: U, currentValue: number) => U,
4437                initialValue: U): U {
4438        return this.reduce(
4439                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4440                        callbackfn(prevVal, currVal), initialValue)
4441    }
4442
4443    /**
4444     * Calls the specified callback function for all the elements in an array.
4445     * The return value of the callback function is the accumulated result,
4446     * and is provided as an argument in the next call to the callback function.
4447     *
4448     * @param callbackfn A function that accepts one argument
4449     * The reduce method calls the callbackfn function one time for each element in the array.
4450     *
4451     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4452     * The first call to the callbackfn function provides this value as an argument.
4453     *
4454     * @returns The value that results from running the callback function to completion over the entire typed array.
4455     */
4456    public reduce<U = number>(
4457                callbackfn: (previousValue: U) => U,
4458                initialValue: U): U {
4459        return this.reduce(
4460                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4461                        callbackfn(prevVal), initialValue)
4462    }
4463
4464    /**
4465     * Calls the specified callback function for all the elements in an array.
4466     * The return value of the callback function is the accumulated result,
4467     * and is provided as an argument in the next call to the callback function.
4468     *
4469     * @param callbackfn A function that accepts no arguments
4470     * The reduce method calls the callbackfn function one time for each element in the array.
4471     *
4472     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4473     * The first call to the callbackfn function provides this value as an argument.
4474     *
4475     * @returns The value that results from running the callback function to completion over the entire typed array.
4476     */
4477    public reduce<U = number>(
4478                callbackfn: () => U,
4479                initialValue: U): U {
4480        return this.reduce(
4481                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4482                        callbackfn(), initialValue)
4483    }
4484
4485    /**
4486     * Calls the specified callback function for all the elements in an array.
4487     * The return value of the callback function is the accumulated result,
4488     * and is provided as an argument in the next call to the callback function.
4489     *
4490     * @param callbackfn A function that accepts four arguments.
4491     * The reduce method calls the callbackfn function one time for each element in the array.
4492     * The first call to the callbackfn function provides array first element value as an argument
4493     *
4494     * @returns The value that results from running the callback function to completion over the entire typed array.
4495     * calling reduce method on an empty array without an initial value creates a TypeError
4496     */
4497    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
4498        if (this.lengthInt == 0) {
4499            throw new TypeError("Reduce of empty array with no initial value")
4500        }
4501
4502        let accumulatedValue = this.getUnsafe(0) as number
4503        for (let i = 1; i < this.lengthInt; ++i) {
4504            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4505        }
4506        return accumulatedValue
4507    }
4508
4509    /**
4510     * Calls the specified callback function for all the elements in an array.
4511     * The return value of the callback function is the accumulated result,
4512     * and is provided as an argument in the next call to the callback function.
4513     *
4514     * @param callbackfn A function that accepts three arguments.
4515     * The reduce method calls the callbackfn function one time for each element in the array.
4516     * The first call to the callbackfn function provides array first element value as an argument
4517     *
4518     * @returns The value that results from running the callback function to completion over the entire typed array.
4519     * calling reduce method on an empty array without an initial value creates a TypeError
4520     */
4521    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
4522        return this.reduce(
4523                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4524                        callbackfn(prevVal, currVal, currIndex))
4525    }
4526
4527    /**
4528     * Calls the specified callback function for all the elements in an array.
4529     * The return value of the callback function is the accumulated result,
4530     * and is provided as an argument in the next call to the callback function.
4531     *
4532     * @param callbackfn A function that accepts two arguments.
4533     * The reduce method calls the callbackfn function one time for each element in the array.
4534     * The first call to the callbackfn function provides array first element value as an argument
4535     *
4536     * @returns The value that results from running the callback function to completion over the entire typed array.
4537     * calling reduce method on an empty array without an initial value creates a TypeError
4538     */
4539    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
4540        return this.reduce(
4541                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4542                        callbackfn(prevVal, currVal))
4543    }
4544
4545    /**
4546     * Calls the specified callback function for all the elements in an array.
4547     * The return value of the callback function is the accumulated result,
4548     * and is provided as an argument in the next call to the callback function.
4549     *
4550     * @param callbackfn A function that accepts one argument.
4551     * The reduce method calls the callbackfn function one time for each element in the array.
4552     * The first call to the callbackfn function provides array first element value as an argument
4553     *
4554     * @returns The value that results from running the callback function to completion over the entire typed array.
4555     * calling reduce method on an empty array without an initial value creates a TypeError
4556     */
4557    public reduce(callbackfn: (previousValue: number) => number): number {
4558        return this.reduce(
4559                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4560                        callbackfn(prevVal))
4561    }
4562
4563    /**
4564     * Calls the specified callback function for all the elements in an array.
4565     * The return value of the callback function is the accumulated result,
4566     * and is provided as an argument in the next call to the callback function.
4567     *
4568     * @param callbackfn A function that accepts no arguments.
4569     * The reduce method calls the callbackfn function one time for each element in the array.
4570     * The first call to the callbackfn function provides array first element value as an argument
4571     *
4572     * @returns The value that results from running the callback function to completion over the entire typed array.
4573     * calling reduce method on an empty array without an initial value creates a TypeError
4574     */
4575    public reduce(callbackfn: () => number): number {
4576        return this.reduce(
4577                (prevVal: number, currVal: number, currIndex: number, array: Int16Array) =>
4578                        callbackfn())
4579    }
4580
4581
4582    /**
4583     * Calls the specified callback function for all the elements in an array, in descending order.
4584     * The return value of the callback function is the accumulated result,
4585     * and is provided as an argument in the next call to the callback function.
4586     *
4587     * @param callbackfn A function that accepts four arguments.
4588     * The reduceRight method calls the callbackfn function one time for each element in the array.
4589     *
4590     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4591     * The first call to the callbackfn function provides this value as an argument.
4592     *
4593     * @returns The value that results from running the callback function to completion over the entire typed array.
4594     */
4595    public reduceRight<U = number>(
4596                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U,
4597                initialValue: U): U {
4598        let accumulatedValue = initialValue
4599        for (let i = this.lengthInt - 1; i >= 0; --i) {
4600            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4601        }
4602        return accumulatedValue
4603    }
4604
4605    /**
4606     * Calls the specified callback function for all the elements in an array, in descending order.
4607     * The return value of the callback function is the accumulated result,
4608     * and is provided as an argument in the next call to the callback function.
4609     *
4610     * @param callbackfn A function that accepts three arguments.
4611     * The reduceRight method calls the callbackfn function one time for each element in the array.
4612     *
4613     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4614     * The first call to the callbackfn function provides this value as an argument.
4615     *
4616     * @returns The value that results from running the callback function to completion over the entire typed array.
4617     */
4618    public reduceRight<U = number>(
4619                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
4620                initialValue: U): U {
4621        return this.reduceRight(
4622                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4623                        callbackfn(prevVal, currVal, currIndex), initialValue)
4624    }
4625
4626    /**
4627     * Calls the specified callback function for all the elements in an array, in descending order.
4628     * The return value of the callback function is the accumulated result,
4629     * and is provided as an argument in the next call to the callback function.
4630     *
4631     * @param callbackfn A function that accepts two arguments.
4632     * The reduceRight method calls the callbackfn function one time for each element in the array.
4633     *
4634     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4635     * The first call to the callbackfn function provides this value as an argument.
4636     *
4637     * @returns The value that results from running the callback function to completion over the entire typed array.
4638     */
4639    public reduceRight<U = number>(
4640                callbackfn: (previousValue: U, currentValue: number) => U,
4641                initialValue: U): U {
4642        return this.reduceRight(
4643                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4644                        callbackfn(prevVal, currVal), initialValue)
4645    }
4646
4647    /**
4648     * Calls the specified callback function for all the elements in an array, in descending order.
4649     * The return value of the callback function is the accumulated result,
4650     * and is provided as an argument in the next call to the callback function.
4651     *
4652     * @param callbackfn A function that accepts one argument.
4653     * The reduceRight method calls the callbackfn function one time for each element in the array.
4654     *
4655     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4656     * The first call to the callbackfn function provides this value as an argument.
4657     *
4658     * @returns The value that results from running the callback function to completion over the entire typed array.
4659     */
4660    public reduceRight<U = number>(
4661                callbackfn: (previousValue: U) => U,
4662                initialValue: U): U {
4663        return this.reduceRight(
4664                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4665                        callbackfn(prevVal), initialValue)
4666    }
4667
4668    /**
4669     * Calls the specified callback function for all the elements in an array, in descending order.
4670     * The return value of the callback function is the accumulated result,
4671     * and is provided as an argument in the next call to the callback function.
4672     *
4673     * @param callbackfn A function that accepts no arguments.
4674     * The reduceRight method calls the callbackfn function one time for each element in the array.
4675     *
4676     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
4677     * The first call to the callbackfn function provides this value as an argument.
4678     *
4679     * @returns The value that results from running the callback function to completion over the entire typed array.
4680     */
4681    public reduceRight<U = number>(
4682                callbackfn: () => U,
4683                initialValue: U): U {
4684        return this.reduceRight(
4685                (prevVal: U, currVal: number, currIndex: number, array: Int16Array) =>
4686                        callbackfn(), initialValue)
4687    }
4688
4689    /**
4690     * Calls the specified callback function for all the elements in an array, in descending order.
4691     * The return value of the callback function is the accumulated result,
4692     * and is provided as an argument in the next call to the callback function.
4693     *
4694     * @param callbackfn A function that accepts four arguments.
4695     * The reduceRight method calls the callbackfn function one time for each element in the array.
4696     * The first call to the callbackfn function provides array last element value as an argument
4697     *
4698     * @returns The value that results from running the callback function to completion over the entire typed array.
4699     * calling reduceRight method on an empty array without an initial value creates a TypeError
4700     */
4701    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number {
4702        if (this.lengthInt == 0) {
4703            throw new TypeError("Reduce of empty array with no initial value")
4704        }
4705
4706        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
4707        for (let i = this.lengthInt - 2; i >= 0; --i) {
4708            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
4709        }
4710        return accumulatedValue
4711    }
4712
4713    /**
4714     * Calls the specified callback function for all the elements in an array, in descending order.
4715     * The return value of the callback function is the accumulated result,
4716     * and is provided as an argument in the next call to the callback function.
4717     *
4718     * @param callbackfn A function that accepts three arguments.
4719     * The reduceRight method calls the callbackfn function one time for each element in the array.
4720     * The first call to the callbackfn function provides array last element value as an argument
4721     *
4722     * @returns The value that results from running the callback function to completion over the entire typed array.
4723     * calling reduceRight method on an empty array without an initial value creates a TypeError
4724     */
4725    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
4726        return this.reduceRight(
4727                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4728                        callbackfn(prevValue, currValue, currIndex))
4729    }
4730
4731    /**
4732     * Calls the specified callback function for all the elements in an array, in descending order.
4733     * The return value of the callback function is the accumulated result,
4734     * and is provided as an argument in the next call to the callback function.
4735     *
4736     * @param callbackfn A function that accepts two arguments.
4737     * The reduceRight method calls the callbackfn function one time for each element in the array.
4738     * The first call to the callbackfn function provides array last element value as an argument
4739     *
4740     * @returns The value that results from running the callback function to completion over the entire typed array.
4741     * calling reduceRight method on an empty array without an initial value creates a TypeError
4742     */
4743    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
4744        return this.reduceRight(
4745                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4746                        callbackfn(prevValue, currValue))
4747    }
4748
4749    /**
4750     * Calls the specified callback function for all the elements in an array, in descending order.
4751     * The return value of the callback function is the accumulated result,
4752     * and is provided as an argument in the next call to the callback function.
4753     *
4754     * @param callbackfn A function that accepts one argument.
4755     * The reduceRight method calls the callbackfn function one time for each element in the array.
4756     * The first call to the callbackfn function provides array last element value as an argument
4757     *
4758     * @returns The value that results from running the callback function to completion over the entire typed array.
4759     * calling reduceRight method on an empty array without an initial value creates a TypeError
4760     */
4761    public reduceRight(callbackfn: (previousValue: number) => number): number {
4762        return this.reduceRight(
4763                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4764                        callbackfn(prevValue))
4765    }
4766
4767    /**
4768     * Calls the specified callback function for all the elements in an array, in descending order.
4769     * The return value of the callback function is the accumulated result,
4770     * and is provided as an argument in the next call to the callback function.
4771     *
4772     * @param callbackfn A function that accepts no arguments.
4773     * The reduceRight method calls the callbackfn function one time for each element in the array.
4774     * The first call to the callbackfn function provides array last element value as an argument
4775     *
4776     * @returns The value that results from running the callback function to completion over the entire typed array.
4777     * calling reduceRight method on an empty array without an initial value creates a TypeError
4778     */
4779    public reduceRight(callbackfn: () => number): number {
4780        return this.reduceRight(
4781                (prevValue: number, currValue: number, currIndex: number, array: Int16Array) =>
4782                        callbackfn())
4783    }
4784
4785   /**
4786    * Creates a new Int16Array using fn(arr[i]) over all elements of current Int16Array.
4787    *
4788    * @param fn a function to apply for each element of current Int16Array
4789    *
4790    * @returns a new Int16Array where for each element from current Int16Array fn was applied
4791    */
4792    public map(fn: (val: number, index: number) => number): Int16Array {
4793        let resBuf = new ArrayBuffer(this.lengthInt * Int16Array.BYTES_PER_ELEMENT as int)
4794        let res = new Int16Array(resBuf, 0, resBuf.getByteLength() / Int16Array.BYTES_PER_ELEMENT as int)
4795        for (let i = 0; i < this.lengthInt; ++i) {
4796            res.set(i, fn(this.getUnsafe(i) as number, i as number) as short)
4797        }
4798        return res
4799    }
4800
4801    /**
4802     * Determines whether the specified callback function returns true for all elements of an array.
4803     *
4804     * @param predicate A function that accepts three arguments.
4805     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4806     * or until the end of the array.
4807     *
4808     * @returns true unless predicate function returns a false for an array element,
4809     * in which case false is immediately returned.
4810     */
4811    public every(predicate: (element: number, index: number, array: Int16Array) => boolean): boolean {
4812        for (let i = 0; i < this.lengthInt; ++i) {
4813            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
4814                return false
4815            }
4816        }
4817        return true
4818    }
4819
4820    /**
4821     * Determines whether the specified callback function returns true for all elements of an array.
4822     *
4823     * @param predicate A function that accepts two arguments.
4824     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4825     * or until the end of the array.
4826     *
4827     * @returns true unless predicate function returns a false for an array element,
4828     * in which case false is immediately returned.
4829     */
4830    public every(predicate: (element: number, index: number) => boolean): boolean {
4831        return this.every((element: number, index: number, array: Int16Array): boolean => predicate(element, index))
4832    }
4833
4834    /**
4835     * Determines whether the specified callback function returns true for all elements of an array.
4836     *
4837     * @param predicate A function that accepts no arguments.
4838     * The every method calls the predicate function for each element in the array until the predicate returns a false,
4839     * or until the end of the array.
4840     *
4841     * @returns true unless predicate function returns a false for an array element,
4842     * in which case false is immediately returned.
4843     */
4844    public every(predicate: () => boolean): boolean {
4845        return this.every((element: number, index: number, array: Int16Array): boolean => predicate())
4846    }
4847
4848    /**
4849     * Creates a new Int16Array from current Int16Array based on a condition fn.
4850     *
4851     * @param fn the condition to apply for each element
4852     *
4853     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4854     */
4855    public filter(fn: (val: number, index: number, array: Int16Array) => boolean): Int16Array {
4856        let markers = new boolean[this.lengthInt]
4857        let resLen = 0
4858        for (let i = 0; i < this.lengthInt; ++i) {
4859            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
4860            if (markers[i]) {
4861                ++resLen
4862            }
4863        }
4864        let resBuf = new ArrayBuffer(resLen * Int16Array.BYTES_PER_ELEMENT as int)
4865        let res = new Int16Array(resBuf, 0)
4866        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
4867            if (markers[i]) {
4868                res.set(j, this.getUnsafe(i))
4869                ++j
4870            }
4871        }
4872        return res
4873    }
4874
4875    /**
4876     * creates a new Int16Array from current Int16Array based on a condition fn
4877     *
4878     * @param fn the condition to apply for each element
4879     *
4880     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4881     */
4882    public filter(fn: (val: number, index: number) => boolean): Int16Array {
4883        let newF: (val: number, index: number, array: Int16Array) => boolean =
4884            (val: number, index: number, array: Int16Array): boolean => { return fn(val, index as number) }
4885        return this.filter(newF)
4886    }
4887
4888    /**
4889     * creates a new Int16Array from current Int16Array based on a condition fn
4890     *
4891     * @param fn the condition to apply for each element
4892     *
4893     * @returns a new Int16Array with elements from current Int16Array that satisfy condition fn
4894     */
4895    public filter(fn: () => boolean): Int16Array {
4896        let newF: (val: number, index: number, array: Int16Array) => boolean =
4897            (val: number, index: number, array: Int16Array): boolean => { return fn() }
4898        return this.filter(newF)
4899    }
4900
4901    /**
4902     * Returns the value of the first element in the array where predicate is true, and undefined
4903     * otherwise
4904     *
4905     * @param predicate find calls predicate once for each element of the array, in ascending
4906     * order, until it finds one where predicate returns true. If such an element is found, find
4907     * immediately returns that element value. Otherwise, find returns undefined
4908     *
4909     * @returns number | undefined
4910     */
4911    public find(predicate: (value: number, index: number, obj: Int16Array) => boolean): number | undefined {
4912        for (let i = 0; i < this.lengthInt; ++i) {
4913            let val = this.getUnsafe(i)
4914            if (predicate(val as number, i as number, this)) {
4915                return val as number
4916            }
4917        }
4918        return undefined
4919    }
4920
4921    /**
4922     * Returns the value of the first element in the array where predicate is true, and undefined
4923     * otherwise
4924     *
4925     * @param predicate find calls predicate once for each element of the array, in ascending
4926     * order, until it finds one where predicate returns true. If such an element is found, find
4927     * immediately returns that element value. Otherwise, find returns undefined
4928     *
4929     * @returns number | undefined
4930     */
4931    public find(predicate: (value: number, index: number) => boolean): number | undefined {
4932        return this.find((value: number, index: number, obj: Int16Array): boolean => predicate(value, index))
4933    }
4934
4935    /**
4936     * Returns the index of the first element in the array where predicate is true, and -1
4937     * otherwise
4938     *
4939     * @param predicate find calls predicate once for each element of the array, in ascending
4940     * order, until it finds one where predicate returns true. If such an element is found,
4941     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
4942     *
4943     * @returns number
4944     */
4945    public findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean): number {
4946        for (let i = 0; i < this.lengthInt; ++i) {
4947            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
4948                return i as number
4949            }
4950        }
4951        return -1 as number
4952    }
4953
4954    /**
4955     * Returns the index of the first element in the array where predicate is true, and -1
4956     * otherwise
4957     *
4958     * @param predicate find calls predicate once for each element of the array, in ascending
4959     * order, until it finds one where predicate returns true. If such an element is found,
4960     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
4961     *
4962     * @returns number
4963     */
4964    public findIndex(predicate: (value: number, index: number) => boolean): number {
4965        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate(value, index as number)) as number
4966    }
4967
4968    /**
4969     * Returns the index of the first element in the array where predicate is true, and -1
4970     * otherwise
4971     *
4972     * @param predicate find calls predicate once for each element of the array, in ascending
4973     * order, until it finds one where predicate returns true. If such an element is found,
4974     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
4975     *
4976     * @returns number
4977     */
4978    public findIndex(predicate: () => boolean): number {
4979        return this.findIndex((value: number, index: number, obj: Int16Array): boolean => predicate()) as number
4980    }
4981
4982    /**
4983     * Finds the last element in the Int16Array that satisfies the condition
4984     *
4985     * @param fn condition
4986     *
4987     * @returns the last element that satisfies fn
4988     */
4989    public findLast(fn: (val: number, index: number, array: Int16Array) => boolean): short {
4990        for (let i = this.lengthInt - 1; i >= 0; --i) {
4991            let val = this.getUnsafe(i)
4992            if (fn(val as number, i as number, this)) {
4993                return val
4994            }
4995        }
4996        throw new Error("Int16Array.findLast: not implemented if an element was not found")
4997    }
4998
4999    /**
5000     * Finds the last element in the Int16Array that satisfies the condition
5001     *
5002     * @param fn condition
5003     *
5004     * @returns the last element that satisfies fn
5005     */
5006    public findLast(fn: (val: number, index: number) => boolean): short {
5007        let newF: (val: number, index: number, array: Int16Array) => boolean =
5008            (val: number, index: number, array: Int16Array): boolean => { return fn(val as number, index as number) }
5009        return this.findLast(newF)
5010    }
5011
5012    /**
5013     * Finds an index of the last element in the Int16Array that satisfies the condition
5014     *
5015     * @param fn condition
5016     *
5017     * @returns the index of the last element that satisfies fn, -1 otherwise
5018     */
5019    public findLastIndex(fn: (val: number, index: number, array: Int16Array) => boolean): number {
5020        for (let i = this.lengthInt - 1; i >= 0; --i) {
5021            let val = this.getUnsafe(i)
5022            if (fn(val as number, i as number, this)) {
5023                return i
5024            }
5025        }
5026        return -1 as number
5027    }
5028
5029    /**
5030     * Finds an index of the last element in the Int16Array that satisfies the condition
5031     *
5032     * @param fn condition
5033     *
5034     * @returns the index of the last element that satisfies fn, -1 otherwise
5035     */
5036    public findLastIndex(fn: (val: number, index: number) => boolean): number {
5037        let newF: (val: number, index: number, array: Int16Array) => boolean =
5038            (val: number, index: number, array: Int16Array): boolean => { return fn(val, index as number) }
5039        return this.findLastIndex(newF) as number
5040    }
5041
5042    /**
5043     * Performs the specified action for each element in Int16Array
5044     *
5045     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5046     * callbackfn function one time for each element in the array.
5047     *
5048     * @returns None
5049     */
5050    public forEach(callbackfn: (value: number, index: number, array: Int16Array) => void): void {
5051        for (let i = 0; i < this.lengthInt; ++i) {
5052            callbackfn(this.getUnsafe(i) as number, i as number, this)
5053        }
5054    }
5055
5056    /**
5057     * Performs the specified action for each element in Int16Array
5058     *
5059     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5060     * callbackfn function one time for each element in the array.
5061     *
5062     * @returns None
5063     */
5064    public forEach(callbackfn: (value: number, index: number) => void): void {
5065        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn(value, index))
5066    }
5067
5068    /**
5069     * Performs the specified action for each element in Int16Array
5070     *
5071     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
5072     * callbackfn function one time for each element in the array.
5073     *
5074     * @returns None
5075     */
5076    public forEach(callbackfn: () => void): void {
5077        this.forEach((value: number, index: number, array: Int16Array): void => callbackfn())
5078    }
5079
5080    /**
5081     * Returns the object itself
5082     *
5083     * @returns Int16Array
5084     */
5085    public valueOf(): Int16Array {
5086        return this
5087    }
5088
5089    internal getUnsafe(index: int): short {
5090        let byteIndex = index * Int16Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
5091        let res : short = 0
5092        let byteVal : short
5093        if (IS_LITTLE_ENDIAN) {
5094            if (this.buffer instanceof ArrayBuffer) {
5095                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5096                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
5097                    byteVal &= 0xff
5098                    res = (res | byteVal << (8 * i)) as short
5099                }
5100            } else if (this.buffer instanceof SharedArrayBuffer) {
5101                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5102                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
5103                    byteVal &= 0xff
5104                    res = (res | byteVal << (8 * i)) as short
5105                }
5106            } else {
5107                throw new Error("unexpected type of ArrayBufferLike")
5108            }
5109            return res
5110        } else {
5111            if (this.buffer instanceof ArrayBuffer) {
5112                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5113                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 1 - i)
5114                    byteVal &= 0xff
5115                    res = (res | byteVal << (8 * i)) as short
5116                }
5117            } else if (this.buffer instanceof SharedArrayBuffer) {
5118                for (let i: int = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5119                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 1 - i)
5120                    byteVal &= 0xff
5121                    res = (res | byteVal << (8 * i)) as short
5122                }
5123            } else {
5124                throw new Error("unexpected type of ArrayBufferLike")
5125            }
5126            return res
5127        }
5128    }
5129
5130    internal setUnsafe(insertPos: int, val: short): void {
5131        let startByte = insertPos * Int16Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
5132        let bits = val
5133        if (IS_LITTLE_ENDIAN) {
5134            if (this.buffer instanceof ArrayBuffer) {
5135                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5136                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5137                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
5138                }
5139            } else if (this.buffer instanceof SharedArrayBuffer) {
5140                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; ++i) {
5141                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5142                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
5143                }
5144            } else {
5145                throw new Error("unexpected type of ArrayBufferLike")
5146            }
5147        } else {
5148            if (this.buffer instanceof ArrayBuffer) {
5149                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; i++) {
5150                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5151                    (this.buffer as ArrayBuffer).set(startByte + 1 - i, byteVal)
5152                }
5153            } else if (this.buffer instanceof SharedArrayBuffer) {
5154                for (let i = 0; i < Int16Array.BYTES_PER_ELEMENT as int; i++) {
5155                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
5156                    (this.buffer as SharedArrayBuffer).set(startByte + 1 - i, byteVal)
5157                }
5158            } else {
5159                throw new Error("unexpected type of ArrayBufferLike")
5160            }
5161        }
5162    }
5163
5164    /** Underlying ArrayBufferLike */
5165    public readonly buffer: ArrayBufferLike
5166
5167    /** Byte offset within the underlying ArrayBufferLike */
5168    public readonly byteOffset: number
5169
5170    /** Number of bytes used */
5171    public readonly byteLength: number
5172
5173    /** String \"Int16Array\" */
5174    public readonly name = "Int16Array"
5175}
5176
5177class Int32ArrayIteratorKeys implements IterableIterator<number> {
5178    private length: int
5179    private idx: int = 0
5180
5181    constructor(parent: Int32Array) {
5182        this.length = parent.length as int
5183    }
5184
5185    public override $_iterator(): IterableIterator<number> {
5186        return this
5187    }
5188
5189    override next(): IteratorResult<number> {
5190        if (this.idx < 0 || this.idx >= this.length) {
5191            return new IteratorResult<number>()
5192        }
5193        return new IteratorResult<number>(false, this.idx++ as number)
5194    }
5195}
5196
5197class Int32ArrayIterator implements IterableIterator<Number> {
5198    private parent: Int32Array
5199    private idx: int = 0
5200
5201    constructor(parent: Int32Array) {
5202        this.parent = parent
5203    }
5204
5205    public override $_iterator(): IterableIterator<Number> {
5206        return this
5207    }
5208
5209    override next(): IteratorResult<Number> {
5210        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5211            return new IteratorResult<Number>()
5212        }
5213        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
5214    }
5215}
5216
5217class Int32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
5218    private parent: Int32Array
5219    private idx: int = 0
5220
5221    constructor(parent: Int32Array) {
5222        this.parent = parent
5223    }
5224
5225    public override $_iterator(): IterableIterator<[Number, Number]> {
5226        return this
5227    }
5228
5229    override next(): IteratorResult<[Number, Number]> {
5230        if (this.idx < 0 || this.idx >= this.parent.length as int) {
5231            return new IteratorResult<[Number, Number]>()
5232        }
5233        return new IteratorResult<[Number, Number]>(
5234            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
5235        )
5236    }
5237}
5238
5239
5240/**
5241 * JS Int32Array API-compatible class
5242 */
5243export final class Int32Array implements Iterable<Number>, ArrayLike<Number> {
5244    public static readonly BYTES_PER_ELEMENT: number = 4
5245    internal readonly lengthInt: int
5246
5247    /**
5248     * Creates an empty Int32Array.
5249     */
5250    public constructor() {
5251        this(0 as int)
5252    }
5253
5254    /**
5255     * Creates an Int32Array with respect to data accessed via Iterable<Number> interface
5256     */
5257    public constructor(elements: Iterable<Number>) {
5258        // NOTE (ikorobkov): dealing with this overload is tricky
5259        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
5260        let arr = Array.from<Number>(elements)
5261        this.byteLength = arr.length * Int32Array.BYTES_PER_ELEMENT as int
5262        this.lengthInt = arr.length as int
5263        this.buffer = new ArrayBuffer(this.byteLength as int)
5264        this.byteOffset = 0
5265        for (let i: int = 0; i < this.lengthInt; ++i) {
5266            this.setUnsafe(i, arr.$_get(i).intValue())
5267        }
5268    }
5269
5270    /**
5271     * Creates an Int32Array with respect to data, byteOffset and length.
5272     *
5273     * @param buf data initializer
5274     *
5275     * @param byteOffset byte offset from begin of the buf
5276     *
5277     * @param length size of elements of type int in newly created Int32Array
5278     */
5279    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
5280        let intByteOffset: int = 0
5281        if (byteOffset != undefined) {
5282            intByteOffset = byteOffset.intValue()
5283            if (intByteOffset < 0) {
5284                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
5285            }
5286        }
5287        let intByteLength: int
5288        if (buf instanceof ArrayBuffer) {
5289            intByteLength = (buf as ArrayBuffer).getByteLength()
5290        } else if (buf instanceof SharedArrayBuffer) {
5291            intByteLength = (buf as SharedArrayBuffer).getByteLength()
5292        } else {
5293            throw new Error("unexpected type of ArrayBufferLike")
5294        }
5295        intByteLength = intByteLength - intByteOffset
5296        if (intByteLength < 0) {
5297            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5298        }
5299
5300        if (intByteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5301            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5302        }
5303        if (intByteOffset % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5304            throw new RangeError("byteOffset should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5305        }
5306
5307        let intLength: int
5308        if (length != undefined) {
5309            intLength = length.intValue()
5310            if (intLength > intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
5311                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
5312            }
5313        } else {
5314            intLength = intByteLength / Int32Array.BYTES_PER_ELEMENT as int
5315        }
5316        if (intLength < 0) {
5317            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
5318        }
5319        if (intLength < intByteLength / Int32Array.BYTES_PER_ELEMENT as int) {
5320            intByteLength = intLength * Int32Array.BYTES_PER_ELEMENT as int
5321        }
5322        this.byteLength = intByteLength
5323        this.byteOffset = intByteOffset
5324        this.lengthInt = intLength
5325        this.buffer = buf
5326    }
5327
5328    /**
5329     * Creates an Int32Array with respect to data, byteOffset and length.
5330     *
5331     * @param buf data initializer
5332     *
5333     * @param byteOffset byte offset from begin of the buf
5334     *
5335     * @param length size of elements of type int in newly created Int32Array
5336     */
5337    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
5338        this(buf, byteOffset, undefined)
5339    }
5340
5341    /**
5342     * Creates an Int32Array with respect to data, byteOffset and length.
5343     *
5344     * @param buf data initializer
5345     *
5346     * @param byteOffset byte offset from begin of the buf
5347     *
5348     * @param length size of elements of type int in newly created Int32Array
5349     */
5350    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
5351        this(buf, new Number(byteOffset), new Number(length))
5352    }
5353
5354    /**
5355     * Creates an Int32Array with respect to data, byteOffset and length.
5356     *
5357     * @param buf data initializer
5358     *
5359     * @param byteOffset byte offset from begin of the buf
5360     *
5361     * @param length size of elements of type int in newly created Int32Array
5362     */
5363    public constructor(buf: ArrayBufferLike, byteOffset: number) {
5364        this(buf, new Number(byteOffset), undefined)
5365    }
5366
5367    /**
5368     * Creates an Int32Array with respect to data, byteOffset and length.
5369     *
5370     * @param buf data initializer
5371     *
5372     * @param byteOffset byte offset from begin of the buf
5373     *
5374     * @param length size of elements of type int in newly created Int32Array
5375     */
5376    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
5377        this(buf, new Number(byteOffset), new Number(length))
5378    }
5379
5380    /**
5381     * Creates an Int32Array with respect to buf and byteOffset.
5382     *
5383     * @param buf data initializer
5384     *
5385     * @param byteOffset byte offset from begin of the buf
5386     */
5387    public constructor(buf: ArrayBufferLike, byteOffset: int) {
5388        this(buf, new Number(byteOffset), undefined)
5389    }
5390
5391    /**
5392     * Creates an Int32Array with respect to buf.
5393     *
5394     * @param buf data initializer
5395     */
5396    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
5397        if (buf instanceof ArrayBuffer) {
5398            this.byteLength = (buf as ArrayBuffer).getByteLength()
5399            if (this.byteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5400               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5401            }
5402            this.lengthInt = this.byteLength / Int32Array.BYTES_PER_ELEMENT as int
5403            this.buffer = buf as ArrayBuffer
5404            this.byteOffset = 0
5405        } else if (buf instanceof SharedArrayBuffer) {
5406            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
5407            if (this.byteLength % Int32Array.BYTES_PER_ELEMENT as int != 0) {
5408               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Int32Array.BYTES_PER_ELEMENT")
5409            }
5410            this.lengthInt = this.byteLength / Int32Array.BYTES_PER_ELEMENT as int
5411            this.buffer = buf as SharedArrayBuffer
5412            this.byteOffset = 0
5413        } else if (buf instanceof ArrayLike) {
5414            // NOTE (ikorobkov): dealing with this overload is tricky
5415            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
5416            let arr = Array.from<Number>((buf as ArrayLike<Number>))
5417            this.byteLength = arr.length as int * Int32Array.BYTES_PER_ELEMENT as int
5418            this.lengthInt = arr.length as int
5419            this.buffer = new ArrayBuffer(this.byteLength as int)
5420            this.byteOffset = 0
5421            for (let i: int = 0; i < this.lengthInt; ++i) {
5422                this.setUnsafe(i, arr.$_get(i).intValue())
5423            }
5424        } else {
5425            throw new Error("unexpected type of buf")
5426        }
5427    }
5428
5429    /**
5430     * Creates an Int32Array with respect to length.
5431     *
5432     * @param length data initializer
5433     */
5434    public constructor(length: int) {
5435        if (length < 0) {
5436            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
5437        }
5438        this.lengthInt = length
5439        this.byteLength = length * Int32Array.BYTES_PER_ELEMENT as int
5440        this.byteOffset = 0
5441        this.buffer = new ArrayBuffer(this.byteLength as int)
5442    }
5443
5444    /**
5445     * Creates an Int32Array with respect to length.
5446     *
5447     * @param length data initializer
5448     */
5449    public constructor(length: number) {
5450        this(length as int)
5451    }
5452
5453    /**
5454     * Creates a copy of Int32Array.
5455     *
5456     * @param other data initializer
5457     */
5458    public constructor(other: Int32Array) {
5459        if (other.buffer instanceof ArrayBuffer) {
5460            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
5461        } else if (other.buffer instanceof SharedArrayBuffer) {
5462            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
5463        } else {
5464            throw new Error("unexpected type of buffer")
5465        }
5466        this.byteLength = other.byteLength
5467        this.lengthInt = other.length as int
5468        this.byteOffset = 0
5469    }
5470
5471    /**
5472     * Creates an Int32Array from number[]
5473     */
5474    public constructor(numbers: number[]) {
5475        this(numbers.length)
5476        for (let i: int = 0; i < this.lengthInt; ++i) {
5477            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
5478        }
5479    }
5480
5481    /**
5482     * Creates an Int32Array from int[]
5483     */
5484    public constructor(numbers: int[]) {
5485        this(numbers.length)
5486        for (let i: int = 0; i < this.lengthInt; ++i) {
5487            this.setUnsafe(i, this.zeroIfInfinity(numbers[i]) as int)
5488        }
5489    }
5490
5491    internal zeroIfInfinity(val: number): number {
5492        if ((val == Infinity) || (val == -Infinity)) {
5493            return 0 as number
5494        }
5495        return val as number
5496    }
5497
5498    internal zeroIfInfinity(val: int): int {
5499        if ((val == Infinity) || (val == -Infinity)) {
5500            return 0 as int
5501        }
5502        return val
5503    }
5504
5505    /**
5506     * Assigns val as element on index.
5507     *
5508     * @param val value to set
5509     *
5510     * @param index index to change
5511     */
5512    public $_set(index: number, val: number): void {
5513        this.$_set(index as int, val)
5514    }
5515
5516    /**
5517     * Assigns val as element on index.
5518     *
5519     * @param val value to set
5520     *
5521     * @param index index to change
5522     */
5523    public $_set(index: int, val: number): void {
5524        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
5525        if (index < 0 || index >= this.lengthInt) {
5526            throw new RangeError("invalid index")
5527        }
5528        let v = this.zeroIfInfinity(val)
5529        this.setUnsafe(index, v as int)
5530    }
5531
5532    /**
5533     * Assigns val as element on index.
5534     *
5535     * @param val value to set
5536     *
5537     * @param index index to change
5538     */
5539    public $_set(index: number, val: int): void {
5540        this.$_set(index as int, val)
5541    }
5542
5543    /**
5544     * Assigns val as element on index.
5545     *
5546     * @param val value to set
5547     *
5548     * @param index index to change
5549     */
5550    public $_set(index: int, val: int): void {
5551        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
5552        if (index < 0 || index >= this.lengthInt) {
5553            throw new RangeError("invalid index")
5554        }
5555        let v = this.zeroIfInfinity(val)
5556        this.setUnsafe(index, v)
5557    }
5558
5559    /** Number of int stored in Int32Array */
5560    public get length(): number {
5561        return this.lengthInt
5562    }
5563
5564    /**
5565     * Returns an instance of number at passed index.
5566     *
5567     * @param index index to look at
5568     *
5569     * @returns a primitive at index
5570     */
5571    public override $_get(index: number): Number {
5572        return this.$_get(index as int) as Number
5573    }
5574
5575    /**
5576     * Returns an instance of number at passed index.
5577     *
5578     * @param index index to look at
5579     *
5580     * @returns a primitive at index
5581     */
5582    public $_get(index: int): number {
5583        if (index < 0 || index >= this.lengthInt) {
5584            throw new RangeError("invalid index")
5585        }
5586        return this.getUnsafe(index) as number
5587    }
5588
5589    /**
5590     * Returns an instance of primitive type at passed index.
5591     *
5592     * @param index index to look at
5593     *
5594     * @returns a primitive at index
5595     */
5596    public at(index: number): Number | undefined {
5597        return this.at(index as int)
5598    }
5599
5600    /**
5601     * Returns an instance of primitive type at passed index.
5602     *
5603     * @param index index to look at
5604     *
5605     * @returns a primitive at index
5606     */
5607    public at(index: int): Number | undefined {
5608        let k: int
5609        if (index >= 0) {
5610            k = index
5611        } else {
5612            k = this.lengthInt + index
5613        }
5614        if (k < 0 || k >= this.lengthInt) {
5615            return undefined
5616        }
5617        return new Number(this.getUnsafe(k))
5618    }
5619
5620    /**
5621     * Makes a copy of internal elements to targetPos from startPos to endPos.
5622     *
5623     * @param target insert index to place copied elements
5624     *
5625     * @param start start index to begin copy from
5626     *
5627     * @param end last index to end copy from, excluded
5628     *
5629     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5630     */
5631    public copyWithin(target: number, start: number, end?: number): Int32Array {
5632        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5633    }
5634
5635    /**
5636     * Makes a copy of internal elements to targetPos from startPos to endPos.
5637     *
5638     * @param target insert index to place copied elements
5639     *
5640     * @param start start index to begin copy from
5641     *
5642     * @param end last index to end copy from, excluded
5643     *
5644     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5645     */
5646    public copyWithin(target: int, start: number, end?: number): Int32Array {
5647        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5648    }
5649
5650    /**
5651     * Makes a copy of internal elements to targetPos from startPos to endPos.
5652     *
5653     * @param target insert index to place copied elements
5654     *
5655     * @param start start index to begin copy from
5656     *
5657     * @param end last index to end copy from, excluded
5658     *
5659     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5660     */
5661    public copyWithin(target: number, start: int, end?: number): Int32Array {
5662        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5663    }
5664
5665    /**
5666     * Makes a copy of internal elements to targetPos from startPos to endPos.
5667     *
5668     * @param target insert index to place copied elements
5669     *
5670     * @param start start index to begin copy from
5671     *
5672     * @param end last index to end copy from, excluded
5673     *
5674     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5675     */
5676    public copyWithin(target: int, start: int, end?: number): Int32Array {
5677        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
5678    }
5679
5680    /**
5681     * Makes a copy of internal elements to targetPos from startPos to endPos.
5682     *
5683     * @param target insert index to place copied elements
5684     *
5685     * @param start start index to begin copy from
5686     *
5687     * @param end last index to end copy from, excluded
5688     *
5689     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
5690     */
5691    public copyWithin(target: int, start: int, end: int): Int32Array {
5692        let toPos = normalizeIndex(target, this.lengthInt)
5693        let fromPos = normalizeIndex(start, this.lengthInt)
5694        const finalPos = normalizeIndex(end, this.lengthInt)
5695        let count: int = finalPos - fromPos
5696        if (count > (this.lengthInt - toPos)) {
5697            count = this.lengthInt - toPos
5698        }
5699        let direction: int = 1
5700        if ((fromPos < toPos) && (toPos < fromPos + count)) {
5701            fromPos = fromPos + count - 1
5702            toPos   = toPos   + count - 1
5703            direction = -1
5704        }
5705        while (count > 0) {
5706            const value = this.getUnsafe(fromPos)
5707            this.setUnsafe(toPos, value)
5708            fromPos = fromPos + direction
5709            toPos = toPos + direction
5710            --count
5711        }
5712        return this
5713    }
5714
5715    /**
5716     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
5717     *
5718     * @param target insert index to place copied elements
5719     *
5720     * See rules of parameters normalization:
5721     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5722     */
5723    public copyWithin(target: number): Int32Array {
5724        return this.copyWithin(target as int)
5725    }
5726
5727    /**
5728     * Makes a copy of internal elements to targetPos from begin to end of Int32Array.
5729     *
5730     * @param target insert index to place copied elements
5731     *
5732     * See rules of parameters normalization:
5733     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
5734     */
5735    public copyWithin(target: int): Int32Array {
5736        return this.copyWithin(target, 0, this.lengthInt)
5737    }
5738
5739    /**
5740     * Returns an array of key, value pairs for every entry in the Int32Array
5741     *
5742     * @returns key, value pairs for every entry in the array
5743     */
5744    public entries(): IterableIterator<[Number, Number]> {
5745        return new Int32ArrayIteratorEntries(this)
5746    }
5747
5748    /**
5749     * Fills the Int32Array with specified value
5750     *
5751     * @param value new valuy
5752     *
5753     * @returns modified Int32Array
5754     */
5755    public fill(value: number, start?: number, end?: number): this {
5756        value = this.zeroIfInfinity(value)
5757        this.fill(value as int, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
5758        return this
5759    }
5760
5761    /**
5762     * Fills the Int32Array with specified value
5763     *
5764     * @param value new valuy
5765     *
5766     * @returns modified Int32Array
5767     */
5768    public fill(value: number, start: int, end?: number): this {
5769        value = this.zeroIfInfinity(value)
5770        this.fill(value as int, start as int, asIntOrDefault(end, this.lengthInt))
5771        return this
5772    }
5773
5774    /**
5775     * Fills the Int32Array with specified value
5776     *
5777     * @param value new valuy
5778     *
5779     * @returns modified Int32Array
5780     */
5781    public fill(value: number, start: int, end: number): this {
5782        value = this.zeroIfInfinity(value)
5783        this.fill(value as int, start as int, end as int)
5784        return this
5785    }
5786
5787    /**
5788     * Fills the Int32Array with specified value
5789     *
5790     * @param value new valuy
5791     *
5792     * @returns modified Int32Array
5793     */
5794    public fill(value: number, start: number, end: int): this {
5795        value = this.zeroIfInfinity(value)
5796        this.fill(value as int, start as int, end as int)
5797        return this
5798    }
5799
5800    /**
5801     * Fills the Int32Array with specified value
5802     *
5803     * @param value new valuy
5804     *
5805     * @returns modified Int32Array
5806     */
5807    public fill(value: number, start: int, end: int): this {
5808        value = this.zeroIfInfinity(value)
5809        this.fill(value as int, start as int, end as int)
5810        return this
5811    }
5812
5813    /**
5814     * Fills the Int32Array with specified value
5815     *
5816     * @param value new valuy
5817     *
5818     * @returns modified Int32Array
5819     */
5820    public fill(value: int, start?: number, end?: number): this {
5821        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
5822        return this
5823    }
5824
5825    /**
5826     * Fills the Int32Array with specified value
5827     *
5828     * @param value new valuy
5829     *
5830     * @returns modified Int32Array
5831     */
5832    public fill(value: int, start: int, end?: number): this {
5833        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
5834        return this
5835    }
5836
5837    /**
5838     * Fills the Int32Array with specified value
5839     *
5840     * @param value new valuy
5841     *
5842     * @returns modified Int32Array
5843     */
5844    public fill(value: int, start: int, end: number): this {
5845        this.fill(value, start as int, end as int)
5846        return this
5847    }
5848
5849    /**
5850     * Fills the Int32Array with specified value
5851     *
5852     * @param value new valuy
5853     *
5854     * @returns modified Int32Array
5855     */
5856    public fill(value: int, start: number, end: int): this {
5857        this.fill(value, start as int, end as int)
5858        return this
5859    }
5860
5861    /**
5862     * Fills the Int32Array with specified value
5863     *
5864     * @param value new valuy
5865     *
5866     * @returns modified Int32Array
5867     */
5868    public fill(value: int, start: int, end: int): this {
5869        const k = normalizeIndex(start, this.lengthInt)
5870        const finalPos = normalizeIndex(end, this.lengthInt)
5871        for (let i: int = k; i < finalPos; ++i) {
5872            this.setUnsafe(i, value)
5873        }
5874        return this
5875    }
5876
5877    /**
5878     * Assigns val as element on insertPos.
5879     * @description Added to avoid (un)packing a single value into array to use overloaded set(int[], insertPos)
5880     *
5881     * @param val value to set
5882     *
5883     * @param insertPos index to change
5884     */
5885    public set(insertPos: number, val: number): void {
5886        this.$_set(insertPos, val)
5887    }
5888
5889    /**
5890     * Assigns val as element on insertPos.
5891     * @description Added to avoid (un)packing a single value into array to use overloaded set(int[], insertPos)
5892     *
5893     * @param val value to set
5894     *
5895     * @param insertPos index to change
5896     */
5897    public set(insertPos: int, val: int): void {
5898        this.$_set(insertPos, val)
5899    }
5900
5901    /**
5902     * Copies all elements of arr to the current Int32Array starting from insertPos.
5903     *
5904     * @param arr array to copy data from
5905     *
5906     * @param insertPos start index where data from arr will be inserted
5907     *
5908     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
5909     */
5910    public set(arr: number[], insertPos: number): void {
5911        const offset = insertPos as int
5912        if (offset < 0 || offset + arr.length > this.lengthInt) {
5913            throw new RangeError("offset is out of bounds")
5914        }
5915        for (let i = 0; i < arr.length as int; ++i) {
5916            let v = this.zeroIfInfinity(arr[i])
5917            this.setUnsafe(offset + i, v as int)
5918        }
5919    }
5920
5921    /**
5922     * Copies all elements of arr to the current Int32Array starting from insertPos.
5923     *
5924     * @param arr array to copy data from
5925     *
5926     * @param insertPos start index where data from arr will be inserted
5927     *
5928     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
5929     */
5930    public set(arr: int[], insertPos: int): void {
5931        const offset = insertPos as int
5932        if (offset < 0 || offset + arr.length > this.lengthInt) {
5933            throw new RangeError("offset is out of bounds")
5934        }
5935        for (let i = 0; i < arr.length as int; ++i) {
5936            let v = this.zeroIfInfinity(arr[i])
5937            this.setUnsafe(offset + i, v)
5938        }
5939    }
5940
5941    /**
5942     * Copies all elements of arr to the current Int32Array.
5943     *
5944     * @param arr array to copy data from
5945     */
5946    public set(arr: number[]): void {
5947        this.set(arr, 0 as number)
5948    }
5949
5950    /**
5951     * Copies all elements of arr to the current Int32Array.
5952     *
5953     * @param arr array to copy data from
5954     */
5955    public set(arr: int[]): void {
5956        this.set(arr, 0 as int)
5957    }
5958
5959    /**
5960     * Copies elements from an ArrayLike object to the Int32Array.
5961     *
5962     * @param array An ArrayLike object containing the elements to copy.
5963     *
5964     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
5965     */
5966    public set(array: ArrayLike<number>, offset: number = 0): void {
5967        const insertPos = offset as int
5968        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
5969            throw new RangeError("offset is out of bounds")
5970        }
5971        for (let i = 0; i < array.length as int; ++i) {
5972            let v = this.zeroIfInfinity(array[i])
5973            this.setUnsafe(insertPos + i, v as int)
5974        }
5975    }
5976
5977    /**
5978     * Returns a new array from a set of elements.
5979     *
5980     * @param items a set of elements to include in the new array object.
5981     *
5982     * @returns new Int32Array
5983     */
5984    public static of(...items: number[]): Int32Array {
5985        let res = new Int32Array(items.length as int)
5986        for (let i: int = 0; i < items.length; i++) {
5987            res.setUnsafe(i, res.zeroIfInfinity(items[i]) as int)
5988        }
5989        return res
5990    }
5991
5992    /**
5993     * Returns a new array from a set of elements.
5994     *
5995     * @param items a set of elements to include in the new array object.
5996     *
5997     * @returns new Int32Array
5998     */
5999    public static of(...items: int[]): Int32Array {
6000        let res = new Int32Array(items.length as int)
6001        for (let i: int = 0; i < items.length; i++) {
6002            res.setUnsafe(i, items[i])
6003        }
6004        return res
6005    }
6006
6007    /**
6008     * Returns a new array from a set of elements.
6009     *
6010     * @param items a set of elements to include in the new array object.
6011     *
6012     * @returns new Int32Array
6013     */
6014    public static of(): Int32Array {
6015        return new Int32Array(0 as int)
6016    }
6017
6018    /**
6019     * Creates an array from an array-like or iterable object.
6020     *
6021     * @param arrayLike An array-like or iterable object to convert to an array.
6022     *
6023     * @returns new Int32Array
6024     */
6025    public static from(arrayLike: ArrayLike<number>): Int32Array {
6026        return Int32Array.from<number>(arrayLike, (x: number, k: number): number => x)
6027    }
6028
6029    /**
6030     * Creates an array from an array-like or iterable object.
6031     *
6032     * @param arrayLike An array-like or iterable object to convert to an array.
6033     *
6034     * @param mapfn A mapping function to call on every element of the array.
6035     *
6036     * @returns new Int32Array
6037     */
6038    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Int32Array {
6039        if (mapfn == undefined) {
6040            mapfn = (v: number, k: number): number => { return v }
6041        }
6042        // Calc length of items inside arrayLike, save length into i variable
6043        let i: long = 0
6044        let iter = arrayLike.$_iterator()
6045        while (true) {
6046            const v = iter.next()
6047            if (v.done) {
6048                break
6049            }
6050            i++
6051        }
6052
6053        let res = new Int32Array(i as int)
6054        i = 0
6055        iter = arrayLike.$_iterator()
6056        while (true) {
6057            const v = iter.next()
6058            if (v.done) {
6059                return res
6060            }
6061            res.setUnsafe(i as int, res.zeroIfInfinity((mapfn)!(v.value as number, i as number)) as int)
6062            i++
6063        }
6064    }
6065
6066
6067    /**
6068     * Creates an array from an array-like or iterable object.
6069     *
6070     * @param arrayLike An array-like or iterable object to convert to an array.
6071     *
6072     * @param mapfn A mapping function to call on every element of the array.
6073     *
6074     * @returns new Int32Array
6075     */
6076    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): Int32Array {
6077        let res = new Int32Array(arrayLike.length)
6078        // 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
6079        const idx = new int[1]
6080        idx[0] = 0
6081        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
6082            res.setUnsafe(idx[0] as int, res.zeroIfInfinity(mapfn(x as T, idx[0] as number)) as int)
6083            idx[0] += 1
6084        })
6085        return res
6086    }
6087
6088    /**
6089     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6090     *
6091     * @param searchElement The element to search for
6092     *
6093     * @param fromIndex The position in this array at which to begin searching for searchElement
6094     *
6095     * @returns true if searchElement is in Int32Array, false otherwise
6096     */
6097    public includes(searchElement: number, fromIndex?: number): boolean {
6098        if (isNaN(searchElement)) {
6099            return false
6100        }
6101        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
6102    }
6103
6104    /**
6105     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6106     *
6107     * @param searchElement The element to search for
6108     *
6109     * @param fromIndex The position in this array at which to begin searching for searchElement
6110     *
6111     * @returns true if e is in Int32Array, false otherwise
6112     */
6113    public includes(searchElement: int, fromIndex: int): boolean {
6114        return this.indexOf(searchElement as int, fromIndex) != -1
6115    }
6116
6117    /**
6118     * Determines whether Int32Array includes a certain element, returning true or false as appropriate
6119     *
6120     * @param searchElement The element to search for
6121     *
6122     * @param fromIndex The position in this array at which to begin searching for searchElement
6123     *
6124     * @returns true if searchElement is in Int32Array, false otherwise
6125     */
6126    public includes(searchElement: int): boolean {
6127        return this.includes(searchElement, 0)
6128    }
6129
6130    /**
6131     * Returns the index of the first occurrence of a value in Int32Array.
6132     *
6133     * @param searchElement The value to locate in the array.
6134     *
6135     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6136     *  search starts at index 0.
6137     *
6138     * @returns index of element if it presents, -1 otherwise
6139     */
6140    public indexOf(searchElement: number, fromIndex?: number): number {
6141        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
6142    }
6143
6144    /**
6145     * Returns the index of the first occurrence of a value in Int32Array.
6146     *
6147     * @param searchElement The value to locate in the array.
6148     *
6149     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6150     *  search starts at index 0.
6151     *
6152     * @returns index of element if it presents, -1 otherwise
6153     */
6154    public indexOf(searchElement: number, fromIndex: int): number {
6155        if (isNaN(searchElement)) {
6156            return -1
6157        }
6158        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
6159        for (let i = fromIndex; i < this.lengthInt; i++) {
6160            if (this.getUnsafe(i) as number == searchElement) {
6161                return i
6162            }
6163        }
6164        return -1
6165    }
6166
6167    /**
6168     * Returns the index of the first occurrence of a value in Int32Array.
6169     *
6170     * @param searchElement The value to locate in the array.
6171     *
6172     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6173     *  search starts at index 0.
6174     *
6175     * @returns index of element if it presents, -1 otherwise
6176     */
6177    public indexOf(searchElement: int, fromIndex: int): number {
6178        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
6179        for (let i = fromIndex; i < this.lengthInt; i++) {
6180            if (this.getUnsafe(i) == searchElement) {
6181                return i
6182            }
6183        }
6184        return -1
6185    }
6186
6187    /**
6188     * Returns the index of the first occurrence of a value in Int32Array.
6189     *
6190     * @param searchElement The value to locate in the array.
6191     *
6192     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
6193     *  search starts at index 0.
6194     *
6195     * @returns index of element if it presents, -1 otherwise
6196     */
6197    public indexOf(searchElement: int): number {
6198        return this.indexOf(searchElement, 0)
6199    }
6200
6201    /**
6202     * Adds all the elements of an array separated by the specified separator string
6203     *
6204     * @param separator A string used to separate one element of an array from the next in the
6205     * resulting String. If omitted, the array elements are separated with a comma
6206     *
6207     * @returns joined representation
6208     */
6209    public join(separator?: String): string {
6210        if (separator == undefined) {
6211            return this.join(",")
6212        }
6213        let res: StringBuilder = new StringBuilder("")
6214        for (let i = 0; i < this.lengthInt - 1; ++i) {
6215            res.append(this.getUnsafe(i) as number)
6216            res.append(separator)
6217        }
6218        if (this.lengthInt > 0) {
6219            res.append(this.getUnsafe(this.lengthInt - 1) as number)
6220        }
6221        return res.toString()
6222    }
6223
6224    /**
6225     * Returns an list of keys in Int32Array
6226     *
6227     * @returns iterator over keys
6228     */
6229    public keys(): IterableIterator<number> {
6230        return new Int32ArrayIteratorKeys(this)
6231    }
6232
6233    /**
6234     * Returns the index of the last occurrence of a value in Int32Array.
6235     *
6236     * @param searchElement The value to locate in the array.
6237     *
6238     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6239     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6240     *
6241     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6242     */
6243    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
6244        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
6245    }
6246
6247    /**
6248     * Returns the index of the last occurrence of a value in Int32Array.
6249     *
6250     * @param searchElement The value to locate in the array.
6251     *
6252     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6253     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6254     *
6255     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6256     */
6257    public lastIndexOf(searchElement: number): number {
6258        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6259    }
6260
6261    /**
6262     * Returns the index of the last occurrence of a value in Int32Array.
6263     *
6264     * @param searchElement The value to locate in the array.
6265     *
6266     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6267     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6268     *
6269     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6270     */
6271    public lastIndexOf(searchElement: number, fromIndex: int): number {
6272        if (isNaN(searchElement)) {
6273            return -1
6274        }
6275        if (this.lengthInt == 0) {
6276            return -1
6277        }
6278        let k: int = this.lengthInt + fromIndex
6279        if (fromIndex >= 0) {
6280            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
6281        }
6282        while (k >= 0) {
6283            if (this.getUnsafe(k) as number == searchElement) {
6284                return k
6285            }
6286            k--
6287        }
6288        return -1
6289    }
6290
6291    /**
6292     * Returns the index of the last occurrence of a value in Int32Array.
6293     *
6294     * @param searchElement The value to locate in the array.
6295     *
6296     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6297     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6298     *
6299     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6300     */
6301    public lastIndexOf(searchElement: int, fromIndex: int): number {
6302        if (this.lengthInt == 0) {
6303            return -1
6304        }
6305        let k: int = this.lengthInt + fromIndex
6306        if (fromIndex >= 0) {
6307            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
6308        }
6309        while (k >= 0) {
6310            if (this.getUnsafe(k) == searchElement) {
6311                return k
6312            }
6313            k--
6314        }
6315        return -1
6316    }
6317
6318    /**
6319     * Returns the index of the last occurrence of a value in Int32Array.
6320     *
6321     * @param searchElement The value to locate in the array.
6322     *
6323     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
6324     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
6325     *
6326     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
6327     */
6328    public lastIndexOf(searchElement: int): number {
6329        return this.lastIndexOf(searchElement, this.lengthInt - 1)
6330    }
6331
6332    /**
6333    * Creates a new Int32Array using initializer
6334    *
6335    * @param data initializer
6336    *
6337    * @returns a new Int32Array from data
6338    */
6339    public of(data: Object[]): Int32Array {
6340        throw new Error("Int32Array.of: not implemented")
6341    }
6342
6343    /**
6344     * Creates a new Int32Array using reversed data from the current one
6345     *
6346     * @returns a new Int32Array using reversed data from the current one
6347     */
6348    public reverse(): Int32Array {
6349        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
6350            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
6351            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
6352            this.setUnsafe(i, tmp)
6353        }
6354        return this
6355    }
6356
6357    /**
6358     * Creates a slice of current Int32Array using range [begin, end)
6359     *
6360     * @param begin start index to be taken into slice
6361     *
6362     * @param end last index to be taken into slice
6363     *
6364     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6365     *
6366     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6367     */
6368    public slice(begin?: number, end?: number): Int32Array {
6369        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6370    }
6371
6372    /**
6373     * Creates a slice of current Int32Array using range [begin, end)
6374     *
6375     * @param begin start index to be taken into slice
6376     *
6377     * @param end last index to be taken into slice
6378     *
6379     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6380     *
6381     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6382     */
6383    public slice(begin: number, end: number): Int32Array {
6384        return this.slice(begin as int, end as int)
6385    }
6386
6387    /**
6388     * Creates a slice of current Int32Array using range [begin, end)
6389     *
6390     * @param begin start index to be taken into slice
6391     *
6392     * @param end last index to be taken into slice
6393     *
6394     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6395     *
6396     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6397     */
6398    public slice(begin: number, end: int): Int32Array {
6399        return this.slice(begin as int, end as int)
6400    }
6401
6402    /**
6403     * Creates a slice of current Int32Array using range [begin, end)
6404     *
6405     * @param begin start index to be taken into slice
6406     *
6407     * @param end last index to be taken into slice
6408     *
6409     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6410     *
6411     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6412     */
6413    public slice(begin: int, end: number): Int32Array {
6414        return this.slice(begin as int, end as int)
6415    }
6416
6417    /**
6418     * Creates a slice of current Int32Array using range [begin, end)
6419     *
6420     * @param begin start index to be taken into slice
6421     *
6422     * @param end last index to be taken into slice
6423     *
6424     * @returns a new Int32Array with elements of current Int32Array[begin;end) where end index is excluded
6425     *
6426     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
6427     */
6428    public slice(begin: int, end: int): Int32Array {
6429        const len: int = this.lengthInt
6430        const relStart = normalizeIndex(begin, len)
6431        const relEnd = normalizeIndex(end, len)
6432        let count = relEnd - relStart
6433        if (count < 0) {
6434            count = 0
6435        }
6436        if (this.buffer instanceof ArrayBuffer) {
6437            let buf = (this.buffer as ArrayBuffer).slice(relStart * Int32Array.BYTES_PER_ELEMENT as int, relEnd * Int32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
6438            return new Int32Array(buf)
6439        } else if (this.buffer instanceof SharedArrayBuffer) {
6440            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Int32Array.BYTES_PER_ELEMENT as int, relEnd * Int32Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
6441            return new Int32Array(buf)
6442        } else {
6443            throw new Error("unexpected type of buffer")
6444        }
6445    }
6446
6447    /**
6448     * Creates a slice of current Int32Array using range [begin, this.length).
6449     *
6450     * @param begin start index to be taken into slice
6451     *
6452     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
6453     */
6454    public slice(begin: number): Int32Array {
6455        return this.slice(begin as int)
6456    }
6457
6458    /**
6459     * Creates a slice of current Int32Array using range [begin, this.length).
6460     *
6461     * @param begin start index to be taken into slice
6462     *
6463     * @returns a new Int32Array with elements of current Int32Array[begin, this.length)
6464     */
6465    public slice(begin: int): Int32Array {
6466        return this.slice(begin, this.lengthInt)
6467    }
6468
6469    /**
6470     * Creates a Int32Array with the same underlying ArrayBufferLike
6471     *
6472     * @param begin start index, inclusive
6473     *
6474     * @param end last index, exclusive
6475     *
6476     * @returns new Int32Array with the same underlying ArrayBufferLike
6477     */
6478    public subarray(begin?: number, end?: number): Int32Array {
6479        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
6480    }
6481
6482    /**
6483     * Creates a Int32Array with the same underlying ArrayBufferLike
6484     *
6485     * @param begin start index, inclusive
6486     *
6487     * @param end last index, exclusive
6488     *
6489     * @returns new Int32Array with the same underlying ArrayBufferLike
6490     */
6491    public subarray(begin: number, end: number): Int32Array {
6492        return this.subarray(begin as int, end as int)
6493    }
6494
6495    /**
6496     * Creates a Int32Array with the same underlying ArrayBufferLike
6497     *
6498     * @param begin start index, inclusive
6499     *
6500     * @param end last index, exclusive
6501     *
6502     * @returns new Int32Array with the same underlying ArrayBufferLike
6503     */
6504    public subarray(begin: number, end: int): Int32Array {
6505        return this.subarray(begin as int, end as int)
6506    }
6507
6508    /**
6509     * Creates a Int32Array with the same underlying ArrayBufferLike
6510     *
6511     * @param begin start index, inclusive
6512     *
6513     * @param end last index, exclusive
6514     *
6515     * @returns new Int32Array with the same underlying ArrayBufferLike
6516     */
6517    public subarray(begin: int, end: number): Int32Array {
6518        return this.subarray(begin as int, end as int)
6519    }
6520
6521    /**
6522     * Creates a Int32Array with the same underlying ArrayBufferLike
6523     *
6524     * @param begin start index, inclusive
6525     *
6526     * @param end last index, exclusive
6527     *
6528     * @returns new Int32Array with the same underlying ArrayBufferLike
6529     */
6530    public subarray(begin: int, end: int): Int32Array {
6531        const len: int = this.lengthInt
6532        const relStart = normalizeIndex(begin, len)
6533        const relEnd = normalizeIndex(end, len)
6534        let count = relEnd - relStart
6535        if (count < 0) {
6536            count = 0
6537        }
6538        return new Int32Array(this.buffer, relStart * Int32Array.BYTES_PER_ELEMENT as int, count)
6539    }
6540
6541    /**
6542     * Creates a Int32Array with the same ArrayBufferLike
6543     *
6544     * @param begin start index, inclusive
6545     *
6546     * @returns new Int32Array with the same ArrayBufferLike
6547     */
6548    public subarray(begin: number): Int32Array {
6549        return this.subarray(begin as int, this.lengthInt)
6550    }
6551
6552    /**
6553     * Creates a Int32Array with the same ArrayBufferLike
6554     *
6555     * @param begin start index, inclusive
6556     *
6557     * @returns new Int32Array with the same ArrayBufferLike
6558     */
6559    public subarray(begin: int): Int32Array {
6560        return this.subarray(begin as int, this.lengthInt)
6561    }
6562
6563    /**
6564     * Converts Int32Array to a string with respect to locale
6565     *
6566     * @param locales
6567     *
6568     * @param options
6569     *
6570     * @returns string representation
6571     */
6572    public toLocaleString(locales: Object, options: Object): string {
6573        throw new Error("Int32Array.toLocaleString: not implemented")
6574    }
6575
6576    /**
6577     * Converts Int32Array to a string with respect to locale
6578     *
6579     * @param locales
6580     *
6581     * @returns string representation
6582     */
6583    public toLocaleString(locales: Object): string {
6584        return this.toLocaleString(new Object(), new Object())
6585    }
6586
6587    /**
6588     * Converts Int32Array to a string with respect to locale
6589     *
6590     * @returns string representation
6591     */
6592    public toLocaleString(): string {
6593        let res: StringBuilder = new StringBuilder("")
6594        for (let i = 0; i < this.lengthInt - 1; ++i) {
6595            res.append((this.getUnsafe(i) as Number).toLocaleString())
6596            res.append(",")
6597        }
6598        if (this.lengthInt > 0) {
6599            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
6600        }
6601        return res.toString()
6602    }
6603
6604    /**
6605     * Creates a reversed copy
6606     *
6607     * @returns a reversed copy
6608     */
6609    public toReversed(): Int32Array {
6610        return new Int32Array(this).reverse()
6611    }
6612
6613    /**
6614     * Creates a sorted copy
6615     *
6616     * @returns a sorted copy
6617     */
6618    public toSorted(): Int32Array {
6619        return new Int32Array(this).sort()
6620    }
6621
6622    /**
6623     * Returns a string representation of the Int32Array
6624     *
6625     * @returns a string representation of the Int32Array
6626     */
6627    public override toString(): string {
6628        return this.join(",")
6629    }
6630
6631    /**
6632     * Returns array values iterator
6633     *
6634     * @returns an iterator
6635     */
6636    public values(): IterableIterator<Number> {
6637        return new Int32ArrayIterator(this)
6638    }
6639
6640    /**
6641     * Iteratorable interface implementation
6642     *
6643     * @returns iterator over all elements
6644     */
6645    public override $_iterator(): IterableIterator<Number> {
6646        return this.values()
6647    }
6648
6649    /**
6650     * Creates a copy with replaced value on index
6651     *
6652     * @param index
6653     *
6654     * @param value
6655     *
6656     * @returns an Int32Array with replaced value on index
6657     */
6658    public with(index: number, value: number): Int32Array {
6659        return this.with(index as int, value as int)
6660    }
6661
6662    /**
6663     * Creates a copy with replaced value on index
6664     *
6665     * @param index
6666     *
6667     * @param value
6668     *
6669     * @returns an Int32Array with replaced value on index
6670     */
6671    public with(index: int, value: int): Int32Array {
6672        let res = new Int32Array(this)
6673        res.set(index, value)
6674        return res
6675    }
6676
6677    /// === with element lambda functions ===
6678    /**
6679     * Determines whether the specified callback function returns true for all elements of an array.
6680     *
6681     * @param predicate A function that accepts one argument.
6682     * The every method calls the predicate function for each element in the array until the predicate returns a false,
6683     * or until the end of the array.
6684     *
6685     * @returns true unless predicate function returns a false for an array element,
6686     * in which case false is immediately returned.
6687     */
6688    public every(predicate: (element: number) => boolean): boolean {
6689        return this.every((element: number, index: number, array: Int32Array): boolean => predicate(element))
6690    }
6691
6692    /**
6693     * creates a new Int32Array from current Int32Array based on a condition fn
6694     *
6695     * @param fn the condition to apply for each element
6696     *
6697     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
6698     */
6699    public filter(fn: (val: number) => boolean): Int32Array {
6700        let newF: (val: number, index: number, array: Int32Array) => boolean =
6701            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6702        return this.filter(newF)
6703    }
6704
6705    /**
6706     * Returns the value of the first element in the array where predicate is true, and undefined
6707     * otherwise
6708     *
6709     * @param predicate find calls predicate once for each element of the array, in ascending
6710     * order, until it finds one where predicate returns true. If such an element is found, find
6711     * immediately returns that element value. Otherwise, find returns undefined
6712     *
6713     * @returns number | undefined
6714     */
6715    public find(predicate: () => boolean): number | undefined {
6716        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate())
6717    }
6718
6719    /**
6720     * Returns the value of the first element in the array where predicate is true, and undefined
6721     * otherwise
6722     *
6723     * @param predicate find calls predicate once for each element of the array, in ascending
6724     * order, until it finds one where predicate returns true. If such an element is found, find
6725     * immediately returns that element value. Otherwise, find returns undefined
6726     *
6727     * @returns number | undefined
6728     */
6729    public find(predicate: (value: number) => boolean): number | undefined {
6730        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate(value))
6731    }
6732
6733    /**
6734     * Returns the index of the first element in the array where predicate is true, and -1
6735     * otherwise
6736     *
6737     * @param predicate find calls predicate once for each element of the array, in ascending
6738     * order, until it finds one where predicate returns true. If such an element is found,
6739     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
6740     *
6741     * @returns number
6742     */
6743    public findIndex(predicate: (value: number) => boolean): number {
6744        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate(value)) as number
6745    }
6746
6747    /**
6748     * Finds the last element in the Int32Array that satisfies the condition
6749     *
6750     * @param fn condition
6751     *
6752     * @returns the last element that satisfies fn
6753     */
6754    public findLast(fn: (val: number) => boolean): number {
6755        let newF: (val: number, index: number, array: Int32Array) => boolean =
6756            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6757        return this.findLast(newF) as number
6758    }
6759
6760    /**
6761     * Finds an index of the last element in the Int32Array that satisfies the condition
6762     *
6763     * @param fn condition
6764     *
6765     * @returns the index of the last element that satisfies fn, -1 otherwise
6766     */
6767    public findLastIndex(fn: (val: number) => boolean): number {
6768        let newF: (val: number, index: number, array: Int32Array) => boolean =
6769            (val: number, index: number, array: Int32Array): boolean => { return fn(val) }
6770        return this.findLastIndex(newF) as number
6771    }
6772
6773    /**
6774     * Performs the specified action for each element in Int32Array
6775     *
6776     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
6777     * callbackfn function one time for each element in the array.
6778     *
6779     * @returns None
6780     */
6781    public forEach(callbackfn: (value: number) => void): void {
6782        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn(value))
6783    }
6784
6785    /**
6786     * Creates a new Int32Array using fn(arr[i]) over all elements of current Int32Array
6787     *
6788     * @param fn a function to apply for each element of current Int32Array
6789     *
6790     * @returns a new Int32Array where for each element from current Int32Array fn was applied
6791     */
6792    public map(fn: (val: number) => number): Int32Array {
6793        let newF: (val: number, index: number) => number =
6794            (val: number, index: number): number => { return fn(val) }
6795        return this.map(newF)
6796    }
6797
6798    /**
6799     * Determines whether the specified callback function returns true for any element of an array.
6800     *
6801     * @param predicate A function that accepts one argument.
6802     * The some method calls the predicate function for each element in the array
6803     * until the predicate returns a true or until the end of the array.
6804     *
6805     * @returns false unless predicate function returns true for an array element,
6806     * in which case true is immediately returned.
6807     */
6808    public some(predicate: (element: number) => boolean): boolean {
6809        return this.some((element: number, index: number, array: Int32Array): boolean => predicate(element))
6810    }
6811
6812    // NOTE (kprokopenko): this may be not skipped
6813    /**
6814     * Sorts in-place
6815     *
6816     * @param compareFn comparator —  used to determine the order of the elements.
6817     * compareFn returns a negative value if first argument is less than second argument,
6818     * zero if they're equal and a positive value otherwise.
6819     * If omitted, the elements are sorted in ascending order.
6820     *
6821     * @returns sorted Int32Array
6822     */
6823    public sort(compareFn?: (a: number, b: number) => number): this {
6824        let arr: int[] = new int[this.lengthInt]
6825        for (let i = 0; i < this.lengthInt; ++i) {
6826            arr[i] = this.getUnsafe(i)
6827        }
6828        let cmp = (l: int, r: int): number => {
6829                return (l - r) as number
6830            }
6831        if (compareFn != undefined) {
6832            cmp = (l: int, r: int): number => {
6833                return compareFn!(l as number, r as number)
6834            }
6835        }
6836        sort(arr, cmp)
6837        for (let i = 0; i < this.lengthInt; ++i) {
6838            this.setUnsafe(i, arr[i])
6839        }
6840        return this
6841    }
6842
6843    /**
6844     * Sorts in-place
6845     *
6846     * @param compareFn comparator —  used to determine the order of the elements.
6847     * compareFn returns a negative value if first argument is less than second argument,
6848     * zero if they're equal and a positive value otherwise.
6849     *
6850     * @returns sorted Int32Array
6851     */
6852    public sort(compareFn: (a: number) => number): this {
6853        let cmp = (a: number, b: number) => { return compareFn(a)}
6854        this.sort(cmp)
6855        return this
6856    }
6857
6858    /**
6859     * Sorts in-place
6860     *
6861     * @param fn compareFn —  used to determine the order of the elements.
6862     * compareFn returns a negative value if first argument is less than second argument,
6863     * zero if they're equal and a positive value otherwise.
6864     *
6865     * @returns sorted Int32Array
6866     */
6867    public sort(compareFn: () => number): this {
6868        let cmp = (a: number, b: number) => { return compareFn()}
6869        this.sort(cmp)
6870        return this
6871    }
6872
6873    /**
6874     * Determines whether the specified callback function returns true for any element of an array.
6875     *
6876     * @param predicate A function that accepts three arguments.
6877     * The some method calls the predicate function for each element in the array
6878     * until the predicate returns a true or until the end of the array.
6879     *
6880     * @returns false unless predicate function returns true for an array element,
6881     * in which case true is immediately returned.
6882     */
6883    public some(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
6884        for (let i = 0; i < this.lengthInt; ++i) {
6885            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
6886                return true
6887            }
6888        }
6889        return false
6890    }
6891
6892    /**
6893     * Determines whether the specified callback function returns true for any element of an array.
6894     *
6895     * @param predicate A function that accepts two arguments.
6896     * The some method calls the predicate function for each element in the array
6897     * until the predicate returns a true or until the end of the array.
6898     *
6899     * @returns false unless predicate function returns true for an array element,
6900     * in which case true is immediately returned.
6901     */
6902    public some(predicate: (element: number, index: number) => boolean): boolean {
6903        return this.some((element: number, index: number, array: Int32Array): boolean => predicate(element, index as number))
6904    }
6905
6906    /**
6907     * Determines whether the specified callback function returns true for any element of an array.
6908     *
6909     * @param predicate A function that accepts no arguments.
6910     * The some method calls the predicate function for each element in the array
6911     * until the predicate returns a true or until the end of the array.
6912     *
6913     * @returns false unless predicate function returns true for an array element,
6914     * in which case true is immediately returned.
6915     */
6916    public some(predicate: () => boolean): boolean {
6917        return this.some((element: number, index: number, array: Int32Array): boolean => predicate())
6918    }
6919
6920    /**
6921     * Calls the specified callback function for all the elements in an array.
6922     * The return value of the callback function is the accumulated result,
6923     * and is provided as an argument in the next call to the callback function.
6924     *
6925     * @param callbackfn A function that accepts four arguments.
6926     * The reduce method calls the callbackfn function one time for each element in the array.
6927     *
6928     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
6929     * The first call to the callbackfn function provides this value as an argument.
6930     *
6931     * @returns The value that results from running the callback function to completion over the entire typed array.
6932     */
6933    public reduce<U = number>(
6934                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
6935                initialValue: U): U {
6936        let accumulatedValue = initialValue
6937        for (let i = 0; i < this.lengthInt; ++i) {
6938            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
6939        }
6940        return accumulatedValue
6941    }
6942
6943    /**
6944     * Calls the specified callback function for all the elements in an array.
6945     * The return value of the callback function is the accumulated result,
6946     * and is provided as an argument in the next call to the callback function.
6947     *
6948     * @param callbackfn A function that accepts three arguments.
6949     * The reduce method calls the callbackfn function one time for each element in the array.
6950     *
6951     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
6952     * The first call to the callbackfn function provides this value as an argument.
6953     *
6954     * @returns The value that results from running the callback function to completion over the entire typed array.
6955     */
6956    public reduce<U = number>(
6957                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
6958                initialValue: U): U {
6959        return this.reduce(
6960                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
6961                        callbackfn(prevVal, currVal, currIndex), initialValue)
6962    }
6963
6964    /**
6965     * Calls the specified callback function for all the elements in an array.
6966     * The return value of the callback function is the accumulated result,
6967     * and is provided as an argument in the next call to the callback function.
6968     *
6969     * @param callbackfn A function that accepts two arguments.
6970     * The reduce method calls the callbackfn function one time for each element in the array.
6971     *
6972     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
6973     * The first call to the callbackfn function provides this value as an argument.
6974     *
6975     * @returns The value that results from running the callback function to completion over the entire typed array.
6976     */
6977    public reduce<U = number>(
6978                callbackfn: (previousValue: U, currentValue: number) => U,
6979                initialValue: U): U {
6980        return this.reduce(
6981                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
6982                        callbackfn(prevVal, currVal), initialValue)
6983    }
6984
6985    /**
6986     * Calls the specified callback function for all the elements in an array.
6987     * The return value of the callback function is the accumulated result,
6988     * and is provided as an argument in the next call to the callback function.
6989     *
6990     * @param callbackfn A function that accepts one argument
6991     * The reduce method calls the callbackfn function one time for each element in the array.
6992     *
6993     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
6994     * The first call to the callbackfn function provides this value as an argument.
6995     *
6996     * @returns The value that results from running the callback function to completion over the entire typed array.
6997     */
6998    public reduce<U = number>(
6999                callbackfn: (previousValue: U) => U,
7000                initialValue: U): U {
7001        return this.reduce(
7002                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7003                        callbackfn(prevVal), initialValue)
7004    }
7005
7006    /**
7007     * Calls the specified callback function for all the elements in an array.
7008     * The return value of the callback function is the accumulated result,
7009     * and is provided as an argument in the next call to the callback function.
7010     *
7011     * @param callbackfn A function that accepts no arguments
7012     * The reduce method calls the callbackfn function one time for each element in the array.
7013     *
7014     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7015     * The first call to the callbackfn function provides this value as an argument.
7016     *
7017     * @returns The value that results from running the callback function to completion over the entire typed array.
7018     */
7019    public reduce<U = number>(
7020                callbackfn: () => U,
7021                initialValue: U): U {
7022        return this.reduce(
7023                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7024                        callbackfn(), initialValue)
7025    }
7026
7027    /**
7028     * Calls the specified callback function for all the elements in an array.
7029     * The return value of the callback function is the accumulated result,
7030     * and is provided as an argument in the next call to the callback function.
7031     *
7032     * @param callbackfn A function that accepts four arguments.
7033     * The reduce method calls the callbackfn function one time for each element in the array.
7034     * The first call to the callbackfn function provides array first element value as an argument
7035     *
7036     * @returns The value that results from running the callback function to completion over the entire typed array.
7037     * calling reduce method on an empty array without an initial value creates a TypeError
7038     */
7039    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
7040        if (this.lengthInt == 0) {
7041            throw new TypeError("Reduce of empty array with no initial value")
7042        }
7043
7044        let accumulatedValue = this.getUnsafe(0) as number
7045        for (let i = 1; i < this.lengthInt; ++i) {
7046            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7047        }
7048        return accumulatedValue
7049    }
7050
7051    /**
7052     * Calls the specified callback function for all the elements in an array.
7053     * The return value of the callback function is the accumulated result,
7054     * and is provided as an argument in the next call to the callback function.
7055     *
7056     * @param callbackfn A function that accepts three arguments.
7057     * The reduce method calls the callbackfn function one time for each element in the array.
7058     * The first call to the callbackfn function provides array first element value as an argument
7059     *
7060     * @returns The value that results from running the callback function to completion over the entire typed array.
7061     * calling reduce method on an empty array without an initial value creates a TypeError
7062     */
7063    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
7064        return this.reduce(
7065                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7066                        callbackfn(prevVal, currVal, currIndex))
7067    }
7068
7069    /**
7070     * Calls the specified callback function for all the elements in an array.
7071     * The return value of the callback function is the accumulated result,
7072     * and is provided as an argument in the next call to the callback function.
7073     *
7074     * @param callbackfn A function that accepts two arguments.
7075     * The reduce method calls the callbackfn function one time for each element in the array.
7076     * The first call to the callbackfn function provides array first element value as an argument
7077     *
7078     * @returns The value that results from running the callback function to completion over the entire typed array.
7079     * calling reduce method on an empty array without an initial value creates a TypeError
7080     */
7081    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
7082        return this.reduce(
7083                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7084                        callbackfn(prevVal, currVal))
7085    }
7086
7087    /**
7088     * Calls the specified callback function for all the elements in an array.
7089     * The return value of the callback function is the accumulated result,
7090     * and is provided as an argument in the next call to the callback function.
7091     *
7092     * @param callbackfn A function that accepts one argument.
7093     * The reduce method calls the callbackfn function one time for each element in the array.
7094     * The first call to the callbackfn function provides array first element value as an argument
7095     *
7096     * @returns The value that results from running the callback function to completion over the entire typed array.
7097     * calling reduce method on an empty array without an initial value creates a TypeError
7098     */
7099    public reduce(callbackfn: (previousValue: number) => number): number {
7100        return this.reduce(
7101                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7102                        callbackfn(prevVal))
7103    }
7104
7105    /**
7106     * Calls the specified callback function for all the elements in an array.
7107     * The return value of the callback function is the accumulated result,
7108     * and is provided as an argument in the next call to the callback function.
7109     *
7110     * @param callbackfn A function that accepts no arguments.
7111     * The reduce method calls the callbackfn function one time for each element in the array.
7112     * The first call to the callbackfn function provides array first element value as an argument
7113     *
7114     * @returns The value that results from running the callback function to completion over the entire typed array.
7115     * calling reduce method on an empty array without an initial value creates a TypeError
7116     */
7117    public reduce(callbackfn: () => number): number {
7118        return this.reduce(
7119                (prevVal: number, currVal: number, currIndex: number, array: Int32Array) =>
7120                        callbackfn())
7121    }
7122
7123
7124    /**
7125     * Calls the specified callback function for all the elements in an array, in descending order.
7126     * The return value of the callback function is the accumulated result,
7127     * and is provided as an argument in the next call to the callback function.
7128     *
7129     * @param callbackfn A function that accepts four arguments.
7130     * The reduceRight method calls the callbackfn function one time for each element in the array.
7131     *
7132     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7133     * The first call to the callbackfn function provides this value as an argument.
7134     *
7135     * @returns The value that results from running the callback function to completion over the entire typed array.
7136     */
7137    public reduceRight<U = number>(
7138                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U,
7139                initialValue: U): U {
7140        let accumulatedValue = initialValue
7141        for (let i = this.lengthInt - 1; i >= 0; --i) {
7142            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7143        }
7144        return accumulatedValue
7145    }
7146
7147    /**
7148     * Calls the specified callback function for all the elements in an array, in descending order.
7149     * The return value of the callback function is the accumulated result,
7150     * and is provided as an argument in the next call to the callback function.
7151     *
7152     * @param callbackfn A function that accepts three arguments.
7153     * The reduceRight method calls the callbackfn function one time for each element in the array.
7154     *
7155     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7156     * The first call to the callbackfn function provides this value as an argument.
7157     *
7158     * @returns The value that results from running the callback function to completion over the entire typed array.
7159     */
7160    public reduceRight<U = number>(
7161                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
7162                initialValue: U): U {
7163        return this.reduceRight(
7164                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7165                        callbackfn(prevVal, currVal, currIndex), initialValue)
7166    }
7167
7168    /**
7169     * Calls the specified callback function for all the elements in an array, in descending order.
7170     * The return value of the callback function is the accumulated result,
7171     * and is provided as an argument in the next call to the callback function.
7172     *
7173     * @param callbackfn A function that accepts two arguments.
7174     * The reduceRight method calls the callbackfn function one time for each element in the array.
7175     *
7176     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7177     * The first call to the callbackfn function provides this value as an argument.
7178     *
7179     * @returns The value that results from running the callback function to completion over the entire typed array.
7180     */
7181    public reduceRight<U = number>(
7182                callbackfn: (previousValue: U, currentValue: number) => U,
7183                initialValue: U): U {
7184        return this.reduceRight(
7185                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7186                        callbackfn(prevVal, currVal), initialValue)
7187    }
7188
7189    /**
7190     * Calls the specified callback function for all the elements in an array, in descending order.
7191     * The return value of the callback function is the accumulated result,
7192     * and is provided as an argument in the next call to the callback function.
7193     *
7194     * @param callbackfn A function that accepts one argument.
7195     * The reduceRight method calls the callbackfn function one time for each element in the array.
7196     *
7197     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7198     * The first call to the callbackfn function provides this value as an argument.
7199     *
7200     * @returns The value that results from running the callback function to completion over the entire typed array.
7201     */
7202    public reduceRight<U = number>(
7203                callbackfn: (previousValue: U) => U,
7204                initialValue: U): U {
7205        return this.reduceRight(
7206                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7207                        callbackfn(prevVal), initialValue)
7208    }
7209
7210    /**
7211     * Calls the specified callback function for all the elements in an array, in descending order.
7212     * The return value of the callback function is the accumulated result,
7213     * and is provided as an argument in the next call to the callback function.
7214     *
7215     * @param callbackfn A function that accepts no arguments.
7216     * The reduceRight method calls the callbackfn function one time for each element in the array.
7217     *
7218     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
7219     * The first call to the callbackfn function provides this value as an argument.
7220     *
7221     * @returns The value that results from running the callback function to completion over the entire typed array.
7222     */
7223    public reduceRight<U = number>(
7224                callbackfn: () => U,
7225                initialValue: U): U {
7226        return this.reduceRight(
7227                (prevVal: U, currVal: number, currIndex: number, array: Int32Array) =>
7228                        callbackfn(), initialValue)
7229    }
7230
7231    /**
7232     * Calls the specified callback function for all the elements in an array, in descending order.
7233     * The return value of the callback function is the accumulated result,
7234     * and is provided as an argument in the next call to the callback function.
7235     *
7236     * @param callbackfn A function that accepts four arguments.
7237     * The reduceRight method calls the callbackfn function one time for each element in the array.
7238     * The first call to the callbackfn function provides array last element value as an argument
7239     *
7240     * @returns The value that results from running the callback function to completion over the entire typed array.
7241     * calling reduceRight method on an empty array without an initial value creates a TypeError
7242     */
7243    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number {
7244        if (this.lengthInt == 0) {
7245            throw new TypeError("Reduce of empty array with no initial value")
7246        }
7247
7248        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
7249        for (let i = this.lengthInt - 2; i >= 0; --i) {
7250            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
7251        }
7252        return accumulatedValue
7253    }
7254
7255    /**
7256     * Calls the specified callback function for all the elements in an array, in descending order.
7257     * The return value of the callback function is the accumulated result,
7258     * and is provided as an argument in the next call to the callback function.
7259     *
7260     * @param callbackfn A function that accepts three arguments.
7261     * The reduceRight method calls the callbackfn function one time for each element in the array.
7262     * The first call to the callbackfn function provides array last element value as an argument
7263     *
7264     * @returns The value that results from running the callback function to completion over the entire typed array.
7265     * calling reduceRight method on an empty array without an initial value creates a TypeError
7266     */
7267    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
7268        return this.reduceRight(
7269                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7270                        callbackfn(prevValue, currValue, currIndex))
7271    }
7272
7273    /**
7274     * Calls the specified callback function for all the elements in an array, in descending order.
7275     * The return value of the callback function is the accumulated result,
7276     * and is provided as an argument in the next call to the callback function.
7277     *
7278     * @param callbackfn A function that accepts two arguments.
7279     * The reduceRight method calls the callbackfn function one time for each element in the array.
7280     * The first call to the callbackfn function provides array last element value as an argument
7281     *
7282     * @returns The value that results from running the callback function to completion over the entire typed array.
7283     * calling reduceRight method on an empty array without an initial value creates a TypeError
7284     */
7285    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
7286        return this.reduceRight(
7287                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7288                        callbackfn(prevValue, currValue))
7289    }
7290
7291    /**
7292     * Calls the specified callback function for all the elements in an array, in descending order.
7293     * The return value of the callback function is the accumulated result,
7294     * and is provided as an argument in the next call to the callback function.
7295     *
7296     * @param callbackfn A function that accepts one argument.
7297     * The reduceRight method calls the callbackfn function one time for each element in the array.
7298     * The first call to the callbackfn function provides array last element value as an argument
7299     *
7300     * @returns The value that results from running the callback function to completion over the entire typed array.
7301     * calling reduceRight method on an empty array without an initial value creates a TypeError
7302     */
7303    public reduceRight(callbackfn: (previousValue: number) => number): number {
7304        return this.reduceRight(
7305                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7306                        callbackfn(prevValue))
7307    }
7308
7309    /**
7310     * Calls the specified callback function for all the elements in an array, in descending order.
7311     * The return value of the callback function is the accumulated result,
7312     * and is provided as an argument in the next call to the callback function.
7313     *
7314     * @param callbackfn A function that accepts no arguments.
7315     * The reduceRight method calls the callbackfn function one time for each element in the array.
7316     * The first call to the callbackfn function provides array last element value as an argument
7317     *
7318     * @returns The value that results from running the callback function to completion over the entire typed array.
7319     * calling reduceRight method on an empty array without an initial value creates a TypeError
7320     */
7321    public reduceRight(callbackfn: () => number): number {
7322        return this.reduceRight(
7323                (prevValue: number, currValue: number, currIndex: number, array: Int32Array) =>
7324                        callbackfn())
7325    }
7326
7327   /**
7328    * Creates a new Int32Array using fn(arr[i]) over all elements of current Int32Array.
7329    *
7330    * @param fn a function to apply for each element of current Int32Array
7331    *
7332    * @returns a new Int32Array where for each element from current Int32Array fn was applied
7333    */
7334    public map(fn: (val: number, index: number) => number): Int32Array {
7335        let resBuf = new ArrayBuffer(this.lengthInt * Int32Array.BYTES_PER_ELEMENT as int)
7336        let res = new Int32Array(resBuf, 0, resBuf.getByteLength() / Int32Array.BYTES_PER_ELEMENT as int)
7337        for (let i = 0; i < this.lengthInt; ++i) {
7338            res.set(i, fn(this.getUnsafe(i) as number, i as number) as int)
7339        }
7340        return res
7341    }
7342
7343    /**
7344     * Determines whether the specified callback function returns true for all elements of an array.
7345     *
7346     * @param predicate A function that accepts three arguments.
7347     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7348     * or until the end of the array.
7349     *
7350     * @returns true unless predicate function returns a false for an array element,
7351     * in which case false is immediately returned.
7352     */
7353    public every(predicate: (element: number, index: number, array: Int32Array) => boolean): boolean {
7354        for (let i = 0; i < this.lengthInt; ++i) {
7355            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
7356                return false
7357            }
7358        }
7359        return true
7360    }
7361
7362    /**
7363     * Determines whether the specified callback function returns true for all elements of an array.
7364     *
7365     * @param predicate A function that accepts two arguments.
7366     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7367     * or until the end of the array.
7368     *
7369     * @returns true unless predicate function returns a false for an array element,
7370     * in which case false is immediately returned.
7371     */
7372    public every(predicate: (element: number, index: number) => boolean): boolean {
7373        return this.every((element: number, index: number, array: Int32Array): boolean => predicate(element, index))
7374    }
7375
7376    /**
7377     * Determines whether the specified callback function returns true for all elements of an array.
7378     *
7379     * @param predicate A function that accepts no arguments.
7380     * The every method calls the predicate function for each element in the array until the predicate returns a false,
7381     * or until the end of the array.
7382     *
7383     * @returns true unless predicate function returns a false for an array element,
7384     * in which case false is immediately returned.
7385     */
7386    public every(predicate: () => boolean): boolean {
7387        return this.every((element: number, index: number, array: Int32Array): boolean => predicate())
7388    }
7389
7390    /**
7391     * Creates a new Int32Array from current Int32Array based on a condition fn.
7392     *
7393     * @param fn the condition to apply for each element
7394     *
7395     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7396     */
7397    public filter(fn: (val: number, index: number, array: Int32Array) => boolean): Int32Array {
7398        let markers = new boolean[this.lengthInt]
7399        let resLen = 0
7400        for (let i = 0; i < this.lengthInt; ++i) {
7401            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
7402            if (markers[i]) {
7403                ++resLen
7404            }
7405        }
7406        let resBuf = new ArrayBuffer(resLen * Int32Array.BYTES_PER_ELEMENT as int)
7407        let res = new Int32Array(resBuf, 0)
7408        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
7409            if (markers[i]) {
7410                res.set(j, this.getUnsafe(i))
7411                ++j
7412            }
7413        }
7414        return res
7415    }
7416
7417    /**
7418     * creates a new Int32Array from current Int32Array based on a condition fn
7419     *
7420     * @param fn the condition to apply for each element
7421     *
7422     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7423     */
7424    public filter(fn: (val: number, index: number) => boolean): Int32Array {
7425        let newF: (val: number, index: number, array: Int32Array) => boolean =
7426            (val: number, index: number, array: Int32Array): boolean => { return fn(val, index as number) }
7427        return this.filter(newF)
7428    }
7429
7430    /**
7431     * creates a new Int32Array from current Int32Array based on a condition fn
7432     *
7433     * @param fn the condition to apply for each element
7434     *
7435     * @returns a new Int32Array with elements from current Int32Array that satisfy condition fn
7436     */
7437    public filter(fn: () => boolean): Int32Array {
7438        let newF: (val: number, index: number, array: Int32Array) => boolean =
7439            (val: number, index: number, array: Int32Array): boolean => { return fn() }
7440        return this.filter(newF)
7441    }
7442
7443    /**
7444     * Returns the value of the first element in the array where predicate is true, and undefined
7445     * otherwise
7446     *
7447     * @param predicate find calls predicate once for each element of the array, in ascending
7448     * order, until it finds one where predicate returns true. If such an element is found, find
7449     * immediately returns that element value. Otherwise, find returns undefined
7450     *
7451     * @returns number | undefined
7452     */
7453    public find(predicate: (value: number, index: number, obj: Int32Array) => boolean): number | undefined {
7454        for (let i = 0; i < this.lengthInt; ++i) {
7455            let val = this.getUnsafe(i)
7456            if (predicate(val as number, i as number, this)) {
7457                return val as number
7458            }
7459        }
7460        return undefined
7461    }
7462
7463    /**
7464     * Returns the value of the first element in the array where predicate is true, and undefined
7465     * otherwise
7466     *
7467     * @param predicate find calls predicate once for each element of the array, in ascending
7468     * order, until it finds one where predicate returns true. If such an element is found, find
7469     * immediately returns that element value. Otherwise, find returns undefined
7470     *
7471     * @returns number | undefined
7472     */
7473    public find(predicate: (value: number, index: number) => boolean): number | undefined {
7474        return this.find((value: number, index: number, obj: Int32Array): boolean => predicate(value, index))
7475    }
7476
7477    /**
7478     * Returns the index of the first element in the array where predicate is true, and -1
7479     * otherwise
7480     *
7481     * @param predicate find calls predicate once for each element of the array, in ascending
7482     * order, until it finds one where predicate returns true. If such an element is found,
7483     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7484     *
7485     * @returns number
7486     */
7487    public findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean): number {
7488        for (let i = 0; i < this.lengthInt; ++i) {
7489            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
7490                return i as number
7491            }
7492        }
7493        return -1 as number
7494    }
7495
7496    /**
7497     * Returns the index of the first element in the array where predicate is true, and -1
7498     * otherwise
7499     *
7500     * @param predicate find calls predicate once for each element of the array, in ascending
7501     * order, until it finds one where predicate returns true. If such an element is found,
7502     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7503     *
7504     * @returns number
7505     */
7506    public findIndex(predicate: (value: number, index: number) => boolean): number {
7507        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate(value, index as number)) as number
7508    }
7509
7510    /**
7511     * Returns the index of the first element in the array where predicate is true, and -1
7512     * otherwise
7513     *
7514     * @param predicate find calls predicate once for each element of the array, in ascending
7515     * order, until it finds one where predicate returns true. If such an element is found,
7516     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
7517     *
7518     * @returns number
7519     */
7520    public findIndex(predicate: () => boolean): number {
7521        return this.findIndex((value: number, index: number, obj: Int32Array): boolean => predicate()) as number
7522    }
7523
7524    /**
7525     * Finds the last element in the Int32Array that satisfies the condition
7526     *
7527     * @param fn condition
7528     *
7529     * @returns the last element that satisfies fn
7530     */
7531    public findLast(fn: (val: number, index: number, array: Int32Array) => boolean): int {
7532        for (let i = this.lengthInt - 1; i >= 0; --i) {
7533            let val = this.getUnsafe(i)
7534            if (fn(val as number, i as number, this)) {
7535                return val
7536            }
7537        }
7538        throw new Error("Int32Array.findLast: not implemented if an element was not found")
7539    }
7540
7541    /**
7542     * Finds the last element in the Int32Array that satisfies the condition
7543     *
7544     * @param fn condition
7545     *
7546     * @returns the last element that satisfies fn
7547     */
7548    public findLast(fn: (val: number, index: number) => boolean): int {
7549        let newF: (val: number, index: number, array: Int32Array) => boolean =
7550            (val: number, index: number, array: Int32Array): boolean => { return fn(val as number, index as number) }
7551        return this.findLast(newF)
7552    }
7553
7554    /**
7555     * Finds an index of the last element in the Int32Array that satisfies the condition
7556     *
7557     * @param fn condition
7558     *
7559     * @returns the index of the last element that satisfies fn, -1 otherwise
7560     */
7561    public findLastIndex(fn: (val: number, index: number, array: Int32Array) => boolean): number {
7562        for (let i = this.lengthInt - 1; i >= 0; --i) {
7563            let val = this.getUnsafe(i)
7564            if (fn(val as number, i as number, this)) {
7565                return i
7566            }
7567        }
7568        return -1 as number
7569    }
7570
7571    /**
7572     * Finds an index of the last element in the Int32Array that satisfies the condition
7573     *
7574     * @param fn condition
7575     *
7576     * @returns the index of the last element that satisfies fn, -1 otherwise
7577     */
7578    public findLastIndex(fn: (val: number, index: number) => boolean): number {
7579        let newF: (val: number, index: number, array: Int32Array) => boolean =
7580            (val: number, index: number, array: Int32Array): boolean => { return fn(val, index as number) }
7581        return this.findLastIndex(newF) as number
7582    }
7583
7584    /**
7585     * Performs the specified action for each element in Int32Array
7586     *
7587     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7588     * callbackfn function one time for each element in the array.
7589     *
7590     * @returns None
7591     */
7592    public forEach(callbackfn: (value: number, index: number, array: Int32Array) => void): void {
7593        for (let i = 0; i < this.lengthInt; ++i) {
7594            callbackfn(this.getUnsafe(i) as number, i as number, this)
7595        }
7596    }
7597
7598    /**
7599     * Performs the specified action for each element in Int32Array
7600     *
7601     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7602     * callbackfn function one time for each element in the array.
7603     *
7604     * @returns None
7605     */
7606    public forEach(callbackfn: (value: number, index: number) => void): void {
7607        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn(value, index))
7608    }
7609
7610    /**
7611     * Performs the specified action for each element in Int32Array
7612     *
7613     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
7614     * callbackfn function one time for each element in the array.
7615     *
7616     * @returns None
7617     */
7618    public forEach(callbackfn: () => void): void {
7619        this.forEach((value: number, index: number, array: Int32Array): void => callbackfn())
7620    }
7621
7622    /**
7623     * Returns the object itself
7624     *
7625     * @returns Int32Array
7626     */
7627    public valueOf(): Int32Array {
7628        return this
7629    }
7630
7631    internal getUnsafe(index: int): int {
7632        let byteIndex = index * Int32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
7633        let res : int = 0
7634        let byteVal : int
7635        if (IS_LITTLE_ENDIAN) {
7636            if (this.buffer instanceof ArrayBuffer) {
7637                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7638                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
7639                    byteVal &= 0xff
7640                    res = (res | byteVal << (8 * i)) as int
7641                }
7642            } else if (this.buffer instanceof SharedArrayBuffer) {
7643                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7644                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
7645                    byteVal &= 0xff
7646                    res = (res | byteVal << (8 * i)) as int
7647                }
7648            } else {
7649                throw new Error("unexpected type of ArrayBufferLike")
7650            }
7651            return res
7652        } else {
7653            if (this.buffer instanceof ArrayBuffer) {
7654                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7655                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 3 - i)
7656                    byteVal &= 0xff
7657                    res = (res | byteVal << (8 * i)) as int
7658                }
7659            } else if (this.buffer instanceof SharedArrayBuffer) {
7660                for (let i: int = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7661                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 3 - i)
7662                    byteVal &= 0xff
7663                    res = (res | byteVal << (8 * i)) as int
7664                }
7665            } else {
7666                throw new Error("unexpected type of ArrayBufferLike")
7667            }
7668            return res
7669        }
7670    }
7671
7672    internal setUnsafe(insertPos: int, val: int): void {
7673        let startByte = insertPos * Int32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
7674        let bits = val
7675        if (IS_LITTLE_ENDIAN) {
7676            if (this.buffer instanceof ArrayBuffer) {
7677                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7678                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7679                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
7680                }
7681            } else if (this.buffer instanceof SharedArrayBuffer) {
7682                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; ++i) {
7683                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7684                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
7685                }
7686            } else {
7687                throw new Error("unexpected type of ArrayBufferLike")
7688            }
7689        } else {
7690            if (this.buffer instanceof ArrayBuffer) {
7691                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; i++) {
7692                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7693                    (this.buffer as ArrayBuffer).set(startByte + 3 - i, byteVal)
7694                }
7695            } else if (this.buffer instanceof SharedArrayBuffer) {
7696                for (let i = 0; i < Int32Array.BYTES_PER_ELEMENT as int; i++) {
7697                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
7698                    (this.buffer as SharedArrayBuffer).set(startByte + 3 - i, byteVal)
7699                }
7700            } else {
7701                throw new Error("unexpected type of ArrayBufferLike")
7702            }
7703        }
7704    }
7705
7706    /** Underlying ArrayBufferLike */
7707    public readonly buffer: ArrayBufferLike
7708
7709    /** Byte offset within the underlying ArrayBufferLike */
7710    public readonly byteOffset: number
7711
7712    /** Number of bytes used */
7713    public readonly byteLength: number
7714
7715    /** String \"Int32Array\" */
7716    public readonly name = "Int32Array"
7717}
7718
7719class BigInt64ArrayIteratorKeys implements IterableIterator<number> {
7720    private length: int
7721    private idx: int = 0
7722
7723    constructor(parent: BigInt64Array) {
7724        this.length = parent.length as int
7725    }
7726
7727    public override $_iterator(): IterableIterator<number> {
7728        return this
7729    }
7730
7731    override next(): IteratorResult<number> {
7732        if (this.idx < 0 || this.idx >= this.length) {
7733            return new IteratorResult<number>()
7734        }
7735        return new IteratorResult<number>(false, this.idx++ as number)
7736    }
7737}
7738
7739class BigInt64ArrayIterator implements IterableIterator<BigInt> {
7740    private parent: BigInt64Array
7741    private idx: int = 0
7742
7743    constructor(parent: BigInt64Array) {
7744        this.parent = parent
7745    }
7746
7747    public override $_iterator(): IterableIterator<BigInt> {
7748        return this
7749    }
7750
7751    override next(): IteratorResult<BigInt> {
7752        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7753            return new IteratorResult<BigInt>()
7754        }
7755        return new IteratorResult<BigInt>(false, new BigInt(this.parent[this.idx++]))
7756    }
7757}
7758
7759class BigInt64ArrayIteratorEntries implements IterableIterator<[Number, BigInt]> {
7760    private parent: BigInt64Array
7761    private idx: int = 0
7762
7763    constructor(parent: BigInt64Array) {
7764        this.parent = parent
7765    }
7766
7767    public override $_iterator(): IterableIterator<[Number, BigInt]> {
7768        return this
7769    }
7770
7771    override next(): IteratorResult<[Number, BigInt]> {
7772        if (this.idx < 0 || this.idx >= this.parent.length as int) {
7773            return new IteratorResult<[Number, BigInt]>()
7774        }
7775        return new IteratorResult<[Number, BigInt]>(
7776            false, [new Number(this.idx), new BigInt(this.parent[this.idx++])] as [Number, BigInt]
7777        )
7778    }
7779}
7780
7781
7782/**
7783 * JS BigInt64Array API-compatible class
7784 */
7785export final class BigInt64Array implements Iterable<BigInt>, ArrayLike<BigInt> {
7786    public static readonly BYTES_PER_ELEMENT: number = 8
7787    internal readonly lengthInt: int
7788
7789    /**
7790     * Creates an empty BigInt64Array.
7791     */
7792    public constructor() {
7793        this(0 as int)
7794    }
7795
7796    /**
7797     * Creates an BigInt64Array with respect to data accessed via Iterable<Number> interface
7798     */
7799    public constructor(elements: Iterable<BigInt>) {
7800        // NOTE (ikorobkov): dealing with this overload is tricky
7801        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
7802        let arr = Array.from<BigInt>(elements)
7803        this.byteLength = arr.length * BigInt64Array.BYTES_PER_ELEMENT as int
7804        this.lengthInt = arr.length as int
7805        this.buffer = new ArrayBuffer(this.byteLength as int)
7806        this.byteOffset = 0
7807        for (let i: int = 0; i < this.lengthInt; ++i) {
7808            this.setUnsafe(i, arr.$_get(i).getLong())
7809        }
7810    }
7811
7812    /**
7813     * Creates an BigInt64Array with respect to data, byteOffset and length.
7814     *
7815     * @param buf data initializer
7816     *
7817     * @param byteOffset byte offset from begin of the buf
7818     *
7819     * @param length size of elements of type long in newly created BigInt64Array
7820     */
7821    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
7822        let intByteOffset: int = 0
7823        if (byteOffset != undefined) {
7824            intByteOffset = byteOffset.intValue()
7825            if (intByteOffset < 0) {
7826                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
7827            }
7828        }
7829        let intByteLength: int
7830        if (buf instanceof ArrayBuffer) {
7831            intByteLength = (buf as ArrayBuffer).getByteLength()
7832        } else if (buf instanceof SharedArrayBuffer) {
7833            intByteLength = (buf as SharedArrayBuffer).getByteLength()
7834        } else {
7835            throw new Error("unexpected type of ArrayBufferLike")
7836        }
7837        intByteLength = intByteLength - intByteOffset
7838        if (intByteLength < 0) {
7839            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
7840        }
7841
7842        if (intByteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
7843            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
7844        }
7845        if (intByteOffset % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
7846            throw new RangeError("byteOffset should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
7847        }
7848
7849        let intLength: int
7850        if (length != undefined) {
7851            intLength = length.intValue()
7852            if (intLength > intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
7853                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
7854            }
7855        } else {
7856            intLength = intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int
7857        }
7858        if (intLength < 0) {
7859            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
7860        }
7861        if (intLength < intByteLength / BigInt64Array.BYTES_PER_ELEMENT as int) {
7862            intByteLength = intLength * BigInt64Array.BYTES_PER_ELEMENT as int
7863        }
7864        this.byteLength = intByteLength
7865        this.byteOffset = intByteOffset
7866        this.lengthInt = intLength
7867        this.buffer = buf
7868    }
7869
7870    /**
7871     * Creates an BigInt64Array with respect to data, byteOffset and length.
7872     *
7873     * @param buf data initializer
7874     *
7875     * @param byteOffset byte offset from begin of the buf
7876     *
7877     * @param length size of elements of type long in newly created BigInt64Array
7878     */
7879    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
7880        this(buf, byteOffset, undefined)
7881    }
7882
7883    /**
7884     * Creates an BigInt64Array with respect to data, byteOffset and length.
7885     *
7886     * @param buf data initializer
7887     *
7888     * @param byteOffset byte offset from begin of the buf
7889     *
7890     * @param length size of elements of type long in newly created BigInt64Array
7891     */
7892    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
7893        this(buf, new Number(byteOffset), new Number(length))
7894    }
7895
7896    /**
7897     * Creates an BigInt64Array with respect to data, byteOffset and length.
7898     *
7899     * @param buf data initializer
7900     *
7901     * @param byteOffset byte offset from begin of the buf
7902     *
7903     * @param length size of elements of type long in newly created BigInt64Array
7904     */
7905    public constructor(buf: ArrayBufferLike, byteOffset: number) {
7906        this(buf, new Number(byteOffset), undefined)
7907    }
7908
7909    /**
7910     * Creates an BigInt64Array with respect to data, byteOffset and length.
7911     *
7912     * @param buf data initializer
7913     *
7914     * @param byteOffset byte offset from begin of the buf
7915     *
7916     * @param length size of elements of type long in newly created BigInt64Array
7917     */
7918    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
7919        this(buf, new Number(byteOffset), new Number(length))
7920    }
7921
7922    /**
7923     * Creates an BigInt64Array with respect to buf and byteOffset.
7924     *
7925     * @param buf data initializer
7926     *
7927     * @param byteOffset byte offset from begin of the buf
7928     */
7929    public constructor(buf: ArrayBufferLike, byteOffset: int) {
7930        this(buf, new Number(byteOffset), undefined)
7931    }
7932
7933    /**
7934     * Creates an BigInt64Array with respect to buf.
7935     *
7936     * @param buf data initializer
7937     */
7938    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
7939        if (buf instanceof ArrayBuffer) {
7940            this.byteLength = (buf as ArrayBuffer).getByteLength()
7941            if (this.byteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
7942               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
7943            }
7944            this.lengthInt = this.byteLength / BigInt64Array.BYTES_PER_ELEMENT as int
7945            this.buffer = buf as ArrayBuffer
7946            this.byteOffset = 0
7947        } else if (buf instanceof SharedArrayBuffer) {
7948            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
7949            if (this.byteLength % BigInt64Array.BYTES_PER_ELEMENT as int != 0) {
7950               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as BigInt64Array.BYTES_PER_ELEMENT")
7951            }
7952            this.lengthInt = this.byteLength / BigInt64Array.BYTES_PER_ELEMENT as int
7953            this.buffer = buf as SharedArrayBuffer
7954            this.byteOffset = 0
7955        } else if (buf instanceof ArrayLike) {
7956            // NOTE (ikorobkov): dealing with this overload is tricky
7957            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
7958            let arr = Array.from<Number>((buf as ArrayLike<Number>))
7959            this.byteLength = arr.length as int * BigInt64Array.BYTES_PER_ELEMENT as int
7960            this.lengthInt = arr.length as int
7961            this.buffer = new ArrayBuffer(this.byteLength as int)
7962            this.byteOffset = 0
7963            for (let i: int = 0; i < this.lengthInt; ++i) {
7964                this.setUnsafe(i, arr.$_get(i).longValue())
7965            }
7966        } else {
7967            throw new Error("unexpected type of buf")
7968        }
7969    }
7970
7971    /**
7972     * Creates an BigInt64Array with respect to length.
7973     *
7974     * @param length data initializer
7975     */
7976    public constructor(length: int) {
7977        if (length < 0) {
7978            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
7979        }
7980        this.lengthInt = length
7981        this.byteLength = length * BigInt64Array.BYTES_PER_ELEMENT as int
7982        this.byteOffset = 0
7983        this.buffer = new ArrayBuffer(this.byteLength as int)
7984    }
7985
7986    /**
7987     * Creates an BigInt64Array with respect to length.
7988     *
7989     * @param length data initializer
7990     */
7991    public constructor(length: number) {
7992        this(length as int)
7993    }
7994
7995    /**
7996     * Creates a copy of BigInt64Array.
7997     *
7998     * @param other data initializer
7999     */
8000    public constructor(other: BigInt64Array) {
8001        if (other.buffer instanceof ArrayBuffer) {
8002            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
8003        } else if (other.buffer instanceof SharedArrayBuffer) {
8004            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
8005        } else {
8006            throw new Error("unexpected type of buffer")
8007        }
8008        this.byteLength = other.byteLength
8009        this.lengthInt = other.length as int
8010        this.byteOffset = 0
8011    }
8012
8013    /**
8014     * Creates an BigInt64Array from number[]
8015     */
8016    public constructor(numbers: number[]) {
8017        this(numbers.length)
8018        for (let i: int = 0; i < this.lengthInt; ++i) {
8019            this.setUnsafe(i, this.zeroIfInfinity(numbers[i] as long))
8020        }
8021    }
8022
8023    /**
8024     * Creates an BigInt64Array from int[]
8025     */
8026    public constructor(numbers: int[]) {
8027        this(numbers.length)
8028        for (let i: int = 0; i < this.lengthInt; ++i) {
8029            this.setUnsafe(i, this.zeroIfInfinity(numbers[i] as long))
8030        }
8031    }
8032
8033    internal zeroIfInfinity(val: BigInt): BigInt {
8034        if ((val.getLong() == Infinity) || (val.getLong() == -Infinity)) {
8035            return new BigInt(0)
8036        }
8037        return new BigInt(val)
8038    }
8039
8040    internal zeroIfInfinity(val: long): long {
8041        if ((val == Infinity) || (val == -Infinity)) {
8042            return 0 as long
8043        }
8044        return val
8045    }
8046
8047    /**
8048     * Assigns val as element on index.
8049     *
8050     * @param val value to set
8051     *
8052     * @param index index to change
8053     */
8054    public $_set(index: number, val: BigInt): void {
8055        this.$_set(index as int, val)
8056    }
8057
8058    /**
8059     * Assigns val as element on index.
8060     *
8061     * @param val value to set
8062     *
8063     * @param index index to change
8064     */
8065    public $_set(index: int, val: BigInt): void {
8066        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8067        if (index < 0 || index >= this.lengthInt) {
8068            throw new RangeError("invalid index")
8069        }
8070        let v = this.zeroIfInfinity(val)
8071        this.setUnsafe(index, v.getLong())
8072    }
8073
8074    /**
8075     * Assigns val as element on index.
8076     *
8077     * @param val value to set
8078     *
8079     * @param index index to change
8080     */
8081    public $_set(index: number, val: int): void {
8082        this.$_set(index as int, val)
8083    }
8084
8085    /**
8086     * Assigns val as element on index.
8087     *
8088     * @param val value to set
8089     *
8090     * @param index index to change
8091     */
8092    public $_set(index: int, val: int): void {
8093        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8094        if (index < 0 || index >= this.lengthInt) {
8095            throw new RangeError("invalid index")
8096        }
8097        let v = this.zeroIfInfinity(val as long)
8098        this.setUnsafe(index, v as long)
8099    }
8100
8101    /**
8102     * Assigns val as element on index.
8103     *
8104     * @param val value to set
8105     *
8106     * @param index index to change
8107     */
8108    public $_set(index: number, val: long): void {
8109        this.$_set(index as int, val)
8110    }
8111
8112    /**
8113     * Assigns val as element on index.
8114     *
8115     * @param val value to set
8116     *
8117     * @param index index to change
8118     */
8119    public $_set(index: int, val: long): void {
8120        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
8121        if (index < 0 || index >= this.lengthInt) {
8122            throw new RangeError("invalid index")
8123        }
8124        let v = this.zeroIfInfinity(val)
8125        this.setUnsafe(index, v)
8126    }
8127
8128    /** Number of long stored in BigInt64Array */
8129    public get length(): number {
8130        return this.lengthInt
8131    }
8132
8133    /**
8134     * Returns an instance of BigInt at passed index.
8135     *
8136     * @param index index to look at
8137     *
8138     * @returns a primitive at index
8139     */
8140    public override $_get(index: number): BigInt {
8141        return this.$_get(index as int) as BigInt
8142    }
8143
8144    /**
8145     * Returns an instance of BigInt at passed index.
8146     *
8147     * @param index index to look at
8148     *
8149     * @returns a primitive at index
8150     */
8151    public $_get(index: int): BigInt {
8152        if (index < 0 || index >= this.lengthInt) {
8153            throw new RangeError("invalid index")
8154        }
8155        return new BigInt(this.getUnsafe(index))
8156    }
8157
8158    /**
8159     * Returns an instance of primitive type at passed index.
8160     *
8161     * @param index index to look at
8162     *
8163     * @returns a primitive at index
8164     */
8165    public at(index: number): BigInt | undefined {
8166        return this.at(index as int)
8167    }
8168
8169    /**
8170     * Returns an instance of primitive type at passed index.
8171     *
8172     * @param index index to look at
8173     *
8174     * @returns a primitive at index
8175     */
8176    public at(index: int): BigInt | undefined {
8177        let k: int
8178        if (index >= 0) {
8179            k = index
8180        } else {
8181            k = this.lengthInt + index
8182        }
8183        if (k < 0 || k >= this.lengthInt) {
8184            return undefined
8185        }
8186        return new BigInt(this.getUnsafe(k))
8187    }
8188
8189    /**
8190     * Makes a copy of internal elements to targetPos from startPos to endPos.
8191     *
8192     * @param target insert index to place copied elements
8193     *
8194     * @param start start index to begin copy from
8195     *
8196     * @param end last index to end copy from, excluded
8197     *
8198     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8199     */
8200    public copyWithin(target: number, start: number, end?: number): BigInt64Array {
8201        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8202    }
8203
8204    /**
8205     * Makes a copy of internal elements to targetPos from startPos to endPos.
8206     *
8207     * @param target insert index to place copied elements
8208     *
8209     * @param start start index to begin copy from
8210     *
8211     * @param end last index to end copy from, excluded
8212     *
8213     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8214     */
8215    public copyWithin(target: int, start: number, end?: number): BigInt64Array {
8216        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8217    }
8218
8219    /**
8220     * Makes a copy of internal elements to targetPos from startPos to endPos.
8221     *
8222     * @param target insert index to place copied elements
8223     *
8224     * @param start start index to begin copy from
8225     *
8226     * @param end last index to end copy from, excluded
8227     *
8228     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8229     */
8230    public copyWithin(target: number, start: int, end?: number): BigInt64Array {
8231        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8232    }
8233
8234    /**
8235     * Makes a copy of internal elements to targetPos from startPos to endPos.
8236     *
8237     * @param target insert index to place copied elements
8238     *
8239     * @param start start index to begin copy from
8240     *
8241     * @param end last index to end copy from, excluded
8242     *
8243     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8244     */
8245    public copyWithin(target: int, start: int, end?: number): BigInt64Array {
8246        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
8247    }
8248
8249    /**
8250     * Makes a copy of internal elements to targetPos from startPos to endPos.
8251     *
8252     * @param target insert index to place copied elements
8253     *
8254     * @param start start index to begin copy from
8255     *
8256     * @param end last index to end copy from, excluded
8257     *
8258     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
8259     */
8260    public copyWithin(target: int, start: int, end: int): BigInt64Array {
8261        let toPos = normalizeIndex(target, this.lengthInt)
8262        let fromPos = normalizeIndex(start, this.lengthInt)
8263        const finalPos = normalizeIndex(end, this.lengthInt)
8264        let count: int = finalPos - fromPos
8265        if (count > (this.lengthInt - toPos)) {
8266            count = this.lengthInt - toPos
8267        }
8268        let direction: int = 1
8269        if ((fromPos < toPos) && (toPos < fromPos + count)) {
8270            fromPos = fromPos + count - 1
8271            toPos   = toPos   + count - 1
8272            direction = -1
8273        }
8274        while (count > 0) {
8275            const value = this.getUnsafe(fromPos)
8276            this.setUnsafe(toPos, value)
8277            fromPos = fromPos + direction
8278            toPos = toPos + direction
8279            --count
8280        }
8281        return this
8282    }
8283
8284    /**
8285     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
8286     *
8287     * @param target insert index to place copied elements
8288     *
8289     * See rules of parameters normalization:
8290     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
8291     */
8292    public copyWithin(target: number): BigInt64Array {
8293        return this.copyWithin(target as int)
8294    }
8295
8296    /**
8297     * Makes a copy of internal elements to targetPos from begin to end of BigInt64Array.
8298     *
8299     * @param target insert index to place copied elements
8300     *
8301     * See rules of parameters normalization:
8302     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
8303     */
8304    public copyWithin(target: int): BigInt64Array {
8305        return this.copyWithin(target, 0, this.lengthInt)
8306    }
8307
8308    /**
8309     * Returns an array of key, value pairs for every entry in the BigInt64Array
8310     *
8311     * @returns key, value pairs for every entry in the array
8312     */
8313    public entries(): IterableIterator<[Number, BigInt]> {
8314        return new BigInt64ArrayIteratorEntries(this)
8315    }
8316
8317    /**
8318     * Fills the BigInt64Array with specified value
8319     *
8320     * @param value new valuy
8321     *
8322     * @returns modified BigInt64Array
8323     */
8324    public fill(value: BigInt, start?: number, end?: number): this {
8325        value = this.zeroIfInfinity(value)
8326        this.fill(value.getLong(), asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
8327        return this
8328    }
8329
8330    /**
8331     * Fills the BigInt64Array with specified value
8332     *
8333     * @param value new valuy
8334     *
8335     * @returns modified BigInt64Array
8336     */
8337    public fill(value: BigInt, start: int, end?: number): this {
8338        value = this.zeroIfInfinity(value)
8339        this.fill(value.getLong(), start as int, asIntOrDefault(end, this.lengthInt))
8340        return this
8341    }
8342
8343    /**
8344     * Fills the BigInt64Array with specified value
8345     *
8346     * @param value new valuy
8347     *
8348     * @returns modified BigInt64Array
8349     */
8350    public fill(value: BigInt, start: int, end: number): this {
8351        value = this.zeroIfInfinity(value)
8352        this.fill(value.getLong(), start as int, end as int)
8353        return this
8354    }
8355
8356    /**
8357     * Fills the BigInt64Array with specified value
8358     *
8359     * @param value new valuy
8360     *
8361     * @returns modified BigInt64Array
8362     */
8363    public fill(value: BigInt, start: number, end: int): this {
8364        value = this.zeroIfInfinity(value)
8365        this.fill(value.getLong(), start as int, end as int)
8366        return this
8367    }
8368
8369    /**
8370     * Fills the BigInt64Array with specified value
8371     *
8372     * @param value new valuy
8373     *
8374     * @returns modified BigInt64Array
8375     */
8376    public fill(value: BigInt, start: int, end: int): this {
8377        value = this.zeroIfInfinity(value)
8378        this.fill(value.getLong(), start as int, end as int)
8379        return this
8380    }
8381
8382    /**
8383     * Fills the BigInt64Array with specified value
8384     *
8385     * @param value new valuy
8386     *
8387     * @returns modified BigInt64Array
8388     */
8389    public fill(value: long, start?: number, end?: number): this {
8390        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
8391        return this
8392    }
8393
8394    /**
8395     * Fills the BigInt64Array with specified value
8396     *
8397     * @param value new valuy
8398     *
8399     * @returns modified BigInt64Array
8400     */
8401    public fill(value: long, start: int, end?: number): this {
8402        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
8403        return this
8404    }
8405
8406    /**
8407     * Fills the BigInt64Array with specified value
8408     *
8409     * @param value new valuy
8410     *
8411     * @returns modified BigInt64Array
8412     */
8413    public fill(value: long, start: int, end: number): this {
8414        this.fill(value, start as int, end as int)
8415        return this
8416    }
8417
8418    /**
8419     * Fills the BigInt64Array with specified value
8420     *
8421     * @param value new valuy
8422     *
8423     * @returns modified BigInt64Array
8424     */
8425    public fill(value: long, start: number, end: int): this {
8426        this.fill(value, start as int, end as int)
8427        return this
8428    }
8429
8430    /**
8431     * Fills the BigInt64Array with specified value
8432     *
8433     * @param value new valuy
8434     *
8435     * @returns modified BigInt64Array
8436     */
8437    public fill(value: long, start: int, end: int): this {
8438        const k = normalizeIndex(start, this.lengthInt)
8439        const finalPos = normalizeIndex(end, this.lengthInt)
8440        for (let i: int = k; i < finalPos; ++i) {
8441            this.setUnsafe(i, value)
8442        }
8443        return this
8444    }
8445
8446    /**
8447     * Assigns val as element on insertPos.
8448     * @description Added to avoid (un)packing a single value into array to use overloaded set(long[], insertPos)
8449     *
8450     * @param val value to set
8451     *
8452     * @param insertPos index to change
8453     */
8454    public set(insertPos: number, val: BigInt): void {
8455        this.$_set(insertPos, val)
8456    }
8457
8458    /**
8459     * Assigns val as element on insertPos.
8460     * @description Added to avoid (un)packing a single value into array to use overloaded set(long[], insertPos)
8461     *
8462     * @param val value to set
8463     *
8464     * @param insertPos index to change
8465     */
8466    public set(insertPos: int, val: long): void {
8467        this.$_set(insertPos, val)
8468    }
8469
8470    /**
8471     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
8472     *
8473     * @param arr array to copy data from
8474     *
8475     * @param insertPos start index where data from arr will be inserted
8476     *
8477     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
8478     */
8479    public set(arr: BigInt[], insertPos: number): void {
8480        const offset = insertPos as int
8481        if (offset < 0 || offset + arr.length > this.lengthInt) {
8482            throw new RangeError("offset is out of bounds")
8483        }
8484        for (let i = 0; i < arr.length as int; ++i) {
8485            let v = this.zeroIfInfinity(arr[i])
8486            this.setUnsafe(offset + i, v.getLong())
8487        }
8488    }
8489
8490    /**
8491     * Copies all elements of arr to the current BigInt64Array starting from insertPos.
8492     *
8493     * @param arr array to copy data from
8494     *
8495     * @param insertPos start index where data from arr will be inserted
8496     *
8497     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
8498     */
8499    public set(arr: long[], insertPos: int): void {
8500        const offset = insertPos as int
8501        if (offset < 0 || offset + arr.length > this.lengthInt) {
8502            throw new RangeError("offset is out of bounds")
8503        }
8504        for (let i = 0; i < arr.length as int; ++i) {
8505            let v = this.zeroIfInfinity(arr[i])
8506            this.setUnsafe(offset + i, v)
8507        }
8508    }
8509
8510    /**
8511     * Copies all elements of arr to the current BigInt64Array.
8512     *
8513     * @param arr array to copy data from
8514     */
8515    public set(arr: BigInt[]): void {
8516        this.set(arr, 0 as number)
8517    }
8518
8519    /**
8520     * Copies all elements of arr to the current BigInt64Array.
8521     *
8522     * @param arr array to copy data from
8523     */
8524    public set(arr: long[]): void {
8525        this.set(arr, 0 as int)
8526    }
8527
8528    /**
8529     * Copies elements from an ArrayLike object to the BigInt64Array.
8530     *
8531     * @param array An ArrayLike object containing the elements to copy.
8532     *
8533     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
8534     */
8535    public set(array: ArrayLike<BigInt>, offset: number = 0): void {
8536        const insertPos = offset as int
8537        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
8538            throw new RangeError("offset is out of bounds")
8539        }
8540        for (let i = 0; i < array.length as int; ++i) {
8541            let v = this.zeroIfInfinity(array[i])
8542            this.setUnsafe(insertPos + i, v.getLong())
8543        }
8544    }
8545
8546    /**
8547     * Returns a new array from a set of elements.
8548     *
8549     * @param items a set of elements to include in the new array object.
8550     *
8551     * @returns new BigInt64Array
8552     */
8553    public static of(...items: number[]): BigInt64Array {
8554        throw new Error("BigInt64Array.of: not implemented")
8555    }
8556
8557    /**
8558     * Returns a new array from a set of elements.
8559     *
8560     * @param items a set of elements to include in the new array object.
8561     *
8562     * @returns new BigInt64Array
8563     */
8564    public static of(...items: int[]): BigInt64Array {
8565        throw new Error("BigInt64Array.of: not implemented")
8566    }
8567
8568    /**
8569     * Returns a new array from a set of elements.
8570     *
8571     * @param items a set of elements to include in the new array object.
8572     *
8573     * @returns new BigInt64Array
8574     */
8575    public static of(...items: long[]): BigInt64Array {
8576        throw new Error("BigInt64Array.of: not implemented")
8577    }
8578
8579    /**
8580     * Returns a new array from a set of elements.
8581     *
8582     * @param items a set of elements to include in the new array object.
8583     *
8584     * @returns new BigInt64Array
8585     */
8586    public static of(): BigInt64Array {
8587        return new BigInt64Array(0 as int)
8588    }
8589
8590    /**
8591     * Creates an array from an array-like or iterable object.
8592     *
8593     * @param arrayLike An array-like or iterable object to convert to an array.
8594     *
8595     * @returns new BigInt64Array
8596     */
8597    public static from(arrayLike: ArrayLike<number>): BigInt64Array {
8598        throw new Error("BigInt64Array.from: not implemented")
8599    }
8600
8601    /**
8602     * Creates an array from an array-like or iterable object.
8603     *
8604     * @param arrayLike An array-like or iterable object to convert to an array.
8605     *
8606     * @param mapfn A mapping function to call on every element of the array.
8607     *
8608     * @returns new BigInt64Array
8609     */
8610    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): BigInt64Array {
8611        throw new Error("BigInt64Array.from: not implemented")
8612    }
8613
8614
8615    /**
8616     * Creates an array from an array-like or iterable object.
8617     *
8618     * @param arrayLike An array-like or iterable object to convert to an array.
8619     *
8620     * @param mapfn A mapping function to call on every element of the array.
8621     *
8622     * @returns new BigInt64Array
8623     */
8624    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): BigInt64Array {
8625        throw new Error("BigInt64Array.from: not implemented")
8626    }
8627
8628    /**
8629     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8630     *
8631     * @param searchElement The element to search for
8632     *
8633     * @param fromIndex The position in this array at which to begin searching for searchElement
8634     *
8635     * @returns true if searchElement is in BigInt64Array, false otherwise
8636     */
8637    public includes(searchElement: BigInt, fromIndex?: number): boolean {
8638        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
8639    }
8640
8641    /**
8642     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8643     *
8644     * @param searchElement The element to search for
8645     *
8646     * @param fromIndex The position in this array at which to begin searching for searchElement
8647     *
8648     * @returns true if e is in BigInt64Array, false otherwise
8649     */
8650    public includes(searchElement: long, fromIndex: int): boolean {
8651        return this.indexOf(searchElement as int, fromIndex) != -1
8652    }
8653
8654    /**
8655     * Determines whether BigInt64Array includes a certain element, returning true or false as appropriate
8656     *
8657     * @param searchElement The element to search for
8658     *
8659     * @param fromIndex The position in this array at which to begin searching for searchElement
8660     *
8661     * @returns true if searchElement is in BigInt64Array, false otherwise
8662     */
8663    public includes(searchElement: long): boolean {
8664        return this.includes(searchElement, 0)
8665    }
8666
8667    /**
8668     * Returns the index of the first occurrence of a value in BigInt64Array.
8669     *
8670     * @param searchElement The value to locate in the array.
8671     *
8672     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8673     *  search starts at index 0.
8674     *
8675     * @returns index of element if it presents, -1 otherwise
8676     */
8677    public indexOf(searchElement: BigInt, fromIndex?: number): number {
8678        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
8679    }
8680
8681    /**
8682     * Returns the index of the first occurrence of a value in BigInt64Array.
8683     *
8684     * @param searchElement The value to locate in the array.
8685     *
8686     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8687     *  search starts at index 0.
8688     *
8689     * @returns index of element if it presents, -1 otherwise
8690     */
8691    public indexOf(searchElement: BigInt, fromIndex: int): number {
8692        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
8693        for (let i = fromIndex; i < this.lengthInt; i++) {
8694            if (new BigInt(this.getUnsafe(i)) == searchElement) {
8695                return i
8696            }
8697        }
8698        return -1
8699    }
8700
8701    /**
8702     * Returns the index of the first occurrence of a value in BigInt64Array.
8703     *
8704     * @param searchElement The value to locate in the array.
8705     *
8706     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8707     *  search starts at index 0.
8708     *
8709     * @returns index of element if it presents, -1 otherwise
8710     */
8711    public indexOf(searchElement: int, fromIndex: int): number {
8712        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
8713        for (let i = fromIndex; i < this.lengthInt; i++) {
8714            if (this.getUnsafe(i) == searchElement as long) {
8715                return i
8716            }
8717        }
8718        return -1
8719    }
8720
8721    /**
8722     * Returns the index of the first occurrence of a value in BigInt64Array.
8723     *
8724     * @param searchElement The value to locate in the array.
8725     *
8726     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
8727     *  search starts at index 0.
8728     *
8729     * @returns index of element if it presents, -1 otherwise
8730     */
8731    public indexOf(searchElement: int): number {
8732        return this.indexOf(searchElement, 0)
8733    }
8734
8735    /**
8736     * Adds all the elements of an array separated by the specified separator string
8737     *
8738     * @param separator A string used to separate one element of an array from the next in the
8739     * resulting String. If omitted, the array elements are separated with a comma
8740     *
8741     * @returns joined representation
8742     */
8743    public join(separator?: String): string {
8744        if (separator == undefined) {
8745            return this.join(",")
8746        }
8747        let res: StringBuilder = new StringBuilder("")
8748        for (let i = 0; i < this.lengthInt - 1; ++i) {
8749            res.append(new BigInt(this.getUnsafe(i)))
8750            res.append(separator)
8751        }
8752        if (this.lengthInt > 0) {
8753            res.append(new BigInt(this.getUnsafe(this.lengthInt - 1)))
8754        }
8755        return res.toString()
8756    }
8757
8758    /**
8759     * Returns an list of keys in BigInt64Array
8760     *
8761     * @returns iterator over keys
8762     */
8763    public keys(): IterableIterator<number> {
8764        return new BigInt64ArrayIteratorKeys(this)
8765    }
8766
8767    /**
8768     * Returns the index of the last occurrence of a value in BigInt64Array.
8769     *
8770     * @param searchElement The value to locate in the array.
8771     *
8772     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8773     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8774     *
8775     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8776     */
8777    public lastIndexOf(searchElement: BigInt, fromIndex: number|undefined): number {
8778        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
8779    }
8780
8781    /**
8782     * Returns the index of the last occurrence of a value in BigInt64Array.
8783     *
8784     * @param searchElement The value to locate in the array.
8785     *
8786     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8787     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8788     *
8789     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8790     */
8791    public lastIndexOf(searchElement: BigInt): number {
8792        return this.lastIndexOf(searchElement, this.lengthInt - 1)
8793    }
8794
8795    /**
8796     * Returns the index of the last occurrence of a value in BigInt64Array.
8797     *
8798     * @param searchElement The value to locate in the array.
8799     *
8800     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8801     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8802     *
8803     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8804     */
8805    public lastIndexOf(searchElement: BigInt, fromIndex: int): number {
8806        if (this.lengthInt == 0) {
8807            return -1
8808        }
8809        let k: int = this.lengthInt + fromIndex
8810        if (fromIndex >= 0) {
8811            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
8812        }
8813        while (k >= 0) {
8814            if (new BigInt(this.getUnsafe(k)) == searchElement) {
8815                return k
8816            }
8817            k--
8818        }
8819        return -1
8820    }
8821
8822    /**
8823     * Returns the index of the last occurrence of a value in BigInt64Array.
8824     *
8825     * @param searchElement The value to locate in the array.
8826     *
8827     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8828     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8829     *
8830     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8831     */
8832    public lastIndexOf(searchElement: int, fromIndex: int): number {
8833        if (this.lengthInt == 0) {
8834            return -1
8835        }
8836        let k: int = this.lengthInt + fromIndex
8837        if (fromIndex >= 0) {
8838            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
8839        }
8840        while (k >= 0) {
8841            if (this.getUnsafe(k) == searchElement as long) {
8842                return k
8843            }
8844            k--
8845        }
8846        return -1
8847    }
8848
8849    /**
8850     * Returns the index of the last occurrence of a value in BigInt64Array.
8851     *
8852     * @param searchElement The value to locate in the array.
8853     *
8854     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
8855     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
8856     *
8857     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
8858     */
8859    public lastIndexOf(searchElement: int): number {
8860        return this.lastIndexOf(searchElement, this.lengthInt - 1)
8861    }
8862
8863    /**
8864    * Creates a new BigInt64Array using initializer
8865    *
8866    * @param data initializer
8867    *
8868    * @returns a new BigInt64Array from data
8869    */
8870    public of(data: Object[]): BigInt64Array {
8871        throw new Error("BigInt64Array.of: not implemented")
8872    }
8873
8874    /**
8875     * Creates a new BigInt64Array using reversed data from the current one
8876     *
8877     * @returns a new BigInt64Array using reversed data from the current one
8878     */
8879    public reverse(): BigInt64Array {
8880        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
8881            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
8882            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
8883            this.setUnsafe(i, tmp)
8884        }
8885        return this
8886    }
8887
8888    /**
8889     * Creates a slice of current BigInt64Array using range [begin, end)
8890     *
8891     * @param begin start index to be taken into slice
8892     *
8893     * @param end last index to be taken into slice
8894     *
8895     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
8896     *
8897     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8898     */
8899    public slice(begin?: number, end?: number): BigInt64Array {
8900        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
8901    }
8902
8903    /**
8904     * Creates a slice of current BigInt64Array using range [begin, end)
8905     *
8906     * @param begin start index to be taken into slice
8907     *
8908     * @param end last index to be taken into slice
8909     *
8910     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
8911     *
8912     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8913     */
8914    public slice(begin: number, end: number): BigInt64Array {
8915        return this.slice(begin as int, end as int)
8916    }
8917
8918    /**
8919     * Creates a slice of current BigInt64Array using range [begin, end)
8920     *
8921     * @param begin start index to be taken into slice
8922     *
8923     * @param end last index to be taken into slice
8924     *
8925     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
8926     *
8927     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8928     */
8929    public slice(begin: number, end: int): BigInt64Array {
8930        return this.slice(begin as int, end as int)
8931    }
8932
8933    /**
8934     * Creates a slice of current BigInt64Array using range [begin, end)
8935     *
8936     * @param begin start index to be taken into slice
8937     *
8938     * @param end last index to be taken into slice
8939     *
8940     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
8941     *
8942     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8943     */
8944    public slice(begin: int, end: number): BigInt64Array {
8945        return this.slice(begin as int, end as int)
8946    }
8947
8948    /**
8949     * Creates a slice of current BigInt64Array using range [begin, end)
8950     *
8951     * @param begin start index to be taken into slice
8952     *
8953     * @param end last index to be taken into slice
8954     *
8955     * @returns a new BigInt64Array with elements of current BigInt64Array[begin;end) where end index is excluded
8956     *
8957     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
8958     */
8959    public slice(begin: int, end: int): BigInt64Array {
8960        const len: int = this.lengthInt
8961        const relStart = normalizeIndex(begin, len)
8962        const relEnd = normalizeIndex(end, len)
8963        let count = relEnd - relStart
8964        if (count < 0) {
8965            count = 0
8966        }
8967        if (this.buffer instanceof ArrayBuffer) {
8968            let buf = (this.buffer as ArrayBuffer).slice(relStart * BigInt64Array.BYTES_PER_ELEMENT as int, relEnd * BigInt64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
8969            return new BigInt64Array(buf)
8970        } else if (this.buffer instanceof SharedArrayBuffer) {
8971            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * BigInt64Array.BYTES_PER_ELEMENT as int, relEnd * BigInt64Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
8972            return new BigInt64Array(buf)
8973        } else {
8974            throw new Error("unexpected type of buffer")
8975        }
8976    }
8977
8978    /**
8979     * Creates a slice of current BigInt64Array using range [begin, this.length).
8980     *
8981     * @param begin start index to be taken into slice
8982     *
8983     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
8984     */
8985    public slice(begin: number): BigInt64Array {
8986        return this.slice(begin as int)
8987    }
8988
8989    /**
8990     * Creates a slice of current BigInt64Array using range [begin, this.length).
8991     *
8992     * @param begin start index to be taken into slice
8993     *
8994     * @returns a new BigInt64Array with elements of current BigInt64Array[begin, this.length)
8995     */
8996    public slice(begin: int): BigInt64Array {
8997        return this.slice(begin, this.lengthInt)
8998    }
8999
9000    /**
9001     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9002     *
9003     * @param begin start index, inclusive
9004     *
9005     * @param end last index, exclusive
9006     *
9007     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9008     */
9009    public subarray(begin?: number, end?: number): BigInt64Array {
9010        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
9011    }
9012
9013    /**
9014     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9015     *
9016     * @param begin start index, inclusive
9017     *
9018     * @param end last index, exclusive
9019     *
9020     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9021     */
9022    public subarray(begin: number, end: number): BigInt64Array {
9023        return this.subarray(begin as int, end as int)
9024    }
9025
9026    /**
9027     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9028     *
9029     * @param begin start index, inclusive
9030     *
9031     * @param end last index, exclusive
9032     *
9033     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9034     */
9035    public subarray(begin: number, end: int): BigInt64Array {
9036        return this.subarray(begin as int, end as int)
9037    }
9038
9039    /**
9040     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9041     *
9042     * @param begin start index, inclusive
9043     *
9044     * @param end last index, exclusive
9045     *
9046     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9047     */
9048    public subarray(begin: int, end: number): BigInt64Array {
9049        return this.subarray(begin as int, end as int)
9050    }
9051
9052    /**
9053     * Creates a BigInt64Array with the same underlying ArrayBufferLike
9054     *
9055     * @param begin start index, inclusive
9056     *
9057     * @param end last index, exclusive
9058     *
9059     * @returns new BigInt64Array with the same underlying ArrayBufferLike
9060     */
9061    public subarray(begin: int, end: int): BigInt64Array {
9062        const len: int = this.lengthInt
9063        const relStart = normalizeIndex(begin, len)
9064        const relEnd = normalizeIndex(end, len)
9065        let count = relEnd - relStart
9066        if (count < 0) {
9067            count = 0
9068        }
9069        return new BigInt64Array(this.buffer, relStart * BigInt64Array.BYTES_PER_ELEMENT as int, count)
9070    }
9071
9072    /**
9073     * Creates a BigInt64Array with the same ArrayBufferLike
9074     *
9075     * @param begin start index, inclusive
9076     *
9077     * @returns new BigInt64Array with the same ArrayBufferLike
9078     */
9079    public subarray(begin: number): BigInt64Array {
9080        return this.subarray(begin as int, this.lengthInt)
9081    }
9082
9083    /**
9084     * Creates a BigInt64Array with the same ArrayBufferLike
9085     *
9086     * @param begin start index, inclusive
9087     *
9088     * @returns new BigInt64Array with the same ArrayBufferLike
9089     */
9090    public subarray(begin: int): BigInt64Array {
9091        return this.subarray(begin as int, this.lengthInt)
9092    }
9093
9094    /**
9095     * Converts BigInt64Array to a string with respect to locale
9096     *
9097     * @param locales
9098     *
9099     * @param options
9100     *
9101     * @returns string representation
9102     */
9103    public toLocaleString(locales: Object, options: Object): string {
9104        throw new Error("BigInt64Array.toLocaleString: not implemented")
9105    }
9106
9107    /**
9108     * Converts BigInt64Array to a string with respect to locale
9109     *
9110     * @param locales
9111     *
9112     * @returns string representation
9113     */
9114    public toLocaleString(locales: Object): string {
9115        return this.toLocaleString(new Object(), new Object())
9116    }
9117
9118    /**
9119     * Converts BigInt64Array to a string with respect to locale
9120     *
9121     * @returns string representation
9122     */
9123    public toLocaleString(): string {
9124        let res: StringBuilder = new StringBuilder("")
9125        for (let i = 0; i < this.lengthInt - 1; ++i) {
9126            res.append(new BigInt(this.getUnsafe(i)).toLocaleString())
9127            res.append(",")
9128        }
9129        if (this.lengthInt > 0) {
9130            res.append(new BigInt(this.getUnsafe(this.lengthInt - 1)).toLocaleString())
9131        }
9132        return res.toString()
9133    }
9134
9135    /**
9136     * Creates a reversed copy
9137     *
9138     * @returns a reversed copy
9139     */
9140    public toReversed(): BigInt64Array {
9141        return new BigInt64Array(this).reverse()
9142    }
9143
9144    /**
9145     * Creates a sorted copy
9146     *
9147     * @returns a sorted copy
9148     */
9149    public toSorted(): BigInt64Array {
9150        return new BigInt64Array(this).sort()
9151    }
9152
9153    /**
9154     * Returns a string representation of the BigInt64Array
9155     *
9156     * @returns a string representation of the BigInt64Array
9157     */
9158    public override toString(): string {
9159        return this.join(",")
9160    }
9161
9162    /**
9163     * Returns array values iterator
9164     *
9165     * @returns an iterator
9166     */
9167    public values(): IterableIterator<BigInt> {
9168        return new BigInt64ArrayIterator(this)
9169    }
9170
9171    /**
9172     * Iteratorable interface implementation
9173     *
9174     * @returns iterator over all elements
9175     */
9176    public override $_iterator(): IterableIterator<BigInt> {
9177        return this.values()
9178    }
9179
9180    /**
9181     * Creates a copy with replaced value on index
9182     *
9183     * @param index
9184     *
9185     * @param value
9186     *
9187     * @returns an BigInt64Array with replaced value on index
9188     */
9189    public with(index: number, value: BigInt): BigInt64Array {
9190        return this.with(index as int, value.getLong())
9191    }
9192
9193    /**
9194     * Creates a copy with replaced value on index
9195     *
9196     * @param index
9197     *
9198     * @param value
9199     *
9200     * @returns an BigInt64Array with replaced value on index
9201     */
9202    public with(index: int, value: long): BigInt64Array {
9203        let res = new BigInt64Array(this)
9204        res.set(index, value)
9205        return res
9206    }
9207
9208    /// === with element lambda functions ===
9209    /**
9210     * Determines whether the specified callback function returns true for all elements of an array.
9211     *
9212     * @param predicate A function that accepts one argument.
9213     * The every method calls the predicate function for each element in the array until the predicate returns a false,
9214     * or until the end of the array.
9215     *
9216     * @returns true unless predicate function returns a false for an array element,
9217     * in which case false is immediately returned.
9218     */
9219    public every(predicate: (element: BigInt) => boolean): boolean {
9220        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element))
9221    }
9222
9223    /**
9224     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
9225     *
9226     * @param fn the condition to apply for each element
9227     *
9228     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
9229     */
9230    public filter(fn: (val: BigInt) => boolean): BigInt64Array {
9231        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9232            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9233        return this.filter(newF)
9234    }
9235
9236    /**
9237     * Returns the value of the first element in the array where predicate is true, and undefined
9238     * otherwise
9239     *
9240     * @param predicate find calls predicate once for each element of the array, in ascending
9241     * order, until it finds one where predicate returns true. If such an element is found, find
9242     * immediately returns that element value. Otherwise, find returns undefined
9243     *
9244     * @returns BigInt | undefined
9245     */
9246    public find(predicate: () => boolean): BigInt | undefined {
9247        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate())
9248    }
9249
9250    /**
9251     * Returns the value of the first element in the array where predicate is true, and undefined
9252     * otherwise
9253     *
9254     * @param predicate find calls predicate once for each element of the array, in ascending
9255     * order, until it finds one where predicate returns true. If such an element is found, find
9256     * immediately returns that element value. Otherwise, find returns undefined
9257     *
9258     * @returns BigInt | undefined
9259     */
9260    public find(predicate: (value: BigInt) => boolean): BigInt | undefined {
9261        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value))
9262    }
9263
9264    /**
9265     * Returns the index of the first element in the array where predicate is true, and -1
9266     * otherwise
9267     *
9268     * @param predicate find calls predicate once for each element of the array, in ascending
9269     * order, until it finds one where predicate returns true. If such an element is found,
9270     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
9271     *
9272     * @returns number
9273     */
9274    public findIndex(predicate: (value: BigInt) => boolean): number {
9275        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value)) as number
9276    }
9277
9278    /**
9279     * Finds the last element in the BigInt64Array that satisfies the condition
9280     *
9281     * @param fn condition
9282     *
9283     * @returns the last element that satisfies fn
9284     */
9285    public findLast(fn: (val: BigInt) => boolean): BigInt {
9286        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9287            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9288        return new BigInt(this.findLast(newF))
9289    }
9290
9291    /**
9292     * Finds an index of the last element in the BigInt64Array that satisfies the condition
9293     *
9294     * @param fn condition
9295     *
9296     * @returns the index of the last element that satisfies fn, -1 otherwise
9297     */
9298    public findLastIndex(fn: (val: BigInt) => boolean): number {
9299        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9300            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val) }
9301        return this.findLastIndex(newF) as number
9302    }
9303
9304    /**
9305     * Performs the specified action for each element in BigInt64Array
9306     *
9307     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
9308     * callbackfn function one time for each element in the array.
9309     *
9310     * @returns None
9311     */
9312    public forEach(callbackfn: (value: BigInt) => void): void {
9313        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn(value))
9314    }
9315
9316    /**
9317     * Creates a new BigInt64Array using fn(arr[i]) over all elements of current BigInt64Array
9318     *
9319     * @param fn a function to apply for each element of current BigInt64Array
9320     *
9321     * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
9322     */
9323    public map(fn: (val: BigInt) => BigInt): BigInt64Array {
9324        let newF: (val: BigInt, index: number) => BigInt =
9325            (val: BigInt, index: number): BigInt => { return fn(val) }
9326        return this.map(newF)
9327    }
9328
9329    /**
9330     * Determines whether the specified callback function returns true for any element of an array.
9331     *
9332     * @param predicate A function that accepts one argument.
9333     * The some method calls the predicate function for each element in the array
9334     * until the predicate returns a true or until the end of the array.
9335     *
9336     * @returns false unless predicate function returns true for an array element,
9337     * in which case true is immediately returned.
9338     */
9339    public some(predicate: (element: BigInt) => boolean): boolean {
9340        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element))
9341    }
9342
9343    // NOTE (kprokopenko): this may be not skipped
9344    /**
9345     * Sorts in-place
9346     *
9347     * @param compareFn comparator —  used to determine the order of the elements.
9348     * compareFn returns a negative value if first argument is less than second argument,
9349     * zero if they're equal and a positive value otherwise.
9350     * If omitted, the elements are sorted in ascending order.
9351     *
9352     * @returns sorted BigInt64Array
9353     */
9354    public sort(compareFn?: (a: BigInt, b: BigInt) => number): this {
9355        let arr: long[] = new long[this.lengthInt]
9356        for (let i = 0; i < this.lengthInt; ++i) {
9357            arr[i] = this.getUnsafe(i)
9358        }
9359        let cmp = (l: long, r: long): number => {
9360                return (l - r) as number
9361            }
9362        if (compareFn != undefined) {
9363            cmp = (l: long, r: long): number => {
9364                return compareFn!(new BigInt(l), new BigInt(r))
9365            }
9366        }
9367        sort(arr, cmp)
9368        for (let i = 0; i < this.lengthInt; ++i) {
9369            this.setUnsafe(i, arr[i])
9370        }
9371        return this
9372    }
9373
9374    /**
9375     * Sorts in-place
9376     *
9377     * @param compareFn comparator —  used to determine the order of the elements.
9378     * compareFn returns a negative value if first argument is less than second argument,
9379     * zero if they're equal and a positive value otherwise.
9380     *
9381     * @returns sorted BigInt64Array
9382     */
9383    public sort(compareFn: (a: BigInt) => number): this {
9384        let cmp = (a: BigInt, b: BigInt) => { return compareFn(a)}
9385        this.sort(cmp)
9386        return this
9387    }
9388
9389    /**
9390     * Sorts in-place
9391     *
9392     * @param fn compareFn —  used to determine the order of the elements.
9393     * compareFn returns a negative value if first argument is less than second argument,
9394     * zero if they're equal and a positive value otherwise.
9395     *
9396     * @returns sorted BigInt64Array
9397     */
9398    public sort(compareFn: () => number): this {
9399        let cmp = (a: BigInt, b: BigInt) => { return compareFn()}
9400        this.sort(cmp)
9401        return this
9402    }
9403
9404    /**
9405     * Determines whether the specified callback function returns true for any element of an array.
9406     *
9407     * @param predicate A function that accepts three arguments.
9408     * The some method calls the predicate function for each element in the array
9409     * until the predicate returns a true or until the end of the array.
9410     *
9411     * @returns false unless predicate function returns true for an array element,
9412     * in which case true is immediately returned.
9413     */
9414    public some(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
9415        for (let i = 0; i < this.lengthInt; ++i) {
9416            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
9417                return true
9418            }
9419        }
9420        return false
9421    }
9422
9423    /**
9424     * Determines whether the specified callback function returns true for any element of an array.
9425     *
9426     * @param predicate A function that accepts two arguments.
9427     * The some method calls the predicate function for each element in the array
9428     * until the predicate returns a true or until the end of the array.
9429     *
9430     * @returns false unless predicate function returns true for an array element,
9431     * in which case true is immediately returned.
9432     */
9433    public some(predicate: (element: BigInt, index: number) => boolean): boolean {
9434        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element, index as number))
9435    }
9436
9437    /**
9438     * Determines whether the specified callback function returns true for any element of an array.
9439     *
9440     * @param predicate A function that accepts no arguments.
9441     * The some method calls the predicate function for each element in the array
9442     * until the predicate returns a true or until the end of the array.
9443     *
9444     * @returns false unless predicate function returns true for an array element,
9445     * in which case true is immediately returned.
9446     */
9447    public some(predicate: () => boolean): boolean {
9448        return this.some((element: BigInt, index: number, array: BigInt64Array): boolean => predicate())
9449    }
9450
9451    /**
9452     * Calls the specified callback function for all the elements in an array.
9453     * The return value of the callback function is the accumulated result,
9454     * and is provided as an argument in the next call to the callback function.
9455     *
9456     * @param callbackfn A function that accepts four arguments.
9457     * The reduce method calls the callbackfn function one time for each element in the array.
9458     *
9459     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9460     * The first call to the callbackfn function provides this value as an argument.
9461     *
9462     * @returns The value that results from running the callback function to completion over the entire typed array.
9463     */
9464    public reduce<U = BigInt>(
9465                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
9466                initialValue: U): U {
9467        let accumulatedValue = initialValue
9468        for (let i = 0; i < this.lengthInt; ++i) {
9469            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9470        }
9471        return accumulatedValue
9472    }
9473
9474    /**
9475     * Calls the specified callback function for all the elements in an array.
9476     * The return value of the callback function is the accumulated result,
9477     * and is provided as an argument in the next call to the callback function.
9478     *
9479     * @param callbackfn A function that accepts three arguments.
9480     * The reduce method calls the callbackfn function one time for each element in the array.
9481     *
9482     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9483     * The first call to the callbackfn function provides this value as an argument.
9484     *
9485     * @returns The value that results from running the callback function to completion over the entire typed array.
9486     */
9487    public reduce<U = BigInt>(
9488                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number) => U,
9489                initialValue: U): U {
9490        return this.reduce(
9491                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9492                        callbackfn(prevVal, currVal, currIndex), initialValue)
9493    }
9494
9495    /**
9496     * Calls the specified callback function for all the elements in an array.
9497     * The return value of the callback function is the accumulated result,
9498     * and is provided as an argument in the next call to the callback function.
9499     *
9500     * @param callbackfn A function that accepts two arguments.
9501     * The reduce method calls the callbackfn function one time for each element in the array.
9502     *
9503     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9504     * The first call to the callbackfn function provides this value as an argument.
9505     *
9506     * @returns The value that results from running the callback function to completion over the entire typed array.
9507     */
9508    public reduce<U = BigInt>(
9509                callbackfn: (previousValue: U, currentValue: BigInt) => U,
9510                initialValue: U): U {
9511        return this.reduce(
9512                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9513                        callbackfn(prevVal, currVal), initialValue)
9514    }
9515
9516    /**
9517     * Calls the specified callback function for all the elements in an array.
9518     * The return value of the callback function is the accumulated result,
9519     * and is provided as an argument in the next call to the callback function.
9520     *
9521     * @param callbackfn A function that accepts one argument
9522     * The reduce method calls the callbackfn function one time for each element in the array.
9523     *
9524     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9525     * The first call to the callbackfn function provides this value as an argument.
9526     *
9527     * @returns The value that results from running the callback function to completion over the entire typed array.
9528     */
9529    public reduce<U = BigInt>(
9530                callbackfn: (previousValue: U) => U,
9531                initialValue: U): U {
9532        return this.reduce(
9533                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9534                        callbackfn(prevVal), initialValue)
9535    }
9536
9537    /**
9538     * Calls the specified callback function for all the elements in an array.
9539     * The return value of the callback function is the accumulated result,
9540     * and is provided as an argument in the next call to the callback function.
9541     *
9542     * @param callbackfn A function that accepts no arguments
9543     * The reduce method calls the callbackfn function one time for each element in the array.
9544     *
9545     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9546     * The first call to the callbackfn function provides this value as an argument.
9547     *
9548     * @returns The value that results from running the callback function to completion over the entire typed array.
9549     */
9550    public reduce<U = BigInt>(
9551                callbackfn: () => U,
9552                initialValue: U): U {
9553        return this.reduce(
9554                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9555                        callbackfn(), initialValue)
9556    }
9557
9558    /**
9559     * Calls the specified callback function for all the elements in an array.
9560     * The return value of the callback function is the accumulated result,
9561     * and is provided as an argument in the next call to the callback function.
9562     *
9563     * @param callbackfn A function that accepts four arguments.
9564     * The reduce method calls the callbackfn function one time for each element in the array.
9565     * The first call to the callbackfn function provides array first element value as an argument
9566     *
9567     * @returns The value that results from running the callback function to completion over the entire typed array.
9568     * calling reduce method on an empty array without an initial value creates a TypeError
9569     */
9570    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
9571        if (this.lengthInt == 0) {
9572            throw new TypeError("Reduce of empty array with no initial value")
9573        }
9574
9575        let accumulatedValue = new BigInt(this.getUnsafe(0))
9576        for (let i = 1; i < this.lengthInt; ++i) {
9577            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9578        }
9579        return accumulatedValue
9580    }
9581
9582    /**
9583     * Calls the specified callback function for all the elements in an array.
9584     * The return value of the callback function is the accumulated result,
9585     * and is provided as an argument in the next call to the callback function.
9586     *
9587     * @param callbackfn A function that accepts three arguments.
9588     * The reduce method calls the callbackfn function one time for each element in the array.
9589     * The first call to the callbackfn function provides array first element value as an argument
9590     *
9591     * @returns The value that results from running the callback function to completion over the entire typed array.
9592     * calling reduce method on an empty array without an initial value creates a TypeError
9593     */
9594    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number) => BigInt): BigInt {
9595        return this.reduce(
9596                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9597                        callbackfn(prevVal, currVal, currIndex))
9598    }
9599
9600    /**
9601     * Calls the specified callback function for all the elements in an array.
9602     * The return value of the callback function is the accumulated result,
9603     * and is provided as an argument in the next call to the callback function.
9604     *
9605     * @param callbackfn A function that accepts two arguments.
9606     * The reduce method calls the callbackfn function one time for each element in the array.
9607     * The first call to the callbackfn function provides array first element value as an argument
9608     *
9609     * @returns The value that results from running the callback function to completion over the entire typed array.
9610     * calling reduce method on an empty array without an initial value creates a TypeError
9611     */
9612    public reduce(callbackfn: (previousValue: BigInt, currentValue: BigInt) => BigInt): BigInt {
9613        return this.reduce(
9614                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9615                        callbackfn(prevVal, currVal))
9616    }
9617
9618    /**
9619     * Calls the specified callback function for all the elements in an array.
9620     * The return value of the callback function is the accumulated result,
9621     * and is provided as an argument in the next call to the callback function.
9622     *
9623     * @param callbackfn A function that accepts one argument.
9624     * The reduce method calls the callbackfn function one time for each element in the array.
9625     * The first call to the callbackfn function provides array first element value as an argument
9626     *
9627     * @returns The value that results from running the callback function to completion over the entire typed array.
9628     * calling reduce method on an empty array without an initial value creates a TypeError
9629     */
9630    public reduce(callbackfn: (previousValue: BigInt) => BigInt): BigInt {
9631        return this.reduce(
9632                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9633                        callbackfn(prevVal))
9634    }
9635
9636    /**
9637     * Calls the specified callback function for all the elements in an array.
9638     * The return value of the callback function is the accumulated result,
9639     * and is provided as an argument in the next call to the callback function.
9640     *
9641     * @param callbackfn A function that accepts no arguments.
9642     * The reduce method calls the callbackfn function one time for each element in the array.
9643     * The first call to the callbackfn function provides array first element value as an argument
9644     *
9645     * @returns The value that results from running the callback function to completion over the entire typed array.
9646     * calling reduce method on an empty array without an initial value creates a TypeError
9647     */
9648    public reduce(callbackfn: () => BigInt): BigInt {
9649        return this.reduce(
9650                (prevVal: BigInt, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9651                        callbackfn())
9652    }
9653
9654
9655    /**
9656     * Calls the specified callback function for all the elements in an array, in descending order.
9657     * The return value of the callback function is the accumulated result,
9658     * and is provided as an argument in the next call to the callback function.
9659     *
9660     * @param callbackfn A function that accepts four arguments.
9661     * The reduceRight method calls the callbackfn function one time for each element in the array.
9662     *
9663     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9664     * The first call to the callbackfn function provides this value as an argument.
9665     *
9666     * @returns The value that results from running the callback function to completion over the entire typed array.
9667     */
9668    public reduceRight<U = BigInt>(
9669                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => U,
9670                initialValue: U): U {
9671        let accumulatedValue = initialValue
9672        for (let i = this.lengthInt - 1; i >= 0; --i) {
9673            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9674        }
9675        return accumulatedValue
9676    }
9677
9678    /**
9679     * Calls the specified callback function for all the elements in an array, in descending order.
9680     * The return value of the callback function is the accumulated result,
9681     * and is provided as an argument in the next call to the callback function.
9682     *
9683     * @param callbackfn A function that accepts three arguments.
9684     * The reduceRight method calls the callbackfn function one time for each element in the array.
9685     *
9686     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9687     * The first call to the callbackfn function provides this value as an argument.
9688     *
9689     * @returns The value that results from running the callback function to completion over the entire typed array.
9690     */
9691    public reduceRight<U = BigInt>(
9692                callbackfn: (previousValue: U, currentValue: BigInt, currentIndex: number) => U,
9693                initialValue: U): U {
9694        return this.reduceRight(
9695                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9696                        callbackfn(prevVal, currVal, currIndex), initialValue)
9697    }
9698
9699    /**
9700     * Calls the specified callback function for all the elements in an array, in descending order.
9701     * The return value of the callback function is the accumulated result,
9702     * and is provided as an argument in the next call to the callback function.
9703     *
9704     * @param callbackfn A function that accepts two arguments.
9705     * The reduceRight method calls the callbackfn function one time for each element in the array.
9706     *
9707     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9708     * The first call to the callbackfn function provides this value as an argument.
9709     *
9710     * @returns The value that results from running the callback function to completion over the entire typed array.
9711     */
9712    public reduceRight<U = BigInt>(
9713                callbackfn: (previousValue: U, currentValue: BigInt) => U,
9714                initialValue: U): U {
9715        return this.reduceRight(
9716                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9717                        callbackfn(prevVal, currVal), initialValue)
9718    }
9719
9720    /**
9721     * Calls the specified callback function for all the elements in an array, in descending order.
9722     * The return value of the callback function is the accumulated result,
9723     * and is provided as an argument in the next call to the callback function.
9724     *
9725     * @param callbackfn A function that accepts one argument.
9726     * The reduceRight method calls the callbackfn function one time for each element in the array.
9727     *
9728     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9729     * The first call to the callbackfn function provides this value as an argument.
9730     *
9731     * @returns The value that results from running the callback function to completion over the entire typed array.
9732     */
9733    public reduceRight<U = BigInt>(
9734                callbackfn: (previousValue: U) => U,
9735                initialValue: U): U {
9736        return this.reduceRight(
9737                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9738                        callbackfn(prevVal), initialValue)
9739    }
9740
9741    /**
9742     * Calls the specified callback function for all the elements in an array, in descending order.
9743     * The return value of the callback function is the accumulated result,
9744     * and is provided as an argument in the next call to the callback function.
9745     *
9746     * @param callbackfn A function that accepts no arguments.
9747     * The reduceRight method calls the callbackfn function one time for each element in the array.
9748     *
9749     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
9750     * The first call to the callbackfn function provides this value as an argument.
9751     *
9752     * @returns The value that results from running the callback function to completion over the entire typed array.
9753     */
9754    public reduceRight<U = BigInt>(
9755                callbackfn: () => U,
9756                initialValue: U): U {
9757        return this.reduceRight(
9758                (prevVal: U, currVal: BigInt, currIndex: number, array: BigInt64Array) =>
9759                        callbackfn(), initialValue)
9760    }
9761
9762    /**
9763     * Calls the specified callback function for all the elements in an array, in descending order.
9764     * The return value of the callback function is the accumulated result,
9765     * and is provided as an argument in the next call to the callback function.
9766     *
9767     * @param callbackfn A function that accepts four arguments.
9768     * The reduceRight method calls the callbackfn function one time for each element in the array.
9769     * The first call to the callbackfn function provides array last element value as an argument
9770     *
9771     * @returns The value that results from running the callback function to completion over the entire typed array.
9772     * calling reduceRight method on an empty array without an initial value creates a TypeError
9773     */
9774    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number, array: BigInt64Array) => BigInt): BigInt {
9775        if (this.lengthInt == 0) {
9776            throw new TypeError("Reduce of empty array with no initial value")
9777        }
9778
9779        let accumulatedValue: BigInt = new BigInt(this.getUnsafe(this.lengthInt - 1))
9780        for (let i = this.lengthInt - 2; i >= 0; --i) {
9781            accumulatedValue = callbackfn(accumulatedValue, new BigInt(this.getUnsafe(i)), i as number, this)
9782        }
9783        return accumulatedValue
9784    }
9785
9786    /**
9787     * Calls the specified callback function for all the elements in an array, in descending order.
9788     * The return value of the callback function is the accumulated result,
9789     * and is provided as an argument in the next call to the callback function.
9790     *
9791     * @param callbackfn A function that accepts three arguments.
9792     * The reduceRight method calls the callbackfn function one time for each element in the array.
9793     * The first call to the callbackfn function provides array last element value as an argument
9794     *
9795     * @returns The value that results from running the callback function to completion over the entire typed array.
9796     * calling reduceRight method on an empty array without an initial value creates a TypeError
9797     */
9798    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt, currentIndex: number) => BigInt): BigInt {
9799        return this.reduceRight(
9800                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
9801                        callbackfn(prevValue, currValue, currIndex))
9802    }
9803
9804    /**
9805     * Calls the specified callback function for all the elements in an array, in descending order.
9806     * The return value of the callback function is the accumulated result,
9807     * and is provided as an argument in the next call to the callback function.
9808     *
9809     * @param callbackfn A function that accepts two arguments.
9810     * The reduceRight method calls the callbackfn function one time for each element in the array.
9811     * The first call to the callbackfn function provides array last element value as an argument
9812     *
9813     * @returns The value that results from running the callback function to completion over the entire typed array.
9814     * calling reduceRight method on an empty array without an initial value creates a TypeError
9815     */
9816    public reduceRight(callbackfn: (previousValue: BigInt, currentValue: BigInt) => BigInt): BigInt {
9817        return this.reduceRight(
9818                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
9819                        callbackfn(prevValue, currValue))
9820    }
9821
9822    /**
9823     * Calls the specified callback function for all the elements in an array, in descending order.
9824     * The return value of the callback function is the accumulated result,
9825     * and is provided as an argument in the next call to the callback function.
9826     *
9827     * @param callbackfn A function that accepts one argument.
9828     * The reduceRight method calls the callbackfn function one time for each element in the array.
9829     * The first call to the callbackfn function provides array last element value as an argument
9830     *
9831     * @returns The value that results from running the callback function to completion over the entire typed array.
9832     * calling reduceRight method on an empty array without an initial value creates a TypeError
9833     */
9834    public reduceRight(callbackfn: (previousValue: BigInt) => BigInt): BigInt {
9835        return this.reduceRight(
9836                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
9837                        callbackfn(prevValue))
9838    }
9839
9840    /**
9841     * Calls the specified callback function for all the elements in an array, in descending order.
9842     * The return value of the callback function is the accumulated result,
9843     * and is provided as an argument in the next call to the callback function.
9844     *
9845     * @param callbackfn A function that accepts no arguments.
9846     * The reduceRight method calls the callbackfn function one time for each element in the array.
9847     * The first call to the callbackfn function provides array last element value as an argument
9848     *
9849     * @returns The value that results from running the callback function to completion over the entire typed array.
9850     * calling reduceRight method on an empty array without an initial value creates a TypeError
9851     */
9852    public reduceRight(callbackfn: () => BigInt): BigInt {
9853        return this.reduceRight(
9854                (prevValue: BigInt, currValue: BigInt, currIndex: number, array: BigInt64Array) =>
9855                        callbackfn())
9856    }
9857
9858   /**
9859    * Creates a new BigInt64Array using fn(arr[i]) over all elements of current BigInt64Array.
9860    *
9861    * @param fn a function to apply for each element of current BigInt64Array
9862    *
9863    * @returns a new BigInt64Array where for each element from current BigInt64Array fn was applied
9864    */
9865    public map(fn: (val: BigInt, index: number) => BigInt): BigInt64Array {
9866        let resBuf = new ArrayBuffer(this.lengthInt * BigInt64Array.BYTES_PER_ELEMENT as int)
9867        let res = new BigInt64Array(resBuf, 0, resBuf.getByteLength() / BigInt64Array.BYTES_PER_ELEMENT as int)
9868        for (let i = 0; i < this.lengthInt; ++i) {
9869            res.set(i, fn(new BigInt(this.getUnsafe(i)), i as number).getLong())
9870        }
9871        return res
9872    }
9873
9874    /**
9875     * Determines whether the specified callback function returns true for all elements of an array.
9876     *
9877     * @param predicate A function that accepts three arguments.
9878     * The every method calls the predicate function for each element in the array until the predicate returns a false,
9879     * or until the end of the array.
9880     *
9881     * @returns true unless predicate function returns a false for an array element,
9882     * in which case false is immediately returned.
9883     */
9884    public every(predicate: (element: BigInt, index: number, array: BigInt64Array) => boolean): boolean {
9885        for (let i = 0; i < this.lengthInt; ++i) {
9886            if (!predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
9887                return false
9888            }
9889        }
9890        return true
9891    }
9892
9893    /**
9894     * Determines whether the specified callback function returns true for all elements of an array.
9895     *
9896     * @param predicate A function that accepts two arguments.
9897     * The every method calls the predicate function for each element in the array until the predicate returns a false,
9898     * or until the end of the array.
9899     *
9900     * @returns true unless predicate function returns a false for an array element,
9901     * in which case false is immediately returned.
9902     */
9903    public every(predicate: (element: BigInt, index: number) => boolean): boolean {
9904        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate(element, index))
9905    }
9906
9907    /**
9908     * Determines whether the specified callback function returns true for all elements of an array.
9909     *
9910     * @param predicate A function that accepts no arguments.
9911     * The every method calls the predicate function for each element in the array until the predicate returns a false,
9912     * or until the end of the array.
9913     *
9914     * @returns true unless predicate function returns a false for an array element,
9915     * in which case false is immediately returned.
9916     */
9917    public every(predicate: () => boolean): boolean {
9918        return this.every((element: BigInt, index: number, array: BigInt64Array): boolean => predicate())
9919    }
9920
9921    /**
9922     * Creates a new BigInt64Array from current BigInt64Array based on a condition fn.
9923     *
9924     * @param fn the condition to apply for each element
9925     *
9926     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
9927     */
9928    public filter(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): BigInt64Array {
9929        let markers = new boolean[this.lengthInt]
9930        let resLen = 0
9931        for (let i = 0; i < this.lengthInt; ++i) {
9932            markers[i] = fn(new BigInt(this.getUnsafe(i)), i as number, this)
9933            if (markers[i]) {
9934                ++resLen
9935            }
9936        }
9937        let resBuf = new ArrayBuffer(resLen * BigInt64Array.BYTES_PER_ELEMENT as int)
9938        let res = new BigInt64Array(resBuf, 0)
9939        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
9940            if (markers[i]) {
9941                res.set(j, this.getUnsafe(i))
9942                ++j
9943            }
9944        }
9945        return res
9946    }
9947
9948    /**
9949     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
9950     *
9951     * @param fn the condition to apply for each element
9952     *
9953     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
9954     */
9955    public filter(fn: (val: BigInt, index: number) => boolean): BigInt64Array {
9956        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9957            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val, index as number) }
9958        return this.filter(newF)
9959    }
9960
9961    /**
9962     * creates a new BigInt64Array from current BigInt64Array based on a condition fn
9963     *
9964     * @param fn the condition to apply for each element
9965     *
9966     * @returns a new BigInt64Array with elements from current BigInt64Array that satisfy condition fn
9967     */
9968    public filter(fn: () => boolean): BigInt64Array {
9969        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
9970            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn() }
9971        return this.filter(newF)
9972    }
9973
9974    /**
9975     * Returns the value of the first element in the array where predicate is true, and undefined
9976     * otherwise
9977     *
9978     * @param predicate find calls predicate once for each element of the array, in ascending
9979     * order, until it finds one where predicate returns true. If such an element is found, find
9980     * immediately returns that element value. Otherwise, find returns undefined
9981     *
9982     * @returns BigInt | undefined
9983     */
9984    public find(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): BigInt | undefined {
9985        for (let i = 0; i < this.lengthInt; ++i) {
9986            let val = this.getUnsafe(i)
9987            if (predicate(new BigInt(val), i as number, this)) {
9988                return new BigInt(val)
9989            }
9990        }
9991        return undefined
9992    }
9993
9994    /**
9995     * Returns the value of the first element in the array where predicate is true, and undefined
9996     * otherwise
9997     *
9998     * @param predicate find calls predicate once for each element of the array, in ascending
9999     * order, until it finds one where predicate returns true. If such an element is found, find
10000     * immediately returns that element value. Otherwise, find returns undefined
10001     *
10002     * @returns BigInt | undefined
10003     */
10004    public find(predicate: (value: BigInt, index: number) => boolean): BigInt | undefined {
10005        return this.find((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value, index))
10006    }
10007
10008    /**
10009     * Returns the index of the first element in the array where predicate is true, and -1
10010     * otherwise
10011     *
10012     * @param predicate find calls predicate once for each element of the array, in ascending
10013     * order, until it finds one where predicate returns true. If such an element is found,
10014     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10015     *
10016     * @returns number
10017     */
10018    public findIndex(predicate: (value: BigInt, index: number, obj: BigInt64Array) => boolean): number {
10019        for (let i = 0; i < this.lengthInt; ++i) {
10020            if (predicate(new BigInt(this.getUnsafe(i)), i as number, this)) {
10021                return i as number
10022            }
10023        }
10024        return -1 as number
10025    }
10026
10027    /**
10028     * Returns the index of the first element in the array where predicate is true, and -1
10029     * otherwise
10030     *
10031     * @param predicate find calls predicate once for each element of the array, in ascending
10032     * order, until it finds one where predicate returns true. If such an element is found,
10033     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10034     *
10035     * @returns number
10036     */
10037    public findIndex(predicate: (value: BigInt, index: number) => boolean): number {
10038        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate(value, index as number)) as number
10039    }
10040
10041    /**
10042     * Returns the index of the first element in the array where predicate is true, and -1
10043     * otherwise
10044     *
10045     * @param predicate find calls predicate once for each element of the array, in ascending
10046     * order, until it finds one where predicate returns true. If such an element is found,
10047     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
10048     *
10049     * @returns number
10050     */
10051    public findIndex(predicate: () => boolean): number {
10052        return this.findIndex((value: BigInt, index: number, obj: BigInt64Array): boolean => predicate()) as number
10053    }
10054
10055    /**
10056     * Finds the last element in the BigInt64Array that satisfies the condition
10057     *
10058     * @param fn condition
10059     *
10060     * @returns the last element that satisfies fn
10061     */
10062    public findLast(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): long {
10063        for (let i = this.lengthInt - 1; i >= 0; --i) {
10064            let val = this.getUnsafe(i)
10065            if (fn(new BigInt(val), i as number, this)) {
10066                return val
10067            }
10068        }
10069        throw new Error("BigInt64Array.findLast: not implemented if an element was not found")
10070    }
10071
10072    /**
10073     * Finds the last element in the BigInt64Array that satisfies the condition
10074     *
10075     * @param fn condition
10076     *
10077     * @returns the last element that satisfies fn
10078     */
10079    public findLast(fn: (val: BigInt, index: number) => boolean): long {
10080        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10081            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(new BigInt(val), index as number) }
10082        return this.findLast(newF)
10083    }
10084
10085    /**
10086     * Finds an index of the last element in the BigInt64Array that satisfies the condition
10087     *
10088     * @param fn condition
10089     *
10090     * @returns the index of the last element that satisfies fn, -1 otherwise
10091     */
10092    public findLastIndex(fn: (val: BigInt, index: number, array: BigInt64Array) => boolean): number {
10093        for (let i = this.lengthInt - 1; i >= 0; --i) {
10094            let val = this.getUnsafe(i)
10095            if (fn(new BigInt(val), i as number, this)) {
10096                return i
10097            }
10098        }
10099        return -1 as number
10100    }
10101
10102    /**
10103     * Finds an index of the last element in the BigInt64Array that satisfies the condition
10104     *
10105     * @param fn condition
10106     *
10107     * @returns the index of the last element that satisfies fn, -1 otherwise
10108     */
10109    public findLastIndex(fn: (val: BigInt, index: number) => boolean): number {
10110        let newF: (val: BigInt, index: number, array: BigInt64Array) => boolean =
10111            (val: BigInt, index: number, array: BigInt64Array): boolean => { return fn(val, index as number) }
10112        return this.findLastIndex(newF) as number
10113    }
10114
10115    /**
10116     * Performs the specified action for each element in BigInt64Array
10117     *
10118     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10119     * callbackfn function one time for each element in the array.
10120     *
10121     * @returns None
10122     */
10123    public forEach(callbackfn: (value: BigInt, index: number, array: BigInt64Array) => void): void {
10124        for (let i = 0; i < this.lengthInt; ++i) {
10125            callbackfn(new BigInt(this.getUnsafe(i)), i as number, this)
10126        }
10127    }
10128
10129    /**
10130     * Performs the specified action for each element in BigInt64Array
10131     *
10132     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10133     * callbackfn function one time for each element in the array.
10134     *
10135     * @returns None
10136     */
10137    public forEach(callbackfn: (value: BigInt, index: number) => void): void {
10138        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn(value, index))
10139    }
10140
10141    /**
10142     * Performs the specified action for each element in BigInt64Array
10143     *
10144     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
10145     * callbackfn function one time for each element in the array.
10146     *
10147     * @returns None
10148     */
10149    public forEach(callbackfn: () => void): void {
10150        this.forEach((value: BigInt, index: number, array: BigInt64Array): void => callbackfn())
10151    }
10152
10153    /**
10154     * Returns the object itself
10155     *
10156     * @returns BigInt64Array
10157     */
10158    public valueOf(): BigInt64Array {
10159        return this
10160    }
10161
10162    internal getUnsafe(index: int): long {
10163        let byteIndex = index * BigInt64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
10164        let res : long = 0
10165        let byteVal : long
10166        if (IS_LITTLE_ENDIAN) {
10167            if (this.buffer instanceof ArrayBuffer) {
10168                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10169                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
10170                    byteVal &= 0xff
10171                    res = (res | byteVal << (8 * i)) as long
10172                }
10173            } else if (this.buffer instanceof SharedArrayBuffer) {
10174                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10175                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
10176                    byteVal &= 0xff
10177                    res = (res | byteVal << (8 * i)) as long
10178                }
10179            } else {
10180                throw new Error("unexpected type of ArrayBufferLike")
10181            }
10182            return res
10183        } else {
10184            if (this.buffer instanceof ArrayBuffer) {
10185                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10186                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 7 - i)
10187                    byteVal &= 0xff
10188                    res = (res | byteVal << (8 * i)) as long
10189                }
10190            } else if (this.buffer instanceof SharedArrayBuffer) {
10191                for (let i: int = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10192                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 7 - i)
10193                    byteVal &= 0xff
10194                    res = (res | byteVal << (8 * i)) as long
10195                }
10196            } else {
10197                throw new Error("unexpected type of ArrayBufferLike")
10198            }
10199            return res
10200        }
10201    }
10202
10203    internal setUnsafe(insertPos: int, val: long): void {
10204        let startByte = insertPos * BigInt64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
10205        let bits = val
10206        if (IS_LITTLE_ENDIAN) {
10207            if (this.buffer instanceof ArrayBuffer) {
10208                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10209                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10210                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
10211                }
10212            } else if (this.buffer instanceof SharedArrayBuffer) {
10213                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; ++i) {
10214                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10215                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
10216                }
10217            } else {
10218                throw new Error("unexpected type of ArrayBufferLike")
10219            }
10220        } else {
10221            if (this.buffer instanceof ArrayBuffer) {
10222                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; i++) {
10223                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10224                    (this.buffer as ArrayBuffer).set(startByte + 7 - i, byteVal)
10225                }
10226            } else if (this.buffer instanceof SharedArrayBuffer) {
10227                for (let i = 0; i < BigInt64Array.BYTES_PER_ELEMENT as int; i++) {
10228                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
10229                    (this.buffer as SharedArrayBuffer).set(startByte + 7 - i, byteVal)
10230                }
10231            } else {
10232                throw new Error("unexpected type of ArrayBufferLike")
10233            }
10234        }
10235    }
10236
10237    /** Underlying ArrayBufferLike */
10238    public readonly buffer: ArrayBufferLike
10239
10240    /** Byte offset within the underlying ArrayBufferLike */
10241    public readonly byteOffset: number
10242
10243    /** Number of bytes used */
10244    public readonly byteLength: number
10245
10246    /** String \"BigInt64Array\" */
10247    public readonly name = "BigInt64Array"
10248}
10249
10250class Float32ArrayIteratorKeys implements IterableIterator<number> {
10251    private length: int
10252    private idx: int = 0
10253
10254    constructor(parent: Float32Array) {
10255        this.length = parent.length as int
10256    }
10257
10258    public override $_iterator(): IterableIterator<number> {
10259        return this
10260    }
10261
10262    override next(): IteratorResult<number> {
10263        if (this.idx < 0 || this.idx >= this.length) {
10264            return new IteratorResult<number>()
10265        }
10266        return new IteratorResult<number>(false, this.idx++ as number)
10267    }
10268}
10269
10270class Float32ArrayIterator implements IterableIterator<Number> {
10271    private parent: Float32Array
10272    private idx: int = 0
10273
10274    constructor(parent: Float32Array) {
10275        this.parent = parent
10276    }
10277
10278    public override $_iterator(): IterableIterator<Number> {
10279        return this
10280    }
10281
10282    override next(): IteratorResult<Number> {
10283        if (this.idx < 0 || this.idx >= this.parent.length as int) {
10284            return new IteratorResult<Number>()
10285        }
10286        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
10287    }
10288}
10289
10290class Float32ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
10291    private parent: Float32Array
10292    private idx: int = 0
10293
10294    constructor(parent: Float32Array) {
10295        this.parent = parent
10296    }
10297
10298    public override $_iterator(): IterableIterator<[Number, Number]> {
10299        return this
10300    }
10301
10302    override next(): IteratorResult<[Number, Number]> {
10303        if (this.idx < 0 || this.idx >= this.parent.length as int) {
10304            return new IteratorResult<[Number, Number]>()
10305        }
10306        return new IteratorResult<[Number, Number]>(
10307            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
10308        )
10309    }
10310}
10311
10312
10313/**
10314 * JS Float32Array API-compatible class
10315 */
10316export final class Float32Array implements Iterable<Number>, ArrayLike<Number> {
10317    public static readonly BYTES_PER_ELEMENT: number = 4
10318    internal readonly lengthInt: int
10319
10320    /**
10321     * Creates an empty Float32Array.
10322     */
10323    public constructor() {
10324        this(0 as int)
10325    }
10326
10327    /**
10328     * Creates an Float32Array with respect to data accessed via Iterable<Number> interface
10329     */
10330    public constructor(elements: Iterable<Number>) {
10331        // NOTE (ikorobkov): dealing with this overload is tricky
10332        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
10333        let arr = Array.from<Number>(elements)
10334        this.byteLength = arr.length * Float32Array.BYTES_PER_ELEMENT as int
10335        this.lengthInt = arr.length as int
10336        this.buffer = new ArrayBuffer(this.byteLength as int)
10337        this.byteOffset = 0
10338        for (let i: int = 0; i < this.lengthInt; ++i) {
10339            this.setUnsafe(i, arr.$_get(i).floatValue())
10340        }
10341    }
10342
10343    /**
10344     * Creates an Float32Array with respect to data, byteOffset and length.
10345     *
10346     * @param buf data initializer
10347     *
10348     * @param byteOffset byte offset from begin of the buf
10349     *
10350     * @param length size of elements of type float in newly created Float32Array
10351     */
10352    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
10353        let intByteOffset: int = 0
10354        if (byteOffset != undefined) {
10355            intByteOffset = byteOffset.intValue()
10356            if (intByteOffset < 0) {
10357                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
10358            }
10359        }
10360        let intByteLength: int
10361        if (buf instanceof ArrayBuffer) {
10362            intByteLength = (buf as ArrayBuffer).getByteLength()
10363        } else if (buf instanceof SharedArrayBuffer) {
10364            intByteLength = (buf as SharedArrayBuffer).getByteLength()
10365        } else {
10366            throw new Error("unexpected type of ArrayBufferLike")
10367        }
10368        intByteLength = intByteLength - intByteOffset
10369        if (intByteLength < 0) {
10370            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
10371        }
10372
10373        if (intByteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10374            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10375        }
10376        if (intByteOffset % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10377            throw new RangeError("byteOffset should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10378        }
10379
10380        let intLength: int
10381        if (length != undefined) {
10382            intLength = length.intValue()
10383            if (intLength > intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
10384                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
10385            }
10386        } else {
10387            intLength = intByteLength / Float32Array.BYTES_PER_ELEMENT as int
10388        }
10389        if (intLength < 0) {
10390            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
10391        }
10392        if (intLength < intByteLength / Float32Array.BYTES_PER_ELEMENT as int) {
10393            intByteLength = intLength * Float32Array.BYTES_PER_ELEMENT as int
10394        }
10395        this.byteLength = intByteLength
10396        this.byteOffset = intByteOffset
10397        this.lengthInt = intLength
10398        this.buffer = buf
10399    }
10400
10401    /**
10402     * Creates an Float32Array with respect to data, byteOffset and length.
10403     *
10404     * @param buf data initializer
10405     *
10406     * @param byteOffset byte offset from begin of the buf
10407     *
10408     * @param length size of elements of type float in newly created Float32Array
10409     */
10410    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
10411        this(buf, byteOffset, undefined)
10412    }
10413
10414    /**
10415     * Creates an Float32Array with respect to data, byteOffset and length.
10416     *
10417     * @param buf data initializer
10418     *
10419     * @param byteOffset byte offset from begin of the buf
10420     *
10421     * @param length size of elements of type float in newly created Float32Array
10422     */
10423    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
10424        this(buf, new Number(byteOffset), new Number(length))
10425    }
10426
10427    /**
10428     * Creates an Float32Array with respect to data, byteOffset and length.
10429     *
10430     * @param buf data initializer
10431     *
10432     * @param byteOffset byte offset from begin of the buf
10433     *
10434     * @param length size of elements of type float in newly created Float32Array
10435     */
10436    public constructor(buf: ArrayBufferLike, byteOffset: number) {
10437        this(buf, new Number(byteOffset), undefined)
10438    }
10439
10440    /**
10441     * Creates an Float32Array with respect to data, byteOffset and length.
10442     *
10443     * @param buf data initializer
10444     *
10445     * @param byteOffset byte offset from begin of the buf
10446     *
10447     * @param length size of elements of type float in newly created Float32Array
10448     */
10449    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
10450        this(buf, new Number(byteOffset), new Number(length))
10451    }
10452
10453    /**
10454     * Creates an Float32Array with respect to buf and byteOffset.
10455     *
10456     * @param buf data initializer
10457     *
10458     * @param byteOffset byte offset from begin of the buf
10459     */
10460    public constructor(buf: ArrayBufferLike, byteOffset: int) {
10461        this(buf, new Number(byteOffset), undefined)
10462    }
10463
10464    /**
10465     * Creates an Float32Array with respect to buf.
10466     *
10467     * @param buf data initializer
10468     */
10469    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
10470        if (buf instanceof ArrayBuffer) {
10471            this.byteLength = (buf as ArrayBuffer).getByteLength()
10472            if (this.byteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10473               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10474            }
10475            this.lengthInt = this.byteLength / Float32Array.BYTES_PER_ELEMENT as int
10476            this.buffer = buf as ArrayBuffer
10477            this.byteOffset = 0
10478        } else if (buf instanceof SharedArrayBuffer) {
10479            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
10480            if (this.byteLength % Float32Array.BYTES_PER_ELEMENT as int != 0) {
10481               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 4 as Float32Array.BYTES_PER_ELEMENT")
10482            }
10483            this.lengthInt = this.byteLength / Float32Array.BYTES_PER_ELEMENT as int
10484            this.buffer = buf as SharedArrayBuffer
10485            this.byteOffset = 0
10486        } else if (buf instanceof ArrayLike) {
10487            // NOTE (ikorobkov): dealing with this overload is tricky
10488            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
10489            let arr = Array.from<Number>((buf as ArrayLike<Number>))
10490            this.byteLength = arr.length as int * Float32Array.BYTES_PER_ELEMENT as int
10491            this.lengthInt = arr.length as int
10492            this.buffer = new ArrayBuffer(this.byteLength as int)
10493            this.byteOffset = 0
10494            for (let i: int = 0; i < this.lengthInt; ++i) {
10495                this.setUnsafe(i, arr.$_get(i).floatValue())
10496            }
10497        } else {
10498            throw new Error("unexpected type of buf")
10499        }
10500    }
10501
10502    /**
10503     * Creates an Float32Array with respect to length.
10504     *
10505     * @param length data initializer
10506     */
10507    public constructor(length: int) {
10508        if (length < 0) {
10509            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
10510        }
10511        this.lengthInt = length
10512        this.byteLength = length * Float32Array.BYTES_PER_ELEMENT as int
10513        this.byteOffset = 0
10514        this.buffer = new ArrayBuffer(this.byteLength as int)
10515    }
10516
10517    /**
10518     * Creates an Float32Array with respect to length.
10519     *
10520     * @param length data initializer
10521     */
10522    public constructor(length: number) {
10523        this(length as int)
10524    }
10525
10526    /**
10527     * Creates a copy of Float32Array.
10528     *
10529     * @param other data initializer
10530     */
10531    public constructor(other: Float32Array) {
10532        if (other.buffer instanceof ArrayBuffer) {
10533            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
10534        } else if (other.buffer instanceof SharedArrayBuffer) {
10535            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
10536        } else {
10537            throw new Error("unexpected type of buffer")
10538        }
10539        this.byteLength = other.byteLength
10540        this.lengthInt = other.length as int
10541        this.byteOffset = 0
10542    }
10543
10544    /**
10545     * Creates an Float32Array from number[]
10546     */
10547    public constructor(numbers: number[]) {
10548        this(numbers.length)
10549        for (let i: int = 0; i < this.lengthInt; ++i) {
10550            this.setUnsafe(i, numbers[i] as float)
10551        }
10552    }
10553
10554    /**
10555     * Creates an Float32Array from int[]
10556     */
10557    public constructor(numbers: int[]) {
10558        this(numbers.length)
10559        for (let i: int = 0; i < this.lengthInt; ++i) {
10560            this.setUnsafe(i, numbers[i] as float)
10561        }
10562    }
10563
10564    /**
10565     * Assigns val as element on index.
10566     *
10567     * @param val value to set
10568     *
10569     * @param index index to change
10570     */
10571    public $_set(index: number, val: number): void {
10572        this.$_set(index as int, val)
10573    }
10574
10575    /**
10576     * Assigns val as element on index.
10577     *
10578     * @param val value to set
10579     *
10580     * @param index index to change
10581     */
10582    public $_set(index: int, val: number): void {
10583        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10584        if (index < 0 || index >= this.lengthInt) {
10585            throw new RangeError("invalid index")
10586        }
10587        this.setUnsafe(index, val as float)
10588    }
10589
10590    /**
10591     * Assigns val as element on index.
10592     *
10593     * @param val value to set
10594     *
10595     * @param index index to change
10596     */
10597    public $_set(index: number, val: int): void {
10598        this.$_set(index as int, val)
10599    }
10600
10601    /**
10602     * Assigns val as element on index.
10603     *
10604     * @param val value to set
10605     *
10606     * @param index index to change
10607     */
10608    public $_set(index: int, val: int): void {
10609        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10610        if (index < 0 || index >= this.lengthInt) {
10611            throw new RangeError("invalid index")
10612        }
10613        this.setUnsafe(index, val as float)
10614    }
10615
10616    /**
10617     * Assigns val as element on index.
10618     *
10619     * @param val value to set
10620     *
10621     * @param index index to change
10622     */
10623    public $_set(index: number, val: float): void {
10624        this.$_set(index as int, val)
10625    }
10626
10627    /**
10628     * Assigns val as element on index.
10629     *
10630     * @param val value to set
10631     *
10632     * @param index index to change
10633     */
10634    public $_set(index: int, val: float): void {
10635        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
10636        if (index < 0 || index >= this.lengthInt) {
10637            throw new RangeError("invalid index")
10638        }
10639        this.setUnsafe(index, val)
10640    }
10641
10642    /** Number of float stored in Float32Array */
10643    public get length(): number {
10644        return this.lengthInt
10645    }
10646
10647    /**
10648     * Returns an instance of number at passed index.
10649     *
10650     * @param index index to look at
10651     *
10652     * @returns a primitive at index
10653     */
10654    public override $_get(index: number): Number {
10655        return this.$_get(index as int) as Number
10656    }
10657
10658    /**
10659     * Returns an instance of number at passed index.
10660     *
10661     * @param index index to look at
10662     *
10663     * @returns a primitive at index
10664     */
10665    public $_get(index: int): number {
10666        if (index < 0 || index >= this.lengthInt) {
10667            throw new RangeError("invalid index")
10668        }
10669        return this.getUnsafe(index) as number
10670    }
10671
10672    /**
10673     * Returns an instance of primitive type at passed index.
10674     *
10675     * @param index index to look at
10676     *
10677     * @returns a primitive at index
10678     */
10679    public at(index: number): Number | undefined {
10680        return this.at(index as int)
10681    }
10682
10683    /**
10684     * Returns an instance of primitive type at passed index.
10685     *
10686     * @param index index to look at
10687     *
10688     * @returns a primitive at index
10689     */
10690    public at(index: int): Number | undefined {
10691        let k: int
10692        if (index >= 0) {
10693            k = index
10694        } else {
10695            k = this.lengthInt + index
10696        }
10697        if (k < 0 || k >= this.lengthInt) {
10698            return undefined
10699        }
10700        return new Number(this.getUnsafe(k))
10701    }
10702
10703    /**
10704     * Makes a copy of internal elements to targetPos from startPos to endPos.
10705     *
10706     * @param target insert index to place copied elements
10707     *
10708     * @param start start index to begin copy from
10709     *
10710     * @param end last index to end copy from, excluded
10711     *
10712     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10713     */
10714    public copyWithin(target: number, start: number, end?: number): Float32Array {
10715        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
10716    }
10717
10718    /**
10719     * Makes a copy of internal elements to targetPos from startPos to endPos.
10720     *
10721     * @param target insert index to place copied elements
10722     *
10723     * @param start start index to begin copy from
10724     *
10725     * @param end last index to end copy from, excluded
10726     *
10727     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10728     */
10729    public copyWithin(target: int, start: number, end?: number): Float32Array {
10730        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
10731    }
10732
10733    /**
10734     * Makes a copy of internal elements to targetPos from startPos to endPos.
10735     *
10736     * @param target insert index to place copied elements
10737     *
10738     * @param start start index to begin copy from
10739     *
10740     * @param end last index to end copy from, excluded
10741     *
10742     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10743     */
10744    public copyWithin(target: number, start: int, end?: number): Float32Array {
10745        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
10746    }
10747
10748    /**
10749     * Makes a copy of internal elements to targetPos from startPos to endPos.
10750     *
10751     * @param target insert index to place copied elements
10752     *
10753     * @param start start index to begin copy from
10754     *
10755     * @param end last index to end copy from, excluded
10756     *
10757     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10758     */
10759    public copyWithin(target: int, start: int, end?: number): Float32Array {
10760        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
10761    }
10762
10763    /**
10764     * Makes a copy of internal elements to targetPos from startPos to endPos.
10765     *
10766     * @param target insert index to place copied elements
10767     *
10768     * @param start start index to begin copy from
10769     *
10770     * @param end last index to end copy from, excluded
10771     *
10772     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
10773     */
10774    public copyWithin(target: int, start: int, end: int): Float32Array {
10775        let toPos = normalizeIndex(target, this.lengthInt)
10776        let fromPos = normalizeIndex(start, this.lengthInt)
10777        const finalPos = normalizeIndex(end, this.lengthInt)
10778        let count: int = finalPos - fromPos
10779        if (count > (this.lengthInt - toPos)) {
10780            count = this.lengthInt - toPos
10781        }
10782        let direction: int = 1
10783        if ((fromPos < toPos) && (toPos < fromPos + count)) {
10784            fromPos = fromPos + count - 1
10785            toPos   = toPos   + count - 1
10786            direction = -1
10787        }
10788        while (count > 0) {
10789            const value = this.getUnsafe(fromPos)
10790            this.setUnsafe(toPos, value)
10791            fromPos = fromPos + direction
10792            toPos = toPos + direction
10793            --count
10794        }
10795        return this
10796    }
10797
10798    /**
10799     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
10800     *
10801     * @param target insert index to place copied elements
10802     *
10803     * See rules of parameters normalization:
10804     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
10805     */
10806    public copyWithin(target: number): Float32Array {
10807        return this.copyWithin(target as int)
10808    }
10809
10810    /**
10811     * Makes a copy of internal elements to targetPos from begin to end of Float32Array.
10812     *
10813     * @param target insert index to place copied elements
10814     *
10815     * See rules of parameters normalization:
10816     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
10817     */
10818    public copyWithin(target: int): Float32Array {
10819        return this.copyWithin(target, 0, this.lengthInt)
10820    }
10821
10822    /**
10823     * Returns an array of key, value pairs for every entry in the Float32Array
10824     *
10825     * @returns key, value pairs for every entry in the array
10826     */
10827    public entries(): IterableIterator<[Number, Number]> {
10828        return new Float32ArrayIteratorEntries(this)
10829    }
10830
10831    /**
10832     * Fills the Float32Array with specified value
10833     *
10834     * @param value new valuy
10835     *
10836     * @returns modified Float32Array
10837     */
10838    public fill(value: number, start?: number, end?: number): this {
10839        this.fill(value as float, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
10840        return this
10841    }
10842
10843    /**
10844     * Fills the Float32Array with specified value
10845     *
10846     * @param value new valuy
10847     *
10848     * @returns modified Float32Array
10849     */
10850    public fill(value: number, start: int, end?: number): this {
10851        this.fill(value as float, start as int, asIntOrDefault(end, this.lengthInt))
10852        return this
10853    }
10854
10855    /**
10856     * Fills the Float32Array with specified value
10857     *
10858     * @param value new valuy
10859     *
10860     * @returns modified Float32Array
10861     */
10862    public fill(value: number, start: int, end: number): this {
10863        this.fill(value as float, start as int, end as int)
10864        return this
10865    }
10866
10867    /**
10868     * Fills the Float32Array with specified value
10869     *
10870     * @param value new valuy
10871     *
10872     * @returns modified Float32Array
10873     */
10874    public fill(value: number, start: number, end: int): this {
10875        this.fill(value as float, start as int, end as int)
10876        return this
10877    }
10878
10879    /**
10880     * Fills the Float32Array with specified value
10881     *
10882     * @param value new valuy
10883     *
10884     * @returns modified Float32Array
10885     */
10886    public fill(value: number, start: int, end: int): this {
10887        this.fill(value as float, start as int, end as int)
10888        return this
10889    }
10890
10891    /**
10892     * Fills the Float32Array with specified value
10893     *
10894     * @param value new valuy
10895     *
10896     * @returns modified Float32Array
10897     */
10898    public fill(value: float, start?: number, end?: number): this {
10899        this.fill(value, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
10900        return this
10901    }
10902
10903    /**
10904     * Fills the Float32Array with specified value
10905     *
10906     * @param value new valuy
10907     *
10908     * @returns modified Float32Array
10909     */
10910    public fill(value: float, start: int, end?: number): this {
10911        this.fill(value, start as int, asIntOrDefault(end, this.lengthInt))
10912        return this
10913    }
10914
10915    /**
10916     * Fills the Float32Array with specified value
10917     *
10918     * @param value new valuy
10919     *
10920     * @returns modified Float32Array
10921     */
10922    public fill(value: float, start: int, end: number): this {
10923        this.fill(value, start as int, end as int)
10924        return this
10925    }
10926
10927    /**
10928     * Fills the Float32Array with specified value
10929     *
10930     * @param value new valuy
10931     *
10932     * @returns modified Float32Array
10933     */
10934    public fill(value: float, start: number, end: int): this {
10935        this.fill(value, start as int, end as int)
10936        return this
10937    }
10938
10939    /**
10940     * Fills the Float32Array with specified value
10941     *
10942     * @param value new valuy
10943     *
10944     * @returns modified Float32Array
10945     */
10946    public fill(value: float, start: int, end: int): this {
10947        const k = normalizeIndex(start, this.lengthInt)
10948        const finalPos = normalizeIndex(end, this.lengthInt)
10949        for (let i: int = k; i < finalPos; ++i) {
10950            this.setUnsafe(i, value)
10951        }
10952        return this
10953    }
10954
10955    /**
10956     * Assigns val as element on insertPos.
10957     * @description Added to avoid (un)packing a single value into array to use overloaded set(float[], insertPos)
10958     *
10959     * @param val value to set
10960     *
10961     * @param insertPos index to change
10962     */
10963    public set(insertPos: number, val: number): void {
10964        this.$_set(insertPos, val)
10965    }
10966
10967    /**
10968     * Assigns val as element on insertPos.
10969     * @description Added to avoid (un)packing a single value into array to use overloaded set(float[], insertPos)
10970     *
10971     * @param val value to set
10972     *
10973     * @param insertPos index to change
10974     */
10975    public set(insertPos: int, val: float): void {
10976        this.$_set(insertPos, val)
10977    }
10978
10979    /**
10980     * Copies all elements of arr to the current Float32Array starting from insertPos.
10981     *
10982     * @param arr array to copy data from
10983     *
10984     * @param insertPos start index where data from arr will be inserted
10985     *
10986     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
10987     */
10988    public set(arr: number[], insertPos: number): void {
10989        const offset = insertPos as int
10990        if (offset < 0 || offset + arr.length > this.lengthInt) {
10991            throw new RangeError("offset is out of bounds")
10992        }
10993        for (let i = 0; i < arr.length as int; ++i) {
10994            this.setUnsafe(offset + i, arr[i] as float)
10995        }
10996    }
10997
10998    /**
10999     * Copies all elements of arr to the current Float32Array starting from insertPos.
11000     *
11001     * @param arr array to copy data from
11002     *
11003     * @param insertPos start index where data from arr will be inserted
11004     *
11005     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
11006     */
11007    public set(arr: float[], insertPos: int): void {
11008        const offset = insertPos as int
11009        if (offset < 0 || offset + arr.length > this.lengthInt) {
11010            throw new RangeError("offset is out of bounds")
11011        }
11012        for (let i = 0; i < arr.length as int; ++i) {
11013            this.setUnsafe(offset + i, arr[i])
11014        }
11015    }
11016
11017    /**
11018     * Copies all elements of arr to the current Float32Array.
11019     *
11020     * @param arr array to copy data from
11021     */
11022    public set(arr: number[]): void {
11023        this.set(arr, 0 as number)
11024    }
11025
11026    /**
11027     * Copies all elements of arr to the current Float32Array.
11028     *
11029     * @param arr array to copy data from
11030     */
11031    public set(arr: float[]): void {
11032        this.set(arr, 0 as int)
11033    }
11034
11035    /**
11036     * Copies elements from an ArrayLike object to the Float32Array.
11037     *
11038     * @param array An ArrayLike object containing the elements to copy.
11039     *
11040     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
11041     */
11042    public set(array: ArrayLike<number>, offset: number = 0): void {
11043        const insertPos = offset as int
11044        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
11045            throw new RangeError("offset is out of bounds")
11046        }
11047        for (let i = 0; i < array.length as int; ++i) {
11048            this.setUnsafe(insertPos + i, array[i] as float)
11049        }
11050    }
11051
11052    /**
11053     * Returns a new array from a set of elements.
11054     *
11055     * @param items a set of elements to include in the new array object.
11056     *
11057     * @returns new Float32Array
11058     */
11059    public static of(...items: number[]): Float32Array {
11060        let res = new Float32Array(items.length as int)
11061        for (let i: int = 0; i < items.length; i++) {
11062            res.setUnsafe(i, items[i] as float)
11063        }
11064        return res
11065    }
11066
11067    /**
11068     * Returns a new array from a set of elements.
11069     *
11070     * @param items a set of elements to include in the new array object.
11071     *
11072     * @returns new Float32Array
11073     */
11074    public static of(...items: int[]): Float32Array {
11075        let res = new Float32Array(items.length as int)
11076        for (let i: int = 0; i < items.length; i++) {
11077            res.setUnsafe(i, items[i] as float)
11078        }
11079        return res
11080    }
11081
11082    /**
11083     * Returns a new array from a set of elements.
11084     *
11085     * @param items a set of elements to include in the new array object.
11086     *
11087     * @returns new Float32Array
11088     */
11089    public static of(...items: float[]): Float32Array {
11090        let res = new Float32Array(items.length as int)
11091        for (let i: int = 0; i < items.length; i++) {
11092            res.setUnsafe(i, items[i])
11093        }
11094        return res
11095    }
11096
11097    /**
11098     * Returns a new array from a set of elements.
11099     *
11100     * @param items a set of elements to include in the new array object.
11101     *
11102     * @returns new Float32Array
11103     */
11104    public static of(): Float32Array {
11105        return new Float32Array(0 as int)
11106    }
11107
11108    /**
11109     * Creates an array from an array-like or iterable object.
11110     *
11111     * @param arrayLike An array-like or iterable object to convert to an array.
11112     *
11113     * @returns new Float32Array
11114     */
11115    public static from(arrayLike: ArrayLike<number>): Float32Array {
11116        return Float32Array.from<number>(arrayLike, (x: number, k: number): number => x)
11117    }
11118
11119    /**
11120     * Creates an array from an array-like or iterable object.
11121     *
11122     * @param arrayLike An array-like or iterable object to convert to an array.
11123     *
11124     * @param mapfn A mapping function to call on every element of the array.
11125     *
11126     * @returns new Float32Array
11127     */
11128    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float32Array {
11129        if (mapfn == undefined) {
11130            mapfn = (v: number, k: number): number => { return v }
11131        }
11132        // Calc length of items inside arrayLike, save length into i variable
11133        let i: long = 0
11134        let iter = arrayLike.$_iterator()
11135        while (true) {
11136            const v = iter.next()
11137            if (v.done) {
11138                break
11139            }
11140            i++
11141        }
11142
11143        let res = new Float32Array(i as int)
11144        i = 0
11145        iter = arrayLike.$_iterator()
11146        while (true) {
11147            const v = iter.next()
11148            if (v.done) {
11149                return res
11150            }
11151            res.setUnsafe(i as int, (mapfn)!(v.value as number, i as number) as float)
11152            i++
11153        }
11154    }
11155
11156
11157    /**
11158     * Creates an array from an array-like or iterable object.
11159     *
11160     * @param arrayLike An array-like or iterable object to convert to an array.
11161     *
11162     * @param mapfn A mapping function to call on every element of the array.
11163     *
11164     * @returns new Float32Array
11165     */
11166    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): Float32Array {
11167        let res = new Float32Array(arrayLike.length)
11168        // 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
11169        const idx = new int[1]
11170        idx[0] = 0
11171        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
11172            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as float)
11173            idx[0] += 1
11174        })
11175        return res
11176    }
11177
11178    /**
11179     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11180     *
11181     * @param searchElement The element to search for
11182     *
11183     * @param fromIndex The position in this array at which to begin searching for searchElement
11184     *
11185     * @returns true if searchElement is in Float32Array, false otherwise
11186     */
11187    public includes(searchElement: number, fromIndex?: number): boolean {
11188        if (isNaN(searchElement)) {
11189            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
11190            for (let i = fromIndexInt; i < this.lengthInt; i++) {
11191                if (isNaN(this.getUnsafe(i))) {
11192                    return true
11193                }
11194            }
11195            return false
11196        }
11197        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
11198    }
11199
11200    /**
11201     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11202     *
11203     * @param searchElement The element to search for
11204     *
11205     * @param fromIndex The position in this array at which to begin searching for searchElement
11206     *
11207     * @returns true if e is in Float32Array, false otherwise
11208     */
11209    public includes(searchElement: float, fromIndex: int): boolean {
11210        return this.indexOf(searchElement as int, fromIndex) != -1
11211    }
11212
11213    /**
11214     * Determines whether Float32Array includes a certain element, returning true or false as appropriate
11215     *
11216     * @param searchElement The element to search for
11217     *
11218     * @param fromIndex The position in this array at which to begin searching for searchElement
11219     *
11220     * @returns true if searchElement is in Float32Array, false otherwise
11221     */
11222    public includes(searchElement: float): boolean {
11223        return this.includes(searchElement, 0)
11224    }
11225
11226    /**
11227     * Returns the index of the first occurrence of a value in Float32Array.
11228     *
11229     * @param searchElement The value to locate in the array.
11230     *
11231     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11232     *  search starts at index 0.
11233     *
11234     * @returns index of element if it presents, -1 otherwise
11235     */
11236    public indexOf(searchElement: number, fromIndex?: number): number {
11237        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
11238    }
11239
11240    /**
11241     * Returns the index of the first occurrence of a value in Float32Array.
11242     *
11243     * @param searchElement The value to locate in the array.
11244     *
11245     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11246     *  search starts at index 0.
11247     *
11248     * @returns index of element if it presents, -1 otherwise
11249     */
11250    public indexOf(searchElement: number, fromIndex: int): number {
11251        if (isNaN(searchElement)) {
11252            return -1
11253        }
11254        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
11255        for (let i = fromIndex; i < this.lengthInt; i++) {
11256            if (this.getUnsafe(i) as number == searchElement) {
11257                return i
11258            }
11259        }
11260        return -1
11261    }
11262
11263    /**
11264     * Returns the index of the first occurrence of a value in Float32Array.
11265     *
11266     * @param searchElement The value to locate in the array.
11267     *
11268     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11269     *  search starts at index 0.
11270     *
11271     * @returns index of element if it presents, -1 otherwise
11272     */
11273    public indexOf(searchElement: int, fromIndex: int): number {
11274        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
11275        for (let i = fromIndex; i < this.lengthInt; i++) {
11276            if (this.getUnsafe(i) == searchElement as float) {
11277                return i
11278            }
11279        }
11280        return -1
11281    }
11282
11283    /**
11284     * Returns the index of the first occurrence of a value in Float32Array.
11285     *
11286     * @param searchElement The value to locate in the array.
11287     *
11288     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
11289     *  search starts at index 0.
11290     *
11291     * @returns index of element if it presents, -1 otherwise
11292     */
11293    public indexOf(searchElement: int): number {
11294        return this.indexOf(searchElement, 0)
11295    }
11296
11297    /**
11298     * Adds all the elements of an array separated by the specified separator string
11299     *
11300     * @param separator A string used to separate one element of an array from the next in the
11301     * resulting String. If omitted, the array elements are separated with a comma
11302     *
11303     * @returns joined representation
11304     */
11305    public join(separator?: String): string {
11306        if (separator == undefined) {
11307            return this.join(",")
11308        }
11309        let res: StringBuilder = new StringBuilder("")
11310        for (let i = 0; i < this.lengthInt - 1; ++i) {
11311            res.append(this.getUnsafe(i) as number)
11312            res.append(separator)
11313        }
11314        if (this.lengthInt > 0) {
11315            res.append(this.getUnsafe(this.lengthInt - 1) as number)
11316        }
11317        return res.toString()
11318    }
11319
11320    /**
11321     * Returns an list of keys in Float32Array
11322     *
11323     * @returns iterator over keys
11324     */
11325    public keys(): IterableIterator<number> {
11326        return new Float32ArrayIteratorKeys(this)
11327    }
11328
11329    /**
11330     * Returns the index of the last occurrence of a value in Float32Array.
11331     *
11332     * @param searchElement The value to locate in the array.
11333     *
11334     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11335     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11336     *
11337     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11338     */
11339    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
11340        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
11341    }
11342
11343    /**
11344     * Returns the index of the last occurrence of a value in Float32Array.
11345     *
11346     * @param searchElement The value to locate in the array.
11347     *
11348     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11349     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11350     *
11351     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11352     */
11353    public lastIndexOf(searchElement: number): number {
11354        return this.lastIndexOf(searchElement, this.lengthInt - 1)
11355    }
11356
11357    /**
11358     * Returns the index of the last occurrence of a value in Float32Array.
11359     *
11360     * @param searchElement The value to locate in the array.
11361     *
11362     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11363     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11364     *
11365     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11366     */
11367    public lastIndexOf(searchElement: number, fromIndex: int): number {
11368        if (isNaN(searchElement)) {
11369            return -1
11370        }
11371        if (this.lengthInt == 0) {
11372            return -1
11373        }
11374        let k: int = this.lengthInt + fromIndex
11375        if (fromIndex >= 0) {
11376            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
11377        }
11378        while (k >= 0) {
11379            if (this.getUnsafe(k) as number == searchElement) {
11380                return k
11381            }
11382            k--
11383        }
11384        return -1
11385    }
11386
11387    /**
11388     * Returns the index of the last occurrence of a value in Float32Array.
11389     *
11390     * @param searchElement The value to locate in the array.
11391     *
11392     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11393     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11394     *
11395     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11396     */
11397    public lastIndexOf(searchElement: int, fromIndex: int): number {
11398        if (this.lengthInt == 0) {
11399            return -1
11400        }
11401        let k: int = this.lengthInt + fromIndex
11402        if (fromIndex >= 0) {
11403            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
11404        }
11405        while (k >= 0) {
11406            if (this.getUnsafe(k) == searchElement as float) {
11407                return k
11408            }
11409            k--
11410        }
11411        return -1
11412    }
11413
11414    /**
11415     * Returns the index of the last occurrence of a value in Float32Array.
11416     *
11417     * @param searchElement The value to locate in the array.
11418     *
11419     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
11420     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
11421     *
11422     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
11423     */
11424    public lastIndexOf(searchElement: int): number {
11425        return this.lastIndexOf(searchElement, this.lengthInt - 1)
11426    }
11427
11428    /**
11429    * Creates a new Float32Array using initializer
11430    *
11431    * @param data initializer
11432    *
11433    * @returns a new Float32Array from data
11434    */
11435    public of(data: Object[]): Float32Array {
11436        throw new Error("Float32Array.of: not implemented")
11437    }
11438
11439    /**
11440     * Creates a new Float32Array using reversed data from the current one
11441     *
11442     * @returns a new Float32Array using reversed data from the current one
11443     */
11444    public reverse(): Float32Array {
11445        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
11446            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
11447            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
11448            this.setUnsafe(i, tmp)
11449        }
11450        return this
11451    }
11452
11453    /**
11454     * Creates a slice of current Float32Array using range [begin, end)
11455     *
11456     * @param begin start index to be taken into slice
11457     *
11458     * @param end last index to be taken into slice
11459     *
11460     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11461     *
11462     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11463     */
11464    public slice(begin?: number, end?: number): Float32Array {
11465        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
11466    }
11467
11468    /**
11469     * Creates a slice of current Float32Array using range [begin, end)
11470     *
11471     * @param begin start index to be taken into slice
11472     *
11473     * @param end last index to be taken into slice
11474     *
11475     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11476     *
11477     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11478     */
11479    public slice(begin: number, end: number): Float32Array {
11480        return this.slice(begin as int, end as int)
11481    }
11482
11483    /**
11484     * Creates a slice of current Float32Array using range [begin, end)
11485     *
11486     * @param begin start index to be taken into slice
11487     *
11488     * @param end last index to be taken into slice
11489     *
11490     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11491     *
11492     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11493     */
11494    public slice(begin: number, end: int): Float32Array {
11495        return this.slice(begin as int, end as int)
11496    }
11497
11498    /**
11499     * Creates a slice of current Float32Array using range [begin, end)
11500     *
11501     * @param begin start index to be taken into slice
11502     *
11503     * @param end last index to be taken into slice
11504     *
11505     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11506     *
11507     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11508     */
11509    public slice(begin: int, end: number): Float32Array {
11510        return this.slice(begin as int, end as int)
11511    }
11512
11513    /**
11514     * Creates a slice of current Float32Array using range [begin, end)
11515     *
11516     * @param begin start index to be taken into slice
11517     *
11518     * @param end last index to be taken into slice
11519     *
11520     * @returns a new Float32Array with elements of current Float32Array[begin;end) where end index is excluded
11521     *
11522     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
11523     */
11524    public slice(begin: int, end: int): Float32Array {
11525        const len: int = this.lengthInt
11526        const relStart = normalizeIndex(begin, len)
11527        const relEnd = normalizeIndex(end, len)
11528        let count = relEnd - relStart
11529        if (count < 0) {
11530            count = 0
11531        }
11532        if (this.buffer instanceof ArrayBuffer) {
11533            let buf = (this.buffer as ArrayBuffer).slice(relStart * Float32Array.BYTES_PER_ELEMENT as int, relEnd * Float32Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
11534            return new Float32Array(buf)
11535        } else if (this.buffer instanceof SharedArrayBuffer) {
11536            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Float32Array.BYTES_PER_ELEMENT as int, relEnd * Float32Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
11537            return new Float32Array(buf)
11538        } else {
11539            throw new Error("unexpected type of buffer")
11540        }
11541    }
11542
11543    /**
11544     * Creates a slice of current Float32Array using range [begin, this.length).
11545     *
11546     * @param begin start index to be taken into slice
11547     *
11548     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
11549     */
11550    public slice(begin: number): Float32Array {
11551        return this.slice(begin as int)
11552    }
11553
11554    /**
11555     * Creates a slice of current Float32Array using range [begin, this.length).
11556     *
11557     * @param begin start index to be taken into slice
11558     *
11559     * @returns a new Float32Array with elements of current Float32Array[begin, this.length)
11560     */
11561    public slice(begin: int): Float32Array {
11562        return this.slice(begin, this.lengthInt)
11563    }
11564
11565    /**
11566     * Creates a Float32Array with the same underlying ArrayBufferLike
11567     *
11568     * @param begin start index, inclusive
11569     *
11570     * @param end last index, exclusive
11571     *
11572     * @returns new Float32Array with the same underlying ArrayBufferLike
11573     */
11574    public subarray(begin?: number, end?: number): Float32Array {
11575        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
11576    }
11577
11578    /**
11579     * Creates a Float32Array with the same underlying ArrayBufferLike
11580     *
11581     * @param begin start index, inclusive
11582     *
11583     * @param end last index, exclusive
11584     *
11585     * @returns new Float32Array with the same underlying ArrayBufferLike
11586     */
11587    public subarray(begin: number, end: number): Float32Array {
11588        return this.subarray(begin as int, end as int)
11589    }
11590
11591    /**
11592     * Creates a Float32Array with the same underlying ArrayBufferLike
11593     *
11594     * @param begin start index, inclusive
11595     *
11596     * @param end last index, exclusive
11597     *
11598     * @returns new Float32Array with the same underlying ArrayBufferLike
11599     */
11600    public subarray(begin: number, end: int): Float32Array {
11601        return this.subarray(begin as int, end as int)
11602    }
11603
11604    /**
11605     * Creates a Float32Array with the same underlying ArrayBufferLike
11606     *
11607     * @param begin start index, inclusive
11608     *
11609     * @param end last index, exclusive
11610     *
11611     * @returns new Float32Array with the same underlying ArrayBufferLike
11612     */
11613    public subarray(begin: int, end: number): Float32Array {
11614        return this.subarray(begin as int, end as int)
11615    }
11616
11617    /**
11618     * Creates a Float32Array with the same underlying ArrayBufferLike
11619     *
11620     * @param begin start index, inclusive
11621     *
11622     * @param end last index, exclusive
11623     *
11624     * @returns new Float32Array with the same underlying ArrayBufferLike
11625     */
11626    public subarray(begin: int, end: int): Float32Array {
11627        const len: int = this.lengthInt
11628        const relStart = normalizeIndex(begin, len)
11629        const relEnd = normalizeIndex(end, len)
11630        let count = relEnd - relStart
11631        if (count < 0) {
11632            count = 0
11633        }
11634        return new Float32Array(this.buffer, relStart * Float32Array.BYTES_PER_ELEMENT as int, count)
11635    }
11636
11637    /**
11638     * Creates a Float32Array with the same ArrayBufferLike
11639     *
11640     * @param begin start index, inclusive
11641     *
11642     * @returns new Float32Array with the same ArrayBufferLike
11643     */
11644    public subarray(begin: number): Float32Array {
11645        return this.subarray(begin as int, this.lengthInt)
11646    }
11647
11648    /**
11649     * Creates a Float32Array with the same ArrayBufferLike
11650     *
11651     * @param begin start index, inclusive
11652     *
11653     * @returns new Float32Array with the same ArrayBufferLike
11654     */
11655    public subarray(begin: int): Float32Array {
11656        return this.subarray(begin as int, this.lengthInt)
11657    }
11658
11659    /**
11660     * Converts Float32Array to a string with respect to locale
11661     *
11662     * @param locales
11663     *
11664     * @param options
11665     *
11666     * @returns string representation
11667     */
11668    public toLocaleString(locales: Object, options: Object): string {
11669        throw new Error("Float32Array.toLocaleString: not implemented")
11670    }
11671
11672    /**
11673     * Converts Float32Array to a string with respect to locale
11674     *
11675     * @param locales
11676     *
11677     * @returns string representation
11678     */
11679    public toLocaleString(locales: Object): string {
11680        return this.toLocaleString(new Object(), new Object())
11681    }
11682
11683    /**
11684     * Converts Float32Array to a string with respect to locale
11685     *
11686     * @returns string representation
11687     */
11688    public toLocaleString(): string {
11689        let res: StringBuilder = new StringBuilder("")
11690        for (let i = 0; i < this.lengthInt - 1; ++i) {
11691            res.append((this.getUnsafe(i) as Number).toLocaleString())
11692            res.append(",")
11693        }
11694        if (this.lengthInt > 0) {
11695            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
11696        }
11697        return res.toString()
11698    }
11699
11700    /**
11701     * Creates a reversed copy
11702     *
11703     * @returns a reversed copy
11704     */
11705    public toReversed(): Float32Array {
11706        return new Float32Array(this).reverse()
11707    }
11708
11709    /**
11710     * Creates a sorted copy
11711     *
11712     * @returns a sorted copy
11713     */
11714    public toSorted(): Float32Array {
11715        return new Float32Array(this).sort()
11716    }
11717
11718    /**
11719     * Returns a string representation of the Float32Array
11720     *
11721     * @returns a string representation of the Float32Array
11722     */
11723    public override toString(): string {
11724        return this.join(",")
11725    }
11726
11727    /**
11728     * Returns array values iterator
11729     *
11730     * @returns an iterator
11731     */
11732    public values(): IterableIterator<Number> {
11733        return new Float32ArrayIterator(this)
11734    }
11735
11736    /**
11737     * Iteratorable interface implementation
11738     *
11739     * @returns iterator over all elements
11740     */
11741    public override $_iterator(): IterableIterator<Number> {
11742        return this.values()
11743    }
11744
11745    /**
11746     * Creates a copy with replaced value on index
11747     *
11748     * @param index
11749     *
11750     * @param value
11751     *
11752     * @returns an Float32Array with replaced value on index
11753     */
11754    public with(index: number, value: number): Float32Array {
11755        return this.with(index as int, value as float)
11756    }
11757
11758    /**
11759     * Creates a copy with replaced value on index
11760     *
11761     * @param index
11762     *
11763     * @param value
11764     *
11765     * @returns an Float32Array with replaced value on index
11766     */
11767    public with(index: int, value: float): Float32Array {
11768        let res = new Float32Array(this)
11769        res.set(index, value)
11770        return res
11771    }
11772
11773    /// === with element lambda functions ===
11774    /**
11775     * Determines whether the specified callback function returns true for all elements of an array.
11776     *
11777     * @param predicate A function that accepts one argument.
11778     * The every method calls the predicate function for each element in the array until the predicate returns a false,
11779     * or until the end of the array.
11780     *
11781     * @returns true unless predicate function returns a false for an array element,
11782     * in which case false is immediately returned.
11783     */
11784    public every(predicate: (element: number) => boolean): boolean {
11785        return this.every((element: number, index: number, array: Float32Array): boolean => predicate(element))
11786    }
11787
11788    /**
11789     * creates a new Float32Array from current Float32Array based on a condition fn
11790     *
11791     * @param fn the condition to apply for each element
11792     *
11793     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
11794     */
11795    public filter(fn: (val: number) => boolean): Float32Array {
11796        let newF: (val: number, index: number, array: Float32Array) => boolean =
11797            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
11798        return this.filter(newF)
11799    }
11800
11801    /**
11802     * Returns the value of the first element in the array where predicate is true, and undefined
11803     * otherwise
11804     *
11805     * @param predicate find calls predicate once for each element of the array, in ascending
11806     * order, until it finds one where predicate returns true. If such an element is found, find
11807     * immediately returns that element value. Otherwise, find returns undefined
11808     *
11809     * @returns number | undefined
11810     */
11811    public find(predicate: () => boolean): number | undefined {
11812        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate())
11813    }
11814
11815    /**
11816     * Returns the value of the first element in the array where predicate is true, and undefined
11817     * otherwise
11818     *
11819     * @param predicate find calls predicate once for each element of the array, in ascending
11820     * order, until it finds one where predicate returns true. If such an element is found, find
11821     * immediately returns that element value. Otherwise, find returns undefined
11822     *
11823     * @returns number | undefined
11824     */
11825    public find(predicate: (value: number) => boolean): number | undefined {
11826        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate(value))
11827    }
11828
11829    /**
11830     * Returns the index of the first element in the array where predicate is true, and -1
11831     * otherwise
11832     *
11833     * @param predicate find calls predicate once for each element of the array, in ascending
11834     * order, until it finds one where predicate returns true. If such an element is found,
11835     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
11836     *
11837     * @returns number
11838     */
11839    public findIndex(predicate: (value: number) => boolean): number {
11840        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate(value)) as number
11841    }
11842
11843    /**
11844     * Finds the last element in the Float32Array that satisfies the condition
11845     *
11846     * @param fn condition
11847     *
11848     * @returns the last element that satisfies fn
11849     */
11850    public findLast(fn: (val: number) => boolean): number {
11851        let newF: (val: number, index: number, array: Float32Array) => boolean =
11852            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
11853        return this.findLast(newF) as number
11854    }
11855
11856    /**
11857     * Finds an index of the last element in the Float32Array that satisfies the condition
11858     *
11859     * @param fn condition
11860     *
11861     * @returns the index of the last element that satisfies fn, -1 otherwise
11862     */
11863    public findLastIndex(fn: (val: number) => boolean): number {
11864        let newF: (val: number, index: number, array: Float32Array) => boolean =
11865            (val: number, index: number, array: Float32Array): boolean => { return fn(val) }
11866        return this.findLastIndex(newF) as number
11867    }
11868
11869    /**
11870     * Performs the specified action for each element in Float32Array
11871     *
11872     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
11873     * callbackfn function one time for each element in the array.
11874     *
11875     * @returns None
11876     */
11877    public forEach(callbackfn: (value: number) => void): void {
11878        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn(value))
11879    }
11880
11881    /**
11882     * Creates a new Float32Array using fn(arr[i]) over all elements of current Float32Array
11883     *
11884     * @param fn a function to apply for each element of current Float32Array
11885     *
11886     * @returns a new Float32Array where for each element from current Float32Array fn was applied
11887     */
11888    public map(fn: (val: number) => number): Float32Array {
11889        let newF: (val: number, index: number) => number =
11890            (val: number, index: number): number => { return fn(val) }
11891        return this.map(newF)
11892    }
11893
11894    /**
11895     * Determines whether the specified callback function returns true for any element of an array.
11896     *
11897     * @param predicate A function that accepts one argument.
11898     * The some method calls the predicate function for each element in the array
11899     * until the predicate returns a true or until the end of the array.
11900     *
11901     * @returns false unless predicate function returns true for an array element,
11902     * in which case true is immediately returned.
11903     */
11904    public some(predicate: (element: number) => boolean): boolean {
11905        return this.some((element: number, index: number, array: Float32Array): boolean => predicate(element))
11906    }
11907
11908    // NOTE (kprokopenko): this may be not skipped
11909    /**
11910     * Sorts in-place
11911     *
11912     * @param compareFn comparator —  used to determine the order of the elements.
11913     * compareFn returns a negative value if first argument is less than second argument,
11914     * zero if they're equal and a positive value otherwise.
11915     * If omitted, the elements are sorted in ascending order.
11916     *
11917     * @returns sorted Float32Array
11918     */
11919    public sort(compareFn?: (a: number, b: number) => number): this {
11920        let arr: float[] = new float[this.lengthInt]
11921        for (let i = 0; i < this.lengthInt; ++i) {
11922            arr[i] = this.getUnsafe(i)
11923        }
11924        let cmp = (l: float, r: float): number => {
11925                return (l - r) as number
11926            }
11927        if (compareFn != undefined) {
11928            cmp = (l: float, r: float): number => {
11929                return compareFn!(l as number, r as number)
11930            }
11931        }
11932        sort(arr, cmp)
11933        for (let i = 0; i < this.lengthInt; ++i) {
11934            this.setUnsafe(i, arr[i])
11935        }
11936        return this
11937    }
11938
11939    /**
11940     * Sorts in-place
11941     *
11942     * @param compareFn comparator —  used to determine the order of the elements.
11943     * compareFn returns a negative value if first argument is less than second argument,
11944     * zero if they're equal and a positive value otherwise.
11945     *
11946     * @returns sorted Float32Array
11947     */
11948    public sort(compareFn: (a: number) => number): this {
11949        let cmp = (a: number, b: number) => { return compareFn(a)}
11950        this.sort(cmp)
11951        return this
11952    }
11953
11954    /**
11955     * Sorts in-place
11956     *
11957     * @param fn compareFn —  used to determine the order of the elements.
11958     * compareFn returns a negative value if first argument is less than second argument,
11959     * zero if they're equal and a positive value otherwise.
11960     *
11961     * @returns sorted Float32Array
11962     */
11963    public sort(compareFn: () => number): this {
11964        let cmp = (a: number, b: number) => { return compareFn()}
11965        this.sort(cmp)
11966        return this
11967    }
11968
11969    /**
11970     * Determines whether the specified callback function returns true for any element of an array.
11971     *
11972     * @param predicate A function that accepts three arguments.
11973     * The some method calls the predicate function for each element in the array
11974     * until the predicate returns a true or until the end of the array.
11975     *
11976     * @returns false unless predicate function returns true for an array element,
11977     * in which case true is immediately returned.
11978     */
11979    public some(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
11980        for (let i = 0; i < this.lengthInt; ++i) {
11981            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
11982                return true
11983            }
11984        }
11985        return false
11986    }
11987
11988    /**
11989     * Determines whether the specified callback function returns true for any element of an array.
11990     *
11991     * @param predicate A function that accepts two arguments.
11992     * The some method calls the predicate function for each element in the array
11993     * until the predicate returns a true or until the end of the array.
11994     *
11995     * @returns false unless predicate function returns true for an array element,
11996     * in which case true is immediately returned.
11997     */
11998    public some(predicate: (element: number, index: number) => boolean): boolean {
11999        return this.some((element: number, index: number, array: Float32Array): boolean => predicate(element, index as number))
12000    }
12001
12002    /**
12003     * Determines whether the specified callback function returns true for any element of an array.
12004     *
12005     * @param predicate A function that accepts no arguments.
12006     * The some method calls the predicate function for each element in the array
12007     * until the predicate returns a true or until the end of the array.
12008     *
12009     * @returns false unless predicate function returns true for an array element,
12010     * in which case true is immediately returned.
12011     */
12012    public some(predicate: () => boolean): boolean {
12013        return this.some((element: number, index: number, array: Float32Array): boolean => predicate())
12014    }
12015
12016    /**
12017     * Calls the specified callback function for all the elements in an array.
12018     * The return value of the callback function is the accumulated result,
12019     * and is provided as an argument in the next call to the callback function.
12020     *
12021     * @param callbackfn A function that accepts four arguments.
12022     * The reduce method calls the callbackfn function one time for each element in the array.
12023     *
12024     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12025     * The first call to the callbackfn function provides this value as an argument.
12026     *
12027     * @returns The value that results from running the callback function to completion over the entire typed array.
12028     */
12029    public reduce<U = number>(
12030                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
12031                initialValue: U): U {
12032        let accumulatedValue = initialValue
12033        for (let i = 0; i < this.lengthInt; ++i) {
12034            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12035        }
12036        return accumulatedValue
12037    }
12038
12039    /**
12040     * Calls the specified callback function for all the elements in an array.
12041     * The return value of the callback function is the accumulated result,
12042     * and is provided as an argument in the next call to the callback function.
12043     *
12044     * @param callbackfn A function that accepts three arguments.
12045     * The reduce method calls the callbackfn function one time for each element in the array.
12046     *
12047     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12048     * The first call to the callbackfn function provides this value as an argument.
12049     *
12050     * @returns The value that results from running the callback function to completion over the entire typed array.
12051     */
12052    public reduce<U = number>(
12053                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
12054                initialValue: U): U {
12055        return this.reduce(
12056                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12057                        callbackfn(prevVal, currVal, currIndex), initialValue)
12058    }
12059
12060    /**
12061     * Calls the specified callback function for all the elements in an array.
12062     * The return value of the callback function is the accumulated result,
12063     * and is provided as an argument in the next call to the callback function.
12064     *
12065     * @param callbackfn A function that accepts two arguments.
12066     * The reduce method calls the callbackfn function one time for each element in the array.
12067     *
12068     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12069     * The first call to the callbackfn function provides this value as an argument.
12070     *
12071     * @returns The value that results from running the callback function to completion over the entire typed array.
12072     */
12073    public reduce<U = number>(
12074                callbackfn: (previousValue: U, currentValue: number) => U,
12075                initialValue: U): U {
12076        return this.reduce(
12077                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12078                        callbackfn(prevVal, currVal), initialValue)
12079    }
12080
12081    /**
12082     * Calls the specified callback function for all the elements in an array.
12083     * The return value of the callback function is the accumulated result,
12084     * and is provided as an argument in the next call to the callback function.
12085     *
12086     * @param callbackfn A function that accepts one argument
12087     * The reduce method calls the callbackfn function one time for each element in the array.
12088     *
12089     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12090     * The first call to the callbackfn function provides this value as an argument.
12091     *
12092     * @returns The value that results from running the callback function to completion over the entire typed array.
12093     */
12094    public reduce<U = number>(
12095                callbackfn: (previousValue: U) => U,
12096                initialValue: U): U {
12097        return this.reduce(
12098                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12099                        callbackfn(prevVal), initialValue)
12100    }
12101
12102    /**
12103     * Calls the specified callback function for all the elements in an array.
12104     * The return value of the callback function is the accumulated result,
12105     * and is provided as an argument in the next call to the callback function.
12106     *
12107     * @param callbackfn A function that accepts no arguments
12108     * The reduce method calls the callbackfn function one time for each element in the array.
12109     *
12110     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12111     * The first call to the callbackfn function provides this value as an argument.
12112     *
12113     * @returns The value that results from running the callback function to completion over the entire typed array.
12114     */
12115    public reduce<U = number>(
12116                callbackfn: () => U,
12117                initialValue: U): U {
12118        return this.reduce(
12119                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12120                        callbackfn(), initialValue)
12121    }
12122
12123    /**
12124     * Calls the specified callback function for all the elements in an array.
12125     * The return value of the callback function is the accumulated result,
12126     * and is provided as an argument in the next call to the callback function.
12127     *
12128     * @param callbackfn A function that accepts four arguments.
12129     * The reduce method calls the callbackfn function one time for each element in the array.
12130     * The first call to the callbackfn function provides array first element value as an argument
12131     *
12132     * @returns The value that results from running the callback function to completion over the entire typed array.
12133     * calling reduce method on an empty array without an initial value creates a TypeError
12134     */
12135    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
12136        if (this.lengthInt == 0) {
12137            throw new TypeError("Reduce of empty array with no initial value")
12138        }
12139
12140        let accumulatedValue = this.getUnsafe(0) as number
12141        for (let i = 1; i < this.lengthInt; ++i) {
12142            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12143        }
12144        return accumulatedValue
12145    }
12146
12147    /**
12148     * Calls the specified callback function for all the elements in an array.
12149     * The return value of the callback function is the accumulated result,
12150     * and is provided as an argument in the next call to the callback function.
12151     *
12152     * @param callbackfn A function that accepts three arguments.
12153     * The reduce method calls the callbackfn function one time for each element in the array.
12154     * The first call to the callbackfn function provides array first element value as an argument
12155     *
12156     * @returns The value that results from running the callback function to completion over the entire typed array.
12157     * calling reduce method on an empty array without an initial value creates a TypeError
12158     */
12159    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
12160        return this.reduce(
12161                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12162                        callbackfn(prevVal, currVal, currIndex))
12163    }
12164
12165    /**
12166     * Calls the specified callback function for all the elements in an array.
12167     * The return value of the callback function is the accumulated result,
12168     * and is provided as an argument in the next call to the callback function.
12169     *
12170     * @param callbackfn A function that accepts two arguments.
12171     * The reduce method calls the callbackfn function one time for each element in the array.
12172     * The first call to the callbackfn function provides array first element value as an argument
12173     *
12174     * @returns The value that results from running the callback function to completion over the entire typed array.
12175     * calling reduce method on an empty array without an initial value creates a TypeError
12176     */
12177    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
12178        return this.reduce(
12179                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12180                        callbackfn(prevVal, currVal))
12181    }
12182
12183    /**
12184     * Calls the specified callback function for all the elements in an array.
12185     * The return value of the callback function is the accumulated result,
12186     * and is provided as an argument in the next call to the callback function.
12187     *
12188     * @param callbackfn A function that accepts one argument.
12189     * The reduce method calls the callbackfn function one time for each element in the array.
12190     * The first call to the callbackfn function provides array first element value as an argument
12191     *
12192     * @returns The value that results from running the callback function to completion over the entire typed array.
12193     * calling reduce method on an empty array without an initial value creates a TypeError
12194     */
12195    public reduce(callbackfn: (previousValue: number) => number): number {
12196        return this.reduce(
12197                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12198                        callbackfn(prevVal))
12199    }
12200
12201    /**
12202     * Calls the specified callback function for all the elements in an array.
12203     * The return value of the callback function is the accumulated result,
12204     * and is provided as an argument in the next call to the callback function.
12205     *
12206     * @param callbackfn A function that accepts no arguments.
12207     * The reduce method calls the callbackfn function one time for each element in the array.
12208     * The first call to the callbackfn function provides array first element value as an argument
12209     *
12210     * @returns The value that results from running the callback function to completion over the entire typed array.
12211     * calling reduce method on an empty array without an initial value creates a TypeError
12212     */
12213    public reduce(callbackfn: () => number): number {
12214        return this.reduce(
12215                (prevVal: number, currVal: number, currIndex: number, array: Float32Array) =>
12216                        callbackfn())
12217    }
12218
12219
12220    /**
12221     * Calls the specified callback function for all the elements in an array, in descending order.
12222     * The return value of the callback function is the accumulated result,
12223     * and is provided as an argument in the next call to the callback function.
12224     *
12225     * @param callbackfn A function that accepts four arguments.
12226     * The reduceRight method calls the callbackfn function one time for each element in the array.
12227     *
12228     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12229     * The first call to the callbackfn function provides this value as an argument.
12230     *
12231     * @returns The value that results from running the callback function to completion over the entire typed array.
12232     */
12233    public reduceRight<U = number>(
12234                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U,
12235                initialValue: U): U {
12236        let accumulatedValue = initialValue
12237        for (let i = this.lengthInt - 1; i >= 0; --i) {
12238            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12239        }
12240        return accumulatedValue
12241    }
12242
12243    /**
12244     * Calls the specified callback function for all the elements in an array, in descending order.
12245     * The return value of the callback function is the accumulated result,
12246     * and is provided as an argument in the next call to the callback function.
12247     *
12248     * @param callbackfn A function that accepts three arguments.
12249     * The reduceRight method calls the callbackfn function one time for each element in the array.
12250     *
12251     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12252     * The first call to the callbackfn function provides this value as an argument.
12253     *
12254     * @returns The value that results from running the callback function to completion over the entire typed array.
12255     */
12256    public reduceRight<U = number>(
12257                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
12258                initialValue: U): U {
12259        return this.reduceRight(
12260                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12261                        callbackfn(prevVal, currVal, currIndex), initialValue)
12262    }
12263
12264    /**
12265     * Calls the specified callback function for all the elements in an array, in descending order.
12266     * The return value of the callback function is the accumulated result,
12267     * and is provided as an argument in the next call to the callback function.
12268     *
12269     * @param callbackfn A function that accepts two arguments.
12270     * The reduceRight method calls the callbackfn function one time for each element in the array.
12271     *
12272     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12273     * The first call to the callbackfn function provides this value as an argument.
12274     *
12275     * @returns The value that results from running the callback function to completion over the entire typed array.
12276     */
12277    public reduceRight<U = number>(
12278                callbackfn: (previousValue: U, currentValue: number) => U,
12279                initialValue: U): U {
12280        return this.reduceRight(
12281                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12282                        callbackfn(prevVal, currVal), initialValue)
12283    }
12284
12285    /**
12286     * Calls the specified callback function for all the elements in an array, in descending order.
12287     * The return value of the callback function is the accumulated result,
12288     * and is provided as an argument in the next call to the callback function.
12289     *
12290     * @param callbackfn A function that accepts one argument.
12291     * The reduceRight method calls the callbackfn function one time for each element in the array.
12292     *
12293     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12294     * The first call to the callbackfn function provides this value as an argument.
12295     *
12296     * @returns The value that results from running the callback function to completion over the entire typed array.
12297     */
12298    public reduceRight<U = number>(
12299                callbackfn: (previousValue: U) => U,
12300                initialValue: U): U {
12301        return this.reduceRight(
12302                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12303                        callbackfn(prevVal), initialValue)
12304    }
12305
12306    /**
12307     * Calls the specified callback function for all the elements in an array, in descending order.
12308     * The return value of the callback function is the accumulated result,
12309     * and is provided as an argument in the next call to the callback function.
12310     *
12311     * @param callbackfn A function that accepts no arguments.
12312     * The reduceRight method calls the callbackfn function one time for each element in the array.
12313     *
12314     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
12315     * The first call to the callbackfn function provides this value as an argument.
12316     *
12317     * @returns The value that results from running the callback function to completion over the entire typed array.
12318     */
12319    public reduceRight<U = number>(
12320                callbackfn: () => U,
12321                initialValue: U): U {
12322        return this.reduceRight(
12323                (prevVal: U, currVal: number, currIndex: number, array: Float32Array) =>
12324                        callbackfn(), initialValue)
12325    }
12326
12327    /**
12328     * Calls the specified callback function for all the elements in an array, in descending order.
12329     * The return value of the callback function is the accumulated result,
12330     * and is provided as an argument in the next call to the callback function.
12331     *
12332     * @param callbackfn A function that accepts four arguments.
12333     * The reduceRight method calls the callbackfn function one time for each element in the array.
12334     * The first call to the callbackfn function provides array last element value as an argument
12335     *
12336     * @returns The value that results from running the callback function to completion over the entire typed array.
12337     * calling reduceRight method on an empty array without an initial value creates a TypeError
12338     */
12339    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number {
12340        if (this.lengthInt == 0) {
12341            throw new TypeError("Reduce of empty array with no initial value")
12342        }
12343
12344        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
12345        for (let i = this.lengthInt - 2; i >= 0; --i) {
12346            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
12347        }
12348        return accumulatedValue
12349    }
12350
12351    /**
12352     * Calls the specified callback function for all the elements in an array, in descending order.
12353     * The return value of the callback function is the accumulated result,
12354     * and is provided as an argument in the next call to the callback function.
12355     *
12356     * @param callbackfn A function that accepts three arguments.
12357     * The reduceRight method calls the callbackfn function one time for each element in the array.
12358     * The first call to the callbackfn function provides array last element value as an argument
12359     *
12360     * @returns The value that results from running the callback function to completion over the entire typed array.
12361     * calling reduceRight method on an empty array without an initial value creates a TypeError
12362     */
12363    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
12364        return this.reduceRight(
12365                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12366                        callbackfn(prevValue, currValue, currIndex))
12367    }
12368
12369    /**
12370     * Calls the specified callback function for all the elements in an array, in descending order.
12371     * The return value of the callback function is the accumulated result,
12372     * and is provided as an argument in the next call to the callback function.
12373     *
12374     * @param callbackfn A function that accepts two arguments.
12375     * The reduceRight method calls the callbackfn function one time for each element in the array.
12376     * The first call to the callbackfn function provides array last element value as an argument
12377     *
12378     * @returns The value that results from running the callback function to completion over the entire typed array.
12379     * calling reduceRight method on an empty array without an initial value creates a TypeError
12380     */
12381    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
12382        return this.reduceRight(
12383                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12384                        callbackfn(prevValue, currValue))
12385    }
12386
12387    /**
12388     * Calls the specified callback function for all the elements in an array, in descending order.
12389     * The return value of the callback function is the accumulated result,
12390     * and is provided as an argument in the next call to the callback function.
12391     *
12392     * @param callbackfn A function that accepts one argument.
12393     * The reduceRight method calls the callbackfn function one time for each element in the array.
12394     * The first call to the callbackfn function provides array last element value as an argument
12395     *
12396     * @returns The value that results from running the callback function to completion over the entire typed array.
12397     * calling reduceRight method on an empty array without an initial value creates a TypeError
12398     */
12399    public reduceRight(callbackfn: (previousValue: number) => number): number {
12400        return this.reduceRight(
12401                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12402                        callbackfn(prevValue))
12403    }
12404
12405    /**
12406     * Calls the specified callback function for all the elements in an array, in descending order.
12407     * The return value of the callback function is the accumulated result,
12408     * and is provided as an argument in the next call to the callback function.
12409     *
12410     * @param callbackfn A function that accepts no arguments.
12411     * The reduceRight method calls the callbackfn function one time for each element in the array.
12412     * The first call to the callbackfn function provides array last element value as an argument
12413     *
12414     * @returns The value that results from running the callback function to completion over the entire typed array.
12415     * calling reduceRight method on an empty array without an initial value creates a TypeError
12416     */
12417    public reduceRight(callbackfn: () => number): number {
12418        return this.reduceRight(
12419                (prevValue: number, currValue: number, currIndex: number, array: Float32Array) =>
12420                        callbackfn())
12421    }
12422
12423   /**
12424    * Creates a new Float32Array using fn(arr[i]) over all elements of current Float32Array.
12425    *
12426    * @param fn a function to apply for each element of current Float32Array
12427    *
12428    * @returns a new Float32Array where for each element from current Float32Array fn was applied
12429    */
12430    public map(fn: (val: number, index: number) => number): Float32Array {
12431        let resBuf = new ArrayBuffer(this.lengthInt * Float32Array.BYTES_PER_ELEMENT as int)
12432        let res = new Float32Array(resBuf, 0, resBuf.getByteLength() / Float32Array.BYTES_PER_ELEMENT as int)
12433        for (let i = 0; i < this.lengthInt; ++i) {
12434            res.set(i, fn(this.getUnsafe(i) as number, i as number) as float)
12435        }
12436        return res
12437    }
12438
12439    /**
12440     * Determines whether the specified callback function returns true for all elements of an array.
12441     *
12442     * @param predicate A function that accepts three arguments.
12443     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12444     * or until the end of the array.
12445     *
12446     * @returns true unless predicate function returns a false for an array element,
12447     * in which case false is immediately returned.
12448     */
12449    public every(predicate: (element: number, index: number, array: Float32Array) => boolean): boolean {
12450        for (let i = 0; i < this.lengthInt; ++i) {
12451            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
12452                return false
12453            }
12454        }
12455        return true
12456    }
12457
12458    /**
12459     * Determines whether the specified callback function returns true for all elements of an array.
12460     *
12461     * @param predicate A function that accepts two arguments.
12462     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12463     * or until the end of the array.
12464     *
12465     * @returns true unless predicate function returns a false for an array element,
12466     * in which case false is immediately returned.
12467     */
12468    public every(predicate: (element: number, index: number) => boolean): boolean {
12469        return this.every((element: number, index: number, array: Float32Array): boolean => predicate(element, index))
12470    }
12471
12472    /**
12473     * Determines whether the specified callback function returns true for all elements of an array.
12474     *
12475     * @param predicate A function that accepts no arguments.
12476     * The every method calls the predicate function for each element in the array until the predicate returns a false,
12477     * or until the end of the array.
12478     *
12479     * @returns true unless predicate function returns a false for an array element,
12480     * in which case false is immediately returned.
12481     */
12482    public every(predicate: () => boolean): boolean {
12483        return this.every((element: number, index: number, array: Float32Array): boolean => predicate())
12484    }
12485
12486    /**
12487     * Creates a new Float32Array from current Float32Array based on a condition fn.
12488     *
12489     * @param fn the condition to apply for each element
12490     *
12491     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12492     */
12493    public filter(fn: (val: number, index: number, array: Float32Array) => boolean): Float32Array {
12494        let markers = new boolean[this.lengthInt]
12495        let resLen = 0
12496        for (let i = 0; i < this.lengthInt; ++i) {
12497            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
12498            if (markers[i]) {
12499                ++resLen
12500            }
12501        }
12502        let resBuf = new ArrayBuffer(resLen * Float32Array.BYTES_PER_ELEMENT as int)
12503        let res = new Float32Array(resBuf, 0)
12504        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
12505            if (markers[i]) {
12506                res.set(j, this.getUnsafe(i))
12507                ++j
12508            }
12509        }
12510        return res
12511    }
12512
12513    /**
12514     * creates a new Float32Array from current Float32Array based on a condition fn
12515     *
12516     * @param fn the condition to apply for each element
12517     *
12518     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12519     */
12520    public filter(fn: (val: number, index: number) => boolean): Float32Array {
12521        let newF: (val: number, index: number, array: Float32Array) => boolean =
12522            (val: number, index: number, array: Float32Array): boolean => { return fn(val, index as number) }
12523        return this.filter(newF)
12524    }
12525
12526    /**
12527     * creates a new Float32Array from current Float32Array based on a condition fn
12528     *
12529     * @param fn the condition to apply for each element
12530     *
12531     * @returns a new Float32Array with elements from current Float32Array that satisfy condition fn
12532     */
12533    public filter(fn: () => boolean): Float32Array {
12534        let newF: (val: number, index: number, array: Float32Array) => boolean =
12535            (val: number, index: number, array: Float32Array): boolean => { return fn() }
12536        return this.filter(newF)
12537    }
12538
12539    /**
12540     * Returns the value of the first element in the array where predicate is true, and undefined
12541     * otherwise
12542     *
12543     * @param predicate find calls predicate once for each element of the array, in ascending
12544     * order, until it finds one where predicate returns true. If such an element is found, find
12545     * immediately returns that element value. Otherwise, find returns undefined
12546     *
12547     * @returns number | undefined
12548     */
12549    public find(predicate: (value: number, index: number, obj: Float32Array) => boolean): number | undefined {
12550        for (let i = 0; i < this.lengthInt; ++i) {
12551            let val = this.getUnsafe(i)
12552            if (predicate(val as number, i as number, this)) {
12553                return val as number
12554            }
12555        }
12556        return undefined
12557    }
12558
12559    /**
12560     * Returns the value of the first element in the array where predicate is true, and undefined
12561     * otherwise
12562     *
12563     * @param predicate find calls predicate once for each element of the array, in ascending
12564     * order, until it finds one where predicate returns true. If such an element is found, find
12565     * immediately returns that element value. Otherwise, find returns undefined
12566     *
12567     * @returns number | undefined
12568     */
12569    public find(predicate: (value: number, index: number) => boolean): number | undefined {
12570        return this.find((value: number, index: number, obj: Float32Array): boolean => predicate(value, index))
12571    }
12572
12573    /**
12574     * Returns the index of the first element in the array where predicate is true, and -1
12575     * otherwise
12576     *
12577     * @param predicate find calls predicate once for each element of the array, in ascending
12578     * order, until it finds one where predicate returns true. If such an element is found,
12579     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12580     *
12581     * @returns number
12582     */
12583    public findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean): number {
12584        for (let i = 0; i < this.lengthInt; ++i) {
12585            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
12586                return i as number
12587            }
12588        }
12589        return -1 as number
12590    }
12591
12592    /**
12593     * Returns the index of the first element in the array where predicate is true, and -1
12594     * otherwise
12595     *
12596     * @param predicate find calls predicate once for each element of the array, in ascending
12597     * order, until it finds one where predicate returns true. If such an element is found,
12598     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12599     *
12600     * @returns number
12601     */
12602    public findIndex(predicate: (value: number, index: number) => boolean): number {
12603        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate(value, index as number)) as number
12604    }
12605
12606    /**
12607     * Returns the index of the first element in the array where predicate is true, and -1
12608     * otherwise
12609     *
12610     * @param predicate find calls predicate once for each element of the array, in ascending
12611     * order, until it finds one where predicate returns true. If such an element is found,
12612     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
12613     *
12614     * @returns number
12615     */
12616    public findIndex(predicate: () => boolean): number {
12617        return this.findIndex((value: number, index: number, obj: Float32Array): boolean => predicate()) as number
12618    }
12619
12620    /**
12621     * Finds the last element in the Float32Array that satisfies the condition
12622     *
12623     * @param fn condition
12624     *
12625     * @returns the last element that satisfies fn
12626     */
12627    public findLast(fn: (val: number, index: number, array: Float32Array) => boolean): float {
12628        for (let i = this.lengthInt - 1; i >= 0; --i) {
12629            let val = this.getUnsafe(i)
12630            if (fn(val as number, i as number, this)) {
12631                return val
12632            }
12633        }
12634        throw new Error("Float32Array.findLast: not implemented if an element was not found")
12635    }
12636
12637    /**
12638     * Finds the last element in the Float32Array that satisfies the condition
12639     *
12640     * @param fn condition
12641     *
12642     * @returns the last element that satisfies fn
12643     */
12644    public findLast(fn: (val: number, index: number) => boolean): float {
12645        let newF: (val: number, index: number, array: Float32Array) => boolean =
12646            (val: number, index: number, array: Float32Array): boolean => { return fn(val as number, index as number) }
12647        return this.findLast(newF)
12648    }
12649
12650    /**
12651     * Finds an index of the last element in the Float32Array that satisfies the condition
12652     *
12653     * @param fn condition
12654     *
12655     * @returns the index of the last element that satisfies fn, -1 otherwise
12656     */
12657    public findLastIndex(fn: (val: number, index: number, array: Float32Array) => boolean): number {
12658        for (let i = this.lengthInt - 1; i >= 0; --i) {
12659            let val = this.getUnsafe(i)
12660            if (fn(val as number, i as number, this)) {
12661                return i
12662            }
12663        }
12664        return -1 as number
12665    }
12666
12667    /**
12668     * Finds an index of the last element in the Float32Array that satisfies the condition
12669     *
12670     * @param fn condition
12671     *
12672     * @returns the index of the last element that satisfies fn, -1 otherwise
12673     */
12674    public findLastIndex(fn: (val: number, index: number) => boolean): number {
12675        let newF: (val: number, index: number, array: Float32Array) => boolean =
12676            (val: number, index: number, array: Float32Array): boolean => { return fn(val, index as number) }
12677        return this.findLastIndex(newF) as number
12678    }
12679
12680    /**
12681     * Performs the specified action for each element in Float32Array
12682     *
12683     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
12684     * callbackfn function one time for each element in the array.
12685     *
12686     * @returns None
12687     */
12688    public forEach(callbackfn: (value: number, index: number, array: Float32Array) => void): void {
12689        for (let i = 0; i < this.lengthInt; ++i) {
12690            callbackfn(this.getUnsafe(i) as number, i as number, this)
12691        }
12692    }
12693
12694    /**
12695     * Performs the specified action for each element in Float32Array
12696     *
12697     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
12698     * callbackfn function one time for each element in the array.
12699     *
12700     * @returns None
12701     */
12702    public forEach(callbackfn: (value: number, index: number) => void): void {
12703        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn(value, index))
12704    }
12705
12706    /**
12707     * Performs the specified action for each element in Float32Array
12708     *
12709     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
12710     * callbackfn function one time for each element in the array.
12711     *
12712     * @returns None
12713     */
12714    public forEach(callbackfn: () => void): void {
12715        this.forEach((value: number, index: number, array: Float32Array): void => callbackfn())
12716    }
12717
12718    /**
12719     * Returns the object itself
12720     *
12721     * @returns Float32Array
12722     */
12723    public valueOf(): Float32Array {
12724        return this
12725    }
12726
12727    internal getUnsafe(index: int): float {
12728        let byteIndex = index * Float32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
12729        let res : int = 0
12730        let byteVal : int
12731        if (IS_LITTLE_ENDIAN) {
12732            if (this.buffer instanceof ArrayBuffer) {
12733                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12734                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
12735                    byteVal &= 0xff
12736                    res = (res | byteVal << (8 * i)) as int
12737                }
12738            } else if (this.buffer instanceof SharedArrayBuffer) {
12739                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12740                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
12741                    byteVal &= 0xff
12742                    res = (res | byteVal << (8 * i)) as int
12743                }
12744            } else {
12745                throw new Error("unexpected type of ArrayBufferLike")
12746            }
12747            return Float.bitCastFromInt(res)
12748        } else {
12749            if (this.buffer instanceof ArrayBuffer) {
12750                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12751                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 3 - i)
12752                    byteVal &= 0xff
12753                    res = (res | byteVal << (8 * i)) as int
12754                }
12755            } else if (this.buffer instanceof SharedArrayBuffer) {
12756                for (let i: int = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12757                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 3 - i)
12758                    byteVal &= 0xff
12759                    res = (res | byteVal << (8 * i)) as int
12760                }
12761            } else {
12762                throw new Error("unexpected type of ArrayBufferLike")
12763            }
12764            return Float.bitCastFromInt(res)
12765        }
12766    }
12767
12768    internal setUnsafe(insertPos: int, val: float): void {
12769        let startByte = insertPos * Float32Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
12770        let bits = Float.bitCastToInt(val)
12771        if (IS_LITTLE_ENDIAN) {
12772            if (this.buffer instanceof ArrayBuffer) {
12773                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12774                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
12775                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
12776                }
12777            } else if (this.buffer instanceof SharedArrayBuffer) {
12778                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; ++i) {
12779                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
12780                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
12781                }
12782            } else {
12783                throw new Error("unexpected type of ArrayBufferLike")
12784            }
12785        } else {
12786            if (this.buffer instanceof ArrayBuffer) {
12787                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; i++) {
12788                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
12789                    (this.buffer as ArrayBuffer).set(startByte + 3 - i, byteVal)
12790                }
12791            } else if (this.buffer instanceof SharedArrayBuffer) {
12792                for (let i = 0; i < Float32Array.BYTES_PER_ELEMENT as int; i++) {
12793                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
12794                    (this.buffer as SharedArrayBuffer).set(startByte + 3 - i, byteVal)
12795                }
12796            } else {
12797                throw new Error("unexpected type of ArrayBufferLike")
12798            }
12799        }
12800    }
12801
12802    /** Underlying ArrayBufferLike */
12803    public readonly buffer: ArrayBufferLike
12804
12805    /** Byte offset within the underlying ArrayBufferLike */
12806    public readonly byteOffset: number
12807
12808    /** Number of bytes used */
12809    public readonly byteLength: number
12810
12811    /** String \"Float32Array\" */
12812    public readonly name = "Float32Array"
12813}
12814
12815class Float64ArrayIteratorKeys implements IterableIterator<number> {
12816    private length: int
12817    private idx: int = 0
12818
12819    constructor(parent: Float64Array) {
12820        this.length = parent.length as int
12821    }
12822
12823    public override $_iterator(): IterableIterator<number> {
12824        return this
12825    }
12826
12827    override next(): IteratorResult<number> {
12828        if (this.idx < 0 || this.idx >= this.length) {
12829            return new IteratorResult<number>()
12830        }
12831        return new IteratorResult<number>(false, this.idx++ as number)
12832    }
12833}
12834
12835class Float64ArrayIterator implements IterableIterator<Number> {
12836    private parent: Float64Array
12837    private idx: int = 0
12838
12839    constructor(parent: Float64Array) {
12840        this.parent = parent
12841    }
12842
12843    public override $_iterator(): IterableIterator<Number> {
12844        return this
12845    }
12846
12847    override next(): IteratorResult<Number> {
12848        if (this.idx < 0 || this.idx >= this.parent.length as int) {
12849            return new IteratorResult<Number>()
12850        }
12851        return new IteratorResult<Number>(false, new Number(this.parent[this.idx++]))
12852    }
12853}
12854
12855class Float64ArrayIteratorEntries implements IterableIterator<[Number, Number]> {
12856    private parent: Float64Array
12857    private idx: int = 0
12858
12859    constructor(parent: Float64Array) {
12860        this.parent = parent
12861    }
12862
12863    public override $_iterator(): IterableIterator<[Number, Number]> {
12864        return this
12865    }
12866
12867    override next(): IteratorResult<[Number, Number]> {
12868        if (this.idx < 0 || this.idx >= this.parent.length as int) {
12869            return new IteratorResult<[Number, Number]>()
12870        }
12871        return new IteratorResult<[Number, Number]>(
12872            false, [new Number(this.idx), new Number(this.parent[this.idx++])]
12873        )
12874    }
12875}
12876
12877
12878/**
12879 * JS Float64Array API-compatible class
12880 */
12881export final class Float64Array implements Iterable<Number>, ArrayLike<Number> {
12882    public static readonly BYTES_PER_ELEMENT: number = 8
12883    internal readonly lengthInt: int
12884
12885    /**
12886     * Creates an empty Float64Array.
12887     */
12888    public constructor() {
12889        this(0 as int)
12890    }
12891
12892    /**
12893     * Creates an Float64Array with respect to data accessed via Iterable<Number> interface
12894     */
12895    public constructor(elements: Iterable<Number>) {
12896        // NOTE (ikorobkov): dealing with this overload is tricky
12897        // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
12898        let arr = Array.from<Number>(elements)
12899        this.byteLength = arr.length * Float64Array.BYTES_PER_ELEMENT as int
12900        this.lengthInt = arr.length as int
12901        this.buffer = new ArrayBuffer(this.byteLength as int)
12902        this.byteOffset = 0
12903        for (let i: int = 0; i < this.lengthInt; ++i) {
12904            this.setUnsafe(i, arr.$_get(i).doubleValue())
12905        }
12906    }
12907
12908    /**
12909     * Creates an Float64Array with respect to data, byteOffset and length.
12910     *
12911     * @param buf data initializer
12912     *
12913     * @param byteOffset byte offset from begin of the buf
12914     *
12915     * @param length size of elements of type double in newly created Float64Array
12916     */
12917    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined, length: Number | undefined) {
12918        let intByteOffset: int = 0
12919        if (byteOffset != undefined) {
12920            intByteOffset = byteOffset.intValue()
12921            if (intByteOffset < 0) {
12922                throw new RangeError("Range Error: byteOffset " + intByteOffset + " is outside the bounds of the buffer")
12923            }
12924        }
12925        let intByteLength: int
12926        if (buf instanceof ArrayBuffer) {
12927            intByteLength = (buf as ArrayBuffer).getByteLength()
12928        } else if (buf instanceof SharedArrayBuffer) {
12929            intByteLength = (buf as SharedArrayBuffer).getByteLength()
12930        } else {
12931            throw new Error("unexpected type of ArrayBufferLike")
12932        }
12933        intByteLength = intByteLength - intByteOffset
12934        if (intByteLength < 0) {
12935            throw new RangeError("Range Error: byteLength " + intByteLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
12936        }
12937
12938        if (intByteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
12939            throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
12940        }
12941        if (intByteOffset % Float64Array.BYTES_PER_ELEMENT as int != 0) {
12942            throw new RangeError("byteOffset should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
12943        }
12944
12945        let intLength: int
12946        if (length != undefined) {
12947            intLength = length.intValue()
12948            if (intLength > intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
12949                throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer with byteOffset " + intByteOffset)
12950            }
12951        } else {
12952            intLength = intByteLength / Float64Array.BYTES_PER_ELEMENT as int
12953        }
12954        if (intLength < 0) {
12955            throw new RangeError("Range Error: length " + intLength + " is outside the bounds of the buffer")
12956        }
12957        if (intLength < intByteLength / Float64Array.BYTES_PER_ELEMENT as int) {
12958            intByteLength = intLength * Float64Array.BYTES_PER_ELEMENT as int
12959        }
12960        this.byteLength = intByteLength
12961        this.byteOffset = intByteOffset
12962        this.lengthInt = intLength
12963        this.buffer = buf
12964    }
12965
12966    /**
12967     * Creates an Float64Array with respect to data, byteOffset and length.
12968     *
12969     * @param buf data initializer
12970     *
12971     * @param byteOffset byte offset from begin of the buf
12972     *
12973     * @param length size of elements of type double in newly created Float64Array
12974     */
12975    public constructor(buf: ArrayBufferLike, byteOffset: Number | undefined) {
12976        this(buf, byteOffset, undefined)
12977    }
12978
12979    /**
12980     * Creates an Float64Array with respect to data, byteOffset and length.
12981     *
12982     * @param buf data initializer
12983     *
12984     * @param byteOffset byte offset from begin of the buf
12985     *
12986     * @param length size of elements of type double in newly created Float64Array
12987     */
12988    public constructor(buf: ArrayBufferLike, byteOffset: number, length: number) {
12989        this(buf, new Number(byteOffset), new Number(length))
12990    }
12991
12992    /**
12993     * Creates an Float64Array with respect to data, byteOffset and length.
12994     *
12995     * @param buf data initializer
12996     *
12997     * @param byteOffset byte offset from begin of the buf
12998     *
12999     * @param length size of elements of type double in newly created Float64Array
13000     */
13001    public constructor(buf: ArrayBufferLike, byteOffset: number) {
13002        this(buf, new Number(byteOffset), undefined)
13003    }
13004
13005    /**
13006     * Creates an Float64Array with respect to data, byteOffset and length.
13007     *
13008     * @param buf data initializer
13009     *
13010     * @param byteOffset byte offset from begin of the buf
13011     *
13012     * @param length size of elements of type double in newly created Float64Array
13013     */
13014    public constructor(buf: ArrayBufferLike, byteOffset: int, length: int) {
13015        this(buf, new Number(byteOffset), new Number(length))
13016    }
13017
13018    /**
13019     * Creates an Float64Array with respect to buf and byteOffset.
13020     *
13021     * @param buf data initializer
13022     *
13023     * @param byteOffset byte offset from begin of the buf
13024     */
13025    public constructor(buf: ArrayBufferLike, byteOffset: int) {
13026        this(buf, new Number(byteOffset), undefined)
13027    }
13028
13029    /**
13030     * Creates an Float64Array with respect to buf.
13031     *
13032     * @param buf data initializer
13033     */
13034    public constructor(buf: ArrayLike<Number> | ArrayBufferLike) {
13035        if (buf instanceof ArrayBuffer) {
13036            this.byteLength = (buf as ArrayBuffer).getByteLength()
13037            if (this.byteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13038               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13039            }
13040            this.lengthInt = this.byteLength / Float64Array.BYTES_PER_ELEMENT as int
13041            this.buffer = buf as ArrayBuffer
13042            this.byteOffset = 0
13043        } else if (buf instanceof SharedArrayBuffer) {
13044            this.byteLength = (buf as SharedArrayBuffer).getByteLength()
13045            if (this.byteLength % Float64Array.BYTES_PER_ELEMENT as int != 0) {
13046               throw new RangeError("ArrayBufferLike.byteLength should be multiple of 8 as Float64Array.BYTES_PER_ELEMENT")
13047            }
13048            this.lengthInt = this.byteLength / Float64Array.BYTES_PER_ELEMENT as int
13049            this.buffer = buf as SharedArrayBuffer
13050            this.byteOffset = 0
13051        } else if (buf instanceof ArrayLike) {
13052            // NOTE (ikorobkov): dealing with this overload is tricky
13053            // with banned `instanceof` generic, so it is delegated to array here. Initial idea from Set.sts
13054            let arr = Array.from<Number>((buf as ArrayLike<Number>))
13055            this.byteLength = arr.length as int * Float64Array.BYTES_PER_ELEMENT as int
13056            this.lengthInt = arr.length as int
13057            this.buffer = new ArrayBuffer(this.byteLength as int)
13058            this.byteOffset = 0
13059            for (let i: int = 0; i < this.lengthInt; ++i) {
13060                this.setUnsafe(i, arr.$_get(i).doubleValue())
13061            }
13062        } else {
13063            throw new Error("unexpected type of buf")
13064        }
13065    }
13066
13067    /**
13068     * Creates an Float64Array with respect to length.
13069     *
13070     * @param length data initializer
13071     */
13072    public constructor(length: int) {
13073        if (length < 0) {
13074            throw new RangeError("Range Error: length " + length + " is outside the bounds of the buffer")
13075        }
13076        this.lengthInt = length
13077        this.byteLength = length * Float64Array.BYTES_PER_ELEMENT as int
13078        this.byteOffset = 0
13079        this.buffer = new ArrayBuffer(this.byteLength as int)
13080    }
13081
13082    /**
13083     * Creates an Float64Array with respect to length.
13084     *
13085     * @param length data initializer
13086     */
13087    public constructor(length: number) {
13088        this(length as int)
13089    }
13090
13091    /**
13092     * Creates a copy of Float64Array.
13093     *
13094     * @param other data initializer
13095     */
13096    public constructor(other: Float64Array) {
13097        if (other.buffer instanceof ArrayBuffer) {
13098            this.buffer = (other.buffer as ArrayBuffer).slice(0 as int, other.byteLength as int) as ArrayBuffer
13099        } else if (other.buffer instanceof SharedArrayBuffer) {
13100            this.buffer = (other.buffer as SharedArrayBuffer).slice(0 as int, other.byteLength as int) as SharedArrayBuffer
13101        } else {
13102            throw new Error("unexpected type of buffer")
13103        }
13104        this.byteLength = other.byteLength
13105        this.lengthInt = other.length as int
13106        this.byteOffset = 0
13107    }
13108
13109    /**
13110     * Creates an Float64Array from number[]
13111     */
13112    public constructor(numbers: number[]) {
13113        this(numbers.length)
13114        for (let i: int = 0; i < this.lengthInt; ++i) {
13115            this.setUnsafe(i, numbers[i] as double)
13116        }
13117    }
13118
13119    /**
13120     * Creates an Float64Array from int[]
13121     */
13122    public constructor(numbers: int[]) {
13123        this(numbers.length)
13124        for (let i: int = 0; i < this.lengthInt; ++i) {
13125            this.setUnsafe(i, numbers[i] as double)
13126        }
13127    }
13128
13129    /**
13130     * Assigns val as element on index.
13131     *
13132     * @param val value to set
13133     *
13134     * @param index index to change
13135     */
13136    public $_set(index: number, val: number): void {
13137        this.$_set(index as int, val)
13138    }
13139
13140    /**
13141     * Assigns val as element on index.
13142     *
13143     * @param val value to set
13144     *
13145     * @param index index to change
13146     */
13147    public $_set(index: int, val: number): void {
13148        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
13149        if (index < 0 || index >= this.lengthInt) {
13150            throw new RangeError("invalid index")
13151        }
13152        this.setUnsafe(index, val as double)
13153    }
13154
13155    /**
13156     * Assigns val as element on index.
13157     *
13158     * @param val value to set
13159     *
13160     * @param index index to change
13161     */
13162    public $_set(index: number, val: int): void {
13163        this.$_set(index as int, val)
13164    }
13165
13166    /**
13167     * Assigns val as element on index.
13168     *
13169     * @param val value to set
13170     *
13171     * @param index index to change
13172     */
13173    public $_set(index: int, val: int): void {
13174        // NOTE (ikorobkov): TS doesn't throw exception. Exception was added to avoid memory's out-of-range access
13175        if (index < 0 || index >= this.lengthInt) {
13176            throw new RangeError("invalid index")
13177        }
13178        this.setUnsafe(index, val as double)
13179    }
13180
13181    /** Number of double stored in Float64Array */
13182    public get length(): number {
13183        return this.lengthInt
13184    }
13185
13186    /**
13187     * Returns an instance of number at passed index.
13188     *
13189     * @param index index to look at
13190     *
13191     * @returns a primitive at index
13192     */
13193    public override $_get(index: number): Number {
13194        return this.$_get(index as int) as Number
13195    }
13196
13197    /**
13198     * Returns an instance of number at passed index.
13199     *
13200     * @param index index to look at
13201     *
13202     * @returns a primitive at index
13203     */
13204    public $_get(index: int): number {
13205        if (index < 0 || index >= this.lengthInt) {
13206            throw new RangeError("invalid index")
13207        }
13208        return this.getUnsafe(index) as number
13209    }
13210
13211    /**
13212     * Returns an instance of primitive type at passed index.
13213     *
13214     * @param index index to look at
13215     *
13216     * @returns a primitive at index
13217     */
13218    public at(index: number): Number | undefined {
13219        return this.at(index as int)
13220    }
13221
13222    /**
13223     * Returns an instance of primitive type at passed index.
13224     *
13225     * @param index index to look at
13226     *
13227     * @returns a primitive at index
13228     */
13229    public at(index: int): Number | undefined {
13230        let k: int
13231        if (index >= 0) {
13232            k = index
13233        } else {
13234            k = this.lengthInt + index
13235        }
13236        if (k < 0 || k >= this.lengthInt) {
13237            return undefined
13238        }
13239        return new Number(this.getUnsafe(k))
13240    }
13241
13242    /**
13243     * Makes a copy of internal elements to targetPos from startPos to endPos.
13244     *
13245     * @param target insert index to place copied elements
13246     *
13247     * @param start start index to begin copy from
13248     *
13249     * @param end last index to end copy from, excluded
13250     *
13251     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13252     */
13253    public copyWithin(target: number, start: number, end?: number): Float64Array {
13254        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13255    }
13256
13257    /**
13258     * Makes a copy of internal elements to targetPos from startPos to endPos.
13259     *
13260     * @param target insert index to place copied elements
13261     *
13262     * @param start start index to begin copy from
13263     *
13264     * @param end last index to end copy from, excluded
13265     *
13266     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13267     */
13268    public copyWithin(target: int, start: number, end?: number): Float64Array {
13269        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13270    }
13271
13272    /**
13273     * Makes a copy of internal elements to targetPos from startPos to endPos.
13274     *
13275     * @param target insert index to place copied elements
13276     *
13277     * @param start start index to begin copy from
13278     *
13279     * @param end last index to end copy from, excluded
13280     *
13281     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13282     */
13283    public copyWithin(target: number, start: int, end?: number): Float64Array {
13284        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13285    }
13286
13287    /**
13288     * Makes a copy of internal elements to targetPos from startPos to endPos.
13289     *
13290     * @param target insert index to place copied elements
13291     *
13292     * @param start start index to begin copy from
13293     *
13294     * @param end last index to end copy from, excluded
13295     *
13296     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13297     */
13298    public copyWithin(target: int, start: int, end?: number): Float64Array {
13299        return this.copyWithin(target as int, start as int, asIntOrDefault(end, this.lengthInt))
13300    }
13301
13302    /**
13303     * Makes a copy of internal elements to targetPos from startPos to endPos.
13304     *
13305     * @param target insert index to place copied elements
13306     *
13307     * @param start start index to begin copy from
13308     *
13309     * @param end last index to end copy from, excluded
13310     *
13311     * See rules of parameters normalization on {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin | MDN}
13312     */
13313    public copyWithin(target: int, start: int, end: int): Float64Array {
13314        let toPos = normalizeIndex(target, this.lengthInt)
13315        let fromPos = normalizeIndex(start, this.lengthInt)
13316        const finalPos = normalizeIndex(end, this.lengthInt)
13317        let count: int = finalPos - fromPos
13318        if (count > (this.lengthInt - toPos)) {
13319            count = this.lengthInt - toPos
13320        }
13321        let direction: int = 1
13322        if ((fromPos < toPos) && (toPos < fromPos + count)) {
13323            fromPos = fromPos + count - 1
13324            toPos   = toPos   + count - 1
13325            direction = -1
13326        }
13327        while (count > 0) {
13328            const value = this.getUnsafe(fromPos)
13329            this.setUnsafe(toPos, value)
13330            fromPos = fromPos + direction
13331            toPos = toPos + direction
13332            --count
13333        }
13334        return this
13335    }
13336
13337    /**
13338     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
13339     *
13340     * @param target insert index to place copied elements
13341     *
13342     * See rules of parameters normalization:
13343     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
13344     */
13345    public copyWithin(target: number): Float64Array {
13346        return this.copyWithin(target as int)
13347    }
13348
13349    /**
13350     * Makes a copy of internal elements to targetPos from begin to end of Float64Array.
13351     *
13352     * @param target insert index to place copied elements
13353     *
13354     * See rules of parameters normalization:
13355     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin}
13356     */
13357    public copyWithin(target: int): Float64Array {
13358        return this.copyWithin(target, 0, this.lengthInt)
13359    }
13360
13361    /**
13362     * Returns an array of key, value pairs for every entry in the Float64Array
13363     *
13364     * @returns key, value pairs for every entry in the array
13365     */
13366    public entries(): IterableIterator<[Number, Number]> {
13367        return new Float64ArrayIteratorEntries(this)
13368    }
13369
13370    /**
13371     * Fills the Float64Array with specified value
13372     *
13373     * @param value new valuy
13374     *
13375     * @returns modified Float64Array
13376     */
13377    public fill(value: number, start?: number, end?: number): this {
13378        this.fill(value as double, asIntOrDefault(start, 0 as int), asIntOrDefault(end, this.lengthInt))
13379        return this
13380    }
13381
13382    /**
13383     * Fills the Float64Array with specified value
13384     *
13385     * @param value new valuy
13386     *
13387     * @returns modified Float64Array
13388     */
13389    public fill(value: number, start: int, end?: number): this {
13390        this.fill(value as double, start as int, asIntOrDefault(end, this.lengthInt))
13391        return this
13392    }
13393
13394    /**
13395     * Fills the Float64Array with specified value
13396     *
13397     * @param value new valuy
13398     *
13399     * @returns modified Float64Array
13400     */
13401    public fill(value: number, start: int, end: number): this {
13402        this.fill(value as double, start as int, end as int)
13403        return this
13404    }
13405
13406    /**
13407     * Fills the Float64Array with specified value
13408     *
13409     * @param value new valuy
13410     *
13411     * @returns modified Float64Array
13412     */
13413    public fill(value: number, start: number, end: int): this {
13414        this.fill(value as double, start as int, end as int)
13415        return this
13416    }
13417
13418    /**
13419     * Fills the Float64Array with specified value
13420     *
13421     * @param value new valuy
13422     *
13423     * @returns modified Float64Array
13424     */
13425    public fill(value: number, start: int, end: int): this {
13426        const k = normalizeIndex(start, this.lengthInt)
13427        const finalPos = normalizeIndex(end, this.lengthInt)
13428        for (let i: int = k; i < finalPos; ++i) {
13429            this.setUnsafe(i, value)
13430        }
13431        return this
13432    }
13433
13434    /**
13435     * Assigns val as element on insertPos.
13436     * @description Added to avoid (un)packing a single value into array to use overloaded set(double[], insertPos)
13437     *
13438     * @param val value to set
13439     *
13440     * @param insertPos index to change
13441     */
13442    public set(insertPos: number, val: number): void {
13443        this.$_set(insertPos, val)
13444    }
13445
13446    /**
13447     * Assigns val as element on insertPos.
13448     * @description Added to avoid (un)packing a single value into array to use overloaded set(double[], insertPos)
13449     *
13450     * @param val value to set
13451     *
13452     * @param insertPos index to change
13453     */
13454    public set(insertPos: int, val: double): void {
13455        this.$_set(insertPos, val)
13456    }
13457
13458    /**
13459     * Copies all elements of arr to the current Float64Array starting from insertPos.
13460     *
13461     * @param arr array to copy data from
13462     *
13463     * @param insertPos start index where data from arr will be inserted
13464     *
13465     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
13466     */
13467    public set(arr: number[], insertPos: number): void {
13468        const offset = insertPos as int
13469        if (offset < 0 || offset + arr.length > this.lengthInt) {
13470            throw new RangeError("offset is out of bounds")
13471        }
13472        for (let i = 0; i < arr.length as int; ++i) {
13473            this.setUnsafe(offset + i, arr[i] as double)
13474        }
13475    }
13476
13477    /**
13478     * Copies all elements of arr to the current Float64Array starting from insertPos.
13479     *
13480     * @param arr array to copy data from
13481     *
13482     * @param insertPos start index where data from arr will be inserted
13483     *
13484     * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set}
13485     */
13486    public set(arr: double[], insertPos: int): void {
13487        const offset = insertPos as int
13488        if (offset < 0 || offset + arr.length > this.lengthInt) {
13489            throw new RangeError("offset is out of bounds")
13490        }
13491        for (let i = 0; i < arr.length as int; ++i) {
13492            this.setUnsafe(offset + i, arr[i])
13493        }
13494    }
13495
13496    /**
13497     * Copies all elements of arr to the current Float64Array.
13498     *
13499     * @param arr array to copy data from
13500     */
13501    public set(arr: double[]): void {
13502        this.set(arr, 0 as int)
13503    }
13504
13505    /**
13506     * Copies elements from an ArrayLike object to the Float64Array.
13507     *
13508     * @param array An ArrayLike object containing the elements to copy.
13509     *
13510     * @param offset Optional. The offset into the target array at which to begin writing values from the source array
13511     */
13512    public set(array: ArrayLike<number>, offset: number = 0): void {
13513        const insertPos = offset as int
13514        if (insertPos < 0 || insertPos + array.length > this.lengthInt) {
13515            throw new RangeError("offset is out of bounds")
13516        }
13517        for (let i = 0; i < array.length as int; ++i) {
13518            this.setUnsafe(insertPos + i, array[i] as double)
13519        }
13520    }
13521
13522    /**
13523     * Returns a new array from a set of elements.
13524     *
13525     * @param items a set of elements to include in the new array object.
13526     *
13527     * @returns new Float64Array
13528     */
13529    public static of(...items: number[]): Float64Array {
13530        let res = new Float64Array(items.length as int)
13531        for (let i: int = 0; i < items.length; i++) {
13532            res.setUnsafe(i, items[i])
13533        }
13534        return res
13535    }
13536
13537    /**
13538     * Returns a new array from a set of elements.
13539     *
13540     * @param items a set of elements to include in the new array object.
13541     *
13542     * @returns new Float64Array
13543     */
13544    public static of(...items: int[]): Float64Array {
13545        let res = new Float64Array(items.length as int)
13546        for (let i: int = 0; i < items.length; i++) {
13547            res.setUnsafe(i, items[i] as double)
13548        }
13549        return res
13550    }
13551
13552    /**
13553     * Returns a new array from a set of elements.
13554     *
13555     * @param items a set of elements to include in the new array object.
13556     *
13557     * @returns new Float64Array
13558     */
13559    public static of(): Float64Array {
13560        return new Float64Array(0 as int)
13561    }
13562
13563    /**
13564     * Creates an array from an array-like or iterable object.
13565     *
13566     * @param arrayLike An array-like or iterable object to convert to an array.
13567     *
13568     * @returns new Float64Array
13569     */
13570    public static from(arrayLike: ArrayLike<number>): Float64Array {
13571        return Float64Array.from<number>(arrayLike, (x: number, k: number): number => x)
13572    }
13573
13574    /**
13575     * Creates an array from an array-like or iterable object.
13576     *
13577     * @param arrayLike An array-like or iterable object to convert to an array.
13578     *
13579     * @param mapfn A mapping function to call on every element of the array.
13580     *
13581     * @returns new Float64Array
13582     */
13583    public static from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number): Float64Array {
13584        if (mapfn == undefined) {
13585            mapfn = (v: number, k: number): number => { return v }
13586        }
13587        // Calc length of items inside arrayLike, save length into i variable
13588        let i: long = 0
13589        let iter = arrayLike.$_iterator()
13590        while (true) {
13591            const v = iter.next()
13592            if (v.done) {
13593                break
13594            }
13595            i++
13596        }
13597
13598        let res = new Float64Array(i as int)
13599        i = 0
13600        iter = arrayLike.$_iterator()
13601        while (true) {
13602            const v = iter.next()
13603            if (v.done) {
13604                return res
13605            }
13606            res.setUnsafe(i as int, (mapfn)!(v.value as number, i as number) as double)
13607            i++
13608        }
13609    }
13610
13611
13612    /**
13613     * Creates an array from an array-like or iterable object.
13614     *
13615     * @param arrayLike An array-like or iterable object to convert to an array.
13616     *
13617     * @param mapfn A mapping function to call on every element of the array.
13618     *
13619     * @returns new Float64Array
13620     */
13621    public static from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => Number): Float64Array {
13622        let res = new Float64Array(arrayLike.length)
13623        // 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
13624        const idx = new int[1]
13625        idx[0] = 0
13626        iteratorForEach<T>(arrayLike.$_iterator(), (x: T): void => {
13627            res.setUnsafe(idx[0] as int, mapfn(x as T, idx[0] as number) as double)
13628            idx[0] += 1
13629        })
13630        return res
13631    }
13632
13633    /**
13634     * Determines whether Float64Array includes a certain element, returning true or false as appropriate
13635     *
13636     * @param searchElement The element to search for
13637     *
13638     * @param fromIndex The position in this array at which to begin searching for searchElement
13639     *
13640     * @returns true if searchElement is in Float64Array, false otherwise
13641     */
13642    public includes(searchElement: number, fromIndex?: number): boolean {
13643        if (isNaN(searchElement)) {
13644            let fromIndexInt: int = normalizeIndex(asIntOrDefault(fromIndex, 0), this.lengthInt)
13645            for (let i = fromIndexInt; i < this.lengthInt; i++) {
13646                if (isNaN(this.getUnsafe(i))) {
13647                    return true
13648                }
13649            }
13650            return false
13651        }
13652        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0)) != -1
13653    }
13654
13655    /**
13656     * Returns the index of the first occurrence of a value in Float64Array.
13657     *
13658     * @param searchElement The value to locate in the array.
13659     *
13660     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
13661     *  search starts at index 0.
13662     *
13663     * @returns index of element if it presents, -1 otherwise
13664     */
13665    public indexOf(searchElement: number, fromIndex?: number): number {
13666        return this.indexOf(searchElement, asIntOrDefault(fromIndex, 0))
13667    }
13668
13669    /**
13670     * Returns the index of the first occurrence of a value in Float64Array.
13671     *
13672     * @param searchElement The value to locate in the array.
13673     *
13674     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
13675     *  search starts at index 0.
13676     *
13677     * @returns index of element if it presents, -1 otherwise
13678     */
13679    public indexOf(searchElement: number, fromIndex: int): number {
13680        if (isNaN(searchElement)) {
13681            return -1
13682        }
13683        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
13684        for (let i = fromIndex; i < this.lengthInt; i++) {
13685            if (this.getUnsafe(i) == searchElement) {
13686                return i
13687            }
13688        }
13689        return -1
13690    }
13691
13692    /**
13693     * Returns the index of the first occurrence of a value in Float64Array.
13694     *
13695     * @param searchElement The value to locate in the array.
13696     *
13697     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
13698     *  search starts at index 0.
13699     *
13700     * @returns index of element if it presents, -1 otherwise
13701     */
13702    public indexOf(searchElement: int, fromIndex: int): number {
13703        fromIndex = normalizeIndex(fromIndex, this.lengthInt)
13704        for (let i = fromIndex; i < this.lengthInt; i++) {
13705            if (this.getUnsafe(i) == searchElement as double) {
13706                return i
13707            }
13708        }
13709        return -1
13710    }
13711
13712    /**
13713     * Returns the index of the first occurrence of a value in Float64Array.
13714     *
13715     * @param searchElement The value to locate in the array.
13716     *
13717     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the
13718     *  search starts at index 0.
13719     *
13720     * @returns index of element if it presents, -1 otherwise
13721     */
13722    public indexOf(searchElement: int): number {
13723        return this.indexOf(searchElement, 0)
13724    }
13725
13726    /**
13727     * Adds all the elements of an array separated by the specified separator string
13728     *
13729     * @param separator A string used to separate one element of an array from the next in the
13730     * resulting String. If omitted, the array elements are separated with a comma
13731     *
13732     * @returns joined representation
13733     */
13734    public join(separator?: String): string {
13735        if (separator == undefined) {
13736            return this.join(",")
13737        }
13738        let res: StringBuilder = new StringBuilder("")
13739        for (let i = 0; i < this.lengthInt - 1; ++i) {
13740            res.append(this.getUnsafe(i) as number)
13741            res.append(separator)
13742        }
13743        if (this.lengthInt > 0) {
13744            res.append(this.getUnsafe(this.lengthInt - 1) as number)
13745        }
13746        return res.toString()
13747    }
13748
13749    /**
13750     * Returns an list of keys in Float64Array
13751     *
13752     * @returns iterator over keys
13753     */
13754    public keys(): IterableIterator<number> {
13755        return new Float64ArrayIteratorKeys(this)
13756    }
13757
13758    /**
13759     * Returns the index of the last occurrence of a value in Float64Array.
13760     *
13761     * @param searchElement The value to locate in the array.
13762     *
13763     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
13764     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
13765     *
13766     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
13767     */
13768    public lastIndexOf(searchElement: number, fromIndex: number|undefined): number {
13769        return this.lastIndexOf(searchElement, asIntOrDefault(fromIndex, 0))
13770    }
13771
13772    /**
13773     * Returns the index of the last occurrence of a value in Float64Array.
13774     *
13775     * @param searchElement The value to locate in the array.
13776     *
13777     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
13778     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
13779     *
13780     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
13781     */
13782    public lastIndexOf(searchElement: number): number {
13783        return this.lastIndexOf(searchElement, this.lengthInt - 1)
13784    }
13785
13786    /**
13787     * Returns the index of the last occurrence of a value in Float64Array.
13788     *
13789     * @param searchElement The value to locate in the array.
13790     *
13791     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
13792     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
13793     *
13794     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
13795     */
13796    public lastIndexOf(searchElement: number, fromIndex: int): number {
13797        if (isNaN(searchElement)) {
13798            return -1
13799        }
13800        if (this.lengthInt == 0) {
13801            return -1
13802        }
13803        let k: int = this.lengthInt + fromIndex
13804        if (fromIndex >= 0) {
13805            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
13806        }
13807        while (k >= 0) {
13808            if (this.getUnsafe(k) == searchElement) {
13809                return k
13810            }
13811            k--
13812        }
13813        return -1
13814    }
13815
13816    /**
13817     * Returns the index of the last occurrence of a value in Float64Array.
13818     *
13819     * @param searchElement The value to locate in the array.
13820     *
13821     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
13822     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
13823     *
13824     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
13825     */
13826    public lastIndexOf(searchElement: int, fromIndex: int): number {
13827        if (this.lengthInt == 0) {
13828            return -1
13829        }
13830        let k: int = this.lengthInt + fromIndex
13831        if (fromIndex >= 0) {
13832            k = (this.lengthInt - 1 < fromIndex) ? this.lengthInt - 1 : fromIndex
13833        }
13834        while (k >= 0) {
13835            if (this.getUnsafe(k) == searchElement as double) {
13836                return k
13837            }
13838            k--
13839        }
13840        return -1
13841    }
13842
13843    /**
13844     * Returns the index of the last occurrence of a value in Float64Array.
13845     *
13846     * @param searchElement The value to locate in the array.
13847     *
13848     * @param fromIndex The array index at which to begin the search. If fromIndex is undefined, the
13849     * search starts at index 0. If fromIndex is ommited, the search begins at index length-1
13850     *
13851     * @returns right-most index of searchElement. It must be less or equal than fromIndex. -1 if not found
13852     */
13853    public lastIndexOf(searchElement: int): number {
13854        return this.lastIndexOf(searchElement, this.lengthInt - 1)
13855    }
13856
13857    /**
13858    * Creates a new Float64Array using initializer
13859    *
13860    * @param data initializer
13861    *
13862    * @returns a new Float64Array from data
13863    */
13864    public of(data: Object[]): Float64Array {
13865        throw new Error("Float64Array.of: not implemented")
13866    }
13867
13868    /**
13869     * Creates a new Float64Array using reversed data from the current one
13870     *
13871     * @returns a new Float64Array using reversed data from the current one
13872     */
13873    public reverse(): Float64Array {
13874        for (let i: int = 0; i < this.lengthInt / 2 as int; i++) {
13875            const tmp = this.getUnsafe(this.lengthInt - 1 - i)
13876            this.setUnsafe(this.lengthInt - 1 - i, this.getUnsafe(i))
13877            this.setUnsafe(i, tmp)
13878        }
13879        return this
13880    }
13881
13882    /**
13883     * Creates a slice of current Float64Array using range [begin, end)
13884     *
13885     * @param begin start index to be taken into slice
13886     *
13887     * @param end last index to be taken into slice
13888     *
13889     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
13890     *
13891     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
13892     */
13893    public slice(begin?: number, end?: number): Float64Array {
13894        return this.slice(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
13895    }
13896
13897    /**
13898     * Creates a slice of current Float64Array using range [begin, end)
13899     *
13900     * @param begin start index to be taken into slice
13901     *
13902     * @param end last index to be taken into slice
13903     *
13904     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
13905     *
13906     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
13907     */
13908    public slice(begin: number, end: number): Float64Array {
13909        return this.slice(begin as int, end as int)
13910    }
13911
13912    /**
13913     * Creates a slice of current Float64Array using range [begin, end)
13914     *
13915     * @param begin start index to be taken into slice
13916     *
13917     * @param end last index to be taken into slice
13918     *
13919     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
13920     *
13921     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
13922     */
13923    public slice(begin: number, end: int): Float64Array {
13924        return this.slice(begin as int, end as int)
13925    }
13926
13927    /**
13928     * Creates a slice of current Float64Array using range [begin, end)
13929     *
13930     * @param begin start index to be taken into slice
13931     *
13932     * @param end last index to be taken into slice
13933     *
13934     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
13935     *
13936     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
13937     */
13938    public slice(begin: int, end: number): Float64Array {
13939        return this.slice(begin as int, end as int)
13940    }
13941
13942    /**
13943     * Creates a slice of current Float64Array using range [begin, end)
13944     *
13945     * @param begin start index to be taken into slice
13946     *
13947     * @param end last index to be taken into slice
13948     *
13949     * @returns a new Float64Array with elements of current Float64Array[begin;end) where end index is excluded
13950     *
13951     * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice
13952     */
13953    public slice(begin: int, end: int): Float64Array {
13954        const len: int = this.lengthInt
13955        const relStart = normalizeIndex(begin, len)
13956        const relEnd = normalizeIndex(end, len)
13957        let count = relEnd - relStart
13958        if (count < 0) {
13959            count = 0
13960        }
13961        if (this.buffer instanceof ArrayBuffer) {
13962            let buf = (this.buffer as ArrayBuffer).slice(relStart * Float64Array.BYTES_PER_ELEMENT as int, relEnd * Float64Array.BYTES_PER_ELEMENT as int) as ArrayBuffer
13963            return new Float64Array(buf)
13964        } else if (this.buffer instanceof SharedArrayBuffer) {
13965            let buf = (this.buffer as SharedArrayBuffer).slice(relStart * Float64Array.BYTES_PER_ELEMENT as int, relEnd * Float64Array.BYTES_PER_ELEMENT as int) as SharedArrayBuffer
13966            return new Float64Array(buf)
13967        } else {
13968            throw new Error("unexpected type of buffer")
13969        }
13970    }
13971
13972    /**
13973     * Creates a slice of current Float64Array using range [begin, this.length).
13974     *
13975     * @param begin start index to be taken into slice
13976     *
13977     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
13978     */
13979    public slice(begin: number): Float64Array {
13980        return this.slice(begin as int)
13981    }
13982
13983    /**
13984     * Creates a slice of current Float64Array using range [begin, this.length).
13985     *
13986     * @param begin start index to be taken into slice
13987     *
13988     * @returns a new Float64Array with elements of current Float64Array[begin, this.length)
13989     */
13990    public slice(begin: int): Float64Array {
13991        return this.slice(begin, this.lengthInt)
13992    }
13993
13994    /**
13995     * Creates a Float64Array with the same underlying ArrayBufferLike
13996     *
13997     * @param begin start index, inclusive
13998     *
13999     * @param end last index, exclusive
14000     *
14001     * @returns new Float64Array with the same underlying ArrayBufferLike
14002     */
14003    public subarray(begin?: number, end?: number): Float64Array {
14004        return this.subarray(asIntOrDefault(begin, 0 as int), asIntOrDefault(end, this.lengthInt))
14005    }
14006
14007    /**
14008     * Creates a Float64Array with the same underlying ArrayBufferLike
14009     *
14010     * @param begin start index, inclusive
14011     *
14012     * @param end last index, exclusive
14013     *
14014     * @returns new Float64Array with the same underlying ArrayBufferLike
14015     */
14016    public subarray(begin: number, end: number): Float64Array {
14017        return this.subarray(begin as int, end as int)
14018    }
14019
14020    /**
14021     * Creates a Float64Array with the same underlying ArrayBufferLike
14022     *
14023     * @param begin start index, inclusive
14024     *
14025     * @param end last index, exclusive
14026     *
14027     * @returns new Float64Array with the same underlying ArrayBufferLike
14028     */
14029    public subarray(begin: number, end: int): Float64Array {
14030        return this.subarray(begin as int, end as int)
14031    }
14032
14033    /**
14034     * Creates a Float64Array with the same underlying ArrayBufferLike
14035     *
14036     * @param begin start index, inclusive
14037     *
14038     * @param end last index, exclusive
14039     *
14040     * @returns new Float64Array with the same underlying ArrayBufferLike
14041     */
14042    public subarray(begin: int, end: number): Float64Array {
14043        return this.subarray(begin as int, end as int)
14044    }
14045
14046    /**
14047     * Creates a Float64Array with the same underlying ArrayBufferLike
14048     *
14049     * @param begin start index, inclusive
14050     *
14051     * @param end last index, exclusive
14052     *
14053     * @returns new Float64Array with the same underlying ArrayBufferLike
14054     */
14055    public subarray(begin: int, end: int): Float64Array {
14056        const len: int = this.lengthInt
14057        const relStart = normalizeIndex(begin, len)
14058        const relEnd = normalizeIndex(end, len)
14059        let count = relEnd - relStart
14060        if (count < 0) {
14061            count = 0
14062        }
14063        return new Float64Array(this.buffer, relStart * Float64Array.BYTES_PER_ELEMENT as int, count)
14064    }
14065
14066    /**
14067     * Creates a Float64Array with the same ArrayBufferLike
14068     *
14069     * @param begin start index, inclusive
14070     *
14071     * @returns new Float64Array with the same ArrayBufferLike
14072     */
14073    public subarray(begin: number): Float64Array {
14074        return this.subarray(begin as int, this.lengthInt)
14075    }
14076
14077    /**
14078     * Creates a Float64Array with the same ArrayBufferLike
14079     *
14080     * @param begin start index, inclusive
14081     *
14082     * @returns new Float64Array with the same ArrayBufferLike
14083     */
14084    public subarray(begin: int): Float64Array {
14085        return this.subarray(begin as int, this.lengthInt)
14086    }
14087
14088    /**
14089     * Converts Float64Array to a string with respect to locale
14090     *
14091     * @param locales
14092     *
14093     * @param options
14094     *
14095     * @returns string representation
14096     */
14097    public toLocaleString(locales: Object, options: Object): string {
14098        throw new Error("Float64Array.toLocaleString: not implemented")
14099    }
14100
14101    /**
14102     * Converts Float64Array to a string with respect to locale
14103     *
14104     * @param locales
14105     *
14106     * @returns string representation
14107     */
14108    public toLocaleString(locales: Object): string {
14109        return this.toLocaleString(new Object(), new Object())
14110    }
14111
14112    /**
14113     * Converts Float64Array to a string with respect to locale
14114     *
14115     * @returns string representation
14116     */
14117    public toLocaleString(): string {
14118        let res: StringBuilder = new StringBuilder("")
14119        for (let i = 0; i < this.lengthInt - 1; ++i) {
14120            res.append((this.getUnsafe(i) as Number).toLocaleString())
14121            res.append(",")
14122        }
14123        if (this.lengthInt > 0) {
14124            res.append((this.getUnsafe(this.lengthInt - 1) as Number).toLocaleString())
14125        }
14126        return res.toString()
14127    }
14128
14129    /**
14130     * Creates a reversed copy
14131     *
14132     * @returns a reversed copy
14133     */
14134    public toReversed(): Float64Array {
14135        return new Float64Array(this).reverse()
14136    }
14137
14138    /**
14139     * Creates a sorted copy
14140     *
14141     * @returns a sorted copy
14142     */
14143    public toSorted(): Float64Array {
14144        return new Float64Array(this).sort()
14145    }
14146
14147    /**
14148     * Returns a string representation of the Float64Array
14149     *
14150     * @returns a string representation of the Float64Array
14151     */
14152    public override toString(): string {
14153        return this.join(",")
14154    }
14155
14156    /**
14157     * Returns array values iterator
14158     *
14159     * @returns an iterator
14160     */
14161    public values(): IterableIterator<Number> {
14162        return new Float64ArrayIterator(this)
14163    }
14164
14165    /**
14166     * Iteratorable interface implementation
14167     *
14168     * @returns iterator over all elements
14169     */
14170    public override $_iterator(): IterableIterator<Number> {
14171        return this.values()
14172    }
14173
14174    /**
14175     * Creates a copy with replaced value on index
14176     *
14177     * @param index
14178     *
14179     * @param value
14180     *
14181     * @returns an Float64Array with replaced value on index
14182     */
14183    public with(index: number, value: number): Float64Array {
14184        return this.with(index as int, value as double)
14185    }
14186
14187    /**
14188     * Creates a copy with replaced value on index
14189     *
14190     * @param index
14191     *
14192     * @param value
14193     *
14194     * @returns an Float64Array with replaced value on index
14195     */
14196    public with(index: int, value: double): Float64Array {
14197        let res = new Float64Array(this)
14198        res.set(index, value)
14199        return res
14200    }
14201
14202    /// === with element lambda functions ===
14203    /**
14204     * Determines whether the specified callback function returns true for all elements of an array.
14205     *
14206     * @param predicate A function that accepts one argument.
14207     * The every method calls the predicate function for each element in the array until the predicate returns a false,
14208     * or until the end of the array.
14209     *
14210     * @returns true unless predicate function returns a false for an array element,
14211     * in which case false is immediately returned.
14212     */
14213    public every(predicate: (element: number) => boolean): boolean {
14214        return this.every((element: number, index: number, array: Float64Array): boolean => predicate(element))
14215    }
14216
14217    /**
14218     * creates a new Float64Array from current Float64Array based on a condition fn
14219     *
14220     * @param fn the condition to apply for each element
14221     *
14222     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
14223     */
14224    public filter(fn: (val: number) => boolean): Float64Array {
14225        let newF: (val: number, index: number, array: Float64Array) => boolean =
14226            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14227        return this.filter(newF)
14228    }
14229
14230    /**
14231     * Returns the value of the first element in the array where predicate is true, and undefined
14232     * otherwise
14233     *
14234     * @param predicate find calls predicate once for each element of the array, in ascending
14235     * order, until it finds one where predicate returns true. If such an element is found, find
14236     * immediately returns that element value. Otherwise, find returns undefined
14237     *
14238     * @returns number | undefined
14239     */
14240    public find(predicate: () => boolean): number | undefined {
14241        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate())
14242    }
14243
14244    /**
14245     * Returns the value of the first element in the array where predicate is true, and undefined
14246     * otherwise
14247     *
14248     * @param predicate find calls predicate once for each element of the array, in ascending
14249     * order, until it finds one where predicate returns true. If such an element is found, find
14250     * immediately returns that element value. Otherwise, find returns undefined
14251     *
14252     * @returns number | undefined
14253     */
14254    public find(predicate: (value: number) => boolean): number | undefined {
14255        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate(value))
14256    }
14257
14258    /**
14259     * Returns the index of the first element in the array where predicate is true, and -1
14260     * otherwise
14261     *
14262     * @param predicate find calls predicate once for each element of the array, in ascending
14263     * order, until it finds one where predicate returns true. If such an element is found,
14264     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
14265     *
14266     * @returns number
14267     */
14268    public findIndex(predicate: (value: number) => boolean): number {
14269        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate(value)) as number
14270    }
14271
14272    /**
14273     * Finds the last element in the Float64Array that satisfies the condition
14274     *
14275     * @param fn condition
14276     *
14277     * @returns the last element that satisfies fn
14278     */
14279    public findLast(fn: (val: number) => boolean): number {
14280        let newF: (val: number, index: number, array: Float64Array) => boolean =
14281            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14282        return this.findLast(newF) as number
14283    }
14284
14285    /**
14286     * Finds an index of the last element in the Float64Array that satisfies the condition
14287     *
14288     * @param fn condition
14289     *
14290     * @returns the index of the last element that satisfies fn, -1 otherwise
14291     */
14292    public findLastIndex(fn: (val: number) => boolean): number {
14293        let newF: (val: number, index: number, array: Float64Array) => boolean =
14294            (val: number, index: number, array: Float64Array): boolean => { return fn(val) }
14295        return this.findLastIndex(newF) as number
14296    }
14297
14298    /**
14299     * Performs the specified action for each element in Float64Array
14300     *
14301     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
14302     * callbackfn function one time for each element in the array.
14303     *
14304     * @returns None
14305     */
14306    public forEach(callbackfn: (value: number) => void): void {
14307        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn(value))
14308    }
14309
14310    /**
14311     * Creates a new Float64Array using fn(arr[i]) over all elements of current Float64Array
14312     *
14313     * @param fn a function to apply for each element of current Float64Array
14314     *
14315     * @returns a new Float64Array where for each element from current Float64Array fn was applied
14316     */
14317    public map(fn: (val: number) => number): Float64Array {
14318        let newF: (val: number, index: number) => number =
14319            (val: number, index: number): number => { return fn(val) }
14320        return this.map(newF)
14321    }
14322
14323    /**
14324     * Determines whether the specified callback function returns true for any element of an array.
14325     *
14326     * @param predicate A function that accepts one argument.
14327     * The some method calls the predicate function for each element in the array
14328     * until the predicate returns a true or until the end of the array.
14329     *
14330     * @returns false unless predicate function returns true for an array element,
14331     * in which case true is immediately returned.
14332     */
14333    public some(predicate: (element: number) => boolean): boolean {
14334        return this.some((element: number, index: number, array: Float64Array): boolean => predicate(element))
14335    }
14336
14337    // NOTE (kprokopenko): this may be not skipped
14338    /**
14339     * Sorts in-place
14340     *
14341     * @param compareFn comparator —  used to determine the order of the elements.
14342     * compareFn returns a negative value if first argument is less than second argument,
14343     * zero if they're equal and a positive value otherwise.
14344     * If omitted, the elements are sorted in ascending order.
14345     *
14346     * @returns sorted Float64Array
14347     */
14348    public sort(compareFn?: (a: number, b: number) => number): this {
14349        let arr: double[] = new double[this.lengthInt]
14350        for (let i = 0; i < this.lengthInt; ++i) {
14351            arr[i] = this.getUnsafe(i)
14352        }
14353        let cmp = (l: double, r: double): number => {
14354                return (l - r) as number
14355            }
14356        if (compareFn != undefined) {
14357            cmp = (l: double, r: double): number => {
14358                return compareFn!(l as number, r as number)
14359            }
14360        }
14361        sort(arr, cmp)
14362        for (let i = 0; i < this.lengthInt; ++i) {
14363            this.setUnsafe(i, arr[i])
14364        }
14365        return this
14366    }
14367
14368    /**
14369     * Sorts in-place
14370     *
14371     * @param compareFn comparator —  used to determine the order of the elements.
14372     * compareFn returns a negative value if first argument is less than second argument,
14373     * zero if they're equal and a positive value otherwise.
14374     *
14375     * @returns sorted Float64Array
14376     */
14377    public sort(compareFn: (a: number) => number): this {
14378        let cmp = (a: number, b: number) => { return compareFn(a)}
14379        this.sort(cmp)
14380        return this
14381    }
14382
14383    /**
14384     * Sorts in-place
14385     *
14386     * @param fn compareFn —  used to determine the order of the elements.
14387     * compareFn returns a negative value if first argument is less than second argument,
14388     * zero if they're equal and a positive value otherwise.
14389     *
14390     * @returns sorted Float64Array
14391     */
14392    public sort(compareFn: () => number): this {
14393        let cmp = (a: number, b: number) => { return compareFn()}
14394        this.sort(cmp)
14395        return this
14396    }
14397
14398    /**
14399     * Determines whether the specified callback function returns true for any element of an array.
14400     *
14401     * @param predicate A function that accepts three arguments.
14402     * The some method calls the predicate function for each element in the array
14403     * until the predicate returns a true or until the end of the array.
14404     *
14405     * @returns false unless predicate function returns true for an array element,
14406     * in which case true is immediately returned.
14407     */
14408    public some(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
14409        for (let i = 0; i < this.lengthInt; ++i) {
14410            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
14411                return true
14412            }
14413        }
14414        return false
14415    }
14416
14417    /**
14418     * Determines whether the specified callback function returns true for any element of an array.
14419     *
14420     * @param predicate A function that accepts two arguments.
14421     * The some method calls the predicate function for each element in the array
14422     * until the predicate returns a true or until the end of the array.
14423     *
14424     * @returns false unless predicate function returns true for an array element,
14425     * in which case true is immediately returned.
14426     */
14427    public some(predicate: (element: number, index: number) => boolean): boolean {
14428        return this.some((element: number, index: number, array: Float64Array): boolean => predicate(element, index as number))
14429    }
14430
14431    /**
14432     * Determines whether the specified callback function returns true for any element of an array.
14433     *
14434     * @param predicate A function that accepts no arguments.
14435     * The some method calls the predicate function for each element in the array
14436     * until the predicate returns a true or until the end of the array.
14437     *
14438     * @returns false unless predicate function returns true for an array element,
14439     * in which case true is immediately returned.
14440     */
14441    public some(predicate: () => boolean): boolean {
14442        return this.some((element: number, index: number, array: Float64Array): boolean => predicate())
14443    }
14444
14445    /**
14446     * Calls the specified callback function for all the elements in an array.
14447     * The return value of the callback function is the accumulated result,
14448     * and is provided as an argument in the next call to the callback function.
14449     *
14450     * @param callbackfn A function that accepts four arguments.
14451     * The reduce method calls the callbackfn function one time for each element in the array.
14452     *
14453     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14454     * The first call to the callbackfn function provides this value as an argument.
14455     *
14456     * @returns The value that results from running the callback function to completion over the entire typed array.
14457     */
14458    public reduce<U = number>(
14459                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
14460                initialValue: U): U {
14461        let accumulatedValue = initialValue
14462        for (let i = 0; i < this.lengthInt; ++i) {
14463            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14464        }
14465        return accumulatedValue
14466    }
14467
14468    /**
14469     * Calls the specified callback function for all the elements in an array.
14470     * The return value of the callback function is the accumulated result,
14471     * and is provided as an argument in the next call to the callback function.
14472     *
14473     * @param callbackfn A function that accepts three arguments.
14474     * The reduce method calls the callbackfn function one time for each element in the array.
14475     *
14476     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14477     * The first call to the callbackfn function provides this value as an argument.
14478     *
14479     * @returns The value that results from running the callback function to completion over the entire typed array.
14480     */
14481    public reduce<U = number>(
14482                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
14483                initialValue: U): U {
14484        return this.reduce(
14485                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14486                        callbackfn(prevVal, currVal, currIndex), initialValue)
14487    }
14488
14489    /**
14490     * Calls the specified callback function for all the elements in an array.
14491     * The return value of the callback function is the accumulated result,
14492     * and is provided as an argument in the next call to the callback function.
14493     *
14494     * @param callbackfn A function that accepts two arguments.
14495     * The reduce method calls the callbackfn function one time for each element in the array.
14496     *
14497     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14498     * The first call to the callbackfn function provides this value as an argument.
14499     *
14500     * @returns The value that results from running the callback function to completion over the entire typed array.
14501     */
14502    public reduce<U = number>(
14503                callbackfn: (previousValue: U, currentValue: number) => U,
14504                initialValue: U): U {
14505        return this.reduce(
14506                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14507                        callbackfn(prevVal, currVal), initialValue)
14508    }
14509
14510    /**
14511     * Calls the specified callback function for all the elements in an array.
14512     * The return value of the callback function is the accumulated result,
14513     * and is provided as an argument in the next call to the callback function.
14514     *
14515     * @param callbackfn A function that accepts one argument
14516     * The reduce method calls the callbackfn function one time for each element in the array.
14517     *
14518     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14519     * The first call to the callbackfn function provides this value as an argument.
14520     *
14521     * @returns The value that results from running the callback function to completion over the entire typed array.
14522     */
14523    public reduce<U = number>(
14524                callbackfn: (previousValue: U) => U,
14525                initialValue: U): U {
14526        return this.reduce(
14527                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14528                        callbackfn(prevVal), initialValue)
14529    }
14530
14531    /**
14532     * Calls the specified callback function for all the elements in an array.
14533     * The return value of the callback function is the accumulated result,
14534     * and is provided as an argument in the next call to the callback function.
14535     *
14536     * @param callbackfn A function that accepts no arguments
14537     * The reduce method calls the callbackfn function one time for each element in the array.
14538     *
14539     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14540     * The first call to the callbackfn function provides this value as an argument.
14541     *
14542     * @returns The value that results from running the callback function to completion over the entire typed array.
14543     */
14544    public reduce<U = number>(
14545                callbackfn: () => U,
14546                initialValue: U): U {
14547        return this.reduce(
14548                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14549                        callbackfn(), initialValue)
14550    }
14551
14552    /**
14553     * Calls the specified callback function for all the elements in an array.
14554     * The return value of the callback function is the accumulated result,
14555     * and is provided as an argument in the next call to the callback function.
14556     *
14557     * @param callbackfn A function that accepts four arguments.
14558     * The reduce method calls the callbackfn function one time for each element in the array.
14559     * The first call to the callbackfn function provides array first element value as an argument
14560     *
14561     * @returns The value that results from running the callback function to completion over the entire typed array.
14562     * calling reduce method on an empty array without an initial value creates a TypeError
14563     */
14564    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
14565        if (this.lengthInt == 0) {
14566            throw new TypeError("Reduce of empty array with no initial value")
14567        }
14568
14569        let accumulatedValue = this.getUnsafe(0) as number
14570        for (let i = 1; i < this.lengthInt; ++i) {
14571            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14572        }
14573        return accumulatedValue
14574    }
14575
14576    /**
14577     * Calls the specified callback function for all the elements in an array.
14578     * The return value of the callback function is the accumulated result,
14579     * and is provided as an argument in the next call to the callback function.
14580     *
14581     * @param callbackfn A function that accepts three arguments.
14582     * The reduce method calls the callbackfn function one time for each element in the array.
14583     * The first call to the callbackfn function provides array first element value as an argument
14584     *
14585     * @returns The value that results from running the callback function to completion over the entire typed array.
14586     * calling reduce method on an empty array without an initial value creates a TypeError
14587     */
14588    public reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
14589        return this.reduce(
14590                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14591                        callbackfn(prevVal, currVal, currIndex))
14592    }
14593
14594    /**
14595     * Calls the specified callback function for all the elements in an array.
14596     * The return value of the callback function is the accumulated result,
14597     * and is provided as an argument in the next call to the callback function.
14598     *
14599     * @param callbackfn A function that accepts two arguments.
14600     * The reduce method calls the callbackfn function one time for each element in the array.
14601     * The first call to the callbackfn function provides array first element value as an argument
14602     *
14603     * @returns The value that results from running the callback function to completion over the entire typed array.
14604     * calling reduce method on an empty array without an initial value creates a TypeError
14605     */
14606    public reduce(callbackfn: (previousValue: number, currentValue: number) => number): number {
14607        return this.reduce(
14608                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14609                        callbackfn(prevVal, currVal))
14610    }
14611
14612    /**
14613     * Calls the specified callback function for all the elements in an array.
14614     * The return value of the callback function is the accumulated result,
14615     * and is provided as an argument in the next call to the callback function.
14616     *
14617     * @param callbackfn A function that accepts one argument.
14618     * The reduce method calls the callbackfn function one time for each element in the array.
14619     * The first call to the callbackfn function provides array first element value as an argument
14620     *
14621     * @returns The value that results from running the callback function to completion over the entire typed array.
14622     * calling reduce method on an empty array without an initial value creates a TypeError
14623     */
14624    public reduce(callbackfn: (previousValue: number) => number): number {
14625        return this.reduce(
14626                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14627                        callbackfn(prevVal))
14628    }
14629
14630    /**
14631     * Calls the specified callback function for all the elements in an array.
14632     * The return value of the callback function is the accumulated result,
14633     * and is provided as an argument in the next call to the callback function.
14634     *
14635     * @param callbackfn A function that accepts no arguments.
14636     * The reduce method calls the callbackfn function one time for each element in the array.
14637     * The first call to the callbackfn function provides array first element value as an argument
14638     *
14639     * @returns The value that results from running the callback function to completion over the entire typed array.
14640     * calling reduce method on an empty array without an initial value creates a TypeError
14641     */
14642    public reduce(callbackfn: () => number): number {
14643        return this.reduce(
14644                (prevVal: number, currVal: number, currIndex: number, array: Float64Array) =>
14645                        callbackfn())
14646    }
14647
14648
14649    /**
14650     * Calls the specified callback function for all the elements in an array, in descending order.
14651     * The return value of the callback function is the accumulated result,
14652     * and is provided as an argument in the next call to the callback function.
14653     *
14654     * @param callbackfn A function that accepts four arguments.
14655     * The reduceRight method calls the callbackfn function one time for each element in the array.
14656     *
14657     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14658     * The first call to the callbackfn function provides this value as an argument.
14659     *
14660     * @returns The value that results from running the callback function to completion over the entire typed array.
14661     */
14662    public reduceRight<U = number>(
14663                callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U,
14664                initialValue: U): U {
14665        let accumulatedValue = initialValue
14666        for (let i = this.lengthInt - 1; i >= 0; --i) {
14667            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14668        }
14669        return accumulatedValue
14670    }
14671
14672    /**
14673     * Calls the specified callback function for all the elements in an array, in descending order.
14674     * The return value of the callback function is the accumulated result,
14675     * and is provided as an argument in the next call to the callback function.
14676     *
14677     * @param callbackfn A function that accepts three arguments.
14678     * The reduceRight method calls the callbackfn function one time for each element in the array.
14679     *
14680     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14681     * The first call to the callbackfn function provides this value as an argument.
14682     *
14683     * @returns The value that results from running the callback function to completion over the entire typed array.
14684     */
14685    public reduceRight<U = number>(
14686                callbackfn: (previousValue: U, currentValue: number, currentIndex: number) => U,
14687                initialValue: U): U {
14688        return this.reduceRight(
14689                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14690                        callbackfn(prevVal, currVal, currIndex), initialValue)
14691    }
14692
14693    /**
14694     * Calls the specified callback function for all the elements in an array, in descending order.
14695     * The return value of the callback function is the accumulated result,
14696     * and is provided as an argument in the next call to the callback function.
14697     *
14698     * @param callbackfn A function that accepts two arguments.
14699     * The reduceRight method calls the callbackfn function one time for each element in the array.
14700     *
14701     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14702     * The first call to the callbackfn function provides this value as an argument.
14703     *
14704     * @returns The value that results from running the callback function to completion over the entire typed array.
14705     */
14706    public reduceRight<U = number>(
14707                callbackfn: (previousValue: U, currentValue: number) => U,
14708                initialValue: U): U {
14709        return this.reduceRight(
14710                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14711                        callbackfn(prevVal, currVal), initialValue)
14712    }
14713
14714    /**
14715     * Calls the specified callback function for all the elements in an array, in descending order.
14716     * The return value of the callback function is the accumulated result,
14717     * and is provided as an argument in the next call to the callback function.
14718     *
14719     * @param callbackfn A function that accepts one argument.
14720     * The reduceRight method calls the callbackfn function one time for each element in the array.
14721     *
14722     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14723     * The first call to the callbackfn function provides this value as an argument.
14724     *
14725     * @returns The value that results from running the callback function to completion over the entire typed array.
14726     */
14727    public reduceRight<U = number>(
14728                callbackfn: (previousValue: U) => U,
14729                initialValue: U): U {
14730        return this.reduceRight(
14731                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14732                        callbackfn(prevVal), initialValue)
14733    }
14734
14735    /**
14736     * Calls the specified callback function for all the elements in an array, in descending order.
14737     * The return value of the callback function is the accumulated result,
14738     * and is provided as an argument in the next call to the callback function.
14739     *
14740     * @param callbackfn A function that accepts no arguments.
14741     * The reduceRight method calls the callbackfn function one time for each element in the array.
14742     *
14743     * @param initialValue The parameter which value is used as the initial value to start the accumulation.
14744     * The first call to the callbackfn function provides this value as an argument.
14745     *
14746     * @returns The value that results from running the callback function to completion over the entire typed array.
14747     */
14748    public reduceRight<U = number>(
14749                callbackfn: () => U,
14750                initialValue: U): U {
14751        return this.reduceRight(
14752                (prevVal: U, currVal: number, currIndex: number, array: Float64Array) =>
14753                        callbackfn(), initialValue)
14754    }
14755
14756    /**
14757     * Calls the specified callback function for all the elements in an array, in descending order.
14758     * The return value of the callback function is the accumulated result,
14759     * and is provided as an argument in the next call to the callback function.
14760     *
14761     * @param callbackfn A function that accepts four arguments.
14762     * The reduceRight method calls the callbackfn function one time for each element in the array.
14763     * The first call to the callbackfn function provides array last element value as an argument
14764     *
14765     * @returns The value that results from running the callback function to completion over the entire typed array.
14766     * calling reduceRight method on an empty array without an initial value creates a TypeError
14767     */
14768    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number {
14769        if (this.lengthInt == 0) {
14770            throw new TypeError("Reduce of empty array with no initial value")
14771        }
14772
14773        let accumulatedValue: number = this.getUnsafe(this.lengthInt - 1) as number
14774        for (let i = this.lengthInt - 2; i >= 0; --i) {
14775            accumulatedValue = callbackfn(accumulatedValue, this.getUnsafe(i) as number, i as number, this)
14776        }
14777        return accumulatedValue
14778    }
14779
14780    /**
14781     * Calls the specified callback function for all the elements in an array, in descending order.
14782     * The return value of the callback function is the accumulated result,
14783     * and is provided as an argument in the next call to the callback function.
14784     *
14785     * @param callbackfn A function that accepts three arguments.
14786     * The reduceRight method calls the callbackfn function one time for each element in the array.
14787     * The first call to the callbackfn function provides array last element value as an argument
14788     *
14789     * @returns The value that results from running the callback function to completion over the entire typed array.
14790     * calling reduceRight method on an empty array without an initial value creates a TypeError
14791     */
14792    public reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number) => number): number {
14793        return this.reduceRight(
14794                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
14795                        callbackfn(prevValue, currValue, currIndex))
14796    }
14797
14798    /**
14799     * Calls the specified callback function for all the elements in an array, in descending order.
14800     * The return value of the callback function is the accumulated result,
14801     * and is provided as an argument in the next call to the callback function.
14802     *
14803     * @param callbackfn A function that accepts two arguments.
14804     * The reduceRight method calls the callbackfn function one time for each element in the array.
14805     * The first call to the callbackfn function provides array last element value as an argument
14806     *
14807     * @returns The value that results from running the callback function to completion over the entire typed array.
14808     * calling reduceRight method on an empty array without an initial value creates a TypeError
14809     */
14810    public reduceRight(callbackfn: (previousValue: number, currentValue: number) => number): number {
14811        return this.reduceRight(
14812                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
14813                        callbackfn(prevValue, currValue))
14814    }
14815
14816    /**
14817     * Calls the specified callback function for all the elements in an array, in descending order.
14818     * The return value of the callback function is the accumulated result,
14819     * and is provided as an argument in the next call to the callback function.
14820     *
14821     * @param callbackfn A function that accepts one argument.
14822     * The reduceRight method calls the callbackfn function one time for each element in the array.
14823     * The first call to the callbackfn function provides array last element value as an argument
14824     *
14825     * @returns The value that results from running the callback function to completion over the entire typed array.
14826     * calling reduceRight method on an empty array without an initial value creates a TypeError
14827     */
14828    public reduceRight(callbackfn: (previousValue: number) => number): number {
14829        return this.reduceRight(
14830                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
14831                        callbackfn(prevValue))
14832    }
14833
14834    /**
14835     * Calls the specified callback function for all the elements in an array, in descending order.
14836     * The return value of the callback function is the accumulated result,
14837     * and is provided as an argument in the next call to the callback function.
14838     *
14839     * @param callbackfn A function that accepts no arguments.
14840     * The reduceRight method calls the callbackfn function one time for each element in the array.
14841     * The first call to the callbackfn function provides array last element value as an argument
14842     *
14843     * @returns The value that results from running the callback function to completion over the entire typed array.
14844     * calling reduceRight method on an empty array without an initial value creates a TypeError
14845     */
14846    public reduceRight(callbackfn: () => number): number {
14847        return this.reduceRight(
14848                (prevValue: number, currValue: number, currIndex: number, array: Float64Array) =>
14849                        callbackfn())
14850    }
14851
14852   /**
14853    * Creates a new Float64Array using fn(arr[i]) over all elements of current Float64Array.
14854    *
14855    * @param fn a function to apply for each element of current Float64Array
14856    *
14857    * @returns a new Float64Array where for each element from current Float64Array fn was applied
14858    */
14859    public map(fn: (val: number, index: number) => number): Float64Array {
14860        let resBuf = new ArrayBuffer(this.lengthInt * Float64Array.BYTES_PER_ELEMENT as int)
14861        let res = new Float64Array(resBuf, 0, resBuf.getByteLength() / Float64Array.BYTES_PER_ELEMENT as int)
14862        for (let i = 0; i < this.lengthInt; ++i) {
14863            res.set(i, fn(this.getUnsafe(i) as number, i as number) as double)
14864        }
14865        return res
14866    }
14867
14868    /**
14869     * Determines whether the specified callback function returns true for all elements of an array.
14870     *
14871     * @param predicate A function that accepts three arguments.
14872     * The every method calls the predicate function for each element in the array until the predicate returns a false,
14873     * or until the end of the array.
14874     *
14875     * @returns true unless predicate function returns a false for an array element,
14876     * in which case false is immediately returned.
14877     */
14878    public every(predicate: (element: number, index: number, array: Float64Array) => boolean): boolean {
14879        for (let i = 0; i < this.lengthInt; ++i) {
14880            if (!predicate(this.getUnsafe(i) as number, i as number, this)) {
14881                return false
14882            }
14883        }
14884        return true
14885    }
14886
14887    /**
14888     * Determines whether the specified callback function returns true for all elements of an array.
14889     *
14890     * @param predicate A function that accepts two arguments.
14891     * The every method calls the predicate function for each element in the array until the predicate returns a false,
14892     * or until the end of the array.
14893     *
14894     * @returns true unless predicate function returns a false for an array element,
14895     * in which case false is immediately returned.
14896     */
14897    public every(predicate: (element: number, index: number) => boolean): boolean {
14898        return this.every((element: number, index: number, array: Float64Array): boolean => predicate(element, index))
14899    }
14900
14901    /**
14902     * Determines whether the specified callback function returns true for all elements of an array.
14903     *
14904     * @param predicate A function that accepts no arguments.
14905     * The every method calls the predicate function for each element in the array until the predicate returns a false,
14906     * or until the end of the array.
14907     *
14908     * @returns true unless predicate function returns a false for an array element,
14909     * in which case false is immediately returned.
14910     */
14911    public every(predicate: () => boolean): boolean {
14912        return this.every((element: number, index: number, array: Float64Array): boolean => predicate())
14913    }
14914
14915    /**
14916     * Creates a new Float64Array from current Float64Array based on a condition fn.
14917     *
14918     * @param fn the condition to apply for each element
14919     *
14920     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
14921     */
14922    public filter(fn: (val: number, index: number, array: Float64Array) => boolean): Float64Array {
14923        let markers = new boolean[this.lengthInt]
14924        let resLen = 0
14925        for (let i = 0; i < this.lengthInt; ++i) {
14926            markers[i] = fn(this.getUnsafe(i) as number, i as number, this)
14927            if (markers[i]) {
14928                ++resLen
14929            }
14930        }
14931        let resBuf = new ArrayBuffer(resLen * Float64Array.BYTES_PER_ELEMENT as int)
14932        let res = new Float64Array(resBuf, 0)
14933        for (let i = 0, j = 0; i < this.lengthInt; ++i) {
14934            if (markers[i]) {
14935                res.set(j, this.getUnsafe(i))
14936                ++j
14937            }
14938        }
14939        return res
14940    }
14941
14942    /**
14943     * creates a new Float64Array from current Float64Array based on a condition fn
14944     *
14945     * @param fn the condition to apply for each element
14946     *
14947     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
14948     */
14949    public filter(fn: (val: number, index: number) => boolean): Float64Array {
14950        let newF: (val: number, index: number, array: Float64Array) => boolean =
14951            (val: number, index: number, array: Float64Array): boolean => { return fn(val, index as number) }
14952        return this.filter(newF)
14953    }
14954
14955    /**
14956     * creates a new Float64Array from current Float64Array based on a condition fn
14957     *
14958     * @param fn the condition to apply for each element
14959     *
14960     * @returns a new Float64Array with elements from current Float64Array that satisfy condition fn
14961     */
14962    public filter(fn: () => boolean): Float64Array {
14963        let newF: (val: number, index: number, array: Float64Array) => boolean =
14964            (val: number, index: number, array: Float64Array): boolean => { return fn() }
14965        return this.filter(newF)
14966    }
14967
14968    /**
14969     * Returns the value of the first element in the array where predicate is true, and undefined
14970     * otherwise
14971     *
14972     * @param predicate find calls predicate once for each element of the array, in ascending
14973     * order, until it finds one where predicate returns true. If such an element is found, find
14974     * immediately returns that element value. Otherwise, find returns undefined
14975     *
14976     * @returns number | undefined
14977     */
14978    public find(predicate: (value: number, index: number, obj: Float64Array) => boolean): number | undefined {
14979        for (let i = 0; i < this.lengthInt; ++i) {
14980            let val = this.getUnsafe(i)
14981            if (predicate(val as number, i as number, this)) {
14982                return val as number
14983            }
14984        }
14985        return undefined
14986    }
14987
14988    /**
14989     * Returns the value of the first element in the array where predicate is true, and undefined
14990     * otherwise
14991     *
14992     * @param predicate find calls predicate once for each element of the array, in ascending
14993     * order, until it finds one where predicate returns true. If such an element is found, find
14994     * immediately returns that element value. Otherwise, find returns undefined
14995     *
14996     * @returns number | undefined
14997     */
14998    public find(predicate: (value: number, index: number) => boolean): number | undefined {
14999        return this.find((value: number, index: number, obj: Float64Array): boolean => predicate(value, index))
15000    }
15001
15002    /**
15003     * Returns the index of the first element in the array where predicate is true, and -1
15004     * otherwise
15005     *
15006     * @param predicate find calls predicate once for each element of the array, in ascending
15007     * order, until it finds one where predicate returns true. If such an element is found,
15008     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15009     *
15010     * @returns number
15011     */
15012    public findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean): number {
15013        for (let i = 0; i < this.lengthInt; ++i) {
15014            if (predicate(this.getUnsafe(i) as number, i as number, this)) {
15015                return i as number
15016            }
15017        }
15018        return -1 as number
15019    }
15020
15021    /**
15022     * Returns the index of the first element in the array where predicate is true, and -1
15023     * otherwise
15024     *
15025     * @param predicate find calls predicate once for each element of the array, in ascending
15026     * order, until it finds one where predicate returns true. If such an element is found,
15027     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15028     *
15029     * @returns number
15030     */
15031    public findIndex(predicate: (value: number, index: number) => boolean): number {
15032        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate(value, index as number)) as number
15033    }
15034
15035    /**
15036     * Returns the index of the first element in the array where predicate is true, and -1
15037     * otherwise
15038     *
15039     * @param predicate find calls predicate once for each element of the array, in ascending
15040     * order, until it finds one where predicate returns true. If such an element is found,
15041     * findIndex immediately returns that element index. Otherwise, findIndex returns -1
15042     *
15043     * @returns number
15044     */
15045    public findIndex(predicate: () => boolean): number {
15046        return this.findIndex((value: number, index: number, obj: Float64Array): boolean => predicate()) as number
15047    }
15048
15049    /**
15050     * Finds the last element in the Float64Array that satisfies the condition
15051     *
15052     * @param fn condition
15053     *
15054     * @returns the last element that satisfies fn
15055     */
15056    public findLast(fn: (val: number, index: number, array: Float64Array) => boolean): double {
15057        for (let i = this.lengthInt - 1; i >= 0; --i) {
15058            let val = this.getUnsafe(i)
15059            if (fn(val as number, i as number, this)) {
15060                return val
15061            }
15062        }
15063        throw new Error("Float64Array.findLast: not implemented if an element was not found")
15064    }
15065
15066    /**
15067     * Finds the last element in the Float64Array that satisfies the condition
15068     *
15069     * @param fn condition
15070     *
15071     * @returns the last element that satisfies fn
15072     */
15073    public findLast(fn: (val: number, index: number) => boolean): double {
15074        let newF: (val: number, index: number, array: Float64Array) => boolean =
15075            (val: number, index: number, array: Float64Array): boolean => { return fn(val as number, index as number) }
15076        return this.findLast(newF)
15077    }
15078
15079    /**
15080     * Finds an index of the last element in the Float64Array that satisfies the condition
15081     *
15082     * @param fn condition
15083     *
15084     * @returns the index of the last element that satisfies fn, -1 otherwise
15085     */
15086    public findLastIndex(fn: (val: number, index: number, array: Float64Array) => boolean): number {
15087        for (let i = this.lengthInt - 1; i >= 0; --i) {
15088            let val = this.getUnsafe(i)
15089            if (fn(val as number, i as number, this)) {
15090                return i
15091            }
15092        }
15093        return -1 as number
15094    }
15095
15096    /**
15097     * Finds an index of the last element in the Float64Array that satisfies the condition
15098     *
15099     * @param fn condition
15100     *
15101     * @returns the index of the last element that satisfies fn, -1 otherwise
15102     */
15103    public findLastIndex(fn: (val: number, index: number) => boolean): number {
15104        let newF: (val: number, index: number, array: Float64Array) => boolean =
15105            (val: number, index: number, array: Float64Array): boolean => { return fn(val, index as number) }
15106        return this.findLastIndex(newF) as number
15107    }
15108
15109    /**
15110     * Performs the specified action for each element in Float64Array
15111     *
15112     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15113     * callbackfn function one time for each element in the array.
15114     *
15115     * @returns None
15116     */
15117    public forEach(callbackfn: (value: number, index: number, array: Float64Array) => void): void {
15118        for (let i = 0; i < this.lengthInt; ++i) {
15119            callbackfn(this.getUnsafe(i) as number, i as number, this)
15120        }
15121    }
15122
15123    /**
15124     * Performs the specified action for each element in Float64Array
15125     *
15126     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15127     * callbackfn function one time for each element in the array.
15128     *
15129     * @returns None
15130     */
15131    public forEach(callbackfn: (value: number, index: number) => void): void {
15132        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn(value, index))
15133    }
15134
15135    /**
15136     * Performs the specified action for each element in Float64Array
15137     *
15138     * @param callbackfn  A function that accepts up to three arguments. forEach calls the
15139     * callbackfn function one time for each element in the array.
15140     *
15141     * @returns None
15142     */
15143    public forEach(callbackfn: () => void): void {
15144        this.forEach((value: number, index: number, array: Float64Array): void => callbackfn())
15145    }
15146
15147    /**
15148     * Returns the object itself
15149     *
15150     * @returns Float64Array
15151     */
15152    public valueOf(): Float64Array {
15153        return this
15154    }
15155
15156    internal getUnsafe(index: int): double {
15157        let byteIndex = index * Float64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
15158        let res : long = 0
15159        let byteVal : long
15160        if (IS_LITTLE_ENDIAN) {
15161            if (this.buffer instanceof ArrayBuffer) {
15162                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15163                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + i)
15164                    byteVal &= 0xff
15165                    res = (res | byteVal << (8 * i)) as long
15166                }
15167            } else if (this.buffer instanceof SharedArrayBuffer) {
15168                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15169                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + i)
15170                    byteVal &= 0xff
15171                    res = (res | byteVal << (8 * i)) as long
15172                }
15173            } else {
15174                throw new Error("unexpected type of ArrayBufferLike")
15175            }
15176            return Double.bitCastFromLong(res)
15177        } else {
15178            if (this.buffer instanceof ArrayBuffer) {
15179                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15180                    byteVal = (this.buffer as ArrayBuffer).at(byteIndex as int + 7 - i)
15181                    byteVal &= 0xff
15182                    res = (res | byteVal << (8 * i)) as long
15183                }
15184            } else if (this.buffer instanceof SharedArrayBuffer) {
15185                for (let i: int = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15186                    byteVal = (this.buffer as SharedArrayBuffer).at(byteIndex as int + 7 - i)
15187                    byteVal &= 0xff
15188                    res = (res | byteVal << (8 * i)) as long
15189                }
15190            } else {
15191                throw new Error("unexpected type of ArrayBufferLike")
15192            }
15193            return Double.bitCastFromLong(res)
15194        }
15195    }
15196
15197    internal setUnsafe(insertPos: int, val: double): void {
15198        let startByte = insertPos * Float64Array.BYTES_PER_ELEMENT as int + this.byteOffset as int
15199        let bits = Double.bitCastToLong(val)
15200        if (IS_LITTLE_ENDIAN) {
15201            if (this.buffer instanceof ArrayBuffer) {
15202                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15203                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15204                    (this.buffer as ArrayBuffer).set(startByte + i, byteVal)
15205                }
15206            } else if (this.buffer instanceof SharedArrayBuffer) {
15207                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; ++i) {
15208                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15209                    (this.buffer as SharedArrayBuffer).set(startByte + i, byteVal)
15210                }
15211            } else {
15212                throw new Error("unexpected type of ArrayBufferLike")
15213            }
15214        } else {
15215            if (this.buffer instanceof ArrayBuffer) {
15216                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; i++) {
15217                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15218                    (this.buffer as ArrayBuffer).set(startByte + 7 - i, byteVal)
15219                }
15220            } else if (this.buffer instanceof SharedArrayBuffer) {
15221                for (let i = 0; i < Float64Array.BYTES_PER_ELEMENT as int; i++) {
15222                    let byteVal = ((bits >>> (i * 8)) & 0xff) as byte
15223                    (this.buffer as SharedArrayBuffer).set(startByte + 7 - i, byteVal)
15224                }
15225            } else {
15226                throw new Error("unexpected type of ArrayBufferLike")
15227            }
15228        }
15229    }
15230
15231    /** Underlying ArrayBufferLike */
15232    public readonly buffer: ArrayBufferLike
15233
15234    /** Byte offset within the underlying ArrayBufferLike */
15235    public readonly byteOffset: number
15236
15237    /** Number of bytes used */
15238    public readonly byteLength: number
15239
15240    /** String \"Float64Array\" */
15241    public readonly name = "Float64Array"
15242}
15243