utils: RefCountedInternPool/RefCountedMap (#9284)
* utils: RefCountedInternPool/RefCountedMap
First, introduce RefCountedInternPool, a reference counted intern pool of
Slice<const T>. Just acquire() a slice that you want and you're guaranteed to
get exactly one canonical value-equal Slice<const T> back.
Additionally, introduce the concept of NullValue to RefCountedMap. A NullValue
defines what should be considered an uninitialized value; by default, it's the
default value of that type (0 for ints, nullptr for pointers, etc). This allows
us to lazily-initialize values in the map. A client can acquire() a bunch of
different resources which will be initialized only when get(factory) is called.
If a client attempts to get() a value without specifying a factory, and the
value is not initialized (i.e. equal to NullValue{}()), RefCountedMap will
panic.
* utils: add unit tests for ref-counted collections
* utils: remove C++20 features, fix memory issue
* utils: remove RefCounted from InternPool
This commit is contained in:
@@ -77,6 +77,12 @@ TEST(RefCountedMapTest, ValueType_GetsValue) {
|
||||
EXPECT_EQ(v1const, 1);
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, ValueType_CanReleaseNullValue) {
|
||||
RefCountedMap<KeyType, ValueType> map;
|
||||
map.acquire(1);
|
||||
map.release(1, [](ValueType& it) { ADD_FAILURE(); });
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
TEST(RefCountedMapTest, ValueType_PanicsIfReleaseMissing) {
|
||||
RefCountedMap<KeyType, ValueType> map;
|
||||
@@ -87,6 +93,12 @@ TEST(RefCountedMapTest, ValueType_PanicsIfGetsMissing) {
|
||||
RefCountedMap<KeyType, ValueType> map;
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, ValueType_PanicsIfGetsNullValue) {
|
||||
RefCountedMap<KeyType, ValueType> map;
|
||||
map.acquire(1);
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
/* Plain pointer types */
|
||||
@@ -149,6 +161,12 @@ TEST(RefCountedMapTest, PlainPointerType_GetsValue) {
|
||||
delete a1;
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, PlainPointerType_CanReleaseNullValue) {
|
||||
RefCountedMap<KeyType, PlainPointerType> map;
|
||||
map.acquire(1);
|
||||
map.release(1, [](ValueType& it) { ADD_FAILURE(); });
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
TEST(RefCountedMapTest, PlainPointerType_PanicsIfReleaseMissing) {
|
||||
RefCountedMap<KeyType, PlainPointerType> map;
|
||||
@@ -159,6 +177,12 @@ TEST(RefCountedMapTest, PlainPointerType_PanicsIfGetsMissing) {
|
||||
RefCountedMap<KeyType, PlainPointerType> map;
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, PlainPointerType_PanicsIfGetsNullValue) {
|
||||
RefCountedMap<KeyType, PlainPointerType> map;
|
||||
map.acquire(1);
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
/* Smart pointer types */
|
||||
@@ -214,6 +238,12 @@ TEST(RefCountedMapTest, SmartPointerType_GetsValue) {
|
||||
EXPECT_EQ(v1const, 1);
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, SmartPointerType_CanReleaseNullValue) {
|
||||
RefCountedMap<KeyType, SmartPointerType> map;
|
||||
map.acquire(1);
|
||||
map.release(1, [](ValueType& it) { ADD_FAILURE(); });
|
||||
}
|
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST
|
||||
TEST(RefCountedMapTest, SmartPointerType_PanicsIfReleaseMissing) {
|
||||
RefCountedMap<KeyType, SmartPointerType> map;
|
||||
@@ -224,4 +254,10 @@ TEST(RefCountedMapTest, SmartPointerType_PanicsIfGetsMissing) {
|
||||
RefCountedMap<KeyType, SmartPointerType> map;
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
|
||||
TEST(RefCountedMapTest, SmartPointerType_PanicsIfGetsNullValue) {
|
||||
RefCountedMap<KeyType, SmartPointerType> map;
|
||||
map.acquire(1);
|
||||
ASSERT_DEATH(map.get(1), "");
|
||||
}
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
Reference in New Issue
Block a user