add full generic support for cx_strsplit() default tip

Tue, 30 Dec 2025 13:50:55 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 30 Dec 2025 13:50:55 +0100
changeset 1680
1aa21afb8763
parent 1679
4a08dabe5e8f

add full generic support for cx_strsplit()

resolves #792

docs/Writerside/topics/string.h.md file | annotate | diff | comparison | revisions
src/cx/string.h file | annotate | diff | comparison | revisions
tests/test_string.c file | annotate | diff | comparison | revisions
--- a/docs/Writerside/topics/string.h.md	Mon Dec 29 11:21:16 2025 +0100
+++ b/docs/Writerside/topics/string.h.md	Tue Dec 30 13:50:55 2025 +0100
@@ -225,19 +225,12 @@
 ```C
 #include <cx/string.h>
 
-size_t cx_strsplit(cxstring string, AnyStr delim,
-        size_t limit, cxstring *output);
+size_t cx_strsplit(UcxStr string, AnyStr delim,
+        size_t limit, UcxStr *output);
 
 size_t cx_strsplit_a(const CxAllocator *allocator,
-        cxstring string, AnyStr delim,
-        size_t limit, cxstring **output);
-
-size_t cx_strsplit_m(cxmutstr string, AnyStr delim,
-        size_t limit, cxmutstr *output);
-
-size_t cx_strsplit_ma(const CxAllocator *allocator,
-        cxmutstr string, AnyStr delim,
-        size_t limit, cxmutstr **output);
+        UcxStr string, AnyStr delim,
+        size_t limit, UcxStr **output);
 ```
 
 The `cx_strsplit()` function splits the input `string` using the specified delimiter `delim`
@@ -249,10 +242,10 @@
 On the other hand, `cx_strsplit_a()` uses the specified `allocator` to allocate the output array,
 and writes the pointer to the allocated memory to `output`.
 
-The functions `cx_strsplit_m()` and `cx_strsplit_ma()` are equivalent to `cx_strsplit()` and `cx_strsplit_a()`,
-except that they work on `cxmustr` instead of `cxstring`.
+> The type of the `UcxStr` must the same for `string` and `output` (i.e., either both `cxstring` or both `cxmutstr`). 
+> {style="note"}
 
-> The `allocator` in `cx_strsplit_a()` and `cx_strsplit_ma()` is _only_ used to allocate the output array.
+> The `allocator` in `cx_strsplit_a()` is _only_ used to allocate the output array.
 > The strings will always point into the original `string`
 > and you need to use `cx_strdup()` or `cx_strdup_a()` if you want copies or zero-terminated strings after performing the split.  
 {style="note"}
--- a/src/cx/string.h	Mon Dec 29 11:21:16 2025 +0100
+++ b/src/cx/string.h	Tue Dec 30 13:50:55 2025 +0100
@@ -882,20 +882,46 @@
         cxmutstr string, cxstring delim, size_t limit,
         cxmutstr **output);
 
+#ifdef __cplusplus
+CX_CPPDECL size_t cx_strsplit_cpp_(cxstring string, cxstring delim,
+        size_t limit, cxstring *output) {
+    return cx_strsplit_(string, delim, limit, output);
+}
+CX_CPPDECL size_t cx_strsplit_cpp_(cxmutstr string, cxstring delim,
+        size_t limit, cxmutstr *output) {
+    return cx_strsplit_m_(string, delim, limit, output);
+}
+CX_CPPDECL size_t cx_strsplit_a_cpp_(const CxAllocator *allocator,
+        cxstring string, cxstring delim, size_t limit, cxstring **output) {
+    return cx_strsplit_a_(allocator, string, delim, limit, output);
+}
+CX_CPPDECL size_t cx_strsplit_a_cpp_(const CxAllocator *allocator,
+        cxmutstr string, cxstring delim, size_t limit, cxmutstr **output) {
+    return cx_strsplit_ma_(allocator, string, delim, limit, output);
+}
+#define cx_strsplit(string, delim, limit, output) \
+        cx_strsplit_cpp_(cx_strcast_m(string), cx_strcast(delim), limit, output)
+#define cx_strsplit_a(allocator, string, delim, limit, output) \
+        cx_strsplit_a_cpp_(allocator, cx_strcast_m(string), cx_strcast(delim), limit, output)
+#else
 /**
  * Splits a given string using a delimiter string.
  *
  * @note The resulting array contains strings that point to the source
  * @p string. Use cx_strdup() to get copies.
  *
- * @param string (@c cxstring) the string to split
+ * @param string the string to split
  * @param delim the delimiter
  * @param limit (@c size_t) the maximum number of split items
- * @param output (@c cxstring*) a preallocated array of at least @p limit length
+ * @param output (@c cxstring* or @c cxmutstr*) a preallocated array of at
+ * least @p limit length
  * @return the actual number of split items
  */
 #define cx_strsplit(string, delim, limit, output) \
