Skip to content

Commit

Permalink
Added f16
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderOMara committed Nov 19, 2024
1 parent abf95c5 commit 20aac37
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
146 changes: 146 additions & 0 deletions member/f16.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { assertEquals } from '@std/assert';
import { getFloat16, setFloat16 } from '@hqtsm/dataview/f16';

import type { ArrayBufferReal } from '../type.ts';
import { byteLength, byteOffset, getType, littleEndian } from '../macro.ts';
import { Struct } from '../struct.ts';
import { memberF16 } from './f16.ts';

Deno.test('memberF16', () => {
const v = new DataView(new ArrayBuffer(4));
for (
const f64 of [
0,
1,
-1,
Math.PI,
-Math.PI,
Math.E,
-Math.E,
Number.EPSILON,
-Number.EPSILON,
Number.MAX_SAFE_INTEGER,
Number.MIN_SAFE_INTEGER,
Number.MAX_VALUE,
Number.MIN_VALUE,
Infinity,
-Infinity,
NaN,
]
) {
setFloat16(v, 0, f64, true);
const f16 = getFloat16(v, 0, true);

class Test extends Struct {
declare public readonly ['constructor']: typeof Test;

declare public alpha: number;

declare public beta: number;

declare public gamma: number;

public static override readonly BYTE_LENGTH: number = ((o) => {
o += memberF16(this, 'alpha', o, true);
o += memberF16(this, 'beta', o, false);
o += memberF16(this, 'gamma', o);
return o;
})(super.BYTE_LENGTH);
}

class TestM extends Test {
declare public readonly ['constructor']: typeof TestM;

constructor(
buffer: ArrayBufferReal,
byteOffset = 0,
littleEndian: boolean | null = null,
) {
super(buffer, byteOffset, littleEndian);
Object.defineProperty(this.dataView, 'getFloat16', {
value: function (
this: DataView,
offset: number,
littleEndian?: boolean,
): number {
return getFloat16(this, offset, littleEndian);
},
});
Object.defineProperty(this.dataView, 'setFloat16', {
value: function (
this: DataView,
offset: number,
value: number,
littleEndian?: boolean,
): void {
setFloat16(this, offset, value, littleEndian);
},
});
}
}

class TestF extends Test {
declare public readonly ['constructor']: typeof TestF;

constructor(
buffer: ArrayBufferReal,
byteOffset = 0,
littleEndian: boolean | null = null,
) {
super(buffer, byteOffset, littleEndian);
Object.defineProperty(this.dataView, 'getFloat16', {
value: null,
});
Object.defineProperty(this.dataView, 'setFloat16', {
value: null,
});
}
}

const off = {
alpha: byteOffset(Test, 'alpha'),
beta: byteOffset(Test, 'beta'),
gamma: byteOffset(Test, 'gamma'),
};

assertEquals(Test.BYTE_LENGTH, 6);
assertEquals(byteLength(Test, 'alpha'), 2);
assertEquals(byteLength(Test, 'beta'), 2);
assertEquals(byteLength(Test, 'gamma'), 2);
assertEquals(littleEndian(Test, 'alpha'), true);
assertEquals(littleEndian(Test, 'beta'), false);
assertEquals(littleEndian(Test, 'gamma'), null);
assertEquals(getType(Test, 'alpha'), 'f16');
assertEquals(getType(Test, 'beta'), 'f16');
assertEquals(getType(Test, 'gamma'), 'f16');

const data = new Uint8Array(Test.BYTE_LENGTH);
const view = new DataView(data.buffer);
for (const Test of [TestM, TestF]) {
const test = new Test(data.buffer, 0, false);
test.alpha = f16;
test.beta = f16;
test.gamma = f16;

assertEquals(test.alpha, f16);
assertEquals(test.beta, f16);
assertEquals(test.gamma, f16);
assertEquals(getFloat16(view, off.alpha, true), f16);
assertEquals(getFloat16(view, off.beta, false), f16);
assertEquals(getFloat16(view, off.gamma, false), f16);
}
for (const Test of [TestM, TestF]) {
const test = new Test(data.buffer, 0, true);
test.alpha = f16;
test.beta = f16;
test.gamma = f16;

assertEquals(test.alpha, f16);
assertEquals(test.beta, f16);
assertEquals(test.gamma, f16);
assertEquals(getFloat16(view, off.alpha, true), f16);
assertEquals(getFloat16(view, off.beta, false), f16);
assertEquals(getFloat16(view, off.gamma, true), f16);
}
}
});
60 changes: 60 additions & 0 deletions member/f16.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { getFloat16, setFloat16 } from '@hqtsm/dataview/f16';

import type { KeyofExtends } from '../type.ts';
import type { Struct } from '../struct.ts';
import { member } from '../member.ts';

/**
* Member float16.
*
* @param StructT Struct constructor.
* @param name Member name.
* @param byteOffset Byte offset.
* @param littleEndian Little endian, big endian, or default.
* @returns Byte length.
*/
export function memberF16<T extends typeof Struct>(
StructT: T,
name: Exclude<KeyofExtends<T['prototype'], number>, keyof Struct>,
byteOffset: number,
littleEndian: boolean | null = null,
): number {
Object.defineProperty(StructT.prototype, name, {
get(this: T['prototype']): number {
const { dataView } = this as unknown as {
dataView: DataView & {
getFloat16?: (
byteOffset: number,
littleEndian?: boolean,
) => number;
};
};
const le = littleEndian ?? this.littleEndian;
return dataView.getFloat16
? dataView.getFloat16(byteOffset, le)
: getFloat16(dataView, byteOffset, le);
},
set(this: T['prototype'], value: number): void {
const { dataView } = this as unknown as {
dataView: DataView & {
setFloat16?: (
byteOffset: number,
value: number,
littleEndian?: boolean,
) => number;
};
};
const le = littleEndian ?? this.littleEndian;
if (dataView.setFloat16) {
dataView.setFloat16(
byteOffset,
value,
le,
);
} else {
setFloat16(dataView, byteOffset, value, le);
}
},
});
return member(StructT, name, byteOffset, 2, littleEndian, 'f16');
}
1 change: 1 addition & 0 deletions member/mod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './f16.ts';
export * from './f32.ts';
export * from './f64.ts';
export * from './i8.ts';
Expand Down
1 change: 1 addition & 0 deletions scripts/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ if (Deno.args.length !== 1 || !/^(dev|prod)$/.test(Deno.args[0])) {
const [env] = Deno.args;

const mappings: BuildOptions['mappings'] = {
'jsr:@hqtsm/dataview/f16': '@hqtsm/dataview',
'jsr:@hqtsm/dataview/i24': '@hqtsm/dataview',
};

Expand Down

0 comments on commit 20aac37

Please sign in to comment.