Skip to content

Commit 3b1852b

Browse files
jtennerdcodeIO
authored andcommitted
Implement TypedArray#every/some/findIndex and improve map/reduce/reduceRight (AssemblyScript#433)
1 parent d371568 commit 3b1852b

File tree

6 files changed

+10452
-2118
lines changed

6 files changed

+10452
-2118
lines changed

std/assembly/index.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,18 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
591591
callbackfn: (accumulator: W, value: T, index: i32, self: this) => W,
592592
initialValue: W,
593593
): W;
594+
/** The some() method tests whether some element in the typed array passes the test implemented by the provided function. This method has the same algorithm as Array.prototype.some().*/
595+
some(callbackfn: (value: T, index: i32, self: this) => bool): bool;
596+
/** 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().*/
597+
map(callbackfn: (value: T, index: i32, self: this) => T): this;
598+
/** 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. */
599+
sort(callback?: (a: T, b: T) => i32): this;
600+
/** 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(). */
601+
fill(value: T, start?: i32, end?: i32): this;
602+
/** 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. */
603+
findIndex(callbackfn: (value: T, index: i32, self: this) => bool): i32;
604+
/** 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(). */
605+
every(callbackfn: (value: T, index: i32, self: this) => bool): i32;
594606
}
595607

596608
/** An array of twos-complement 8-bit signed integers. */

std/assembly/internal/typedarray.ts

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export abstract class TypedArray<T> {
6060
}
6161