-        cx_strsplit_(string, cx_strcast(delim), limit, output)
+        _Generic(cx_strcast_m(string), \
+        cxstring: cx_strsplit_, \
+        cxmutstr: cx_strsplit_m_)\
+        (cx_strcast_m(string), cx_strcast(delim), limit, output)
 
 /**
  * Splits a given string using a delimiter string.
@@ -909,53 +935,19 @@
  * @p output and the number returned will be zero.
  *
  * @param allocator (@c CxAllocator*) the allocator to use for allocating the resulting array
- * @param string (@c cxstring) the string to split
+ * @param string the string to split
  * @param delim  the delimiter
  * @param limit (@c size_t) the maximum number of split items
- * @param output (@c cxstring**) a pointer where the address of the allocated
- * array shall be written to
+ * @param output (@c cxstring** or @c cxmutstr**) a pointer where the address
+ * of the allocated array shall be written to
  * @return the actual number of split items
  */
 #define cx_strsplit_a(allocator, string, delim, limit, output) \
-        cx_strsplit_a_(allocator, string, cx_strcast(delim), limit, output)
-
-
-/**
- * Splits a given string using a delimiter string.
- *
- * @note The resulting array contains strings that point to the source
- * @p string. Use cx_strdup() to get copies.
- *
- * @param string (@c cxmutstr) the string to split
- * @param delim  the delimiter
- * @param limit (@c size_t) the maximum number of split items
- * @param output (@c cxmutstr*) a preallocated array of at least @p limit length
- * @return the actual number of split items
- */
-#define cx_strsplit_m(string, delim, limit, output) \
-        cx_strsplit_m_(string, cx_strcast(delim), limit, output)
-
-/**
- * Splits a given string using a delimiter string.
- *
- * The array pointed to by @p output will be allocated by @p allocator.
- *
- * @note The resulting array contains strings that point to the source
- * @p string. Use cx_strdup() to get copies.
- *
- * @attention If allocation fails, the @c NULL pointer will be written to
- * @p output and the number returned will be zero.
- *
- * @param allocator (@c CxAllocator*) the allocator to use for allocating the resulting array
- * @param string (@c cxmutstr) the string to split
- * @param delim  the delimiter
- * @param limit (@c size_t) the maximum number of split items
- * @param output (@c cxmutstr**) a pointer where the address of the allocated
- * array shall be written to
- * @return the actual number of split items
- */
-#define cx_strsplit_ma(allocator, string, delim, limit, output) \
-        cx_strsplit_ma_(allocator, string, cx_strcast(delim), limit, output)
+        _Generic(cx_strcast_m(string), \
+        cxstring: cx_strsplit_a_, \
+        cxmutstr: cx_strsplit_ma_)\
+        (allocator, cx_strcast_m(string), cx_strcast(delim), limit, output)
+#endif
 
 /**
  * Compares two strings.
--- a/tests/test_string.c	Mon Dec 29 11:21:16 2025 +0100
+++ b/tests/test_string.c	Tue Dec 30 13:50:55 2025 +0100
@@ -702,10 +702,10 @@
         CX_TEST_ASSERT(0 == cx_strcmp(list[1], ""));
         CX_TEST_ASSERT(0 == cx_strcmp(list[2], "a,csv,string"));
 
-        // call the _m variant just for coverage
+        // test with a cxmutstr
         cxmutstr mtest = cx_strdup(test);
         cxmutstr mlist[4];
-        n = cx_strsplit_m(mtest, "is,", 4, mlist);
+        n = cx_strsplit(mtest, "is,", 4, mlist);
         CX_TEST_ASSERT(n == 3);
         CX_TEST_ASSERT(0 == cx_strcmp(mlist[0], "th"));
         CX_TEST_ASSERT(0 == cx_strcmp(mlist[1], ""));
@@ -818,10 +818,10 @@
         CX_TEST_ASSERT(0 == cx_strcmp(list[2], "a,csv,string"));
         cxFree(alloc, list);
 
-        // call the _m variant just for coverage
+        // test with a cxmutstr
         cxmutstr mtest = cx_strdup(test);
         cxmutstr *mlist;
-        n = cx_strsplit_ma(alloc, mtest, "is,", 4, &mlist);
+        n = cx_strsplit_a(alloc, mtest, "is,", 4, &mlist);
         CX_TEST_ASSERT(n == 3);
         CX_TEST_ASSERT(0 == cx_strcmp(mlist[0], "th"));
         CX_TEST_ASSERT(0 == cx_strcmp(mlist[1], ""));

mercurial