Skip to content

Commit e7d4786

Browse files
MaxGraeydcodeIO
authored andcommitted
Add TypedArray#filter (AssemblyScript#818)
1 parent 97d5462 commit e7d4786

File tree

7 files changed

+7428
-2025
lines changed

7 files changed

+7428
-2025
lines changed

std/assembly/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,8 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
11491149
some(callbackfn: (value: T, index: i32, self: this) => bool): bool;
11501150
/** The map() method creates a new typed array with the results of calling a provided function on every element in this typed array. This method has the same algorithm as Array.prototype.map().*/
11511151
map(callbackfn: (value: T, index: i32, self: this) => T): TypedArray<T>;
1152+
/** The filter() method creates a new typed array with all elements that pass the test implemented by the provided function. This method has the same algorithm as Array.prototype.filter(). */
1153+
filter(callbackfn: (value: T, index: i32, self: this) => bool): TypedArray<T>;
11521154
/** The sort() method sorts the elements of a typed array numerically in place and returns the typed array. This method has the same algorithm as Array.prototype.sort(), except that sorts the values numerically instead of as strings. TypedArray is one of the typed array types here. */
11531155
sort(callback?: (a: T, b: T) => i32): this;
11541156
/** The fill() method fills all the elements of a typed array from a start index to an end index with a static value. This method has the same algorithm as Array.prototype.fill(). */

std/assembly/typedarray.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ export class Int8Array extends ArrayBufferView {
9090
return MAP<Int8Array, i8>(this, fn);
9191
}
9292

93+
filter(fn: (value: i8, index: i32, self: Int8Array) => bool): Int8Array {
94+
return FILTER<Int8Array, i8>(this, fn);
95+
}
96+
9397
findIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 {
9498
return FIND_INDEX<Int8Array, i8>(this, fn);
9599
}
@@ -202,6 +206,10 @@ export class Uint8Array extends ArrayBufferView {
202206
return MAP<Uint8Array, u8>(this, fn);
203207
}
204208

209+
filter(fn: (value: u8, index: i32, self: Uint8Array) => bool): Uint8Array {
210+
return FILTER<Uint8Array, u8>(this, fn);
211+
}
212+
205213
findIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 {
206214
return FIND_INDEX<Uint8Array, u8>(this, fn);
207215
}
@@ -314,6 +322,10 @@ export class Uint8ClampedArray extends ArrayBufferView {
314322
return MAP<Uint8ClampedArray, u8>(this, fn);
315323
}
316324

325+
filter(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): Uint8ClampedArray {
326+
return FILTER<Uint8ClampedArray, u8>(this, fn);
327+
}
328+
317329
findIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 {
318330
return FIND_INDEX<Uint8ClampedArray, u8>(this, fn);
319331
}
@@ -426,6 +438,10 @@ export class Int16Array extends ArrayBufferView {
426438
return MAP<Int16Array, i16>(this, fn);
427439
}
428440

441+
filter(fn: (value: i16, index: i32, self: Int16Array) => bool): Int16Array {
442+
return FILTER<Int16Array, i16>(this, fn);
443+
}
444+
429445
findIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 {
430446
return FIND_INDEX<Int16Array, i16>(this, fn);
431447
}
@@ -538,6 +554,10 @@ export class Uint16Array extends ArrayBufferView {
538554
return MAP<Uint16Array, u16>(this, fn);
539555
}
540556

557+
filter(fn: (value: u16, index: i32, self: Uint16Array) => bool): Uint16Array {
558+
return FILTER<Uint16Array, u16>(this, fn);
559+
}
560+
541561
findIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 {
542562
return FIND_INDEX<Uint16Array, u16>(this, fn);
543563
}
@@ -650,6 +670,10 @@ export class Int32Array extends ArrayBufferView {
650670
return MAP<Int32Array, i32>(this, fn);
651671
}
652672

673+
filter(fn: (value: i32, index: i32, self: Int32Array) => bool): Int32Array {
674+
return FILTER<Int32Array, i32>(this, fn);
675+
}
676+
653677
findIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 {
654678
return FIND_INDEX<Int32Array, i32>(this, fn);
655679
}
@@ -762,6 +786,10 @@ export class Uint32Array extends ArrayBufferView {
762786
return MAP<Uint32Array, u32>(this, fn);
763787
}
764788

789+
filter(fn: (value: u32, index: i32, self: Uint32Array) => bool): Uint32Array {
790+
return FILTER<Uint32Array, u32>(this, fn);
791+
}
792+
765793
findIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 {
766794
return FIND_INDEX<Uint32Array, u32>(this, fn);
767795
}
@@ -874,6 +902,10 @@ export class Int64Array extends ArrayBufferView {
874902
return MAP<Int64Array, i64>(this, fn);
875903
}
876904

905+
filter(fn: (value: i64, index: i32, self: Int64Array) => bool): Int64Array {
906+
return FILTER<Int64Array, i64>(this, fn);
907+
}
908+
877909
findIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 {
878910
return FIND_INDEX<Int64Array, i64>(this, fn);
879911
}
@@ -986,6 +1018,10 @@ export class Uint64Array extends ArrayBufferView {
9861018
return MAP<Uint64Array, u64>(this, fn);
9871019
}
9881020