6262
@inline
63-
export function FILL<TArray extends TypedArray<T>, T>(
63+
export function FILL<TArray extends TypedArray<T>, T extends number>(
6464
array: TArray,
6565
value: NATIVE<T>,
6666
start: i32,
@@ -133,16 +133,16 @@ export function REDUCE<TArray extends TypedArray<T>, T, TRet>(
133133
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
134134
initialValue: TRet
135135
): TRet {
136-
var index = 0;
137-
var length = <i32>array.length;
138-
while (index != length) {
136+
var length = array.length;
137+
var buffer = array.buffer;
138+
var byteOffset = array.byteOffset;
139+
for (let i = 0; i < length; i++) {
139140
initialValue = callbackfn(
140141
initialValue,
141-
unchecked(array[index]),
142-
index,
142+
LOAD<T>(buffer, i, byteOffset),
143+
i,
143144
array,
144145
);
145-
++index;
146146
}
147147
return initialValue;
148148
}
@@ -153,16 +153,15 @@ export function REDUCE_RIGHT<TArray extends TypedArray<T>, T, TRet>(
153153
callbackfn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,
154154
initialValue: TRet
155155
): TRet {
156-
var index = <i32>array.length - 1;
157-
var length = -1;
158-
while (index != length) {
156+
var buffer = array.buffer;
157+
var byteOffset = array.byteOffset;
158+
for (let i = array.length - 1; i >= 0; i--) {
159159
initialValue = callbackfn(
160160
initialValue,
161-
unchecked(array[index]),
162-
index,
161+
LOAD<T>(buffer, i, byteOffset),
162+
i,
163163
array,
164164
);
165-
--index;
166165
}
167166
return initialValue;
168167
}
@@ -172,12 +171,63 @@ export function MAP<TArray extends TypedArray<T>, T>(
172171
array: TArray,
173172
callbackfn: (value: T, index: i32, self: TArray) => T,
174173
): TArray {
175-
var length: i32 = array.length;
174+
var length = array.length;
175+
var buffer = array.buffer;
176+
var byteOffset = array.byteOffset;
176177
var result = instantiate<TArray>(length);
177-
var i: i32 = 0;
178-
while (i < length) {
179-
unchecked(result[i] = callbackfn(array[i], i, <TArray>array));
180-
++i;
178+
var resultBuffer = result.buffer;
179+
for (let i = 0; i < length; i++) {
180+
STORE<T, NATIVE<T>>(resultBuffer, i, <NATIVE<T>>callbackfn(LOAD<T>(buffer, i, byteOffset), i, array));
181181
}
182+
182183
return result;
183184
}
185+
186+
@inline
187+
export function FIND_INDEX<TArray extends TypedArray<T>, T>(
188+
array: TArray,
189+
callbackfn: (value: T, index: i32, array: TArray) => bool,
190+
): i32 {
191+
var length = array.length;
192+
var buffer = array.buffer;
193+
var byteOffset = array.byteOffset;
194+
for (let i = 0; i < length; i++) {
195+
if (callbackfn(LOAD<T>(buffer, i, byteOffset), i, array)) {
196+
return i;
197+
}
198+
}
199+
return -1;
200+
}
201+
202+
@inline
203+
export function SOME<TArray extends TypedArray<T>, T>(
204+
array: TArray,
205+
callbackfn: (value: T, index: i32, array: TArray) => bool,
206+
): bool {
207+
var length = array.length;
208+
var buffer = array.buffer;
209+
var byteOffset = array.byteOffset;
210+
for (let i = 0; i < length; i++) {
211+
if (callbackfn(LOAD<T>(buffer, i, byteOffset), i, array)) {
212+
return true;
213+
}
214+
}
215+
return false;
216+
}
217+
218+
@inline
219+
export function EVERY<TArray extends TypedArray<T>, T>(
220+
array: TArray,
221+
callbackfn: (value: T, index: i32, array: TArray) => bool,
222+
): bool {
223+
var length = array.length;
224+
var buffer = array.buffer;
225+
var byteOffset = array.byteOffset;
226+
for (let i = 0; i < length; i++) {
227+
if (callbackfn(LOAD<T>(buffer, i, byteOffset), i, array)) {
228+
continue;
229+
}
230+
return false;
231+
}
232+
return true;
233+
}

std/assembly/typedarray.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import {
66
REDUCE,
77
REDUCE_RIGHT,
88
MAP,
9+
FIND_INDEX,
10+
SOME,
11+
EVERY,
912
} from "./internal/typedarray";
1013

1114
import {
@@ -44,6 +47,18 @@ export class Int8Array extends TypedArray<i8> {
4447
map(callbackfn: (value: i8, index: i32, self: Int8Array) => i8): Int8Array {
4548
return MAP<Int8Array, i8>(this, callbackfn);
4649
}
50+
51+
findIndex(callbackfn: (value: i8, index: i32, self: Int8Array) => bool): i32 {
52+
return FIND_INDEX<Int8Array, i8>(this, callbackfn);
53+
}
54+
55+
some(callbackfn: (value: i8, index: i32, self: Int8Array) => bool): bool {
56+
return SOME<Int8Array, i8>(this, callbackfn);
57+
}
58+
59+
every(callbackfn: (value: i8, index: i32, self: Int8Array) => bool): bool {
60+
return EVERY<Int8Array, i8>(this, callbackfn);
61+
}
4762
}
4863

4964
export class Uint8Array extends TypedArray<u8> {
@@ -78,6 +93,18 @@ export class Uint8Array extends TypedArray<u8> {
7893
map(callbackfn: (value: u8, index: i32, self: Uint8Array) => u8): Uint8Array {
7994
return MAP<Uint8Array, u8>(this, callbackfn);
8095
}
96+
97+
findIndex(callbackfn: (value: u8, index: i32, self: Uint8Array) => bool): i32 {
98+
return FIND_INDEX<Uint8Array, u8>(this, callbackfn);
99+
}
100+
101+
some(callbackfn: (value: u8, index: i32, self: Uint8Array) => bool): bool {
102+
return SOME<Uint8Array, u8>(this, callbackfn);
103+
}
104+
105+
every(callbackfn: (value: u8, index: i32, self: Uint8Array) => bool): bool {
106+
return EVERY<Uint8Array, u8>(this, callbackfn);
107+
}
81108
}
82109

83110
export class Uint8ClampedArray extends Uint8Array {
@@ -108,6 +135,18 @@ export class Uint8ClampedArray extends Uint8Array {
108135
map(callbackfn: (value: u8, index: i32, self: Uint8ClampedArray) => u8): Uint8ClampedArray {
109136
return MAP<Uint8ClampedArray, u8>(this, callbackfn);
110137
}
138+
139+
findIndex(callbackfn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 {
140+
return FIND_INDEX<Uint8ClampedArray, u8>(this, callbackfn);
141+
}
142+
143+
some(callbackfn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool {
144+
return SOME<Uint8ClampedArray, u8>(this, callbackfn);
145+
}
146+
147+
every(callbackfn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool {
148+
return EVERY<Uint8ClampedArray, u8>(this, callbackfn);
149+
}
111150
}
112151

113152
export class Int16Array extends TypedArray<i16> {
@@ -142,6 +181,18 @@ export class Int16Array extends TypedArray<i16> {
142181
map(callbackfn: (value: i16, index: i32, self: Int16Array) => i16): Int16Array {
143182
return MAP<Int16Array, i16>(this, callbackfn);
144183
}
184+
185+
findIndex(callbackfn: (value: i16, index: i32, self: Int16Array) => bool): i32 {
186+
return FIND_INDEX<Int16Array, i16>(this, callbackfn);
187+
}
188+
189+
some(callbackfn: (value: i16, index: i32, self: Int16Array) => bool): bool {
190+
return SOME<Int16Array, i16>(this, callbackfn);
191+
}
192+
193+
every(callbackfn: (value: i16, index: i32, self: Int16Array) => bool): bool {
194+
return EVERY<Int16Array, i16>(this, callbackfn);
195+
}
145196
}
146197

147198
export class Uint16Array extends TypedArray<u16> {
@@ -176,6 +227,18 @@ export class Uint16Array extends TypedArray<u16> {
176227
map(callbackfn: (value: u16, index: i32, self: Uint16Array) => u16): Uint16Array {
177228
return MAP<Uint16Array, u16>(this, callbackfn);
178229
}
230+
231+
findIndex(callbackfn: (value: u16, index: i32, self: Uint16Array) => bool): i32 {
232+
return FIND_INDEX<Uint16Array, u16>(this, callbackfn);
233+
}
234+
235+
some(callbackfn: (value: u16, index: i32, self: Uint16Array) => bool): bool {
236+
return SOME<Uint16Array, u16>(this, callbackfn);
237+
}
238+
239+
every(callbackfn: (value: u16, index: i32, self: Uint16Array) => bool): bool {
240+
return EVERY<Uint16Array, u16>(this, callbackfn);
241+
}
179242
}
180243

181244
export class Int32Array extends TypedArray<i32> {
@@ -210,6 +273,18 @@ export class Int32Array extends TypedArray<i32> {
210273
map(callbackfn: (value: i32, index: i32, self: Int32Array) => i32): Int32Array {
211274
return MAP<Int32Array, i32>(this, callbackfn);
212275
}
276+
277+
findIndex(callbackfn: (value: i32, index: i32, self: Int32Array) => bool): i32 {
278+
return FIND_INDEX<Int32Array, i32>(this, callbackfn);
279+
}
280+
281+
some(callbackfn: (value: i32, index: i32, self: Int32Array) => bool): bool {
282+
return SOME<Int32Array, i32>(this, callbackfn);
283+
}
284+
285+
every(callbackfn: (value: i32, index: i32, self: Int32Array) => bool): bool {
286+
return EVERY<Int32Array, i32>(this, callbackfn);
287+
}
213288
}
214289

215290
export class Uint32Array extends TypedArray<u32> {
@@ -244,6 +319,18 @@ export class Uint32Array extends TypedArray<u32> {
244319
map(callbackfn: (value: u32, index: i32, self: Uint32Array) => u32): Uint32Array {
245320
return MAP<Uint32Array, u32>(this, callbackfn);
246321
}
322+
323+
findIndex(callbackfn: (value: u32, index: i32, self: Uint32Array) => bool): i32 {
324+
return FIND_INDEX<Uint32Array, u32>(this, callbackfn);
325+
}
326+
327+
some(callbackfn: (value: u32, index: i32, self: Uint32Array) => bool): bool {
328+
return SOME<Uint32Array, u32>(this, callbackfn);
329+
}
330+
331+
every(callbackfn: (value: u32, index: i32, self: Uint32Array) => bool): bool {
332+
return EVERY<Uint32Array, u32>(this, callbackfn);
333+
}
247334
}
248335

249336
export class Int64Array extends TypedArray<i64> {
@@ -278,6 +365,18 @@ export class Int64Array extends TypedArray<i64> {
278365
map(callbackfn: (value: i64, index: i32, self: Int64Array) => i64): Int64Array {
279366
return MAP<Int64Array, i64>(this, callbackfn);
280367
}
368+
369+
findIndex(callbackfn: (value: i64, index: i32, self: Int64Array) => bool): i32 {
370+
return FIND_INDEX<Int64Array, i64>(this, callbackfn);
371+
}
372+
373+
some(callbackfn: (value: i64, index: i32, self: Int64Array) => bool): bool {
374+
return SOME<Int64Array, i64>(this, callbackfn);
375+
}
376+
377+
every(callbackfn: (value: i64, index: i32, self: Int64Array) => bool): bool {
378+
return EVERY<Int64Array, i64>(this, callbackfn);
379+
}
281380
}
282381

283382
export class Uint64Array extends TypedArray<u64> {
@@ -312,6 +411,18 @@ export class Uint64Array extends TypedArray<u64> {
312411
map(callbackfn: (value: u64, index: i32, self: Uint64Array) => u64): Uint64Array {
313412
return MAP<Uint64Array, u64>(this, callbackfn);
314413
}
414+
415+
findIndex(callbackfn: (value: u64, index: i32, self: Uint64Array) => bool): i32 {
416+
return FIND_INDEX<Uint64Array, u64>(this, callbackfn);
417+
}
418+
419+
some(callbackfn: (value: u64, index: i32, self: Uint64Array) => bool): bool {
420+
return SOME<Uint64Array, u64>(this, callbackfn);
421+
}
422+
423+
every(callbackfn: (value: u64, index: i32, self: Uint64Array) => bool): bool {
424+
return EVERY<Uint64Array, u64>(this, callbackfn);
425+
}
315426
}
316427

317428
export class Float32Array extends TypedArray<f32> {
@@ -346,6 +457,18 @@ export class Float32Array extends TypedArray<f32> {
346457
map(callbackfn: (value: f32, index: i32, self: Float32Array) => f32): Float32Array {
347458
return MAP<Float32Array, f32>(this, callbackfn);
348459
}
460+
461+
findIndex(callbackfn: (value: f32, index: i32, self: Float32Array) => bool): i32 {
462+
return FIND_INDEX<Float32Array, f32>(this, callbackfn);
463+
}
464+
465+
some(callbackfn: (value: f32, index: i32, self: Float32Array) => bool): bool {
466+
return SOME<Float32Array, f32>(this, callbackfn);
467+
}
468+
469+
every(callbackfn: (value: f32, index: i32, self: Float32Array) => bool): bool {
470+
return EVERY<Float32Array, f32>(this, callbackfn);
471+
}
349472
}
350473

351474
export class Float64Array extends TypedArray<f64> {
@@ -380,4 +503,16 @@ export class Float64Array extends TypedArray<f64> {
380503
map(callbackfn: (value: f64, index: i32, self: Float64Array) => f64): Float64Array {
381504
return MAP<Float64Array, f64>(this, callbackfn);
382505
}
506+
507+
findIndex(callbackfn: (value: f64, index: i32, self: Float64Array) => bool): i32 {
508+
return FIND_INDEX<Float64Array, f64>(this, callbackfn);
509+
}
510+
511+
some(callbackfn: (value: f64, index: i32, self: Float64Array) => bool): bool {
512+
return SOME<Float64Array, f64>(this, callbackfn);
513+
}
514+
515+
every(callbackfn: (value: f64, index: i32, self: Float64Array) => bool): bool {
516+
return EVERY<Float64Array, f64>(this, callbackfn);
517+
}
383518
}

0 commit comments

Comments
 (0)