src/cx/map.h

changeset 1341
dc88d2ece7e4
parent 1180
4c3a69b9723a
--- 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

mercurial