This commit is contained in:
@ -25,78 +25,78 @@ using namespace IACore;
|
||||
|
||||
IAT_BEGIN_BLOCK(Core, DataOps)
|
||||
|
||||
BOOL TestCRC32()
|
||||
{
|
||||
{
|
||||
String s = "123456789";
|
||||
Span<CONST UINT8> span(reinterpret_cast<PCUINT8>(s.data()), s.size());
|
||||
UINT32 result = DataOps::CRC32(span);
|
||||
bool TestCRC32() {
|
||||
{
|
||||
String s = "123456789";
|
||||
Span<const u8> span(reinterpret_cast<const u8 *>(s.data()), s.size());
|
||||
u32 result = DataOps::CRC32(span);
|
||||
|
||||
IAT_CHECK_EQ(result, 0xE3069283);
|
||||
}
|
||||
IAT_CHECK_EQ(result, 0xE3069283);
|
||||
}
|
||||
|
||||
{
|
||||
UINT32 result = DataOps::CRC32({});
|
||||
IAT_CHECK_EQ(result, 0U);
|
||||
}
|
||||
{
|
||||
u32 result = DataOps::CRC32({});
|
||||
IAT_CHECK_EQ(result, 0U);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<UINT8> buffer(33);
|
||||
for (size_t i = 1; i < 33; ++i)
|
||||
buffer[i] = (UINT8) i;
|
||||
{
|
||||
std::vector<u8> buffer(33);
|
||||
for (size_t i = 1; i < 33; ++i)
|
||||
buffer[i] = (u8)i;
|
||||
|
||||
std::vector<UINT8> refData(32);
|
||||
for (size_t i = 0; i < 32; ++i)
|
||||
refData[i] = (UINT8) (i + 1);
|
||||
std::vector<u8> refData(32);
|
||||
for (size_t i = 0; i < 32; ++i)
|
||||
refData[i] = (u8)(i + 1);
|
||||
|
||||
UINT32 hashRef = DataOps::CRC32(Span<CONST UINT8>(refData.data(), refData.size()));
|
||||
u32 hashRef =
|
||||
DataOps::CRC32(Span<const u8>(refData.data(), refData.size()));
|
||||
|
||||
UINT32 hashUnaligned = DataOps::CRC32(Span<CONST UINT8>(buffer.data() + 1, 32));
|
||||
u32 hashUnaligned = DataOps::CRC32(Span<const u8>(buffer.data() + 1, 32));
|
||||
|
||||
IAT_CHECK_EQ(hashRef, hashUnaligned);
|
||||
}
|
||||
IAT_CHECK_EQ(hashRef, hashUnaligned);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestHash_xxHash()
|
||||
{
|
||||
{
|
||||
String s = "123456789";
|
||||
UINT32 result = DataOps::Hash_xxHash(s);
|
||||
IAT_CHECK_EQ(result, 0x937bad67);
|
||||
}
|
||||
bool TestHash_xxHash() {
|
||||
{
|
||||
String s = "123456789";
|
||||
u32 result = DataOps::Hash_xxHash(s);
|
||||
IAT_CHECK_EQ(result, 0x937bad67);
|
||||
}
|
||||
|
||||
{
|
||||
String s = "The quick brown fox jumps over the lazy dog";
|
||||
UINT32 result = DataOps::Hash_xxHash(s);
|
||||
IAT_CHECK_EQ(result, 0xE85EA4DE);
|
||||
}
|
||||
{
|
||||
String s = "The quick brown fox jumps over the lazy dog";
|
||||
u32 result = DataOps::Hash_xxHash(s);
|
||||
IAT_CHECK_EQ(result, 0xE85EA4DE);
|
||||
}
|
||||
|
||||
{
|
||||
String s = "Test";
|
||||
UINT32 r1 = DataOps::Hash_xxHash(s);
|
||||
UINT32 r2 = DataOps::Hash_xxHash(Span<CONST UINT8>((PCUINT8) s.data(), s.size()));
|
||||
IAT_CHECK_EQ(r1, r2);
|
||||
}
|
||||
{
|
||||
String s = "Test";
|
||||
u32 r1 = DataOps::Hash_xxHash(s);
|
||||
u32 r2 =
|
||||
DataOps::Hash_xxHash(Span<const u8>((const u8 *)s.data(), s.size()));
|
||||
IAT_CHECK_EQ(r1, r2);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestHash_FNV1A()
|
||||
{
|
||||
{
|
||||
String s = "123456789";
|
||||
UINT32 result = DataOps::Hash_FNV1A(Span<CONST UINT8>((PCUINT8) s.data(), s.size()));
|
||||
IAT_CHECK_EQ(result, 0xbb86b11c);
|
||||
}
|
||||
bool TestHash_FNV1A() {
|
||||
{
|
||||
String s = "123456789";
|
||||
u32 result =
|
||||
DataOps::Hash_FNV1A(Span<const u8>((const u8 *)s.data(), s.size()));
|
||||
IAT_CHECK_EQ(result, 0xbb86b11c);
|
||||
}
|
||||
|
||||
{
|
||||
UINT32 result = DataOps::Hash_FNV1A(Span<CONST UINT8>{});
|
||||
IAT_CHECK_EQ(result, 0x811C9DC5);
|
||||
}
|
||||
{
|
||||
u32 result = DataOps::Hash_FNV1A(Span<const u8>{});
|
||||
IAT_CHECK_EQ(result, 0x811C9DC5);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -34,14 +34,14 @@ IAT_BEGIN_BLOCK(Core, Environment)
|
||||
// -------------------------------------------------------------------------
|
||||
// 1. Basic Set and Get (The Happy Path)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestBasicCycle()
|
||||
bool TestBasicCycle()
|
||||
{
|
||||
// 1. Ensure clean slate
|
||||
Environment::Unset(TEST_KEY);
|
||||
IAT_CHECK_NOT(Environment::Exists(TEST_KEY));
|
||||
|
||||
// 2. Set
|
||||
BOOL setRes = Environment::Set(TEST_KEY, TEST_VAL);
|
||||
bool setRes = Environment::Set(TEST_KEY, TEST_VAL);
|
||||
IAT_CHECK(setRes);
|
||||
IAT_CHECK(Environment::Exists(TEST_KEY));
|
||||
|
||||
@ -62,7 +62,7 @@ BOOL TestBasicCycle()
|
||||
// -------------------------------------------------------------------------
|
||||
// 2. Overwriting Values
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestOverwrite()
|
||||
bool TestOverwrite()
|
||||
{
|
||||
Environment::Set(TEST_KEY, "ValueA");
|
||||
IAT_CHECK_EQ(Environment::Get(TEST_KEY), String("ValueA"));
|
||||
@ -78,12 +78,12 @@ BOOL TestOverwrite()
|
||||
// -------------------------------------------------------------------------
|
||||
// 3. Unset Logic
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestUnset()
|
||||
bool TestUnset()
|
||||
{
|
||||
Environment::Set(TEST_KEY, "To Be Deleted");
|
||||
IAT_CHECK(Environment::Exists(TEST_KEY));
|
||||
|
||||
BOOL unsetRes = Environment::Unset(TEST_KEY);
|
||||
bool unsetRes = Environment::Unset(TEST_KEY);
|
||||
IAT_CHECK(unsetRes);
|
||||
|
||||
// Verify it is actually gone
|
||||
@ -99,7 +99,7 @@ BOOL TestUnset()
|
||||
// -------------------------------------------------------------------------
|
||||
// 4. Default Value Fallbacks
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestDefaults()
|
||||
bool TestDefaults()
|
||||
{
|
||||
const char *ghostKey = "IA_THIS_KEY_DOES_NOT_EXIST";
|
||||
|
||||
@ -122,7 +122,7 @@ BOOL TestDefaults()
|
||||
// -------------------------------------------------------------------------
|
||||
// Does Set(Key, "") create an existing empty variable, or unset it?
|
||||
// Standard POSIX/Windows API behavior is that it EXISTS, but is empty.
|
||||
BOOL TestEmptyValue()
|
||||
bool TestEmptyValue()
|
||||
{
|
||||
Environment::Set(TEST_KEY, "");
|
||||
|
||||
@ -149,14 +149,14 @@ BOOL TestEmptyValue()
|
||||
// -------------------------------------------------------------------------
|
||||
// 6. Validation / Bad Input
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestBadInput()
|
||||
bool TestBadInput()
|
||||
{
|
||||
// Setting an empty key should fail gracefully
|
||||
BOOL res = Environment::Set("", "Value");
|
||||
bool res = Environment::Set("", "Value");
|
||||
IAT_CHECK_NOT(res);
|
||||
|
||||
// Unsetting an empty key should fail
|
||||
BOOL resUnset = Environment::Unset("");
|
||||
bool resUnset = Environment::Unset("");
|
||||
IAT_CHECK_NOT(resUnset);
|
||||
|
||||
return TRUE;
|
||||
|
||||
@ -37,7 +37,7 @@ IAT_BEGIN_BLOCK(Core, ProcessOps)
|
||||
// -------------------------------------------------------------------------
|
||||
// 1. Basic Execution (Exit Code 0)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestBasicRun()
|
||||
bool TestBasicRun()
|
||||
{
|
||||
// Simple "echo hello"
|
||||
String captured;
|
||||
@ -57,9 +57,9 @@ BOOL TestBasicRun()
|
||||
// -------------------------------------------------------------------------
|
||||
// 2. Argument Parsing
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestArguments()
|
||||
bool TestArguments()
|
||||
{
|
||||
Vector<String> lines;
|
||||
Vec<String> lines;
|
||||
|
||||
// Echo two distinct words.
|
||||
// Windows: cmd.exe /c echo one two
|
||||
@ -83,7 +83,7 @@ BOOL TestArguments()
|
||||
// -------------------------------------------------------------------------
|
||||
// 3. Error / Non-Zero Exit Codes
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestExitCodes()
|
||||
bool TestExitCodes()
|
||||
{
|
||||
// We need a command that returns non-zero.
|
||||
// Windows: cmd /c exit 1
|
||||
@ -110,7 +110,7 @@ BOOL TestExitCodes()
|
||||
// -------------------------------------------------------------------------
|
||||
// 4. Missing Executable Handling
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestMissingExe()
|
||||
bool TestMissingExe()
|
||||
{
|
||||
// Try to run a random string
|
||||
auto result = ProcessOps::SpawnProcessSync("sdflkjghsdflkjg", "", [](StringView) {});
|
||||
@ -132,7 +132,7 @@ BOOL TestMissingExe()
|
||||
// -------------------------------------------------------------------------
|
||||
// 5. Line Buffer Logic (The 4096 split test)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestLargeOutput()
|
||||
bool TestLargeOutput()
|
||||
{
|
||||
// Need to generate output larger than the internal 4096 buffer
|
||||
// to ensure the "partial line" logic works when a line crosses a buffer boundary.
|
||||
@ -169,7 +169,7 @@ BOOL TestLargeOutput()
|
||||
// -------------------------------------------------------------------------
|
||||
// 6. Multi-Line Handling
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestMultiLine()
|
||||
bool TestMultiLine()
|
||||
{
|
||||
// Windows: cmd /c "echo A && echo B"
|
||||
// Linux: /bin/sh -c "echo A; echo B"
|
||||
@ -207,7 +207,7 @@ BOOL TestMultiLine()
|
||||
// -------------------------------------------------------------------------
|
||||
// 6. Complex Command Line Arguments Handling
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestComplexArguments()
|
||||
bool TestComplexArguments()
|
||||
{
|
||||
// Should parse as 3 arguments:
|
||||
// 1. -DDEFINED_MSG="Hello World"
|
||||
|
||||
@ -23,78 +23,75 @@ IAT_BEGIN_BLOCK(Core, RingBuffer)
|
||||
// -------------------------------------------------------------------------
|
||||
// 1. Basic Push Pop
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestPushPop()
|
||||
{
|
||||
// Allocate raw memory for the ring buffer
|
||||
// ControlBlock (128 bytes) + Data
|
||||
std::vector<UINT8> memory(sizeof(RingBufferView::ControlBlock) + 1024);
|
||||
bool TestPushPop() {
|
||||
// Allocate raw memory for the ring buffer
|
||||
// ControlBlock (128 bytes) + Data
|
||||
std::vector<u8> memory(sizeof(RingBufferView::ControlBlock) + 1024);
|
||||
|
||||
// Initialize as OWNER (Producer)
|
||||
RingBufferView producer(std::span<UINT8>(memory), TRUE);
|
||||
// Initialize as OWNER (Producer)
|
||||
RingBufferView producer(std::span<u8>(memory), TRUE);
|
||||
|
||||
// Initialize as CONSUMER (Pointer to same memory)
|
||||
RingBufferView consumer(std::span<UINT8>(memory), FALSE);
|
||||
// Initialize as CONSUMER (Pointer to same memory)
|
||||
RingBufferView consumer(std::span<u8>(memory), FALSE);
|
||||
|
||||
// Data to send
|
||||
String msg = "Hello RingBuffer";
|
||||
BOOL pushed = producer.Push(1, {(const UINT8 *) msg.data(), msg.size()});
|
||||
IAT_CHECK(pushed);
|
||||
// Data to send
|
||||
String msg = "Hello RingBuffer";
|
||||
bool pushed = producer.Push(1, {(const u8 *)msg.data(), msg.size()});
|
||||
IAT_CHECK(pushed);
|
||||
|
||||
// Read back
|
||||
RingBufferView::PacketHeader header;
|
||||
UINT8 readBuf[128];
|
||||
// Read back
|
||||
RingBufferView::PacketHeader header;
|
||||
u8 readBuf[128];
|
||||
|
||||
INT32 bytesRead = consumer.Pop(header, std::span<UINT8>(readBuf, 128));
|
||||
i32 bytesRead = consumer.Pop(header, std::span<u8>(readBuf, 128));
|
||||
|
||||
IAT_CHECK_EQ(header.ID, (UINT16) 1);
|
||||
IAT_CHECK_EQ(bytesRead, (INT32) msg.size());
|
||||
IAT_CHECK_EQ(header.ID, (u16)1);
|
||||
IAT_CHECK_EQ(bytesRead, (i32)msg.size());
|
||||
|
||||
String readMsg((char *) readBuf, bytesRead);
|
||||
IAT_CHECK_EQ(readMsg, msg);
|
||||
String readMsg((char *)readBuf, bytesRead);
|
||||
IAT_CHECK_EQ(readMsg, msg);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 2. Wrap Around
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestWrapAround()
|
||||
{
|
||||
// Small buffer to force wrapping quickly
|
||||
// Capacity will be 100 bytes
|
||||
std::vector<UINT8> memory(sizeof(RingBufferView::ControlBlock) + 100);
|
||||
RingBufferView rb(std::span<UINT8>(memory), TRUE);
|
||||
bool TestWrapAround() {
|
||||
// Small buffer to force wrapping quickly
|
||||
// Capacity will be 100 bytes
|
||||
std::vector<u8> memory(sizeof(RingBufferView::ControlBlock) + 100);
|
||||
RingBufferView rb(std::span<u8>(memory), TRUE);
|
||||
|
||||
// Fill buffer to near end
|
||||
// Push 80 bytes
|
||||
std::vector<UINT8> junk(80, 0xFF);
|
||||
rb.Push(1, junk);
|
||||
// Fill buffer to near end
|
||||
// Push 80 bytes
|
||||
std::vector<u8> junk(80, 0xFF);
|
||||
rb.Push(1, junk);
|
||||
|
||||
// Pop them to advance READ cursor
|
||||
RingBufferView::PacketHeader header;
|
||||
UINT8 outBuf[100];
|
||||
rb.Pop(header, outBuf);
|
||||
// Pop them to advance READ cursor
|
||||
RingBufferView::PacketHeader header;
|
||||
u8 outBuf[100];
|
||||
rb.Pop(header, outBuf);
|
||||
|
||||
// Now READ and WRITE are near index 80.
|
||||
// Pushing 40 bytes should trigger a wrap-around (split write)
|
||||
std::vector<UINT8> wrapData(40, 0xAA);
|
||||
BOOL pushed = rb.Push(2, wrapData);
|
||||
IAT_CHECK(pushed);
|
||||
// Now READ and WRITE are near index 80.
|
||||
// Pushing 40 bytes should trigger a wrap-around (split write)
|
||||
std::vector<u8> wrapData(40, 0xAA);
|
||||
bool pushed = rb.Push(2, wrapData);
|
||||
IAT_CHECK(pushed);
|
||||
|
||||
// Pop and verify integrity
|
||||
INT32 popSize = rb.Pop(header, outBuf);
|
||||
IAT_CHECK_EQ(popSize, 40);
|
||||
// Pop and verify integrity
|
||||
i32 popSize = rb.Pop(header, outBuf);
|
||||
IAT_CHECK_EQ(popSize, 40);
|
||||
|
||||
// Check if data is intact
|
||||
BOOL match = TRUE;
|
||||
for (int i = 0; i < 40; i++)
|
||||
{
|
||||
if (outBuf[i] != 0xAA)
|
||||
match = FALSE;
|
||||
}
|
||||
IAT_CHECK(match);
|
||||
// Check if data is intact
|
||||
bool match = TRUE;
|
||||
for (int i = 0; i < 40; i++) {
|
||||
if (outBuf[i] != 0xAA)
|
||||
match = FALSE;
|
||||
}
|
||||
IAT_CHECK(match);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IAT_BEGIN_TEST_LIST()
|
||||
|
||||
@ -20,12 +20,12 @@ using namespace IACore;
|
||||
|
||||
IAT_BEGIN_BLOCK(Core, FloatVec4)
|
||||
|
||||
BOOL TestFloatArithmetic()
|
||||
bool TestFloatArithmetic()
|
||||
{
|
||||
FloatVec4 v1(10.0f, 20.0f, 30.0f, 40.0f);
|
||||
FloatVec4 v2(2.0f, 4.0f, 5.0f, 8.0f);
|
||||
|
||||
ALIGN(16) FLOAT32 res[4];
|
||||
alignas(16) f32 res[4];
|
||||
|
||||
(v1 / v2).Store(res);
|
||||
IAT_CHECK_APPROX(res[0], 5.0f);
|
||||
@ -40,9 +40,9 @@ BOOL TestFloatArithmetic()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestMathHelpers()
|
||||
bool TestMathHelpers()
|
||||
{
|
||||
ALIGN(16) FLOAT32 res[4];
|
||||
alignas(16) f32 res[4];
|
||||
|
||||
FloatVec4 vSq(4.0f, 9.0f, 16.0f, 25.0f);
|
||||
vSq.Sqrt().Store(res);
|
||||
@ -63,9 +63,9 @@ BOOL TestMathHelpers()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestApproxMath()
|
||||
bool TestApproxMath()
|
||||
{
|
||||
ALIGN(16) FLOAT32 res[4];
|
||||
alignas(16) f32 res[4];
|
||||
FloatVec4 v(16.0f, 25.0f, 100.0f, 1.0f);
|
||||
|
||||
v.Rsqrt().Store(res);
|
||||
@ -76,16 +76,16 @@ BOOL TestApproxMath()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestLinearAlgebra()
|
||||
bool TestLinearAlgebra()
|
||||
{
|
||||
FloatVec4 v1(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
FloatVec4 v2(1.0f, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
FLOAT32 dot = v1.Dot(v2);
|
||||
f32 dot = v1.Dot(v2);
|
||||
IAT_CHECK_APPROX(dot, 4.0f);
|
||||
|
||||
FloatVec4 vNorm(10.0f, 0.0f, 0.0f, 0.0f);
|
||||
ALIGN(16) FLOAT32 res[4];
|
||||
alignas(16) f32 res[4];
|
||||
|
||||
vNorm.Normalize().Store(res);
|
||||
IAT_CHECK_APPROX(res[0], 1.0f);
|
||||
|
||||
@ -23,10 +23,10 @@ using namespace IACore;
|
||||
|
||||
IAT_BEGIN_BLOCK(Core, IntVec4)
|
||||
|
||||
BOOL TestConstructors()
|
||||
bool TestConstructors()
|
||||
{
|
||||
IntVec4 vBroadcast(10);
|
||||
ALIGN(16) UINT32 storeBuf[4];
|
||||
alignas(16) u32 storeBuf[4];
|
||||
vBroadcast.Store(storeBuf);
|
||||
|
||||
IAT_CHECK_EQ(storeBuf[0], 10U);
|
||||
@ -37,7 +37,7 @@ BOOL TestConstructors()
|
||||
IAT_CHECK_EQ(storeBuf[0], 1U);
|
||||
IAT_CHECK_EQ(storeBuf[3], 4U);
|
||||
|
||||
ALIGN(16) UINT32 srcBuf[4] = {100, 200, 300, 400};
|
||||
alignas(16) u32 srcBuf[4] = {100, 200, 300, 400};
|
||||
IntVec4 vLoad = IntVec4::Load(srcBuf);
|
||||
vLoad.Store(storeBuf);
|
||||
IAT_CHECK_EQ(storeBuf[1], 200U);
|
||||
@ -45,13 +45,13 @@ BOOL TestConstructors()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestArithmetic()
|
||||
bool TestArithmetic()
|
||||
{
|
||||
IntVec4 v1(10, 20, 30, 40);
|
||||
IntVec4 v2(1, 2, 3, 4);
|
||||
|
||||
IntVec4 vAdd = v1 + v2;
|
||||
ALIGN(16) UINT32 res[4];
|
||||
alignas(16) u32 res[4];
|
||||
vAdd.Store(res);
|
||||
IAT_CHECK_EQ(res[0], 11U);
|
||||
IAT_CHECK_EQ(res[3], 44U);
|
||||
@ -69,13 +69,13 @@ BOOL TestArithmetic()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestBitwise()
|
||||
bool TestBitwise()
|
||||
{
|
||||
IntVec4 vAllOnes(0xFFFFFFFF);
|
||||
IntVec4 vZero((UINT32) 0);
|
||||
IntVec4 vZero((u32) 0);
|
||||
IntVec4 vPattern(0xAAAAAAAA);
|
||||
|
||||
ALIGN(16) UINT32 res[4];
|
||||
alignas(16) u32 res[4];
|
||||
|
||||
(vAllOnes & vPattern).Store(res);
|
||||
IAT_CHECK_EQ(res[0], 0xAAAAAAAAU);
|
||||
@ -100,13 +100,13 @@ BOOL TestBitwise()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestSaturation()
|
||||
bool TestSaturation()
|
||||
{
|
||||
UINT32 max = 0xFFFFFFFF;
|
||||
u32 max = 0xFFFFFFFF;
|
||||
IntVec4 vHigh(max - 10);
|
||||
IntVec4 vAdd(20);
|
||||
|
||||
ALIGN(16) UINT32 res[4];
|
||||
alignas(16) u32 res[4];
|
||||
|
||||
vHigh.SatAdd(vAdd).Store(res);
|
||||
IAT_CHECK_EQ(res[0], max);
|
||||
@ -119,10 +119,10 @@ BOOL TestSaturation()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL TestAdvancedOps()
|
||||
bool TestAdvancedOps()
|
||||
{
|
||||
IntVec4 v(0, 50, 100, 150);
|
||||
ALIGN(16) UINT32 res[4];
|
||||
alignas(16) u32 res[4];
|
||||
|
||||
v.Clamp(40, 110).Store(res);
|
||||
IAT_CHECK_EQ(res[0], 40U);
|
||||
|
||||
@ -22,141 +22,135 @@ using namespace IACore;
|
||||
IAT_BEGIN_BLOCK(Core, StreamReader)
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 1. Basic Primitive Reading (UINT8)
|
||||
// 1. Basic Primitive Reading (u8)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestReadUint8()
|
||||
{
|
||||
UINT8 data[] = {0xAA, 0xBB, 0xCC};
|
||||
StreamReader reader(data);
|
||||
bool TestReadUint8() {
|
||||
u8 data[] = {0xAA, 0xBB, 0xCC};
|
||||
StreamReader reader(data);
|
||||
|
||||
// Read First Byte
|
||||
auto val1 = reader.Read<UINT8>();
|
||||
IAT_CHECK(val1.has_value());
|
||||
IAT_CHECK_EQ(*val1, 0xAA);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 1);
|
||||
// Read First Byte
|
||||
auto val1 = reader.Read<u8>();
|
||||
IAT_CHECK(val1.has_value());
|
||||
IAT_CHECK_EQ(*val1, 0xAA);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)1);
|
||||
|
||||
// Read Second Byte
|
||||
auto val2 = reader.Read<UINT8>();
|
||||
IAT_CHECK_EQ(*val2, 0xBB);
|
||||
// Read Second Byte
|
||||
auto val2 = reader.Read<u8>();
|
||||
IAT_CHECK_EQ(*val2, 0xBB);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 2. Multi-byte Reading (Endianness check)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestReadMultiByte()
|
||||
{
|
||||
// 0x04030201 in Little Endian memory layout
|
||||
// IACore always assumes a Little Endian machine
|
||||
UINT8 data[] = {0x01, 0x02, 0x03, 0x04};
|
||||
StreamReader reader(data);
|
||||
bool TestReadMultiByte() {
|
||||
// 0x04030201 in Little Endian memory layout
|
||||
// IACore always assumes a Little Endian machine
|
||||
u8 data[] = {0x01, 0x02, 0x03, 0x04};
|
||||
StreamReader reader(data);
|
||||
|
||||
auto val = reader.Read<UINT32>();
|
||||
IAT_CHECK(val.has_value());
|
||||
auto val = reader.Read<u32>();
|
||||
IAT_CHECK(val.has_value());
|
||||
|
||||
IAT_CHECK_EQ(*val, (UINT32) 0x04030201);
|
||||
IAT_CHECK_EQ(*val, (u32)0x04030201);
|
||||
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 4);
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)4);
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 3. Floating Point (Approx check)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestReadFloat()
|
||||
{
|
||||
FLOAT32 pi = 3.14159f;
|
||||
// Bit-cast float to bytes for setup
|
||||
UINT8 data[4];
|
||||
std::memcpy(data, &pi, 4);
|
||||
bool TestReadFloat() {
|
||||
f32 pi = 3.14159f;
|
||||
// Bit-cast float to bytes for setup
|
||||
u8 data[4];
|
||||
std::memcpy(data, &pi, 4);
|
||||
|
||||
StreamReader reader(data);
|
||||
auto val = reader.Read<FLOAT32>();
|
||||
StreamReader reader(data);
|
||||
auto val = reader.Read<f32>();
|
||||
|
||||
IAT_CHECK(val.has_value());
|
||||
IAT_CHECK_APPROX(*val, pi);
|
||||
IAT_CHECK(val.has_value());
|
||||
IAT_CHECK_APPROX(*val, pi);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 4. Batch Buffer Reading
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestReadBuffer()
|
||||
{
|
||||
UINT8 src[] = {1, 2, 3, 4, 5};
|
||||
UINT8 dst[3] = {0};
|
||||
StreamReader reader(src);
|
||||
bool TestReadBuffer() {
|
||||
u8 src[] = {1, 2, 3, 4, 5};
|
||||
u8 dst[3] = {0};
|
||||
StreamReader reader(src);
|
||||
|
||||
// Read 3 bytes into dst
|
||||
auto res = reader.Read(dst, 3);
|
||||
IAT_CHECK(res.has_value());
|
||||
// Read 3 bytes into dst
|
||||
auto res = reader.Read(dst, 3);
|
||||
IAT_CHECK(res.has_value());
|
||||
|
||||
// Verify dst content
|
||||
IAT_CHECK_EQ(dst[0], 1);
|
||||
IAT_CHECK_EQ(dst[1], 2);
|
||||
IAT_CHECK_EQ(dst[2], 3);
|
||||
// Verify dst content
|
||||
IAT_CHECK_EQ(dst[0], 1);
|
||||
IAT_CHECK_EQ(dst[1], 2);
|
||||
IAT_CHECK_EQ(dst[2], 3);
|
||||
|
||||
// Verify cursor
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 3);
|
||||
// Verify cursor
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)3);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 5. Navigation (Seek, Skip, Remaining)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestNavigation()
|
||||
{
|
||||
UINT8 data[10] = {0}; // Zero init
|
||||
StreamReader reader(data);
|
||||
bool TestNavigation() {
|
||||
u8 data[10] = {0}; // Zero init
|
||||
StreamReader reader(data);
|
||||
|
||||
IAT_CHECK_EQ(reader.Remaining(), (SIZE_T) 10);
|
||||
IAT_CHECK_EQ(reader.Remaining(), (usize)10);
|
||||
|
||||
// Skip
|
||||
reader.Skip(5);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 5);
|
||||
IAT_CHECK_EQ(reader.Remaining(), (SIZE_T) 5);
|
||||
// Skip
|
||||
reader.Skip(5);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)5);
|
||||
IAT_CHECK_EQ(reader.Remaining(), (usize)5);
|
||||
|
||||
// Skip clamping
|
||||
reader.Skip(100); // Should clamp to 10
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 10);
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
// Skip clamping
|
||||
reader.Skip(100); // Should clamp to 10
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)10);
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
|
||||
// Seek
|
||||
reader.Seek(2);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (SIZE_T) 2);
|
||||
IAT_CHECK_EQ(reader.Remaining(), (SIZE_T) 8);
|
||||
IAT_CHECK_NOT(reader.IsEOF());
|
||||
// Seek
|
||||
reader.Seek(2);
|
||||
IAT_CHECK_EQ(reader.Cursor(), (usize)2);
|
||||
IAT_CHECK_EQ(reader.Remaining(), (usize)8);
|
||||
IAT_CHECK_NOT(reader.IsEOF());
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 6. Error Handling (EOF Protection)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestBoundaryChecks()
|
||||
{
|
||||
UINT8 data[] = {0x00, 0x00};
|
||||
StreamReader reader(data);
|
||||
bool TestBoundaryChecks() {
|
||||
u8 data[] = {0x00, 0x00};
|
||||
StreamReader reader(data);
|
||||
|
||||
// Valid read
|
||||
UNUSED(reader.Read<UINT16>());
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
// Valid read
|
||||
UNUSED(reader.Read<u16>());
|
||||
IAT_CHECK(reader.IsEOF());
|
||||
|
||||
// Invalid Read Primitive
|
||||
auto val = reader.Read<UINT8>();
|
||||
IAT_CHECK_NOT(val.has_value()); // Should be unexpected
|
||||
// Invalid Read Primitive
|
||||
auto val = reader.Read<u8>();
|
||||
IAT_CHECK_NOT(val.has_value()); // Should be unexpected
|
||||
|
||||
// Invalid Batch Read
|
||||
UINT8 buf[1];
|
||||
auto batch = reader.Read(buf, 1);
|
||||
IAT_CHECK_NOT(batch.has_value());
|
||||
// Invalid Batch Read
|
||||
u8 buf[1];
|
||||
auto batch = reader.Read(buf, 1);
|
||||
IAT_CHECK_NOT(batch.has_value());
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -25,7 +25,7 @@ using namespace IACore;
|
||||
|
||||
struct TestVec3
|
||||
{
|
||||
FLOAT32 x, y, z;
|
||||
f32 x, y, z;
|
||||
|
||||
// Equality operator required for hash maps, though strictly
|
||||
// the hash function itself doesn't need it, it's good practice to test both.
|
||||
@ -48,10 +48,10 @@ IAT_BEGIN_BLOCK(Core, Utils)
|
||||
// -------------------------------------------------------------------------
|
||||
// 1. Binary <-> Hex String Conversion
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestHexConversion()
|
||||
bool TestHexConversion()
|
||||
{
|
||||
// A. Binary To Hex
|
||||
UINT8 bin[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0xFF};
|
||||
u8 bin[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0xFF};
|
||||
String hex = IACore::Utils::BinaryToHexString(bin);
|
||||
|
||||
IAT_CHECK_EQ(hex, String("DEADBEEF00FF"));
|
||||
@ -59,7 +59,7 @@ BOOL TestHexConversion()
|
||||
// B. Hex To Binary (Valid Upper)
|
||||
auto resUpper = IACore::Utils::HexStringToBinary("DEADBEEF00FF");
|
||||
IAT_CHECK(resUpper.has_value());
|
||||
IAT_CHECK_EQ(resUpper->size(), (SIZE_T) 6);
|
||||
IAT_CHECK_EQ(resUpper->size(), (usize) 6);
|
||||
IAT_CHECK_EQ((*resUpper)[0], 0xDE);
|
||||
IAT_CHECK_EQ((*resUpper)[5], 0xFF);
|
||||
|
||||
@ -69,7 +69,7 @@ BOOL TestHexConversion()
|
||||
IAT_CHECK_EQ((*resLower)[0], 0xDE);
|
||||
|
||||
// D. Round Trip Integrity
|
||||
Vector<UINT8> original = {1, 2, 3, 4, 5};
|
||||
Vec<u8> original = {1, 2, 3, 4, 5};
|
||||
String s = IACore::Utils::BinaryToHexString(original);
|
||||
auto back = IACore::Utils::HexStringToBinary(s);
|
||||
IAT_CHECK(back.has_value());
|
||||
@ -82,7 +82,7 @@ BOOL TestHexConversion()
|
||||
// -------------------------------------------------------------------------
|
||||
// 2. Hex Error Handling
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestHexErrors()
|
||||
bool TestHexErrors()
|
||||
{
|
||||
// Odd Length
|
||||
auto odd = IACore::Utils::HexStringToBinary("ABC");
|
||||
@ -95,7 +95,7 @@ BOOL TestHexErrors()
|
||||
// Empty string is valid (empty vector)
|
||||
auto empty = IACore::Utils::HexStringToBinary("");
|
||||
IAT_CHECK(empty.has_value());
|
||||
IAT_CHECK_EQ(empty->size(), (SIZE_T) 0);
|
||||
IAT_CHECK_EQ(empty->size(), (usize) 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -103,9 +103,9 @@ BOOL TestHexErrors()
|
||||
// -------------------------------------------------------------------------
|
||||
// 3. Algorithms: Sorting
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestSort()
|
||||
bool TestSort()
|
||||
{
|
||||
Vector<int> nums = {5, 1, 4, 2, 3};
|
||||
Vec<int> nums = {5, 1, 4, 2, 3};
|
||||
|
||||
IACore::Utils::Sort(nums);
|
||||
|
||||
@ -121,10 +121,10 @@ BOOL TestSort()
|
||||
// -------------------------------------------------------------------------
|
||||
// 4. Algorithms: Binary Search (Left/Right)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestBinarySearch()
|
||||
bool TestBinarySearch()
|
||||
{
|
||||
// Must be sorted for Binary Search
|
||||
Vector<int> nums = {10, 20, 20, 20, 30};
|
||||
Vec<int> nums = {10, 20, 20, 20, 30};
|
||||
|
||||
// Search Left (Lower Bound) -> First element >= value
|
||||
auto itLeft = IACore::Utils::BinarySearchLeft(nums, 20);
|
||||
@ -148,11 +148,11 @@ BOOL TestBinarySearch()
|
||||
// -------------------------------------------------------------------------
|
||||
// 5. Hashing Basics
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestHashBasics()
|
||||
bool TestHashBasics()
|
||||
{
|
||||
UINT64 h1 = IACore::Utils::ComputeHash(10, 20.5f, "Hello");
|
||||
UINT64 h2 = IACore::Utils::ComputeHash(10, 20.5f, "Hello");
|
||||
UINT64 h3 = IACore::Utils::ComputeHash(10, 20.5f, "World");
|
||||
u64 h1 = IACore::Utils::ComputeHash(10, 20.5f, "Hello");
|
||||
u64 h2 = IACore::Utils::ComputeHash(10, 20.5f, "Hello");
|
||||
u64 h3 = IACore::Utils::ComputeHash(10, 20.5f, "World");
|
||||
|
||||
// Determinism
|
||||
IAT_CHECK_EQ(h1, h2);
|
||||
@ -162,8 +162,8 @@ BOOL TestHashBasics()
|
||||
|
||||
// Order sensitivity (Golden ratio combine should care about order)
|
||||
// Hash(A, B) != Hash(B, A)
|
||||
UINT64 orderA = IACore::Utils::ComputeHash(1, 2);
|
||||
UINT64 orderB = IACore::Utils::ComputeHash(2, 1);
|
||||
u64 orderA = IACore::Utils::ComputeHash(1, 2);
|
||||
u64 orderB = IACore::Utils::ComputeHash(2, 1);
|
||||
IAT_CHECK_NEQ(orderA, orderB);
|
||||
|
||||
return TRUE;
|
||||
@ -172,7 +172,7 @@ BOOL TestHashBasics()
|
||||
// -------------------------------------------------------------------------
|
||||
// 6. Macro Verification (IA_MAKE_HASHABLE)
|
||||
// -------------------------------------------------------------------------
|
||||
BOOL TestHashMacro()
|
||||
bool TestHashMacro()
|
||||
{
|
||||
TestVec3 v1{1.0f, 2.0f, 3.0f};
|
||||
TestVec3 v2{1.0f, 2.0f, 3.0f};
|
||||
@ -180,9 +180,9 @@ BOOL TestHashMacro()
|
||||
|
||||
ankerl::unordered_dense::hash<TestVec3> hasher;
|
||||
|
||||
UINT64 h1 = hasher(v1);
|
||||
UINT64 h2 = hasher(v2);
|
||||
UINT64 h3 = hasher(v3);
|
||||
u64 h1 = hasher(v1);
|
||||
u64 h2 = hasher(v2);
|
||||
u64 h3 = hasher(v3);
|
||||
|
||||
IAT_CHECK_EQ(h1, h2); // Same content = same hash
|
||||
IAT_CHECK_NEQ(h1, h3); // Different content = different hash
|
||||
@ -191,10 +191,10 @@ BOOL TestHashMacro()
|
||||
// Verify ComputeHash integration
|
||||
// -------------------------------------------------------------
|
||||
|
||||
UINT64 hManual = 0;
|
||||
u64 hManual = 0;
|
||||
IACore::Utils::HashCombine(hManual, v1);
|
||||
|
||||
UINT64 hWrapper = IACore::Utils::ComputeHash(v1);
|
||||
u64 hWrapper = IACore::Utils::ComputeHash(v1);
|
||||
|
||||
// This proves ComputeHash found the specialization and mixed it correctly
|
||||
IAT_CHECK_EQ(hManual, hWrapper);
|
||||
|
||||
Reference in New Issue
Block a user