Skip to content

Commit

Permalink
Add isTypedArray API
Browse files Browse the repository at this point in the history
  • Loading branch information
petamoriken committed Dec 18, 2021
1 parent 701db74 commit e65a777
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 57 deletions.
30 changes: 23 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ yarn add @petamoriken/float16
```js
// ES Modules
import {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} from "@petamoriken/float16";
Expand All @@ -62,7 +62,7 @@ import {
```js
// CommonJS
const {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} = require("@petamoriken/float16");
Expand All @@ -75,7 +75,7 @@ service.

```ts
import {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} from "https://deno.land/x/float16/mod.ts";
Expand All @@ -90,7 +90,7 @@ from your Web server with the JavaScript `Content-Type` HTTP header.
<!-- Module Scripts -->
<script type="module">
import {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} from "DEST/TO/float16.mjs";
Expand All @@ -102,7 +102,7 @@ from your Web server with the JavaScript `Content-Type` HTTP header.
<script src="DEST/TO/float16.js"></script>
<script>
const {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} = float16;
Expand All @@ -116,7 +116,7 @@ from your Web server with the JavaScript `Content-Type` HTTP header.
<!-- Module Scripts -->
<script type="module">
import {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} from "https://cdn.jsdelivr.net/npm/@petamoriken/float16/+esm";
Expand All @@ -128,7 +128,7 @@ from your Web server with the JavaScript `Content-Type` HTTP header.
<script src="https://cdn.jsdelivr.net/npm/@petamoriken/float16/browser/float16.min.js"></script>
<script>
const {
Float16Array, isFloat16Array,
Float16Array, isFloat16Array, isTypedArray,
getFloat16, setFloat16,
hfround,
} = float16;
Expand Down Expand Up @@ -190,6 +190,22 @@ isFloat16Array(new Float32Array(10)); // false
isFloat16Array(new Uint16Array(10)); // false
```

### `isTypedArray`

`isFloat16Array` is a utility function to check whether the value given as an
argument is an instance of a type of `TypedArray` or not.
Unlike `util.types.isTypedArray` in Node.js, this returns `true` for `Float16Array`.

```ts
declare function isTypedArray(value: unknown): value is Float16Array;
```

```js
isTypedArray(new Float16Array(10)); // true
isTypedArray(new Float32Array(10)); // true
isTypedArray(new Uint16Array(10)); // true
```

### `getFloat16`, `setFloat16`

`getFloat16` and `setFloat16` are similar to `DataView` methods such as
Expand Down
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,12 @@ export declare const Float16Array: Float16ArrayConstructor;
*/
export declare function isFloat16Array(value: unknown): value is Float16Array;

/**
* Returns `true` if the value is a type of TypedArray instance that contains Float16Array.
* @since v3.6.0
*/
export declare function isTypedArray(value: unknown): value is Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float16Array|Float32Array|Float64Array|BigUint64Array|BigInt64Array;

/**
* Gets the Float16 value at the specified byte offset from the start of the view. There is
* no alignment constraint; multi-byte values may be fetched from any offset.
Expand Down
53 changes: 11 additions & 42 deletions src/Float16Array.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { toSafe, wrapGenerator } from "./_util/arrayIterator.mjs";
import { brand, hasFloat16ArrayBrand } from "./_util/brand.mjs";
import { convertToNumber, roundToFloat16Bits } from "./_util/converter.mjs";
import {
isArrayBuffer,
isBigIntTypedArray,
isCanonicalIntegerIndexString,
isNativeBigIntTypedArray,
isNativeTypedArray,
isObject,
isObjectLike,
isOrdinaryArray,
isOrdinaryTypedArray,
isOrdinaryNativeTypedArray,
isSharedArrayBuffer,
isTypedArray,
} from "./_util/is.mjs";
import {
ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER,
Expand All @@ -20,7 +20,6 @@ import {
OFFSET_IS_OUT_OF_BOUNDS,
REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE,
SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT,
THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT,
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY,
THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT,
} from "./_util/messages.mjs";
Expand All @@ -47,14 +46,12 @@ import {
ReflectDefineProperty,
ReflectGet,
ReflectGetOwnPropertyDescriptor,
ReflectGetPrototypeOf,
ReflectHas,
ReflectOwnKeys,
ReflectSet,
ReflectSetPrototypeOf,
SetPrototypeAdd,
SetPrototypeHas,
SymbolFor,
SymbolIterator,
SymbolToStringTag,
TypedArray,
Expand Down Expand Up @@ -87,37 +84,9 @@ import {

const BYTES_PER_ELEMENT = 2;

const brand = SymbolFor("__Float16Array__");

/** @type {WeakMap<Float16Array, Uint16Array & { __float16bits: never }>} */
const float16bitsArrays = new NativeWeakMap();

/**
* @param {unknown} target
* @throws {TypeError}
* @returns {boolean}
*/
function hasFloat16ArrayBrand(target) {
if (!isObjectLike(target)) {
return false;
}

const prototype = ReflectGetPrototypeOf(target);
if (!isObjectLike(prototype)) {
return false;
}

const constructor = prototype.constructor;
if (constructor === undefined) {
return false;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}

return ReflectHas(constructor, brand);
}

