summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-02-14 07:54:01 +0100
committerGitHub <[email protected]>2023-02-14 07:54:01 +0100
commite456085a392d063df1a2495422523a2474ea6a18 (patch)
tree363250af394400d0fb6a33763f5a89acd1b4dd61
parent7dc6fddc079f4f572c8fb7c0ffd5a27e03291a2d (diff)
parent6df7f90dbabf7f60e37109335f2cb8f8b6b5d02f (diff)
downloadSTC-modified-e456085a392d063df1a2495422523a2474ea6a18.tar.gz
STC-modified-e456085a392d063df1a2495422523a2474ea6a18.zip
Merge pull request #48 from tylov/dev411
Release V4.1.1
-rw-r--r--README.md80
-rw-r--r--docs/cbits_api.md40
-rw-r--r--docs/ccommon_api.md133
-rw-r--r--docs/cregex_api.md8
-rw-r--r--docs/cspan_api.md18
-rw-r--r--docs/csview_api.md28
-rw-r--r--include/stc/algo/filter.h8
-rw-r--r--include/stc/cbits.h74
-rw-r--r--include/stc/ccommon.h16
-rw-r--r--include/stc/cstr.h16
-rw-r--r--include/stc/csview.h8
-rw-r--r--include/stc/priv/altnames.h3
-rw-r--r--include/stc/utf8.h2
-rw-r--r--misc/examples/cstr_match.c4
-rw-r--r--misc/examples/forfilter.c4
-rw-r--r--misc/examples/prime.c14
-rw-r--r--misc/examples/regex2.c2
-rw-r--r--misc/examples/replace.c4
-rw-r--r--misc/examples/splitstr.c4
-rw-r--r--misc/examples/sso_substr.c2
-rw-r--r--misc/examples/sview_split.c4
-rw-r--r--misc/examples/utf8replace_c.c4
22 files changed, 240 insertions, 236 deletions
diff --git a/README.md b/README.md
index 84795f2d..f74ee916 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
STC - Smart Template Containers for C
=====================================
-News: Version 4.1 Released (Feb 2023)
+News: Version 4.1.1 Released (Feb 2023)
------------------------------------------------
I am happy to finally announce a new release! Major changes:
- A new exciting [**cspan**](docs/cspan_api.md) single/multi-dimensional array view (with numpy-like slicing).
@@ -12,11 +12,12 @@ I am happy to finally announce a new release! Major changes:
- Updates on **cregex** with several [new unicode character classes](docs/cregex_api.md#regex-cheatsheet).
- Algorithms:
- [crange](docs/ccommon_api.md#crange) - similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html) integer range generator.
- - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like filtering.
- - [csort](misc/benchmarks/various/csort_bench.c) - fast quicksort with custom inline comparison.
+ - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like view filtering.
+ - [csort](include/stc/algo/csort.h) - [fast quicksort](misc/benchmarks/various/csort_bench.c) with custom inline comparison.
+- Renamed `c_ARGSV()` => `c_SV()`: **csview** print arg. Note `c_sv()` is shorthand for *csview_from()*.
- Support for [uppercase flow-control](include/stc/priv/altnames.h) macro names in ccommon.h.
+- Some API changes in **cregex** and **cstr**.
- Create single header container versions with python script.
-- Some API changes in cregex and cstr.
- [Previous changes for version 4](#version-4).
Introduction
@@ -132,9 +133,9 @@ for lookup in containers. E.g. for containers with string type (**cstr**) elemen
as lookup type. It will then use the input `const char*` directly when comparing with the string data in the
container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup.
Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which
-is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used for adding
-entries into containers through using the *emplace*-functions. E.g. `MyCStrVec_emplace_back(&vec, "Hello")`.
-3. ***Standardized container iterators***. All container can be iterated the same way, and uses the
+is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used when adding
+entries into containers through using the *emplace*-functions. E.g. `cvec_str_emplace_back(&vec, "Hello")`.
+3. ***Standardized container iterators***. All container can be iterated in similar manner, and uses the
same element access syntax. E.g.:
- `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for
every type of container defined as `IntContainer` with `int` elements. Also the form:
@@ -368,47 +369,50 @@ Each templated type requires one `#include`, even if it's the same container bas
The template parameters are given by a `#define i_xxxx` statement, where *xxxx* is the parameter name.
The list of template parameters:
-- `i_key` - Element key type for map/set only. **[required]**.
-- `i_val` - Element value type. **[required for]** cmap/csmap, it is the mapped value type.
-- `i_cmp` - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements unless *i_opt* is defined with *c_no_cmp*.
-- `i_hash` - Hash function taking *i_keyraw*\* - defaults to *c_default_hash*. **[required for]** ***cmap/cset*** with non-POD *i_keyraw* elements.
-- `i_eq` - Equality comparison of two *i_keyraw*\* - defaults to *!i_cmp*. Companion with *i_hash*.
+- `i_key` *Type* - Element key type for map/set only. **[required]**.
+- `i_val` *Type* - Element value type. **[required for]** cmap/csmap, it is the mapped value type.
+- `i_cmp` *Func* - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements unless *i_opt* is defined with *c_no_cmp*.
+- `i_hash` *Func* - Hash function taking *i_keyraw*\* - defaults to *c_default_hash*. **[required for]** ***cmap/cset*** with non-POD *i_keyraw* elements.
+- `i_eq` *Func* - Equality comparison of two *i_keyraw*\* - defaults to *!i_cmp*. Companion with *i_hash*.
Properties:
-- `i_tag` - Container type name tag. Defaults to *i_key* name.
-- `i_type` - Full container type name. Alternative to *i_tag*.
-- `i_opt` - Boolean properties: may combine *c_no_cmp*, *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator.
+- `i_tag` *Name* - Container type name tag. Defaults to *i_key* name.
+- `i_type` *Name* - Full container type name. Alternative to *i_tag*.
+- `i_opt` *Flags* - Boolean properties: may combine *c_no_cmp*, *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator.
Key:
-- `i_keydrop` - Destroy map/set key func - defaults to empty destructor.
-- `i_keyclone` - **[required if]** *i_keydrop* is defined (exception for **carc**, as it shares).
-- `i_keyraw` - Convertion "raw" type - defaults to *i_key*.
-- `i_keyfrom` - Convertion func *i_key* <- *i_keyraw*.
-- `i_keyto` - Convertion func *i_key*\* -> *i_keyraw*. **[required if]** *i_keyraw* is defined
+- `i_keydrop` *Func* - Destroy map/set key func - defaults to empty destructor.
+- `i_keyclone` *Func* - **[required if]** *i_keydrop* is defined (exception for **carc**, as it shares).
+- `i_keyraw` *Type* - Convertion "raw" type - defaults to *i_key*.
+- `i_keyfrom` *Func* - Convertion func *i_key* <= *i_keyraw*.
+- `i_keyto` *Func* - Convertion func *i_key*\* => *i_keyraw*. **[required if]** *i_keyraw* is defined
Val:
-- `i_valdrop` - Destroy mapped or value func - defaults to empty destruct.
-- `i_valclone` - **[required if]** *i_valdrop* is defined.
-- `i_valraw` - Convertion "raw" type - defaults to *i_val*.
-- `i_valfrom` - Convertion func *i_val* <- *i_valraw*.
-- `i_valto` - Convertion func *i_val*\* -> *i_valraw*.
-
-Specials (meta-template parameters):
-- `i_keyclass TYPE` - Auto-binds to standard named functions: *TYPE_clone()*, *TYPE_drop()*, *TYPE_cmp()*, *TYPE_eq()*, *TYPE_hash()*. If `i_keyraw` is defined, function *TYPE_toraw()* is bound to `i_keyto`, and *TYPE_from()* binds to `i_keyfrom`. Only functions required by the container type needs to be defined. E.g.:
- - *TYPE_hash()* and *TYPE_eq()* are only required by **cmap**, **cset** and smart pointers.
- - *TYPE_cmp()* is not used by **cstack** and **cmap/cset**, or if *#define i_opt c_no_cmp* is specified.
- - *TYPE_clone()* is not used by if *#define i_opt c_no_clone* is specified.
-- `i_key_str` - Defines *i_keyclass = cstr*, *i_tag = str*, and *i_keyraw = const char*\*. Defines type convertion
-*i_keyfrom/i_keyto*, and *i_cmp*, *i_eq*, *i_hash*, *i_keydrop* functions using *const char*\* as input.
-- `i_key_ssv` - Defines *i_keyclass = cstr*, *i_tag = ssv*, and *i_keyraw = csview*. Defines type convertion
-*i_keyfrom/i_keyto* and *i_cmp*, *i_eq*, *i_hash*, *i_keydrop* functions using *csview* as input.
-- `i_keyboxed TYPE` - Use when TYPE is a smart pointer **carc** or **cbox**. Defines *i_keyclass = TYPE*, and *i_keyraw = TYPE\**. NB: Do not use when defining carc/cbox types themselves.
-- `i_valclass`, `i_val_str`, `i_val_ssv`, `i_valboxed` - Similar rules as for ***key***.
+- `i_valdrop` *Func* - Destroy mapped or value func - defaults to empty destruct.
+- `i_valclone` *Func* - **[required if]** *i_valdrop* is defined.
+- `i_valraw` *Type* - Convertion "raw" type - defaults to *i_val*.
+- `i_valfrom` *Func* - Convertion func *i_val* <= *i_valraw*.
+- `i_valto` *Func* - Convertion func *i_val*\* => *i_valraw*.
+
+Specials: Meta-template parameters. Use instead of `i_key` / `i_val`.
+- `i_keyclass` *Type* - Auto-set standard named functions: *Type_clone()*, *Type_drop()*, *Type_cmp()*, *Type_eq()*, *Type_hash()*.
+If `i_keyraw` is defined, it sets `i_keyto` = *Type_toraw()* and `i_keyfrom` = *Type_from()*.
+Only functions required by the container type is required to be defined. E.g.:
+ - *Type_hash()* and *Type_eq()* are only required by **cmap**, **cset** and smart pointers.
+ - *Type_cmp()* is not used by **cstack** and **cmap/cset**, or if *#define i_opt c_no_cmp* is specified.
+ - *Type_clone()* is not used if *#define i_opt c_no_clone* is specified.
+- `i_key_str` - Sets `i_keyclass` = *cstr*, `i_tag` = *str*, and `i_keyraw` = *const char*\*. Defines both type convertion
+`i_keyfrom`, `i_keyto`, and sets `i_cmp`, `i_eq`, `i_hash` functions with *const char\*\** as argument.
+- `i_key_ssv` - Sets `i_keyclass` = *cstr*, `i_tag` = *ssv*, and `i_keyraw` = *csview\**. Defines both type convertion
+`i_keyfrom`, `i_keyto`, and sets `i_cmp`, `i_eq`, `i_hash` functions with *csview\** as argument.
+- `i_keyboxed` *Type* - Use when *Type* is a smart pointer **carc** or **cbox**. Defines *i_keyclass = Type*, and *i_keyraw = Type\**.
+NB: Do not use when defining carc/cbox types themselves.
+- `i_valclass` *Type*, `i_val_str`, `i_val_ssv`, `i_valboxed` - Similar rules as for ***key***.
**Notes**:
- Instead of defining `i_cmp`, you may define *i_opt c_no_cmp* to disable *searching and sorting* functions.
- Instead of defining `i_*clone`, you may define *i_opt c_no_clone* to disable *clone* functionality.
-- For `i_keyclass`, if *i_keyraw RAWTYPE* is defined along with it, *i_keyfrom* may also be defined to enable the *emplace*-functions. NB: the signature for ***cmp***, ***eq***, and ***hash*** uses *RAWTYPE* as input.
+- For `i_keyclass`, if *i_keyraw* is defined along with it, *i_keyfrom* may also be defined to enable the *emplace*-functions. NB: the signature for ***cmp***, ***eq***, and ***hash*** uses *i_keyraw* as input.
The *emplace* versus non-emplace container methods
--------------------------------------------------
diff --git a/docs/cbits_api.md b/docs/cbits_api.md
index 60586a5b..21c9a86d 100644
--- a/docs/cbits_api.md
+++ b/docs/cbits_api.md
@@ -21,34 +21,34 @@ All cbits definitions and prototypes are available by including a single header
```c
cbits cbits_init(void);
cbits cbits_from(const char* str);
-cbits cbits_with_size(intptr_t size, bool value); // size must be <= N if N is defined
-cbits cbits_with_pattern(intptr_t size, uint64_t pattern);
+cbits cbits_with_size(int64_t size, bool value); // size must be <= N if N is defined
+cbits cbits_with_pattern(int64_t size, uint64_t pattern);
cbits cbits_clone(cbits other);
void cbits_clear(cbits* self);
cbits* cbits_copy(cbits* self, const cbits* other);
-void cbits_resize(cbits* self, intptr_t size, bool value); // only if i_len is not defined
+void cbits_resize(cbits* self, int64_t size, bool value); // only if i_len is not defined
void cbits_drop(cbits* self);
cbits* cbits_take(cbits* self, const cbits* other); // give other to self
cbits cbits_move(cbits* self); // transfer self to caller
-intptr_t cbits_size(const cbits* self);
-intptr_t cbits_count(const cbits* self); // count number of bits set
+int64_t cbits_size(const cbits* self);
+int64_t cbits_count(const cbits* self); // count number of bits set
-bool cbits_test(const cbits* self, intptr_t i);
-bool cbits_at(const cbits* self, intptr_t i); // same as cbits_test()
+bool cbits_test(const cbits* self, int64_t i);
+bool cbits_at(const cbits* self, int64_t i); // same as cbits_test()
bool cbits_subset_of(const cbits* self, const cbits* other); // is set a subset of other?
bool cbits_disjoint(const cbits* self, const cbits* other); // no common bits
-char* cbits_to_str(const cbits* self, char* str, intptr_t start, intptr_t stop);
+char* cbits_to_str(const cbits* self, char* str, int64_t start, int64_t stop);
-void cbits_set(cbits* self, intptr_t i);
-void cbits_reset(cbits* self, intptr_t i);
-void cbits_set_value(cbits* self, intptr_t i, bool value);
+void cbits_set(cbits* self, int64_t i);
+void cbits_reset(cbits* self, int64_t i);
+void cbits_set_value(cbits* self, int64_t i, bool value);
void cbits_set_all(cbits* self, bool value);
void cbits_set_pattern(cbits* self, uint64_t pattern);
void cbits_flip_all(cbits* self);
-void cbits_flip(cbits* self, intptr_t i);
+void cbits_flip(cbits* self, int64_t i);
void cbits_intersect(cbits* self, const cbits* other);
void cbits_union(cbits* self, const cbits* other);
@@ -70,19 +70,19 @@ void cbits_xor(cbits* self, const cbits* other); // set of di
#include <math.h>
#include <time.h>
-cbits sieveOfEratosthenes(intptr_t n)
+cbits sieveOfEratosthenes(int64_t n)
{
cbits bits = cbits_with_size(n>>1, true);
- intptr_t q = (intptr_t) sqrt(n);
+ int64_t q = (int64_t) sqrt(n);
- for (intptr_t i = 3; i <= q; i += 2) {
- for (intptr_t j = i; j < n; j += 2) {
+ for (int64_t i = 3; i <= q; i += 2) {
+ for (int64_t j = i; j < n; j += 2) {
if (cbits_test(&bits, j>>1)) {
i = j;
break;
}
}
- for (intptr_t j = i*i; j < n; j += i*2)
+ for (int64_t j = i*i; j < n; j += i*2)
cbits_reset(&bits, j>>1);
}
return bits;
@@ -90,18 +90,18 @@ cbits sieveOfEratosthenes(intptr_t n)
int main(void)
{
- intptr_t n = 100000000;
+ int64_t n = 100000000;
printf("computing prime numbers up to %" c_ZI "\n", n);
clock_t t1 = clock();
cbits primes = sieveOfEratosthenes(n + 1);
- intptr_t nprimes = cbits_count(&primes);
+ int64_t nprimes = cbits_count(&primes);
clock_t t2 = clock();
printf("number of primes: %" c_ZI ", time: %f\n", nprimes, (float)(t2 - t1)/CLOCKS_PER_SEC);
printf(" 2");
- for (intptr_t i = 3; i < 1000; i += 2)
+ for (int64_t i = 3; i < 1000; i += 2)
if (cbits_test(&primes, i>>1)) printf(" %" c_ZI, i);
puts("");
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index a2f0b99d..60167c06 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -32,7 +32,7 @@ c_with (FILE* fp = fopen(fname, "rb"), fp != NULL, fclose(fp))
}
return ok;
-// `c_auto` automatically initialize and destruct up to 4 variables, like c_with.
+// `c_auto` automatically initialize and destruct up to 4 variables:
c_auto (cstr, s1, s2)
{
cstr_append(&s1, "Hello");
@@ -44,6 +44,7 @@ c_auto (cstr, s1, s2)
printf("%s %s\n", cstr_str(&s1), cstr_str(&s2));
}
+// `c_with` is a general variant of `c_auto`:
c_with (cstr str = cstr_lit("Hello"), cstr_drop(&str))
{
cstr_append(&str, " world");
@@ -91,55 +92,6 @@ int main()
printf("%s\n", cstr_str(i.ref));
}
```
-
-### The **checkauto** utility program (for RAII)
-The **checkauto** program will check the source code for any misuses of the `c_auto*` macros which
-may lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**,
-so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable
-the cleanup/drop method to be called. A `break` may originally be intended to break a loop or switch
-outside the `c_auto` scope.
-
-NOTE: One must always make sure to unwind temporary allocated resources before a `return` in C. However, by using `c_auto*`-macros,
-- it is much easier to automatically detect misplaced return/break between resource acquisition and destruction.
-- it prevents forgetting to call the destructor at the end.
-
-The **checkauto** utility will report any misusages. The following example shows how to correctly break/return
-from a `c_auto` scope:
-```c
- int flag = 0;
- for (int i = 0; i<n; ++i) {
- c_auto (cstr, text)
- c_auto (List, list)
- {
- for (int j = 0; j<m; ++j) {
- List_push_back(&list, i*j);
- if (cond1())
- break; // OK: breaks current for-loop only
- }
- // WRONG:
- if (cond2())
- break; // checkauto ERROR! break inside c_auto.
-
- if (cond3())
- return -1; // checkauto ERROR! return inside c_auto
-
- // CORRECT:
- if (cond2()) {
- flag = 1; // flag to break outer for-loop
- continue; // cleanup and leave c_auto block
- }
- if (cond3()) {
- flag = -1; // return -1
- continue; // cleanup and leave c_auto block
- }
- ...
- }
- // do the return/break outside of c_auto
- if (flag < 0) return flag;
- else if (flag > 0) break;
- ...
- } // for
-```
## Loop abstraction macros
### c_forlist
@@ -229,12 +181,12 @@ Iterate containers with stop-criteria and chained range filtering.
| Built-in filter | Description |
|:----------------------------------|:-------------------------------------|
-| `c_flt_skip(it, numItems)` | Skip numItems |
-| `c_flt_take(it, numItems)` | Take numItems |
+| `c_flt_skip(it, numItems)` | Skip numItems (inc count) |
+| `c_flt_take(it, numItems)` | Take numItems (inc count) |
| `c_flt_skipwhile(it, predicate)` | Skip items until predicate is false |
| `c_flt_takewhile(it, predicate)` | Take items until predicate is false |
-| `c_flt_last(it)` | Get count of last filter successes |
-| `c_flt_lastwhile(it)` | Get value of last while-filter |
+| `c_flt_count(it)` | Increment current and return value |
+| `c_flt_last(it)` | Get value of last count/skip/take |
`it.index` holds the index of the source item.
```c
@@ -244,27 +196,27 @@ Iterate containers with stop-criteria and chained range filtering.
#include <stdio.h>
bool isPrime(int i) {
- for (int j=2; j*j <= i; ++j) if (i % j == 0) return false;
+ for (int j=2; j*j <= i; ++j)
+ if (i % j == 0) return false;
return true;
}
-// Get 10 prime numbers after 1 million, but only every 25th of them.
-
int main() {
- crange R = crange_make(1000001, INT32_MAX, 2);
+ // Get 10 prime numbers starting from 1000.
+ // Skip the first 24 primes, then select every 15th prime.
+ crange R = crange_make(1001, INT32_MAX, 2);
c_forfilter (i, crange, R,
isPrime(*i.ref)
- && (c_flt_skip(i, INT32_MAX) ||
- c_flt_last(i) % 25 == 0)
- , c_flt_take(i, 10)) // breaks loop on false.
- {
+ && c_flt_skip(i, 24)
+ && c_flt_count(i) % 15 == 1
+ , c_flt_take(i, 10)) // , = breaks loop on false.
printf(" %d", *i.ref);
- }
+ puts("");
}
-// Out: 1000303 1000639 1000999 1001311 1001593 1001981 1002299 1002583 1002887 1003241
+// out: 1171 1283 1409 1493 1607 1721 1847 1973 2081 2203
```
-Note that `c_flt_take()` is given as an optional argument, which breaks the loop on false
-(for efficiency). Without the comma, it will give same result, but the full input is processed first.
+Note that `c_flt_take()` is given as an optional argument, which breaks the loop on false.
+With `&&` instead of the comma it will give same result, but the full input is processed first.
### c_make, c_new, c_delete
@@ -369,3 +321,52 @@ Return number of elements in an array. array must not be a pointer!
int array[] = {1, 2, 3, 4};
intptr_t n = c_arraylen(array);
```
+
+## The **checkauto** utility program (for RAII)
+The **checkauto** program will check the source code for any misuses of the `c_auto*` macros which
+may lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**,
+so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable
+the cleanup/drop method to be called. A `break` may originally be intended to break a loop or switch
+outside the `c_auto` scope.
+
+NOTE: One must always make sure to unwind temporary allocated resources before a `return` in C. However, by using `c_auto*`-macros,
+- it is much easier to automatically detect misplaced return/break between resource acquisition and destruction.
+- it prevents forgetting to call the destructor at the end.
+
+The **checkauto** utility will report any misusages. The following example shows how to correctly break/return
+from a `c_auto` scope:
+```c
+int flag = 0;
+for (int i = 0; i<n; ++i) {
+ c_auto (cstr, text)
+ c_auto (List, list)
+ {
+ for (int j = 0; j<m; ++j) {
+ List_push_back(&list, i*j);
+ if (cond1())
+ break; // OK: breaks current for-loop only
+ }
+ // WRONG:
+ if (cond2())
+ break; // checkauto ERROR! break inside c_auto.
+
+ if (cond3())
+ return -1; // checkauto ERROR! return inside c_auto
+
+ // CORRECT:
+ if (cond2()) {
+ flag = 1; // flag to break outer for-loop
+ continue; // cleanup and leave c_auto block
+ }
+ if (cond3()) {
+ flag = -1; // return -1
+ continue; // cleanup and leave c_auto block
+ }
+ ...
+ }
+ // do the return/break outside of c_auto
+ if (flag < 0) return flag;
+ else if (flag > 0) break;
+ ...
+}
+```
diff --git a/docs/cregex_api.md b/docs/cregex_api.md
index 8cabb6fc..64fb6a2b 100644
--- a/docs/cregex_api.md
+++ b/docs/cregex_api.md
@@ -108,7 +108,7 @@ int main() {
// Lets find the first date in the string:
csview match[4]; // full-match, year, month, date.
if (cregex_find(&re, input, match, CREG_DEFAULT) == CREG_OK)
- printf("Found date: %.*s\n", c_SVARG(match[0]));
+ printf("Found date: %.*s\n", c_SV(match[0]));
else
printf("Could not find any date\n");
@@ -124,7 +124,7 @@ int main() {
For a single match you may use the all-in-one function:
```c
if (cregex_find_pattern(pattern, input, match, CREG_DEFAULT))
- printf("Found date: %.*s\n", c_SVARG(match[0]));
+ printf("Found date: %.*s\n", c_SV(match[0]));
```
To compile, use: `gcc first_match.c src/cregex.c src/utf8code.c`.
@@ -137,13 +137,13 @@ To iterate multiple matches in an input string, you may use
csview match[5] = {0};
while (cregex_find(&re, input, match, CREG_M_NEXT) == CREG_OK)
c_forrange (k, cregex_captures(&re))
- printf("submatch %lld: %.*s\n", k, c_SVARG(match[k]));
+ printf("submatch %lld: %.*s\n", k, c_SV(match[k]));
```
There is also a safe macro which simplifies this:
```c
c_formatch (it, &re, input)
c_forrange (k, cregex_captures(&re))
- printf("submatch %lld: %.*s\n", k, c_SVARG(it.match[k]));
+ printf("submatch %lld: %.*s\n", k, c_SV(it.match[k]));
```
## Using cregex in a project
diff --git a/docs/cspan_api.md b/docs/cspan_api.md
index 1bd36446..1e60a526 100644
--- a/docs/cspan_api.md
+++ b/docs/cspan_api.md
@@ -1,9 +1,9 @@
# STC [cspan](../include/stc/cspan.h): Multi-dimensional Array View
![Array](pics/array.jpg)
-The **cspan** is templated non-owning *single* and *multi-dimensional* view of an array. It is similar
-to Python's numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) /
-[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan).
+The **cspan** is templated non-owning *single* and *multi-dimensional* view of an array. It has similarities
+with Python's numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) /
+[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan), and others.
## Header file and declaration
**cspan** types are defined by the *using_cspan()* macro after the header is included.
@@ -68,7 +68,7 @@ void SpanType_next(SpanTypeN_iter* it);
## Example 1
-The *cspan_slice()* function is similar to pythons numpy multi-dimensional arrays slicing, e.g.:
+Dimension slicing in python, C, and C++:
```py
import numpy as np
@@ -92,7 +92,7 @@ if __name__ == '__main__':
```
... can be written in C using cspan:
```c
-#include <c11/fmt.h>
+#include <stdio.h>
#include <stc/cspan.h>
using_cspan3(myspan, int); // define myspan, myspan2, myspan3.
@@ -105,11 +105,11 @@ int main() {
c_forrange (i, ss2.shape[0])
c_forrange (j, ss2.shape[1])
- fmt_print(" {}", *cspan_at(&ss2, i, j));
+ printf(" %d", *cspan_at(&ss2, i, j));
puts("");
c_foreach (i, myspan2, ss2)
- fmt_print(" {}", *i.ref);
+ printf(" %d", *i.ref);
}
```
... and (almost) in C++23:
@@ -130,11 +130,11 @@ int main() {
std::print(" {}", ss2[i, j]);
std::println();
- // std::mdspan can't be iterated as a flat container!
+ // std::mdspan can't be iterated joined/flat!
}
```
## Example 2
-Slicing cspan without and with reducing the rank (like numpy array slicing):
+Slicing cspan without and with reducing the rank:
```c
#include <c11/fmt.h>
#include <stc/cspan.h>
diff --git a/docs/csview_api.md b/docs/csview_api.md
index 29c59d9c..33e61f0e 100644
--- a/docs/csview_api.md
+++ b/docs/csview_api.md
@@ -26,11 +26,11 @@ All csview definitions and prototypes are available by including a single header
## Methods
```c
-csview c_SV(const char literal_only[]); // construct from literal, no strlen()
-csview c_SV(const char* str, intptr_t n); // construct from str and length n
-csview csview_lit(const char literal_only[]); // alias for c_SV(lit)
+csview c_sv(const char literal_only[]); // construct from literal, no strlen()
+csview c_sv(const char* str, intptr_t n); // construct from str and length n
+csview csview_lit(const char literal_only[]); // alias for c_sv(lit)
csview csview_from(const char* str); // construct from const char*
-csview csview_from_n(const char* str, intptr_t n); // alias for c_SV(str, n)
+csview csview_from_n(const char* str, intptr_t n); // alias for c_sv(str, n)
intptr_t csview_size(csview sv);
bool csview_empty(csview sv);
@@ -88,7 +88,7 @@ csview cstr_slice_ex(const cstr* s, intptr_t p, intptr_t q); // nega
To iterate tokens in an input string separated by a string:
```c
c_fortoken (i, "hello, one, two, three", ", ")
- printf("token: %.*s\n", c_SVARG(i.token));
+ printf("token: %.*s\n", c_SV(i.token));
```
#### Helper methods
@@ -111,8 +111,8 @@ uint64_t csview_hash(const csview* x);
| Name | Value | Usage |
|:---------------|:---------------------|:---------------------------------------------|
-| `csview_NULL` | same as `c_SV("")` | `sview = csview_NULL;` |
-| `c_SVARG(sv)` | printf argument | `printf("sv: %.*s\n", c_SVARG(sv));` |
+| `csview_NULL` | same as `c_sv("")` | `sview = csview_NULL;` |
+| `c_SV(sv)` | printf argument | `printf("sv: %.*s\n", c_SV(sv));` |
## Example
```c
@@ -129,7 +129,7 @@ int main ()
csview sv2 = cstr_substr(&str1, pos, 4); // get "live"
csview sv3 = cstr_slice(&str1, -8, -1); // get "details"
printf("%.*s %.*s %.*s\n",
- c_SVARG(sv1), c_SVARG(sv2), c_SVARG(sv3));
+ c_SV(sv1), c_SV(sv2), c_SV(sv3));
cstr s1 = cstr_lit("Apples are red");
cstr s2 = cstr_from_sv(cstr_substr(&s1, -3, 3)); // "red"
cstr s3 = cstr_from_sv(cstr_substr(&s1, 0, 6)); // "Apples"
@@ -153,11 +153,11 @@ int main()
{
c_auto (cstr, s1) {
s1 = cstr_lit("hell😀 w😀rld");
- cstr_u8_replace_at(&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)
- printf("%.*s,", c_SVARG(i.u8.chr));
+ printf("%.*s,", c_SV(i.u8.chr));
}
}
```
@@ -177,7 +177,7 @@ and does not depend on null-terminated strings. *string_split()* function return
void print_split(csview input, const char* sep)
{
c_fortoken_sv (i, input, sep)
- printf("[%.*s]\n", c_SVARG(i.token));
+ printf("[%.*s]\n", c_SV(i.token));
}
#include <stc/cstr.h>
@@ -196,12 +196,12 @@ cstack_str string_split(csview input, const char* sep)
int main()
{
- print_split(c_SV("//This is a//double-slash//separated//string"), "//");
+ print_split(c_sv("//This is a//double-slash//separated//string"), "//");
puts("");
- print_split(c_SV("This has no matching separator"), "xx");
+ print_split(c_sv("This has no matching separator"), "xx");
puts("");
- c_with (cstack_str s = string_split(c_SV("Split,this,,string,now,"), ","), cstack_str_drop(&s))
+ c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), ","), cstack_str_drop(&s))
c_foreach (i, cstack_str, s)
printf("[%s]\n", cstr_str(i.ref));
}
diff --git a/include/stc/algo/filter.h b/include/stc/algo/filter.h
index 8357cb4d..6f8e1654 100644
--- a/include/stc/algo/filter.h
+++ b/include/stc/algo/filter.h
@@ -50,15 +50,15 @@ int main()
#include <stc/ccommon.h>
#ifndef c_NFILTERS
- #define c_NFILTERS 14 /* 22, 30, .. */
+#define c_NFILTERS 32
#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_take(i, n) (c_flt_count(i) <= (n))
+#define c_flt_skip(i, n) (c_flt_count(i) > (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_flt_last(i) (i).s1[(i).s1top-1]
-#define c_flt_lastwhile(i) (i).s2[(i).s2top-1]
+#define c_flt_count(i) ++(i).s1[(i).s1top++]
#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__)
diff --git a/include/stc/cbits.h b/include/stc/cbits.h
index 0c169b88..c3167dae 100644
--- a/include/stc/cbits.h
+++ b/include/stc/cbits.h
@@ -56,7 +56,7 @@ int main() {
#include <string.h>
#define _cbits_bit(i) ((uint64_t)1 << ((i) & 63))
-#define _cbits_words(n) (intptr_t)(((n) + 63)>>6)
+#define _cbits_words(n) (int64_t)(((n) + 63)>>6)
#define _cbits_bytes(n) (_cbits_words(n) * c_sizeof(uint64_t))
#if defined(__GNUC__) || defined(__clang__)
@@ -73,23 +73,23 @@ int main() {
}
#endif
-STC_INLINE intptr_t _cbits_count(const uint64_t* set, const intptr_t sz) {
- const intptr_t n = sz>>6;
- intptr_t count = 0;
- for (intptr_t i = 0; i < n; ++i)
+STC_INLINE int64_t _cbits_count(const uint64_t* set, const int64_t sz) {
+ const int64_t n = sz>>6;
+ int64_t count = 0;
+ for (int64_t i = 0; i < n; ++i)
count += cpopcount64(set[i]);
if (sz & 63)
count += cpopcount64(set[n] & (_cbits_bit(sz) - 1));
return count;
}
-STC_INLINE char* _cbits_to_str(const uint64_t* set, const intptr_t sz,
- char* out, intptr_t start, intptr_t stop) {
+STC_INLINE char* _cbits_to_str(const uint64_t* set, const int64_t sz,
+ char* out, int64_t start, int64_t stop) {
if (stop > sz) stop = sz;
assert(start <= stop);
c_memset(out, '0', stop - start);
- for (intptr_t i = start; i < stop; ++i)
+ for (int64_t i = start; i < stop; ++i)
if ((set[i>>6] & _cbits_bit(i)) != 0)
out[i - start] = '1';
out[stop - start] = '\0';
@@ -97,19 +97,19 @@ STC_INLINE char* _cbits_to_str(const uint64_t* set, const intptr_t sz,
}
#define _cbits_OPR(OPR, VAL) \
- const uint64_t n = (uint64_t)sz>>6; \
- for (uint64_t i = 0; i < n; ++i) \
+ const int64_t n = sz>>6; \
+ for (int64_t i = 0; i < n; ++i) \
if ((set[i] OPR other[i]) != VAL) \
return false; \
if (!(sz & 63)) \
return true; \
- const uint64_t i = n, m = _cbits_bit(sz) - 1; \
+ const uint64_t i = (uint64_t)n, m = _cbits_bit(sz) - 1; \
return ((set[i] OPR other[i]) & m) == (VAL & m)
-STC_INLINE bool _cbits_subset_of(const uint64_t* set, const uint64_t* other, const intptr_t sz)
+STC_INLINE bool _cbits_subset_of(const uint64_t* set, const uint64_t* other, const int64_t sz)
{ _cbits_OPR(|, set[i]); }
-STC_INLINE bool _cbits_disjoint(const uint64_t* set, const uint64_t* other, const intptr_t sz)
+STC_INLINE bool _cbits_disjoint(const uint64_t* set, const uint64_t* other, const int64_t sz)
{ _cbits_OPR(&, 0); }
#endif // CBITS_H_INCLUDED
@@ -121,12 +121,12 @@ STC_INLINE bool _cbits_disjoint(const uint64_t* set, const uint64_t* other, cons
#define _i_assert(x) assert(x)
#define i_type cbits
-struct { uint64_t *data64; intptr_t _size; } typedef i_type;
+struct { uint64_t *data64; int64_t _size; } typedef i_type;
STC_INLINE cbits cbits_init(void) { return c_LITERAL(cbits){NULL}; }
STC_INLINE void cbits_create(cbits* self) { self->data64 = NULL; self->_size = 0; }
STC_INLINE void cbits_drop(cbits* self) { c_free(self->data64); }
-STC_INLINE intptr_t cbits_size(const cbits* self) { return self->_size; }
+STC_INLINE int64_t cbits_size(const cbits* self) { return self->_size; }
STC_INLINE cbits* cbits_take(cbits* self, cbits other) {
if (self->data64 != other.data64) {
@@ -137,7 +137,7 @@ STC_INLINE cbits* cbits_take(cbits* self, cbits other) {
}
STC_INLINE cbits cbits_clone(cbits other) {
- const intptr_t bytes = _cbits_bytes(other._size);
+ const int64_t bytes = _cbits_bytes(other._size);
cbits set = {(uint64_t *)c_memcpy(c_malloc(bytes), other.data64, bytes), other._size};
return set;
}
@@ -151,8 +151,8 @@ STC_INLINE cbits* cbits_copy(cbits* self, const cbits* other) {
return self;
}
-STC_INLINE void cbits_resize(cbits* self, const intptr_t size, const bool value) {
- const intptr_t new_n = _cbits_words(size), osize = self->_size, old_n = _cbits_words(osize);
+STC_INLINE void cbits_resize(cbits* self, const int64_t size, const bool value) {
+ const int64_t new_n = _cbits_words(size), osize = self->_size, old_n = _cbits_words(osize);
self->data64 = (uint64_t *)c_realloc(self->data64, new_n*8);
self->_size = size;
if (new_n >= old_n) {
@@ -174,13 +174,13 @@ STC_INLINE cbits cbits_move(cbits* self) {
return tmp;
}
-STC_INLINE cbits cbits_with_size(const intptr_t size, const bool value) {
+STC_INLINE cbits cbits_with_size(const int64_t size, const bool value) {
cbits set = {(uint64_t *)c_malloc(_cbits_bytes(size)), size};
cbits_set_all(&set, value);
return set;
}
-STC_INLINE cbits cbits_with_pattern(const intptr_t size, const uint64_t pattern) {
+STC_INLINE cbits cbits_with_pattern(const int64_t size, const uint64_t pattern) {
cbits set = {(uint64_t *)c_malloc(_cbits_bytes(size)), size};
cbits_set_pattern(&set, pattern);
return set;
@@ -198,7 +198,7 @@ struct { uint64_t data64[(i_capacity - 1)/64 + 1]; } typedef i_type;
STC_INLINE i_type _i_memb(_init)(void) { return c_LITERAL(i_type){0}; }
STC_INLINE void _i_memb(_create)(i_type* self) {}
STC_INLINE void _i_memb(_drop)(i_type* self) {}
-STC_INLINE intptr_t _i_memb(_size)(const i_type* self) { return i_capacity; }
+STC_INLINE int64_t _i_memb(_size)(const i_type* self) { return i_capacity; }
STC_INLINE i_type _i_memb(_move)(i_type* self) { return *self; }
STC_INLINE i_type* _i_memb(_take)(i_type* self, i_type other)
@@ -213,13 +213,13 @@ STC_INLINE i_type* _i_memb(_copy)(i_type* self, const i_type* other)
STC_INLINE void _i_memb(_set_all)(i_type *self, const bool value);
STC_INLINE void _i_memb(_set_pattern)(i_type *self, const uint64_t pattern);
-STC_INLINE i_type _i_memb(_with_size)(const intptr_t size, const bool value) {
+STC_INLINE i_type _i_memb(_with_size)(const int64_t size, const bool value) {
assert(size <= i_capacity);
i_type set; _i_memb(_set_all)(&set, value);
return set;
}
-STC_INLINE i_type _i_memb(_with_pattern)(const intptr_t size, const uint64_t pattern) {
+STC_INLINE i_type _i_memb(_with_pattern)(const int64_t size, const uint64_t pattern) {
assert(size <= i_capacity);
i_type set; _i_memb(_set_pattern)(&set, pattern);
return set;
@@ -232,36 +232,36 @@ STC_INLINE void _i_memb(_set_all)(i_type *self, const bool value)
{ c_memset(self->data64, value? ~0 : 0, _cbits_bytes(_i_memb(_size)(self))); }
STC_INLINE void _i_memb(_set_pattern)(i_type *self, const uint64_t pattern) {
- intptr_t n = _cbits_words(_i_memb(_size)(self));
+ int64_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] = pattern;
}
-STC_INLINE bool _i_memb(_test)(const i_type* self, const intptr_t i)
+STC_INLINE bool _i_memb(_test)(const i_type* self, const int64_t i)
{ return (self->data64[i>>6] & _cbits_bit(i)) != 0; }
-STC_INLINE bool _i_memb(_at)(const i_type* self, const intptr_t i)
+STC_INLINE bool _i_memb(_at)(const i_type* self, const int64_t i)
{ return (self->data64[i>>6] & _cbits_bit(i)) != 0; }
-STC_INLINE void _i_memb(_set)(i_type *self, const intptr_t i)
+STC_INLINE void _i_memb(_set)(i_type *self, const int64_t i)
{ self->data64[i>>6] |= _cbits_bit(i); }
-STC_INLINE void _i_memb(_reset)(i_type *self, const intptr_t i)
+STC_INLINE void _i_memb(_reset)(i_type *self, const int64_t i)
{ self->data64[i>>6] &= ~_cbits_bit(i); }
-STC_INLINE void _i_memb(_set_value)(i_type *self, const intptr_t i, const bool b) {
+STC_INLINE void _i_memb(_set_value)(i_type *self, const int64_t i, const bool b) {
self->data64[i>>6] ^= ((uint64_t)-(int)b ^ self->data64[i>>6]) & _cbits_bit(i);
}
-STC_INLINE void _i_memb(_flip)(i_type *self, const intptr_t i)
+STC_INLINE void _i_memb(_flip)(i_type *self, const int64_t i)
{ self->data64[i>>6] ^= _cbits_bit(i); }
STC_INLINE void _i_memb(_flip_all)(i_type *self) {
- intptr_t n = _cbits_words(_i_memb(_size)(self));
+ int64_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] ^= ~(uint64_t)0;
}
STC_INLINE i_type _i_memb(_from)(const char* str) {
- intptr_t n = c_strlen(str);
+ int64_t n = c_strlen(str);
i_type set = _i_memb(_with_size)(n, false);
while (n--) if (str[n] == '1') _i_memb(_set)(&set, n);
return set;
@@ -270,26 +270,26 @@ STC_INLINE i_type _i_memb(_from)(const char* str) {
/* Intersection */
STC_INLINE void _i_memb(_intersect)(i_type *self, const i_type* other) {
_i_assert(self->_size == other->_size);
- intptr_t n = _cbits_words(_i_memb(_size)(self));
+ int64_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] &= other->data64[n];
}
/* Union */
STC_INLINE void _i_memb(_union)(i_type *self, const i_type* other) {
_i_assert(self->_size == other->_size);
- intptr_t n = _cbits_words(_i_memb(_size)(self));
+ int64_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] |= other->data64[n];
}
/* Exclusive disjunction */
STC_INLINE void _i_memb(_xor)(i_type *self, const i_type* other) {
_i_assert(self->_size == other->_size);
- intptr_t n = _cbits_words(_i_memb(_size)(self));
+ int64_t n = _cbits_words(_i_memb(_size)(self));
while (n--) self->data64[n] ^= other->data64[n];
}
-STC_INLINE intptr_t _i_memb(_count)(const i_type* self)
+STC_INLINE int64_t _i_memb(_count)(const i_type* self)
{ return _cbits_count(self->data64, _i_memb(_size)(self)); }
-STC_INLINE char* _i_memb(_to_str)(const i_type* self, char* out, intptr_t start, intptr_t stop)
+STC_INLINE char* _i_memb(_to_str)(const i_type* self, char* out, int64_t start, int64_t stop)
{ return _cbits_to_str(self->data64, _i_memb(_size)(self), out, start, stop); }
STC_INLINE bool _i_memb(_subset_of)(const i_type* self, const i_type* other) {
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index 0b3083ef..04c26d4c 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -129,13 +129,13 @@ typedef const char* crawstr;
#define crawstr_hash(p) cstrhash(*(p))
#define crawstr_len(literal) (c_sizeof("" literal) - 1)
-#define c_SV(...) c_MACRO_OVERLOAD(c_SV, __VA_ARGS__)
-#define c_SV_1(lit) c_SV_2(lit, crawstr_len(lit))
-#define c_SV_2(str, n) (c_LITERAL(csview){str, n})
-#define c_SVARG(sv) (int)(sv).size, (sv).str /* use with "%.*s" */
-#define c_PAIR(ref) (ref)->first, (ref)->second
+#define c_sv(...) c_MACRO_OVERLOAD(c_sv, __VA_ARGS__)
+#define c_sv_1(lit) c_sv_2(lit, crawstr_len(lit))
+#define c_sv_2(str, n) (c_LITERAL(csview){str, n})
-#define _c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k)))
+#define c_SV(sv) (int)(sv).size, (sv).str // print csview: use format "%.*s"
+#define c_PAIR(ref) (ref)->first, (ref)->second
+#define c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k)))
STC_INLINE uint64_t cfasthash(const void* key, intptr_t len) {
const uint8_t *x = (const uint8_t*) key;
@@ -143,7 +143,7 @@ STC_INLINE uint64_t cfasthash(const void* key, intptr_t len) {
uint32_t u4;
while (n--) {
memcpy(&u8, x, 8), x += 8;
- h += (_c_ROTL(u8, 26) ^ u8)*0xc6a4a7935bd1e99d;
+ h += (c_ROTL(u8, 26) ^ u8)*0xc6a4a7935bd1e99d;
}
switch (len &= 7) {
case 0: return h;
@@ -152,7 +152,7 @@ STC_INLINE uint64_t cfasthash(const void* key, intptr_t len) {
}
h += *x++;
while (--len) h = (h << 10) - h + *x++;
- return _c_ROTL(h, 26) ^ h;
+ return c_ROTL(h, 26) ^ h;
}
STC_INLINE uint64_t cstrhash(const char *str)
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index c5808d02..ce6dba81 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -181,10 +181,10 @@ STC_INLINE cstr cstr_toupper_sv(csview sv)
{ return cstr_tocase(sv, 2); }
STC_INLINE cstr cstr_tolower(const char* str)
- { return cstr_tolower_sv(c_SV(str, c_strlen(str))); }
+ { return cstr_tolower_sv(c_sv(str, c_strlen(str))); }
STC_INLINE cstr cstr_toupper(const char* str)
- { return cstr_toupper_sv(c_SV(str, c_strlen(str))); }
+ { return cstr_toupper_sv(c_sv(str, c_strlen(str))); }
STC_INLINE void cstr_lowercase(cstr* self)
{ cstr_take(self, cstr_tolower_sv(cstr_sv(self))); }
@@ -316,7 +316,7 @@ STC_INLINE bool cstr_starts_with_s(const cstr* self, cstr sub)
STC_INLINE bool cstr_istarts_with(const cstr* self, const char* sub) {
csview sv = cstr_sv(self);
intptr_t len = c_strlen(sub);
- return len <= sv.size && !utf8_icmp_sv(sv, c_SV(sub, len));
+ return len <= sv.size && !utf8_icmp_sv(sv, c_sv(sub, len));
}
@@ -330,7 +330,7 @@ STC_INLINE bool cstr_ends_with_s(const cstr* self, cstr sub)
{ return cstr_ends_with_sv(self, cstr_sv(&sub)); }
STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub)
- { return cstr_ends_with_sv(self, c_SV(sub, c_strlen(sub))); }
+ { return cstr_ends_with_sv(self, c_sv(sub, c_strlen(sub))); }
STC_INLINE bool cstr_iends_with(const cstr* self, const char* sub) {
csview sv = cstr_sv(self);
@@ -375,8 +375,8 @@ STC_INLINE char* cstr_append_s(cstr* self, cstr s) {
#define cstr_replace(...) c_MACRO_OVERLOAD(cstr_replace, __VA_ARGS__)
#define cstr_replace_3(self, search, repl) cstr_replace_4(self, search, repl, INT32_MAX)
STC_INLINE void cstr_replace_4(cstr* self, const char* search, const char* repl, int32_t count) {
- cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(search, c_strlen(search)),
- c_SV(repl, c_strlen(repl)), count));
+ cstr_take(self, cstr_replace_sv(cstr_sv(self), c_sv(search, c_strlen(search)),
+ c_sv(repl, c_strlen(repl)), count));
}
STC_INLINE void cstr_replace_at_sv(cstr* self, intptr_t pos, intptr_t len, const csview repl) {
@@ -385,7 +385,7 @@ STC_INLINE void cstr_replace_at_sv(cstr* self, intptr_t pos, intptr_t len, const
}
STC_INLINE void cstr_replace_at(cstr* self, intptr_t pos, intptr_t len, const char* repl)
- { cstr_replace_at_sv(self, pos, len, c_SV(repl, c_strlen(repl))); }
+ { cstr_replace_at_sv(self, pos, len, c_sv(repl, c_strlen(repl))); }
STC_INLINE void cstr_replace_at_s(cstr* self, intptr_t pos, intptr_t len, cstr repl)
{ cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); }
@@ -395,7 +395,7 @@ STC_INLINE void cstr_u8_replace_at(cstr* self, intptr_t bytepos, intptr_t u8len,
STC_INLINE void cstr_insert(cstr* self, intptr_t pos, const char* str)
- { cstr_replace_at_sv(self, pos, 0, c_SV(str, c_strlen(str))); }
+ { cstr_replace_at_sv(self, pos, 0, c_sv(str, c_strlen(str))); }
STC_INLINE void cstr_insert_sv(cstr* self, intptr_t pos, csview sv)
{ cstr_replace_at_sv(self, pos, 0, sv); }
diff --git a/include/stc/csview.h b/include/stc/csview.h
index 748f7d30..bba3aea3 100644
--- a/include/stc/csview.h
+++ b/include/stc/csview.h
@@ -27,12 +27,12 @@
#include "forward.h"
#include "utf8.h"
-#define csview_NULL c_SV_1("")
+#define csview_NULL c_sv_1("")
#define csview_init() csview_NULL
#define csview_drop(p) c_default_drop(p)
#define csview_clone(sv) c_default_clone(sv)
-#define csview_lit(literal) c_SV_1(literal)
-#define csview_from_n(str, n) c_SV_2(str, n)
+#define csview_lit(literal) c_sv_1(literal)
+#define csview_from_n(str, n) c_sv_2(str, n)
STC_API intptr_t csview_find_sv(csview sv, csview search);
@@ -47,7 +47,7 @@ STC_INLINE bool csview_equals(csview sv, const char* str)
{ intptr_t n = c_strlen(str); return sv.size == n && !c_memcmp(sv.str, str, n); }
STC_INLINE intptr_t csview_find(csview sv, const char* str)
- { return csview_find_sv(sv, c_SV(str, c_strlen(str))); }
+ { return csview_find_sv(sv, c_sv(str, c_strlen(str))); }
STC_INLINE bool csview_contains(csview sv, const char* str)
{ return csview_find(sv, str) != c_NPOS; }
diff --git a/include/stc/priv/altnames.h b/include/stc/priv/altnames.h
index bfda05ca..b10c7a11 100644
--- a/include/stc/priv/altnames.h
+++ b/include/stc/priv/altnames.h
@@ -35,5 +35,4 @@
#define c_DEFER c_defer
#define c_NEW c_new
#define c_ARRAYLEN c_arraylen
-#define c_ARGSV c_SVARG
-#define c_sv c_SV
+#define c_ARGSV c_SV // [deprecated]
diff --git a/include/stc/utf8.h b/include/stc/utf8.h
index 7ad01ef4..a4cc3846 100644
--- a/include/stc/utf8.h
+++ b/include/stc/utf8.h
@@ -68,7 +68,7 @@ STC_INLINE uint32_t utf8_peek(const char* s) {
/* case-insensitive utf8 string comparison */
STC_INLINE int utf8_icmp(const char* s1, const char* s2) {
- return utf8_icmp_sv(c_SV(s1, INTPTR_MAX), c_SV(s2, INTPTR_MAX));
+ return utf8_icmp_sv(c_sv(s1, INTPTR_MAX), c_sv(s2, INTPTR_MAX));
}
STC_INLINE bool utf8_valid(const char* s) {
diff --git a/misc/examples/cstr_match.c b/misc/examples/cstr_match.c
index 4d11edbb..6682c4ba 100644
--- a/misc/examples/cstr_match.c
+++ b/misc/examples/cstr_match.c
@@ -17,7 +17,7 @@ int main()
csview ch1 = cstr_u8_chr(&s1, 7);
csview ch2 = cstr_u8_chr(&s1, 10);
printf("%s\nsize: %" c_ZI ", %" c_ZI "\n", cstr_str(&s1), cstr_u8_size(&s1), cstr_size(&s1));
- printf("ch1: %.*s\n", c_SVARG(ch1));
- printf("ch2: %.*s\n", c_SVARG(ch2));
+ printf("ch1: %.*s\n", c_SV(ch1));
+ printf("ch2: %.*s\n", c_SV(ch2));
}
}
diff --git a/misc/examples/forfilter.c b/misc/examples/forfilter.c
index b0be4e69..5e1cf15e 100644
--- a/misc/examples/forfilter.c
+++ b/misc/examples/forfilter.c
@@ -102,14 +102,14 @@ void demo3(void)
puts("demo3:");
c_foreach (w, SVec, words_containing_i)
- printf(" %.*s", c_SVARG(*w.ref));
+ printf(" %.*s", c_SV(*w.ref));
puts("");
}
}
void demo4(void)
{
- csview s = c_SV("ab123cReAghNGnΩoEp"); // Ω = multi-byte
+ csview s = c_sv("ab123cReAghNGnΩoEp"); // Ω = multi-byte
c_auto (cstr, out) {
c_forfilter (i, csview, s, utf8_isupper(utf8_peek(i.ref))) {
char chr[4];
diff --git a/misc/examples/prime.c b/misc/examples/prime.c
index 1a272e78..e705dcb7 100644
--- a/misc/examples/prime.c
+++ b/misc/examples/prime.c
@@ -6,19 +6,19 @@
#include <stc/algo/crange.h>
-cbits sieveOfEratosthenes(intptr_t n)
+cbits sieveOfEratosthenes(int64_t n)
{
cbits bits = cbits_with_size(n/2 + 1, true);
- intptr_t q = (intptr_t)sqrt((double) n) + 1;
- for (intptr_t i = 3; i < q; i += 2) {
- intptr_t j = i;
+ int64_t q = (int64_t)sqrt((double) n) + 1;
+ for (int64_t i = 3; i < q; i += 2) {
+ int64_t j = i;
for (; j < n; j += 2) {
if (cbits_test(&bits, j>>1)) {
i = j;
break;
}
}
- for (intptr_t j = i*i; j < n; j += i*2)
+ for (int64_t j = i*i; j < n; j += i*2)
cbits_reset(&bits, j>>1);
}
return bits;
@@ -26,12 +26,12 @@ cbits sieveOfEratosthenes(intptr_t n)
int main(void)
{
- intptr_t n = 1000000000;
+ int64_t n = 1000000000;
printf("Computing prime numbers up to %" c_ZI "\n", n);
clock_t t1 = clock();
c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) {
- intptr_t np = cbits_count(&primes);
+ int64_t np = cbits_count(&primes);
clock_t t2 = clock();
printf("Number of primes: %" c_ZI ", time: %f\n\n", np, (float)(t2 - t1) / (float)CLOCKS_PER_SEC);
diff --git a/misc/examples/regex2.c b/misc/examples/regex2.c
index 4c58f3ba..20bd323c 100644
--- a/misc/examples/regex2.c
+++ b/misc/examples/regex2.c
@@ -27,7 +27,7 @@ int main()
c_formatch (j, &re, s[i].input) {
c_forrange (k, cregex_captures(&re))
- printf(" submatch %lld: %.*s\n", k, c_SVARG(j.match[k]));
+ printf(" submatch %lld: %.*s\n", k, c_SV(j.match[k]));
}
}
}
diff --git a/misc/examples/replace.c b/misc/examples/replace.c
index 15cf3bae..c22c71ff 100644
--- a/misc/examples/replace.c
+++ b/misc/examples/replace.c
@@ -19,13 +19,13 @@ int main ()
cstr_replace_at(&s, 9, 5, s2); // "this is an example string." (1)
printf("(1) %s\n", cstr_str(&s));
- cstr_replace_at_sv(&s, 19, 6, c_SV(s3+7, 6)); // "this is an example phrase." (2)
+ cstr_replace_at_sv(&s, 19, 6, c_sv(s3+7, 6)); // "this is an example phrase." (2)
printf("(2) %s\n", cstr_str(&s));
cstr_replace_at(&s, 8, 10, "just a"); // "this is just a phrase." (3)
printf("(3) %s\n", cstr_str(&s));
- cstr_replace_at_sv(&s, 8, 6, c_SV("a shorty", 7)); // "this is a short phrase." (4)
+ cstr_replace_at_sv(&s, 8, 6, c_sv("a shorty", 7)); // "this is a short phrase." (4)
printf("(4) %s\n", cstr_str(&s));
cstr_replace_at(&s, 22, 1, "!!!"); // "this is a short phrase!!!" (5)
diff --git a/misc/examples/splitstr.c b/misc/examples/splitstr.c
index 4705696c..5bf02d42 100644
--- a/misc/examples/splitstr.c
+++ b/misc/examples/splitstr.c
@@ -8,12 +8,12 @@ int main()
puts("Split with c_fortoken (csview):");
c_fortoken (i, "Hello World C99!", " ")
- printf("'%.*s'\n", c_SVARG(i.token));
+ printf("'%.*s'\n", c_SV(i.token));
puts("\nSplit with c_formatch (regex):");
c_with (cregex re = cregex_from("[^ ]+"), cregex_drop(&re))
c_formatch (i, &re, " Hello World C99! ")
- printf("'%.*s'\n", c_SVARG(i.match[0]));
+ printf("'%.*s'\n", c_SV(i.match[0]));
}
diff --git a/misc/examples/sso_substr.c b/misc/examples/sso_substr.c
index d17dc89c..4b2dbcc8 100644
--- a/misc/examples/sso_substr.c
+++ b/misc/examples/sso_substr.c
@@ -8,7 +8,7 @@ int main ()
intptr_t pos = cstr_find(&str, "live"); // position of "live"
csview sv2 = cstr_substr_ex(&str, pos, 4); // "live"
csview sv3 = cstr_slice_ex(&str, -8, -1); // "details"
- printf("%.*s, %.*s, %.*s\n", c_SVARG(sv1), c_SVARG(sv2), c_SVARG(sv3));
+ printf("%.*s, %.*s, %.*s\n", c_SV(sv1), c_SV(sv2), c_SV(sv3));
cstr_assign(&str, "apples are green or red");
cstr s2 = cstr_from_sv(cstr_substr_ex(&str, -3, 3)); // "red"
diff --git a/misc/examples/sview_split.c b/misc/examples/sview_split.c
index 2bb7aaee..18d547f8 100644
--- a/misc/examples/sview_split.c
+++ b/misc/examples/sview_split.c
@@ -4,13 +4,13 @@
int main()
{
// No memory allocations or string length calculations!
- const csview date = c_SV("2021/03/12");
+ const csview date = c_sv("2021/03/12");
intptr_t pos = 0;
const csview year = csview_token(date, "/", &pos);
const csview month = csview_token(date, "/", &pos);
const csview day = csview_token(date, "/", &pos);
- printf("%.*s, %.*s, %.*s\n", c_SVARG(year), c_SVARG(month), c_SVARG(day));
+ printf("%.*s, %.*s, %.*s\n", c_SV(year), c_SV(month), c_SV(day));
c_auto (cstr, y, m, d) {
y = cstr_from_sv(year), m = cstr_from_sv(month), d = cstr_from_sv(day);
diff --git a/misc/examples/utf8replace_c.c b/misc/examples/utf8replace_c.c
index adb8c042..b697efd8 100644
--- a/misc/examples/utf8replace_c.c
+++ b/misc/examples/utf8replace_c.c
@@ -11,12 +11,12 @@ int main()
cstr_u8_replace_at(&hello,
cstr_u8_to_pos(&hello, 7),
1,
- c_SV("🐨")
+ c_sv("🐨")
);
printf("%s\n", cstr_str(&hello));
c_foreach (c, cstr, hello)
- printf("%.*s,", c_SVARG(c.u8.chr));
+ printf("%.*s,", c_SV(c.u8.chr));
str = cstr_lit("scooby, dooby doo");
cstr_replace(&str, "oo", "00");