mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 04:01:32 -06:00

* Speedups: remove dependency on c++ * Speedups: intset: handle malloc failing * Speedups: intset: fix corner case for int64 on 32bit systems original idea was to only use bucket->val if int<pointer, but we always have a union now anyway * Speedups: add size comment to player_set bucket configuration * test: more tests for LocationStore.find_item * test: require _speedups in CI This kind of tests that the build succeeds. * test: even more tests for LocationStore.find_item * Speedups: intset uniform comment style * Speedups: intset: avoid memory leak when realloc fails * Speedups: intset: make `gcc -pedantic -std=c99 -fanalyzer` without warnings Unnamed unions are not in C99, this got fixed. The overhead of setting count=0 is minimal or optimized-out and silences -fanalizer (see comment). * Speedups: don't leak memory in case of exception * Speedups: intset: validate alloc and free This won't happen in our cython, but it's still a good addition. * CI: add test framework for C/C++ code * CI: ctest: fix cwd * Speedups: intset: ignore msvc warning * Tests: intset: revert attempt at no-asan We solve this with env vars in ctest now, and this fails for msvc. * Test: cpp: docs: fix typo * Test: cpp: docs: fix another typo * Test: intset: proper bucket count for Negative test INTxx_MIN % 1 would not produce a negative number, so the test was flawed.
106 lines
2.7 KiB
C++
106 lines
2.7 KiB
C++
#include <limits>
|
|
#include <cstdint>
|
|
#include <gtest/gtest.h>
|
|
|
|
// uint32Set
|
|
#define INTSET_NAME uint32Set
|
|
#define INTSET_TYPE uint32_t
|
|
#include "../../../intset.h"
|
|
#undef INTSET_NAME
|
|
#undef INTSET_TYPE
|
|
|
|
// int64Set
|
|
#define INTSET_NAME int64Set
|
|
#define INTSET_TYPE int64_t
|
|
#include "../../../intset.h"
|
|
|
|
|
|
TEST(IntsetTest, ZeroBuckets)
|
|
{
|
|
// trying to allocate with zero buckets has to either fail or be functioning
|
|
uint32Set *set = uint32Set_new(0);
|
|
if (!set)
|
|
return; // failed -> OK
|
|
|
|
EXPECT_FALSE(uint32Set_contains(set, 1));
|
|
EXPECT_TRUE(uint32Set_add(set, 1));
|
|
EXPECT_TRUE(uint32Set_contains(set, 1));
|
|
uint32Set_free(set);
|
|
}
|
|
|
|
TEST(IntsetTest, Duplicate)
|
|
{
|
|
// adding the same number again can't fail
|
|
uint32Set *set = uint32Set_new(2);
|
|
ASSERT_TRUE(set);
|
|
EXPECT_TRUE(uint32Set_add(set, 0));
|
|
EXPECT_TRUE(uint32Set_add(set, 0));
|
|
EXPECT_TRUE(uint32Set_contains(set, 0));
|
|
uint32Set_free(set);
|
|
}
|
|
|
|
TEST(IntsetTest, SetAllocFailure)
|
|
{
|
|
// try to allocate 100TB of RAM, should fail and return NULL
|
|
if (sizeof(size_t) < 8)
|
|
GTEST_SKIP() << "Alloc error not testable on 32bit";
|
|
int64Set *set = int64Set_new(6250000000000ULL);
|
|
EXPECT_FALSE(set);
|
|
int64Set_free(set);
|
|
}
|
|
|
|
TEST(IntsetTest, SetAllocOverflow)
|
|
{
|
|
// try to overflow argument passed to malloc
|
|
int64Set *set = int64Set_new(std::numeric_limits<size_t>::max());
|
|
EXPECT_FALSE(set);
|
|
int64Set_free(set);
|
|
}
|
|
|
|
TEST(IntsetTest, NullFree)
|
|
{
|
|
// free(NULL) should not try to free buckets
|
|
uint32Set_free(NULL);
|
|
int64Set_free(NULL);
|
|
}
|
|
|
|
TEST(IntsetTest, BucketRealloc)
|
|
{
|
|
// add a couple of values to the same bucket to test growing the bucket
|
|
uint32Set* set = uint32Set_new(1);
|
|
ASSERT_TRUE(set);
|
|
EXPECT_FALSE(uint32Set_contains(set, 0));
|
|
EXPECT_TRUE(uint32Set_add(set, 0));
|
|
EXPECT_TRUE(uint32Set_contains(set, 0));
|
|
for (uint32_t i = 1; i < 32; ++i) {
|
|
EXPECT_TRUE(uint32Set_add(set, i));
|
|
EXPECT_TRUE(uint32Set_contains(set, i - 1));
|
|
EXPECT_TRUE(uint32Set_contains(set, i));
|
|
EXPECT_FALSE(uint32Set_contains(set, i + 1));
|
|
}
|
|
uint32Set_free(set);
|
|
}
|
|
|
|
TEST(IntSet, Max)
|
|
{
|
|
constexpr auto n = std::numeric_limits<uint32_t>::max();
|
|
uint32Set *set = uint32Set_new(1);
|
|
ASSERT_TRUE(set);
|
|
EXPECT_FALSE(uint32Set_contains(set, n));
|
|
EXPECT_TRUE(uint32Set_add(set, n));
|
|
EXPECT_TRUE(uint32Set_contains(set, n));
|
|
uint32Set_free(set);
|
|
}
|
|
|
|
TEST(InsetTest, Negative)
|
|
{
|
|
constexpr auto n = std::numeric_limits<int64_t>::min();
|
|
static_assert(n < 0, "n not negative");
|
|
int64Set *set = int64Set_new(3);
|
|
ASSERT_TRUE(set);
|
|
EXPECT_FALSE(int64Set_contains(set, n));
|
|
EXPECT_TRUE(int64Set_add(set, n));
|
|
EXPECT_TRUE(int64Set_contains(set, n));
|
|
int64Set_free(set);
|
|
}
|