1021+
filter(fn: (value: u64, index: i32, self: Uint64Array) => bool): Uint64Array {
1022+
return FILTER<Uint64Array, u64>(this, fn);
1023+
}
1024+
9891025
findIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 {
9901026
return FIND_INDEX<Uint64Array, u64>(this, fn);
9911027
}
@@ -1098,6 +1134,10 @@ export class Float32Array extends ArrayBufferView {
10981134
return MAP<Float32Array, f32>(this, fn);
10991135
}
11001136

1137+
filter(fn: (value: f32, index: i32, self: Float32Array) => bool): Float32Array {
1138+
return FILTER<Float32Array, f32>(this, fn);
1139+
}
1140+
11011141
findIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 {
11021142
return FIND_INDEX<Float32Array, f32>(this, fn);
11031143
}
@@ -1210,6 +1250,10 @@ export class Float64Array extends ArrayBufferView {
12101250
return MAP<Float64Array, f64>(this, fn);
12111251
}
12121252

1253+
filter(fn: (value: f64, index: i32, self: Float64Array) => bool): Float64Array {
1254+
return FILTER<Float64Array, f64>(this, fn);
1255+
}
1256+
12131257
findIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 {
12141258
return FIND_INDEX<Float64Array, f64>(this, fn);
12151259
}
@@ -1364,6 +1408,35 @@ function MAP<TArray extends ArrayBufferView, T>(
13641408
return out;
13651409
}
13661410

1411+
// @ts-ignore: decorator
1412+
@inline
1413+
function FILTER<TArray extends ArrayBufferView, T>(
1414+
array: TArray,
1415+
fn: (value: T, index: i32, self: TArray) => bool,
1416+
): TArray {
1417+
var len = array.length;
1418+
var out = changetype<TArray>(__alloc(offsetof<TArray>(), idof<TArray>()));
1419+
var buffer = __alloc(len << alignof<T>(), idof<ArrayBuffer>());
1420+
var dataStart = array.dataStart;
1421+
var j: usize = 0;
1422+
for (let i = 0; i < len; i++) {
1423+
let value = load<T>(dataStart + (<usize>i << alignof<T>()));
1424+
if (fn(value, i, array)) {
1425+
store<T>(
1426+
buffer + (j++ << alignof<T>()),
1427+
value
1428+
);
1429+
}
1430+
}
1431+
// shrink output buffer
1432+
var length = j << alignof<T>();
1433+
var data = __realloc(buffer, length);
1434+
out.data = changetype<ArrayBuffer>(data); // retain
1435+
out.dataStart = data;
1436+
out.dataLength = length;
1437+
return out;
1438+
}
1439+
13671440
// @ts-ignore: decorator
13681441
@inline
13691442
function FIND_INDEX<TArray extends ArrayBufferView, T>(

tests/compiler/std/dataview.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@
16341634
if
16351635
i32.const 280
16361636
i32.const 376
1637-
i32.const 150
1637+
i32.const 154
16381638
i32.const 44
16391639
call $~lib/builtins/abort
16401640
unreachable

tests/compiler/std/dataview.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,7 +3327,7 @@
33273327
if
33283328
i32.const 280
33293329
i32.const 376
3330-
i32.const 150
3330+
i32.const 154
33313331
i32.const 44
33323332
call $~lib/builtins/abort
33333333
unreachable

tests/compiler/std/typedarray.optimized.wat

Lines changed: 3347 additions & 893 deletions
Large diffs are not rendered by default.

tests/compiler/std/typedarray.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,33 @@ testArrayMap<Uint64Array, u64>();
346346
testArrayMap<Float32Array, f32>();
347347
testArrayMap<Float64Array, f64>();
348348

349+
function testArrayFilter<ArrayType extends TypedArray<T>, T extends number>(): void {
350+
var source: ArrayType = instantiate<ArrayType>(6);
351+
source[0] = <T>1;
352+
source[1] = <T>2;
353+
source[2] = <T>3;
354+
source[3] = <T>4;
355+
source[5] = <T>5;
356+
var result = source.filter((value: T): bool => value > 2);
357+
assert(result.byteOffset == 0);
358+
assert(result.length == 3);
359+
assert(result[0] == <T>3);
360+
assert(result[1] == <T>4);
361+
assert(result[2] == <T>5);
362+
}
363+
364+
testArrayFilter<Int8Array, i8>();
365+
testArrayFilter<Uint8Array, u8>();
366+
testArrayFilter<Uint8ClampedArray, u8>();
367+
testArrayFilter<Int16Array, i16>();
368+
testArrayFilter<Uint16Array, u16>();
369+
testArrayFilter<Int32Array, i32>();
370+
testArrayFilter<Uint32Array, u32>();
371+
testArrayFilter<Int64Array, i64>();
372+
testArrayFilter<Uint64Array, u64>();
373+
testArrayFilter<Float32Array, f32>();
374+
testArrayFilter<Float64Array, f64>();
375+
349376
function testArraySome<ArrayType extends TypedArray<T>, T extends number>(): void {
350377
var source: ArrayType = instantiate<ArrayType>(3);
351378
source[0] = <T>2;

tests/compiler/std/typedarray.untouched.wat

Lines changed: 3977 additions & 1130 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)