summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/stc/algo/crange.h72
-rw-r--r--include/stc/algo/csort.h127
-rw-r--r--include/stc/algo/cspan.h77
-rw-r--r--include/stc/algo/filter.h78
-rw-r--r--include/stc/carc.h15
-rw-r--r--include/stc/carr2.h152
-rw-r--r--include/stc/carr3.h157
-rw-r--r--include/stc/cbox.h22
-rw-r--r--include/stc/ccommon.h1
-rw-r--r--include/stc/cregex.h8
-rw-r--r--include/stc/cstack.h2
-rw-r--r--include/stc/cstr.h16
-rw-r--r--include/stc/priv/allcaps.h56
-rw-r--r--include/stc/views.h142
14 files changed, 446 insertions, 479 deletions
diff --git a/include/stc/algo/crange.h b/include/stc/algo/crange.h
new file mode 100644
index 00000000..ccdd13ae
--- /dev/null
+++ b/include/stc/algo/crange.h
@@ -0,0 +1,72 @@
+/* MIT License
+ *
+ * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*/
+/*
+#include <stdio.h>
+#include <stc/algo/filter.h>
+#include <stc/algo/crange.h>
+
+int main()
+{
+ crange r1 = crange_make(80, 90);
+ c_foreach (i, crange, r1)
+ printf(" %lld", *i.ref);
+ puts("");
+
+ // use a temporary crange object.
+ int a = 100, b = INT32_MAX;
+ c_forfilter (i, crange, crange_LITERAL(a, b, 8)
+ , i.index > 10
+ , c_flt_take(i, 3))
+ printf(" %lld", *i.ref);
+ puts("");
+}
+*/
+#ifndef STC_CRANGE_H_INCLUDED
+#define STC_CRANGE_H_INCLUDED
+
+#include <stc/ccommon.h>
+
+#define crange_LITERAL(...) \
+ (*(crange[]){crange_make(__VA_ARGS__)})
+
+typedef long long crange_value;
+typedef struct { crange_value start, end, step, value; } crange;
+typedef struct { crange_value *ref, end, step; } crange_iter;
+
+#define crange_make(...) c_MACRO_OVERLOAD(crange_make, __VA_ARGS__)
+#define crange_make1(stop) crange_make3(0, stop, 1)
+#define crange_make2(start, stop) crange_make3(start, stop, 1)
+
+STC_INLINE crange crange_make3(crange_value start, crange_value stop, crange_value step)
+ { crange r = {start, stop - (step > 0), step}; return r; }
+
+STC_INLINE crange_iter crange_begin(crange* self)
+ { self->value = self->start; crange_iter it = {&self->value, 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; }
+
+#endif
diff --git a/include/stc/algo/csort.h b/include/stc/algo/csort.h
new file mode 100644
index 00000000..9b115398
--- /dev/null
+++ b/include/stc/algo/csort.h
@@ -0,0 +1,127 @@
+/* MIT License
+ *
+ * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef STC_CSORT_H_INCLUDED
+#define STC_CSORT_H_INCLUDED
+#include <stdint.h>
+#define c_CONCAT(a, b) a ## b
+#define c_PASTE(a, b) c_CONCAT(a, b)
+#endif
+
+/* Generic Quicksort in C
+template params:
+#define i_val - value type [required]
+#define i_less - less function. default: *x < *y
+#define i_tag NAME - define csort_NAME(). default {i_val}
+
+// test:
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#define i_val int
+#include <stc/crandom.h>
+#include <stc/algo/csort.h>
+#ifdef __cplusplus
+#include <algorithm>
+#endif
+
+int testsort(csortval_int *a, size_t size, const char *desc) {
+ clock_t t = clock();
+#ifdef __cplusplus
+ puts("std::sort");
+ std::sort(a, a + size);
+#else
+ puts("csort");
+ csort_int(a, size);
+#endif
+ t = clock() - t;
+
+ printf("%s: %zu elements sorted in %.3fms\n",
+ desc, size, t * 1000.0 / CLOCKS_PER_SEC);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ size_t i, size = argc > 1 ? strtoull(argv[1], NULL, 0) : 10000000;
+ csortval_int *a = (csortval_int*)malloc(sizeof(*a) * size);
+ if (a != NULL) {
+ for (i = 0; i < size; i++)
+ a[i] = crandom() & (1U << 28) - 1;
+ testsort(a, size, "random");
+ for (i = 0; i < 20; i++) printf(" %d", a[i]);
+ puts("");
+ testsort(a, size, "sorted");
+ for (i = 0; i < size; i++) a[i] = size - i;
+ testsort(a, size, "reverse sorted");
+ for (i = 0; i < size; i++) a[i] = 126735;
+ testsort(a, size, "constant");
+ free(a);
+ }
+ return 0;
+}*/
+#ifndef i_tag
+#define i_tag i_val
+#endif
+#ifndef i_less
+#define i_less(x, y) *x < *y
+#endif
+
+typedef i_val c_PASTE(csortval_, i_tag);
+
+static inline void c_PASTE(cisort_, i_tag)(i_val arr[], intptr_t low, intptr_t high) {
+ for (intptr_t j = low, i = low+1; i <= high; j = i, ++i) {
+ i_val key = arr[i];
+ while (j >= 0 && (i_less((&key), (&arr[j])))) {
+ arr[j + 1] = arr[j];
+ --j;
+ }
+ arr[j + 1] = key;
+ }
+}
+
+static inline void c_PASTE(cqsort_, i_tag)(i_val arr[], intptr_t low, intptr_t high)
+{
+ intptr_t i = low, j = high;
+ i_val pivot = arr[(i + j)/2];
+
+ while (i <= j) {
+ while (i_less((&arr[i]), (&pivot))) ++i;
+ while (i_less((&pivot), (&arr[j]))) --j;
+ if (i <= j) {
+ i_val t = arr[i]; arr[i] = arr[j]; arr[j] = t;
+ ++i; --j;
+ }
+ }
+ if (j > low) j - low < 65 ? c_PASTE(cisort_, i_tag)(arr, low, j)
+ : c_PASTE(cqsort_, i_tag)(arr, low, j);
+ if (i < high) high - i < 65 ? c_PASTE(cisort_, i_tag)(arr, i, high)
+ : c_PASTE(cqsort_, i_tag)(arr, i, high);
+}
+
+static inline void c_PASTE(csort_, i_tag)(i_val arr[], size_t elements)
+{
+ elements < 65 ? c_PASTE(cisort_, i_tag)(arr, 0, (intptr_t)elements - 1)
+ : c_PASTE(cqsort_, i_tag)(arr, 0, (intptr_t)elements - 1);
+}
+#undef i_tag
+#undef i_val
+#undef i_less
diff --git a/include/stc/algo/cspan.h b/include/stc/algo/cspan.h
new file mode 100644
index 00000000..d6d6dd56
--- /dev/null
+++ b/include/stc/algo/cspan.h
@@ -0,0 +1,77 @@
+/* MIT License
+ *
+ * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*/
+/*
+#include <stdio.h>
+#include <stc/algo/cspan.h>
+using_cspan(IntSpan, int);
+
+int main()
+{
+ int array[] = {1, 2, 3, 4, 5};
+ IntSpan iv = {array, c_arraylen(array)};
+
+ c_foreach (i, IntSpan, iv)
+ printf(" %d", *i.ref);
+ puts("");
+
+ // use a temporary IntSpan object.
+ c_forfilter (i, IntSpan, cspan_LITERAL(IntSpan, {10, 20, 30, 23, 22, 21})
+ , c_flt_skipwhile(i, *i.ref < 25)
+ && (*i.ref & 1) == 0 // even only
+ , c_flt_take(i, 2)) // break after 2
+ printf(" %d", *i.ref);
+ puts("");
+}
+*/
+#ifndef STC_CSPAN_H_INCLUDED
+#define STC_CSPAN_H_INCLUDED
+
+#include <stc/ccommon.h>
+
+#define cspan_LITERAL(C, ...) \
+ ((C){.data = (C##_value[])__VA_ARGS__, \
+ .size = sizeof((C##_value[])__VA_ARGS__)/sizeof(C##_value)})
+
+#define using_cspan(Self, T) \
+typedef T Self##_raw; typedef const Self##_raw Self##_value; \
+typedef struct { Self##_value *data; size_t size; } Self; \
+typedef struct { Self##_value *ref, *end; } Self##_iter; \
+ \
+STC_INLINE Self##_value* Self##_at(const Self* self, size_t idx) \
+ { assert(idx < self->size); return self->data + idx; } \
+ \
+STC_INLINE Self##_iter Self##_begin(const Self* self) { \
+ Self##_iter it = {self->data, self->data + self->size}; \
+ return it; \
+} \
+ \
+STC_INLINE Self##_iter Self##_end(const Self* self) { \
+ Self##_iter it = {NULL, self->data + self->size}; \
+ return it; \
+} \
+ \
+STC_INLINE void Self##_next(Self##_iter* it) \
+ { if (++it->ref == it->end) it->ref = NULL; } \
+struct stc_nostruct
+
+#endif
diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h
new file mode 100644
index 00000000..10aeb7e7
--- /dev/null
+++ b/include/stc/algo/filter.h
@@ -0,0 +1,78 @@
+/* MIT License
+ *
+ * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*/
+/*
+#include <stdio.h>
+#define i_val int
+#include <stc/cstack.h>
+#include <stc/algo/filter.h>
+
+int main()
+{
+ c_WITH (cstack_int stk = {0}, cstack_int_drop(&stk)) {
+ c_FORLIST (i, int, {1, 2, 3, 4, 5, 6, 7, 8, 9})
+ cstack_int_push(&stk, i);
+
+ 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("");
+ }
+}
+*/
+#ifndef STC_FILTER_H_INCLUDED
+#define STC_FILTER_H_INCLUDED
+
+#include <stc/ccommon.h>
+
+#ifndef c_NFILTERS
+ #define c_NFILTERS 14 /* 22, 30, .. */
+#endif
+
+#define c_flt_take(i, n) (++(i).s1[(i).s1top++] <= (n))
+#define c_flt_skip(i, n) (++(i).s1[(i).s1top++] > (n))
+#define c_flt_skipwhile(i, pred) ((i).s2[(i).s2top++] |= !(pred))
+#define c_flt_takewhile(i, pred) !c_flt_skipwhile(i, pred)
+
+#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__)
+
+#define c_forfilter4(i, C, cnt, filter) \
+ c_forfilter_b(i, C, C##_begin(&cnt), filter)
+
+#define c_forfilter5(i, C, cnt, filter, cond) \
+ c_forfilter_b(i, C, C##_begin(&cnt), filter) if (!(cond)) break; else
+
+#define c_forfilter_b(i, C, start, filter) \
+ for (struct {C##_iter it; C##_value *ref; \
+ uint32_t s1[c_NFILTERS], index, count; \
+ bool s2[c_NFILTERS]; uint8_t s1top, s2top;} \
+ i = {.it=start, .ref=i.it.ref}; i.it.ref \
+ ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.s1top=0, i.s2top=0) \
+ if (!((filter) && ++i.count)) ; else
+
+#endif
diff --git a/include/stc/carc.h b/include/stc/carc.h
index 22453f1d..f14fdd65 100644
--- a/include/stc/carc.h
+++ b/include/stc/carc.h
@@ -72,7 +72,6 @@ int main() {
#endif
#define carc_NULL {NULL, NULL}
-#define _cx_carc_rep struct _cx_memb(_rep_)
#endif // CARC_H_INCLUDED
#ifndef _i_prefix
@@ -91,7 +90,7 @@ typedef i_keyraw _cx_raw;
#if !c_option(c_is_forward)
_cx_deftypes(_c_carc_types, _cx_self, i_key);
#endif
-_cx_carc_rep { catomic_long counter; i_key value; };
+struct _cx_memb(_rep_) { catomic_long counter; i_key value; };
STC_INLINE _cx_self _cx_memb(_init)(void)
{ return c_INIT(_cx_self){NULL, NULL}; }
@@ -109,7 +108,7 @@ STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) {
// c++: std::make_shared<_cx_value>(val)
STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) {
_cx_self ptr;
- _cx_carc_rep *rep = c_alloc(_cx_carc_rep);
+ struct _cx_memb(_rep_)* rep = c_alloc(struct _cx_memb(_rep_));
*(ptr.use_count = &rep->counter) = 1;
*(ptr.get = &rep->value) = val;
return ptr;
@@ -127,7 +126,7 @@ STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) {
STC_INLINE void _cx_memb(_drop)(_cx_self* self) {
if (self->use_count && _i_atomic_dec_and_test(self->use_count)) {
i_keydrop(self->get);
- if ((char *)self->get != (char *)self->use_count + offsetof(_cx_carc_rep, value))
+ if ((char *)self->get != (char *)self->use_count + offsetof(struct _cx_memb(_rep_), value))
c_free(self->get);
c_free((long*)self->use_count);
}
@@ -158,17 +157,17 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) {
return ptr;
}
-STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) {
+STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) {
if (ptr.use_count)
_i_atomic_inc(ptr.use_count);
_cx_memb(_drop)(self);
*self = ptr;
}
-STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self ptr) {
- if (self->get != ptr.get)
+STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self unowned) {
+ if (self->get != unowned.get)
_cx_memb(_drop)(self);
- *self = ptr;
+ *self = unowned;
}
#ifndef i_no_cmp
diff --git a/include/stc/carr2.h b/include/stc/carr2.h
deleted file mode 100644
index 89ae9b77..00000000
--- a/include/stc/carr2.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#include "ccommon.h"
-
-#ifndef CARR2_H_INCLUDED
-#define CARR2_H_INCLUDED
-#include "forward.h"
-#include <stdlib.h>
-#endif
-/*
-// carr2- 2D dynamic array in one memory block with easy indexing.
-#define i_key int
-#include <stc/carr2.h>
-#include <stdio.h>
-
-int main() {
- int w = 7, h = 5;
- c_with (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image))
- {
- int *dat = carr2_int_data(&image);
- for (int i = 0; i < carr2_int_size(&image); ++i)
- dat[i] = i;
-
- for (int x = 0; x < image.xdim; ++x)
- for (int y = 0; y < image.ydim; ++y)
- printf(" %d", image.data[x][y]);
- puts("\n");
-
- c_foreach (i, carr2_int, image)
- printf(" %d", *i.ref);
- puts("");
- }
-}
-*/
-
-#ifndef _i_prefix
-#define _i_prefix carr2_
-#endif
-#include "priv/template.h"
-#if !c_option(c_is_forward)
-_cx_deftypes(_c_carr2_types, _cx_self, i_key);
-#endif
-
-STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null);
-STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* storage);
-STC_API _cx_value* _cx_memb(_release)(_cx_self* self);
-STC_API void _cx_memb(_drop)(_cx_self* self);
-#if !defined i_no_clone
-STC_API _cx_self _cx_memb(_clone)(_cx_self src);
-STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other);
-#endif
-
-STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim) {
- return _cx_memb(_with_data)(xdim, ydim, c_alloc_n(_cx_value, xdim*ydim));
-}
-STC_INLINE size_t _cx_memb(_size)(const _cx_self* self)
- { return self->xdim*self->ydim; }
-
-STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self)
- { return *self->data; }
-
-STC_INLINE const _cx_value *_cx_memb(_at)(const _cx_self* self, size_t x, size_t y) {
- assert(x < self->xdim && y < self->ydim);
- return *self->data + self->ydim*x + y;
-}
-
-STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) {
- return self->ydim*x + y;
-}
-
-
-STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
- size_t n = self->xdim*self->ydim;
- return c_INIT(_cx_iter){n ? *self->data : NULL, *self->data + n};
-}
-
-STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_INIT(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; }
-
-STC_INLINE void _cx_memb(_next)(_cx_iter* it)
- { if (++it->ref == it->end) it->ref = NULL; }
-
-/* -------------------------- IMPLEMENTATION ------------------------- */
-#if defined(i_implement)
-
-STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* block) {
- _cx_self _arr = {c_alloc_n(_cx_value*, xdim), xdim, ydim};
- for (size_t x = 0; x < xdim; ++x, block += ydim)
- _arr.data[x] = block;
- return _arr;
-}
-
-STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) {
- _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim);
- for (_cx_value* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p)
- *p = null;
- return _arr;
-}
-
-#if !defined i_no_clone
-
-STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) {
- _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim);
- for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q)
- *p = i_keyclone((*q));
- return _arr;
-}
-
-STC_DEF void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
- if (self->data == other->data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other);
-}
-#endif
-
-STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) {
- _cx_value *values = self->data[0];
- c_free(self->data);
- self->data = NULL;
- return values;
-}
-
-STC_DEF void _cx_memb(_drop)(_cx_self* self) {
- if (!self->data) return;
- for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(self); p != q; ) {
- --q; i_keydrop(q);
- }
- c_free(self->data[0]); /* values */
- c_free(self->data); /* pointers */
-}
-
-#endif
-#include "priv/template.h"
diff --git a/include/stc/carr3.h b/include/stc/carr3.h
deleted file mode 100644
index d167dd69..00000000
--- a/include/stc/carr3.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#include "ccommon.h"
-
-#ifndef CARR3_H_INCLUDED
-#define CARR3_H_INCLUDED
-#include "forward.h"
-#include <stdlib.h>
-#endif
-/*
-// carr3 - 3D dynamic array in one memory block with easy indexing.
-#define i_key int
-#include <stc/carr3.h>
-#include <stdio.h>
-
-int main() {
- int w = 7, h = 5, d = 3;
- c_with (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image))
- {
- int *dat = carr3_int_data(&image);
- for (int i = 0; i < carr3_int_size(&image); ++i)
- dat[i] = i;
-
- for (int x = 0; x < image.xdim; ++x)
- for (int y = 0; y < image.ydim; ++y)
- for (int z = 0; z < image.zdim; ++z)
- printf(" %d", image.data[x][y][z]);
- puts("\n");
-
- c_foreach (i, carr3_int, image)
- printf(" %d", *i.ref);
- puts("");
- }
-}
-*/
-
-#ifndef _i_prefix
-#define _i_prefix carr3_
-#endif
-#include "priv/template.h"
-
-#if !c_option(c_is_forward)
-_cx_deftypes(_c_carr3_types, _cx_self, i_key);
-#endif
-
-STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null);
-STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage);
-STC_API _cx_value* _cx_memb(_release)(_cx_self* self);
-STC_API void _cx_memb(_drop)(_cx_self* self);
-#if !defined i_no_clone
-STC_API _cx_self _cx_memb(_clone)(_cx_self src);
-STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other);
-#endif
-
-STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim, size_t zdim) {
- return _cx_memb(_with_data)(xdim, ydim, zdim, c_alloc_n(_cx_value, xdim*ydim*zdim));
-}
-
-STC_INLINE size_t _cx_memb(_size)(const _cx_self* self)
- { return self->xdim*self->ydim*self->zdim; }
-
-STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self)
- { return **self->data; }
-
-STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t x, size_t y, size_t z) {
- assert(x < self->xdim && y < self->ydim && z < self->zdim);
- return **self->data + self->zdim*(self->ydim*x + y) + z;
-}
-
-STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_t z) {
- return self->zdim*(self->ydim*x + y) + z;
-}
-
-
-STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
- size_t n = _cx_memb(_size)(self);
- return c_INIT(_cx_iter){n ? **self->data : NULL, **self->data + n};
-}
-
-STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_INIT(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; }
-
-STC_INLINE void _cx_memb(_next)(_cx_iter* it)
- { if (++it->ref == it->end) it->ref = NULL; }
-
-/* -------------------------- IMPLEMENTATION ------------------------- */
-#if defined(i_implement)
-
-STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* block) {
- _cx_self _arr = {c_alloc_n(_cx_value**, xdim*(ydim + 1)), xdim, ydim, zdim};
- _cx_value** p = (_cx_value**) &_arr.data[xdim];
- for (size_t x = 0, y; x < xdim; ++x, p += ydim)
- for (y = 0, _arr.data[x] = p; y < ydim; ++y, block += zdim)
- p[y] = block;
- return _arr;
-}
-
-STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null) {
- _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim, zdim);
- for (_cx_value* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p)
- *p = null;
- return _arr;
-}
-
-#if !defined i_no_clone
-
-STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) {
- _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim, src.zdim);
- for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q)
- *p = i_keyclone((*q));
- return _arr;
-}
-
-STC_DEF void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
- if (self->data == other->data) return;
- _cx_memb(_drop)(self); *self = _cx_memb(_clone)(*other);
-}
-#endif
-
-STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) {
- _cx_value *values = self->data[0][0];
- c_free(self->data);
- self->data = NULL;
- return values;
-}
-
-STC_DEF void _cx_memb(_drop)(_cx_self* self) {
- if (!self->data) return;
- for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(self); p != q; ) {
- --q; i_keydrop(q);
- }
- c_free(self->data[0][0]); /* data */
- c_free(self->data); /* pointers */
-}
-
-#endif
-#include "priv/template.h"
diff --git a/include/stc/cbox.h b/include/stc/cbox.h
index bcb1b275..b8a61375 100644
--- a/include/stc/cbox.h
+++ b/include/stc/cbox.h
@@ -77,7 +77,7 @@ typedef i_keyraw _cx_raw;
_cx_deftypes(_c_cbox_types, _cx_self, i_key);
#endif
-// constructors (takes ownsership)
+// constructors (take ownership)
STC_INLINE _cx_self _cx_memb(_init)(void)
{ return c_INIT(_cx_self){NULL}; }
@@ -110,6 +110,9 @@ STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) {
return ptr;
}
+STC_INLINE _cx_value* _cx_memb(_release)(_cx_self* self)
+ { return _cx_memb(_move)(self).get; }
+
STC_INLINE void _cx_memb(_reset)(_cx_self* self) {
_cx_memb(_drop)(self);
self->get = NULL;
@@ -117,8 +120,7 @@ STC_INLINE void _cx_memb(_reset)(_cx_self* self) {
// take ownership of p
STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
- if (self->get)
- i_keydrop(self->get);
+ _cx_memb(_drop)(self);
self->get = p;
}
@@ -140,10 +142,18 @@ STC_INLINE _cx_self _cx_memb(_from)(_cx_value val)
}
#endif // !i_no_clone
-STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self other) {
- if (other.get != self->get)
+STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self unowned) {
+ if (unowned.get != self->get)
_cx_memb(_drop)(self);
- *self = other;
+ *self = unowned;
+}
+/* transfer ownership; set dying to NULL */
+STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self* dying) {
+ if (dying->get == self->get)
+ return;
+ _cx_memb(_drop)(self);
+ *self = *dying;
+ dying->get = NULL;
}
#ifndef i_no_cmp
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index af6b52a5..95c35915 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -29,6 +29,7 @@
#include <stdbool.h>
#include <string.h>
#include <assert.h>
+#include "priv/allcaps.h"
#if SIZE_MAX == UINT32_MAX
#define c_ZU PRIu32
diff --git a/include/stc/cregex.h b/include/stc/cregex.h
index b6e33879..975bd675 100644
--- a/include/stc/cregex.h
+++ b/include/stc/cregex.h
@@ -127,15 +127,15 @@ cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsi
static inline
cstr cregex_replace(const cregex* re, const char* input, const char* replace) {
csview sv = {input, strlen(input)};
- return cregex_replace_sv(re, sv, replace, 0, NULL, CREG_DEFAULT);
+ return cregex_replace_sv(re, sv, replace, ~0U, NULL, CREG_DEFAULT);
}
/* replace + compile RE pattern, and extra arguments */
-cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count,
- bool (*mfun)(int i, csview match, cstr* mstr), int crflags);
+cstr cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count,
+ bool (*mfun)(int i, csview match, cstr* mstr), int crflags);
static inline
cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace)
- { return cregex_replace_pattern_n(pattern, input, replace, 0, NULL, CREG_DEFAULT); }
+ { return cregex_replace_pattern_ex(pattern, input, replace, ~0U, NULL, CREG_DEFAULT); }
/* destroy regex */
void cregex_drop(cregex* self);
diff --git a/include/stc/cstack.h b/include/stc/cstack.h
index 73d0e2e1..5e87cf9f 100644
--- a/include/stc/cstack.h
+++ b/include/stc/cstack.h
@@ -68,7 +68,7 @@ STC_INLINE _cx_self _cx_memb(_with_size)(size_t size, i_key null) {
while (size) out.data[--size] = null;
return out;
}
-#endif
+#endif // i_capacity
STC_INLINE void _cx_memb(_clear)(_cx_self* self) {
_cx_value *p = self->data + self->_len;
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index 6f774135..9748b72c 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -88,7 +88,6 @@ STC_API void cstr_u8_erase(cstr* self, size_t bytepos, size_t u8len);
STC_API cstr cstr_from_fmt(const char* fmt, ...);
STC_API size_t cstr_append_fmt(cstr* self, const char* fmt, ...);
STC_API size_t cstr_printf(cstr* self, const char* fmt, ...);
-STC_API void cstr_replace(cstr* self, const char* search, const char* repl, unsigned count);
STC_API cstr cstr_replace_sv(csview sv, csview search, csview repl, unsigned count);
STC_INLINE cstr_buf cstr_buffer(cstr* s) {
@@ -376,6 +375,12 @@ STC_INLINE char* cstr_append_s(cstr* self, cstr s) {
return cstr_append_n(self, sv.str, sv.size);
}
+STC_INLINE void cstr_replace_ex(cstr* self, const char* search, const char* repl, unsigned count) {
+ cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(search, strlen(search)),
+ c_SV(repl, strlen(repl)), count));
+}
+STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl)
+ { cstr_replace_ex(self, search, repl, ~0U); }
STC_INLINE void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview repl) {
char* d = _cstr_internal_move(self, pos + len, pos + repl.size);
@@ -388,7 +393,7 @@ STC_INLINE void cstr_replace_at(cstr* self, size_t pos, size_t len, const char*
STC_INLINE void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl)
{ cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); }
-STC_INLINE void cstr_u8_replace(cstr* self, size_t bytepos, size_t u8len, csview repl)
+STC_INLINE void cstr_u8_replace_at(cstr* self, size_t bytepos, size_t u8len, csview repl)
{ cstr_replace_at_sv(self, bytepos, utf8_pos(cstr_str(self) + bytepos, u8len), repl); }
@@ -583,13 +588,6 @@ cstr_replace_sv(csview in, csview search, csview repl, unsigned count) {
return out;
}
-STC_DEF void
-cstr_replace(cstr* self, const char* search, const char* repl, unsigned count) {
- csview in = cstr_sv(self);
- cstr_take(self, cstr_replace_sv(in, c_SV(search, strlen(search)),
- c_SV(repl, strlen(repl)), count));
-}
-
STC_DEF void cstr_erase(cstr* self, const size_t pos, size_t len) {
cstr_buf r = cstr_buffer(self);
if (len > r.size - pos) len = r.size - pos;
diff --git a/include/stc/priv/allcaps.h b/include/stc/priv/allcaps.h
new file mode 100644
index 00000000..1e2460b5
--- /dev/null
+++ b/include/stc/priv/allcaps.h
@@ -0,0 +1,56 @@
+/* MIT License
+ *
+ * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#define c_ALLOC c_alloc
+#define c_ALLOC_N c_alloc_n
+#define c_NEW c_new
+#define c_MALLOC c_malloc
+#define c_CALLOC c_calloc
+#define c_REALLOC c_realloc
+#define c_FREE c_free
+#define c_DELETE c_delete
+#define c_SWAP c_swap
+#define c_CONTAINER_OF c_container_of
+#define c_STATIC_ASSERT c_static_assert
+#define c_ARRAYLEN c_arraylen
+#define c_OPTION c_option
+#define c_FORLIST c_forlist
+#define c_FORRANGE c_forrange
+#define c_FOREACH c_foreach
+#define c_FORWHILE c_forwhile
+#define c_FORPAIR c_forpair
+#define c_FORFILTER c_forfilter
+#define c_FORMATCH c_formatch
+#define c_FORTOKEN c_fortoken
+#define c_FORTOKEN_SV c_fortoken_sv
+#define c_AUTO c_auto
+#define c_AUTODROP c_autodrop
+#define c_WITH c_with
+#define c_SCOPE c_scope
+#define c_DEFER c_defer
+#define c_DROP c_drop
+#define c_FIND_IF c_find_if
+#define c_ERASE_IF c_erase_if
+#define c_FLT_TAKE c_flt_take
+#define c_FLT_SKIP c_flt_skip
+#define c_FLT_SKIPWHILE c_flt_skipwhile
+#define c_FLT_TAKEWHILE c_flt_takewhile
diff --git a/include/stc/views.h b/include/stc/views.h
deleted file mode 100644
index 8f7a0d78..00000000
--- a/include/stc/views.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
-*/
-/*
-#include <stdio.h>
-#include <stc/views.h>
-using_clview(IView, int);
-
-int main()
-{
- int array[] = {1, 2, 3, 4, 5};
- IView iv = {array, c_arraylen(array)};
-
- c_foreach (i, IView, iv)
- printf(" %d", *i.ref);
- puts("");
-
- // use a temporary IView object.
- c_forfilter (i, IView, clview_literal(IView, {10, 20, 30, 23, 22, 21})
- , c_flt_skipwhile(i, *i.ref < 25)
- && (*i.ref & 1) == 0 // even only
- , c_flt_take(i, 2)) // break after 2
- printf(" %d", *i.ref);
- puts("");
-
- // crange:
-
- crange r1 = crange_make(80, 90);
- c_foreach (i, crange, r1)
- printf(" %lld", *i.ref);
- puts("");
-
- // use a temporary crange object.
- int a = 100, b = INT32_MAX;
- c_forfilter (i, crange, crange_literal(a, b, 8)
- , i.index > 10
- , c_flt_take(i, 3))
- printf(" %lld", *i.ref);
- puts("");
-}
-*/
-#ifndef STC_VIEWS_H_INCLUDED
-#define STC_VIEWS_H_INCLUDED
-
-#include <stc/ccommon.h>
-
-#ifndef c_FLT_STACK
- #define c_FLT_STACK 14 /* 22, 30, .. */
-#endif
-#define c_flt_take(i, n) (++(i).s1[(i).s1top++] <= (n))
-#define c_flt_skip(i, n) (++(i).s1[(i).s1top++] > (n))
-#define c_flt_skipwhile(i, pred) ((i).s2[(i).s2top++] |= !(pred))
-#define c_flt_takewhile(i, pred) !c_flt_skipwhile(i, pred)
-
-#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__)
-#define c_forfilter4(i, C, cnt, filter) \
- c_forfilter_s(i, C, C##_begin(&cnt), filter)
-#define c_forfilter5(i, C, cnt, filter, cond) \
- c_forfilter_s(i, C, C##_begin(&cnt), filter) if (!(cond)) break; else
-#define c_forfilter_s(i, C, start, filter) \
- for (struct {C##_iter it; C##_value *ref; \
- uint32_t s1[c_FLT_STACK], index, count; \
- bool s2[c_FLT_STACK]; uint8_t s1top, s2top;} \
- i = {.it=start, .ref=i.it.ref}; i.it.ref \
- ; C##_next(&i.it), i.ref = i.it.ref, ++i.index, i.s1top=0, i.s2top=0) \
- if (!((filter) && ++i.count)) ; else
-
-
-// clview type
-
-#define clview_literal(C, ...) \
- ((C){.data = (C##_value[])__VA_ARGS__, \
- .size = sizeof((C##_value[])__VA_ARGS__)/sizeof(C##_value)})
-
-#define using_clview(Self, T) \
-typedef T Self##_raw; typedef const Self##_raw Self##_value; \
-typedef struct { Self##_value *data; size_t size; } Self; \
-typedef struct { Self##_value *ref, *end; } Self##_iter; \
- \
-STC_INLINE Self##_value* Self##_at(const Self* self, size_t idx) \
- { assert(idx < self->size); return self->data + idx; } \
- \
-STC_INLINE Self##_iter Self##_begin(const Self* self) { \
- Self##_iter it = {self->data, self->data + self->size}; \
- return it; \
-} \
- \
-STC_INLINE Self##_iter Self##_end(const Self* self) { \
- Self##_iter it = {NULL, self->data + self->size}; \
- return it; \
-} \
- \
-STC_INLINE void Self##_next(Self##_iter* it) \
- { if (++it->ref == it->end) it->ref = NULL; } \
-struct stc_nostruct
-
-
-// crange type
-
-#define crange_literal(...) \
- (*(crange[]){crange_make(__VA_ARGS__)})
-
-typedef long long crange_value;
-typedef struct { crange_value start, end, step, value; } crange;
-typedef struct { crange_value *ref, end, step; } crange_iter;
-
-#define crange_make(...) c_MACRO_OVERLOAD(crange_make, __VA_ARGS__)
-#define crange_make1(stop) crange_make3(0, stop, 1)
-#define crange_make2(start, stop) crange_make3(start, stop, 1)
-
-STC_INLINE crange crange_make3(crange_value start, crange_value stop, crange_value step)
- { crange r = {start, stop - (step > 0), step}; return r; }
-
-STC_INLINE crange_iter crange_begin(crange* self)
- { self->value = self->start; crange_iter it = {&self->value, 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; }
-
-#endif