diff options
Diffstat (limited to 'include/stc/algo')
| -rw-r--r-- | include/stc/algo/coroutine.h | 25 | ||||
| -rw-r--r-- | include/stc/algo/crange.h | 6 | ||||
| -rw-r--r-- | include/stc/algo/csort.h | 6 | ||||
| -rw-r--r-- | include/stc/algo/filter.h | 95 |
4 files changed, 94 insertions, 38 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index 59e4cfca..b0ecd6b7 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -59,20 +59,20 @@ int main(void) { enum { cco_state_final = -1, - cco_state_expired = -2, + cco_state_done = -2, }; -#define cco_alive(ctx) ((ctx)->cco_state > 0) +#define cco_suspended(ctx) ((ctx)->cco_state > 0) +#define cco_alive(ctx) ((ctx)->cco_state != cco_state_done) #define cco_begin(ctx) \ int *_state = &(ctx)->cco_state; \ switch (*_state) { \ - case cco_state_expired: \ case 0: #define cco_end(retval) \ - *_state = cco_state_expired; break; \ - default: goto _cco_final_; /* avoid unused-warning */ \ + *_state = cco_state_done; break; \ + case -99: goto _cco_final_; \ } \ return retval @@ -83,13 +83,16 @@ enum { case __LINE__:; \ } while (0) -#define cco_yield_3(corocall, ctx, retval) \ +#define cco_yield_2(corocall2, ctx2) \ + cco_yield_3(corocall2, ctx2, ) + +#define cco_yield_3(corocall2, ctx2, retval) \ do { \ *_state = __LINE__; \ do { \ - corocall; if (cco_alive(ctx)) return retval; \ + corocall2; if (cco_suspended(ctx2)) return retval; \ case __LINE__:; \ - } while ((ctx)->cco_state >= cco_state_final); \ + } while (cco_alive(ctx2)); \ } while (0) #define cco_final \ @@ -105,4 +108,10 @@ enum { if (*_state > 0) *_state = cco_state_final; \ } while (0) +#define cco_reset(ctx) \ + do { \ + int* _state = &(ctx)->cco_state; \ + if (*_state == cco_state_done) *_state = 0; \ + } while (0) + #endif diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h index 4fc957b6..ca06c258 100644 --- a/include/stc/algo/crange.h +++ b/include/stc/algo/crange.h @@ -34,9 +34,9 @@ int main() // use a temporary crange object. int a = 100, b = INT32_MAX; - c_forfilter (i, crange, crange_obj(a, b, 8) - , i.index > 10 - && c_flt_take(i, 3)) + c_forfilter (i, crange, crange_obj(a, b, 8), + c_flt_skip(i, 10) && + c_flt_take(i, 3)) printf(" %lld", *i.ref); puts(""); } diff --git a/include/stc/algo/csort.h b/include/stc/algo/csort.h index c452064f..53fe9fcc 100644 --- a/include/stc/algo/csort.h +++ b/include/stc/algo/csort.h @@ -20,8 +20,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include <stc/ccommon.h> -#include <stc/priv/template.h> +#include "../ccommon.h" +#include "../priv/template.h" /* Generic Quicksort in C, performs as fast as c++ std::sort(). template params: @@ -86,4 +86,4 @@ static inline void c_PASTE(cqsort_, i_tag)(i_val arr[], intptr_t lo, intptr_t hi static inline void c_PASTE(csort_, i_tag)(i_val arr[], intptr_t n) { c_PASTE(cqsort_, i_tag)(arr, 0, n - 1); } -#include <stc/priv/template.h> +#include "../priv/template2.h" diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h index 48a36d9b..e133577c 100644 --- a/include/stc/algo/filter.h +++ b/include/stc/algo/filter.h @@ -24,24 +24,24 @@ #include <stdio.h> #define i_val int #include <stc/cstack.h> -#include <stc/algo/filter.h> +#include <stc/calgo.h> int main() { - c_with (cstack_int stk = c_make(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9}), - cstack_int_drop(&stk)) - { - c_foreach (i, cstack_int, stk) - printf(" %d", *i.ref); - puts(""); - - c_forfilter (i, cstack_int, stk - , c_flt_skipwhile(i, *i.ref < 3) - && (*i.ref & 1) == 0 // even only - && c_flt_take(i, 2)) // break after 2 - printf(" %d", *i.ref); - puts(""); - } + cstack_int stk = c_make(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9}); + + c_foreach (i, cstack_int, stk) + printf(" %d", *i.ref); + puts(""); + + c_forfilter (i, cstack_int, stk, + c_flt_skipwhile(i, *i.ref < 3) && + (*i.ref & 1) == 0 && // even only + c_flt_take(i, 2)) // break after 2 + printf(" %d", *i.ref); + puts(""); + + cstack_int_drop(&stk); } */ #ifndef STC_FILTER_H_INCLUDED @@ -49,24 +49,71 @@ int main() #include <stc/ccommon.h> -#ifndef c_NFILTERS -#define c_NFILTERS 32 -#endif +// c_forfilter: -#define c_flt_take(i, n) _flt_take(&(i).b, n) -#define c_flt_skip(i, n) (c_flt_count(i) > (n)) +#define c_flt_skip(i, n) (c_flt_counter(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) #define c_flt_takewhile(i, pred) _flt_takewhile(&(i).b, pred) -#define c_flt_last(i) (i).b.s1[(i).b.s1top-1] -#define c_flt_count(i) ++(i).b.s1[(i).b.s1top++] +#define c_flt_counter(i) ++(i).b.s1[(i).b.s1top++] +#define c_flt_getcount(i) (i).b.s1[(i).b.s1top - 1] #define c_forfilter(i, C, cnt, filter) \ + c_forfilter_it(i, C, C##_begin(&cnt), filter) + +#define c_forfilter_it(i, C, start, filter) \ for (struct {struct _flt_base b; C##_iter it; C##_value *ref;} \ - i = {.it=C##_begin(&cnt), .ref=i.it.ref} ; !i.b.done & (i.ref != NULL) ; \ + i = {.it=start, .ref=i.it.ref} ; !i.b.done & (i.it.ref != NULL) ; \ 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: +#define c_erase_if(it, C, cnt, pred) do { \ + C* _cnt = &cnt; \ + intptr_t _index = 0; \ + for (C##_iter it = C##_begin(_cnt); it.ref; ++_index) { \ + 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, _index = 0; \ + C##_iter it = C##_begin(_cnt), _i; \ + while (it.ref && !(pred)) \ + C##_next(&it), ++_index; \ + for (_i = it; it.ref; C##_next(&it), ++_index) \ + 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 +#endif struct _flt_base { uint32_t s1[c_NFILTERS]; |
