summaryrefslogtreecommitdiffhomepage
path: root/include/stc/algo
diff options
context:
space:
mode:
Diffstat (limited to 'include/stc/algo')
-rw-r--r--include/stc/algo/coroutine.h25
-rw-r--r--include/stc/algo/crange.h6
-rw-r--r--include/stc/algo/csort.h6
-rw-r--r--include/stc/algo/filter.h95
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];