/**
* @param {unknown} target
* @returns {target is Float16Array}
Expand Down Expand Up @@ -146,7 +115,7 @@ function assertFloat16Array(target) {
*/
function assertSpeciesTypedArray(target, count) {
const isTargetFloat16Array = isFloat16Array(target);
const isTargetTypedArray = isTypedArray(target);
const isTargetTypedArray = isNativeTypedArray(target);

if (!isTargetFloat16Array && !isTargetTypedArray) {
throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT);
Expand All @@ -168,7 +137,7 @@ function assertSpeciesTypedArray(target, count) {
}
}

if (isBigIntTypedArray(target)) {
if (isNativeBigIntTypedArray(target)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}
}
Expand Down Expand Up @@ -296,7 +265,7 @@ export class Float16Array {
/** @type {number} */
let length;

if (isTypedArray(input)) { // TypedArray
if (isNativeTypedArray(input)) { // TypedArray
list = input;
length = TypedArrayPrototypeGetLength(input);

Expand All @@ -312,7 +281,7 @@ export class Float16Array {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}

if (isBigIntTypedArray(input)) {
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}

Expand Down Expand Up @@ -425,7 +394,7 @@ export class Float16Array {
if (isOrdinaryArray(src)) {
list = src;
length = src.length;
} else if (isOrdinaryTypedArray(src)) {
} else if (isOrdinaryNativeTypedArray(src)) {
list = src;
length = TypedArrayPrototypeGetLength(src);
} else {
Expand Down Expand Up @@ -823,7 +792,7 @@ export class Float16Array {
);
}

if (isBigIntTypedArray(input)) {
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(
CANNOT_MIX_BIGINT_AND_OTHER_TYPES
);
Expand All @@ -839,7 +808,7 @@ export class Float16Array {
);
}

if (isTypedArray(input)) {
if (isNativeTypedArray(input)) {
const buffer = TypedArrayPrototypeGetBuffer(input);
if (IsDetachedBuffer(buffer)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
Expand Down
31 changes: 31 additions & 0 deletions src/_util/brand.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { isObject, isObjectLike } from "./is.mjs";
import { THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT } from "./messages.mjs";
import { NativeTypeError, ReflectGetPrototypeOf, ReflectHas, SymbolFor } from "./primordials.mjs";

export const brand = SymbolFor("__Float16Array__");

/**
* @param {unknown} target
* @throws {TypeError}
* @returns {boolean}
*/
export function hasFloat16ArrayBrand(target) {
if (!isObjectLike(target)) {
return false;
}

const prototype = ReflectGetPrototypeOf(target);
if (!isObjectLike(prototype)) {
return false;
}

const constructor = prototype.constructor;
if (constructor === undefined) {
return false;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}

return ReflectHas(constructor, brand);
}
8 changes: 4 additions & 4 deletions src/_util/is.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ export function isObjectLike(value) {
* @param {unknown} value
* @returns {value is TypedArray}
*/
export function isTypedArray(value) {
export function isNativeTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined;
}

/**
* @param {unknown} value
* @returns {value is BigInt64Array|BigUint64Array}
*/
export function isBigIntTypedArray(value) {
export function isNativeBigIntTypedArray(value) {
const typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value);
return typedArrayName === "BigInt64Array" ||
typedArrayName === "BigUint64Array";
Expand Down Expand Up @@ -104,8 +104,8 @@ export function isOrdinaryArray(value) {
* @param {unknown} value
* @returns {value is TypedArray}
*/
export function isOrdinaryTypedArray(value) {
if (!isTypedArray(value)) {
export function isOrdinaryNativeTypedArray(value) {
if (!isNativeTypedArray(value)) {
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* ignore unused exports */

export { hfround } from "./hfround.mjs";
export { Float16Array, isFloat16Array } from "./Float16Array.mjs";
export { isTypedArray } from "./isTypedArray.mjs";
export { getFloat16, setFloat16 } from "./DataView.mjs";
export { hfround } from "./hfround.mjs";
10 changes: 10 additions & 0 deletions src/isTypedArray.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { isFloat16Array } from "./Float16Array.mjs";
import { isNativeTypedArray } from "./_util/is.mjs";

/**
* @param {unknown} target
* @returns {value is Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float16Array|Float32Array|Float64Array|BigUint64Array|BigInt64Array}
*/
export function isTypedArray(target) {
return isNativeTypedArray(target) || isFloat16Array(target);
}
1 change: 1 addition & 0 deletions test/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<script src="Float16Array.js"></script>
<script src="DataView.js"></script>
<script src="hfround.js"></script>
<script src="isTypedArray.js"></script>

<script class="mocha-exec">
mocha.run();
Expand Down
1 change: 1 addition & 0 deletions test/browser/power.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<script src="Float16Array.power.js"></script>
<script src="DataView.power.js"></script>
<script src="hfround.power.js"></script>
<script src="isTypedArray.power.js"></script>

<script class="mocha-exec">
mocha.run();
Expand Down
Loading

0 comments on commit e65a777

Please sign in to comment.