OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 /** | |
6 * Specialized integers and floating point numbers, | |
7 * with SIMD support and efficient lists. | |
8 */ | |
9 library dart.typed_data; | |
10 | |
11 import 'dart:collection' show ListMixin; | |
12 import 'dart:_internal' show FixedLengthListMixin; | |
13 import 'dart:_native_typed_data'; | |
14 import 'dart:_foreign_helper' show JS; | |
15 import 'dart:math' as Math; | |
16 | |
17 export 'dart:_native_typed_data' show Endianness; | |
18 | |
19 | |
20 /** | |
21 * A sequence of bytes underlying a typed data object. | |
22 * Used to process large quantities of binary or numerical data | |
23 * more efficiently using a typed view. | |
24 */ | |
25 abstract class ByteBuffer { | |
26 int get lengthInBytes; | |
27 | |
28 /** | |
29 * Creates a new [Uint8List] view of this buffer. | |
30 */ | |
31 Uint8List asUint8List([int offsetInBytes = 0, int length]); | |
32 /** | |
33 * Creates a new [Int8List] view of this buffer. | |
34 */ | |
35 Int8List asInt8List([int offsetInBytes = 0, int length]); | |
36 /** | |
37 * Creates a new [Uint8Clamped] view of this buffer. | |
38 */ | |
39 Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]); | |
40 /** | |
41 * Creates a new [Uint16List] view of this buffer. | |
42 */ | |
43 Uint16List asUint16List([int offsetInBytes = 0, int length]); | |
44 /** | |
45 * Creates a new [Int16List] view of this buffer. | |
46 */ | |
47 Int16List asInt16List([int offsetInBytes = 0, int length]); | |
48 /** | |
49 * Creates a new [Uint32List] view of this buffer. | |
50 */ | |
51 Uint32List asUint32List([int offsetInBytes = 0, int length]); | |
52 /** | |
53 * Creates a new [Int32List] view of this buffer. | |
54 */ | |
55 Int32List asInt32List([int offsetInBytes = 0, int length]); | |
56 /** | |
57 * Creates a new [Uint64List] view of this buffer. | |
58 */ | |
59 Uint64List asUint64List([int offsetInBytes = 0, int length]); | |
60 /** | |
61 * Creates a new [Int64List] view of this buffer. | |
62 */ | |
63 Int64List asInt64List([int offsetInBytes = 0, int length]); | |
64 /** | |
65 * Creates a new [Int32x4List] view of this buffer. | |
66 */ | |
67 Int32x4List asInt32x4List([int offsetInBytes = 0, int length]); | |
68 /** | |
69 * Creates a new [Float32List] view of this buffer. | |
70 */ | |
71 Float32List asFloat32List([int offsetInBytes = 0, int length]); | |
72 /** | |
73 * Creates a new [Float64List] view of this buffer. | |
74 */ | |
75 Float64List asFloat64List([int offsetInBytes = 0, int length]); | |
76 /** | |
77 * Creates a new [Float32x4List] view of this buffer. | |
78 */ | |
79 Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]); | |
80 /** | |
81 * Creates a new [Float64x2List] view of this buffer. | |
82 */ | |
83 Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]); | |
84 /** | |
85 * Creates a new [ByteData] view of this buffer. | |
86 */ | |
87 ByteData asByteData([int offsetInBytes = 0, int length]); | |
88 } | |
89 | |
90 | |
91 /** | |
92 * A typed view of a sequence of bytes. | |
93 */ | |
94 abstract class TypedData { | |
95 /** | |
96 * Returns the byte buffer associated with this object. | |
97 */ | |
98 ByteBuffer get buffer; | |
99 | |
100 /** | |
101 * Returns the length of this view, in bytes. | |
102 */ | |
103 int get lengthInBytes; | |
104 | |
105 /** | |
106 * Returns the offset in bytes into the underlying byte buffer of this view. | |
107 */ | |
108 int get offsetInBytes; | |
109 | |
110 /** | |
111 * Returns the number of bytes in the representation of each element in this | |
112 * list. | |
113 */ | |
114 int get elementSizeInBytes; | |
115 } | |
116 | |
117 | |
118 /** | |
119 * A fixed-length, random-access sequence of bytes that also provides random | |
120 * and unaligned access to the fixed-width integers and floating point | |
121 * numbers represented by those bytes. | |
122 * ByteData may be used to pack and unpack data from external sources | |
123 * (such as networks or files systems), and to process large quantities | |
124 * of numerical data more efficiently than would be possible | |
125 * with ordinary [List] implementations. ByteData can save space, by | |
126 * eliminating the need for object headers, and time, by eliminating the | |
127 * need for data copies. Finally, ByteData may be used to intentionally | |
128 * reinterpret the bytes representing one arithmetic type as another. | |
129 * For example this code fragment determine what 32-bit signed integer | |
130 * is represented by the bytes of a 32-bit floating point number: | |
131 * | |
132 * var buffer = new Uint8List(8).buffer; | |
133 * var bdata = new ByteData.view(buffer); | |
134 * bdata.setFloat32(0, 3.04); | |
135 * int huh = bdata.getInt32(0); | |
136 */ | |
137 abstract class ByteData extends TypedData { | |
138 /** | |
139 * Creates a [ByteData] of the specified length (in elements), all of | |
140 * whose elements are initially zero. | |
141 */ | |
142 factory ByteData(int length) => new NativeByteData(length); | |
143 | |
144 /** | |
145 * Creates an [ByteData] _view_ of the specified region in the specified | |
146 * byte buffer. Changes in the [ByteData] will be visible in the byte | |
147 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
148 * specified, it defaults to zero (the first byte in the byte buffer). | |
149 * If the length is not specified, it defaults to null, which indicates | |
150 * that the view extends to the end of the byte buffer. | |
151 * | |
152 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
153 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
154 * the length of [buffer]. | |
155 */ | |
156 factory ByteData.view(ByteBuffer buffer, | |
157 [int offsetInBytes = 0, int length]) => | |
158 buffer.asByteData(offsetInBytes, length); | |
159 | |
160 int get elementSizeInBytes => 1; | |
161 | |
162 /** | |
163 * Returns the floating point number represented by the four bytes at | |
164 * the specified [byteOffset] in this object, in IEEE 754 | |
165 * single-precision binary floating-point format (binary32). | |
166 * | |
167 * Throws [RangeError] if [byteOffset] is negative, or | |
168 * `byteOffset + 4` is greater than the length of this object. | |
169 */ | |
170 num getFloat32(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
171 | |
172 /** | |
173 * Returns the floating point number represented by the eight bytes at | |
174 * the specified [byteOffset] in this object, in IEEE 754 | |
175 * double-precision binary floating-point format (binary64). | |
176 * | |
177 * Throws [RangeError] if [byteOffset] is negative, or | |
178 * `byteOffset + 8` is greater than the length of this object. | |
179 */ | |
180 num getFloat64(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
181 | |
182 /** | |
183 * Returns the (possibly negative) integer represented by the two bytes at | |
184 * the specified [byteOffset] in this object, in two's complement binary | |
185 * form. | |
186 * The return value will be between 2<sup>15</sup> and 2<sup>15</sup> - 1, | |
187 * inclusive. | |
188 * | |
189 * Throws [RangeError] if [byteOffset] is negative, or | |
190 * `byteOffset + 2` is greater than the length of this object. | |
191 */ | |
192 int getInt16(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
193 | |
194 /** | |
195 * Returns the (possibly negative) integer represented by the four bytes at | |
196 * the specified [byteOffset] in this object, in two's complement binary | |
197 * form. | |
198 * The return value will be between 2<sup>31</sup> and 2<sup>31</sup> - 1, | |
199 * inclusive. | |
200 * | |
201 * Throws [RangeError] if [byteOffset] is negative, or | |
202 * `byteOffset + 4` is greater than the length of this object. | |
203 */ | |
204 int getInt32(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
205 | |
206 /** | |
207 * Returns the (possibly negative) integer represented by the eight bytes at | |
208 * the specified [byteOffset] in this object, in two's complement binary | |
209 * form. | |
210 * The return value will be between 2<sup>63</sup> and 2<sup>63</sup> - 1, | |
211 * inclusive. | |
212 * | |
213 * Throws [RangeError] if [byteOffset] is negative, or | |
214 * `byteOffset + 8` is greater than the length of this object. | |
215 */ | |
216 int getInt64(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
217 | |
218 /** | |
219 * Returns the (possibly negative) integer represented by the byte at the | |
220 * specified [byteOffset] in this object, in two's complement binary | |
221 * representation. The return value will be between -128 and 127, inclusive. | |
222 * | |
223 * Throws [RangeError] if [byteOffset] is negative, or | |
224 * greater than or equal to the length of this object. | |
225 */ | |
226 int getInt8(int byteOffset) ; | |
227 | |
228 /** | |
229 * Returns the positive integer represented by the two bytes starting | |
230 * at the specified [byteOffset] in this object, in unsigned binary | |
231 * form. | |
232 * The return value will be between 0 and 2<sup>16</sup> - 1, inclusive. | |
233 * | |
234 * Throws [RangeError] if [byteOffset] is negative, or | |
235 * `byteOffset + 2` is greater than the length of this object. | |
236 */ | |
237 int getUint16(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
238 | |
239 /** | |
240 * Returns the positive integer represented by the four bytes starting | |
241 * at the specified [byteOffset] in this object, in unsigned binary | |
242 * form. | |
243 * The return value will be between 0 and 2<sup>32</sup> - 1, inclusive. | |
244 * | |
245 * Throws [RangeError] if [byteOffset] is negative, or | |
246 * `byteOffset + 4` is greater than the length of this object. | |
247 */ | |
248 int getUint32(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
249 | |
250 /** | |
251 * Returns the positive integer represented by the eight bytes starting | |
252 * at the specified [byteOffset] in this object, in unsigned binary | |
253 * form. | |
254 * The return value will be between 0 and 2<sup>64</sup> - 1, inclusive. | |
255 * | |
256 * Throws [RangeError] if [byteOffset] is negative, or | |
257 * `byteOffset + 8` is greater than the length of this object. | |
258 */ | |
259 int getUint64(int byteOffset, [Endianness endian=Endianness.BIG_ENDIAN]); | |
260 | |
261 /** | |
262 * Returns the positive integer represented by the byte at the specified | |
263 * [byteOffset] in this object, in unsigned binary form. The | |
264 * return value will be between 0 and 255, inclusive. | |
265 * | |
266 * Throws [RangeError] if [byteOffset] is negative, or | |
267 * greater than or equal to the length of this object. | |
268 */ | |
269 int getUint8(int byteOffset); | |
270 | |
271 /** | |
272 * Sets the four bytes starting at the specified [byteOffset] in this | |
273 * object to the IEEE 754 single-precision binary floating-point | |
274 * (binary32) representation of the specified [value]. | |
275 * | |
276 * **Note that this method can lose precision.** The input [value] is | |
277 * a 64-bit floating point value, which will be converted to 32-bit | |
278 * floating point value by IEEE 754 rounding rules before it is stored. | |
279 * If [value] cannot be represented exactly as a binary32, it will be | |
280 * converted to the nearest binary32 value. If two binary32 values are | |
281 * equally close, the one whose least significant bit is zero will be used. | |
282 * Note that finite (but large) values can be converted to infinity, and | |
283 * small non-zero values can be converted to zero. | |
284 * | |
285 * Throws [RangeError] if [byteOffset] is negative, or | |
286 * `byteOffset + 4` is greater than the length of this object. | |
287 */ | |
288 void setFloat32(int byteOffset, num value, | |
289 [Endianness endian=Endianness.BIG_ENDIAN]); | |
290 | |
291 /** | |
292 * Sets the eight bytes starting at the specified [byteOffset] in this | |
293 * object to the IEEE 754 double-precision binary floating-point | |
294 * (binary64) representation of the specified [value]. | |
295 * | |
296 * Throws [RangeError] if [byteOffset] is negative, or | |
297 * `byteOffset + 8` is greater than the length of this object. | |
298 */ | |
299 void setFloat64(int byteOffset, num value, | |
300 [Endianness endian=Endianness.BIG_ENDIAN]); | |
301 | |
302 /** | |
303 * Sets the two bytes starting at the specified [byteOffset] in this | |
304 * object to the two's complement binary representation of the specified | |
305 * [value], which must fit in two bytes. In other words, [value] must lie | |
306 * between 2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive. | |
307 * | |
308 * Throws [RangeError] if [byteOffset] is negative, or | |
309 * `byteOffset + 2` is greater than the length of this object. | |
310 */ | |
311 void setInt16(int byteOffset, int value, | |
312 [Endianness endian=Endianness.BIG_ENDIAN]); | |
313 | |
314 /** | |
315 * Sets the four bytes starting at the specified [byteOffset] in this | |
316 * object to the two's complement binary representation of the specified | |
317 * [value], which must fit in four bytes. In other words, [value] must lie | |
318 * between 2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive. | |
319 * | |
320 * Throws [RangeError] if [byteOffset] is negative, or | |
321 * `byteOffset + 4` is greater than the length of this object. | |
322 */ | |
323 void setInt32(int byteOffset, int value, | |
324 [Endianness endian=Endianness.BIG_ENDIAN]); | |
325 | |
326 /** | |
327 * Sets the eight bytes starting at the specified [byteOffset] in this | |
328 * object to the two's complement binary representation of the specified | |
329 * [value], which must fit in eight bytes. In other words, [value] must lie | |
330 * between 2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive. | |
331 * | |
332 * Throws [RangeError] if [byteOffset] is negative, or | |
333 * `byteOffset + 8` is greater than the length of this object. | |
334 */ | |
335 void setInt64(int byteOffset, int value, | |
336 [Endianness endian=Endianness.BIG_ENDIAN]); | |
337 | |
338 /** | |
339 * Sets the byte at the specified [byteOffset] in this object to the | |
340 * two's complement binary representation of the specified [value], which | |
341 * must fit in a single byte. In other words, [value] must be between | |
342 * -128 and 127, inclusive. | |
343 * | |
344 * Throws [RangeError] if [byteOffset] is negative, or | |
345 * greater than or equal to the length of this object. | |
346 */ | |
347 void setInt8(int byteOffset, int value); | |
348 | |
349 /** | |
350 * Sets the two bytes starting at the specified [byteOffset] in this object | |
351 * to the unsigned binary representation of the specified [value], | |
352 * which must fit in two bytes. in other words, [value] must be between | |
353 * 0 and 2<sup>16</sup> - 1, inclusive. | |
354 * | |
355 * Throws [RangeError] if [byteOffset] is negative, or | |
356 * `byteOffset + 2` is greater than the length of this object. | |
357 */ | |
358 void setUint16(int byteOffset, int value, | |
359 [Endianness endian=Endianness.BIG_ENDIAN]); | |
360 | |
361 /** | |
362 * Sets the four bytes starting at the specified [byteOffset] in this object | |
363 * to the unsigned binary representation of the specified [value], | |
364 * which must fit in four bytes. in other words, [value] must be between | |
365 * 0 and 2<sup>32</sup> - 1, inclusive. | |
366 * | |
367 * Throws [RangeError] if [byteOffset] is negative, or | |
368 * `byteOffset + 4` is greater than the length of this object. | |
369 */ | |
370 void setUint32(int byteOffset, int value, | |
371 [Endianness endian=Endianness.BIG_ENDIAN]); | |
372 | |
373 /** | |
374 * Sets the eight bytes starting at the specified [byteOffset] in this object | |
375 * to the unsigned binary representation of the specified [value], | |
376 * which must fit in eight bytes. in other words, [value] must be between | |
377 * 0 and 2<sup>64</sup> - 1, inclusive. | |
378 * | |
379 * Throws [RangeError] if [byteOffset] is negative, or | |
380 * `byteOffset + 8` is greater than the length of this object. | |
381 */ | |
382 void setUint64(int byteOffset, int value, | |
383 [Endianness endian=Endianness.BIG_ENDIAN]); | |
384 | |
385 /** | |
386 * Sets the byte at the specified [byteOffset] in this object to the | |
387 * unsigned binary representation of the specified [value], which must fit | |
388 * in a single byte. in other words, [value] must be between 0 and 255, | |
389 * inclusive. | |
390 * | |
391 * Throws [RangeError] if [byteOffset] is negative, | |
392 * or greater than or equal to the length of this object. | |
393 */ | |
394 void setUint8(int byteOffset, int value); | |
395 } | |
396 | |
397 | |
398 /** | |
399 * A fixed-length list of IEEE 754 single-precision binary floating-point | |
400 * numbers that is viewable as a [TypedData]. For long lists, this | |
401 * implementation can be considerably more space- and time-efficient than | |
402 * the default [List] implementation. | |
403 */ | |
404 abstract class Float32List implements TypedData, List<double> { | |
405 /** | |
406 * Creates a [Float32List] of the specified length (in elements), all of | |
407 * whose elements are initially zero. | |
408 */ | |
409 factory Float32List(int length) = NativeFloat32List; | |
410 | |
411 /** | |
412 * Creates a [Float32List] with the same size as the [elements] list | |
413 * and copies over the elements. | |
414 */ | |
415 factory Float32List.fromList(List<double> elements) => | |
416 new NativeFloat32List.fromList(elements); | |
417 | |
418 /** | |
419 * Creates a [Float32List] _view_ of the specified region in the specified | |
420 * byte buffer. Changes in the [Float32List] will be visible in the byte | |
421 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
422 * specified, it defaults to zero (the first byte in the byte buffer). | |
423 * If the length is not specified, it defaults to null, which indicates | |
424 * that the view extends to the end of the byte buffer. | |
425 * | |
426 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
427 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
428 * the length of [buffer]. | |
429 * | |
430 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
431 * BYTES_PER_ELEMENT. | |
432 */ | |
433 factory Float32List.view(ByteBuffer buffer, | |
434 [int offsetInBytes = 0, int length]) => | |
435 buffer.asFloat32List(offsetInBytes, length); | |
436 | |
437 static const int BYTES_PER_ELEMENT = 4; | |
438 } | |
439 | |
440 | |
441 /** | |
442 * A fixed-length list of IEEE 754 double-precision binary floating-point | |
443 * numbers that is viewable as a [TypedData]. For long lists, this | |
444 * implementation can be considerably more space- and time-efficient than | |
445 * the default [List] implementation. | |
446 */ | |
447 abstract class Float64List implements TypedData, List<double> { | |
448 /** | |
449 * Creates a [Float64List] of the specified length (in elements), all of | |
450 * whose elements are initially zero. | |
451 */ | |
452 factory Float64List(int length) = NativeFloat64List; | |
453 | |
454 /** | |
455 * Creates a [Float64List] with the same size as the [elements] list | |
456 * and copies over the elements. | |
457 */ | |
458 factory Float64List.fromList(List<double> elements) => | |
459 new NativeFloat64List.fromList(elements); | |
460 | |
461 /** | |
462 * Creates a [Float64List] _view_ of the specified region in the specified | |
463 * byte buffer. Changes in the [Float64List] will be visible in the byte | |
464 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
465 * specified, it defaults to zero (the first byte in the byte buffer). | |
466 * If the length is not specified, it defaults to null, which indicates | |
467 * that the view extends to the end of the byte buffer. | |
468 * | |
469 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
470 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
471 * the length of [buffer]. | |
472 * | |
473 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
474 * BYTES_PER_ELEMENT. | |
475 */ | |
476 factory Float64List.view(ByteBuffer buffer, | |
477 [int offsetInBytes = 0, int length]) => | |
478 buffer.asFloat64List(offsetInBytes, length); | |
479 | |
480 static const int BYTES_PER_ELEMENT = 8; | |
481 } | |
482 | |
483 | |
484 /** | |
485 * A fixed-length list of 16-bit signed integers that is viewable as a | |
486 * [TypedData]. For long lists, this implementation can be considerably | |
487 * more space- and time-efficient than the default [List] implementation. | |
488 */ | |
489 abstract class Int16List extends TypedData implements List<int> { | |
490 /** | |
491 * Creates an [Int16List] of the specified length (in elements), all of | |
492 * whose elements are initially zero. | |
493 */ | |
494 factory Int16List(int length) = NativeInt16List; | |
495 | |
496 /** | |
497 * Creates a [Int16List] with the same size as the [elements] list | |
498 * and copies over the elements. | |
499 */ | |
500 factory Int16List.fromList(List<int> elements) => | |
501 new NativeInt16List.fromList(elements); | |
502 | |
503 /** | |
504 * Creates an [Int16List] _view_ of the specified region in the specified | |
505 * byte buffer. Changes in the [Int16List] will be visible in the byte | |
506 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
507 * specified, it defaults to zero (the first byte in the byte buffer). | |
508 * If the length is not specified, it defaults to null, which indicates | |
509 * that the view extends to the end of the byte buffer. | |
510 * | |
511 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
512 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
513 * the length of [buffer]. | |
514 * | |
515 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
516 * BYTES_PER_ELEMENT. | |
517 */ | |
518 factory Int16List.view(ByteBuffer buffer, | |
519 [int offsetInBytes = 0, int length]) => | |
520 buffer.asInt16List(offsetInBytes, length); | |
521 | |
522 static const int BYTES_PER_ELEMENT = 2; | |
523 } | |
524 | |
525 | |
526 /** | |
527 * A fixed-length list of 32-bit signed integers that is viewable as a | |
528 * [TypedData]. For long lists, this implementation can be considerably | |
529 * more space- and time-efficient than the default [List] implementation. | |
530 */ | |
531 abstract class Int32List implements TypedData, List<int> { | |
532 /** | |
533 * Creates an [Int32List] of the specified length (in elements), all of | |
534 * whose elements are initially zero. | |
535 */ | |
536 factory Int32List(int length) = NativeInt32List; | |
537 | |
538 /** | |
539 * Creates a [Int32List] with the same size as the [elements] list | |
540 * and copies over the elements. | |
541 */ | |
542 factory Int32List.fromList(List<int> elements) => | |
543 new NativeInt32List.fromList(elements); | |
544 | |
545 /** | |
546 * Creates an [Int32List] _view_ of the specified region in the specified | |
547 * byte buffer. Changes in the [Int32List] will be visible in the byte | |
548 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
549 * specified, it defaults to zero (the first byte in the byte buffer). | |
550 * If the length is not specified, it defaults to null, which indicates | |
551 * that the view extends to the end of the byte buffer. | |
552 * | |
553 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
554 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
555 * the length of [buffer]. | |
556 * | |
557 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
558 * BYTES_PER_ELEMENT. | |
559 */ | |
560 factory Int32List.view(ByteBuffer buffer, | |
561 [int offsetInBytes = 0, int length]) => | |
562 buffer.asInt32List(offsetInBytes, length); | |
563 | |
564 static const int BYTES_PER_ELEMENT = 4; | |
565 } | |
566 | |
567 | |
568 /** | |
569 * A fixed-length list of 8-bit signed integers. | |
570 * For long lists, this implementation can be considerably | |
571 * more space- and time-efficient than the default [List] implementation. | |
572 */ | |
573 abstract class Int8List implements TypedData, List<int> { | |
574 /** | |
575 * Creates an [Int8List] of the specified length (in elements), all of | |
576 * whose elements are initially zero. | |
577 */ | |
578 factory Int8List(int length) = NativeInt8List; | |
579 | |
580 /** | |
581 * Creates a [Int8List] with the same size as the [elements] list | |
582 * and copies over the elements. | |
583 */ | |
584 factory Int8List.fromList(List<int> elements) => | |
585 new NativeInt8List.fromList(elements); | |
586 | |
587 /** | |
588 * Creates an [Int8List] _view_ of the specified region in the specified | |
589 * byte buffer. Changes in the [Int8List] will be visible in the byte | |
590 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
591 * specified, it defaults to zero (the first byte in the byte buffer). | |
592 * If the length is not specified, it defaults to null, which indicates | |
593 * that the view extends to the end of the byte buffer. | |
594 * | |
595 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
596 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
597 * the length of [buffer]. | |
598 */ | |
599 factory Int8List.view(ByteBuffer buffer, | |
600 [int offsetInBytes = 0, int length]) => | |
601 buffer.asInt8List(offsetInBytes, length); | |
602 | |
603 static const int BYTES_PER_ELEMENT = 1; | |
604 } | |
605 | |
606 | |
607 /** | |
608 * A fixed-length list of 16-bit unsigned integers that is viewable as a | |
609 * [TypedData]. For long lists, this implementation can be considerably | |
610 * more space- and time-efficient than the default [List] implementation. | |
611 */ | |
612 abstract class Uint16List implements TypedData, List<int> { | |
613 /** | |
614 * Creates a [Uint16List] of the specified length (in elements), all | |
615 * of whose elements are initially zero. | |
616 */ | |
617 factory Uint16List(int length) = NativeUint16List; | |
618 | |
619 /** | |
620 * Creates a [Uint16List] with the same size as the [elements] list | |
621 * and copies over the elements. | |
622 */ | |
623 factory Uint16List.fromList(List<int> elements) => | |
624 new NativeUint16List.fromList(elements); | |
625 | |
626 /** | |
627 * Creates a [Uint16List] _view_ of the specified region in | |
628 * the specified byte buffer. Changes in the [Uint16List] will be | |
629 * visible in the byte buffer and vice versa. If the [offsetInBytes] index | |
630 * of the region is not specified, it defaults to zero (the first byte in | |
631 * the byte buffer). If the length is not specified, it defaults to null, | |
632 * which indicates that the view extends to the end of the byte buffer. | |
633 * | |
634 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
635 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
636 * the length of [buffer]. | |
637 * | |
638 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
639 * BYTES_PER_ELEMENT. | |
640 */ | |
641 factory Uint16List.view(ByteBuffer buffer, | |
642 [int offsetInBytes = 0, int length]) => | |
643 buffer.asUint16List(offsetInBytes, length); | |
644 | |
645 static const int BYTES_PER_ELEMENT = 2; | |
646 } | |
647 | |
648 | |
649 /** | |
650 * A fixed-length list of 32-bit unsigned integers that is viewable as a | |
651 * [TypedData]. For long lists, this implementation can be considerably | |
652 * more space- and time-efficient than the default [List] implementation. | |
653 */ | |
654 abstract class Uint32List implements TypedData, List<int> { | |
655 /** | |
656 * Creates a [Uint32List] of the specified length (in elements), all | |
657 * of whose elements are initially zero. | |
658 */ | |
659 factory Uint32List(int length) = NativeUint32List; | |
660 | |
661 /** | |
662 * Creates a [Uint32List] with the same size as the [elements] list | |
663 * and copies over the elements. | |
664 */ | |
665 factory Uint32List.fromList(List<int> elements) => | |
666 new NativeUint32List.fromList(elements); | |
667 | |
668 /** | |
669 * Creates a [Uint32List] _view_ of the specified region in | |
670 * the specified byte buffer. Changes in the [Uint32] will be | |
671 * visible in the byte buffer and vice versa. If the [offsetInBytes] index | |
672 * of the region is not specified, it defaults to zero (the first byte in | |
673 * the byte buffer). If the length is not specified, it defaults to null, | |
674 * which indicates that the view extends to the end of the byte buffer. | |
675 * | |
676 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
677 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
678 * the length of [buffer]. | |
679 * | |
680 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
681 * BYTES_PER_ELEMENT. | |
682 */ | |
683 factory Uint32List.view(ByteBuffer buffer, | |
684 [int offsetInBytes = 0, int length]) => | |
685 buffer.asUint32List(offsetInBytes, length); | |
686 | |
687 static const int BYTES_PER_ELEMENT = 4; | |
688 } | |
689 | |
690 | |
691 /** | |
692 * A fixed-length list of 8-bit unsigned integers. | |
693 * For long lists, this implementation can be considerably | |
694 * more space- and time-efficient than the default [List] implementation. | |
695 * Indexed store clamps the value to range 0..0xFF. | |
696 */ | |
697 abstract class Uint8ClampedList implements TypedData, List<int> { | |
698 /** | |
699 * Creates a [Uint8ClampedList] of the specified length (in elements), all of | |
700 * whose elements are initially zero. | |
701 */ | |
702 factory Uint8ClampedList(int length) = NativeUint8ClampedList; | |
703 | |
704 /** | |
705 * Creates a [Uint8ClampedList] of the same size as the [elements] | |
706 * list and copies over the values clamping when needed. | |
707 */ | |
708 factory Uint8ClampedList.fromList(List<int> elements) => | |
709 new NativeUint8ClampedList.fromList(elements); | |
710 | |
711 /** | |
712 * Creates a [Uint8ClampedList] _view_ of the specified region in the | |
713 * specified byte [buffer]. Changes in the [Uint8List] will be visible in the | |
714 * byte buffer and vice versa. If the [offsetInBytes] index of the region is | |
715 * not specified, it defaults to zero (the first byte in the byte buffer). | |
716 * If the length is not specified, it defaults to null, which indicates that | |
717 * the view extends to the end of the byte buffer. | |
718 * | |
719 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
720 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
721 * the length of [buffer]. | |
722 */ | |
723 factory Uint8ClampedList.view(ByteBuffer buffer, | |
724 [int offsetInBytes = 0, int length]) => | |
725 buffer.asUint8ClampedList(offsetInBytes, length); | |
726 | |
727 static const int BYTES_PER_ELEMENT = 1; | |
728 } | |
729 | |
730 | |
731 /** | |
732 * A fixed-length list of 8-bit unsigned integers. | |
733 * For long lists, this implementation can be considerably | |
734 * more space- and time-efficient than the default [List] implementation. | |
735 */ | |
736 abstract class Uint8List implements TypedData, List<int> { | |
737 /** | |
738 * Creates a [Uint8List] of the specified length (in elements), all of | |
739 * whose elements are initially zero. | |
740 */ | |
741 factory Uint8List(int length) = NativeUint8List; | |
742 | |
743 /** | |
744 * Creates a [Uint8List] with the same size as the [elements] list | |
745 * and copies over the elements. | |
746 */ | |
747 factory Uint8List.fromList(List<int> elements) => | |
748 new NativeUint8List.fromList(elements); | |
749 | |
750 /** | |
751 * Creates a [Uint8List] _view_ of the specified region in the specified | |
752 * byte buffer. Changes in the [Uint8List] will be visible in the byte | |
753 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
754 * specified, it defaults to zero (the first byte in the byte buffer). | |
755 * If the length is not specified, it defaults to null, which indicates | |
756 * that the view extends to the end of the byte buffer. | |
757 * | |
758 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
759 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
760 * the length of [buffer]. | |
761 */ | |
762 factory Uint8List.view(ByteBuffer buffer, | |
763 [int offsetInBytes = 0, int length]) => | |
764 buffer.asUint8List(offsetInBytes, length); | |
765 | |
766 static const int BYTES_PER_ELEMENT = 1; | |
767 } | |
768 | |
769 | |
770 /** | |
771 * A fixed-length list of 64-bit signed integers that is viewable as a | |
772 * [TypedData]. For long lists, this implementation can be considerably | |
773 * more space- and time-efficient than the default [List] implementation. | |
774 */ | |
775 abstract class Int64List extends TypedData implements List<int> { | |
776 /** | |
777 * Creates an [Int64List] of the specified length (in elements), all of | |
778 * whose elements are initially zero. | |
779 */ | |
780 factory Int64List(int length) { | |
781 throw new UnsupportedError("Int64List not supported by dart2js."); | |
782 } | |
783 | |
784 /** | |
785 * Creates a [Int64List] with the same size as the [elements] list | |
786 * and copies over the elements. | |
787 */ | |
788 factory Int64List.fromList(List<int> list) { | |
789 throw new UnsupportedError("Int64List not supported by dart2js."); | |
790 } | |
791 | |
792 /** | |
793 * Creates an [Int64List] _view_ of the specified region in the specified | |
794 * byte buffer. Changes in the [Int64List] will be visible in the byte buffer | |
795 * and vice versa. If the [offsetInBytes] index of the region is not | |
796 * specified, it defaults to zero (the first byte in the byte buffer). | |
797 * If the length is not specified, it defaults to null, which indicates that | |
798 * the view extends to the end of the byte buffer. | |
799 * | |
800 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
801 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
802 * the length of [buffer]. | |
803 * | |
804 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
805 * BYTES_PER_ELEMENT. | |
806 */ | |
807 factory Int64List.view(ByteBuffer buffer, [int byteOffset, int length]) { | |
808 throw new UnsupportedError("Int64List not supported by dart2js."); | |
809 } | |
810 | |
811 static const int BYTES_PER_ELEMENT = 8; | |
812 } | |
813 | |
814 | |
815 /** | |
816 * A fixed-length list of 64-bit unsigned integers that is viewable as a | |
817 * [TypedData]. For long lists, this implementation can be considerably | |
818 * more space- and time-efficient than the default [List] implementation. | |
819 */ | |
820 abstract class Uint64List extends TypedData implements List<int> { | |
821 /** | |
822 * Creates a [Uint64List] of the specified length (in elements), all | |
823 * of whose elements are initially zero. | |
824 */ | |
825 factory Uint64List(int length) { | |
826 throw new UnsupportedError("Uint64List not supported by dart2js."); | |
827 } | |
828 | |
829 /** | |
830 * Creates a [Uint64List] with the same size as the [elements] list | |
831 * and copies over the elements. | |
832 */ | |
833 factory Uint64List.fromList(List<int> list) { | |
834 throw new UnsupportedError("Uint64List not supported by dart2js."); | |
835 } | |
836 | |
837 /** | |
838 * Creates an [Uint64List] _view_ of the specified region in | |
839 * the specified byte buffer. Changes in the [Uint64List] will be | |
840 * visible in the byte buffer and vice versa. If the [offsetInBytes] | |
841 * index of the region is not specified, it defaults to zero (the first | |
842 * byte in the byte buffer). If the length is not specified, it defaults | |
843 * to null, which indicates that the view extends to the end of the byte | |
844 * buffer. | |
845 * | |
846 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
847 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
848 * the length of [buffer]. | |
849 * | |
850 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
851 * BYTES_PER_ELEMENT. | |
852 */ | |
853 factory Uint64List.view(ByteBuffer buffer, [int byteOffset, int length]) { | |
854 throw new UnsupportedError("Uint64List not supported by dart2js."); | |
855 } | |
856 | |
857 static const int BYTES_PER_ELEMENT = 8; | |
858 } | |
859 | |
860 | |
861 /** | |
862 * A fixed-length list of Float32x4 numbers that is viewable as a | |
863 * [TypedData]. For long lists, this implementation will be considerably more | |
864 * space- and time-efficient than the default [List] implementation. | |
865 */ | |
866 class Float32x4List | |
867 extends Object with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4> | |
868 implements List<Float32x4>, TypedData { | |
869 | |
870 final Float32List _storage; | |
871 | |
872 ByteBuffer get buffer => _storage.buffer; | |
873 | |
874 int get lengthInBytes => _storage.lengthInBytes; | |
875 | |
876 int get offsetInBytes => _storage.offsetInBytes; | |
877 | |
878 int get elementSizeInBytes => BYTES_PER_ELEMENT; | |
879 | |
880 void _invalidIndex(int index, int length) { | |
881 if (index < 0 || index >= length) { | |
882 throw new RangeError.range(index, 0, length); | |
883 } else { | |
884 throw new ArgumentError('Invalid list index $index'); | |
885 } | |
886 } | |
887 | |
888 void _checkIndex(int index, int length) { | |
889 if (JS('bool', '(# >>> 0 != #)', index, index) || index >= length) { | |
890 _invalidIndex(index, length); | |
891 } | |
892 } | |
893 | |
894 int _checkSublistArguments(int start, int end, int length) { | |
895 // For `sublist` the [start] and [end] indices are allowed to be equal to | |
896 // [length]. However, [_checkIndex] only allows indices in the range | |
897 // 0 .. length - 1. We therefore increment the [length] argument by one | |
898 // for the [_checkIndex] checks. | |
899 _checkIndex(start, length + 1); | |
900 if (end == null) return length; | |
901 _checkIndex(end, length + 1); | |
902 if (start > end) throw new RangeError.range(start, 0, end); | |
903 return end; | |
904 } | |
905 | |
906 /** | |
907 * Creates a [Float32x4List] of the specified length (in elements), | |
908 * all of whose elements are initially zero. | |
909 */ | |
910 Float32x4List(int length) : _storage = new Float32List(length*4); | |
911 | |
912 Float32x4List._externalStorage(Float32List storage) : _storage = storage; | |
913 | |
914 Float32x4List._slowFromList(List<Float32x4> list) | |
915 : _storage = new Float32List(list.length * 4) { | |
916 for (int i = 0; i < list.length; i++) { | |
917 var e = list[i]; | |
918 _storage[(i * 4) + 0] = e.x; | |
919 _storage[(i * 4) + 1] = e.y; | |
920 _storage[(i * 4) + 2] = e.z; | |
921 _storage[(i * 4) + 3] = e.w; | |
922 } | |
923 } | |
924 | |
925 /** | |
926 * Creates a [Float32x4List] with the same size as the [elements] list | |
927 * and copies over the elements. | |
928 */ | |
929 factory Float32x4List.fromList(List<Float32x4> list) { | |
930 if (list is Float32x4List) { | |
931 Float32x4List nativeList = list as Float32x4List; | |
932 return new Float32x4List._externalStorage( | |
933 new Float32List.fromList(nativeList._storage)); | |
934 } else { | |
935 return new Float32x4List._slowFromList(list); | |
936 } | |
937 } | |
938 | |
939 /** | |
940 * Creates a [Float32x4List] _view_ of the specified region in the specified | |
941 * byte buffer. Changes in the [Float32x4List] will be visible in the byte | |
942 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
943 * specified, it defaults to zero (the first byte in the byte buffer). | |
944 * If the length is not specified, it defaults to null, which indicates | |
945 * that the view extends to the end of the byte buffer. | |
946 * | |
947 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
948 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
949 * the length of [buffer]. | |
950 * | |
951 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
952 * BYTES_PER_ELEMENT. | |
953 */ | |
954 Float32x4List.view(ByteBuffer buffer, | |
955 [int byteOffset = 0, int length]) | |
956 : _storage = buffer.asFloat32List(byteOffset, | |
957 length != null ? length * 4 : null); | |
958 | |
959 static const int BYTES_PER_ELEMENT = 16; | |
960 | |
961 int get length => _storage.length ~/ 4; | |
962 | |
963 Float32x4 operator[](int index) { | |
964 _checkIndex(index, length); | |
965 double _x = _storage[(index * 4) + 0]; | |
966 double _y = _storage[(index * 4) + 1]; | |
967 double _z = _storage[(index * 4) + 2]; | |
968 double _w = _storage[(index * 4) + 3]; | |
969 return new Float32x4(_x, _y, _z, _w); | |
970 } | |
971 | |
972 void operator[]=(int index, Float32x4 value) { | |
973 _checkIndex(index, length); | |
974 _storage[(index * 4) + 0] = value._storage[0]; | |
975 _storage[(index * 4) + 1] = value._storage[1]; | |
976 _storage[(index * 4) + 2] = value._storage[2]; | |
977 _storage[(index * 4) + 3] = value._storage[3]; | |
978 } | |
979 | |
980 List<Float32x4> sublist(int start, [int end]) { | |
981 end = _checkSublistArguments(start, end, length); | |
982 return new Float32x4List._externalStorage( | |
983 _storage.sublist(start * 4, end * 4)); | |
984 } | |
985 } | |
986 | |
987 | |
988 /** | |
989 * A fixed-length list of Int32x4 numbers that is viewable as a | |
990 * [TypedData]. For long lists, this implementation will be considerably more | |
991 * space- and time-efficient than the default [List] implementation. | |
992 */ | |
993 class Int32x4List | |
994 extends Object with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4> | |
995 implements List<Int32x4>, TypedData { | |
996 | |
997 final Uint32List _storage; | |
998 | |
999 ByteBuffer get buffer => _storage.buffer; | |
1000 | |
1001 int get lengthInBytes => _storage.lengthInBytes; | |
1002 | |
1003 int get offsetInBytes => _storage.offsetInBytes; | |
1004 | |
1005 int get elementSizeInBytes => BYTES_PER_ELEMENT; | |
1006 | |
1007 void _invalidIndex(int index, int length) { | |
1008 if (index < 0 || index >= length) { | |
1009 throw new RangeError.range(index, 0, length); | |
1010 } else { | |
1011 throw new ArgumentError('Invalid list index $index'); | |
1012 } | |
1013 } | |
1014 | |
1015 void _checkIndex(int index, int length) { | |
1016 if (JS('bool', '(# >>> 0 != #)', index, index) | |
1017 || JS('bool', '# >= #', index, length)) { | |
1018 _invalidIndex(index, length); | |
1019 } | |
1020 } | |
1021 | |
1022 int _checkSublistArguments(int start, int end, int length) { | |
1023 // For `sublist` the [start] and [end] indices are allowed to be equal to | |
1024 // [length]. However, [_checkIndex] only allows indices in the range | |
1025 // 0 .. length - 1. We therefore increment the [length] argument by one | |
1026 // for the [_checkIndex] checks. | |
1027 _checkIndex(start, length + 1); | |
1028 if (end == null) return length; | |
1029 _checkIndex(end, length + 1); | |
1030 if (start > end) throw new RangeError.range(start, 0, end); | |
1031 return end; | |
1032 } | |
1033 | |
1034 /** | |
1035 * Creates a [Int32x4List] of the specified length (in elements), | |
1036 * all of whose elements are initially zero. | |
1037 */ | |
1038 Int32x4List(int length) : _storage = new Uint32List(length * 4); | |
1039 | |
1040 Int32x4List._externalStorage(Uint32List storage) : _storage = storage; | |
1041 | |
1042 Int32x4List._slowFromList(List<Int32x4> list) | |
1043 : _storage = new Uint32List(list.length * 4) { | |
1044 for (int i = 0; i < list.length; i++) { | |
1045 var e = list[i]; | |
1046 _storage[(i * 4) + 0] = e.x; | |
1047 _storage[(i * 4) + 1] = e.y; | |
1048 _storage[(i * 4) + 2] = e.z; | |
1049 _storage[(i * 4) + 3] = e.w; | |
1050 } | |
1051 } | |
1052 | |
1053 /** | |
1054 * Creates a [Int32x4List] with the same size as the [elements] list | |
1055 * and copies over the elements. | |
1056 */ | |
1057 factory Int32x4List.fromList(List<Int32x4> list) { | |
1058 if (list is Int32x4List) { | |
1059 return new Int32x4List._externalStorage( | |
1060 new Uint32List.fromList(list._storage)); | |
1061 } else { | |
1062 return new Int32x4List._slowFromList(list); | |
1063 } | |
1064 } | |
1065 | |
1066 /** | |
1067 * Creates a [Int32x4List] _view_ of the specified region in the specified | |
1068 * byte buffer. Changes in the [Int32x4List] will be visible in the byte | |
1069 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
1070 * specified, it defaults to zero (the first byte in the byte buffer). | |
1071 * If the length is not specified, it defaults to null, which indicates | |
1072 * that the view extends to the end of the byte buffer. | |
1073 * | |
1074 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
1075 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
1076 * the length of [buffer]. | |
1077 * | |
1078 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
1079 * BYTES_PER_ELEMENT. | |
1080 */ | |
1081 Int32x4List.view(ByteBuffer buffer, | |
1082 [int byteOffset = 0, int length]) | |
1083 : _storage = buffer.asUint32List(byteOffset, | |
1084 length != null ? length * 4 : null); | |
1085 | |
1086 static const int BYTES_PER_ELEMENT = 16; | |
1087 | |
1088 int get length => _storage.length ~/ 4; | |
1089 | |
1090 Int32x4 operator[](int index) { | |
1091 _checkIndex(index, length); | |
1092 int _x = _storage[(index * 4) + 0]; | |
1093 int _y = _storage[(index * 4) + 1]; | |
1094 int _z = _storage[(index * 4) + 2]; | |
1095 int _w = _storage[(index * 4) + 3]; | |
1096 return new Int32x4(_x, _y, _z, _w); | |
1097 } | |
1098 | |
1099 void operator[]=(int index, Int32x4 value) { | |
1100 _checkIndex(index, length); | |
1101 _storage[(index * 4) + 0] = value._storage[0]; | |
1102 _storage[(index * 4) + 1] = value._storage[1]; | |
1103 _storage[(index * 4) + 2] = value._storage[2]; | |
1104 _storage[(index * 4) + 3] = value._storage[3]; | |
1105 } | |
1106 | |
1107 List<Int32x4> sublist(int start, [int end]) { | |
1108 end = _checkSublistArguments(start, end, length); | |
1109 return new Int32x4List._externalStorage(_storage.sublist(start*4, end*4)); | |
1110 } | |
1111 } | |
1112 | |
1113 | |
1114 /** | |
1115 * A fixed-length list of Float64x2 numbers that is viewable as a | |
1116 * [TypedData]. For long lists, this implementation will be considerably more | |
1117 * space- and time-efficient than the default [List] implementation. | |
1118 */ | |
1119 class Float64x2List | |
1120 extends Object with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2> | |
1121 implements List<Float64x2>, TypedData { | |
1122 | |
1123 final Float64List _storage; | |
1124 | |
1125 ByteBuffer get buffer => _storage.buffer; | |
1126 | |
1127 int get lengthInBytes => _storage.lengthInBytes; | |
1128 | |
1129 int get offsetInBytes => _storage.offsetInBytes; | |
1130 | |
1131 int get elementSizeInBytes => BYTES_PER_ELEMENT; | |
1132 | |
1133 void _invalidIndex(int index, int length) { | |
1134 if (index < 0 || index >= length) { | |
1135 throw new RangeError.range(index, 0, length); | |
1136 } else { | |
1137 throw new ArgumentError('Invalid list index $index'); | |
1138 } | |
1139 } | |
1140 | |
1141 void _checkIndex(int index, int length) { | |
1142 if (JS('bool', '(# >>> 0 != #)', index, index) || index >= length) { | |
1143 _invalidIndex(index, length); | |
1144 } | |
1145 } | |
1146 | |
1147 int _checkSublistArguments(int start, int end, int length) { | |
1148 // For `sublist` the [start] and [end] indices are allowed to be equal to | |
1149 // [length]. However, [_checkIndex] only allows indices in the range | |
1150 // 0 .. length - 1. We therefore increment the [length] argument by one | |
1151 // for the [_checkIndex] checks. | |
1152 _checkIndex(start, length + 1); | |
1153 if (end == null) return length; | |
1154 _checkIndex(end, length + 1); | |
1155 if (start > end) throw new RangeError.range(start, 0, end); | |
1156 return end; | |
1157 } | |
1158 | |
1159 /** | |
1160 * Creates a [Float64x2List] of the specified length (in elements), | |
1161 * all of whose elements are initially zero. | |
1162 */ | |
1163 Float64x2List(int length) : _storage = new Float64List(length * 2); | |
1164 | |
1165 Float64x2List._externalStorage(Float64List storage) : _storage = storage; | |
1166 | |
1167 Float64x2List._slowFromList(List<Float64x2> list) | |
1168 : _storage = new Float64List(list.length * 2) { | |
1169 for (int i = 0; i < list.length; i++) { | |
1170 var e = list[i]; | |
1171 _storage[(i * 2) + 0] = e.x; | |
1172 _storage[(i * 2) + 1] = e.y; | |
1173 } | |
1174 } | |
1175 | |
1176 /** | |
1177 * Creates a [Float64x2List] with the same size as the [elements] list | |
1178 * and copies over the elements. | |
1179 */ | |
1180 factory Float64x2List.fromList(List<Float64x2> list) { | |
1181 if (list is Float64x2List) { | |
1182 Float64x2List nativeList = list as Float64x2List; | |
1183 return new Float64x2List._externalStorage( | |
1184 new Float64List.fromList(nativeList._storage)); | |
1185 } else { | |
1186 return new Float64x2List._slowFromList(list); | |
1187 } | |
1188 } | |
1189 | |
1190 /** | |
1191 * Creates a [Float64x2List] _view_ of the specified region in the specified | |
1192 * byte buffer. Changes in the [Float64x2List] will be visible in the byte | |
1193 * buffer and vice versa. If the [offsetInBytes] index of the region is not | |
1194 * specified, it defaults to zero (the first byte in the byte buffer). | |
1195 * If the length is not specified, it defaults to null, which indicates | |
1196 * that the view extends to the end of the byte buffer. | |
1197 * | |
1198 * Throws [RangeError] if [offsetInBytes] or [length] are negative, or | |
1199 * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than | |
1200 * the length of [buffer]. | |
1201 * | |
1202 * Throws [ArgumentError] if [offsetInBytes] is not a multiple of | |
1203 * BYTES_PER_ELEMENT. | |
1204 */ | |
1205 Float64x2List.view(ByteBuffer buffer, | |
1206 [int byteOffset = 0, int length]) | |
1207 : _storage = buffer.asFloat64List(byteOffset, | |
1208 length != null ? length * 2 : null); | |
1209 | |
1210 static const int BYTES_PER_ELEMENT = 16; | |
1211 | |
1212 int get length => _storage.length ~/ 2; | |
1213 | |
1214 Float64x2 operator[](int index) { | |
1215 _checkIndex(index, length); | |
1216 double _x = _storage[(index * 2) + 0]; | |
1217 double _y = _storage[(index * 2) + 1]; | |
1218 return new Float64x2(_x, _y); | |
1219 } | |
1220 | |
1221 void operator[]=(int index, Float64x2 value) { | |
1222 _checkIndex(index, length); | |
1223 _storage[(index * 2) + 0] = value._storage[0]; | |
1224 _storage[(index * 2) + 1] = value._storage[1]; | |
1225 } | |
1226 | |
1227 List<Float64x2> sublist(int start, [int end]) { | |
1228 end = _checkSublistArguments(start, end, length); | |
1229 return new Float64x2List._externalStorage( | |
1230 _storage.sublist(start * 2, end * 2)); | |
1231 } | |
1232 } | |
1233 | |
1234 | |
1235 /** | |
1236 * Interface of Dart Float32x4 immutable value type and operations. | |
1237 * Float32x4 stores 4 32-bit floating point values in "lanes". | |
1238 * The lanes are "x", "y", "z", and "w" respectively. | |
1239 */ | |
1240 class Float32x4 { | |
1241 final _storage = new Float32List(4); | |
1242 | |
1243 Float32x4(double x, double y, double z, double w) { | |
1244 _storage[0] = x; | |
1245 _storage[1] = y; | |
1246 _storage[2] = z; | |
1247 _storage[3] = w; | |
1248 } | |
1249 Float32x4.splat(double v) { | |
1250 _storage[0] = v; | |
1251 _storage[1] = v; | |
1252 _storage[2] = v; | |
1253 _storage[3] = v; | |
1254 } | |
1255 Float32x4.zero(); | |
1256 /// Returns a bit-wise copy of [x] as a Float32x4. | |
1257 Float32x4.fromInt32x4Bits(Int32x4 x) { | |
1258 var view = new Float32List.view(x._storage.buffer); | |
1259 _storage[0] = view[0]; | |
1260 _storage[1] = view[1]; | |
1261 _storage[2] = view[2]; | |
1262 _storage[3] = view[3]; | |
1263 } | |
1264 Float32x4.fromFloat64x2(Float64x2 v) { | |
1265 _storage[0] = v._storage[0]; | |
1266 _storage[1] = v._storage[1]; | |
1267 } | |
1268 | |
1269 String toString() { | |
1270 return '[${_storage[0]}, ${_storage[1]}, ${_storage[2]}, ${_storage[3]}]'; | |
1271 } | |
1272 | |
1273 /// Addition operator. | |
1274 Float32x4 operator+(Float32x4 other) { | |
1275 double _x = _storage[0] + other._storage[0]; | |
1276 double _y = _storage[1] + other._storage[1]; | |
1277 double _z = _storage[2] + other._storage[2]; | |
1278 double _w = _storage[3] + other._storage[3]; | |
1279 return new Float32x4(_x, _y, _z, _w); | |
1280 } | |
1281 | |
1282 /// Negate operator. | |
1283 Float32x4 operator-() { | |
1284 double _x = -_storage[0]; | |
1285 double _y = -_storage[1]; | |
1286 double _z = -_storage[2]; | |
1287 double _w = -_storage[3]; | |
1288 return new Float32x4(_x, _y, _z, _w); | |
1289 } | |
1290 | |
1291 /// Subtraction operator. | |
1292 Float32x4 operator-(Float32x4 other) { | |
1293 double _x = _storage[0] - other._storage[0]; | |
1294 double _y = _storage[1] - other._storage[1]; | |
1295 double _z = _storage[2] - other._storage[2]; | |
1296 double _w = _storage[3] - other._storage[3]; | |
1297 return new Float32x4(_x, _y, _z, _w); | |
1298 } | |
1299 | |
1300 /// Multiplication operator. | |
1301 Float32x4 operator*(Float32x4 other) { | |
1302 double _x = _storage[0] * other._storage[0]; | |
1303 double _y = _storage[1] * other._storage[1]; | |
1304 double _z = _storage[2] * other._storage[2]; | |
1305 double _w = _storage[3] * other._storage[3]; | |
1306 return new Float32x4(_x, _y, _z, _w); | |
1307 } | |
1308 | |
1309 /// Division operator. | |
1310 Float32x4 operator/(Float32x4 other) { | |
1311 double _x = _storage[0] / other._storage[0]; | |
1312 double _y = _storage[1] / other._storage[1]; | |
1313 double _z = _storage[2] / other._storage[2]; | |
1314 double _w = _storage[3] / other._storage[3]; | |
1315 return new Float32x4(_x, _y, _z, _w); | |
1316 } | |
1317 | |
1318 /// Relational less than. | |
1319 Int32x4 lessThan(Float32x4 other) { | |
1320 bool _cx = _storage[0] < other._storage[0]; | |
1321 bool _cy = _storage[1] < other._storage[1]; | |
1322 bool _cz = _storage[2] < other._storage[2]; | |
1323 bool _cw = _storage[3] < other._storage[3]; | |
1324 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1325 _cy == true ? 0xFFFFFFFF : 0x0, | |
1326 _cz == true ? 0xFFFFFFFF : 0x0, | |
1327 _cw == true ? 0xFFFFFFFF : 0x0); | |
1328 } | |
1329 | |
1330 /// Relational less than or equal. | |
1331 Int32x4 lessThanOrEqual(Float32x4 other) { | |
1332 bool _cx = _storage[0] <= other._storage[0]; | |
1333 bool _cy = _storage[1] <= other._storage[1]; | |
1334 bool _cz = _storage[2] <= other._storage[2]; | |
1335 bool _cw = _storage[3] <= other._storage[3]; | |
1336 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1337 _cy == true ? 0xFFFFFFFF : 0x0, | |
1338 _cz == true ? 0xFFFFFFFF : 0x0, | |
1339 _cw == true ? 0xFFFFFFFF : 0x0); | |
1340 } | |
1341 | |
1342 /// Relational greater than. | |
1343 Int32x4 greaterThan(Float32x4 other) { | |
1344 bool _cx = _storage[0] > other._storage[0]; | |
1345 bool _cy = _storage[1] > other._storage[1]; | |
1346 bool _cz = _storage[2] > other._storage[2]; | |
1347 bool _cw = _storage[3] > other._storage[3]; | |
1348 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1349 _cy == true ? 0xFFFFFFFF : 0x0, | |
1350 _cz == true ? 0xFFFFFFFF : 0x0, | |
1351 _cw == true ? 0xFFFFFFFF : 0x0); | |
1352 } | |
1353 | |
1354 /// Relational greater than or equal. | |
1355 Int32x4 greaterThanOrEqual(Float32x4 other) { | |
1356 bool _cx = _storage[0] >= other._storage[0]; | |
1357 bool _cy = _storage[1] >= other._storage[1]; | |
1358 bool _cz = _storage[2] >= other._storage[2]; | |
1359 bool _cw = _storage[3] >= other._storage[3]; | |
1360 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1361 _cy == true ? 0xFFFFFFFF : 0x0, | |
1362 _cz == true ? 0xFFFFFFFF : 0x0, | |
1363 _cw == true ? 0xFFFFFFFF : 0x0); | |
1364 } | |
1365 | |
1366 /// Relational equal. | |
1367 Int32x4 equal(Float32x4 other) { | |
1368 bool _cx = _storage[0] == other._storage[0]; | |
1369 bool _cy = _storage[1] == other._storage[1]; | |
1370 bool _cz = _storage[2] == other._storage[2]; | |
1371 bool _cw = _storage[3] == other._storage[3]; | |
1372 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1373 _cy == true ? 0xFFFFFFFF : 0x0, | |
1374 _cz == true ? 0xFFFFFFFF : 0x0, | |
1375 _cw == true ? 0xFFFFFFFF : 0x0); | |
1376 } | |
1377 | |
1378 /// Relational not-equal. | |
1379 Int32x4 notEqual(Float32x4 other) { | |
1380 bool _cx = _storage[0] != other._storage[0]; | |
1381 bool _cy = _storage[1] != other._storage[1]; | |
1382 bool _cz = _storage[2] != other._storage[2]; | |
1383 bool _cw = _storage[3] != other._storage[3]; | |
1384 return new Int32x4(_cx == true ? 0xFFFFFFFF : 0x0, | |
1385 _cy == true ? 0xFFFFFFFF : 0x0, | |
1386 _cz == true ? 0xFFFFFFFF : 0x0, | |
1387 _cw == true ? 0xFFFFFFFF : 0x0); | |
1388 } | |
1389 | |
1390 /// Returns a copy of [this] each lane being scaled by [s]. | |
1391 Float32x4 scale(double s) { | |
1392 double _x = s * _storage[0]; | |
1393 double _y = s * _storage[1]; | |
1394 double _z = s * _storage[2]; | |
1395 double _w = s * _storage[3]; | |
1396 return new Float32x4(_x, _y, _z, _w); | |
1397 } | |
1398 | |
1399 /// Returns the absolute value of this [Float32x4]. | |
1400 Float32x4 abs() { | |
1401 double _x = _storage[0].abs(); | |
1402 double _y = _storage[1].abs(); | |
1403 double _z = _storage[2].abs(); | |
1404 double _w = _storage[3].abs(); | |
1405 return new Float32x4(_x, _y, _z, _w); | |
1406 } | |
1407 | |
1408 /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. | |
1409 Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) { | |
1410 double _lx = lowerLimit._storage[0]; | |
1411 double _ly = lowerLimit._storage[1]; | |
1412 double _lz = lowerLimit._storage[2]; | |
1413 double _lw = lowerLimit._storage[3]; | |
1414 double _ux = upperLimit._storage[0]; | |
1415 double _uy = upperLimit._storage[1]; | |
1416 double _uz = upperLimit._storage[2]; | |
1417 double _uw = upperLimit._storage[3]; | |
1418 double _x = _storage[0]; | |
1419 double _y = _storage[1]; | |
1420 double _z = _storage[2]; | |
1421 double _w = _storage[3]; | |
1422 // MAX(MIN(self, upper), lower). | |
1423 _x = _x > _ux ? _ux : _x; | |
1424 _y = _y > _uy ? _uy : _y; | |
1425 _z = _z > _uz ? _uz : _z; | |
1426 _w = _w > _uw ? _uw : _w; | |
1427 _x = _x < _lx ? _lx : _x; | |
1428 _y = _y < _ly ? _ly : _y; | |
1429 _z = _z < _lz ? _lz : _z; | |
1430 _w = _w < _lw ? _lw : _w; | |
1431 return new Float32x4(_x, _y, _z, _w); | |
1432 } | |
1433 | |
1434 /// Extracted x value. | |
1435 double get x => _storage[0]; | |
1436 /// Extracted y value. | |
1437 double get y => _storage[1]; | |
1438 /// Extracted z value. | |
1439 double get z => _storage[2]; | |
1440 /// Extracted w value. | |
1441 double get w => _storage[3]; | |
1442 | |
1443 /// Extract the sign bit from each lane return them in the first 4 bits. | |
1444 int get signMask { | |
1445 var view = new Uint32List.view(_storage.buffer); | |
1446 var mx = (view[0] & 0x80000000) >> 31; | |
1447 var my = (view[1] & 0x80000000) >> 31; | |
1448 var mz = (view[2] & 0x80000000) >> 31; | |
1449 var mw = (view[3] & 0x80000000) >> 31; | |
1450 return mx | my << 1 | mz << 2 | mw << 3; | |
1451 } | |
1452 | |
1453 /// Mask passed to [shuffle] and [shuffleMix]. | |
1454 static const int XXXX = 0x0; | |
1455 static const int XXXY = 0x40; | |
1456 static const int XXXZ = 0x80; | |
1457 static const int XXXW = 0xC0; | |
1458 static const int XXYX = 0x10; | |
1459 static const int XXYY = 0x50; | |
1460 static const int XXYZ = 0x90; | |
1461 static const int XXYW = 0xD0; | |
1462 static const int XXZX = 0x20; | |
1463 static const int XXZY = 0x60; | |
1464 static const int XXZZ = 0xA0; | |
1465 static const int XXZW = 0xE0; | |
1466 static const int XXWX = 0x30; | |
1467 static const int XXWY = 0x70; | |
1468 static const int XXWZ = 0xB0; | |
1469 static const int XXWW = 0xF0; | |
1470 static const int XYXX = 0x4; | |
1471 static const int XYXY = 0x44; | |
1472 static const int XYXZ = 0x84; | |
1473 static const int XYXW = 0xC4; | |
1474 static const int XYYX = 0x14; | |
1475 static const int XYYY = 0x54; | |
1476 static const int XYYZ = 0x94; | |
1477 static const int XYYW = 0xD4; | |
1478 static const int XYZX = 0x24; | |
1479 static const int XYZY = 0x64; | |
1480 static const int XYZZ = 0xA4; | |
1481 static const int XYZW = 0xE4; | |
1482 static const int XYWX = 0x34; | |
1483 static const int XYWY = 0x74; | |
1484 static const int XYWZ = 0xB4; | |
1485 static const int XYWW = 0xF4; | |
1486 static const int XZXX = 0x8; | |
1487 static const int XZXY = 0x48; | |
1488 static const int XZXZ = 0x88; | |
1489 static const int XZXW = 0xC8; | |
1490 static const int XZYX = 0x18; | |
1491 static const int XZYY = 0x58; | |
1492 static const int XZYZ = 0x98; | |
1493 static const int XZYW = 0xD8; | |
1494 static const int XZZX = 0x28; | |
1495 static const int XZZY = 0x68; | |
1496 static const int XZZZ = 0xA8; | |
1497 static const int XZZW = 0xE8; | |
1498 static const int XZWX = 0x38; | |
1499 static const int XZWY = 0x78; | |
1500 static const int XZWZ = 0xB8; | |
1501 static const int XZWW = 0xF8; | |
1502 static const int XWXX = 0xC; | |
1503 static const int XWXY = 0x4C; | |
1504 static const int XWXZ = 0x8C; | |
1505 static const int XWXW = 0xCC; | |
1506 static const int XWYX = 0x1C; | |
1507 static const int XWYY = 0x5C; | |
1508 static const int XWYZ = 0x9C; | |
1509 static const int XWYW = 0xDC; | |
1510 static const int XWZX = 0x2C; | |
1511 static const int XWZY = 0x6C; | |
1512 static const int XWZZ = 0xAC; | |
1513 static const int XWZW = 0xEC; | |
1514 static const int XWWX = 0x3C; | |
1515 static const int XWWY = 0x7C; | |
1516 static const int XWWZ = 0xBC; | |
1517 static const int XWWW = 0xFC; | |
1518 static const int YXXX = 0x1; | |
1519 static const int YXXY = 0x41; | |
1520 static const int YXXZ = 0x81; | |
1521 static const int YXXW = 0xC1; | |
1522 static const int YXYX = 0x11; | |
1523 static const int YXYY = 0x51; | |
1524 static const int YXYZ = 0x91; | |
1525 static const int YXYW = 0xD1; | |
1526 static const int YXZX = 0x21; | |
1527 static const int YXZY = 0x61; | |
1528 static const int YXZZ = 0xA1; | |
1529 static const int YXZW = 0xE1; | |
1530 static const int YXWX = 0x31; | |
1531 static const int YXWY = 0x71; | |
1532 static const int YXWZ = 0xB1; | |
1533 static const int YXWW = 0xF1; | |
1534 static const int YYXX = 0x5; | |
1535 static const int YYXY = 0x45; | |
1536 static const int YYXZ = 0x85; | |
1537 static const int YYXW = 0xC5; | |
1538 static const int YYYX = 0x15; | |
1539 static const int YYYY = 0x55; | |
1540 static const int YYYZ = 0x95; | |
1541 static const int YYYW = 0xD5; | |
1542 static const int YYZX = 0x25; | |
1543 static const int YYZY = 0x65; | |
1544 static const int YYZZ = 0xA5; | |
1545 static const int YYZW = 0xE5; | |
1546 static const int YYWX = 0x35; | |
1547 static const int YYWY = 0x75; | |
1548 static const int YYWZ = 0xB5; | |
1549 static const int YYWW = 0xF5; | |
1550 static const int YZXX = 0x9; | |
1551 static const int YZXY = 0x49; | |
1552 static const int YZXZ = 0x89; | |
1553 static const int YZXW = 0xC9; | |
1554 static const int YZYX = 0x19; | |
1555 static const int YZYY = 0x59; | |
1556 static const int YZYZ = 0x99; | |
1557 static const int YZYW = 0xD9; | |
1558 static const int YZZX = 0x29; | |
1559 static const int YZZY = 0x69; | |
1560 static const int YZZZ = 0xA9; | |
1561 static const int YZZW = 0xE9; | |
1562 static const int YZWX = 0x39; | |
1563 static const int YZWY = 0x79; | |
1564 static const int YZWZ = 0xB9; | |
1565 static const int YZWW = 0xF9; | |
1566 static const int YWXX = 0xD; | |
1567 static const int YWXY = 0x4D; | |
1568 static const int YWXZ = 0x8D; | |
1569 static const int YWXW = 0xCD; | |
1570 static const int YWYX = 0x1D; | |
1571 static const int YWYY = 0x5D; | |
1572 static const int YWYZ = 0x9D; | |
1573 static const int YWYW = 0xDD; | |
1574 static const int YWZX = 0x2D; | |
1575 static const int YWZY = 0x6D; | |
1576 static const int YWZZ = 0xAD; | |
1577 static const int YWZW = 0xED; | |
1578 static const int YWWX = 0x3D; | |
1579 static const int YWWY = 0x7D; | |
1580 static const int YWWZ = 0xBD; | |
1581 static const int YWWW = 0xFD; | |
1582 static const int ZXXX = 0x2; | |
1583 static const int ZXXY = 0x42; | |
1584 static const int ZXXZ = 0x82; | |
1585 static const int ZXXW = 0xC2; | |
1586 static const int ZXYX = 0x12; | |
1587 static const int ZXYY = 0x52; | |
1588 static const int ZXYZ = 0x92; | |
1589 static const int ZXYW = 0xD2; | |
1590 static const int ZXZX = 0x22; | |
1591 static const int ZXZY = 0x62; | |
1592 static const int ZXZZ = 0xA2; | |
1593 static const int ZXZW = 0xE2; | |
1594 static const int ZXWX = 0x32; | |
1595 static const int ZXWY = 0x72; | |
1596 static const int ZXWZ = 0xB2; | |
1597 static const int ZXWW = 0xF2; | |
1598 static const int ZYXX = 0x6; | |
1599 static const int ZYXY = 0x46; | |
1600 static const int ZYXZ = 0x86; | |
1601 static const int ZYXW = 0xC6; | |
1602 static const int ZYYX = 0x16; | |
1603 static const int ZYYY = 0x56; | |
1604 static const int ZYYZ = 0x96; | |
1605 static const int ZYYW = 0xD6; | |
1606 static const int ZYZX = 0x26; | |
1607 static const int ZYZY = 0x66; | |
1608 static const int ZYZZ = 0xA6; | |
1609 static const int ZYZW = 0xE6; | |
1610 static const int ZYWX = 0x36; | |
1611 static const int ZYWY = 0x76; | |
1612 static const int ZYWZ = 0xB6; | |
1613 static const int ZYWW = 0xF6; | |
1614 static const int ZZXX = 0xA; | |
1615 static const int ZZXY = 0x4A; | |
1616 static const int ZZXZ = 0x8A; | |
1617 static const int ZZXW = 0xCA; | |
1618 static const int ZZYX = 0x1A; | |
1619 static const int ZZYY = 0x5A; | |
1620 static const int ZZYZ = 0x9A; | |
1621 static const int ZZYW = 0xDA; | |
1622 static const int ZZZX = 0x2A; | |
1623 static const int ZZZY = 0x6A; | |
1624 static const int ZZZZ = 0xAA; | |
1625 static const int ZZZW = 0xEA; | |
1626 static const int ZZWX = 0x3A; | |
1627 static const int ZZWY = 0x7A; | |
1628 static const int ZZWZ = 0xBA; | |
1629 static const int ZZWW = 0xFA; | |
1630 static const int ZWXX = 0xE; | |
1631 static const int ZWXY = 0x4E; | |
1632 static const int ZWXZ = 0x8E; | |
1633 static const int ZWXW = 0xCE; | |
1634 static const int ZWYX = 0x1E; | |
1635 static const int ZWYY = 0x5E; | |
1636 static const int ZWYZ = 0x9E; | |
1637 static const int ZWYW = 0xDE; | |
1638 static const int ZWZX = 0x2E; | |
1639 static const int ZWZY = 0x6E; | |
1640 static const int ZWZZ = 0xAE; | |
1641 static const int ZWZW = 0xEE; | |
1642 static const int ZWWX = 0x3E; | |
1643 static const int ZWWY = 0x7E; | |
1644 static const int ZWWZ = 0xBE; | |
1645 static const int ZWWW = 0xFE; | |
1646 static const int WXXX = 0x3; | |
1647 static const int WXXY = 0x43; | |
1648 static const int WXXZ = 0x83; | |
1649 static const int WXXW = 0xC3; | |
1650 static const int WXYX = 0x13; | |
1651 static const int WXYY = 0x53; | |
1652 static const int WXYZ = 0x93; | |
1653 static const int WXYW = 0xD3; | |
1654 static const int WXZX = 0x23; | |
1655 static const int WXZY = 0x63; | |
1656 static const int WXZZ = 0xA3; | |
1657 static const int WXZW = 0xE3; | |
1658 static const int WXWX = 0x33; | |
1659 static const int WXWY = 0x73; | |
1660 static const int WXWZ = 0xB3; | |
1661 static const int WXWW = 0xF3; | |
1662 static const int WYXX = 0x7; | |
1663 static const int WYXY = 0x47; | |
1664 static const int WYXZ = 0x87; | |
1665 static const int WYXW = 0xC7; | |
1666 static const int WYYX = 0x17; | |
1667 static const int WYYY = 0x57; | |
1668 static const int WYYZ = 0x97; | |
1669 static const int WYYW = 0xD7; | |
1670 static const int WYZX = 0x27; | |
1671 static const int WYZY = 0x67; | |
1672 static const int WYZZ = 0xA7; | |
1673 static const int WYZW = 0xE7; | |
1674 static const int WYWX = 0x37; | |
1675 static const int WYWY = 0x77; | |
1676 static const int WYWZ = 0xB7; | |
1677 static const int WYWW = 0xF7; | |
1678 static const int WZXX = 0xB; | |
1679 static const int WZXY = 0x4B; | |
1680 static const int WZXZ = 0x8B; | |
1681 static const int WZXW = 0xCB; | |
1682 static const int WZYX = 0x1B; | |
1683 static const int WZYY = 0x5B; | |
1684 static const int WZYZ = 0x9B; | |
1685 static const int WZYW = 0xDB; | |
1686 static const int WZZX = 0x2B; | |
1687 static const int WZZY = 0x6B; | |
1688 static const int WZZZ = 0xAB; | |
1689 static const int WZZW = 0xEB; | |
1690 static const int WZWX = 0x3B; | |
1691 static const int WZWY = 0x7B; | |
1692 static const int WZWZ = 0xBB; | |
1693 static const int WZWW = 0xFB; | |
1694 static const int WWXX = 0xF; | |
1695 static const int WWXY = 0x4F; | |
1696 static const int WWXZ = 0x8F; | |
1697 static const int WWXW = 0xCF; | |
1698 static const int WWYX = 0x1F; | |
1699 static const int WWYY = 0x5F; | |
1700 static const int WWYZ = 0x9F; | |
1701 static const int WWYW = 0xDF; | |
1702 static const int WWZX = 0x2F; | |
1703 static const int WWZY = 0x6F; | |
1704 static const int WWZZ = 0xAF; | |
1705 static const int WWZW = 0xEF; | |
1706 static const int WWWX = 0x3F; | |
1707 static const int WWWY = 0x7F; | |
1708 static const int WWWZ = 0xBF; | |
1709 static const int WWWW = 0xFF; | |
1710 | |
1711 /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. | |
1712 Float32x4 shuffle(int m) { | |
1713 if ((m < 0) || (m > 255)) { | |
1714 throw new RangeError('mask $m must be in the range [0..256)'); | |
1715 } | |
1716 double _x = _storage[m & 0x3]; | |
1717 double _y = _storage[(m >> 2) & 0x3]; | |
1718 double _z = _storage[(m >> 4) & 0x3]; | |
1719 double _w = _storage[(m >> 6) & 0x3]; | |
1720 return new Float32x4(_x, _y, _z, _w); | |
1721 } | |
1722 | |
1723 /// Shuffle the lane values in [this] and [other]. The returned | |
1724 /// Float32x4 will have XY lanes from [this] and ZW lanes from [other]. | |
1725 /// Uses the same [mask] as [shuffle]. | |
1726 Float32x4 shuffleMix(Float32x4 other, int m) { | |
1727 if ((m < 0) || (m > 255)) { | |
1728 throw new RangeError('mask $m must be in the range [0..256)'); | |
1729 } | |
1730 double _x = _storage[m & 0x3]; | |
1731 double _y = _storage[(m >> 2) & 0x3]; | |
1732 double _z = other._storage[(m >> 4) & 0x3]; | |
1733 double _w = other._storage[(m >> 6) & 0x3]; | |
1734 return new Float32x4(_x, _y, _z, _w); | |
1735 } | |
1736 | |
1737 /// Copy [this] and replace the [x] lane. | |
1738 Float32x4 withX(double x) { | |
1739 double _x = x; | |
1740 double _y = _storage[1]; | |
1741 double _z = _storage[2]; | |
1742 double _w = _storage[3]; | |
1743 return new Float32x4(_x, _y, _z, _w); | |
1744 } | |
1745 | |
1746 /// Copy [this] and replace the [y] lane. | |
1747 Float32x4 withY(double y) { | |
1748 double _x = _storage[0]; | |
1749 double _y = y; | |
1750 double _z = _storage[2]; | |
1751 double _w = _storage[3]; | |
1752 return new Float32x4(_x, _y, _z, _w); | |
1753 } | |
1754 | |
1755 /// Copy [this] and replace the [z] lane. | |
1756 Float32x4 withZ(double z) { | |
1757 double _x = _storage[0]; | |
1758 double _y = _storage[1]; | |
1759 double _z = z; | |
1760 double _w = _storage[3]; | |
1761 return new Float32x4(_x, _y, _z, _w); | |
1762 } | |
1763 | |
1764 /// Copy [this] and replace the [w] lane. | |
1765 Float32x4 withW(double w) { | |
1766 double _x = _storage[0]; | |
1767 double _y = _storage[1]; | |
1768 double _z = _storage[2]; | |
1769 double _w = w; | |
1770 return new Float32x4(_x, _y, _z, _w); | |
1771 } | |
1772 | |
1773 /// Returns the lane-wise minimum value in [this] or [other]. | |
1774 Float32x4 min(Float32x4 other) { | |
1775 double _x = _storage[0] < other._storage[0] ? | |
1776 _storage[0] : other._storage[0]; | |
1777 double _y = _storage[1] < other._storage[1] ? | |
1778 _storage[1] : other._storage[1]; | |
1779 double _z = _storage[2] < other._storage[2] ? | |
1780 _storage[2] : other._storage[2]; | |
1781 double _w = _storage[3] < other._storage[3] ? | |
1782 _storage[3] : other._storage[3]; | |
1783 return new Float32x4(_x, _y, _z, _w); | |
1784 } | |
1785 | |
1786 /// Returns the lane-wise maximum value in [this] or [other]. | |
1787 Float32x4 max(Float32x4 other) { | |
1788 double _x = _storage[0] > other._storage[0] ? | |
1789 _storage[0] : other._storage[0]; | |
1790 double _y = _storage[1] > other._storage[1] ? | |
1791 _storage[1] : other._storage[1]; | |
1792 double _z = _storage[2] > other._storage[2] ? | |
1793 _storage[2] : other._storage[2]; | |
1794 double _w = _storage[3] > other._storage[3] ? | |
1795 _storage[3] : other._storage[3]; | |
1796 return new Float32x4(_x, _y, _z, _w); | |
1797 } | |
1798 | |
1799 /// Returns the square root of [this]. | |
1800 Float32x4 sqrt() { | |
1801 double _x = Math.sqrt(_storage[0]); | |
1802 double _y = Math.sqrt(_storage[1]); | |
1803 double _z = Math.sqrt(_storage[2]); | |
1804 double _w = Math.sqrt(_storage[3]); | |
1805 return new Float32x4(_x, _y, _z, _w); | |
1806 } | |
1807 | |
1808 /// Returns the reciprocal of [this]. | |
1809 Float32x4 reciprocal() { | |
1810 double _x = 1.0 / _storage[0]; | |
1811 double _y = 1.0 / _storage[1]; | |
1812 double _z = 1.0 / _storage[2]; | |
1813 double _w = 1.0 / _storage[3]; | |
1814 return new Float32x4(_x, _y, _z, _w); | |
1815 } | |
1816 | |
1817 /// Returns the square root of the reciprocal of [this]. | |
1818 Float32x4 reciprocalSqrt() { | |
1819 double _x = Math.sqrt(1.0 / _storage[0]); | |
1820 double _y = Math.sqrt(1.0 / _storage[1]); | |
1821 double _z = Math.sqrt(1.0 / _storage[2]); | |
1822 double _w = Math.sqrt(1.0 / _storage[3]); | |
1823 return new Float32x4(_x, _y, _z, _w); | |
1824 } | |
1825 } | |
1826 | |
1827 | |
1828 /** | |
1829 * Interface of Dart Int32x4 and operations. | |
1830 * Int32x4 stores 4 32-bit bit-masks in "lanes". | |
1831 * The lanes are "x", "y", "z", and "w" respectively. | |
1832 */ | |
1833 class Int32x4 { | |
1834 final _storage = new Int32List(4); | |
1835 | |
1836 Int32x4(int x, int y, int z, int w) { | |
1837 _storage[0] = x; | |
1838 _storage[1] = y; | |
1839 _storage[2] = z; | |
1840 _storage[3] = w; | |
1841 } | |
1842 | |
1843 Int32x4.bool(bool x, bool y, bool z, bool w) { | |
1844 _storage[0] = x == true ? 0xFFFFFFFF : 0x0; | |
1845 _storage[1] = y == true ? 0xFFFFFFFF : 0x0; | |
1846 _storage[2] = z == true ? 0xFFFFFFFF : 0x0; | |
1847 _storage[3] = w == true ? 0xFFFFFFFF : 0x0; | |
1848 } | |
1849 | |
1850 /// Returns a bit-wise copy of [x] as a Int32x4. | |
1851 Int32x4.fromFloat32x4Bits(Float32x4 x) { | |
1852 var view = new Uint32List.view(x._storage.buffer); | |
1853 _storage[0] = view[0]; | |
1854 _storage[1] = view[1]; | |
1855 _storage[2] = view[2]; | |
1856 _storage[3] = view[3]; | |
1857 } | |
1858 | |
1859 String toString() { | |
1860 return '[${_storage[0]}, ${_storage[1]}, ${_storage[2]}, ${_storage[3]}]'; | |
1861 } | |
1862 | |
1863 /// The bit-wise or operator. | |
1864 Int32x4 operator|(Int32x4 other) { | |
1865 int _x = _storage[0] | other._storage[0]; | |
1866 int _y = _storage[1] | other._storage[1]; | |
1867 int _z = _storage[2] | other._storage[2]; | |
1868 int _w = _storage[3] | other._storage[3]; | |
1869 return new Int32x4(_x, _y, _z, _w); | |
1870 } | |
1871 | |
1872 /// The bit-wise and operator. | |
1873 Int32x4 operator&(Int32x4 other) { | |
1874 int _x = _storage[0] & other._storage[0]; | |
1875 int _y = _storage[1] & other._storage[1]; | |
1876 int _z = _storage[2] & other._storage[2]; | |
1877 int _w = _storage[3] & other._storage[3]; | |
1878 return new Int32x4(_x, _y, _z, _w); | |
1879 } | |
1880 | |
1881 /// The bit-wise xor operator. | |
1882 Int32x4 operator^(Int32x4 other) { | |
1883 int _x = _storage[0] ^ other._storage[0]; | |
1884 int _y = _storage[1] ^ other._storage[1]; | |
1885 int _z = _storage[2] ^ other._storage[2]; | |
1886 int _w = _storage[3] ^ other._storage[3]; | |
1887 return new Int32x4(_x, _y, _z, _w); | |
1888 } | |
1889 | |
1890 Int32x4 operator+(Int32x4 other) { | |
1891 var r = new Int32x4(0, 0, 0, 0); | |
1892 r._storage[0] = (_storage[0] + other._storage[0]); | |
1893 r._storage[1] = (_storage[1] + other._storage[1]); | |
1894 r._storage[2] = (_storage[2] + other._storage[2]); | |
1895 r._storage[3] = (_storage[3] + other._storage[3]); | |
1896 return r; | |
1897 } | |
1898 | |
1899 Int32x4 operator-(Int32x4 other) { | |
1900 var r = new Int32x4(0, 0, 0, 0); | |
1901 r._storage[0] = (_storage[0] - other._storage[0]); | |
1902 r._storage[1] = (_storage[1] - other._storage[1]); | |
1903 r._storage[2] = (_storage[2] - other._storage[2]); | |
1904 r._storage[3] = (_storage[3] - other._storage[3]); | |
1905 return r; | |
1906 } | |
1907 | |
1908 /// Extract 32-bit mask from x lane. | |
1909 int get x => _storage[0]; | |
1910 /// Extract 32-bit mask from y lane. | |
1911 int get y => _storage[1]; | |
1912 /// Extract 32-bit mask from z lane. | |
1913 int get z => _storage[2]; | |
1914 /// Extract 32-bit mask from w lane. | |
1915 int get w => _storage[3]; | |
1916 | |
1917 /// Extract the top bit from each lane return them in the first 4 bits. | |
1918 int get signMask { | |
1919 int mx = (_storage[0] & 0x80000000) >> 31; | |
1920 int my = (_storage[1] & 0x80000000) >> 31; | |
1921 int mz = (_storage[2] & 0x80000000) >> 31; | |
1922 int mw = (_storage[3] & 0x80000000) >> 31; | |
1923 return mx | my << 1 | mz << 2 | mw << 3; | |
1924 } | |
1925 | |
1926 /// Mask passed to [shuffle] and [shuffleMix]. | |
1927 static const int XXXX = 0x0; | |
1928 static const int XXXY = 0x40; | |
1929 static const int XXXZ = 0x80; | |
1930 static const int XXXW = 0xC0; | |
1931 static const int XXYX = 0x10; | |
1932 static const int XXYY = 0x50; | |
1933 static const int XXYZ = 0x90; | |
1934 static const int XXYW = 0xD0; | |
1935 static const int XXZX = 0x20; | |
1936 static const int XXZY = 0x60; | |
1937 static const int XXZZ = 0xA0; | |
1938 static const int XXZW = 0xE0; | |
1939 static const int XXWX = 0x30; | |
1940 static const int XXWY = 0x70; | |
1941 static const int XXWZ = 0xB0; | |
1942 static const int XXWW = 0xF0; | |
1943 static const int XYXX = 0x4; | |
1944 static const int XYXY = 0x44; | |
1945 static const int XYXZ = 0x84; | |
1946 static const int XYXW = 0xC4; | |
1947 static const int XYYX = 0x14; | |
1948 static const int XYYY = 0x54; | |
1949 static const int XYYZ = 0x94; | |
1950 static const int XYYW = 0xD4; | |
1951 static const int XYZX = 0x24; | |
1952 static const int XYZY = 0x64; | |
1953 static const int XYZZ = 0xA4; | |
1954 static const int XYZW = 0xE4; | |
1955 static const int XYWX = 0x34; | |
1956 static const int XYWY = 0x74; | |
1957 static const int XYWZ = 0xB4; | |
1958 static const int XYWW = 0xF4; | |
1959 static const int XZXX = 0x8; | |
1960 static const int XZXY = 0x48; | |
1961 static const int XZXZ = 0x88; | |
1962 static const int XZXW = 0xC8; | |
1963 static const int XZYX = 0x18; | |
1964 static const int XZYY = 0x58; | |
1965 static const int XZYZ = 0x98; | |
1966 static const int XZYW = 0xD8; | |
1967 static const int XZZX = 0x28; | |
1968 static const int XZZY = 0x68; | |
1969 static const int XZZZ = 0xA8; | |
1970 static const int XZZW = 0xE8; | |
1971 static const int XZWX = 0x38; | |
1972 static const int XZWY = 0x78; | |
1973 static const int XZWZ = 0xB8; | |
1974 static const int XZWW = 0xF8; | |
1975 static const int XWXX = 0xC; | |
1976 static const int XWXY = 0x4C; | |
1977 static const int XWXZ = 0x8C; | |
1978 static const int XWXW = 0xCC; | |
1979 static const int XWYX = 0x1C; | |
1980 static const int XWYY = 0x5C; | |
1981 static const int XWYZ = 0x9C; | |
1982 static const int XWYW = 0xDC; | |
1983 static const int XWZX = 0x2C; | |
1984 static const int XWZY = 0x6C; | |
1985 static const int XWZZ = 0xAC; | |
1986 static const int XWZW = 0xEC; | |
1987 static const int XWWX = 0x3C; | |
1988 static const int XWWY = 0x7C; | |
1989 static const int XWWZ = 0xBC; | |
1990 static const int XWWW = 0xFC; | |
1991 static const int YXXX = 0x1; | |
1992 static const int YXXY = 0x41; | |
1993 static const int YXXZ = 0x81; | |
1994 static const int YXXW = 0xC1; | |
1995 static const int YXYX = 0x11; | |
1996 static const int YXYY = 0x51; | |
1997 static const int YXYZ = 0x91; | |
1998 static const int YXYW = 0xD1; | |
1999 static const int YXZX = 0x21; | |
2000 static const int YXZY = 0x61; | |
2001 static const int YXZZ = 0xA1; | |
2002 static const int YXZW = 0xE1; | |
2003 static const int YXWX = 0x31; | |
2004 static const int YXWY = 0x71; | |
2005 static const int YXWZ = 0xB1; | |
2006 static const int YXWW = 0xF1; | |
2007 static const int YYXX = 0x5; | |
2008 static const int YYXY = 0x45; | |
2009 static const int YYXZ = 0x85; | |
2010 static const int YYXW = 0xC5; | |
2011 static const int YYYX = 0x15; | |
2012 static const int YYYY = 0x55; | |
2013 static const int YYYZ = 0x95; | |
2014 static const int YYYW = 0xD5; | |
2015 static const int YYZX = 0x25; | |
2016 static const int YYZY = 0x65; | |
2017 static const int YYZZ = 0xA5; | |
2018 static const int YYZW = 0xE5; | |
2019 static const int YYWX = 0x35; | |
2020 static const int YYWY = 0x75; | |
2021 static const int YYWZ = 0xB5; | |
2022 static const int YYWW = 0xF5; | |
2023 static const int YZXX = 0x9; | |
2024 static const int YZXY = 0x49; | |
2025 static const int YZXZ = 0x89; | |
2026 static const int YZXW = 0xC9; | |
2027 static const int YZYX = 0x19; | |
2028 static const int YZYY = 0x59; | |
2029 static const int YZYZ = 0x99; | |
2030 static const int YZYW = 0xD9; | |
2031 static const int YZZX = 0x29; | |
2032 static const int YZZY = 0x69; | |
2033 static const int YZZZ = 0xA9; | |
2034 static const int YZZW = 0xE9; | |
2035 static const int YZWX = 0x39; | |
2036 static const int YZWY = 0x79; | |
2037 static const int YZWZ = 0xB9; | |
2038 static const int YZWW = 0xF9; | |
2039 static const int YWXX = 0xD; | |
2040 static const int YWXY = 0x4D; | |
2041 static const int YWXZ = 0x8D; | |
2042 static const int YWXW = 0xCD; | |
2043 static const int YWYX = 0x1D; | |
2044 static const int YWYY = 0x5D; | |
2045 static const int YWYZ = 0x9D; | |
2046 static const int YWYW = 0xDD; | |
2047 static const int YWZX = 0x2D; | |
2048 static const int YWZY = 0x6D; | |
2049 static const int YWZZ = 0xAD; | |
2050 static const int YWZW = 0xED; | |
2051 static const int YWWX = 0x3D; | |
2052 static const int YWWY = 0x7D; | |
2053 static const int YWWZ = 0xBD; | |
2054 static const int YWWW = 0xFD; | |
2055 static const int ZXXX = 0x2; | |
2056 static const int ZXXY = 0x42; | |
2057 static const int ZXXZ = 0x82; | |
2058 static const int ZXXW = 0xC2; | |
2059 static const int ZXYX = 0x12; | |
2060 static const int ZXYY = 0x52; | |
2061 static const int ZXYZ = 0x92; | |
2062 static const int ZXYW = 0xD2; | |
2063 static const int ZXZX = 0x22; | |
2064 static const int ZXZY = 0x62; | |
2065 static const int ZXZZ = 0xA2; | |
2066 static const int ZXZW = 0xE2; | |
2067 static const int ZXWX = 0x32; | |
2068 static const int ZXWY = 0x72; | |
2069 static const int ZXWZ = 0xB2; | |
2070 static const int ZXWW = 0xF2; | |
2071 static const int ZYXX = 0x6; | |
2072 static const int ZYXY = 0x46; | |
2073 static const int ZYXZ = 0x86; | |
2074 static const int ZYXW = 0xC6; | |
2075 static const int ZYYX = 0x16; | |
2076 static const int ZYYY = 0x56; | |
2077 static const int ZYYZ = 0x96; | |
2078 static const int ZYYW = 0xD6; | |
2079 static const int ZYZX = 0x26; | |
2080 static const int ZYZY = 0x66; | |
2081 static const int ZYZZ = 0xA6; | |
2082 static const int ZYZW = 0xE6; | |
2083 static const int ZYWX = 0x36; | |
2084 static const int ZYWY = 0x76; | |
2085 static const int ZYWZ = 0xB6; | |
2086 static const int ZYWW = 0xF6; | |
2087 static const int ZZXX = 0xA; | |
2088 static const int ZZXY = 0x4A; | |
2089 static const int ZZXZ = 0x8A; | |
2090 static const int ZZXW = 0xCA; | |
2091 static const int ZZYX = 0x1A; | |
2092 static const int ZZYY = 0x5A; | |
2093 static const int ZZYZ = 0x9A; | |
2094 static const int ZZYW = 0xDA; | |
2095 static const int ZZZX = 0x2A; | |
2096 static const int ZZZY = 0x6A; | |
2097 static const int ZZZZ = 0xAA; | |
2098 static const int ZZZW = 0xEA; | |
2099 static const int ZZWX = 0x3A; | |
2100 static const int ZZWY = 0x7A; | |
2101 static const int ZZWZ = 0xBA; | |
2102 static const int ZZWW = 0xFA; | |
2103 static const int ZWXX = 0xE; | |
2104 static const int ZWXY = 0x4E; | |
2105 static const int ZWXZ = 0x8E; | |
2106 static const int ZWXW = 0xCE; | |
2107 static const int ZWYX = 0x1E; | |
2108 static const int ZWYY = 0x5E; | |
2109 static const int ZWYZ = 0x9E; | |
2110 static const int ZWYW = 0xDE; | |
2111 static const int ZWZX = 0x2E; | |
2112 static const int ZWZY = 0x6E; | |
2113 static const int ZWZZ = 0xAE; | |
2114 static const int ZWZW = 0xEE; | |
2115 static const int ZWWX = 0x3E; | |
2116 static const int ZWWY = 0x7E; | |
2117 static const int ZWWZ = 0xBE; | |
2118 static const int ZWWW = 0xFE; | |
2119 static const int WXXX = 0x3; | |
2120 static const int WXXY = 0x43; | |
2121 static const int WXXZ = 0x83; | |
2122 static const int WXXW = 0xC3; | |
2123 static const int WXYX = 0x13; | |
2124 static const int WXYY = 0x53; | |
2125 static const int WXYZ = 0x93; | |
2126 static const int WXYW = 0xD3; | |
2127 static const int WXZX = 0x23; | |
2128 static const int WXZY = 0x63; | |
2129 static const int WXZZ = 0xA3; | |
2130 static const int WXZW = 0xE3; | |
2131 static const int WXWX = 0x33; | |
2132 static const int WXWY = 0x73; | |
2133 static const int WXWZ = 0xB3; | |
2134 static const int WXWW = 0xF3; | |
2135 static const int WYXX = 0x7; | |
2136 static const int WYXY = 0x47; | |
2137 static const int WYXZ = 0x87; | |
2138 static const int WYXW = 0xC7; | |
2139 static const int WYYX = 0x17; | |
2140 static const int WYYY = 0x57; | |
2141 static const int WYYZ = 0x97; | |
2142 static const int WYYW = 0xD7; | |
2143 static const int WYZX = 0x27; | |
2144 static const int WYZY = 0x67; | |
2145 static const int WYZZ = 0xA7; | |
2146 static const int WYZW = 0xE7; | |
2147 static const int WYWX = 0x37; | |
2148 static const int WYWY = 0x77; | |
2149 static const int WYWZ = 0xB7; | |
2150 static const int WYWW = 0xF7; | |
2151 static const int WZXX = 0xB; | |
2152 static const int WZXY = 0x4B; | |
2153 static const int WZXZ = 0x8B; | |
2154 static const int WZXW = 0xCB; | |
2155 static const int WZYX = 0x1B; | |
2156 static const int WZYY = 0x5B; | |
2157 static const int WZYZ = 0x9B; | |
2158 static const int WZYW = 0xDB; | |
2159 static const int WZZX = 0x2B; | |
2160 static const int WZZY = 0x6B; | |
2161 static const int WZZZ = 0xAB; | |
2162 static const int WZZW = 0xEB; | |
2163 static const int WZWX = 0x3B; | |
2164 static const int WZWY = 0x7B; | |
2165 static const int WZWZ = 0xBB; | |
2166 static const int WZWW = 0xFB; | |
2167 static const int WWXX = 0xF; | |
2168 static const int WWXY = 0x4F; | |
2169 static const int WWXZ = 0x8F; | |
2170 static const int WWXW = 0xCF; | |
2171 static const int WWYX = 0x1F; | |
2172 static const int WWYY = 0x5F; | |
2173 static const int WWYZ = 0x9F; | |
2174 static const int WWYW = 0xDF; | |
2175 static const int WWZX = 0x2F; | |
2176 static const int WWZY = 0x6F; | |
2177 static const int WWZZ = 0xAF; | |
2178 static const int WWZW = 0xEF; | |
2179 static const int WWWX = 0x3F; | |
2180 static const int WWWY = 0x7F; | |
2181 static const int WWWZ = 0xBF; | |
2182 static const int WWWW = 0xFF; | |
2183 | |
2184 /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants. | |
2185 Int32x4 shuffle(int mask) { | |
2186 if ((mask < 0) || (mask > 255)) { | |
2187 throw new RangeError('mask $mask must be in the range [0..256)'); | |
2188 } | |
2189 int _x = _storage[mask & 0x3]; | |
2190 int _y = _storage[(mask >> 2) & 0x3]; | |
2191 int _z = _storage[(mask >> 4) & 0x3]; | |
2192 int _w = _storage[(mask >> 6) & 0x3]; | |
2193 return new Int32x4(_x, _y, _z, _w); | |
2194 } | |
2195 | |
2196 /// Shuffle the lane values in [this] and [other]. The returned | |
2197 /// Int32x4 will have XY lanes from [this] and ZW lanes from [other]. | |
2198 /// Uses the same [mask] as [shuffle]. | |
2199 Int32x4 shuffleMix(Int32x4 other, int mask) { | |
2200 if ((mask < 0) || (mask > 255)) { | |
2201 throw new RangeError('mask $mask must be in the range [0..256)'); | |
2202 } | |
2203 int _x = _storage[mask & 0x3]; | |
2204 int _y = _storage[(mask >> 2) & 0x3]; | |
2205 int _z = other._storage[(mask >> 4) & 0x3]; | |
2206 int _w = other._storage[(mask >> 6) & 0x3]; | |
2207 return new Int32x4(_x, _y, _z, _w); | |
2208 } | |
2209 | |
2210 /// Returns a new [Int32x4] copied from [this] with a new x value. | |
2211 Int32x4 withX(int x) { | |
2212 int _x = x; | |
2213 int _y = _storage[1]; | |
2214 int _z = _storage[2]; | |
2215 int _w = _storage[3]; | |
2216 return new Int32x4(_x, _y, _z, _w); | |
2217 } | |
2218 | |
2219 /// Returns a new [Int32x4] copied from [this] with a new y value. | |
2220 Int32x4 withY(int y) { | |
2221 int _x = _storage[0]; | |
2222 int _y = y; | |
2223 int _z = _storage[2]; | |
2224 int _w = _storage[3]; | |
2225 return new Int32x4(_x, _y, _z, _w); | |
2226 } | |
2227 | |
2228 /// Returns a new [Int32x4] copied from [this] with a new z value. | |
2229 Int32x4 withZ(int z) { | |
2230 int _x = _storage[0]; | |
2231 int _y = _storage[1]; | |
2232 int _z = z; | |
2233 int _w = _storage[3]; | |
2234 return new Int32x4(_x, _y, _z, _w); | |
2235 } | |
2236 | |
2237 /// Returns a new [Int32x4] copied from [this] with a new w value. | |
2238 Int32x4 withW(int w) { | |
2239 int _x = _storage[0]; | |
2240 int _y = _storage[1]; | |
2241 int _z = _storage[2]; | |
2242 int _w = w; | |
2243 return new Int32x4(_x, _y, _z, _w); | |
2244 } | |
2245 | |
2246 /// Extracted x value. Returns false for 0, true for any other value. | |
2247 bool get flagX => _storage[0] != 0x0; | |
2248 /// Extracted y value. Returns false for 0, true for any other value. | |
2249 bool get flagY => _storage[1] != 0x0; | |
2250 /// Extracted z value. Returns false for 0, true for any other value. | |
2251 bool get flagZ => _storage[2] != 0x0; | |
2252 /// Extracted w value. Returns false for 0, true for any other value. | |
2253 bool get flagW => _storage[3] != 0x0; | |
2254 | |
2255 /// Returns a new [Int32x4] copied from [this] with a new x value. | |
2256 Int32x4 withFlagX(bool x) { | |
2257 int _x = x == true ? 0xFFFFFFFF : 0x0; | |
2258 int _y = _storage[1]; | |
2259 int _z = _storage[2]; | |
2260 int _w = _storage[3]; | |
2261 return new Int32x4(_x, _y, _z, _w); | |
2262 } | |
2263 | |
2264 /// Returns a new [Int32x4] copied from [this] with a new y value. | |
2265 Int32x4 withFlagY(bool y) { | |
2266 int _x = _storage[0]; | |
2267 int _y = y == true ? 0xFFFFFFFF : 0x0; | |
2268 int _z = _storage[2]; | |
2269 int _w = _storage[3]; | |
2270 return new Int32x4(_x, _y, _z, _w); | |
2271 } | |
2272 | |
2273 /// Returns a new [Int32x4] copied from [this] with a new z value. | |
2274 Int32x4 withFlagZ(bool z) { | |
2275 int _x = _storage[0]; | |
2276 int _y = _storage[1]; | |
2277 int _z = z == true ? 0xFFFFFFFF : 0x0; | |
2278 int _w = _storage[3]; | |
2279 return new Int32x4(_x, _y, _z, _w); | |
2280 } | |
2281 | |
2282 /// Returns a new [Int32x4] copied from [this] with a new w value. | |
2283 Int32x4 withFlagW(bool w) { | |
2284 int _x = _storage[0]; | |
2285 int _y = _storage[1]; | |
2286 int _z = _storage[2]; | |
2287 int _w = w == true ? 0xFFFFFFFF : 0x0; | |
2288 return new Int32x4(_x, _y, _z, _w); | |
2289 } | |
2290 | |
2291 /// Merge [trueValue] and [falseValue] based on [this]' bit mask: | |
2292 /// Select bit from [trueValue] when bit in [this] is on. | |
2293 /// Select bit from [falseValue] when bit in [this] is off. | |
2294 Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) { | |
2295 var trueView = new Int32List.view(trueValue._storage.buffer); | |
2296 var falseView = new Int32List.view(falseValue._storage.buffer); | |
2297 int cmx = _storage[0]; | |
2298 int cmy = _storage[1]; | |
2299 int cmz = _storage[2]; | |
2300 int cmw = _storage[3]; | |
2301 int stx = trueView[0]; | |
2302 int sty = trueView[1]; | |
2303 int stz = trueView[2]; | |
2304 int stw = trueView[3]; | |
2305 int sfx = falseView[0]; | |
2306 int sfy = falseView[1]; | |
2307 int sfz = falseView[2]; | |
2308 int sfw = falseView[3]; | |
2309 int _x = (cmx & stx) | (~cmx & sfx); | |
2310 int _y = (cmy & sty) | (~cmy & sfy); | |
2311 int _z = (cmz & stz) | (~cmz & sfz); | |
2312 int _w = (cmw & stw) | (~cmw & sfw); | |
2313 var r = new Float32x4(0.0, 0.0, 0.0, 0.0); | |
2314 var rView = new Int32List.view(r._storage.buffer); | |
2315 rView[0] = _x; | |
2316 rView[1] = _y; | |
2317 rView[2] = _z; | |
2318 rView[3] = _w; | |
2319 return r; | |
2320 } | |
2321 } | |
2322 | |
2323 class Float64x2 { | |
2324 final _storage = new Float64List(2); | |
2325 | |
2326 Float64x2(double x, double y) { | |
2327 _storage[0] = x; | |
2328 _storage[1] = y; | |
2329 } | |
2330 | |
2331 Float64x2.splat(double v) { | |
2332 _storage[0] = v; | |
2333 _storage[1] = v; | |
2334 } | |
2335 | |
2336 Float64x2.zero(); | |
2337 | |
2338 Float64x2.fromFloat32x4(Float32x4 v) { | |
2339 _storage[0] = v._storage[0]; | |
2340 _storage[1] = v._storage[1]; | |
2341 } | |
2342 | |
2343 String toString() { | |
2344 return '[${_storage[0]}, ${_storage[1]}]'; | |
2345 } | |
2346 | |
2347 /// Addition operator. | |
2348 Float64x2 operator+(Float64x2 other) { | |
2349 return new Float64x2(_storage[0] + other._storage[0], | |
2350 _storage[1] + other._storage[1]); | |
2351 } | |
2352 | |
2353 /// Negate operator. | |
2354 Float64x2 operator-() { | |
2355 return new Float64x2(-_storage[0], -_storage[1]); | |
2356 } | |
2357 | |
2358 /// Subtraction operator. | |
2359 Float64x2 operator-(Float64x2 other) { | |
2360 return new Float64x2(_storage[0] - other._storage[0], | |
2361 _storage[1] - other._storage[1]); | |
2362 } | |
2363 /// Multiplication operator. | |
2364 Float64x2 operator*(Float64x2 other) { | |
2365 return new Float64x2(_storage[0] * other._storage[0], | |
2366 _storage[1] * other._storage[1]); | |
2367 } | |
2368 /// Division operator. | |
2369 Float64x2 operator/(Float64x2 other) { | |
2370 return new Float64x2(_storage[0] / other._storage[0], | |
2371 _storage[1] / other._storage[1]); | |
2372 } | |
2373 | |
2374 /// Returns a copy of [this] each lane being scaled by [s]. | |
2375 Float64x2 scale(double s) { | |
2376 return new Float64x2(_storage[0] * s, _storage[1] * s); | |
2377 } | |
2378 | |
2379 /// Returns the absolute value of this [Float64x2]. | |
2380 Float64x2 abs() { | |
2381 return new Float64x2(_storage[0].abs(), _storage[1].abs()); | |
2382 } | |
2383 | |
2384 /// Clamps [this] to be in the range [lowerLimit]-[upperLimit]. | |
2385 Float64x2 clamp(Float64x2 lowerLimit, | |
2386 Float64x2 upperLimit) { | |
2387 double _lx = lowerLimit._storage[0]; | |
2388 double _ly = lowerLimit._storage[1]; | |
2389 double _ux = upperLimit._storage[0]; | |
2390 double _uy = upperLimit._storage[1]; | |
2391 double _x = _storage[0]; | |
2392 double _y = _storage[1]; | |
2393 // MAX(MIN(self, upper), lower). | |
2394 _x = _x > _ux ? _ux : _x; | |
2395 _y = _y > _uy ? _uy : _y; | |
2396 _x = _x < _lx ? _lx : _x; | |
2397 _y = _y < _ly ? _ly : _y; | |
2398 return new Float64x2(_x, _y); | |
2399 } | |
2400 | |
2401 /// Extracted x value. | |
2402 double get x => _storage[0]; | |
2403 /// Extracted y value. | |
2404 double get y => _storage[1]; | |
2405 | |
2406 /// Extract the sign bits from each lane return them in the first 2 bits. | |
2407 int get signMask { | |
2408 var view = new Uint32List.view(_storage.buffer); | |
2409 var mx = (view[1] & 0x80000000) >> 31; | |
2410 var my = (view[3] & 0x80000000) >> 31; | |
2411 return mx | my << 1; | |
2412 } | |
2413 | |
2414 /// Returns a new [Float64x2] copied from [this] with a new x value. | |
2415 Float64x2 withX(double x) { | |
2416 return new Float64x2(x, _storage[1]); | |
2417 } | |
2418 | |
2419 /// Returns a new [Float64x2] copied from [this] with a new y value. | |
2420 Float64x2 withY(double y) { | |
2421 return new Float64x2(_storage[0], y); | |
2422 } | |
2423 | |
2424 /// Returns the lane-wise minimum value in [this] or [other]. | |
2425 Float64x2 min(Float64x2 other) { | |
2426 return new Float64x2( | |
2427 _storage[0] < other._storage[0] ? _storage[0] : other._storage[0], | |
2428 _storage[1] < other._storage[1] ? _storage[1] : other._storage[1]); | |
2429 | |
2430 } | |
2431 | |
2432 /// Returns the lane-wise maximum value in [this] or [other]. | |
2433 Float64x2 max(Float64x2 other) { | |
2434 return new Float64x2( | |
2435 _storage[0] > other._storage[0] ? _storage[0] : other._storage[0], | |
2436 _storage[1] > other._storage[1] ? _storage[1] : other._storage[1]); | |
2437 } | |
2438 | |
2439 /// Returns the lane-wise square root of [this]. | |
2440 Float64x2 sqrt() { | |
2441 return new Float64x2(Math.sqrt(_storage[0]), Math.sqrt(_storage[1])); | |
2442 } | |
2443 } | |
2444 | |
OLD | NEW |