]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add array_lsearch_ptr[_modifiable]() and array_lsearch_ptr_idx()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 20 Aug 2024 07:35:54 +0000 (10:35 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:39:59 +0000 (10:39 +0200)
src/lib/array.c
src/lib/array.h
src/lib/test-array.c

index 6950248e3128dc5a3838c56e54e42ad682369c2c..7f1cf0958195dc7d75917f08d5023baf87ee16d8 100644 (file)
@@ -164,3 +164,32 @@ const void *array_lsearch_i(const struct array *array, const void *key,
 
        return NULL;
 }
+
+const void *array_lsearch_ptr_i(const struct array *array, const void *key)
+{
+       i_assert(array->element_size == sizeof(key));
+       const void *const *data = array->buffer->data;
+       unsigned int i, count = array_count_i(array);
+
+       for (i = 0; i < count; i++) {
+               if (data[i] == key)
+                       return data[i];
+       }
+       return NULL;
+}
+
+bool array_lsearch_ptr_idx_i(const struct array *array, const void *key,
+                            unsigned int *idx_r)
+{
+       i_assert(array->element_size == sizeof(key));
+       const void *const *data = array->buffer->data;
+       unsigned int i, count = array_count_i(array);
+
+       for (i = 0; i < count; i++) {
+               if (data[i] == key) {
+                       *idx_r = i;
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
index 55bd88bbdbfef23a143764a9b407da8a5a9d19c9..798b7fe39f2597f8ef608f45df44ef7be70f09c3 100644 (file)
@@ -441,4 +441,20 @@ static inline void *array_lsearch_modifiable_i(struct array *array, const void *
        ARRAY_TYPE_CAST_MODIFIABLE(array) \
        ARRAY_SEARCH_CALL(lsearch_modifiable, array, key, cmp)
 
+/* Search a pointer from an array */
+const void *array_lsearch_ptr_i(const struct array *array, const void *key);
+#define array_lsearch_ptr(array, key) \
+       TYPE_CHECKS(const void *, \
+       COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(***(array)->v, *(key)), \
+       array_lsearch_ptr_i(&(array)->arr, key))
+#define array_lsearch_ptr_modifiable(array, key) \
+       (void *)array_lsearch_ptr(array, key)
+
+bool array_lsearch_ptr_idx_i(const struct array *array, const void *key,
+                            unsigned int *idx_r);
+#define array_lsearch_ptr_idx(array, key, idx_r) \
+       TYPE_CHECKS(bool, \
+       COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE(***(array)->v, *(key)), \
+       array_lsearch_ptr_idx_i(&(array)->arr, key, idx_r))
+
 #endif
index e6aade12c4b8bbaaff3ffd82e4e6ea635df2d7c4..a0eeb2970a2e1f367c249ed473a6aa85ce59799b 100644 (file)
@@ -352,6 +352,41 @@ test_array_free(void)
        test_array_free_case(TRUE);
 }
 
+struct test_ptr {
+       int a, b;
+};
+
+static void test_array_lsearch_ptr(void)
+{
+       struct test_ptr input[] = {
+               { 1, 2 },
+               { 3, 4 },
+               { 5, 6 },
+       };
+       struct test_ptr *input_ptr[] = {
+               &input[0],
+               &input[1],
+               &input[2],
+       };
+       ARRAY(struct test_ptr *) array;
+       unsigned int ptr_i;
+
+       test_begin("array_lsearch_ptr()");
+       t_array_init(&array, N_ELEMENTS(input_ptr));
+       array_append(&array, input_ptr, N_ELEMENTS(input_ptr));
+       struct test_ptr *const *output = array_front(&array);
+       for (unsigned int i = 0; i < N_ELEMENTS(input); i++) {
+               test_assert_idx(array_lsearch_ptr(&array, &input[i]) == output[i], i);
+               test_assert_idx(array_lsearch_ptr_idx(&array, &input[i], &ptr_i) && ptr_i == i, i);
+       }
+       struct test_ptr wrong_input = { 0, 0 };
+       test_assert(!array_lsearch_ptr_idx(&array, &wrong_input, &ptr_i));
+       const struct test_ptr *const_input = &wrong_input;
+       test_assert(array_lsearch_ptr(&array, const_input) == NULL);
+       test_assert(!array_lsearch_ptr_idx(&array, const_input, &ptr_i));
+       test_end();
+}
+
 void test_array(void)
 {
        test_array_elem();
@@ -363,6 +398,7 @@ void test_array(void)
        test_array_cmp();
        test_array_cmp_str();
        test_array_free();
+       test_array_lsearch_ptr();
 }
 
 enum fatal_test_state fatal_array(unsigned int stage)