diff --git a/core/include/clist.h b/core/include/clist.h index 3b2d54e4c7..488c3ec041 100644 --- a/core/include/clist.h +++ b/core/include/clist.h @@ -31,6 +31,7 @@ * clist_find_before() | O(n) | find node return node pointing to node * clist_remove() | O(n) | remove and return node * clist_sort() | O(NlogN)| sort list (stable) + * clist_count() | O(n) | count the number of elements in a list * * clist can be used as a traditional list, a queue (FIFO) and a stack (LIFO) using * fast O(1) operations. @@ -419,6 +420,27 @@ static inline void clist_sort(clist_node_t *list, clist_cmp_func_t cmp) } } +/** + * @brief Count the number of items in the given list + * + * @param[in] list ptr to the first element of the list + * + * @return the number of elements in the given list + */ +static inline size_t clist_count(clist_node_t *list) +{ + clist_node_t *node = list->next; + size_t cnt = 0; + if (node) { + do { + node = node->next; + ++cnt; + } while (node != list->next); + } + + return cnt; +} + #ifdef __cplusplus } #endif diff --git a/tests/unittests/tests-core/tests-core-clist.c b/tests/unittests/tests-core/tests-core-clist.c index bbf5acd9cc..6701bed9a3 100644 --- a/tests/unittests/tests-core/tests-core-clist.c +++ b/tests/unittests/tests-core/tests-core-clist.c @@ -314,6 +314,23 @@ static void test_clist_sort(void) } } +static void test_clist_count(void) +{ + size_t n = clist_count(&test_clist); + TEST_ASSERT(n == 0); + + for (unsigned i = 1; i <= TEST_CLIST_LEN; i++) { + clist_rpush(&test_clist, &tests_clist_buf[i - 1]); + n = clist_count(&test_clist); + TEST_ASSERT(n == i); + } + for (unsigned i = TEST_CLIST_LEN; i > 0; i--) { + clist_lpop(&test_clist); + n = clist_count(&test_clist); + TEST_ASSERT(n == (i - 1)); + } +} + Test *tests_core_clist_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -331,6 +348,7 @@ Test *tests_core_clist_tests(void) new_TestFixture(test_clist_foreach), new_TestFixture(test_clist_sort_empty), new_TestFixture(test_clist_sort), + new_TestFixture(test_clist_count), }; EMB_UNIT_TESTCALLER(core_clist_tests, set_up, NULL,