#include "Testing/MemoryTesting.h" #include "Memory/Memory.h" #include "Memory/Alignment.h" #include "Memory/MemoryOperator.h" #include "Miscellaneous/AssertionMacros.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_BEGIN(Testing) void TestMemory() { TestAlignment(); TestMemoryBuffer(); TestMemoryMalloc(); TestMemoryOperator(); } void TestAlignment() { int32 Unaligned = 0xAAAA; int32 Aligned8 = Memory::Align(Unaligned, 8); int32 Aligned16 = Memory::Align(Unaligned, 16); int32 Aligned32 = Memory::Align(Unaligned, 32); int32 Aligned64 = Memory::Align(Unaligned, 64); int32 AlignedDown8 = Memory::AlignDown(Unaligned, 8); int32 AlignedDown16 = Memory::AlignDown(Unaligned, 16); int32 AlignedDown32 = Memory::AlignDown(Unaligned, 32); int32 AlignedDown64 = Memory::AlignDown(Unaligned, 64); int32 AlignedArbitrary8 = Memory::AlignArbitrary(Unaligned, 8); int32 AlignedArbitrary16 = Memory::AlignArbitrary(Unaligned, 16); int32 AlignedArbitrary32 = Memory::AlignArbitrary(Unaligned, 32); int32 AlignedArbitrary64 = Memory::AlignArbitrary(Unaligned, 64); always_check((Memory::IsAligned(Aligned8, 8) && Aligned8 > Unaligned)); always_check((Memory::IsAligned(Aligned16, 16) && Aligned16 > Unaligned)); always_check((Memory::IsAligned(Aligned32, 32) && Aligned32 > Unaligned)); always_check((Memory::IsAligned(Aligned64, 64) && Aligned64 > Unaligned)); always_check((Memory::IsAligned(Aligned8, 8) && AlignedDown8 < Unaligned)); always_check((Memory::IsAligned(Aligned16, 16) && AlignedDown16 < Unaligned)); always_check((Memory::IsAligned(Aligned32, 32) && AlignedDown32 < Unaligned)); always_check((Memory::IsAligned(Aligned64, 64) && AlignedDown64 < Unaligned)); always_check((Memory::IsAligned(AlignedArbitrary8, 8))); always_check((Memory::IsAligned(AlignedArbitrary16, 16))); always_check((Memory::IsAligned(AlignedArbitrary32, 32))); always_check((Memory::IsAligned(AlignedArbitrary64, 64))); } void TestMemoryBuffer() { int64 TempA; int64 TempB; int64 TempC; int64 TempD; uint8* PtrA = reinterpret_cast(&TempA); uint8* PtrB = reinterpret_cast(&TempB); uint8* PtrC = reinterpret_cast(&TempC); uint8* PtrD = reinterpret_cast(&TempD); TempA = 0x0123456789ABCDEF; TempB = 0x0123456789AB0000; Memory::Memmove(PtrA, PtrA + 2, 6); always_check((TempA << 16) == TempB); TempA = 0x0123456789ABCDEF; Memory::Memmove(TempB, TempA); always_check(TempB == TempA); TempA = 1004; TempB = 1005; TempC = 1005; TempD = 1006; int32 ResultA = Memory::Memcmp(PtrA, PtrB, sizeof(int64)); int32 ResultB = Memory::Memcmp(PtrB, PtrC, sizeof(int64)); int32 ResultC = Memory::Memcmp(PtrC, PtrD, sizeof(int64)); always_check((ResultA < 0) == (ResultC < 0)); always_check(ResultB == 0); int32 ResultD = Memory::Memcmp(TempA, TempB); int32 ResultE = Memory::Memcmp(TempB, TempC); int32 ResultF = Memory::Memcmp(TempC, TempD); always_check((ResultD < 0) == (ResultF < 0)); always_check(ResultE == 0); Memory::Memset(PtrA, 0x3F, sizeof(int64)); always_check(TempA == 0x3F3F3F3F3F3F3F3F); Memory::Memset(TempB, 0x3F); always_check(TempB == 0x3F3F3F3F3F3F3F3F); Memory::Memzero(PtrA, sizeof(int64)); always_check(TempA == 0); Memory::Memzero(TempB); always_check(TempB == 0); TempA = 0x0123456789ABCDEF; Memory::Memcpy(PtrC, PtrA, sizeof(int64)); always_check(TempA == TempC); TempB = 0xDEDCBA9876543210; Memory::Memcpy(TempD, TempB); always_check(TempB == TempD); } void TestMemoryMalloc() { int32* PtrA; int64* PtrB; PtrA = reinterpret_cast(Memory::SystemMalloc(sizeof(int32))); *PtrA = 0x01234567; always_check(*PtrA == 0x01234567); PtrB = reinterpret_cast(Memory::SystemRealloc(PtrA, sizeof(int64))); *PtrB = 0x0123456789ABCDEF; always_check(*PtrB == 0x0123456789ABCDEF); Memory::SystemFree(PtrB); PtrA = reinterpret_cast(Memory::Malloc(sizeof(int32), 1024)); always_check(Memory::IsAligned(PtrA, 1024)); *PtrA = 0x01234567; always_check(*PtrA == 0x01234567); PtrB = reinterpret_cast(Memory::Realloc(PtrA, sizeof(int64), 1024)); always_check(Memory::IsAligned(PtrB, 1024)); *PtrB = 0x0123456789ABCDEF; always_check(*PtrB == 0x0123456789ABCDEF); Memory::Free(PtrB); PtrA = new int32; PtrB = new int64; *PtrA = 0x01234567; always_check(*PtrA == 0x01234567); *PtrB = 0x0123456789ABCDEF; always_check(*PtrB == 0x0123456789ABCDEF); delete PtrA; delete PtrB; struct alignas(1024) FTest { int32 A; }; FTest* PtrC = new FTest[4]; always_check(Memory::IsAligned(PtrC, 1024)); PtrC->A = 0x01234567; always_check(PtrC->A == 0x01234567); delete[] PtrC; } NAMESPACE_UNNAMED_BEGIN struct FTracker { static int32 Status; FTracker() { always_check(Status == 0); Status = -1; } FTracker(const FTracker&) { always_check(Status == 1); Status = -1; } FTracker(FTracker&&) { always_check(Status == 2); Status = -1; } ~FTracker() { always_check(Status == 3); Status = -1; } FTracker& operator=(const FTracker&) { always_check(Status == 4); Status = -1; return *this; } FTracker& operator=(FTracker&&) { always_check(Status == 5); Status = -1; return *this; } }; int32 FTracker::Status = -1; NAMESPACE_UNNAMED_END void TestMemoryOperator() { FTracker* PtrA = reinterpret_cast(Memory::Malloc(sizeof(FTracker))); FTracker* PtrB = reinterpret_cast(Memory::Malloc(sizeof(FTracker))); FTracker::Status = 0; Memory::DefaultConstruct(PtrA); always_check(FTracker::Status == -1); FTracker::Status = 1; Memory::Construct(PtrA, PtrB); always_check(FTracker::Status == -1); FTracker::Status = 1; Memory::CopyConstruct(PtrA, PtrB); always_check(FTracker::Status == -1); FTracker::Status = 2; Memory::MoveConstruct(PtrA, PtrB); always_check(FTracker::Status == -1); FTracker::Status = 3; Memory::Destruct(PtrA); always_check(FTracker::Status == -1); FTracker::Status = 4; Memory::CopyAssign(PtrA, PtrB); always_check(FTracker::Status == -1); FTracker::Status = 5; Memory::MoveAssign(PtrA, PtrB); always_check(FTracker::Status == -1); Memory::Free(PtrA); Memory::Free(PtrB); } NAMESPACE_END(Testing) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END