Skip to content

Commit

Permalink
Add function to create new list from iterator.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rot127 committed Oct 23, 2024
1 parent 8dbba03 commit 01ff555
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ AlignConsecutiveMacros: true
AlignTrailingComments: false
AlignOperands: false
Cpp11BracedListStyle: false
ForEachMacros: ['rz_list_foreach', 'rz_list_foreach_safe', 'rz_vector_foreach', 'rz_vector_foreach_prev', 'rz_vector_enumerate', 'rz_pvector_foreach', 'rz_pvector_enumerate', 'rz_rbtree_foreach', 'rz_interval_tree_foreach', 'rz_skiplist_foreach', 'graph_foreach_anode']
ForEachMacros: ['rz_list_foreach', 'rz_list_foreach_enum', 'rz_list_foreach_safe', 'rz_vector_foreach', 'rz_vector_foreach_prev', 'rz_vector_enumerate', 'rz_pvector_foreach', 'rz_pvector_enumerate', 'rz_rbtree_foreach', 'rz_interval_tree_foreach', 'rz_skiplist_foreach', 'graph_foreach_anode']
SortIncludes: false
RequiresClausePosition: SingleLine
TypenameMacros: ['HT_', 'Ht_', 'HtName_']
TypenameMacros: ['HT_', 'Ht_', 'HtName_']
5 changes: 5 additions & 0 deletions librz/include/rz_list.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef RZ_LIST_H
#define RZ_LIST_H

#include <rz_util/rz_iterator.h>
#include <rz_types.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -33,6 +34,9 @@ typedef int (*RzListComparator)(const void *value, const void *list_data, void *
#define rz_list_foreach(list, it, pos) \
if (list) \
for (it = list->head; it && (pos = it->elem, 1); it = it->next)
#define rz_list_foreach_enum(list, it, pos, i) \
if (list) \
for (it = list->head, i = 0; it && (pos = it->elem, 1); it = it->next, ++i)
#define rz_list_foreach_iter(iter, it, pos) \
for (it = iter; it && (pos = it->elem, 1); it = it->next)
/* Safe when calling rz_list_delete() while iterating over the list. */
Expand Down Expand Up @@ -62,6 +66,7 @@ typedef int (*RzListComparator)(const void *value, const void *list_data, void *
RZ_API RZ_OWN RzList *rz_list_new(void);
RZ_API RZ_OWN RzList *rz_list_newf(RZ_NULLABLE RzListFree f);
RZ_API RZ_OWN RzList *rz_list_new_from_array(RZ_NONNULL const void **arr, size_t arr_size);
RZ_API RZ_OWN RzList *rz_list_new_from_iterator(RZ_BORROW RZ_NONNULL RzIterator *iter);
RZ_API RZ_BORROW RzListIter *rz_list_iter_get_prev(RZ_NONNULL RzListIter *iter);
RZ_API RZ_BORROW RzListIter *rz_list_iter_get_next(RZ_NONNULL RzListIter *iter);
RZ_API RZ_BORROW void *rz_list_iter_get_prev_data(RZ_NONNULL RzListIter *iter);
Expand Down
18 changes: 18 additions & 0 deletions librz/util/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,24 @@ RZ_API RZ_OWN RzList *rz_list_new_from_array(RZ_NONNULL const void **arr, size_t
return l;
}

/**
* \brief Allocates a new RzList and adds all elements of the iterator \p iter to it.
* \p iter keeps the ownership over the values.
*
* \return The produced list. Or NULL in case of failure.
**/
RZ_API RZ_OWN RzList *rz_list_new_from_iterator(RZ_BORROW RZ_NONNULL RzIterator *iter) {
RzList *l = rz_list_new();
if (!l) {
return NULL;
}
void **val;
rz_iterator_foreach(iter, val) {
rz_list_append(l, (void *)*val);
}
return l;
}

/**
* \brief Creates a RzListIter element that can be inserted into a RzList
*
Expand Down
26 changes: 26 additions & 0 deletions test/unit/test_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-3.0-only

#include <rz_list.h>
#include <rz_util/ht_up.h>
#include "minunit.h"
#define BUF_LENGTH 100

Expand Down Expand Up @@ -218,6 +219,30 @@ bool test_rz_list_sort5(void) {
mu_end;
}

bool test_rz_list_from_iter(void) {
HtUP *alpha_ht = ht_up_new(NULL, NULL);
char *unordered_alphabeth[] = { "b", "w", "k", "a", "c", "d", "e", "f", "g", "h", "i", "j", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "x", "y", "z" };
char *lower[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };

for (size_t i = 0; i < 26; i++) {
ht_up_insert(alpha_ht, i, (void *)unordered_alphabeth[i]);
}
RzIterator *iter = ht_up_as_iter(alpha_ht);
RzList *list = rz_list_new_from_iterator(iter);
rz_list_sort(list, (RzListComparator)strcmp, NULL);
mu_assert_eq(rz_list_length(list), 26, "Number of elements are off");
RzListIter *it;
const char *elem;
size_t i = 0;
rz_list_foreach_enum(list, it, elem, i) {
mu_assert_streq(elem, lower[i], "Value mismatched.");
}
ht_up_free(alpha_ht);
rz_iterator_free(iter);
rz_list_free(list);
mu_end;
}

// 3-valued comparator -> {LT,EQ,GT}.
static int pintcmp(int *a, int *b, void *user) {
return (int)(*a > *b) - (int)(*b > *a);
Expand Down Expand Up @@ -501,6 +526,7 @@ int all_tests() {
mu_run_test(test_rz_list_reverse);
mu_run_test(test_rz_list_clone);
mu_run_test(test_rz_list_find_ptr);
mu_run_test(test_rz_list_from_iter);
return tests_passed != tests_run;
}

Expand Down

0 comments on commit 01ff555

Please sign in to comment.