mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
more APIs
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
Checks: '-*,bugprone-*,cert-*,clang-analyzer-*,google-*,llvm-*,-llvm-header-guard,misc-*,modernize-*,-modernize-use-trailing-return-type,-modernize-avoid-c-arrays,performance-*,portability-*,readability-*,-readability-magic-numbers,-readability-uppercase-literal-suffix,cppcoreguidelines-*,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-avoid-c-arrays,hicpp-*,-hicpp-vararg,-hicpp-no-array-decay,-hicpp-avoid-c-arrays,-hicpp-uppercase-literal-suffix,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-static-cast-downcast,-modernize-pass-by-value,-cert-dcl50-cpp,-cert-err58-cpp,-bugprone-undefined-memory-manipulation,-*-function-size,-misc-no-recursion,-cppcoreguidelines-avoid-non-const-global-variables,-readability-function-cognitive-complexity,-performance-no-int-to-ptr'
|
||||
CheckOptions:
|
||||
- key: readability-redundant-access-specifiers.CheckFirstDeclaration
|
||||
value: 1
|
||||
- key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables
|
||||
value: 1
|
||||
- key: cppcoreguidelines-pro-type-member-init.IgnoreArrays
|
||||
value: 1
|
||||
- key: cppcoreguidelines-macro-usage.AllowedRegexp
|
||||
value: (KYTY_*)|(EXIT*)|(ASSERT*)|(UT_*)
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.MemberCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.PrivateMemberPrefix
|
||||
value: 'm_'
|
||||
- key: readability-identifier-naming.ProtectedMemberPrefix
|
||||
value: 'm_'
|
||||
- key: readability-identifier-naming.PublicMethodCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.PublicMemberCase
|
||||
value: aNy_CasE
|
||||
- key: readability-identifier-naming.StructCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ConstantCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.EnumConstantCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.TemplateParameterCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ValueTemplateParameterCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.LocalConstantCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.GlobalConstantCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.GlobalConstantPrefix
|
||||
value: 'g_'
|
||||
- key: readability-identifier-naming.GlobalVariableCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.GlobalVariablePrefix
|
||||
value: 'g_'
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.ParameterCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.ConstexprVariableCase
|
||||
value: UPPER_CASE
|
||||
@@ -0,0 +1,39 @@
|
||||
file(GLOB unit_test_src
|
||||
"include/*.h"
|
||||
"src/*.cpp"
|
||||
"src/core/*.cpp"
|
||||
)
|
||||
|
||||
if (MSVC AND CLANG)
|
||||
set_source_files_properties(${unit_test_src} PROPERTIES COMPILE_FLAGS "-Wno-pragma-pack")
|
||||
endif()
|
||||
|
||||
add_library(unit_test STATIC ${unit_test_src})
|
||||
|
||||
target_link_libraries(unit_test core)
|
||||
target_link_libraries(unit_test math)
|
||||
|
||||
target_include_directories(unit_test PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
list(APPEND inc_headers
|
||||
${PROJECT_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
# ${CMAKE_SOURCE_DIR}/3rdparty/sdl2/include
|
||||
# ${CMAKE_SOURCE_DIR}/3rdparty/lua/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/gtest/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/gtest
|
||||
# ${CMAKE_SOURCE_DIR}/3rdparty/rijndael/source
|
||||
# ${CMAKE_SOURCE_DIR}/3rdparty/miniz
|
||||
# ${CMAKE_SOURCE_DIR}/3rdparty/magic_enum/include
|
||||
)
|
||||
|
||||
list(APPEND check_headers
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
clang_tidy_check(unit_test "" "${check_headers}" "${inc_headers}")
|
||||
|
||||
include_what_you_use(unit_test "${inc_headers}")
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "Kyty/UnitTest.h"
|
||||
|
||||
namespace Kyty::UnitTest {
|
||||
|
||||
UT_LINK(CoreCharString);
|
||||
UT_LINK(CoreMSpace);
|
||||
|
||||
KYTY_SUBSYSTEM_INIT(UnitTest)
|
||||
{
|
||||
testing::InitGoogleTest(KYTY_SUBSYSTEM_ARGC, KYTY_SUBSYSTEM_ARGV);
|
||||
}
|
||||
|
||||
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(UnitTest) {}
|
||||
|
||||
KYTY_SUBSYSTEM_DESTROY(UnitTest) {}
|
||||
|
||||
bool unit_test_all()
|
||||
{
|
||||
return RUN_ALL_TESTS() == 0;
|
||||
}
|
||||
|
||||
} // namespace Kyty::UnitTest
|
||||
@@ -0,0 +1,230 @@
|
||||
#include "Kyty/Core/MSpace.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
#include "Kyty/Math/Rand.h"
|
||||
#include "Kyty/UnitTest.h"
|
||||
|
||||
UT_BEGIN(CoreMSpace);
|
||||
|
||||
using Core::MSpaceCreate;
|
||||
using Core::MSpaceDestroy;
|
||||
using Core::MSpaceFree;
|
||||
using Core::MSpaceMalloc;
|
||||
using Core::MSpaceRealloc;
|
||||
using Math::Rand;
|
||||
|
||||
static void test_fail()
|
||||
{
|
||||
size_t s = 1000;
|
||||
auto* buf = new uint8_t[s];
|
||||
|
||||
auto* m = MSpaceCreate("test", buf, s, true, nullptr);
|
||||
|
||||
EXPECT_EQ(m, nullptr);
|
||||
|
||||
void* ptr = MSpaceMalloc(m, 56);
|
||||
|
||||
EXPECT_EQ(ptr, nullptr);
|
||||
|
||||
EXPECT_FALSE(MSpaceFree(m, ptr));
|
||||
|
||||
EXPECT_FALSE(MSpaceDestroy(m));
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
static size_t g_size = 0;
|
||||
static uint8_t* g_ptr = nullptr;
|
||||
|
||||
static void test_callback(Core::mspace_t m, size_t /*free_size*/, size_t size)
|
||||
{
|
||||
g_size = size;
|
||||
if (g_ptr != nullptr)
|
||||
{
|
||||
EXPECT_TRUE(MSpaceFree(m, g_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_ok()
|
||||
{
|
||||
size_t s = 2000;
|
||||
auto* buf = new uint8_t[s];
|
||||
|
||||
auto* m = MSpaceCreate("test", buf, s, true, test_callback);
|
||||
|
||||
EXPECT_NE(m, nullptr);
|
||||
|
||||
auto* ptr = static_cast<uint8_t*>(MSpaceMalloc(m, 56));
|
||||
EXPECT_NE(ptr, nullptr);
|
||||
EXPECT_TRUE(ptr > buf && ptr < buf + s);
|
||||
|
||||
g_size = 0;
|
||||
g_ptr = nullptr;
|
||||
auto* ptr2 = static_cast<uint8_t*>(MSpaceMalloc(m, 460));
|
||||
EXPECT_EQ(ptr2, nullptr);
|
||||
EXPECT_EQ(g_size, 460u);
|
||||
|
||||
g_size = 0;
|
||||
g_ptr = ptr;
|
||||
ptr2 = static_cast<uint8_t*>(MSpaceMalloc(m, 460));
|
||||
EXPECT_NE(ptr2, nullptr);
|
||||
EXPECT_TRUE(ptr2 > buf && ptr2 < buf + s);
|
||||
|
||||
EXPECT_TRUE(MSpaceFree(m, ptr2));
|
||||
|
||||
g_size = 0;
|
||||
g_ptr = nullptr;
|
||||
ptr2 = static_cast<uint8_t*>(MSpaceRealloc(m, nullptr, 60));
|
||||
EXPECT_NE(ptr2, nullptr);
|
||||
EXPECT_TRUE(ptr2 > buf && ptr2 < buf + s);
|
||||
ptr2 = static_cast<uint8_t*>(MSpaceRealloc(m, ptr2, 160));
|
||||
EXPECT_NE(ptr2, nullptr);
|
||||
EXPECT_TRUE(ptr2 > buf && ptr2 < buf + s);
|
||||
|
||||
EXPECT_TRUE(MSpaceDestroy(m));
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
static void test_align()
|
||||
{
|
||||
uint32_t s = Rand::UintInclusiveRange(5000, 20000) & ~0x7u;
|
||||
auto* buf = new uint8_t[s];
|
||||
|
||||
auto* m = MSpaceCreate("test", buf, s, true, nullptr);
|
||||
|
||||
EXPECT_NE(m, nullptr);
|
||||
|
||||
// printf("buf = %016" PRIx64 ", %u\n", reinterpret_cast<uint64_t>(buf), s);
|
||||
|
||||
int iter_num = Rand::IntInclusiveRange(10, 20);
|
||||
|
||||
for (int i = 0; i < iter_num; i++)
|
||||
{
|
||||
uint32_t size = Rand::UintInclusiveRange(1, 64);
|
||||
uint32_t size_r = Rand::UintInclusiveRange(32, 128);
|
||||
auto* buf32 = MSpaceMalloc(m, size);
|
||||
auto* buf32_r = MSpaceRealloc(m, buf32, size_r);
|
||||
auto addr32 = reinterpret_cast<uint64_t>(buf32);
|
||||
auto addr32_r = reinterpret_cast<uint64_t>(buf32_r);
|
||||
// printf("%016" PRIx64 ", %u => %016" PRIx64 ", %u\n", addr32, size, addr32_r, size_r);
|
||||
EXPECT_NE(addr32, 0u);
|
||||
EXPECT_EQ(addr32 & 0x1fu, 0u);
|
||||
EXPECT_NE(addr32_r, 0u);
|
||||
EXPECT_EQ(addr32_r & 0x1fu, 0u);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(MSpaceDestroy(m));
|
||||
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
struct TestRecord
|
||||
{
|
||||
uint8_t* buf = nullptr;
|
||||
uint8_t pattern = 0;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
|
||||
static void test_fill()
|
||||
{
|
||||
uint32_t s = Rand::UintInclusiveRange(2000, 10000) & ~0x7u;
|
||||
auto* buf = new uint8_t[s];
|
||||
|
||||
auto* m = MSpaceCreate("test", buf, s, true, nullptr);
|
||||
EXPECT_NE(m, nullptr);
|
||||
|
||||
Vector<TestRecord> rs;
|
||||
|
||||
for (int step = 0; step < 5; step++)
|
||||
{
|
||||
int add = 0;
|
||||
int del = 0;
|
||||
int rea = 0;
|
||||
for (;;)
|
||||
{
|
||||
uint32_t size = Rand::UintInclusiveRange(1, 200);
|
||||
auto* buf32 = static_cast<uint8_t*>(MSpaceMalloc(m, size));
|
||||
if (buf32 == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
uint8_t pattern = Rand::UintInclusiveRange(0, 255);
|
||||
memset(buf32, pattern, size);
|
||||
|
||||
TestRecord r {};
|
||||
r.buf = buf32;
|
||||
r.pattern = pattern;
|
||||
r.size = size;
|
||||
|
||||
rs.Add(r);
|
||||
add++;
|
||||
}
|
||||
|
||||
for (auto& r: rs)
|
||||
{
|
||||
if (r.buf != nullptr && (Rand::Uint() % 8) == 0)
|
||||
{
|
||||
MSpaceFree(m, r.buf);
|
||||
r.buf = nullptr;
|
||||
del++;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& r: rs)
|
||||
{
|
||||
if (r.buf != nullptr && (Rand::Uint() % 4) == 0)
|
||||
{
|
||||
auto* n = static_cast<uint8_t*>(MSpaceRealloc(m, r.buf, r.size + Rand::UintInclusiveRange(1, 200)));
|
||||
if (n != nullptr)
|
||||
{
|
||||
r.buf = n;
|
||||
rea++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// printf("add = %d, del = %d, rea = %d\n", add, del, rea);
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
for (const auto& r: rs)
|
||||
{
|
||||
if (r.buf != nullptr)
|
||||
{
|
||||
for (uint32_t i = 0; i < r.size; i++)
|
||||
{
|
||||
if (r.pattern != r.buf[i])
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(ok);
|
||||
|
||||
EXPECT_TRUE(MSpaceDestroy(m));
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
TEST(Core, MSpace)
|
||||
{
|
||||
UT_MEM_CHECK_INIT();
|
||||
|
||||
test_fail();
|
||||
test_ok();
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
test_align();
|
||||
test_fill();
|
||||
}
|
||||
|
||||
UT_MEM_CHECK();
|
||||
}
|
||||
|
||||
UT_END();
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user