specify the intersection functions default tip

Sat, 01 Nov 2025 19:48:50 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 01 Nov 2025 19:48:50 +0100
changeset 1465
dc886f1a6155
parent 1464
9a10af83cfab

specify the intersection functions

relates to #554 and issue #555

CHANGELOG file | annotate | diff | comparison | revisions
docs/Writerside/topics/about.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/list.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/map.h.md file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/cx/map.h file | annotate | diff | comparison | revisions
--- a/CHANGELOG	Sat Nov 01 19:31:48 2025 +0100
+++ b/CHANGELOG	Sat Nov 01 19:48:50 2025 +0100
@@ -8,6 +8,7 @@
  * adds support for comparing arbitrary strings without explicit call to cx_strcast()
  * adds cxListClone() and cxMapClone()
  * adds cxListDifference(), cxMapDifference(), and cxMapListDifference()
+ * adds cxListIntersection(), cxMapIntersection(), and cxMapListIntersection()
  * adds cxListContains() and cxMapContains()
  * adds cxListSet()
  * adds cxListFirst() and cxListLast()
--- a/docs/Writerside/topics/about.md	Sat Nov 01 19:31:48 2025 +0100
+++ b/docs/Writerside/topics/about.md	Sat Nov 01 19:48:50 2025 +0100
@@ -35,6 +35,7 @@
 * adds support for comparing arbitrary strings without explicit call to cx_strcast()
 * adds cxListClone() and cxMapClone()
 * adds cxListDifference(), cxMapDifference(), and cxMapListDifference()
+* adds cxListIntersection(), cxMapIntersection(), and cxMapListIntersection()
 * adds cxListContains() and cxMapContains()
 * adds cxListSet()
 * adds cxListFirst() and cxListLast()
--- a/docs/Writerside/topics/list.h.md	Sat Nov 01 19:31:48 2025 +0100
+++ b/docs/Writerside/topics/list.h.md	Sat Nov 01 19:48:50 2025 +0100
@@ -374,6 +374,12 @@
         cx_clone_func clone_func,
         const CxAllocator *clone_allocator,
         void *data);
+        
+int cxListIntersection(CxList *dst,
+        const CxList *src, const CxList *other,
+        cx_clone_func clone_func,
+        const CxAllocator *clone_allocator,
+        void *data);
 ```
 
 With `cxListClone()` you can create deep copies of the elements in a list and insert them into another list.
@@ -382,8 +388,9 @@
 to insert anything.
 
 The function `cxListDifference()` is similar to `cxListClone()`,
-except that it only clones elements from the minuend that are _not_ contained in the subtrahend.
-It is optimized for sorted lists, in which case it will take linear time instead of quadratic time for the operation.
+except that it only clones elements from the minuend that are _not_ contained in the subtrahend,
+while `cxListIntersection()` only clones elements that _are_ contained in both lists.
+Both functions are optimized for sorted lists, in which case they will take linear time instead of quadratic time for the operation.
 
 Refer to the documentation of the [clone-function callback](allocator.h.md#clone-function) to learn how to implement it.
 
--- a/docs/Writerside/topics/map.h.md	Sat Nov 01 19:31:48 2025 +0100
+++ b/docs/Writerside/topics/map.h.md	Sat Nov 01 19:48:50 2025 +0100
@@ -312,6 +312,18 @@
         cx_clone_func clone_func,
         const CxAllocator *clone_allocator,
         void *data);
+
+int cxMapIntersection(CxMap *dst,
+        const CxMap *src, const CxMap *other,
+        cx_clone_func clone_func,
+        const CxAllocator *clone_allocator,
+        void *data);
+
+int cxMapListIntersection(CxMap *dst,
+        const CxMap *src, const CxList *keys,
+        cx_clone_func clone_func,
+        const CxAllocator *clone_allocator,
+        void *data);
 ```
 
 With `cxMapClone()` you can create deep copies of the values in one map and insert them into another map.
@@ -323,6 +335,8 @@
 except that they only clone an element from the source map, when the key is _not_ contained in the
 other map (or list, respectively).
 This is equivalent to computing the set difference for the set of keys.
+Likewise, `cxMapIntersection()` and `cxMapListIntersection()` only clone an element from the source map,
+when the key is contained in _both_ collections.
 
 Refer to the documentation of the [clone-function callback](allocator.h.md#clone-function) to learn how to implement it.
 
--- a/src/cx/list.h	Sat Nov 01 19:31:48 2025 +0100
+++ b/src/cx/list.h	Sat Nov 01 19:48:50 2025 +0100
@@ -1011,6 +1011,28 @@
         const CxList *minuend, const CxList *subtrahend,
         cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
 
+/**
+ * Clones elements from a list only if they are also present in another list.
+ *
+ * This function is optimized for the case when both the @p minuend and the
+ * @p subtrahend are sorted.
+ *
+ * If the destination list already contains elements, the intersection is appended
+ * to that list.
+ *
+ * @param dst the destination list
+ * @param src the list to clone the elements from
+ * @param other the list to check the elements for existence
+ * @param clone_func the clone function for the elements
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3)
+CX_EXPORT int cxListIntersection(CxList *dst, const CxList *src, const CxList *other,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
--- a/src/cx/map.h	Sat Nov 01 19:31:48 2025 +0100
+++ b/src/cx/map.h	Sat Nov 01 19:48:50 2025 +0100
@@ -545,6 +545,44 @@
 CX_EXPORT int cxMapListDifference(CxMap *dst, const CxMap *src, const CxList *keys,
         cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
 
+
+/**
+ * Clones entries of a map only if their key is present in another map.
+ *
+ * @param dst the destination map
+ * @param src the map to clone the entries from
+ * @param other the map to check for existence of the keys
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapIntersection(CxMap *dst, const CxMap *src, const CxMap *other,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
+/**
+ * Clones entries of a map only if their key is present in a list.
+ *
+ * Note that the list must contain keys of type @c CxKey
+ * (or pointers to such keys) and must use @c cx_hash_key_cmp
+ * as the compare function.
+ * Generic key types cannot be processed in this case.
+ *
+ * @param dst the destination map
+ * @param src the source map
+ * @param keys the list of @c CxKey items
+ * @param clone_func the clone function for the values
+ * @param clone_allocator the allocator that is passed to the clone function
+ * @param data optional additional data that is passed to the clone function
+ * @retval zero when the elements were successfully cloned
+ * @retval non-zero when an allocation error occurred
+ */
+cx_attr_nonnull_arg(1, 2, 3, 4)
+CX_EXPORT int cxMapListIntersection(CxMap *dst, const CxMap *src, const CxList *keys,
+        cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
+
 #ifdef    __cplusplus
 } // extern "C"
 #endif

mercurial