diff options
| author | Tyge Løvset <[email protected]> | 2023-03-22 17:32:21 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-03-22 17:32:21 +0100 |
| commit | e6a25eaaf4687ff99d0d719d0b32ad512156039e (patch) | |
| tree | 6bc1730f6882eb054c6472361487a0be8b85c7aa | |
| parent | 66429475ed6ac0deaba85989174e8880762d7888 (diff) | |
| download | STC-modified-e6a25eaaf4687ff99d0d719d0b32ad512156039e.tar.gz STC-modified-e6a25eaaf4687ff99d0d719d0b32ad512156039e.zip | |
Added c_foreach_r() macro for reverse iter of cvec, cdeq, cstack.
Moved c_find_if, c_erase_if, c_eraseremove_if to algo/filter.h
Internals.
| -rw-r--r-- | docs/ccommon_api.md | 15 | ||||
| -rw-r--r-- | include/stc/algo/filter.h | 44 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 48 | ||||
| -rw-r--r-- | include/stc/cmap.h | 4 | ||||
| -rw-r--r-- | include/stc/forward.h | 2 | ||||
| -rw-r--r-- | misc/examples/arcvec_erase.c | 4 | ||||
| -rw-r--r-- | misc/examples/csmap_find.c | 2 | ||||
| -rw-r--r-- | misc/examples/csset_erase.c | 2 | ||||
| -rw-r--r-- | misc/examples/demos.c | 2 | ||||
| -rw-r--r-- | misc/examples/forloops.c | 11 |
10 files changed, 74 insertions, 60 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index ff75d83d..64daad42 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -94,13 +94,14 @@ int main() ``` ## Loop abstraction macros -### c_foreach, c_forpair - -| Usage | Description | -|:-----------------------------------------|:--------------------------------| -| `c_foreach (it, ctype, container)` | Iteratate all elements | -| `c_foreach (it, ctype, it1, it2)` | Iterate the range [it1, it2) | -| `c_forpair (key, val, ctype, container)` | Iterate with structured binding | +### c_foreach, c_foreach_r, c_forpair + +| Usage | Description | +|:-----------------------------------------|:----------------------------------------| +| `c_foreach (it, ctype, container)` | Iteratate all elements | +| `c_foreach (it, ctype, it1, it2)` | Iterate the range [it1, it2) | +| `c_foreach_r (it, ctype, container)` | Iteratate in reverse (cstack,cvec,cdeq) | +| `c_forpair (key, val, ctype, container)` | Iterate with structured binding | ```c #define i_key int diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 5e3125b1..1978ea43 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -49,6 +49,8 @@ int main() #include <stc/ccommon.h> +// c_forfilter: + #define c_flt_skip(i, n) (c_flt_count(i) > (n)) #define c_flt_skipwhile(i, pred) ((i).b.s2[(i).b.s2top++] |= !(pred)) #define c_flt_take(i, n) _flt_take(&(i).b, n) @@ -65,6 +67,48 @@ int main() C##_next(&i.it), i.ref = i.it.ref, i.b.s1top=0, i.b.s2top=0) \ if (!(filter)) ; else + +// c_find_if, c_erase_if, c_eraseremove_if: + +#define c_find_if(...) c_MACRO_OVERLOAD(c_find_if, __VA_ARGS__) +#define c_find_if_4(it, C, cnt, pred) do { \ + intptr_t index = 0; \ + for (it = C##_begin(&cnt); it.ref && !(pred); C##_next(&it)) \ + ++index; \ +} while (0) + +#define c_find_if_5(it, C, start, end, pred) do { \ + intptr_t index = 0; \ + const C##_value* _endref = (end).ref; \ + for (it = start; it.ref != _endref && !(pred); C##_next(&it)) \ + ++index; \ + if (it.ref == _endref) it.ref = NULL; \ +} while (0) + + +// Use with: clist, cmap, cset, csmap, csset, cstr: +#define c_erase_if(it, C, cnt, pred) do { \ + C* _cnt = &cnt; \ + for (C##_iter it = C##_begin(_cnt); it.ref;) { \ + if (pred) it = C##_erase_at(_cnt, it); \ + else C##_next(&it); \ + } \ +} while (0) + + +// Use with: cstack, cvec, cdeq, cqueue: +#define c_eraseremove_if(it, C, cnt, pred) do { \ + C* _cnt = &cnt; \ + intptr_t _n = 0; \ + C##_iter it = C##_begin(_cnt), _i; \ + while (it.ref && !(pred)) \ + C##_next(&it); \ + for (_i = it; it.ref; C##_next(&it)) \ + if (pred) C##_value_drop(it.ref), ++_n; \ + else *_i.ref = *it.ref, C##_next(&_i); \ + _cnt->_len -= _n; \ +} while (0) + // ------------------------ private ------------------------- #ifndef c_NFILTERS #define c_NFILTERS 32 diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index ad6063e4..b822b9f8 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -178,6 +178,10 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, for (C##_iter it = start, *_endref = (C##_iter*)(finish).ref \ ; it.ref != (C##_value*)_endref; C##_next(&it)) +#define c_foreach_r(it, C, cnt) \ + for (C##_iter it = {.ref=C##_end(&cnt).end - 1, .end=(cnt).data - 1} \ + ; it.ref != it.end; --it.ref) + #define c_forpair(key, val, C, cnt) /* structured binding */ \ for (struct {C##_iter it; const C##_key* key; C##_mapped* val;} _ = {.it=C##_begin(&cnt)} \ ; _.it.ref && (_.key = &_.it.ref->first, _.val = &_.it.ref->second) \ @@ -193,8 +197,8 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, ; (_inc > 0) ^ (i > _end); i += _inc) #ifndef __cplusplus #define c_forlist(it, T, ...) \ - for (struct {T* data; T* ref; int size, index;} \ - it = {.data=(T[])__VA_ARGS__, .ref=it.data, .size=(int)(sizeof((T[])__VA_ARGS__)/sizeof(T))} \ + for (struct {T* ref; int size, index;} \ + it = {.ref=(T[])__VA_ARGS__, .size=(int)(sizeof((T[])__VA_ARGS__)/sizeof(T))} \ ; it.index < it.size; ++it.ref, ++it.index) #else #include <initializer_list> @@ -224,44 +228,8 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ (C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) -/* Generic functions */ - -#define c_drop(C, ...) do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) -#define c_find_if(...) c_MACRO_OVERLOAD(c_find_if, __VA_ARGS__) -#define c_find_if_4(it, C, cnt, pred) do { \ - intptr_t index = 0; \ - for (it = C##_begin(&cnt); it.ref && !(pred); C##_next(&it)) \ - ++index; \ -} while (0) -#define c_find_if_5(it, C, start, end, pred) do { \ - intptr_t index = 0; \ - const C##_value* _endref = (end).ref; \ - for (it = start; it.ref != _endref && !(pred); C##_next(&it)) \ - ++index; \ - if (it.ref == _endref) it.ref = NULL; \ -} while (0) - -// use with: clist, cmap, cset, csmap, csset, cstr: -#define c_erase_if(it, C, cnt, pred) do { \ - C* _cnt = &cnt; \ - for (C##_iter it = C##_begin(_cnt); it.ref;) { \ - if (pred) it = C##_erase_at(_cnt, it); \ - else C##_next(&it); \ - } \ -} while (0) - -// use with: cstack, cvec, cdeq, cqueue: -#define c_eraseremove_if(it, C, cnt, pred) do { \ - C* _cnt = &cnt; \ - intptr_t _n = 0; \ - C##_iter it = C##_begin(_cnt), _i; \ - while (it.ref && !(pred)) \ - C##_next(&it); \ - for (_i = it; it.ref; C##_next(&it)) \ - if (pred) C##_value_drop(it.ref), ++_n; \ - else *_i.ref = *it.ref, C##_next(&_i); \ - _cnt->_len -= _n; \ -} while (0) +#define c_drop(C, ...) \ + do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) #endif // CCOMMON_H_INCLUDED diff --git a/include/stc/cmap.h b/include/stc/cmap.h index bc3b5546..d9081ae0 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -224,7 +224,7 @@ STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { if (it._hx) while (*it._hx == 0) ++it.ref, ++it._hx; - if (it.ref == it.end) it.ref = NULL; + if (it.ref == it._end) it.ref = NULL; return it; } @@ -235,7 +235,7 @@ _cx_memb(_end)(const _cx_self* self) STC_INLINE void _cx_memb(_next)(_cx_iter* it) { while ((++it->ref, *++it->_hx == 0)) ; - if (it->ref == it->end) it->ref = NULL; + if (it->ref == it->_end) it->ref = NULL; } STC_INLINE _cx_iter diff --git a/include/stc/forward.h b/include/stc/forward.h index 00c531fe..31e67e7d 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -118,7 +118,7 @@ typedef union { } SELF##_result; \ \ typedef struct { \ - SELF##_value *ref, *end; \ + SELF##_value *ref, *_end; \ uint8_t* _hx; \ } SELF##_iter; \ \ diff --git a/misc/examples/arcvec_erase.c b/misc/examples/arcvec_erase.c index 38f11097..9c85d3ab 100644 --- a/misc/examples/arcvec_erase.c +++ b/misc/examples/arcvec_erase.c @@ -30,12 +30,12 @@ int main() printf("\nerase vec.data[2]; or first matching value depending on compare.\n"); Vec_iter it; it = Vec_find(&vec, *vec.data[2].get); - if (it.ref != Vec_end(&vec).ref) + if (it.ref) Vec_erase_at(&vec, it); int year = 2015; it = Vec_find(&vec, year); // Ok as tmp only. - if (it.ref != Vec_end(&vec).ref) + if (it.ref) Vec_erase_at(&vec, it); printf("vec after erase :"); diff --git a/misc/examples/csmap_find.c b/misc/examples/csmap_find.c index fe5558e2..863cdea0 100644 --- a/misc/examples/csmap_find.c +++ b/misc/examples/csmap_find.c @@ -33,7 +33,7 @@ void findit(csmap_istr c, csmap_istr_key val) { printf("Trying find() on value %d\n", val); csmap_istr_iter result = csmap_istr_find(&c, val); // prefer contains() or get() - if (result.ref != csmap_istr_end(&c).ref) { + if (result.ref) { printf("Element found: "); print_elem(csmap_istr_value_toraw(result.ref)); puts(""); } else { puts("Element not found."); diff --git a/misc/examples/csset_erase.c b/misc/examples/csset_erase.c index e8f2fec5..cf94156c 100644 --- a/misc/examples/csset_erase.c +++ b/misc/examples/csset_erase.c @@ -23,7 +23,7 @@ int main() puts(""); printf("Erase values >= %d:\n", val); - while (it.ref != csset_int_end(&set).ref) + while (it.ref) it = csset_int_erase_at(&set, it); c_foreach (k, csset_int, set) diff --git a/misc/examples/demos.c b/misc/examples/demos.c index d5336cbf..2a7f3888 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -152,7 +152,7 @@ void mapdemo2() cmap_si_emplace_or_assign(&nums, "Groovy", 200); // overwrite previous // iterate the map: - for (cmap_si_iter i = cmap_si_begin(&nums); i.ref != cmap_si_end(&nums).ref; cmap_si_next(&i)) + for (cmap_si_iter i = cmap_si_begin(&nums); i.ref; cmap_si_next(&i)) printf("long: %s: %d\n", cstr_str(&i.ref->first), i.ref->second); // or rather use the short form: diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 144ec637..2fe21c8b 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -35,11 +35,8 @@ int main() printf(" %s", *i.ref);
puts("");
- c_forlist (i, const char*, {"12", "23", "453", "65", "676"})
- printf(" %s", i.data[i.size - 1 - i.index]);
-
- c_auto (IVec, vec)
+ c_auto (IVec, vec)
c_auto (IMap, map)
{
c_forlist (i, int, {12, 23, 453, 65, 113, 215, 676, 34, 67, 20, 27, 66, 189, 45, 280, 199})
@@ -51,8 +48,12 @@ int main() puts("\n\nc_foreach:");
c_foreach (i, IVec, vec)
printf(" %d", *i.ref);
- puts("");
+ puts("\n\nc_foreach_r: reverse");
+ c_foreach_r (i, IVec, vec)
+ printf(" %d", *i.ref);
+
+ puts("\n\nc_foreach in map:");
c_foreach (i, IMap, map)
printf(" (%d %d)", i.ref->first, i.ref->second);
|
