From fa7349b626d4466bab2fe280b0682da5b65c886f Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 20 Aug 2024 10:35:54 +0300 Subject: [PATCH] lib: Add array_lsearch_ptr[_modifiable]() and array_lsearch_ptr_idx() --- src/lib/array.c | 29 +++++++++++++++++++++++++++++ src/lib/array.h | 16 ++++++++++++++++ src/lib/test-array.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/src/lib/array.c b/src/lib/array.c index 6950248e31..7f1cf09581 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -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; +} diff --git a/src/lib/array.h b/src/lib/array.h index 55bd88bbdb..798b7fe39f 100644 --- a/src/lib/array.h +++ b/src/lib/array.h @@ -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 diff --git a/src/lib/test-array.c b/src/lib/test-array.c index e6aade12c4..a0eeb2970a 100644 --- a/src/lib/test-array.c +++ b/src/lib/test-array.c @@ -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) -- 2.47.3