# HG changeset patch # User Mike Becker # Date 1766574033 -3600 # Node ID e5a8c41ecb58c840765c106b477f25f0fdf3ceb4 # Parent 9c995cba33930123d29e7920acc26b804a23ef85 adds support for CxHashKey pointers in CX_HASH_KEY() and all map functions diff -r 9c995cba3393 -r e5a8c41ecb58 CHANGELOG --- a/CHANGELOG Wed Dec 24 11:53:40 2025 +0100 +++ b/CHANGELOG Wed Dec 24 12:00:33 2025 +0100 @@ -10,6 +10,7 @@ * adds cxMapCompare() * adds line continuation support to CxProperties / CxPropertiesConfig * adds cx_hash_key_as_string() + * adds support for CxHashKey pointers in CX_HASH_KEY() and all map functions * adds cx_bstr() and cx_bstr_m() * adds cxBufferMaximumCapacity() * adds cxBufferAppendString() diff -r 9c995cba3393 -r e5a8c41ecb58 docs/Writerside/topics/about.md --- a/docs/Writerside/topics/about.md Wed Dec 24 11:53:40 2025 +0100 +++ b/docs/Writerside/topics/about.md Wed Dec 24 12:00:33 2025 +0100 @@ -37,6 +37,7 @@ * adds cxMapCompare() * adds line continuation support to CxProperties / CxPropertiesConfig * adds cx_hash_key_as_string() +* adds support for CxHashKey pointers in CX_HASH_KEY() and all map functions * adds cx_bstr() and cx_bstr_m() * adds cxBufferMaximumCapacity() * adds cxBufferAppendString() diff -r 9c995cba3393 -r e5a8c41ecb58 src/cx/hash_key.h --- a/src/cx/hash_key.h Wed Dec 24 11:53:40 2025 +0100 +++ b/src/cx/hash_key.h Wed Dec 24 12:00:33 2025 +0100 @@ -192,18 +192,30 @@ * You should never need to use this manually. * * @param key the key - * @return a copy of the key + * @return a copy of the key (not the data) */ cx_attr_nodiscard CX_INLINE CxHashKey cx_hash_key_identity(CxHashKey key) { return key; } +/** + * The dereference function for the CX_HASH_KEY() macro. + * You should never need to use this manually. + * + * @param key a pointer to a key + * @return a copy of the key (not the data) + */ +cx_attr_nodiscard +CX_INLINE CxHashKey cx_hash_key_deref(const CxHashKey *key) { + return *key; +} + #ifndef __cplusplus /** * Creates a hash key from any of the supported types with implicit length. * - * Does nothing when passing a CxHashkey. + * Does nothing when passing a CxHashKey and dereferences CxHashKey pointers. * * Supported types are UCX strings, zero-terminated C strings, * and 32-bit or 64-bit unsigned integers. @@ -212,6 +224,8 @@ * @returns the @c CxHashKey */ #define CX_HASH_KEY(key) _Generic((key), \ + CxHashKey*: cx_hash_key_deref, \ + const CxHashKey*: cx_hash_key_deref, \ CxHashKey: cx_hash_key_identity, \ cxstring: cx_hash_key_cxstr, \ cxmutstr: cx_hash_key_mutstr, \ @@ -255,6 +269,10 @@ return key; } +CX_CPPDECL CxHashKey CX_HASH_KEY(const CxHashKey *key) { + return *key; +} + CX_CPPDECL CxHashKey CX_HASH_KEY(cxstring str) { return cx_hash_key_cxstr(str); } diff -r 9c995cba3393 -r e5a8c41ecb58 tests/test_hash_key.c --- a/tests/test_hash_key.c Wed Dec 24 11:53:40 2025 +0100 +++ b/tests/test_hash_key.c Wed Dec 24 12:00:33 2025 +0100 @@ -61,6 +61,21 @@ } } +CX_TEST(test_hash_key_from_pointer_to_another_key) { + CxHashKey k = CX_HASH_KEY("one key"); + CX_TEST_DO { + const CxHashKey *p1 = &k; + CxHashKey *p2 = &k; + CxHashKey k1 = CX_HASH_KEY(p1); + CxHashKey k2 = CX_HASH_KEY(p2); + CX_TEST_ASSERT(0 == cx_hash_key_cmp(&k, &k1)); + CX_TEST_ASSERT(0 == cx_hash_key_cmp(&k, &k2)); + // check that this did not copy the data + CX_TEST_ASSERT(k.data == k1.data); + CX_TEST_ASSERT(k.data == k2.data); + } +} + CX_TEST(test_hash_key_int_functions) { uint32_t a = 0xabc01337u; uint64_t b = 0xabc0133747110815ull; @@ -177,6 +192,7 @@ CxTestSuite *suite = cx_test_suite_new("hash_key"); cx_test_register(suite, test_hash_key_functions); + cx_test_register(suite, test_hash_key_from_pointer_to_another_key); cx_test_register(suite, test_hash_key_int_functions); cx_test_register(suite, test_hash_key_macro); cx_test_register(suite, test_hash_key_cmp);