Skip to content

Commit a0307d8

Browse files
authored
feat: Add findLastIndex for Array and TypedArray (Stage 3) (AssemblyScript#1981)
1 parent 20a0635 commit a0307d8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+24144
-20072
lines changed

std/assembly/array.ts

Lines changed: 115 additions & 108 deletions
Large diffs are not rendered by default.

std/assembly/index.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView {
16021602
fill(value: T, start?: i32, end?: i32): this;
16031603
/** The findIndex() method returns an index in the typed array, if an element in the typed array satisfies the provided testing function. Otherwise -1 is returned. See also the find() [not implemented] method, which returns the value of a found element in the typed array instead of its index. */
16041604
findIndex(callbackfn: (value: T, index: i32, self: this) => bool): i32;
1605+
/** The findLastIndex() method returns an index start searching from the end in the typed array, if an element in the typed array satisfies the provided testing function. Otherwise -1 is returned. See also the find() [not implemented] method, which returns the value of a found element in the typed array instead of its index. */
1606+
findLastIndex(callbackfn: (value: T, index: i32, self: this) => bool): i32;
16051607
/** The every() method tests whether all elements in the typed array pass the test implemented by the provided function. This method has the same algorithm as Array.prototype.every(). */
16061608
every(callbackfn: (value: T, index: i32, self: this) => bool): bool;
16071609
/** The forEach() method executes a provided function once per array element. This method has the same algorithm as Array.prototype.forEach().*/
@@ -1688,7 +1690,8 @@ declare class Array<T> {
16881690
at(index: i32): T;
16891691
fill(value: T, start?: i32, end?: i32): this;
16901692
every(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
1691-
findIndex(predicate: (element: T, index: i32, array?: Array<T>) => bool): i32;
1693+
findIndex(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): i32;
1694+
findLastIndex(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): i32;
16921695
includes(searchElement: T, fromIndex?: i32): bool;
16931696
indexOf(searchElement: T, fromIndex?: i32): i32;
16941697
lastIndexOf(searchElement: T, fromIndex?: i32): i32;

std/assembly/typedarray.ts

Lines changed: 96 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export class Int8Array extends ArrayBufferView {
107107
return FIND_INDEX<Int8Array, i8>(this, fn);
108108
}
109109

110+
findLastIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 {
111+
return FIND_LAST_INDEX<Int8Array, i8>(this, fn);
112+
}
113+
110114
some(fn: (value: i8, index: i32, self: Int8Array) => bool): bool {
111115
return SOME<Int8Array, i8>(this, fn);
112116
}
@@ -243,6 +247,10 @@ export class Uint8Array extends ArrayBufferView {
243247
return FIND_INDEX<Uint8Array, u8>(this, fn);
244248
}
245249

250+
findLastIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 {
251+
return FIND_LAST_INDEX<Uint8Array, u8>(this, fn);
252+
}
253+
246254
some(fn: (value: u8, index: i32, self: Uint8Array) => bool): bool {
247255
return SOME<Uint8Array, u8>(this, fn);
248256
}
@@ -379,6 +387,10 @@ export class Uint8ClampedArray extends ArrayBufferView {
379387
return FIND_INDEX<Uint8ClampedArray, u8>(this, fn);
380388
}
381389

390+
findLastIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 {
391+
return FIND_LAST_INDEX<Uint8ClampedArray, u8>(this, fn);
392+
}
393+
382394
some(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool {
383395
return SOME<Uint8ClampedArray, u8>(this, fn);
384396
}
@@ -515,6 +527,10 @@ export class Int16Array extends ArrayBufferView {
515527
return FIND_INDEX<Int16Array, i16>(this, fn);
516528
}
517529

530+
findLastIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 {
531+
return FIND_LAST_INDEX<Int16Array, i16>(this, fn);
532+
}
533+
518534
some(fn: (value: i16, index: i32, self: Int16Array) => bool): bool {
519535
return SOME<Int16Array, i16>(this, fn);
520536
}
@@ -651,6 +667,10 @@ export class Uint16Array extends ArrayBufferView {
651667
return FIND_INDEX<Uint16Array, u16>(this, fn);
652668
}
653669

670+
findLastIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 {
671+
return FIND_LAST_INDEX<Uint16Array, u16>(this, fn);
672+
}
673+
654674
some(fn: (value: u16, index: i32, self: Uint16Array) => bool): bool {
655675
return SOME<Uint16Array, u16>(this, fn);
656676
}
@@ -787,6 +807,10 @@ export class Int32Array extends ArrayBufferView {
787807
return FIND_INDEX<Int32Array, i32>(this, fn);
788808
}
789809

810+
findLastIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 {
811+
return FIND_LAST_INDEX<Int32Array, i32>(this, fn);
812+
}
813+
790814
some(fn: (value: i32, index: i32, self: Int32Array) => bool): bool {
791815
return SOME<Int32Array, i32>(this, fn);
792816
}
@@ -923,6 +947,10 @@ export class Uint32Array extends ArrayBufferView {
923947
return FIND_INDEX<Uint32Array, u32>(this, fn);
924948
}
925949

950+
findLastIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 {
951+
return FIND_LAST_INDEX<Uint32Array, u32>(this, fn);
952+
}
953+
926954
some(fn: (value: u32, index: i32, self: Uint32Array) => bool): bool {
927955
return SOME<Uint32Array, u32>(this, fn);
928956
}
@@ -1059,6 +1087,10 @@ export class Int64Array extends ArrayBufferView {
10591087
return FIND_INDEX<Int64Array, i64>(this, fn);
10601088
}
10611089

1090+
findLastIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 {
1091+
return FIND_LAST_INDEX<Int64Array, i64>(this, fn);
1092+
}
1093+
10621094
some(fn: (value: i64, index: i32, self: Int64Array) => bool): bool {
10631095
return SOME<Int64Array, i64>(this, fn);
10641096
}
@@ -1195,6 +1227,10 @@ export class Uint64Array extends ArrayBufferView {
11951227
return FIND_INDEX<Uint64Array, u64>(this, fn);
11961228
}
11971229

1230+
findLastIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 {
1231+
return FIND_LAST_INDEX<Uint64Array, u64>(this, fn);
1232+
}
1233+
11981234
some(fn: (value: u64, index: i32, self: Uint64Array) => bool): bool {
11991235
return SOME<Uint64Array, u64>(this, fn);
12001236
}
@@ -1331,6 +1367,10 @@ export class Float32Array extends ArrayBufferView {
13311367
return FIND_INDEX<Float32Array, f32>(this, fn);
13321368
}
13331369

1370+
findLastIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 {
1371+
return FIND_LAST_INDEX<Float32Array, f32>(this, fn);
1372+
}
1373+
13341374
some(fn: (value: f32, index: i32, self: Float32Array) => bool): bool {
13351375
return SOME<Float32Array, f32>(this, fn);
13361376
}
@@ -1467,6 +1507,10 @@ export class Float64Array extends ArrayBufferView {
14671507
return FIND_INDEX<Float64Array, f64>(this, fn);
14681508
}
14691509

1510+
findLastIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 {
1511+
return FIND_LAST_INDEX<Float64Array, f64>(this, fn);
1512+
}
1513+
14701514
some(fn: (value: f64, index: i32, self: Float64Array) => bool): bool {
14711515
return SOME<Float64Array, f64>(this, fn);
14721516
}
@@ -1508,15 +1552,15 @@ function FILL<TArray extends ArrayBufferView, T extends number>(
15081552
start: i32,
15091553
end: i32
15101554
): TArray {
1511-
var dataStart = array.dataStart;
1555+
var ptr = array.dataStart;
15121556
var len = array.length;
15131557
start = start < 0 ? max(len + start, 0) : min(start, len);
15141558
end = end < 0 ? max(len + end, 0) : min(end, len);
15151559
if (sizeof<T>() == 1) {
1516-
if (start < end) memory.fill(dataStart + <usize>start, <u8>value, <usize>(end - start));
1560+
if (start < end) memory.fill(ptr + <usize>start, <u8>value, <usize>(end - start));
15171561
} else {
15181562
for (; start < end; ++start) {
1519-
store<T>(dataStart + (<usize>start << alignof<T>()), value);
1563+
store<T>(ptr + (<usize>start << alignof<T>()), value);
15201564
}
15211565
}
15221566
return array;
@@ -1572,7 +1616,7 @@ function COPY_WITHIN<TArray extends ArrayBufferView, T>(
15721616
end: i32
15731617
): TArray {
15741618
var len = array.length;
1575-
var dataStart = array.dataStart;
1619+
var ptr = array.dataStart;
15761620

15771621
end = min<i32>(end, len);
15781622
var to = target < 0 ? max(len + target, 0) : min(target, len);
@@ -1581,8 +1625,8 @@ function COPY_WITHIN<TArray extends ArrayBufferView, T>(
15811625
var count = min(last - from, len - to);
15821626

15831627
memory.copy(
1584-
dataStart + (<usize>to << alignof<T>()),
1585-
dataStart + (<usize>from << alignof<T>()),
1628+
ptr + (<usize>to << alignof<T>()),
1629+
ptr + (<usize>from << alignof<T>()),
15861630
<usize>count << alignof<T>()
15871631
);
15881632
return array;
@@ -1595,9 +1639,9 @@ function REDUCE<TArray extends ArrayBufferView, T, TRet>(
15951639
fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
15961640
initialValue: TRet
15971641
): TRet {
1598-
var dataStart = array.dataStart;
1642+
var ptr = array.dataStart;
15991643
for (let i = 0, k = array.length; i < k; i++) {
1600-
initialValue = fn(initialValue, load<T>(dataStart + (<usize>i << alignof<T>())), i, array);
1644+
initialValue = fn(initialValue, load<T>(ptr + (<usize>i << alignof<T>())), i, array);
16011645
}
16021646
return initialValue;
16031647
}
@@ -1609,9 +1653,9 @@ function REDUCE_RIGHT<TArray extends ArrayBufferView, T, TRet>(
16091653
fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
16101654
initialValue: TRet
16111655
): TRet {
1612-
var dataStart = array.dataStart;
1656+
var ptr = array.dataStart;
16131657
for (let i = array.length - 1; i >= 0; i--) {
1614-
initialValue = fn(initialValue, load<T>(dataStart + (<usize>i << alignof<T>())), i, array);
1658+
initialValue = fn(initialValue, load<T>(ptr + (<usize>i << alignof<T>())), i, array);
16151659
}
16161660
return initialValue;
16171661
}
@@ -1623,15 +1667,15 @@ function MAP<TArray extends ArrayBufferView, T>(
16231667
fn: (value: T, index: i32, self: TArray) => T,
16241668
): TArray {
16251669
var len = array.length;
1626-
var dataStart = array.dataStart;
1670+
var ptr = array.dataStart;
16271671

16281672
var byteLength = len << alignof<T>();
16291673
var out = changetype<TArray>(__new(offsetof<TArray>(), idof<TArray>()));
16301674
var buf = changetype<ArrayBuffer>(__new(byteLength, idof<ArrayBuffer>()));
16311675
for (let i = 0; i < len; i++) {
16321676
store<T>(
16331677
changetype<usize>(buf) + (<usize>i << alignof<T>()),
1634-
fn(load<T>(dataStart + (<usize>i << alignof<T>())), i, array)
1678+
fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array)
16351679
);
16361680
}
16371681
store<usize>(changetype<usize>(out), changetype<usize>(buf), offsetof<TArray>("buffer"));
@@ -1677,9 +1721,22 @@ function FIND_INDEX<TArray extends ArrayBufferView, T>(
16771721
array: TArray,
16781722
fn: (value: T, index: i32, array: TArray) => bool,
16791723
): i32 {
1680-
var dataStart = array.dataStart;
1724+
var ptr = array.dataStart;
16811725
for (let i = 0, k = array.length; i < k; i++) {
1682-
if (fn(load<T>(dataStart + (<usize>i << alignof<T>())), i, array)) return i;
1726+
if (fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array)) return i;
1727+
}
1728+
return -1;
1729+
}
1730+
1731+
// @ts-ignore: decorator
1732+
@inline
1733+
function FIND_LAST_INDEX<TArray extends ArrayBufferView, T>(
1734+
array: TArray,
1735+
fn: (value: T, index: i32, array: TArray) => bool,
1736+
): i32 {
1737+
var ptr = array.dataStart;
1738+
for (let i = array.length - 1; i >= 0; --i) {
1739+
if (fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array)) return i;
16831740
}
16841741
return -1;
16851742
}
@@ -1693,11 +1750,11 @@ function INCLUDES<TArray extends ArrayBufferView, T>(
16931750
): bool {
16941751
if (isFloat<T>()) {
16951752
let index: isize = fromIndex;
1696-
let length: isize = array.length;
1697-
if (length == 0 || index >= length) return false;
1698-
if (index < 0) index = max(length + index, 0);
1753+
let len: isize = array.length;
1754+
if (len == 0 || index >= len) return false;
1755+
if (index < 0) index = max(len + index, 0);
16991756
let dataStart = array.dataStart;
1700-
while (index < length) {
1757+
while (index < len) {
17011758
let elem = load<T>(dataStart + (index << alignof<T>()));
17021759
// @ts-ignore
17031760
if (elem == searchElement || isNaN(elem) & isNaN(searchElement)) return true;
@@ -1717,11 +1774,11 @@ function INDEX_OF<TArray extends ArrayBufferView, T>(
17171774
fromIndex: i32,
17181775
): i32 {
17191776
var index: isize = fromIndex;
1720-
var length: isize = array.length;
1721-
if (length == 0 || index >= length) return -1;
1722-
if (index < 0) index = max(length + index, 0);
1777+
var len: isize = array.length;
1778+
if (len == 0 || index >= len) return -1;
1779+
if (index < 0) index = max(len + index, 0);
17231780
var dataStart = array.dataStart;
1724-
while (index < length) {
1781+
while (index < len) {
17251782
if (load<T>(dataStart + (index << alignof<T>())) == searchElement) return <i32>index;
17261783
++index;
17271784
}
@@ -1736,10 +1793,10 @@ function LAST_INDEX_OF<TArray extends ArrayBufferView, T>(
17361793
fromIndex: i32,
17371794
): i32 {
17381795
var index: isize = fromIndex;
1739-
var length: isize = array.length;
1740-
if (length == 0) return -1;
1741-
if (index < 0) index = length + index; // no need to clamp
1742-
else if (index >= length) index = length - 1;
1796+
var len: isize = array.length;
1797+
if (len == 0) return -1;
1798+
if (index < 0) index = len + index; // no need to clamp
1799+
else if (index >= len) index = len - 1;
17431800
var dataStart = array.dataStart;
17441801
while (index >= 0) {
17451802
if (load<T>(dataStart + (index << alignof<T>())) == searchElement) return <i32>index;
@@ -1754,9 +1811,9 @@ function SOME<TArray extends ArrayBufferView, T>(
17541811
array: TArray,
17551812
fn: (value: T, index: i32, array: TArray) => bool,
17561813
): bool {
1757-
var dataStart = array.dataStart;
1814+
var ptr = array.dataStart;
17581815
for (let i = 0, k = array.length; i < k; i++) {
1759-
if (fn(load<T>(dataStart + (<usize>i << alignof<T>())), i, array)) return true;
1816+
if (fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array)) return true;
17601817
}
17611818
return false;
17621819
}
@@ -1767,9 +1824,9 @@ function EVERY<TArray extends ArrayBufferView, T>(
17671824
array: TArray,
17681825
fn: (value: T, index: i32, array: TArray) => bool,
17691826
): bool {
1770-
var dataStart = array.dataStart;
1827+
var ptr = array.dataStart;
17711828
for (let i = 0, k = array.length; i < k; i++) {
1772-
if (fn(load<T>(dataStart + (<usize>i << alignof<T>())), i, array)) continue;
1829+
if (fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array)) continue;
17731830
return false;
17741831
}
17751832
return true;
@@ -1781,19 +1838,19 @@ function FOREACH<TArray extends ArrayBufferView, T>(
17811838
array: TArray,
17821839
fn: (value: T, index: i32, array: TArray) => void,
17831840
): void {
1784-
var dataStart = array.dataStart;
1841+
var ptr = array.dataStart;
17851842
for (let i = 0, k = array.length; i < k; i++) {
1786-
fn(load<T>(dataStart + (<usize>i << alignof<T>())), i, array);
1843+
fn(load<T>(ptr + (<usize>i << alignof<T>())), i, array);
17871844
}
17881845
}
17891846

17901847
// @ts-ignore: decorator
17911848
@inline
17921849
function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {
1793-
var dataStart = array.dataStart;
1850+
var ptr = array.dataStart;
17941851
for (let front: usize = 0, back: usize = array.length - 1; front < back; ++front, --back) {
1795-
let frontPtr = dataStart + (front << alignof<T>());
1796-
let backPtr = dataStart + (back << alignof<T>());
1852+
let frontPtr = ptr + (front << alignof<T>());
1853+
let backPtr = ptr + (back << alignof<T>());
17971854
let temp = load<T>(frontPtr);
17981855
store<T>(frontPtr, load<T>(backPtr));
17991856
store<T>(backPtr, temp);
@@ -1806,16 +1863,16 @@ function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {
18061863
function WRAP<TArray extends ArrayBufferView, T>(
18071864
buffer: ArrayBuffer,
18081865
byteOffset: i32 = 0,
1809-
length: i32 = -1
1866+
len: i32 = -1
18101867
): TArray {
18111868
var byteLength: i32;
18121869
var bufferByteLength = buffer.byteLength;
18131870
const mask: u32 = sizeof<T>() - 1;
18141871
if (i32(<u32>byteOffset > <u32>bufferByteLength) | (byteOffset & mask)) {
18151872
throw new RangeError(E_INDEXOUTOFRANGE);
18161873
}
1817-
if (length < 0) {
1818-
if (length == -1) {
1874+
if (len < 0) {
1875+
if (len == -1) {
18191876
if (bufferByteLength & mask) {
18201877
throw new RangeError(E_INVALIDLENGTH);
18211878
}
@@ -1824,7 +1881,7 @@ function WRAP<TArray extends ArrayBufferView, T>(
18241881
throw new RangeError(E_INVALIDLENGTH);
18251882
}
18261883
} else {
1827-
byteLength = length << alignof<T>();
1884+
byteLength = len << alignof<T>();
18281885
if (byteOffset + byteLength > bufferByteLength) {
18291886
throw new RangeError(E_INVALIDLENGTH);
18301887
}

0 commit comments

Comments
 (0)