summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-09-25 14:51:35 +0200
committerTyge Løvset <[email protected]>2022-09-25 15:09:23 +0200
commit2093b18689383286915df511167a12dc5d7bc75f (patch)
tree174779ae7e7b4f6d10ec8be300ea9574e2395729
parent756120e349a892ef1b7655fc777f28ec13845300 (diff)
downloadSTC-modified-2093b18689383286915df511167a12dc5d7bc75f.tar.gz
STC-modified-2093b18689383286915df511167a12dc5d7bc75f.zip
Added: crange number generator type. (similar to c++ std::iota). Fixed c_forfilter again. Cleanups. Docs added.
-rw-r--r--docs/ccommon_api.md90
-rw-r--r--docs/cdeq_api.md2
-rw-r--r--docs/cstr_api.md2
-rw-r--r--docs/csview_api.md2
-rw-r--r--docs/cvec_api.md2
-rw-r--r--examples/city.c8
-rw-r--r--examples/forfilter.c63
-rw-r--r--examples/new_deq.c2
-rw-r--r--examples/new_vec.c2
-rw-r--r--include/stc/ccommon.h42
-rw-r--r--include/stc/cdeq.h2
-rw-r--r--include/stc/cstack.h2
-rw-r--r--include/stc/cstr.h4
-rw-r--r--include/stc/csview.h4
-rw-r--r--include/stc/cvec.h2
15 files changed, 170 insertions, 59 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index c45dadc1..8938f0d2 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -149,9 +149,9 @@ c_forlist (i, int, {1, 2, 3})
c_forlist (i, cmap_ii_raw, { {4, 5}, {6, 7} })
cmap_ii_insert(&map, i.ref->first, i.ref->second);
-// even string literals
+// even string literals pushed to a stack of cstr:
c_forlist (i, const char*, {"Hello", "crazy", "world"})
- cstack_s_push(&stk, *i.ref);
+ cstack_str_emplace(&stk, *i.ref);
```
### c_foreach, c_forpair
@@ -168,7 +168,7 @@ c_forlist (i, const char*, {"Hello", "crazy", "world"})
#define i_tag ii
#include <stc/csmap.h>
...
-c_forlist (i, csmap_ii_value, { {23,1}, {3,2}, {7,3}, {5,4}, {12,5} })
+c_forlist (i, csmap_ii_raw, { {23,1}, {3,2}, {7,3}, {5,4}, {12,5} })
csmap_ii_insert(&map, i.ref->first, i.ref->second);
c_foreach (i, csmap_ii, map)
@@ -186,7 +186,7 @@ c_forpair (id, count, csmap_ii, map)
```
### c_forrange
-Declare an iterator and specify a range to iterate with a for loop. Like python's ***for i in range()*** loop:
+Abstaction for iterating sequence of numbers. Like python's ***for i in range()*** loop.
| Usage | Python equivalent |
|:----------------------------------------------|:-------------------------------------|
@@ -207,6 +207,88 @@ c_forrange (i, int, 30, 0, -5) printf(" %d", i);
// 30 25 20 15 10 5
```
+### c_forwhile, c_forfilter
+Iterate containers with stop-criteria and chained range filtering.
+
+| Usage | Description |
+|:-----------------------------------------------------------|:-------------------------------------|
+| `c_forwhile (it, ctype, container, whilepred)` | Iterate as long as whilepred is true |
+| `c_forfilter (it, ctype, container, filter(s))` | Filter out items in chain |
+| `c_forfilter (it, ctype, container, filter(s), whilepred)` | Adds a "takewhile" filter argument |
+
+| Built-in filter | Description |
+|:----------------------------------|:-------------------------------------|
+| `c_flt_drop(it, numItems)` | Drop numItems |
+| `c_flt_dropwhile(it, predicate)` | Drop items until predicate is false |
+| `c_flt_take(it, numItems)` | Take numItems |
+
+`it.index` holds the current item index.
+```c
+#define i_type IVec
+#define i_val int
+#include <stc/cstack.h>
+#include <stdio.h>
+
+bool flt_prime(int i) {
+ for (int j=2; j*j <= i; ++j){
+ if (i % j == 0) return false;
+ }
+ return true;
+}
+#define flt_odd(i) ((i) & 1)
+
+int main() {
+ c_auto (IVec, vec) {
+ c_forrange (i, 1000) IVec_push(&vec, 1000000 + i);
+
+ c_forfilter (i, IVec, vec,
+ flt_odd(*i.ref)
+ && c_flt_drop(i, 100) // built-in
+ && flt_prime(*i.ref)
+ , c_flt_take(i, 10)) { // breaks loop on false.
+ printf(" %d", *i.ref);
+ }
+ puts("");
+ }
+}
+// Out: 1000211 1000213 1000231 1000249 1000253 1000273 1000289 1000291 1000303 1000313
+```
+Note that `c_flt_take()` is given as an optional argument, which makes the loop stop when it becomes false (for efficiency). Chaining it after `flt_prime()` instead will give same result, but the full input is processed.
+
+### crange
+**crange** is a number sequence generator type. The **crange_value** type is `intmax_t`. Below, *start*, *end*, *step* are of *crange_type*.
+```c
+crange crange_init(void); // will generate 0, 1, 2, ...
+crange crange_from(start); // will generate start, start+1, ...
+crange crange_from(start, end); // will generate start, start+1, ... end-1
+crange crange_from(start, end, step); // will generate start, start+step, ... upto-not-including end
+ // note that step may be negative.
+crange_iter crange_begin(crange* self);
+crange_iter crange_end(crange* self);
+void crange_next(crange_iter* it);
+
+// Example usage:
+
+bool isPrime(int i) {
+ for (int j=2; j*j <= i; ++j) if (i % j == 0) return false;
+ return true;
+}
+
+crange r1 = crange_from(3, 32, 2);
+printf("1 2");
+c_forfilter (i, crange, r1,
+ isPrime(*i.ref))
+ printf(" %lld", *i.ref);
+// 1 2 3 5 7 11 13 17 19 23 29 31
+
+crange r2 = crange_from(3, INTMAX_MAX, 2);
+printf("1 2");
+c_forfilter (i, crange, r2,
+ isPrime(*i.ref)
+ , c_flt_take(10))
+ printf(" %lld", *i.ref);
+// 1 2 3 5 7 11 13 17 19 23 29 31
+```
### c_find_if, c_find_in, c_erase_if
Find or erase linearily in containers using a predicate
```c
diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md
index 969cecc2..cfd5565e 100644
--- a/docs/cdeq_api.md
+++ b/docs/cdeq_api.md
@@ -81,7 +81,7 @@ void cdeq_X_sort_range(cdeq_X_iter i1, cdeq_X_iter i2,
cdeq_X_iter cdeq_X_begin(const cdeq_X* self);
cdeq_X_iter cdeq_X_end(const cdeq_X* self);
void cdeq_X_next(cdeq_X_iter* it);
-cdeq_X_iter cdeq_X_advance(cdeq_X_iter it, isize_t n);
+cdeq_X_iter cdeq_X_advance(cdeq_X_iter it, intptr_t n);
cdeq_X_raw cdeq_X_value_toraw(cdeq_X_value* pval);
cdeq_X_value cdeq_X_value_clone(cdeq_X_value val);
diff --git a/docs/cstr_api.md b/docs/cstr_api.md
index 53850e04..439faca7 100644
--- a/docs/cstr_api.md
+++ b/docs/cstr_api.md
@@ -108,7 +108,7 @@ void cstr_u8_erase(cstr* self, size_t bytepos, size_t u8len); // erase u
cstr_iter cstr_begin(const cstr* self);
cstr_iter cstr_end(const cstr* self);
void cstr_next(cstr_iter* it);
-cstr_iter cstr_advance(cstr_iter it, isize_t n);
+cstr_iter cstr_advance(cstr_iter it, intptr_t n);
// utf8 functions requires linking with src/utf8code.c symbols:
bool cstr_valid_utf8(const cstr* self); // check if str is valid utf8
diff --git a/docs/csview_api.md b/docs/csview_api.md
index 37ebf79a..70587911 100644
--- a/docs/csview_api.md
+++ b/docs/csview_api.md
@@ -55,7 +55,7 @@ bool csview_valid_utf8(csview sv); // requires
csview_iter csview_begin(const csview* self);
csview_iter csview_end(const csview* self);
void csview_next(csview_iter* it); // utf8 codepoint step, not byte!
-csview_iter csview_advance(csview_iter it, isize_t n);
+csview_iter csview_advance(csview_iter it, intptr_t n);
// from utf8.h
size_t utf8_size(const char *s);
diff --git a/docs/cvec_api.md b/docs/cvec_api.md
index dca273aa..c9442bb1 100644
--- a/docs/cvec_api.md
+++ b/docs/cvec_api.md
@@ -92,7 +92,7 @@ void cvec_X_sort_range(cvec_X_iter i1, cvec_X_iter i2,
cvec_X_iter cvec_X_begin(const cvec_X* self);
cvec_X_iter cvec_X_end(const cvec_X* self);
void cvec_X_next(cvec_X_iter* iter);
-cvec_X_iter cvec_X_advance(cvec_X_iter it, isize_t n);
+cvec_X_iter cvec_X_advance(cvec_X_iter it, intptr_t n);
cvec_X_raw cvec_X_value_toraw(cvec_X_value* pval);
cvec_X_value cvec_X_value_clone(cvec_X_value val);
diff --git a/examples/city.c b/examples/city.c
index c98d3098..80bfbb12 100644
--- a/examples/city.c
+++ b/examples/city.c
@@ -52,10 +52,10 @@ int main(void)
c_auto (CityMap, map)
{
c_forlist (i, City, {
- {cstr_new("New York"), cstr_new("US"), 4.3, 23.2, 9000000},
- {cstr_new("Paris"), cstr_new("France"), 4.3, 23.2, 9000000},
- {cstr_new("Berlin"), cstr_new("Germany"), 4.3, 23.2, 9000000},
- {cstr_new("London"), cstr_new("UK"), 4.3, 23.2, 9000000},
+ {cstr_new("New York"), cstr_new("US"), 4.3f, 23.2f, 9000000},
+ {cstr_new("Paris"), cstr_new("France"), 4.3f, 23.2f, 9000000},
+ {cstr_new("Berlin"), cstr_new("Germany"), 4.3f, 23.2f, 9000000},
+ {cstr_new("London"), cstr_new("UK"), 4.3f, 23.2f, 9000000},
}) Cities_emplace(&cities, *i.ref);
copy = Cities_clone(cities); // share each element!
diff --git a/examples/forfilter.c b/examples/forfilter.c
index 46e59562..29128836 100644
--- a/examples/forfilter.c
+++ b/examples/forfilter.c
@@ -14,6 +14,7 @@
// filters and transforms:
#define flt_remove(i, x) (*i.ref != (x))
#define flt_even(i) ((*i.ref & 1) == 0)
+#define flt_odd(i) (*i.ref & 1)
#define trf_square(i) (*i.ref * *i.ref)
void demo1(void)
@@ -22,21 +23,24 @@ void demo1(void)
c_forlist (i, int, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13, 14, 15, 80, 16, 17})
IVec_push(&vec, *i.ref);
+ puts("demo1:");
c_forfilter (i, IVec, vec, flt_remove(i, 80))
printf(" %d", *i.ref);
puts("");
int res, sum = 0;
- c_forfilter (i, IVec, vec, c_flt_drop(i, 3)
- && flt_even(i)
- && flt_remove(i, 80)
- //&& c_flt_take(i, 5)
- , c_flt_take(i, 5)
+ c_forfilter (i, IVec, vec,
+ c_flt_dropwhile(i, *i.ref != 80)
+ && c_flt_drop(i, 1)
+ && c_flt_dropwhile(i, *i.ref != 80)
+ && flt_even(i)
+ && flt_remove(i, 80)
+ , c_flt_take(i, 5) // takewhile
){
sum += res = trf_square(i);
- printf(" %d:%d", *i.ref, res);
+ printf(" %d", res);
}
- printf("\nsum: %d\n", sum);
+ printf("\n sum: %d\n", sum);
}
}
@@ -55,11 +59,13 @@ fn main() {
void demo2(void)
{
c_auto (IVec, vector) {
- int n = 0;
- for (size_t x=1;; ++x)
- if (n == 5) break;
- else if (x & 1) ++n, IVec_push(&vector, x*x);
+ crange rv = crange_from(1);
+ c_forfilter (x, crange, rv,
+ flt_odd(x)
+ , c_flt_take(x, 5))
+ IVec_push(&vector, trf_square(x));
+ puts("demo2:");
c_foreach (i, IVec, vector) printf(" %d", *i.ref);
puts("");
}
@@ -89,6 +95,7 @@ void demo3(void)
csview_contains(*w.ref, c_sv("i")))
SVec_push(&words_containing_i, *w.ref);
+ puts("demo3:");
c_foreach (w, SVec, words_containing_i)
printf(" %.*s", c_ARGsv(*w.ref));
puts("");
@@ -97,18 +104,33 @@ void demo3(void)
void demo4(void)
{
- csview s = c_sv("ab123cReAghNGnΩoEp");
- cstr out = cstr_null;
-
- c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) {
- char buf[4];
- utf8_encode(buf, utf8_tolower(utf8_peek(i.ref)));
- cstr_push(&out, buf);
+ csview s = c_sv("ab123cReAghNGnΩoEp"); // Ω = multi-byte
+ c_auto (cstr, out) {
+ c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) {
+ char chr[4];
+ utf8_encode(chr, utf8_tolower(utf8_peek(i.ref)));
+ cstr_push(&out, chr);
+ }
+ puts("demo4:");
+ printf(" %s\n", cstr_str(&out));
}
-
- printf("%s\n", cstr_str(&out));
}
+void demo5(void)
+{
+ #define flt_even(i) ((*i.ref & 1) == 0)
+ #define flt_mid_decade(i) ((*i.ref % 10) != 0)
+ puts("demo5:");
+ crange r1 = crange_from(1963);
+ c_forfilter (i, crange, r1,
+ c_flt_drop(i,15)
+ && c_flt_dropwhile(i, flt_mid_decade(i))
+ && c_flt_drop(i,30)
+ && flt_even(i)
+ , c_flt_take(i,10))
+ printf(" %lld", *i.ref);
+ puts("");
+}
int main(void)
{
@@ -116,6 +138,7 @@ int main(void)
demo2();
demo3();
demo4();
+ demo5();
}
#include "../src/utf8code.c"
diff --git a/examples/new_deq.c b/examples/new_deq.c
index 5f7c357f..dd6f04c0 100644
--- a/examples/new_deq.c
+++ b/examples/new_deq.c
@@ -42,7 +42,7 @@ int main()
}
c_auto (cdeq_float, fvec)
{
- cdeq_float_push_back(&fvec, 123.3);
+ cdeq_float_push_back(&fvec, 123.3f);
}
c_auto (cdeq_pnt, pvec)
{
diff --git a/examples/new_vec.c b/examples/new_vec.c
index 9ae2ccf1..e0fa79ae 100644
--- a/examples/new_vec.c
+++ b/examples/new_vec.c
@@ -41,7 +41,7 @@ int main()
c_auto (cvec_str, svec)
{
cvec_i32_push_back(&vec, 123);
- cvec_float_push_back(&fvec, 123.3);
+ cvec_float_push_back(&fvec, 123.3f);
cvec_pnt_push_back(&pvec, (Point){42, 14});
cvec_pnt_push_back(&pvec, (Point){32, 94});
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index ac55b3e9..4ed3ebf8 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -30,14 +30,6 @@
#include <string.h>
#include <assert.h>
-#if SIZE_MAX == UINT32_MAX
- typedef int32_t isize_t;
-# define ISIZE_MAX INT32_MAX
-#elif SIZE_MAX == UINT64_MAX
- typedef int64_t isize_t;
-# define ISIZE_MAX INT64_MAX
-#endif
-
#if defined(_MSC_VER)
# pragma warning(disable: 4116 4996) // unnamed type definition in parentheses
# define STC_FORCE_INLINE static __forceinline
@@ -171,27 +163,25 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
; it.ref != (C##_value*)_endref; C##_next(&it))
#ifndef c_FLT_STACK
-#define c_FLT_STACK 4
+#define c_FLT_STACK 20
#endif
-
-#define c_flt_drop(i, n) (++(i).dropped[(i).dn++] > (n))
-#define c_flt_dropwhile(i, pred) ((i).dropwhile |= !(pred))
-#define c_flt_take(i, n) (++(i).taken[(i).tn++] <= (n))
+#define c_flt_take(i, n) (++(i).stack[(i).top++] <= (n))
+#define c_flt_drop(i, n) (++(i).stack[(i).top++] > (n))
+#define c_flt_dropwhile(i, pred) ((i).stack[(i).top++] |= !(pred))
#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__)
#define c_forfilter4(it, C, cnt, filter) \
c_forfilter_s(it, C, C##_begin(&cnt), filter)
-#define c_forfilter5(it, C, cnt, filter, loopwhile) \
- c_forfilter_s(it, C, C##_begin(&cnt), filter) if (!(loopwhile)) break; else
+#define c_forfilter5(it, C, cnt, filter, takewhile) \
+ c_forfilter_s(it, C, C##_begin(&cnt), filter) if (!(takewhile)) break; else
#define c_forfilter_s(it, C, start, filter) \
c_foreach_s(it, C, start) if (!(filter)) ; else
#define c_foreach_s(i, C, start) \
for (struct {C##_iter it; C##_value *ref; \
- uint32_t index, taken[c_FLT_STACK+1], dropped[c_FLT_STACK]; \
- int8_t dn, tn; bool dropwhile;} \
+ uint32_t index, top, stack[c_FLT_STACK];} \
i = {.it=start, .ref=i.it.ref}; i.ref \
- ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.dn=0, i.tn=0)
+ ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.top=0)
#define c_forwhile(i, C, cnt, cond) \
for (struct {C##_iter it; C##_value *ref; size_t index;} \
@@ -213,6 +203,22 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
for (itype i=start, _inc=step, _end=(stop) - (_inc > 0) \
; (_inc > 0) ^ (i > _end); i += _inc)
+typedef intmax_t crange_value;
+struct {crange_value val, end, step; } typedef crange;
+struct {crange_value *ref, end, step; } typedef crange_iter;
+#define crange_from(...) c_MACRO_OVERLOAD(crange_from, __VA_ARGS__)
+#define crange_init() crange_from3(0, INTMAX_MAX, 1)
+#define crange_from1(start) crange_from3(start, INTMAX_MAX, 1)
+#define crange_from2(start, end) crange_from3(start, end, 1)
+STC_INLINE crange crange_from3(crange_value start, crange_value finish, crange_value step)
+ { crange r = {start, finish - (step > 0), step}; return r; }
+STC_INLINE crange_iter crange_begin(crange* self)
+ { crange_iter it = {&self->val, self->end, self->step}; return it; }
+STC_INLINE crange_iter crange_end(crange* self)
+ { crange_iter it = {NULL}; return it; }
+STC_INLINE void crange_next(crange_iter* it)
+ { *it->ref += it->step; if ((it->step > 0) == (*it->ref > it->end)) it->ref = NULL; }
+
#define c_forlist(it, T, ...) \
for (struct {T* data; T* ref; size_t index;} \
it = {.data=(T[])__VA_ARGS__, .ref=it.data} \
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h
index 423464ac..2b8513e1 100644
--- a/include/stc/cdeq.h
+++ b/include/stc/cdeq.h
@@ -110,7 +110,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
{ if (++it->ref == it->end) it->ref = NULL; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, isize_t n)
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t n)
{ if ((it.ref += n) >= it.end) it.ref = NULL; return it; }
#if !defined _i_queue
diff --git a/include/stc/cstack.h b/include/stc/cstack.h
index 9126cdef..2f9b2626 100644
--- a/include/stc/cstack.h
+++ b/include/stc/cstack.h
@@ -180,7 +180,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
{ if (++it->ref == it->end) it->ref = NULL; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, isize_t n)
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t n)
{ if ((it.ref += n) >= it.end) it.ref = NULL ; return it; }
#include "template.h"
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index 961ca344..7b382085 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -48,7 +48,7 @@
enum { cstr_s_cap = sizeof(cstr_buf) - 1 };
#define cstr_s_size(s) ((size_t)(cstr_s_cap - (s)->sml.last))
-#define cstr_s_set_size(s, len) ((s)->sml.last = cstr_s_cap - (len), (s)->sml.data[len] = 0)
+#define cstr_s_set_size(s, len) ((s)->sml.last = (uint8_t)(cstr_s_cap - (len)), (s)->sml.data[len] = 0)
#define cstr_s_data(s) (s)->sml.data
#define cstr_s_end(s) ((s)->sml.data + cstr_s_size(s))
@@ -237,7 +237,7 @@ STC_INLINE void cstr_next(cstr_iter* it) {
it->u8.chr.size = utf8_chr_size(it->ref);
if (!*it->ref) it->ref = NULL;
}
-STC_INLINE cstr_iter cstr_advance(cstr_iter it, isize_t pos) {
+STC_INLINE cstr_iter cstr_advance(cstr_iter it, intptr_t pos) {
int inc = -1;
if (pos > 0) pos = -pos, inc = 1;
while (pos && *it.ref) pos += (*(it.ref += inc) & 0xC0) != 0x80;
diff --git a/include/stc/csview.h b/include/stc/csview.h
index 3bb8a542..2be30cb0 100644
--- a/include/stc/csview.h
+++ b/include/stc/csview.h
@@ -86,7 +86,7 @@ STC_INLINE void csview_next(csview_iter* it) {
it->u8.chr.size = utf8_chr_size(it->ref);
if (it->ref == it->u8.end) it->ref = NULL;
}
-STC_INLINE csview_iter csview_advance(csview_iter it, isize_t pos) {
+STC_INLINE csview_iter csview_advance(csview_iter it, intptr_t pos) {
int inc = -1;
if (pos > 0) pos = -pos, inc = 1;
while (pos && it.ref != it.u8.end) pos += (*(it.ref += inc) & 0xC0) != 0x80;
@@ -145,7 +145,7 @@ STC_INLINE csview cstr_u8_substr(const cstr* self , size_t bytepos, size_t u8len
STC_INLINE int csview_cmp(const csview* x, const csview* y) {
size_t n = x->size < y->size ? x->size : y->size;
int c = memcmp(x->str, y->str, n);
- return c ? c : x->size - y->size;
+ return c ? c : (int)(x->size - y->size);
}
STC_INLINE int csview_icmp(const csview* x, const csview* y)
diff --git a/include/stc/cvec.h b/include/stc/cvec.h
index 4419f4a8..aeb17e1a 100644
--- a/include/stc/cvec.h
+++ b/include/stc/cvec.h
@@ -207,7 +207,7 @@ STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
{ if (++it->ref == it->end) it->ref = NULL; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, isize_t n)
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t n)
{ if ((it.ref += n) >= it.end) it.ref = NULL; return it; }
STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it)