From 65657dd7755d439e221be3eaa7c7b8de473ee5b9 Mon Sep 17 00:00:00 2001 From: Tyge Date: Mon, 20 Apr 2020 07:07:15 +0200 Subject: Fixed and redesigned iterators. --- benchmark.c | 8 ++++++++ stc/cdefs.h | 2 +- stc/cmap.h | 15 ++++----------- stc/cslist.h | 33 ++++++++++++++------------------- stc/cvector.h | 15 +++++++-------- 5 files changed, 34 insertions(+), 39 deletions(-) diff --git a/benchmark.c b/benchmark.c index 9d2583e2..7f4e8cef 100644 --- a/benchmark.c +++ b/benchmark.c @@ -114,4 +114,12 @@ int main() MAP_TEST2(FMAP, ii) MAP_TEST2(RMAP, ii) #endif + + CMap_ix small = cmap_init; + cmap_ix_put(&small, 80, 800); + cmap_ix_put(&small, 10, 100); + cmap_ix_put(&small, 30, 300); + + c_foreach (i, cmap_ix, small) + printf("%d: %d\n", i.item->key, i.item->value); } diff --git a/stc/cdefs.h b/stc/cdefs.h index fa127c28..bf010db9 100644 --- a/stc/cdefs.h +++ b/stc/cdefs.h @@ -54,7 +54,7 @@ #define c_defaultDestroy(p) ((void)0) #define c_foreach(it, ctag, con) \ - for (ctag##_iter_t it = ctag##_begin(con); it.item != ctag##_end(con).item; it = ctag##_next(it)) + for (ctag##_iter_t it = ctag##_begin(&con); it.item; it = ctag##_next(it)) /* One-byte-at-a-time hash based on Murmur's mix */ static inline uint32_t c_defaultHash(const void *data, size_t len) { diff --git a/stc/cmap.h b/stc/cmap.h index f547922e..abf520eb 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -245,26 +245,19 @@ cmap_##tag##_erase(CMap_##tag* self, cmap_##tag##_rawkey_t rawKey) { \ } \ \ static inline cmap_##tag##_iter_t \ -cmap_##tag##_begin(CMap_##tag map) { \ - cmap_##tag##_iter_t null = {NULL, NULL}; \ - if (cmap_size(map) == 0) return null; \ - CMapEntry_##tag* e = map._table.data, *end = e + _cvector_capacity(map._table); \ +cmap_##tag##_begin(CMap_##tag* map) { \ + CMapEntry_##tag* e = map->_table.data, *end = e + _cvector_capacity(map->_table); \ while (e != end && !e->hashx) ++e; \ - cmap_##tag##_iter_t it = {e, end}; return it; \ + return (cmap_##tag##_iter_t) {e == end ? NULL : e, end}; \ } \ \ static inline cmap_##tag##_iter_t \ cmap_##tag##_next(cmap_##tag##_iter_t it) { \ do { ++it.item; } while (it.item != it._end && !it.item->hashx); \ + if (it.item == it._end) it.item = NULL; \ return it; \ } \ \ -static inline cmap_##tag##_iter_t \ -cmap_##tag##_end(CMap_##tag map) { \ - CMapEntry_##tag* end = (cmap_size(map) == 0) ? NULL : map._table.data + _cvector_capacity(map._table); \ - cmap_##tag##_iter_t it = {end, end}; \ - return it; \ -} \ typedef Key cmap_##tag##_key_t; \ typedef Value cmap_##tag##_value_t diff --git a/stc/cslist.h b/stc/cslist.h index bf44d114..48fb3817 100644 --- a/stc/cslist.h +++ b/stc/cslist.h @@ -52,7 +52,7 @@ }; \ \ c_struct (cslist_##tag##_iter_t) { \ - CSListNode_##tag *item, *head; \ + CSListNode_##tag *item, **_last; \ } @@ -93,24 +93,6 @@ while (self->last) \ cslist_##tag##_popFront(self); \ } \ - \ - static inline cslist_##tag##_iter_t \ - cslist_##tag##_begin(CSList_##tag lst) { \ - CSListNode_##tag *head = lst.last ? lst.last->next : NULL; \ - return (cslist_##tag##_iter_t) {head, head}; \ - } \ - \ - static inline cslist_##tag##_iter_t \ - cslist_##tag##_next(cslist_##tag##_iter_t it) { \ - CSListNode_##tag *next = it.item->next; \ - it.item = next != it.head ? next : NULL; \ - return it; \ - } \ - \ - static inline cslist_##tag##_iter_t \ - cslist_##tag##_end(CSList_##tag lst) { \ - return (cslist_##tag##_iter_t) {NULL}; \ - } \ \ static inline int \ cslist_##tag##_sortCmp(const void* x, const void* y) { \ @@ -123,6 +105,19 @@ CSListNode__base* last = cslist_sort_base((CSListNode__base *) self->last, cslist_##tag##_sortCmp); \ self->last = (CSListNode_##tag *) last; \ } \ + \ + static inline cslist_##tag##_iter_t \ + cslist_##tag##_begin(CSList_##tag* lst) { \ + CSListNode_##tag *head = lst->last ? lst->last->next : NULL; \ + return (cslist_##tag##_iter_t) {head, &lst->last}; \ + } \ + \ + static inline cslist_##tag##_iter_t \ + cslist_##tag##_next(cslist_##tag##_iter_t it) { \ + if ((it.item = it.item->next) == (*it._last)->next) \ + it.item = NULL; \ + return it; \ + } \ \ typedef Value cslist_##tag##_value_t diff --git a/stc/cvector.h b/stc/cvector.h index d46905e4..069a335e 100644 --- a/stc/cvector.h +++ b/stc/cvector.h @@ -150,24 +150,23 @@ cvector_##tag##_popBack(CVector_##tag* self) { \ \ \ typedef struct cvector_##tag##_iter_t { \ - Value* item; \ + Value *item, *end; \ } cvector_##tag##_iter_t; \ \ static inline cvector_##tag##_iter_t \ -cvector_##tag##_begin(CVector_##tag vec) { \ - return (cvector_##tag##_iter_t) {vec.data}; \ +cvector_##tag##_begin(CVector_##tag* vec) { \ + cvector_##tag##_iter_t it; \ + it.item = vec->data, it.end = it.item + cvector_size(*vec); \ + if (it.item == it.end) it.item = NULL; \ + return it; \ } \ \ static inline cvector_##tag##_iter_t \ cvector_##tag##_next(cvector_##tag##_iter_t it) { \ - ++it.item; \ + if (++it.item == it.end) it.item = NULL; \ return it; \ } \ \ -static inline cvector_##tag##_iter_t \ -cvector_##tag##_end(CVector_##tag vec) { \ - return (cvector_##tag##_iter_t) {vec.data + cvector_size(vec)}; \ -} \ typedef Value cvector_##tag##_value_t -- cgit v1.2.3