-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
abf95c5
commit 20aac37
Showing
4 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters