diff options
| author | Tyge Løvset <[email protected]> | 2022-12-29 00:28:50 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-12-29 00:28:50 +0100 |
| commit | 0761c13f316cc98ae7756f3527931aa86bed5016 (patch) | |
| tree | e90777558956fcf91d6b1c958e0c3a6fb0ab007f | |
| parent | d623c6c85071b9af5d607bb5d9aceceaea05220a (diff) | |
| download | STC-modified-0761c13f316cc98ae7756f3527931aa86bed5016.tar.gz STC-modified-0761c13f316cc98ae7756f3527931aa86bed5016.zip | |
Restructuring of some headers into include/algo folder. Some API changes *_replace*() functions have been renamed, and a few minor API changes.
| -rw-r--r-- | README.md | 11 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 4 | ||||
| -rw-r--r-- | docs/cregex_api.md | 4 | ||||
| -rw-r--r-- | docs/cstr_api.md | 7 | ||||
| -rw-r--r-- | docs/csview_api.md | 2 | ||||
| -rw-r--r-- | include/stc/algo/crange.h | 72 | ||||
| -rw-r--r-- | include/stc/algo/csort.h | 127 | ||||
| -rw-r--r-- | include/stc/algo/cspan.h | 77 | ||||
| -rw-r--r-- | include/stc/algo/filter.h | 76 | ||||
| -rw-r--r-- | include/stc/carc.h | 7 | ||||
| -rw-r--r-- | include/stc/cbox.h | 8 | ||||
| -rw-r--r-- | include/stc/cregex.h | 8 | ||||
| -rw-r--r-- | include/stc/cstack.h | 3 | ||||
| -rw-r--r-- | include/stc/cstr.h | 16 | ||||
| -rw-r--r-- | include/stc/views.h | 142 | ||||
| -rw-r--r-- | misc/examples/cpque.c | 2 | ||||
| -rw-r--r-- | misc/examples/demos.c | 2 | ||||
| -rw-r--r-- | misc/examples/forfilter.c | 8 | ||||
| -rw-r--r-- | misc/examples/forloops.c | 2 | ||||
| -rw-r--r-- | misc/examples/prime.c | 6 | ||||
| -rw-r--r-- | misc/examples/regex_replace.c | 4 | ||||
| -rw-r--r-- | misc/examples/utf8replace_c.c | 4 | ||||
| -rw-r--r-- | misc/include/alt/cstr.h | 11 | ||||
| -rw-r--r-- | src/cregex.c | 4 |
24 files changed, 411 insertions, 196 deletions
@@ -26,26 +26,25 @@ in the future, and do minor modifications. Containers ---------- -- [***ccommon*** - Generic algorithms and macros](docs/ccommon_api.md) - [***carc*** - **std::shared_ptr** alike type](docs/carc_api.md) -- [***carr2***, ***carr3*** - 2D and 3D **array** types](docs/carray_api.md) -- [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***cbox*** - **std::unique_ptr** alike type](docs/cbox_api.md) -- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) +- [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***clist*** - **std::forward_list** alike type](docs/clist_api.md) -- [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md) -- [***cpque*** - **std::priority_queue** alike type](docs/cpque_api.md) - [***cqueue*** - **std::queue** alike type](docs/cqueue_api.md) +- [***cpque*** - **std::priority_queue** alike type](docs/cpque_api.md) +- [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md) - [***cset*** - **std::unordered_set** alike type](docs/cset_api.md) - [***csmap*** - **std::map** sorted map alike type](docs/csmap_api.md) - [***csset*** - **std::set** sorted set alike type](docs/csset_api.md) - [***cstack*** - **std::stack** alike type](docs/cstack_api.md) - [***cstr*** - **std::string** alike type](docs/cstr_api.md) - [***csview*** - **std::string_view** alike type](docs/csview_api.md) +- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) - [***cvec*** - **std::vector** alike type](docs/cvec_api.md) Others ------ +- [***ccommon*** - Generic algorithms and macros](docs/ccommon_api.md) - [***cregex*** - Regular expression parser (extended from Rob Pike's regexp9)](docs/cregex_api.md) - [***crandom*** - A novel very fast *PRNG* named **stc64**](docs/crandom_api.md) - [***coption*** - getopt() alike command line args parser](docs/coption_api.md) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index a9961002..474c80ac 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -288,13 +288,13 @@ c_FORFILTER (i, crange, r1 // 2. The 11 first primes: printf("2"); -c_FORFILTER (i, crange, crange_literal(3, crange_MAX, 2) +c_FORFILTER (i, crange, crange_LITERAL(3, INT64_MAX, 2) , isPrime(*i.ref) , c_FLT_TAKE(10)) printf(" %lld", *i.ref); // 2 3 5 7 11 13 17 19 23 29 31 ``` -### c_FIND_IF, c_find_in, c_ERASE_IF +### c_FIND_IF, c_ERASE_IF Find or erase linearily in containers using a predicate ```c // Search vec for first value > 2: diff --git a/docs/cregex_api.md b/docs/cregex_api.md index 1b3c03d6..3197a59e 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -48,8 +48,8 @@ cstr cregex_replace_sv(const cregex* re, csview input, const char* replac /* All-in-one replacement (compile + find/replace + drop) */ cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace); -cstr cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, - bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); +cstr cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count, + bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags); void cregex_drop(cregex* self); /* destroy */ ``` diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 3857633a..0ee8b2cb 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -68,7 +68,8 @@ void cstr_insert_s(cstr* self, size_t pos, cstr ins); void cstr_erase(cstr* self, size_t pos, size_t len); // erase len bytes from pos -void cstr_replace(cstr* self, const char* search, const char* repl, unsigned count); // count==0: replace all. +void cstr_replace(cstr* self, const char* search, const char* repl); +void cstr_replace_ex(cstr* self, const char* search, const char* repl, unsigned count); cstr cstr_replace_sv(csview in, csview search, csview repl, unsigned count); void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* repl); // replace at a position void cstr_replace_at_sv(cstr* self, size_t pos, size_t len, const csview repl); @@ -101,7 +102,7 @@ size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 si size_t cstr_u8_to_pos(const cstr* self, size_t u8idx); // byte pos offset at utf8 codepoint index const char* cstr_u8_at(const cstr* self, size_t u8idx); // char* position at utf8 codepoint index csview cstr_u8_chr(const cstr* self, size_t u8idx); // get utf8 character as a csview -void cstr_u8_replace(cstr* self, size_t bytepos, size_t u8len, csview repl); // replace u8len utf8 chars +void cstr_u8_replace_at(cstr* self, size_t bytepos, size_t u8len, csview repl); // replace u8len utf8 chars void cstr_u8_erase(cstr* self, size_t bytepos, size_t u8len); // erase u8len codepoints from pos // iterate utf8 codepoints @@ -173,7 +174,7 @@ int main() { cstr_erase(&s1, 7, 5); // -nine printf("%s\n", cstr_str(&s1)); - cstr_replace(&s1, "seven", "four", 1); + cstr_replace_ex(&s1, "seven", "four", 1); printf("%s\n", cstr_str(&s1)); // reassign: diff --git a/docs/csview_api.md b/docs/csview_api.md index 05348745..b5508ace 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -153,7 +153,7 @@ int main() { c_AUTO (cstr, s1) { s1 = cstr_lit("hell😀 w😀rld"); - cstr_u8_replace(&s1, cstr_find(&s1, "😀rld"), 1, c_SV("ø")); + cstr_u8_replace_at(&s1, cstr_find(&s1, "😀rld"), 1, c_SV("ø")); printf("%s\n", cstr_str(&s1)); c_FOREACH (i, cstr, s1) 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..486568f2 --- /dev/null +++ b/include/stc/algo/filter.h @@ -0,0 +1,76 @@ +/* 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 +#define i_capacity 10 +#include <stc/cstack.h> +#include <stc/algo/filter.h> + +int main() +{ + cstack_int stk = cstack_INITIALIZER(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(""); +} +*/ +#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..7f7789ab 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); } diff --git a/include/stc/cbox.h b/include/stc/cbox.h index bcb1b275..a0966fcc 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; } 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..e4b64848 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -52,6 +52,9 @@ STC_INLINE _cx_self _cx_memb(_init)(void) { } #ifdef i_capacity +#define cstack_INITIALIZER(T, ...) \ + {.data=__VA_ARGS__, ._len=sizeof((T[])__VA_ARGS__)/sizeof(T)} + STC_INLINE void _cx_memb(_create)(_cx_self* self) { self->_len = 0; } #else 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/views.h b/include/stc/views.h deleted file mode 100644 index ea5f4536..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_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_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_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 - - -// 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 diff --git a/misc/examples/cpque.c b/misc/examples/cpque.c index 47080038..2ec841ae 100644 --- a/misc/examples/cpque.c +++ b/misc/examples/cpque.c @@ -8,7 +8,7 @@ #include <stdio.h> #include <stdbool.h> #include <stc/forward.h> -#include <stc/views.h> +#include <stc/algo/crange.h> #include <stc/cstr.h> // predeclare diff --git a/misc/examples/demos.c b/misc/examples/demos.c index b077aa73..4a9fac89 100644 --- a/misc/examples/demos.c +++ b/misc/examples/demos.c @@ -13,7 +13,7 @@ void stringdemo1() cstr_erase(&cs, 7, 5); // -nine printf("%s.\n", cstr_str(&cs)); - cstr_replace(&cs, "seven", "four", 1); + cstr_replace_ex(&cs, "seven", "four", 1); printf("%s.\n", cstr_str(&cs)); cstr_take(&cs, cstr_from_fmt("%s *** %s", cstr_str(&cs), cstr_str(&cs))); diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c index 32154904..c0a4ccad 100644 --- a/misc/examples/forfilter.c +++ b/misc/examples/forfilter.c @@ -2,7 +2,8 @@ #define i_extern #include <stc/cstr.h> #include <stc/csview.h> -#include <stc/views.h> +#include <stc/algo/filter.h> +#include <stc/algo/crange.h> #define i_type IVec #define i_val int @@ -63,12 +64,13 @@ void demo2(void) c_AUTO (IVec, vector) { puts("demo2:"); - c_FORFILTER (x, crange, crange_literal(INT64_MAX) + c_FORFILTER (x, crange, crange_LITERAL(INT64_MAX) , c_FLT_SKIPWHILE(x, *x.ref != 11) && *x.ref % 2 != 0 , c_FLT_TAKE(x, 5)) IVec_push(&vector, *x.ref * *x.ref); - c_FOREACH (x, IVec, vector) printf(" %d", *x.ref); + c_FOREACH (x, IVec, vector) + printf(" %d", *x.ref); puts(""); } } diff --git a/misc/examples/forloops.c b/misc/examples/forloops.c index 95a955a3..69c1c193 100644 --- a/misc/examples/forloops.c +++ b/misc/examples/forloops.c @@ -1,5 +1,5 @@ #include <stdio.h>
-#include <stc/views.h>
+#include <stc/algo/filter.h>
#define i_type IVec
#define i_val int
diff --git a/misc/examples/prime.c b/misc/examples/prime.c index 41d637b8..f6e89e09 100644 --- a/misc/examples/prime.c +++ b/misc/examples/prime.c @@ -2,7 +2,9 @@ #include <math.h> #include <time.h> #include <stc/cbits.h> -#include <stc/views.h> +#include <stc/algo/filter.h> +#include <stc/algo/crange.h> + cbits sieveOfEratosthenes(size_t n) { @@ -41,7 +43,7 @@ int main(void) puts(""); puts("Show the last 50 primes using a temporary crange generator:"); - c_FORFILTER (i, crange, crange_literal(n - 1, 0, -2) + c_FORFILTER (i, crange, crange_LITERAL(n - 1, 0, -2) , cbits_test(&primes, *i.ref>>1) , c_FLT_TAKE(i, 50)) { printf("%lld ", *i.ref); diff --git a/misc/examples/regex_replace.c b/misc/examples/regex_replace.c index d621c0db..a170856b 100644 --- a/misc/examples/regex_replace.c +++ b/misc/examples/regex_replace.c @@ -26,11 +26,11 @@ int main() printf("fixed: %s\n", cstr_str(&str)); /* US date format, and add 10 years to dates: */ - cstr_take(&str, cregex_replace_pattern_n(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); + cstr_take(&str, cregex_replace_pattern_ex(pattern, input, "$1/$3/$2", 0, add_10_years, CREG_DEFAULT)); printf("us+10: %s\n", cstr_str(&str)); /* Wrap first date inside []: */ - cstr_take(&str, cregex_replace_pattern_n(pattern, input, "[$0]", 1, NULL, CREG_DEFAULT)); + cstr_take(&str, cregex_replace_pattern_ex(pattern, input, "[$0]", 1, NULL, CREG_DEFAULT)); printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c index 74b765dc..3645bd0a 100644 --- a/misc/examples/utf8replace_c.c +++ b/misc/examples/utf8replace_c.c @@ -8,10 +8,10 @@ int main() { printf("%s\n", cstr_str(&hello)); /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace(&hello, cstr_u8_to_pos(&hello, 7), 1, c_SV("🐨")); + cstr_u8_replace_at(&hello, cstr_u8_to_pos(&hello, 7), 1, c_SV("🐨")); printf("%s\n", cstr_str(&hello)); - cstr_replace(&hello, "🐨", "ø", 1); + cstr_replace_ex(&hello, "🐨", "ø", 1); printf("%s\n", cstr_str(&hello)); upper = cstr_toupper_sv(cstr_sv(&hello)); diff --git a/misc/include/alt/cstr.h b/misc/include/alt/cstr.h index ecb9c9fb..8de6c4b0 100644 --- a/misc/include/alt/cstr.h +++ b/misc/include/alt/cstr.h @@ -182,12 +182,12 @@ STC_INLINE uint64_t cstr_hash(const cstr *self) { return cfasthash(self->str, _cstr_p(self)->size); } -STC_INLINE void -cstr_replace(cstr* self, const char* find, const char* repl, unsigned count) { - csview in = cstr_sv(self); - cstr_take(self, cstr_replace_sv(in, c_SV(find, strlen(find)), - c_SV(repl, strlen(repl)), count)); +STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { + cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), + 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); } /* -------------------------- IMPLEMENTATION ------------------------- */ #if defined(i_implement) @@ -324,7 +324,6 @@ STC_DEF cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { cstr out = cstr_NULL; size_t from = 0; char* res; - if (count == 0) count = ~0; if (find.size) while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { const size_t pos = res - str.str; diff --git a/src/cregex.c b/src/cregex.c index c30ff967..d19b063f 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -1268,8 +1268,8 @@ cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned } cstr -cregex_replace_pattern_n(const char* pattern, const char* input, const char* replace, unsigned count, - bool (*mfun)(int, csview, cstr*), int crflags) { +cregex_replace_pattern_ex(const char* pattern, const char* input, const char* replace, unsigned count, + bool (*mfun)(int, csview, cstr*), int crflags) { cregex re = cregex_init(); if (cregex_compile(&re, pattern, crflags) != CREG_OK) assert(0); |
