From c42c18bb94606b45454da937690f872b5ebd59d1 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 5 Sep 2020 12:30:26 +0200 Subject: Added range iterators. --- examples/bits.c | 2 +- examples/demos.c | 2 +- examples/list.c | 2 +- stc/carray.h | 14 +++++++++++--- stc/cbitset.h | 31 ++++++++++++++++--------------- stc/cdefs.h | 12 ++++++++---- stc/clist.h | 23 ++++++++++++++--------- stc/cmap.h | 12 ++++++++++-- stc/cqueue.h | 4 ++++ stc/cstack.h | 4 ++++ stc/cstr.h | 11 +++++++++-- stc/cvec.h | 15 +++++++++++---- 12 files changed, 90 insertions(+), 42 deletions(-) diff --git a/examples/bits.c b/examples/bits.c index d3554033..28d1cfff 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -28,7 +28,7 @@ int main() { puts("\nIterator:"); printf("%4zu: ", set.size); c_foreach (i, cbitset, set) - printf("%d", i.item(i)); + printf("%d", cbitset_itval(i)); puts(""); cbitset_t s2 = cbitset_clone(set); diff --git a/examples/demos.c b/examples/demos.c index 6b2806fa..474e539e 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -86,7 +86,7 @@ void listdemo1() c_foreach (i, clist_ix, nums) printf("value: %d\n", i.item->value); /* merge/append nums2 to nums */ - clist_ix_splice_after(&nums, clist_ix_last(&nums), &nums2); + clist_ix_splice_front(&nums, &nums2); c_foreach (i, clist_ix, nums) printf("spliced: %d\n", i.item->value); diff --git a/examples/list.c b/examples/list.c index 3b46f02b..4eea5620 100644 --- a/examples/list.c +++ b/examples/list.c @@ -29,7 +29,7 @@ int main() { int removed = clist_fx_remove(&list, 30); clist_fx_insert_after(&list, clist_fx_before_begin(&list), 5); // same as push_front() - clist_fx_insert_after(&list, clist_fx_last(&list), 500); // same as push_back() + clist_fx_push_back(&list, 500); clist_fx_push_front(&list, 1964); c_foreach (i, clist_fx, list) printf(" %g", i.item->value); diff --git a/stc/carray.h b/stc/carray.h index a167c58f..86324ff9 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -72,15 +72,23 @@ STC_INLINE size_t _carray3_size(const size_t* zdim) { \ STC_INLINE carray##D##X##_iter_t \ carray##D##X##_begin(carray##D##X* a) { \ - carray##D##X##_iter_t it = {a->data, a->data + carray##D##_size(*a)}; return it; \ + carray##D##X##_iter_t it = {a->data}; return it; \ + } \ + STC_INLINE carray##D##X##_iter_t \ + carray##D##X##_end(carray##D##X* a) { \ + carray##D##X##_iter_t it = {a->data + carray##D##_size(*a)}; return it; \ + } \ + STC_INLINE carray##D##X##_iter_t \ + carray##D##X##_range(carray##D##X##_iter_t start, carray##D##X##_iter_t finish) { \ + start.end = finish.item; return start; \ } \ STC_INLINE void \ - carray##D##X##_next(carray##D##X##_iter_t* it) { ++it->item; } \ + carray##D##X##_next(carray##D##X##_iter_t* it) {++it->item;} \ \ STC_INLINE void \ carray##D##X##_destroy(carray##D##X* self) { \ if (self->_xdim & _carray_OWN) { \ - c_foreach (i, carray##D##X, *self) \ + c_foreach_3 (i, carray##D##X, *self) \ valueDestroy(i.item); \ free(self->data); \ } \ diff --git a/stc/cbitset.h b/stc/cbitset.h index 32659a36..a3268f23 100644 --- a/stc/cbitset.h +++ b/stc/cbitset.h @@ -43,7 +43,6 @@ int main() { #ifndef CBITSET__H__ #define CBITSET__H__ -#include #include "cstr.h" typedef struct cbitset { uint64_t* _arr; size_t size; } cbitset_t; @@ -147,26 +146,28 @@ STC_INLINE cbitset_t cbitset_not(cbitset_t s1) { cbitset_flip_all(&set); return set; } -typedef struct cbitset_iter cbitset_iter_t; -typedef bool(*cbitset_cb)(cbitset_iter_t); -struct cbitset_iter { +typedef struct { cbitset_t *_bs; - cbitset_cb item, end; - size_t pos; -}; + size_t item, end; +} cbitset_iter_t; -STC_INLINE bool cbitset_item(cbitset_iter_t it) { - return cbitset_test(*it._bs, it.pos); -} STC_INLINE cbitset_iter_t cbitset_begin(cbitset_t* self) { - if (self->size == 0) { cbitset_iter_t it = {NULL}; return it; } - cbitset_iter_t it = {self, &cbitset_item, NULL, 0}; - return it; + cbitset_iter_t it = {self, 0}; return it; +} +STC_INLINE cbitset_iter_t +cbitset_end(cbitset_t* self) { + cbitset_iter_t it = {self, self->size}; return it; +} +STC_INLINE cbitset_iter_t +cbitset_range(cbitset_iter_t start, cbitset_iter_t finish) { + start.end = finish.item; return start; } STC_INLINE void -cbitset_next(cbitset_iter_t* it) { - if (++it->pos == it->_bs->size) it->item = NULL; +cbitset_next(cbitset_iter_t* it) {++it->item;} + +STC_INLINE bool cbitset_itval(cbitset_iter_t it) { + return cbitset_test(*it._bs, it.item); } #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) diff --git a/stc/cdefs.h b/stc/cdefs.h index c612eca9..5a407f45 100644 --- a/stc/cdefs.h +++ b/stc/cdefs.h @@ -26,8 +26,8 @@ #include #include #include +#include -#define STC_INLINE static inline #if defined(_MSC_VER) #define STC_FORCE_INLINE static __forceinline #elif defined(__GNUC__) || defined(__clang__) @@ -35,6 +35,7 @@ #else #define STC_FORCE_INLINE static inline #endif +#define STC_INLINE static inline #if defined(STC_HEADER) || defined(STC_IMPLEMENTATION) #define STC_API extern @@ -72,8 +73,12 @@ #define c_default_compare(x, y) c_compare(c_default_less, x, y) #define c_default_destroy(p) ((void)0) -#define c_foreach(it, ctype, container) \ - for (ctype##_iter_t it = ctype##_begin(&container); it.item != it.end; ctype##_next(&it)) +#define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__) + +#define c_foreach_3(it, ctype, container) \ + for (ctype##_iter_t it = ctype##_range(ctype##_begin(&container), ctype##_end(&container)); it.item != it.end; ctype##_next(&it)) +#define c_foreach_4(it, ctype, start, finish) \ + for (ctype##_iter_t it = ctype##_range(start, finish); it.item != it.end; ctype##_next(&it)) #define c_items(...) __VA_ARGS__ #define c_push(container_ptr, ctype, items) do { \ @@ -93,5 +98,4 @@ ctype##_destroy(__arr[i]); \ } while (0) - #endif diff --git a/stc/clist.h b/stc/clist.h index f5713e46..3e1a88b2 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -129,21 +129,24 @@ STC_API size_t _clist_size(const clist_void* self); \ STC_INLINE clist_##X##_iter_t \ clist_##X##_before_begin(clist_##X* self) { \ - clist_##X##_iter_t it = {self->last, self->last, &self->last}; return it; \ + clist_##X##_iter_t it = {self->last, NULL, &self->last}; return it; \ } \ STC_INLINE clist_##X##_iter_t \ clist_##X##_begin(clist_##X* self) { \ - clist_##X##_node_t *head = self->last ? self->last->next : NULL; \ + clist_##X##_node_t* head = self->last ? self->last->next : NULL; \ clist_##X##_iter_t it = {head, NULL, &self->last}; return it; \ } \ STC_INLINE clist_##X##_iter_t \ - clist_##X##_last(clist_##X* self) { \ - clist_##X##_iter_t it = {self->last, NULL, &self->last}; return it; \ + clist_##X##_end(clist_##X* self) { \ + clist_##X##_iter_t it = {NULL, NULL, &self->last}; return it; \ + } \ + STC_INLINE clist_##X##_iter_t \ + clist_##X##_range(clist_##X##_iter_t start, clist_##X##_iter_t finish) { \ + start.end = finish.item; return start; \ } \ STC_INLINE void \ clist_##X##_next(clist_##X##_iter_t* it) { \ - it->end = it->item == *it->_last ? it->item->next : NULL; \ - it->item = it->item->next; \ + it->item = (it->item == *it->_last) ? NULL : it->item->next; \ } \ STC_INLINE clist_##X##_value_t* \ clist_##X##_itval(clist_##X##_iter_t it) {return &it.item->value;} \ @@ -167,7 +170,8 @@ STC_API size_t _clist_size(const clist_void* self); } \ STC_INLINE void \ clist_##X##_splice_back(clist_##X* self, clist_##X* other) { \ - clist_##X##_splice_after(self, clist_##X##_last(self), other); \ + clist_##X##_iter_t last = {self->last, self->last, &self->last}; \ + clist_##X##_splice_after(self, last, other); \ } \ \ STC_API clist_##X##_iter_t \ @@ -220,11 +224,12 @@ STC_API size_t _clist_size(const clist_void* self); STC_API clist_##X##_iter_t \ clist_##X##_insert_after_v(clist_##X* self, clist_##X##_iter_t pos, Value value) { \ _clist_insert_after(self, X, pos.item, value); \ - if (pos.item == self->last && pos.item != pos.end) self->last = entry; \ + if (pos.item == self->last && pos.item == pos.end) self->last = entry; \ pos.item = entry; return pos; \ } \ STC_API clist_##X##_iter_t \ clist_##X##_erase_after(clist_##X* self, clist_##X##_iter_t pos) { \ + assert(pos.end != self->last); \ _clist_erase_after(self, X, pos.item, valueDestroy); \ clist_##X##_next(&pos); return pos; \ } \ @@ -296,7 +301,7 @@ _clist_splice_after(clist_void* self, clist_void_iter_t pos, clist_void* other) clist_void_node_t *next = pos.item->next; pos.item->next = other->last->next; other->last->next = next; - if (pos.item == self->last && pos.item != pos.end) self->last = other->last; + if (pos.item == self->last && pos.item == pos.end) self->last = other->last; } other->last = NULL; } diff --git a/stc/cmap.h b/stc/cmap.h index 9b02849d..3378388a 100644 --- a/stc/cmap.h +++ b/stc/cmap.h @@ -242,12 +242,20 @@ ctype##_##X##_erase(ctype##_##X* self, ctype##_##X##_rawkey_t rawKey); \ STC_INLINE ctype##_##X##_iter_t \ ctype##_##X##_begin(ctype##_##X* self) { \ ctype##_##X##_iter_t it = {self->table, self->table + self->bucket_count, self->_hashx}; \ - if (it._hx) while (*it._hx == 0) ++it.item, ++it._hx; \ + while (it.item != it.end && *it._hx == 0) ++it.item, ++it._hx; \ return it; \ } \ +STC_INLINE ctype##_##X##_iter_t \ +ctype##_##X##_end(ctype##_##X* self) {\ + ctype##_##X##_iter_t it = {self->table + self->bucket_count, NULL, NULL}; return it; \ +} \ +STC_INLINE ctype##_##X##_iter_t \ +ctype##_##X##_range(ctype##_##X##_iter_t start, ctype##_##X##_iter_t finish) {\ + start.end = finish.item; return start; \ +} \ STC_INLINE void \ ctype##_##X##_next(ctype##_##X##_iter_t* it) { \ - while ((++it->item, *++it->_hx == 0)) ; \ + while (++it->item != it->end && *++it->_hx == 0) ; \ } \ CMAP_ONLY_##ctype( STC_INLINE ctype##_##X##_value_t* \ ctype##_##X##_itval(ctype##_##X##_iter_t it) {return &it.item->value;} ) \ diff --git a/stc/cqueue.h b/stc/cqueue.h index 03741c46..b8378e49 100644 --- a/stc/cqueue.h +++ b/stc/cqueue.h @@ -94,6 +94,10 @@ cqueue_##X##_push_n(cqueue_##X *self, const cqueue_##X##_input_t in[], size_t si typedef ctype##_iter_t cqueue_##X##_iter_t; \ STC_INLINE cqueue_##X##_iter_t \ cqueue_##X##_begin(cqueue_##X* self) {return ctype##_begin(self);} \ +STC_INLINE cqueue_##X##_iter_t \ +cqueue_##X##_end(cqueue_##X* self) {return ctype##_end(self);} \ +STC_INLINE cqueue_##X##_iter_t \ +cqueue_##X##_range(cqueue_##X##_iter_t s, cqueue_##X##_iter_t f) {return ctype##_range(s, f);} \ STC_INLINE void \ cqueue_##X##_next(cqueue_##X##_iter_t* it) {ctype##_next(it);} \ STC_INLINE cqueue_##X##_value_t* \ diff --git a/stc/cstack.h b/stc/cstack.h index 4924f991..10e91865 100644 --- a/stc/cstack.h +++ b/stc/cstack.h @@ -81,6 +81,10 @@ cstack_##X##_push_n(cstack_##X *self, const cstack_##X##_input_t in[], size_t si typedef ctype##_iter_t cstack_##X##_iter_t; \ STC_INLINE cstack_##X##_iter_t \ cstack_##X##_begin(cstack_##X* self) {return ctype##_begin(self);} \ +STC_INLINE cstack_##X##_iter_t \ +cstack_##X##_end(cstack_##X* self) {return ctype##_end(self);} \ +STC_INLINE cstack_##X##_iter_t \ +cstack_##X##_range(cstack_##X##_iter_t s, cstack_##X##_iter_t f) {return ctype##_range(s, f);} \ STC_INLINE void \ cstack_##X##_next(cstack_##X##_iter_t* it) {ctype##_next(it);} \ STC_INLINE cstack_##X##_value_t* \ diff --git a/stc/cstr.h b/stc/cstr.h index c615b325..8a484be4 100644 --- a/stc/cstr.h +++ b/stc/cstr.h @@ -115,9 +115,16 @@ STC_INLINE char* cstr_back(cstr_t* self) {return self->str + _cstr_size(*self) - 1;} STC_INLINE cstr_iter_t -cstr_begin(cstr_t* self) { - cstr_iter_t it = {self->str, self->str + cstr_size(*self)}; return it; +cstr_begin(cstr_t* self) {cstr_iter_t it = {self->str}; return it;} +STC_INLINE cstr_iter_t +cstr_end(cstr_t* self) { + cstr_iter_t it = {self->str + cstr_size(*self)}; return it; +} +STC_INLINE cstr_iter_t +cstr_range(cstr_iter_t start, cstr_iter_t finish) { + start.end = finish.item; return start; } + STC_INLINE void cstr_next(cstr_iter_t* it) { ++it->item; } STC_INLINE char* cstr_itval(cstr_iter_t it) {return it.item;} diff --git a/stc/cvec.h b/stc/cvec.h index 4dff3363..e5724301 100644 --- a/stc/cvec.h +++ b/stc/cvec.h @@ -140,12 +140,19 @@ typedef struct { \ } cvec_##X##_iter_t; \ \ STC_INLINE cvec_##X##_iter_t \ -cvec_##X##_begin(cvec_##X* vec) { \ - cvec_##X##_iter_t it = {vec->data, vec->data + cvec_size(*vec)}; \ - return it; \ +cvec_##X##_begin(cvec_##X* self) { \ + cvec_##X##_iter_t it = {self->data}; return it; \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_end(cvec_##X* self) { \ + cvec_##X##_iter_t it = {self->data + cvec_size(*self)}; return it; \ +} \ +STC_INLINE cvec_##X##_iter_t \ +cvec_##X##_range(cvec_##X##_iter_t start, cvec_##X##_iter_t finish) { \ + start.end = finish.item; return start; \ } \ STC_INLINE void \ -cvec_##X##_next(cvec_##X##_iter_t* it) { ++it->item; } \ +cvec_##X##_next(cvec_##X##_iter_t* it) {++it->item;} \ STC_INLINE cvec_##X##_value_t* \ cvec_##X##_itval(cvec_##X##_iter_t it) {return it.item;} \ \ -- cgit v1.2.3