diff -r 31c61b6dcaa5 -r dc88d2ece7e4 src/cx/map.h --- a/src/cx/map.h Fri Aug 15 17:46:47 2025 +0200 +++ b/src/cx/map.h Sun Aug 17 23:05:16 2025 +0200 @@ -185,8 +185,11 @@ /** * Add or overwrite an element. + * If the @p value is @c NULL, the implementation + * shall only allocate memory instead of adding an existing value to the map. + * Returns a pointer to the allocated memory or @c NULL if allocation fails. */ - int (*put)( + void *(*put)( CxMap *map, CxHashKey key, void *value @@ -387,7 +390,7 @@ CxHashKey const &key, void *value ) { - return map->cl->put(map, key, value); + return map->cl->put(map, key, value) == NULL; } cx_attr_nonnull @@ -396,7 +399,7 @@ cxstring const &key, void *value ) { - return map->cl->put(map, cx_hash_key_cxstr(key), value); + return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; } cx_attr_nonnull @@ -405,7 +408,7 @@ cxmutstr const &key, void *value ) { - return map->cl->put(map, cx_hash_key_cxstr(key), value); + return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; } cx_attr_nonnull @@ -415,7 +418,40 @@ const char *key, void *value ) { - return map->cl->put(map, cx_hash_key_str(key), value); + return map->cl->put(map, cx_hash_key_str(key), value) == NULL; +} + +cx_attr_nonnull +static inline void *cxMapEmplace( + CxMap *map, + CxHashKey const &key +) { + return map->cl->put(map, key, NULL); +} + +cx_attr_nonnull +static inline void *cxMapEmplace( + CxMap *map, + cxstring const &key +) { + return map->cl->put(map, cx_hash_key_cxstr(key), NULL); +} + +cx_attr_nonnull +static inline void *cxMapEmplace( + CxMap *map, + cxmutstr const &key +) { + return map->cl->put(map, cx_hash_key_cxstr(key), NULL); +} + +cx_attr_nonnull +cx_attr_cstr_arg(2) +static inline void *cxMapEmplace( + CxMap *map, + const char *key +) { + return map->cl->put(map, cx_hash_key_str(key), NULL); } cx_attr_nonnull @@ -540,7 +576,7 @@ CxHashKey key, void *value ) { - return map->cl->put(map, key, value); + return map->cl->put(map, key, value) == NULL; } /** @@ -552,7 +588,7 @@ cxstring key, void *value ) { - return map->cl->put(map, cx_hash_key_cxstr(key), value); + return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; } /** @@ -564,7 +600,7 @@ cxmutstr key, void *value ) { - return map->cl->put(map, cx_hash_key_cxstr(key), value); + return map->cl->put(map, cx_hash_key_cxstr(key), value) == NULL; } /** @@ -577,7 +613,7 @@ const char *key, void *value ) { - return map->cl->put(map, cx_hash_key_str(key), value); + return map->cl->put(map, cx_hash_key_str(key), value) == NULL; } /** @@ -608,6 +644,77 @@ (map, key, value) /** + * @copydoc cxMapEmplace() + */ +cx_attr_nonnull +static inline void *cx_map_emplace( + CxMap *map, + CxHashKey key +) { + return map->cl->put(map, key, NULL); +} + +/** + * @copydoc cxMapEmplace() + */ +cx_attr_nonnull +static inline void *cx_map_emplace_cxstr( + CxMap *map, + cxstring key +) { + return map->cl->put(map, cx_hash_key_cxstr(key), NULL); +} + +/** + * @copydoc cxMapEmplace() + */ +cx_attr_nonnull +static inline void *cx_map_emplace_mustr( + CxMap *map, + cxmutstr key +) { + return map->cl->put(map, cx_hash_key_cxstr(key), NULL); +} + +/** + * @copydoc cxMapEmplace() + */ +cx_attr_nonnull +cx_attr_cstr_arg(2) +static inline void *cx_map_emplace_str( + CxMap *map, + const char *key +) { + return map->cl->put(map, cx_hash_key_str(key), NULL); +} + +/** + * Allocates memory for a value in the map associated with the specified key. + * + * A possible existing value will be overwritten. + * If destructor functions are specified, they are called for + * the overwritten element. + * + * If the map is storing pointers, this function returns a @c void** pointer, + * meaning a pointer to that pointer. + * + * The @p key is always copied. + * + * @param map (@c CxMap*) the map + * @param key (@c CxHashKey, @c char*, @c cxstring, or @c cxmutstr) the key + * @return the pointer to the allocated memory or @c NULL if allocation fails + * @retval zero success + * @retval non-zero value on memory allocation failure + */ +#define cxMapEmplace(map, key) _Generic((key), \ + CxHashKey: cx_map_emplace, \ + cxstring: cx_map_emplace_cxstr, \ + cxmutstr: cx_map_emplace_mustr, \ + char*: cx_map_emplace_str, \ + const char*: cx_map_emplace_str) \ + (map, key) + +/** * @copydoc cxMapGet() */ cx_attr_nonnull