summaryrefslogtreecommitdiffhomepage
path: root/include/stc/algo
diff options
context:
space:
mode:
Diffstat (limited to 'include/stc/algo')
-rw-r--r--include/stc/algo/coroutine.h117
-rw-r--r--include/stc/algo/crange.h25
-rw-r--r--include/stc/algo/csort.h89
-rw-r--r--include/stc/algo/filter.h35
-rw-r--r--include/stc/algo/raii.h51
-rw-r--r--include/stc/algo/sort.h123
6 files changed, 210 insertions, 230 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h
deleted file mode 100644
index b0ecd6b7..00000000
--- a/include/stc/algo/coroutine.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2023 Tyge Løvset
- *
- * 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_COROUTINE_INCLUDED
-#define STC_COROUTINE_INCLUDED
-/*
-#include <stdio.h>
-#include <stc/algo/coroutine.h>
-
-struct iterate {
- int max_x, max_y;
- int x, y;
- int cco_state; // required member
-};
-
-bool iterate(struct iterate* I) {
- cco_begin(I);
- for (I->x = 0; I->x < I->max_x; I->x++)
- for (I->y = 0; I->y < I->max_y; I->y++)
- cco_yield(true);
-
- cco_final:
- puts("final");
- cco_end(false);
-}
-
-int main(void) {
- struct iterate it = {.max_x=3, .max_y=3};
- int n = 0;
- while (iterate(&it))
- {
- printf("%d %d\n", it.x, it.y);
- // example of early stop:
- if (++n == 20) cco_stop(&it); // signal to stop at next
- }
- return 0;
-}
-*/
-#include <stc/ccommon.h>
-
-enum {
- cco_state_final = -1,
- cco_state_done = -2,
-};
-
-#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 0:
-
-#define cco_end(retval) \
- *_state = cco_state_done; break; \
- case -99: goto _cco_final_; \
- } \
- return retval
-
-#define cco_yield(...) c_MACRO_OVERLOAD(cco_yield, __VA_ARGS__)
-#define cco_yield_1(retval) \
- do { \
- *_state = __LINE__; return retval; \
- case __LINE__:; \
- } while (0)
-
-#define cco_yield_2(corocall2, ctx2) \
- cco_yield_3(corocall2, ctx2, )
-
-#define cco_yield_3(corocall2, ctx2, retval) \
- do { \
- *_state = __LINE__; \
- do { \
- corocall2; if (cco_suspended(ctx2)) return retval; \
- case __LINE__:; \
- } while (cco_alive(ctx2)); \
- } while (0)
-
-#define cco_final \
- case cco_state_final: \
- _cco_final_
-
-#define cco_return \
- goto _cco_final_
-
-#define cco_stop(ctx) \
- do { \
- int* _state = &(ctx)->cco_state; \
- 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 ca06c258..faeda162 100644
--- a/include/stc/algo/crange.h
+++ b/include/stc/algo/crange.h
@@ -25,16 +25,17 @@
#include <stc/algo/filter.h>
#include <stc/algo/crange.h>
-int main()
+int main(void)
{
- crange r1 = crange_make(80, 90);
+ crange r1 = crange_init(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_obj(a, b, 8),
+ crange r2 = crange_init(a, b, 8);
+ c_forfilter (i, crange, r2,
c_flt_skip(i, 10) &&
c_flt_take(i, 3))
printf(" %lld", *i.ref);
@@ -44,29 +45,27 @@ int main()
#ifndef STC_CRANGE_H_INCLUDED
#define STC_CRANGE_H_INCLUDED
-#include <stc/ccommon.h>
-
-#define crange_obj(...) \
- (*(crange[]){crange_make(__VA_ARGS__)})
+#include "../ccommon.h"
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_make_1(stop) crange_make_3(0, stop, 1)
-#define crange_make_2(start, stop) crange_make_3(start, stop, 1)
+#define crange_make crange_init // [deprecated]
+#define crange_init(...) c_MACRO_OVERLOAD(crange_init, __VA_ARGS__)
+#define crange_init_1(stop) crange_init_3(0, stop, 1)
+#define crange_init_2(start, stop) crange_init_3(start, stop, 1)
-STC_INLINE crange crange_make_3(crange_value start, crange_value stop, crange_value step)
+STC_INLINE crange crange_init_3(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)
+STC_INLINE crange_iter crange_end(crange* self)
{ crange_iter it = {NULL}; return it; }
-STC_INLINE void crange_next(crange_iter* 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
deleted file mode 100644
index 53fe9fcc..00000000
--- a/include/stc/algo/csort.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2023 Tyge Løvset
- *
- * 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"
-#include "../priv/template.h"
-
-/* Generic Quicksort in C, performs as fast as c++ std::sort().
-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>
-#define i_val int
-#include <stc/algo/csort.h>
-
-int main() {
- int arr[] = {23, 321, 5434, 25, 245, 1, 654, 33, 543, 21};
-
- csort_int(arr, c_arraylen(arr));
-
- for (int i = 0; i < c_arraylen(arr); i++)
- printf(" %d", arr[i]);
- puts("");
-}
-*/
-
-typedef i_val c_PASTE(c_CONCAT(csort_, i_tag), _value);
-
-static inline void c_PASTE(cisort_, i_tag)(i_val arr[], intptr_t lo, intptr_t hi) {
- for (intptr_t j = lo, i = lo + 1; i <= hi; 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 lo, intptr_t hi) {
- intptr_t i = lo, j;
- while (lo < hi) {
- i_val pivot = arr[lo + (hi - lo)*7/16];
- j = hi;
-
- while (i <= j) {
- while (i_less((&arr[i]), (&pivot))) ++i;
- while (i_less((&pivot), (&arr[j]))) --j;
- if (i <= j) {
- c_swap(i_val, arr+i, arr+j);
- ++i; --j;
- }
- }
- if (j - lo > hi - i) {
- c_swap(intptr_t, &lo, &i);
- c_swap(intptr_t, &hi, &j);
- }
-
- if (j - lo > 64) c_PASTE(cqsort_, i_tag)(arr, lo, j);
- else if (j > lo) c_PASTE(cisort_, i_tag)(arr, lo, j);
- lo = i;
- }
-}
-
-static inline void c_PASTE(csort_, i_tag)(i_val arr[], intptr_t n)
- { c_PASTE(cqsort_, i_tag)(arr, 0, n - 1); }
-
-#include "../priv/template2.h"
diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h
index e133577c..320cd50d 100644
--- a/include/stc/algo/filter.h
+++ b/include/stc/algo/filter.h
@@ -24,11 +24,11 @@
#include <stdio.h>
#define i_val int
#include <stc/cstack.h>
-#include <stc/calgo.h>
+#include <stc/algorithm.h>
-int main()
+int main(void)
{
- cstack_int stk = c_make(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9});
+ cstack_int stk = c_init(cstack_int, {1, 2, 3, 4, 5, 6, 7, 8, 9});
c_foreach (i, cstack_int, stk)
printf(" %d", *i.ref);
@@ -47,7 +47,7 @@ int main()
#ifndef STC_FILTER_H_INCLUDED
#define STC_FILTER_H_INCLUDED
-#include <stc/ccommon.h>
+#include "../ccommon.h"
// c_forfilter:
@@ -85,29 +85,42 @@ int main()
if (it.ref == _endref) it.ref = NULL; \
} while (0)
+#define c_all_of(boolptr, it, C, cnt, pred) do { \
+ C##_iter it; \
+ c_find_if_4(it, C, cnt, !(pred)); \
+ *(boolptr) = it.ref == NULL; \
+} while (0)
+#define c_any_of(boolptr, it, C, cnt, pred) do { \
+ C##_iter it; \
+ c_find_if_4(it, C, cnt, pred); \
+ *(boolptr) = it.ref != NULL; \
+} while (0)
+#define c_none_of(boolptr, it, C, cnt, pred) do { \
+ C##_iter it; \
+ c_find_if_4(it, C, cnt, pred); \
+ *(boolptr) = 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) { \
+ 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, _index = 0; \
+ intptr_t _n = 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) \
+ 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; \
+ C##_adjust_end_(_cnt, -_n); \
} while (0)
// ------------------------ private -------------------------
diff --git a/include/stc/algo/raii.h b/include/stc/algo/raii.h
new file mode 100644
index 00000000..584f5c59
--- /dev/null
+++ b/include/stc/algo/raii.h
@@ -0,0 +1,51 @@
+/* MIT License
+ *
+ * Copyright (c) 2023 Tyge Løvset
+ *
+ * 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_RAII_INCLUDED
+#define STC_RAII_INCLUDED
+
+#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__)
+#define c_with_2(declvar, drop) \
+ for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop)
+#define c_with_3(declvar, pred, drop) \
+ for (declvar, *_i, **_ip = &_i; _ip && (pred); _ip = 0, drop)
+
+#define c_scope(...) c_MACRO_OVERLOAD(c_scope, __VA_ARGS__)
+#define c_scope_2(init, drop) \
+ for (int _i = (init, 1); _i; _i = 0, drop)
+#define c_scope_3(init, pred, drop) \
+ for (int _i = (init, 1); _i && (pred); _i = 0, drop)
+
+#define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__)
+#define c_auto_2(C, a) \
+ c_with_2(C a = C##_init(), C##_drop(&a))
+#define c_auto_3(C, a, b) \
+ c_with_2(c_EXPAND(C a = C##_init(), b = C##_init()), \
+ (C##_drop(&b), C##_drop(&a)))
+#define c_auto_4(C, a, b, c) \
+ c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \
+ (C##_drop(&c), C##_drop(&b), C##_drop(&a)))
+#define c_auto_5(C, a, b, c, d) \
+ 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)))
+
+#endif
diff --git a/include/stc/algo/sort.h b/include/stc/algo/sort.h
new file mode 100644
index 00000000..86c9b9f1
--- /dev/null
+++ b/include/stc/algo/sort.h
@@ -0,0 +1,123 @@
+/* MIT License
+ *
+ * Copyright (c) 2023 Tyge Løvset
+ *
+ * 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.
+ */
+/* Generic Quicksort in C, performs as fast as c++ std::sort().
+template params:
+#define i_key - value type [required]
+#define i_less - less function. default: *x < *y
+#define i_type name - define {{name}}_sort_n(), else {{i_key}}array_sort_n().
+
+// ex1:
+#include <stdio.h>
+#define i_key int
+#include <stc/algo/sort.h>
+
+int main(void) {
+ int nums[] = {23, 321, 5434, 25, 245, 1, 654, 33, 543, 21};
+
+ intarray_sort_n(nums, c_arraylen(nums));
+
+ for (int i = 0; i < c_arraylen(nums); i++)
+ printf(" %d", nums[i]);
+ puts("");
+}
+
+// ex2:
+#define i_key int
+#define i_type IDeq
+#define i_more // retain input template params to be reused by sort.h
+#include <stc/cdeq.h>
+#include <stc/algo/sort.h>
+
+int main(void) {
+ IDeq nums = c_init(IDeq, {5434, 25, 245, 1, 654, 33, 543, 21});
+ IDeq_push_front(&nums, 23);
+ IDeq_push_front(&nums, 321);
+
+ IDeq_sort_n(&nums, IDeq_size(&nums));
+
+ c_foreach (i, IDeq, nums)
+ printf(" %d", *i.ref);
+ IDeq_drop(&nums);
+}
+*/
+#include "../ccommon.h"
+
+#if !defined i_key && defined i_val
+ #define i_key i_val
+#endif
+#ifndef i_type
+ #define i_at(arr, idx) (&arr[idx])
+ #ifndef i_tag
+ #define i_tag i_key
+ #endif
+ #define i_type c_PASTE(i_tag, s)
+ typedef i_key i_type;
+#endif
+#ifndef i_at
+ #define i_at(arr, idx) _cx_MEMB(_at_mut)(arr, idx)
+#endif
+#include "../priv/template.h"
+
+
+static inline void _cx_MEMB(_insertsort_ij)(_cx_Self* arr, intptr_t lo, intptr_t hi) {
+ for (intptr_t j = lo, i = lo + 1; i <= hi; j = i, ++i) {
+ i_key key = *i_at(arr, i);
+ while (j >= 0 && (i_less((&key), i_at(arr, j)))) {
+ *i_at(arr, j + 1) = *i_at(arr, j);
+ --j;
+ }
+ *i_at(arr, j + 1) = key;
+ }
+}
+
+static inline void _cx_MEMB(_sort_ij)(_cx_Self* arr, intptr_t lo, intptr_t hi) {
+ intptr_t i = lo, j;
+ while (lo < hi) {
+ i_key pivot = *i_at(arr, lo + (hi - lo)*7/16);
+ j = hi;
+
+ while (i <= j) {
+ while (i_less(i_at(arr, i), (&pivot))) ++i;
+ while (i_less((&pivot), i_at(arr, j))) --j;
+ if (i <= j) {
+ c_swap(i_key, i_at(arr, i), i_at(arr, j));
+ ++i; --j;
+ }
+ }
+ if (j - lo > hi - i) {
+ c_swap(intptr_t, &lo, &i);
+ c_swap(intptr_t, &hi, &j);
+ }
+
+ if (j - lo > 64) _cx_MEMB(_sort_ij)(arr, lo, j);
+ else if (j > lo) _cx_MEMB(_insertsort_ij)(arr, lo, j);
+ lo = i;
+ }
+}
+
+static inline void _cx_MEMB(_sort_n)(_cx_Self* arr, intptr_t len) {
+ _cx_MEMB(_sort_ij)(arr, 0, len - 1);
+}
+
+#include "../priv/template2.h"
+#undef i_at