--- a/tests/test_hash_map.c Fri Aug 15 17:46:47 2025 +0200 +++ b/tests/test_hash_map.c Sun Aug 17 23:05:16 2025 +0200 @@ -79,6 +79,70 @@ cx_testing_allocator_destroy(&talloc); } +CX_TEST(test_hash_map_emplace) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *allocator = &talloc.base; + CX_TEST_DO { + CxMap *map = cxHashMapCreate(allocator, 20, 4); + + char *v = cxMapEmplace(map, "key 1"); + CX_TEST_ASSERT(v != NULL); + strcpy(v, "val 1"); + + char *tv = cxMapGet(map, "key 1"); + CX_TEST_ASSERT(tv != NULL); + CX_TEST_ASSERT(0 == strcmp(tv, "val 1")); + + v = cxMapEmplace(map, "key 1"); + CX_TEST_ASSERT(v != NULL); + CX_TEST_ASSERT(0 != strcmp(v, "val 1")); + + tv = cxMapGet(map, "key 1"); + CX_TEST_ASSERT(tv != NULL); + CX_TEST_ASSERT(0 != strcmp(tv, "val 1")); + + cxMapFree(map); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_hash_map_emplace_pointers) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *allocator = &talloc.base; + CX_TEST_DO { + CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 4); + cxDefineAdvancedDestructor(map, cxFree, allocator); + + char *val1 = cxMalloc(allocator, 8); + strcpy(val1, "val 1"); + char *val2 = cxMalloc(allocator, 8); + strcpy(val2, "val 2"); + + char **v1 = cxMapEmplace(map, "key 1"); + CX_TEST_ASSERT(v1 != NULL); + *v1 = val1; + + char *tv = cxMapGet(map, "key 1"); + CX_TEST_ASSERT(tv != NULL); + CX_TEST_ASSERT(0 == strcmp(tv, "val 1")); + + // this will call the destructor of former v1 + char **v2 = cxMapEmplace(map, "key 1"); + CX_TEST_ASSERT(v2 != NULL); + *v2 = val2; + tv = cxMapGet(map, "key 1"); + CX_TEST_ASSERT(tv != NULL); + CX_TEST_ASSERT(0 == strcmp(tv, "val 2")); + + cxMapFree(map); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + CX_TEST(test_hash_map_rehash) { CxTestingAllocator talloc; cx_testing_allocator_init(&talloc); @@ -731,6 +795,8 @@ cx_test_register(suite, test_hash_map_create); cx_test_register(suite, test_hash_map_create_store_pointers); cx_test_register(suite, test_hash_map_basic_operations); + cx_test_register(suite, test_hash_map_emplace); + cx_test_register(suite, test_hash_map_emplace_pointers); cx_test_register(suite, test_hash_map_rehash); cx_test_register(suite, test_hash_map_rehash_not_required); cx_test_register(suite, test_hash_map_clear);