summaryrefslogtreecommitdiffhomepage
path: root/docs
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-02-04 23:35:56 +0100
committerGitHub <[email protected]>2023-02-04 23:35:56 +0100
commitadc47cefc2976768c3f0b773bd26bfd1062e8a53 (patch)
tree4923f88afb0d091d5d39ae03d65a4998a0517652 /docs
parent0c4c4f8bba17562735b67b2923cd23c773aa53a7 (diff)
parentd2ff84c53aa9bd3857fdf22dcf7cd9398a4780be (diff)
downloadSTC-modified-adc47cefc2976768c3f0b773bd26bfd1062e8a53.tar.gz
STC-modified-adc47cefc2976768c3f0b773bd26bfd1062e8a53.zip
Merge pull request #46 from tylov/newinit
Version 4.1 RC2: signed sizes and indices, cspan with numpy slicing.
Diffstat (limited to 'docs')
-rw-r--r--docs/cbits_api.md90
-rw-r--r--docs/cbox_api.md8
-rw-r--r--docs/ccommon_api.md107
-rw-r--r--docs/cdeq_api.md34
-rw-r--r--docs/clist_api.md26
-rw-r--r--docs/cmap_api.md52
-rw-r--r--docs/cpque_api.md12
-rw-r--r--docs/cqueue_api.md2
-rw-r--r--docs/crandom_api.md26
-rw-r--r--docs/cregex_api.md41
-rw-r--r--docs/cset_api.md24
-rw-r--r--docs/csmap_api.md12
-rw-r--r--docs/cspan_api.md255
-rw-r--r--docs/csset_api.md8
-rw-r--r--docs/cstack_api.md16
-rw-r--r--docs/cstr_api.md221
-rw-r--r--docs/csview_api.md68
-rw-r--r--docs/cvec_api.md50
18 files changed, 572 insertions, 480 deletions
diff --git a/docs/cbits_api.md b/docs/cbits_api.md
index b21611df..60586a5b 100644
--- a/docs/cbits_api.md
+++ b/docs/cbits_api.md
@@ -19,40 +19,40 @@ All cbits definitions and prototypes are available by including a single header
## Methods
```c
-cbits cbits_init(void);
-cbits cbits_from(const char* str);
-cbits cbits_with_size(size_t size, bool value); // size must be <= N if N is defined
-cbits cbits_with_pattern(size_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, size_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
-
-size_t cbits_size(const cbits* self);
-size_t cbits_count(const cbits* self); // count number of bits set
-
-bool cbits_test(const cbits* self, size_t i);
-bool cbits_at(const cbits* self, size_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, size_t start, size_t stop);
-
-void cbits_set(cbits* self, size_t i);
-void cbits_reset(cbits* self, size_t i);
-void cbits_set_value(cbits* self, size_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, size_t i);
-
-void cbits_intersect(cbits* self, const cbits* other);
-void cbits_union(cbits* self, const cbits* other);
-void cbits_xor(cbits* self, const cbits* other); // set of disjoint bits
+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_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_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
+
+bool cbits_test(const cbits* self, intptr_t i);
+bool cbits_at(const cbits* self, intptr_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);
+
+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_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_intersect(cbits* self, const cbits* other);
+void cbits_union(cbits* self, const cbits* other);
+void cbits_xor(cbits* self, const cbits* other); // set of disjoint bits
```
## Types
@@ -70,19 +70,19 @@ void cbits_xor(cbits* self, const cbits* other); // set
#include <math.h>
#include <time.h>
-cbits sieveOfEratosthenes(size_t n)
+cbits sieveOfEratosthenes(intptr_t n)
{
cbits bits = cbits_with_size(n>>1, true);
- size_t q = (size_t) sqrt(n);
+ intptr_t q = (intptr_t) sqrt(n);
- for (size_t i = 3; i <= q; i += 2) {
- for (size_t j = i; j < n; j += 2) {
+ for (intptr_t i = 3; i <= q; i += 2) {
+ for (intptr_t j = i; j < n; j += 2) {
if (cbits_test(&bits, j>>1)) {
i = j;
break;
}
}
- for (size_t j = i*i; j < n; j += i*2)
+ for (intptr_t j = i*i; j < n; j += i*2)
cbits_reset(&bits, j>>1);
}
return bits;
@@ -90,19 +90,19 @@ cbits sieveOfEratosthenes(size_t n)
int main(void)
{
- size_t n = 100000000;
- printf("computing prime numbers up to %" c_ZU "\n", n);
+ intptr_t n = 100000000;
+ printf("computing prime numbers up to %" c_ZI "\n", n);
clock_t t1 = clock();
cbits primes = sieveOfEratosthenes(n + 1);
- size_t nprimes = cbits_count(&primes);
+ intptr_t nprimes = cbits_count(&primes);
clock_t t2 = clock();
- printf("number of primes: %" c_ZU ", time: %f\n", nprimes, (float)(t2 - t1)/CLOCKS_PER_SEC);
+ printf("number of primes: %" c_ZI ", time: %f\n", nprimes, (float)(t2 - t1)/CLOCKS_PER_SEC);
printf(" 2");
- for (size_t i = 3; i < 1000; i += 2)
- if (cbits_test(&primes, i>>1)) printf(" %" c_ZU, i);
+ for (intptr_t i = 3; i < 1000; i += 2)
+ if (cbits_test(&primes, i>>1)) printf(" %" c_ZI, i);
puts("");
cbits_drop(&primes);
diff --git a/docs/cbox_api.md b/docs/cbox_api.md
index 8906f154..4430b9f8 100644
--- a/docs/cbox_api.md
+++ b/docs/cbox_api.md
@@ -48,10 +48,10 @@ void cbox_X_drop(cbox_X* self); // destruct the co
void cbox_X_reset(cbox_X* self);
void cbox_X_reset_to(cbox_X* self, i_val* p); // assign new cbox from ptr. Takes ownership of p.
-uint64_t cbox_X_hash(const cbox_X* x); // hash value
-int cbox_X_cmp(const cbox_X* x, const cbox_X* y); // compares pointer addresses if no `i_cmp` is specified.
- // is defined. Otherwise uses 'i_cmp' or default cmp.
-bool cbox_X_eq(const cbox_X* x, const cbox_X* y); // cbox_X_cmp() == 0
+uint64_t cbox_X_hash(const cbox_X* x); // hash value
+int cbox_X_cmp(const cbox_X* x, const cbox_X* y); // compares pointer addresses if no `i_cmp` is specified.
+ // is defined. Otherwise uses 'i_cmp' or default cmp.
+bool cbox_X_eq(const cbox_X* x, const cbox_X* y); // cbox_X_cmp() == 0
// functions on pointed to objects.
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index b610ff04..54b0312d 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -104,7 +104,7 @@ NOTE: One must always make sure to unwind temporary allocated resources before a
- 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:
+from a `c_AUTO` scope:
```c
int flag = 0;
for (int i = 0; i<n; ++i) {
@@ -122,7 +122,7 @@ from a `c_AUTO` scope:
if (cond3())
return -1; // checkauto ERROR! return inside c_AUTO
-
+
// CORRECT:
if (cond2()) {
flag = 1; // flag to break outer for-loop
@@ -225,10 +225,10 @@ 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_SKIPWHILE(it, predicate)` | Skip items until predicate is false |
-| `c_FLT_TAKEWHILE(it, predicate)` | Take items until predicate is false |
+| `c_flt_skip(it, numItems)` | Skip numItems |
+| `c_flt_take(it, numItems)` | Take numItems |
+| `c_flt_skipwhile(it, predicate)` | Skip items until predicate is false |
+| `c_flt_takewhile(it, predicate)` | Take items until predicate is false |
`it.index` holds the index of the source item, and `it.count` the current number of items taken.
```c
@@ -249,20 +249,36 @@ int main() {
c_FORFILTER (i, IVec, vec,
isOdd(*i.ref)
- && c_FLT_SKIP(i, 100) // built-in
+ && c_flt_skip(i, 100) // built-in
&& isPrime(*i.ref)
- , c_FLT_TAKE(i, 10)) { // breaks loop on false.
- printf(" %d", *i.ref);
+ , c_flt_take(i, 10)) { // breaks loop on false.
+ printf(" %d", *i.ref);
}
puts("");
}
}
-// Out: 1000211 1000213 1000231 1000249 1000253 1000273 1000289 1000291 1000303 1000313
+// Out: 1000211 1000213 1000231 1000249 1000253 1000273 1000289 1000291 1000303 1000313
+```
+Note that `c_flt_take()` is given as an optional argument, which makes the loop stop when it becomes false (for efficiency). Chaining it after `isPrime()` instead will give same result, but the full input is processed.
+
+### c_make
+
+Make a container from a literal initializer list. Example:
+```c
+#define i_val_str // cstr value type
+#include <stc/cset.h>
+
+#define i_key int
+#define i_val int
+#include <stc/cmap.h>
+...
+cset_str myset = c_make(cset_str, {"This", "is", "the", "story"}); // note: const char* values given!
+int x = 7, y = 8;
+cmap_int mymap = c_make(cmap_int, { {1, 2}, {3, 4}, {5, 6}, {x, y} });
```
-Note that `c_FLT_TAKE()` is given as an optional argument, which makes the loop stop when it becomes false (for efficiency). Chaining it after `isPrime()` instead will give same result, but the full input is processed.
### crange
-**crange** is a number sequence generator type. The **crange_value** type is `long long`. Below, *start*, *stop*, *step* are type *crange_value*:
+**crange** is a number sequence generator type. The **crange_value** type is `long long`. Below *start*, *stop*, and *step* are of type *crange_value*:
```c
crange crange_make(stop); // will generate 0, 1, ..., stop-1
crange crange_make(start, stop); // will generate start, start+1, ... stop-1
@@ -275,57 +291,42 @@ void crange_next(crange_iter* it);
// 1. All primes less than 32:
crange r1 = crange_make(3, 32, 2);
printf("2"); // first prime
-c_FORFILTER (i, crange, r1
+c_FORFILTER (i, crange, r1
, isPrime(*i.ref))
printf(" %lld", *i.ref);
// 2 3 5 7 11 13 17 19 23 29 31
// 2. The 11 first primes:
printf("2");
-c_FORFILTER (i, crange, crange_literal(3, INT64_MAX, 2)
+c_FORFILTER (i, crange, crange_literal(3, INT64_MAX, 2)
, isPrime(*i.ref)
- , c_FLT_TAKE(10))
+ , c_flt_take(10))
printf(" %lld", *i.ref);
// 2 3 5 7 11 13 17 19 23 29 31
```
-### c_FIND_IF, c_ERASE_IF
+### c_find_if, c_erase_if, c_swap, c_drop
Find or erase linearily in containers using a predicate
```c
// Search vec for first value > 2:
cvec_i_iter i;
-c_FIND_IF(i, cvec_i, vec, *i.ref > 2);
+c_find_if(i, cvec_i, vec, *i.ref > 2);
if (i.ref) printf("%d\n", *i.ref);
// Search map for a string containing "hello" and erase it:
cmap_str_iter it, it1 = ..., it2 = ...;
-c_FIND_IF(it, csmap_str, it1, it2, cstr_contains(it.ref, "hello"));
+c_find_if(it, csmap_str, it1, it2, cstr_contains(it.ref, "hello"));
if (it.ref) cmap_str_erase_at(&map, it);
// Erase all strings containing "hello":
// Note 1: iter i need not be declared.
// Note 2: variables index and count can be accessed in predicate.
-c_ERASE_IF(i, csmap_str, map, cstr_contains(i.ref, "hello"));
-```
-
-### c_NEW, c_ALLOC, c_ALLOC_N, c_DROP
-
-| Usage | Meaning |
-|:-------------------------------|:----------------------------------------|
-| `c_NEW (type, value)` | Move value to a new object on the heap |
-| `c_ALLOC (type)` | `(type *) c_MALLOC(sizeof(type))` |
-| `c_ALLOC_N (type, N)` | `(type *) c_MALLOC((N)*sizeof(type))` |
-| `c_DROP (ctype, &c1, ..., &cN)` | `ctype_drop(&c1); ... ctype_drop(&cN)` |
+c_erase_if(i, csmap_str, map, cstr_contains(i.ref, "hello"));
-```c
-struct Pnt { double x, y, z; };
-struct Pnt *pnt = c_NEW (struct Pnt, {1.2, 3.4, 5.6});
-c_FREE(pnt);
-
-int* array = c_ALLOC_N (int, 100);
-c_FREE(array);
+// Safe macro for swapping internals of two objects of same type:
+c_swap(cmap_int, &map1, &map2);
-cstr a = cstr_lit("Hello"), b = cstr_lit("World");
-c_DROP(cstr, &a, &b);
+// Drop multiple containers of same type:
+c_drop(cvec_i, &vec1, &vec2, &vec3);
```
### General predefined template parameter functions
@@ -341,17 +342,29 @@ bool crawstr_eq(const crawstr* x, const crawstr* y);
uint64_t crawstr_hash(const crawstr* x);
```
-### c_MALLOC, c_CALLOC, c_REALLOC, c_FREE
-Memory allocator for the entire library. Macros can be overridden by the user.
+### c_NEW, c_ALLOC, c_ALLOC_N
+
+| Usage | Meaning |
+|:----------------------------|:-------------------------------------------|
+| `c_NEW (type, value)` | Allocate and init a new object on the heap |
+| `c_ALLOC (type)` | `(type *) c_malloc(c_sizeof(type))` |
+| `c_ALLOC_N (type, N)` | `(type *) c_malloc((N)*c_sizeof(type))` |
-### c_SWAP, c_ARRAYLEN
-- **c_SWAP(T, xp, yp)**: Safe macro for swapping internals of two objects of same type.
-- **c_ARRAYLEN(array)**: Return number of elements in an array.
```c
-cmap_int map1 = {0}, map2 = {0};
-...
-c_SWAP(cmap_int, &map1, &map2);
+struct Pnt { double x, y, z; };
+struct Pnt *pnt = c_NEW(struct Pnt, {1.2, 3.4, 5.6});
+c_free(pnt);
+
+int* array = c_ALLOC_N(int, 100);
+c_free(array);
+```
+### c_malloc, c_calloc, c_realloc, c_free: customizable allocators
+Memory allocator for the entire library. Macros can be overridden by the user.
+
+### c_ARRAYLEN
+- **c_ARRAYLEN(array)**: Return number of elements in an array. array must not be a pointer!
+```c
int array[] = {1, 2, 3, 4};
-size_t n = c_ARRAYLEN(array);
+intptr_t n = c_ARRAYLEN(array);
```
diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md
index 584d382f..716a608c 100644
--- a/docs/cdeq_api.md
+++ b/docs/cdeq_api.md
@@ -27,25 +27,25 @@ See the c++ class [std::deque](https://en.cppreference.com/w/cpp/container/deque
```c
cdeq_X cdeq_X_init(void);
-cdeq_X cdeq_X_with_capacity(size_t size);
+cdeq_X cdeq_X_with_capacity(intptr_t size);
cdeq_X cdeq_X_clone(cdeq_X deq);
void cdeq_X_clear(cdeq_X* self);
void cdeq_X_copy(cdeq_X* self, const cdeq_X* other);
cdeq_X_iter cdeq_X_copy_range(cdeq_X* self, i_val* pos, const i_val* p1, const i_val* p2);
-bool cdeq_X_reserve(cdeq_X* self, size_t cap);
+bool cdeq_X_reserve(cdeq_X* self, intptr_t cap);
void cdeq_X_shrink_to_fit(cdeq_X* self);
-void cdeq_X_drop(cdeq_X* self); // destructor
+void cdeq_X_drop(cdeq_X* self); // destructor
bool cdeq_X_empty(const cdeq_X* self);
-size_t cdeq_X_size(const cdeq_X* self);
-size_t cdeq_X_capacity(const cdeq_X* self);
+intptr_t cdeq_X_size(const cdeq_X* self);
+intptr_t cdeq_X_capacity(const cdeq_X* self);
-const cdeq_X_value* cdeq_X_at(const cdeq_X* self, size_t idx);
-const cdeq_X_value* cdeq_X_get(const cdeq_X* self, i_valraw raw); // return NULL if not found
-cdeq_X_value* cdeq_X_get_mut(cdeq_X* self, i_valraw raw); // mutable get
+const cdeq_X_value* cdeq_X_at(const cdeq_X* self, intptr_t idx);
+const cdeq_X_value* cdeq_X_get(const cdeq_X* self, i_valraw raw); // return NULL if not found
+cdeq_X_value* cdeq_X_get_mut(cdeq_X* self, i_valraw raw); // mutable get
cdeq_X_iter cdeq_X_find(const cdeq_X* self, i_valraw raw);
-cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); // return cvec_X_end() if not found
+cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); // return cvec_X_end() if not found
cdeq_X_value* cdeq_X_front(const cdeq_X* self);
cdeq_X_value* cdeq_X_back(const cdeq_X* self);
@@ -55,23 +55,23 @@ cdeq_X_value* cdeq_X_emplace_front(cdeq_X* self, i_valraw raw);
void cdeq_X_pop_front(cdeq_X* self);
cdeq_X_value* cdeq_X_push_back(cdeq_X* self, i_val value);
-cdeq_X_value* cdeq_X_push(cdeq_X* self, i_val value); // alias for push_back()
+cdeq_X_value* cdeq_X_push(cdeq_X* self, i_val value); // alias for push_back()
cdeq_X_value* cdeq_X_emplace_back(cdeq_X* self, i_valraw raw);
-cdeq_X_value* cdeq_X_emplace(cdeq_X* self, i_valraw raw); // alias for emplace_back()
+cdeq_X_value* cdeq_X_emplace(cdeq_X* self, i_valraw raw); // alias for emplace_back()
void cdeq_X_pop_back(cdeq_X* self);
-cdeq_X_iter cdeq_X_insert(cdeq_X* self, size_t idx, i_val value); // move value
-cdeq_X_iter cdeq_X_insert_n(cdeq_X* self, size_t idx, const i_val[] arr, size_t n); // move arr values
-cdeq_X_iter cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value
+cdeq_X_iter cdeq_X_insert(cdeq_X* self, intptr_t idx, i_val value); // move value
+cdeq_X_iter cdeq_X_insert_n(cdeq_X* self, intptr_t idx, const i_val[] arr, intptr_t n); // move arr values
+cdeq_X_iter cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value
cdeq_X_iter cdeq_X_insert_range(cdeq_X* self, i_val* pos,
const i_val* p1, const i_val* p2);
-cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values
+cdeq_X_iter cdeq_X_emplace_n(cdeq_X* self, intptr_t idx, const i_valraw[] arr, intptr_t n); // clone values
cdeq_X_iter cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw);
cdeq_X_iter cdeq_X_emplace_range(cdeq_X* self, i_val* pos,
const i_valraw* p1, const i_valraw* p2);
-cdeq_X_iter cdeq_X_erase_n(cdeq_X* self, size_t idx, size_t n);
+cdeq_X_iter cdeq_X_erase_n(cdeq_X* self, intptr_t idx, intptr_t n);
cdeq_X_iter cdeq_X_erase_at(cdeq_X* self, cdeq_X_iter it);
cdeq_X_iter cdeq_X_erase_range(cdeq_X* self, cdeq_X_iter it1, cdeq_X_iter it2);
cdeq_X_iter cdeq_X_erase_range_p(cdeq_X* self, i_val* p1, i_val* p2);
@@ -83,7 +83,7 @@ void cdeq_X_sort_range(cdeq_X_iter i1, cdeq_X_iter i2,
cdeq_X_iter cdeq_X_begin(const cdeq_X* self);
cdeq_X_iter cdeq_X_end(const cdeq_X* self);
void cdeq_X_next(cdeq_X_iter* it);
-cdeq_X_iter cdeq_X_advance(cdeq_X_iter it, intptr_t n);
+cdeq_X_iter cdeq_X_advance(cdeq_X_iter it, size_t n);
cdeq_X_raw cdeq_X_value_toraw(cdeq_X_value* pval);
cdeq_X_value cdeq_X_value_clone(cdeq_X_value val);
diff --git a/docs/clist_api.md b/docs/clist_api.md
index e97d7b5d..29bfd5ff 100644
--- a/docs/clist_api.md
+++ b/docs/clist_api.md
@@ -45,33 +45,33 @@ clist_X clist_X_clone(clist_X list);
void clist_X_clear(clist_X* self);
void clist_X_copy(clist_X* self, const clist_X* other);
-void clist_X_drop(clist_X* self); // destructor
+void clist_X_drop(clist_X* self); // destructor
bool clist_X_empty(const clist_X* list);
-size_t clist_X_count(const clist_X* list); // size() in O(n) time
+intptr_t clist_X_count(const clist_X* list); // size() in O(n) time
clist_X_value* clist_X_back(const clist_X* self);
clist_X_value* clist_X_front(const clist_X* self);
-void clist_X_push_back(clist_X* self, i_val value); // note: no pop_back()
+void clist_X_push_back(clist_X* self, i_val value); // note: no pop_back()
void clist_X_push_front(clist_X* self, i_val value);
-void clist_X_push(clist_X* self, i_val value); // alias for push_back()
+void clist_X_push(clist_X* self, i_val value); // alias for push_back()
void clist_X_emplace_back(clist_X* self, i_valraw raw);
void clist_X_emplace_front(clist_X* self, i_valraw raw);
-void clist_X_emplace(clist_X* self, i_valraw raw); // alias for emplace_back()
+void clist_X_emplace(clist_X* self, i_valraw raw); // alias for emplace_back()
-clist_X_iter clist_X_insert_at(clist_X* self, clist_X_iter it, i_val value); // return iter to new elem
+clist_X_iter clist_X_insert_at(clist_X* self, clist_X_iter it, i_val value); // return iter to new elem
clist_X_iter clist_X_emplace_at(clist_X* self, clist_X_iter it, i_valraw raw);
void clist_X_pop_front(clist_X* self);
-clist_X_iter clist_X_erase_at(clist_X* self, clist_X_iter it); // return iter after it
+clist_X_iter clist_X_erase_at(clist_X* self, clist_X_iter it); // return iter after it
clist_X_iter clist_X_erase_range(clist_X* self, clist_X_iter it1, clist_X_iter it2);
-size_t clist_X_remove(clist_X* self, i_valraw raw); // removes all matches
+intptr_t clist_X_remove(clist_X* self, i_valraw raw); // removes all matches
-clist_X clist_X_split_off(clist_X* self, clist_X_iter i1, clist_X_iter i2); // split off [i1, i2)
-clist_X_iter clist_X_splice(clist_X* self, clist_X_iter it, clist_X* other); // return updated valid it
-clist_X_iter clist_X_splice_range(clist_X* self, clist_X_iter it, // return updated valid it
+clist_X clist_X_split_off(clist_X* self, clist_X_iter i1, clist_X_iter i2); // split off [i1, i2)
+clist_X_iter clist_X_splice(clist_X* self, clist_X_iter it, clist_X* other); // return updated valid it
+clist_X_iter clist_X_splice_range(clist_X* self, clist_X_iter it, // return updated valid it
clist_X* other, clist_X_iter it1, clist_X_iter it2);
clist_X_iter clist_X_find(const clist_X* self, i_valraw raw);
@@ -83,10 +83,10 @@ void clist_X_sort(clist_X* self);
void clist_X_reverse(clist_X* self);
// Node API
-clist_X_node* clist_X_get_node(clist_X_value* val); // get the enclosing node
+clist_X_node* clist_X_get_node(clist_X_value* val); // get the enclosing node
clist_X_value* clist_X_push_node_back(clist_X* self, clist_X_node* node);
clist_X_value* clist_X_insert_node_after(clist_X* self, clist_X_node* ref, clist_X_node* node);
-clist_X_node* clist_X_unlink_node_after(clist_X* self, clist_X_node* ref); // return the unlinked node
+clist_X_node* clist_X_unlink_node_after(clist_X* self, clist_X_node* ref); // return the unlinked node
void clist_X_erase_node_after(clist_X* self, clist_X_node* node);
clist_X_iter clist_X_begin(const clist_X* self);
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index a33715fc..0b91abc7 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -48,56 +48,56 @@ See the c++ class [std::unordered_map](https://en.cppreference.com/w/cpp/contain
```c
cmap_X cmap_X_init(void);
-cmap_X cmap_X_with_capacity(size_t cap);
+cmap_X cmap_X_with_capacity(int64_t cap);
cmap_X cmap_X_clone(cmap_x map);
void cmap_X_clear(cmap_X* self);
void cmap_X_copy(cmap_X* self, const cmap_X* other);
-float cmap_X_max_load_factor(const cmap_X* self); // default: 0.85f
-bool cmap_X_reserve(cmap_X* self, size_t size);
+float cmap_X_max_load_factor(const cmap_X* self); // default: 0.85f
+bool cmap_X_reserve(cmap_X* self, int64_t size);
void cmap_X_shrink_to_fit(cmap_X* self);
-void cmap_X_drop(cmap_X* self); // destructor
+void cmap_X_drop(cmap_X* self); // destructor
-size_t cmap_X_size(const cmap_X* self);
-size_t cmap_X_capacity(const cmap_X* self); // buckets * max_load_factor
bool cmap_X_empty(const cmap_X* self );
-size_t cmap_X_bucket_count(const cmap_X* self); // num. of allocated buckets
-
-const cmap_X_mapped* cmap_X_at(const cmap_X* self, i_keyraw rkey); // rkey must be in map
-cmap_X_mapped* cmap_X_at_mut(cmap_X* self, i_keyraw rkey); // mutable at
-const cmap_X_value* cmap_X_get(const cmap_X* self, i_keyraw rkey); // const get
-cmap_X_value* cmap_X_get_mut(cmap_X* self, i_keyraw rkey); // mutable get
+int64_t cmap_X_size(const cmap_X* self);
+int64_t cmap_X_capacity(const cmap_X* self); // buckets * max_load_factor
+int64_t cmap_X_bucket_count(const cmap_X* self); // num. of allocated buckets
+
+const cmap_X_mapped* cmap_X_at(const cmap_X* self, i_keyraw rkey); // rkey must be in map
+cmap_X_mapped* cmap_X_at_mut(cmap_X* self, i_keyraw rkey); // mutable at
+const cmap_X_value* cmap_X_get(const cmap_X* self, i_keyraw rkey); // const get
+cmap_X_value* cmap_X_get_mut(cmap_X* self, i_keyraw rkey); // mutable get
bool cmap_X_contains(const cmap_X* self, i_keyraw rkey);
-cmap_X_iter cmap_X_find(const cmap_X* self, i_keyraw rkey); // find element
+cmap_X_iter cmap_X_find(const cmap_X* self, i_keyraw rkey); // find element
-cmap_X_result cmap_X_insert(cmap_X* self, i_key key, i_val mapped); // no change if key in map
-cmap_X_result cmap_X_insert_or_assign(cmap_X* self, i_key key, i_val mapped); // always update mapped
-cmap_X_result cmap_X_push(cmap_X* self, cmap_X_value entry); // similar to insert
+cmap_X_result cmap_X_insert(cmap_X* self, i_key key, i_val mapped); // no change if key in map
+cmap_X_result cmap_X_insert_or_assign(cmap_X* self, i_key key, i_val mapped); // always update mapped
+cmap_X_result cmap_X_push(cmap_X* self, cmap_X_value entry); // similar to insert
-cmap_X_result cmap_X_emplace(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map
+cmap_X_result cmap_X_emplace(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map
cmap_X_result cmap_X_emplace_or_assign(cmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update rmapped
-size_t cmap_X_erase(cmap_X* self, i_keyraw rkey); // return 0 or 1
-cmap_X_iter cmap_X_erase_at(cmap_X* self, cmap_X_iter it); // return iter after it
+int cmap_X_erase(cmap_X* self, i_keyraw rkey); // return 0 or 1
+cmap_X_iter cmap_X_erase_at(cmap_X* self, cmap_X_iter it); // return iter after it
void cmap_X_erase_entry(cmap_X* self, cmap_X_value* entry);
cmap_X_iter cmap_X_begin(const cmap_X* self);
cmap_X_iter cmap_X_end(const cmap_X* self);
void cmap_X_next(cmap_X_iter* it);
-cmap_X_iter cmap_X_advance(cmap_X_iter it, size_t n);
+cmap_X_iter cmap_X_advance(cmap_X_iter it, uint64_t n);
cmap_X_value cmap_X_value_clone(cmap_X_value val);
cmap_X_raw cmap_X_value_toraw(cmap_X_value* pval);
```
Helpers:
```c
-uint64_t c_default_hash(const X *obj); // macro, calls cfasthash(obj, sizeof *obj)
-uint64_t cstrhash(const char *str); // string hash funcion, uses strlen()
-uint64_t cfasthash(const void *data, size_t len); // base hash function
+uint64_t c_default_hash(const X *obj); // macro, calls cfasthash(obj, sizeof *obj)
+uint64_t cstrhash(const char *str); // string hash funcion, uses strlen()
+uint64_t cfasthash(const void *data, intptr_t len); // base hash function
// equalto template parameter functions:
-bool c_default_eq(const i_keyraw* a, const i_keyraw* b); // *a == *b
-bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // !memcmp(a, b, sizeof *a)
+bool c_default_eq(const i_keyraw* a, const i_keyraw* b); // *a == *b
+bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // !memcmp(a, b, sizeof *a)
```
## Types
@@ -353,7 +353,7 @@ typedef struct Viking {
} Viking;
static inline void Viking_drop(Viking* v) {
- c_DROP(cstr, &v->name, &v->country);
+ c_drop(cstr, &v->name, &v->country);
}
// Define Viking raw struct with cmp, hash, and convertion functions between Viking and RViking structs:
diff --git a/docs/cpque_api.md b/docs/cpque_api.md
index 392d3149..48a5b29e 100644
--- a/docs/cpque_api.md
+++ b/docs/cpque_api.md
@@ -28,17 +28,17 @@ See the c++ class [std::priority_queue](https://en.cppreference.com/w/cpp/contai
```c
cpque_X cpque_X_init(void); // create empty pri-queue.
-cpque_X cpque_X_with_capacity(size_t cap);
-cpque_X cpque_X_with_size(size_t size, i_val null);
+cpque_X cpque_X_with_capacity(intptr_t cap);
+cpque_X cpque_X_with_size(intptr_t size, i_val null);
cpque_X cpque_X_clone(cpque_X pq);
void cpque_X_clear(cpque_X* self);
-bool cpque_X_reserve(cpque_X* self, size_t n);
+bool cpque_X_reserve(cpque_X* self, intptr_t n);
void cpque_X_shrink_to_fit(cpque_X* self);
void cpque_X_copy(cpque_X* self, const cpque_X* other);
void cpque_X_drop(cpque_X* self); // destructor
-size_t cpque_X_size(const cpque_X* self);
+intptr_t cpque_X_size(const cpque_X* self);
bool cpque_X_empty(const cpque_X* self);
i_val* cpque_X_top(const cpque_X* self);
@@ -47,7 +47,7 @@ void cpque_X_push(cpque_X* self, i_val value);
void cpque_X_emplace(cpque_X* self, i_valraw raw); // converts from raw
void cpque_X_pop(cpque_X* self);
-void cpque_X_erase_at(cpque_X* self, size_t idx);
+void cpque_X_erase_at(cpque_X* self, intptr_t idx);
i_val cpque_X_value_clone(i_val value);
```
@@ -71,7 +71,7 @@ i_val cpque_X_value_clone(i_val value);
int main()
{
- size_t N = 10000000;
+ intptr_t N = 10000000;
stc64_t rng = stc64_new(1234);
stc64_uniform_t dist = stc64_uniform_new(0, N * 10);
diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md
index 977fa855..212cdabe 100644
--- a/docs/cqueue_api.md
+++ b/docs/cqueue_api.md
@@ -32,7 +32,7 @@ void cqueue_X_clear(cqueue_X* self);
void cqueue_X_copy(cqueue_X* self, const cqueue_X* other);
void cqueue_X_drop(cqueue_X* self); // destructor
-size_t cqueue_X_size(const cqueue_X* self);
+intptr_t cqueue_X_size(const cqueue_X* self);
bool cqueue_X_empty(const cqueue_X* self);
cqueue_X_value* cqueue_X_front(const cqueue_X* self);
cqueue_X_value* cqueue_X_back(const cqueue_X* self);
diff --git a/docs/crandom_api.md b/docs/crandom_api.md
index bd3bf848..391c485f 100644
--- a/docs/crandom_api.md
+++ b/docs/crandom_api.md
@@ -41,22 +41,22 @@ All crandom definitions and prototypes are available by including a single heade
## Methods
```c
-void csrandom(uint64_t seed); // seed global stc64 prng
-uint64_t crandom(void); // global stc64_rand(rng)
-double crandomf(void); // global stc64_randf(rng)
+void csrandom(uint64_t seed); // seed global stc64 prng
+uint64_t crandom(void); // global stc64_rand(rng)
+double crandomf(void); // global stc64_randf(rng)
-stc64_t stc64_new(uint64_t seed); // stc64_init(s) is deprecated
-stc64_t stc64_with_seq(uint64_t seed, uint64_t seq); // with unique stream
+stc64_t stc64_new(uint64_t seed); // stc64_init(s) is deprecated
+stc64_t stc64_with_seq(uint64_t seed, uint64_t seq); // with unique stream
-uint64_t stc64_rand(stc64_t* rng); // range [0, 2^64 - 1]
-double stc64_randf(stc64_t* rng); // range [0.0, 1.0)
+uint64_t stc64_rand(stc64_t* rng); // range [0, 2^64 - 1]
+double stc64_randf(stc64_t* rng); // range [0.0, 1.0)
-stc64_uniform_t stc64_uniform_new(int64_t low, int64_t high); // uniform-distribution
-int64_t stc64_uniform(stc64_t* rng, stc64_uniform_t* dist); // range [low, high]
+stc64_uniform_t stc64_uniform_new(int64_t low, int64_t high); // uniform-distribution
+int64_t stc64_uniform(stc64_t* rng, stc64_uniform_t* dist); // range [low, high]
stc64_uniformf_t stc64_uniformf_new(double lowf, double highf);
-double stc64_uniformf(stc64_t* rng, stc64_uniformf_t* dist); // range [lowf, highf)
+double stc64_uniformf(stc64_t* rng, stc64_uniformf_t* dist); // range [lowf, highf)
-stc64_normalf_t stc64_normalf_new(double mean, double stddev); // normal-distribution
+stc64_normalf_t stc64_normalf_new(double mean, double stddev); // normal-distribution
double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist);
```
## Types
@@ -76,7 +76,7 @@ double stc64_normalf(stc64_t* rng, stc64_normalf_t* dist);
// Declare int -> int sorted map. Uses typetag 'i' for ints.
#define i_key int
-#define i_val size_t
+#define i_val intptr_t
#define i_tag i
#include <stc/csmap.h>
@@ -102,7 +102,7 @@ int main()
// Print the gaussian bar chart
cstr bar = cstr_init();
c_FOREACH (i, csmap_i, mhist) {
- size_t n = (size_t) (i.ref->second * StdDev * Scale * 2.5 / N);
+ int n = (int)(i.ref->second * StdDev * Scale * 2.5 / N);
if (n > 0) {
cstr_resize(&bar, n, '*');
printf("%4d %s\n", i.ref->first, cstr_str(&bar));
diff --git a/docs/cregex_api.md b/docs/cregex_api.md
index c01f324c..e74040d8 100644
--- a/docs/cregex_api.md
+++ b/docs/cregex_api.md
@@ -23,35 +23,36 @@ enum {
};
cregex cregex_init(void);
-cregex cregex_from(const char* pattern, int cflags);
- /* return CREG_OK, or negative error code on failure */
-int cregex_compile(cregex *self, const char* pattern, int cflags);
+cregex cregex_from(const char* pattern, int cflags = CREG_DEFAULT);
+ // return CREG_OK, or negative error code on failure
+int cregex_compile(cregex *self, const char* pattern, int cflags = CREG_DEFAULT);
- /* num. of capture groups in regex. 0 if RE is invalid. First group is the full match */
+ // num. of capture groups in regex. 0 if RE is invalid. First group is the full match
int cregex_captures(const cregex* self);
- /* return CREG_OK, CREG_NOMATCH, or CREG_MATCHERROR */
-int cregex_find(const cregex* re, const char* input, csview match[], int mflags);
- /* Search inside input string-view only */
+ // return CREG_OK, CREG_NOMATCH, or CREG_MATCHERROR
+int cregex_find(const cregex* re, const char* input, csview match[], int mflags = CREG_DEFAULT);
+ // Search inside input string-view only
int cregex_find_sv(const cregex* re, csview input, csview match[]);
- /* All-in-one search (compile + find + drop) */
-int cregex_find_pattern(const char* pattern, const char* input, csview match[], int cmflags);
+ // All-in-one search (compile + find + drop)
+int cregex_find_pattern(const char* pattern, const char* input, csview match[], int cmflags = CREG_DEFAULT);
- /* Check if there are matches in input */
+ // Check if there are matches in input
bool cregex_is_match(const cregex* re, const char* input);
- /* Replace all matches in input */
-cstr cregex_replace(const cregex* re, const char* input, const char* replace);
- /* Replace count matches in input string-view. Optionally transform replacement with mfun. */
-cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count,
+ // Replace all matches in input
+cstr cregex_replace(const cregex* re, const char* input, const char* replace, int count = INT_MAX);
+ // Replace count matches in input string-view. Optionally transform replacement with mfun.
+cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, int count = INT_MAX);
+cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, int count,
bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags);
- /* 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_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 */
+ // All-in-one replacement (compile + find/replace + drop)
+cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace, int count = INT_MAX);
+cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace, int count,
+ bool(*mfun)(int capgrp, csview match, cstr* mstr), int rflags);
+ // destroy
+void cregex_drop(cregex* self);
```
### Error codes
diff --git a/docs/cset_api.md b/docs/cset_api.md
index e1d08a87..ef4df63b 100644
--- a/docs/cset_api.md
+++ b/docs/cset_api.md
@@ -30,32 +30,32 @@ A **cset** is an associative container that contains a set of unique objects of
```c
cset_X cset_X_init(void);
-cset_X cset_X_with_capacity(size_t cap);
+cset_X cset_X_with_capacity(intptr_t cap);
cset_X cset_X_clone(cset_x set);
void cset_X_clear(cset_X* self);
void cset_X_copy(cset_X* self, const cset_X* other);
-float cset_X_max_load_factor(const cset_X* self); // default: 0.85
-bool cset_X_reserve(cset_X* self, size_t size);
+float cset_X_max_load_factor(const cset_X* self); // default: 0.85
+bool cset_X_reserve(cset_X* self, intptr_t size);
void cset_X_shrink_to_fit(cset_X* self);
-void cset_X_drop(cset_X* self); // destructor
+void cset_X_drop(cset_X* self); // destructor
-size_t cset_X_size(const cset_X* self); // num. of allocated buckets
-size_t cset_X_capacity(const cset_X* self); // buckets * max_load_factor
+intptr_t cset_X_size(const cset_X* self); // num. of allocated buckets
+intptr_t cset_X_capacity(const cset_X* self); // buckets * max_load_factor
bool cset_X_empty(const cset_X* self);
-size_t cset_X_bucket_count(const cset_X* self);
+intptr_t cset_X_bucket_count(const cset_X* self);
bool cset_X_contains(const cset_X* self, i_keyraw rkey);
-const cset_X_value* cset_X_get(const cset_X* self, i_keyraw rkey); // return NULL if not found
-cset_X_value* cset_X_get_mut(cset_X* self, i_keyraw rkey); // mutable get
+const cset_X_value* cset_X_get(const cset_X* self, i_keyraw rkey); // return NULL if not found
+cset_X_value* cset_X_get_mut(cset_X* self, i_keyraw rkey); // mutable get
cset_X_iter cset_X_find(const cset_X* self, i_keyraw rkey);
cset_X_result cset_X_insert(cset_X* self, i_key key);
-cset_X_result cset_X_push(cset_X* self, i_key key); // alias for insert.
+cset_X_result cset_X_push(cset_X* self, i_key key); // alias for insert.
cset_X_result cset_X_emplace(cset_X* self, i_keyraw rkey);
-size_t cset_X_erase(cset_X* self, i_keyraw rkey); // return 0 or 1
-cset_X_iter cset_X_erase_at(cset_X* self, cset_X_iter it); // return iter after it
+intptr_t cset_X_erase(cset_X* self, i_keyraw rkey); // return 0 or 1
+cset_X_iter cset_X_erase_at(cset_X* self, cset_X_iter it); // return iter after it
void cset_X_erase_entry(cset_X* self, cset_X_value* entry);
cset_X_iter cset_X_begin(const cset_X* self);
diff --git a/docs/csmap_api.md b/docs/csmap_api.md
index 687a6cab..b090f737 100644
--- a/docs/csmap_api.md
+++ b/docs/csmap_api.md
@@ -42,8 +42,8 @@ See the c++ class [std::map](https://en.cppreference.com/w/cpp/container/map) fo
```c
csmap_X csmap_X_init(void);
-csset_X csmap_X_with_capacity(size_t cap);
-bool csmap_X_reserve(csmap_X* self, size_t cap);
+csset_X csmap_X_with_capacity(int64_t cap);
+bool csmap_X_reserve(csmap_X* self, int64_t cap);
void csmap_X_shrink_to_fit(csmap_X* self);
csmap_X csmap_X_clone(csmap_x map);
@@ -51,9 +51,9 @@ void csmap_X_clear(csmap_X* self);
void csmap_X_copy(csmap_X* self, const csmap_X* other);
void csmap_X_drop(csmap_X* self); // destructor
-size_t csmap_X_size(const csmap_X* self);
bool csmap_X_empty(const csmap_X* self);
-bool csmap_X_capacity(const csmap_X* self);
+int64_t csmap_X_size(const csmap_X* self);
+int64_t csmap_X_capacity(const csmap_X* self);
const csmap_X_mapped* csmap_X_at(const csmap_X* self, i_keyraw rkey); // rkey must be in map
csmap_X_mapped* csmap_X_at_mut(csmap_X* self, i_keyraw rkey); // mutable at
@@ -74,14 +74,14 @@ csmap_X_result csmap_X_push(csmap_X* self, csmap_X_value entry);
csmap_X_result csmap_X_emplace(csmap_X* self, i_keyraw rkey, i_valraw rmapped); // no change if rkey in map
csmap_X_result csmap_X_emplace_or_assign(csmap_X* self, i_keyraw rkey, i_valraw rmapped); // always update rmapped
-size_t csmap_X_erase(csmap_X* self, i_keyraw rkey);
+intptr_t csmap_X_erase(csmap_X* self, i_keyraw rkey);
csmap_X_iter csmap_X_erase_at(csmap_X* self, csmap_X_iter it); // returns iter after it
csmap_X_iter csmap_X_erase_range(csmap_X* self, csmap_X_iter it1, csmap_X_iter it2); // returns updated it2
csmap_X_iter csmap_X_begin(const csmap_X* self);
csmap_X_iter csmap_X_end(const csmap_X* self);
void csmap_X_next(csmap_X_iter* iter);
-csmap_X_iter csmap_X_advance(csmap_X_iter it, size_t n);
+csmap_X_iter csmap_X_advance(csmap_X_iter it, uint64_t n);
csmap_X_value csmap_X_value_clone(csmap_X_value val);
csmap_X_raw csmap_X_value_toraw(csmap_X_value* pval);
diff --git a/docs/cspan_api.md b/docs/cspan_api.md
index 2865a1a5..d0463b0a 100644
--- a/docs/cspan_api.md
+++ b/docs/cspan_api.md
@@ -1,120 +1,199 @@
# STC [cspan](../include/stc/cspan.h): Multi-dimensional Array View
![Array](pics/array.jpg)
-The **cspan** is templated non-owning multi-dimensional view of an array.
-
-See the c++ classes [std::span](https://en.cppreference.com/w/cpp/container/span) and
+The **cspan** is templated non-owning multi-dimensional view of an array. See the c++ classes
+[std::span](https://en.cppreference.com/w/cpp/container/span) and
[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan) for similar functionality.
## Header file and declaration
```c
#include <stc/cspan.h>
-using_cspan(SpanType, ValueType, Rank); // define SpanType with ValueType elements.
- // Rank is number of dimensions (max 4)
+using_cspan(SpanType, ValueType); // define a 1-d SpanType with ValueType elements.
+using_cspan(SpanTypeN, ValueType, Rank); // define multi-dimensional span with Rank.
+ // Rank is number of dimensions (max 5)
// Shorthands:
-using_cspan2(S, ValueType); // define span types S, S2 with ranks 1, 2.
-using_cspan3(S, ValueType); // define span types S, S2, S3 with ranks 1, 2, 3.
-using_cspan4(S, ValueType); // define span types S, S2, S3, S4 with ranks 1, 2, 3, 4.
+using_cspan2(S, ValueType); // define span types S, S2 with ranks 1, 2.
+using_cspan3(S, ValueType); // define span types S, S2, S3 with ranks 1, 2, 3.
+using_cspan4(S, ValueType); // define span types S, S2, S3, S4 with ranks 1, 2, 3, 4.
```
## Methods
-Note that `cspan_make()`, `cmake_from*()`, `cspan_atN()`, `and cspan_subspanN()` require a (safe) cast to its span-type
-on assignment, but not on initialization of a span variable. All functions are type-safe, and arguments are side-effect safe, except for SpanType arg. which must not have side-effects.
+All functions are type-safe, and index arguments are side-effect safe.
```c
-SpanType{N} cspan_make(ValueType* data, size_t xdim, ...); // make N-dimensional cspan
-SpanType cspan_from(STCContainer* cnt); // create a 1D cspan from a compatible STC container
-SpanType cspan_from_array(ValueType array[]); // create a 1D cspan from a C array
-SpanType cspan_from_list(T ValueType, {val0, val1, ...}); // create a 1D cspan from an initializer list
-SpanType& cspan_literal(T SpanType, {val0, val1, ...}); // create a 1D cspan compound literal from init list
-
-void cspan_resize(SpanType{N}* self, size_t xdim, ...); // change the extent of each dimension
+SpanTypeN cspan_md(ValueType* data, intptr_t xdim, ...); // create a multi-dimensional cspan
+SpanType cspan_make(T SpanType, {v1, v2, ...}); // make a 1d-dimensional cspan from values
+SpanType cspan_from(STCContainer* cnt); // create a 1d cspan from a compatible STC container
+SpanType cspan_from_array(ValueType array[]); // create a 1d cspan from a C array
+
+intptr_t cspan_size(const SpanTypeN* self); // return number of elements
+unsigned cspan_rank(const SpanTypeN* self); // return number of dimensions
+intptr_t cspan_index(const SpanTypeN* self, intptr_t x, ..); // index of element
+
+ValueType* cspan_at(const SpanTypeN* self, intptr_t x, ...); // at(): num of args specifies rank of input span.
+ValueType* cspan_front(const SpanTypeN* self);
+ValueType* cspan_back(const SpanTypeN* self);
-size_t cspan_size(const SpanType{N}* self); // return number of elements
-unsigned cspan_rank(const SpanType{N}* self); // return number of dimensions
-size_t cspan_index(const SpanType{N}* self, size_t x, ...); // index of element
+ // general index slicing to create a subspan.
+ // {x} reduces rank. {x,c_END} slice to end. {c_ALL} take the full extent.
+SpanTypeN cspan_slice(T SpanTypeN, const SpanTypeM* parent, {x0,x1}, {y0,y1}, ...);
-ValueType* cspan_at(SpanType{N}* self, size_t x, ...); // at(): num of args decides input SpanType{N}.
-SpanType cspan_at2(SpanType2* self, size_t x); // return a 1D subarray cspan.
-SpanType{N} cspan_at3(SpanType3* self, size_t x, ...); // atN(): N decides input SpanType,
-SpanType{N} cspan_at4(SpanType4* self, size_t x, ...); // and num of args decides returned SpanType{N}.
-
-SpanType cspan_subspan(const SpanType* self, size_t offset, size_t count); // return a slice of a 1D cspan
-SpanType2 cspan_subspan2(const SpanType2 self, size_t offset, size_t count); // return a slice of a 2D cspan
-SpanType3 cspan_subspan3(const SpanType3 self, size_t offset, size_t count); // return a slice of a 3D cspan
-SpanType4 cspan_subspan4(const SpanType4 self, size_t offset, size_t count); // return a slice of a 4D cspan
-
-SpanType{N}_iter SpanType_begin(const SpanType{N}* self);
-SpanType{N}_iter SpanType_end(const SpanType{N}* self);
-void SpanType_next(SpanType{N}_iter* it);
+ // create a subspan of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL});
+SpanType cspan_submd2(const SpanType2* self, intptr_t x); // return a 1d subspan from a 2d span.
+SpanTypeN cspan_submd3(const SpanType3* self, intptr_t x, ...); // return a 1d or 2d subspan from a 3d span.
+SpanTypeN cspan_submd4(const SpanType4* self, intptr_t x, ...); // number of args determines rank of output span.
+
+ // create a subspan of same rank. Like e.g. cspan_slice(Span3, &ms3, {off,off+count}, {c_ALL}, {c_ALL});
+SpanType cspan_subspan(const SpanType* self, intptr_t offset, intptr_t count);
+SpanType2 cspan_subspan2(const SpanType2 self, intptr_t offset, intptr_t count);
+SpanType3 cspan_subspan3(const SpanType3 self, intptr_t offset, intptr_t count);
+
+SpanTypeN_iter SpanType_begin(const SpanTypeN* self);
+SpanTypeN_iter SpanType_end(const SpanTypeN* self);
+void SpanType_next(SpanTypeN_iter* it);
```
## Types
-| Type name | Type definition | Used to represent... |
-|:--------------------|:-----------------------------------------------|:---------------------|
-| SpanType{N} | `struct { ValueType *data; uint32_t dim[N]; }` | SpanType with rank N |
-| SpanType{N}`_value` | `ValueType` | The ValueType |
-| SpanType{N}`_iter` | `struct { ValueType *ref; ... }` | Iterator type |
+| Type name | Type definition | Used to represent... |
+|:------------------|:-----------------------------------------------|:---------------------|
+| SpanTypeN | `struct { ValueType *data; uint32_t shape[N]; }` | SpanType with rank N |
+| SpanTypeN`_value` | `ValueType` | The ValueType |
+| `c_ALL` | `0,-1` | Full extent |
+| `c_END` | `-1` | End of extent |
+
+## Example 1
+
+The *cspan_slice()* function is similar to pythons numpy multi-dimensional arrays slicing, e.g.:
+```py
+import numpy as np
+
+if __name__ == '__main__':
+ ms3 = np.array((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24), int)
+
+ ms3 = np.reshape(ms3, (2, 3, 4))
+ ss3 = ms3[:, 1:3, 2:]
+ ss2 = ss3[1]
+
+ for i in range(ss2.shape[0]):
+ for j in range(ss2.shape[1]):
+ print(" {}".format(ss2[i, j]), end='')
+ print('')
-## Example
+ for i in ss2.flat:
+ print(" {}".format(i), end='')
+
+# 19 20 23 24
+# 19 20 23 24
+```
+... can be done in C with cspan:
```c
-#include <stdio.h>
-#define i_val float
-#include <stc/cstack.h>
+#include <c11/fmt.h>
+#include <stc/cspan.h>
+using_cspan3(myspan, int); // define myspan, myspan2, myspan3.
+
+int main() {
+ int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
+ myspan3 ms3 = cspan_md(arr, 2, 3, 4);
+ myspan3 ss3 = cspan_slice(myspan3, &ms3, {c_ALL}, {1,3}, {2,c_END});
+ myspan2 ss2 = cspan_submd3(&ss3, 1);
+
+ c_FORRANGE (i, ss2.shape[0])
+ c_FORRANGE (j, ss2.shape[1])
+ fmt_print(" {}", *cspan_at(&ss2, i, j));
+ puts("");
+
+ c_FOREACH (i, myspan2, ss2)
+ fmt_print(" {}", *i.ref);
+}
+```
+... and (almost) in C++23:
+```c++
+#include <print>
+#include <mdspan>
+#include <tuple>
+
+int main() {
+ int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};
+
+ std::mdspan ms3(arr, 2, 3, 4);
+ auto ss3 = std::submdspan(ms3, std::full_extent, std::tuple{1,3}, std::tuple{2,4});
+ auto ss2 = std::submdspan(ss3, 1, std::full_extent, std::full_extent);
+
+ for (std::size_t i = 0; i < ss2.extent(0); ++i)
+ for (std::size_t j = 0; j < ss2.extent(1); ++j)
+ std::print(" {}", ss2[i, j]);
+ std::println();
+
+ // std::mdspan can't be iterated as a flat container!
+}
+```
+## Example 2
+Slicing cspan without and with reducing the rank (like numpy array slicing):
+```c
+#include <c11/fmt.h>
#include <stc/cspan.h>
-using_cspan3(FS, float); // Shorthand to define span types FS, FS2, and FS3.
+
+using_cspan3(Span, int); // Shorthand to define Span, Span2, and Span3
int main()
{
- int xd = 6, yd = 4, zd = 3;
- c_AUTO (cstack_float, vec) {
- c_FORRANGE (i, xd*yd*zd)
- cstack_float_push(&vec, i);
-
- // define "span3[xd][yd][zd]"
- FS3 span3 = cspan_make(vec.data, xd, yd, zd);
- *cspan_at(&span3, 4, 3, 2) = 3.14f;
- printf("index: %d", (int)cspan_index(&span3, 4, 3, 2));
-
- FS span1 = cspan_at3(&span3, 4, 3);
- printf("\niterate span1: ");
- c_FOREACH (i, FS, span1)
- printf("%g ", *i.ref);
-
- FS2 span2 = cspan_at3(&span3, 4);
- printf("\niterate span2: ");
- c_FOREACH (i, FS2, span2)
- printf("%g ", *i.ref);
-
- puts("\niterate span3 by dimensions:");
- c_FORRANGE (i, span3.dim[0]) {
- c_FORRANGE (j, span3.dim[1]) {
- c_FORRANGE (k, span3.dim[2])
- printf(" %2g", *cspan_at(&span3, i, j, k));
- printf(" |");
- }
- puts("");
+ // c_make() can create any STC container/span from an initializer list:
+ Span span = c_make(Span, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24});
+ // create a 3d cspan:
+ Span3 span3 = cspan_md(span.data, 2, 4, 3);
+
+ // reduce rank: (i.e. span3[1])
+ Span2 span2 = cspan_submd3(&span3, 1);
+
+ puts("\niterate span2 flat:");
+ c_FOREACH (i, Span2, span2)
+ fmt_print(" {}", *i.ref);
+ puts("");
+
+ // slice without reducing rank:
+ Span3 ss3 = cspan_slice(Span3, &span3, {c_ALL}, {3,4}, {c_ALL});
+
+ puts("\niterate ss3 by dimensions:");
+ c_FORRANGE (i, ss3.shape[0]) {
+ c_FORRANGE (j, ss3.shape[1]) {
+ c_FORRANGE (k, ss3.shape[2])
+ fmt_print(" {:2}", *cspan_at(&ss3, i, j, k));
+ fmt_print(" |");
}
-
- printf("%g\n", *cspan_at(&span3, 4, 3, 2));
- printf("%g\n", *cspan_at(&span2, 3, 2));
- printf("%g\n", *cspan_at(&span1, 2));
+ puts("");
+ }
+ // slice and reduce rank:
+ Span2 ss2 = cspan_slice(Span2, &span3, {c_ALL}, {3}, {c_ALL});
+
+ puts("\niterate ss2 by dimensions:");
+ c_FORRANGE (i, ss2.shape[0]) {
+ c_FORRANGE (j, ss2.shape[1]) {
+ fmt_print(" {:2}", *cspan_at(&ss2, i, j));
+ fmt_print(" |");
+ }
+ puts("");
}
+
+ puts("\niterate ss2 flat:");
+ c_FOREACH (i, Span2, ss2)
+ fmt_print(" {:2}", *i.ref);
+ puts("");
}
```
Output:
```
-index: 59
-iterate span1: 57 58 3.14
-iterate span2: 48 49 50 51 52 53 54 55 56 57 58 3.14
-iterate span3 by dimensions:
- 0 1 2 | 3 4 5 | 6 7 8 | 9 10 11 |
- 12 13 14 | 15 16 17 | 18 19 20 | 21 22 23 |
- 24 25 26 | 27 28 29 | 30 31 32 | 33 34 35 |
- 36 37 38 | 39 40 41 | 42 43 44 | 45 46 47 |
- 48 49 50 | 51 52 53 | 54 55 56 | 57 58 3.14 |
- 60 61 62 | 63 64 65 | 66 67 68 | 69 70 71 |
-3.14
-3.14
-3.14
+iterate span2 flat:
+ 13 14 15 16 17 18 19 20 21 22 23 24
+
+iterate ss3 by dimensions:
+ 10 11 12 |
+ 22 23 24 |
+
+iterate ss2 by dimensions:
+ 10 | 11 | 12 |
+ 22 | 23 | 24 |
+
+iterate ss2 flat:
+ 10 11 12 22 23 24
```
diff --git a/docs/csset_api.md b/docs/csset_api.md
index 6276f486..7e068909 100644
--- a/docs/csset_api.md
+++ b/docs/csset_api.md
@@ -28,8 +28,8 @@ See the c++ class [std::set](https://en.cppreference.com/w/cpp/container/set) fo
```c
csset_X csset_X_init(void);
-csset_X csset_X_with_capacity(size_t cap);
-bool csset_X_reserve(csset_X* self, size_t cap);
+csset_X csset_X_with_capacity(intptr_t cap);
+bool csset_X_reserve(csset_X* self, intptr_t cap);
void csset_X_shrink_to_fit(csset_X* self);
csset_X csset_X_clone(csset_x set);
@@ -37,7 +37,7 @@ void csset_X_clear(csset_X* self);
void csset_X_copy(csset_X* self, const csset_X* other);
void csset_X_drop(csset_X* self); // destructor
-size_t csset_X_size(const csset_X* self);
+intptr_t csset_X_size(const csset_X* self);
bool csset_X_empty(const csset_X* self);
const csset_X_value* csset_X_get(const csset_X* self, i_keyraw rkey); // const get
@@ -51,7 +51,7 @@ csset_X_result csset_X_insert(csset_X* self, i_key key);
csset_X_result csset_X_push(csset_X* self, i_key key); // alias for insert()
csset_X_result csset_X_emplace(csset_X* self, i_keyraw rkey);
-size_t csset_X_erase(csset_X* self, i_keyraw rkey);
+intptr_t csset_X_erase(csset_X* self, i_keyraw rkey);
csset_X_iter csset_X_erase_at(csset_X* self, csset_X_iter it); // return iter after it
csset_X_iter csset_X_erase_range(csset_X* self, csset_X_iter it1, csset_X_iter it2); // return updated it2
diff --git a/docs/cstack_api.md b/docs/cstack_api.md
index e8423385..b1371f4e 100644
--- a/docs/cstack_api.md
+++ b/docs/cstack_api.md
@@ -26,24 +26,24 @@ See the c++ class [std::stack](https://en.cppreference.com/w/cpp/container/stack
```c
cstack_X cstack_X_init(void);
-cstack_X cstack_X_with_capacity(size_t cap);
-cstack_X cstack_X_with_size(size_t size, i_val fill);
+cstack_X cstack_X_with_capacity(intptr_t cap);
+cstack_X cstack_X_with_size(intptr_t size, i_val fill);
cstack_X cstack_X_clone(cstack_X st);
void cstack_X_clear(cstack_X* self);
-bool cstack_X_reserve(cstack_X* self, size_t n);
+bool cstack_X_reserve(cstack_X* self, intptr_t n);
void cstack_X_shrink_to_fit(cstack_X* self);
-i_val* cstack_X_append_uninit(cstack_X* self, size_t n);
+i_val* cstack_X_append_uninit(cstack_X* self, intptr_t n);
void cstack_X_copy(cstack_X* self, const cstack_X* other);
void cstack_X_drop(cstack_X* self); // destructor
-size_t cstack_X_size(const cstack_X* self);
-size_t cstack_X_capacity(const cstack_X* self);
+intptr_t cstack_X_size(const cstack_X* self);
+intptr_t cstack_X_capacity(const cstack_X* self);
bool cstack_X_empty(const cstack_X* self);
i_val* cstack_X_top(const cstack_X* self);
-const i_val* cstack_X_at(const cstack_X* self, size_t idx);
-i_val* cstack_X_at_mut(cstack_X* self, size_t idx);
+const i_val* cstack_X_at(const cstack_X* self, intptr_t idx);
+i_val* cstack_X_at_mut(cstack_X* self, intptr_t idx);
i_val* cstack_X_push(cstack_X* self, i_val value);
i_val* cstack_X_emplace(cstack_X* self, i_valraw raw);
diff --git a/docs/cstr_api.md b/docs/cstr_api.md
index 4f895549..37316d4d 100644
--- a/docs/cstr_api.md
+++ b/docs/cstr_api.md
@@ -18,118 +18,117 @@ All cstr definitions and prototypes are available by including a single header f
## Methods
```c
-cstr cstr_init(void); // constructor; same as cstr_NULL.
-cstr cstr_lit(const char literal_only[]); // cstr from literal; no strlen() call.
-cstr cstr_from(const char* str); // constructor using strlen()
-cstr cstr_from_n(const char* str, size_t n); // constructor with n first bytes of str
-cstr cstr_from_sv(csview sv); // construct cstr from csview
-cstr cstr_with_capacity(size_t cap);
-cstr cstr_with_size(size_t len, char fill); // repeat fill len times
-cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting
-cstr cstr_clone(cstr s);
-
-cstr* cstr_take(cstr* self, cstr s); // take ownership of s, i.e. don't drop s.
-cstr cstr_move(cstr* self); // move string to caller, leave self empty
-void cstr_drop(cstr* self); // destructor
-
-const char* cstr_str(const cstr* self); // cast to const char*
-char* cstr_data(cstr* self); // cast to mutable char*
-csview cstr_sv(const cstr* self); // cast to string view
-cstr_buf cstr_buffer(cstr* self); // cast to mutable buffer (with capacity)
-
-size_t cstr_size(const cstr* self);
-size_t cstr_capacity(const cstr* self);
-bool cstr_empty(const cstr* self);
-
-char* cstr_reserve(cstr* self, size_t capacity); // return pointer to buffer
-void cstr_resize(cstr* self, size_t len, char fill);
-void cstr_shrink_to_fit(cstr* self);
-void cstr_clear(cstr* self);
-
-char* cstr_assign(cstr* self, const char* str);
-char* cstr_assign_n(cstr* self, const char* str, size_t n); // assign n first bytes of str
-char* cstr_assign_sv(cstr* self, csview sv);
-char* cstr_copy(cstr* self, cstr s); // copy-assign a cstr
-int cstr_printf(cstr* self, const char* fmt, ...); // source and target must not overlap.
-
-char* cstr_append(cstr* self, const char* str);
-char* cstr_append_n(cstr* self, const char* str, size_t n); // append n first bytes of str
-char* cstr_append_sv(cstr* self, csview str);
-char* cstr_append_s(cstr* self, cstr str);
-int cstr_append_fmt(cstr* self, const char* fmt, ...); // printf() formatting
-char* cstr_append_uninit(cstr* self, size_t len); // return ptr to start of uninited data
-
-void cstr_push(cstr* self, const char* chr); // append one utf8 char
-void cstr_pop(cstr* self); // pop one utf8 char
-
-void cstr_insert(cstr* self, size_t pos, const char* ins);
-void cstr_insert_sv(cstr* self, size_t pos, csview ins);
-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);
-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);
-void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl);
-
-bool cstr_equals(const cstr* self, const char* str);
-bool cstr_equals_sv(const cstr* self, csview sv);
-bool cstr_equals_s(const cstr* self, cstr s);
-
-size_t cstr_find(const cstr* self, const char* search);
-size_t cstr_find_at(const cstr* self, size_t pos, const char* search); // search from pos
-bool cstr_contains(const cstr* self, const char* search);
-
-bool cstr_starts_with(const cstr* self, const char* str);
-bool cstr_starts_with_sv(const cstr* self, csview sv);
-bool cstr_starts_with_s(const cstr* self, cstr s);
-
-bool cstr_ends_with(const cstr* self, const char* str);
-bool cstr_ends_with_sv(const cstr* self, csview sv);
-bool cstr_ends_with_s(const cstr* self, cstr s);
-
-bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream)
-bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does not append delim to result
+cstr cstr_init(void); // constructor; same as cstr_NULL.
+cstr cstr_lit(const char literal_only[]); // cstr from literal; no strlen() call.
+cstr cstr_from(const char* str); // constructor using strlen()
+cstr cstr_from_n(const char* str, intptr_t n); // constructor with n first bytes of str
+cstr cstr_from_sv(csview sv); // construct cstr from csview
+cstr cstr_with_capacity(intptr_t cap);
+cstr cstr_with_size(intptr_t len, char fill); // repeat fill len times
+cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting
+cstr cstr_clone(cstr s);
+
+cstr* cstr_take(cstr* self, cstr s); // take ownership of s, i.e. don't drop s.
+cstr cstr_move(cstr* self); // move string to caller, leave self empty
+void cstr_drop(cstr* self); // destructor
+
+const char* cstr_str(const cstr* self); // cast to const char*
+char* cstr_data(cstr* self); // cast to mutable char*
+csview cstr_sv(const cstr* self); // cast to string view
+cstr_buf cstr_buffer(cstr* self); // cast to mutable buffer (with capacity)
+
+intptr_t cstr_size(const cstr* self);
+intptr_t cstr_capacity(const cstr* self);
+bool cstr_empty(const cstr* self);
+
+char* cstr_reserve(cstr* self, intptr_t capacity); // return pointer to buffer
+void cstr_resize(cstr* self, intptr_t len, char fill);
+void cstr_shrink_to_fit(cstr* self);
+void cstr_clear(cstr* self);
+
+char* cstr_assign(cstr* self, const char* str);
+char* cstr_assign_n(cstr* self, const char* str, intptr_t n); // assign n first bytes of str
+char* cstr_assign_sv(cstr* self, csview sv);
+char* cstr_copy(cstr* self, cstr s); // copy-assign a cstr
+int cstr_printf(cstr* self, const char* fmt, ...); // source and target must not overlap.
+
+char* cstr_append(cstr* self, const char* str);
+char* cstr_append_n(cstr* self, const char* str, intptr_t n); // append n first bytes of str
+char* cstr_append_sv(cstr* self, csview str);
+char* cstr_append_s(cstr* self, cstr str);
+int cstr_append_fmt(cstr* self, const char* fmt, ...); // printf() formatting
+char* cstr_append_uninit(cstr* self, intptr_t len); // return ptr to start of uninited data
+
+void cstr_push(cstr* self, const char* chr); // append one utf8 char
+void cstr_pop(cstr* self); // pop one utf8 char
+
+void cstr_insert(cstr* self, intptr_t pos, const char* ins);
+void cstr_insert_sv(cstr* self, intptr_t pos, csview ins);
+void cstr_insert_s(cstr* self, intptr_t pos, cstr ins);
+
+void cstr_erase(cstr* self, intptr_t pos, intptr_t len); // erase len bytes from pos
+
+void cstr_replace(cstr* self, const char* search, const char* repl, unsigned count = MAX_INT);
+cstr cstr_replace_sv(csview in, csview search, csview repl, unsigned count);
+void cstr_replace_at(cstr* self, intptr_t pos, intptr_t len, const char* repl); // replace at a pos
+void cstr_replace_at_sv(cstr* self, intptr_t pos, intptr_t len, const csview repl);
+void cstr_replace_at_s(cstr* self, intptr_t pos, intptr_t len, cstr repl);
+
+bool cstr_equals(const cstr* self, const char* str);
+bool cstr_equals_sv(const cstr* self, csview sv);
+bool cstr_equals_s(const cstr* self, cstr s);
+
+intptr_t cstr_find(const cstr* self, const char* search);
+intptr_t cstr_find_at(const cstr* self, intptr_t pos, const char* search); // search from pos
+bool cstr_contains(const cstr* self, const char* search);
+
+bool cstr_starts_with(const cstr* self, const char* str);
+bool cstr_starts_with_sv(const cstr* self, csview sv);
+bool cstr_starts_with_s(const cstr* self, cstr s);
+
+bool cstr_ends_with(const cstr* self, const char* str);
+bool cstr_ends_with_sv(const cstr* self, csview sv);
+bool cstr_ends_with_s(const cstr* self, cstr s);
+
+bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream)
+bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does not append delim to result
```
#### UTF8 methods
```c
-size_t cstr_u8_size(const cstr* self); // number of utf8 codepoints
-size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 size within n bytes
-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_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
+intptr_t cstr_u8_size(const cstr* self); // number of utf8 codepoints
+intptr_t cstr_u8_size_n(const cstr self, intptr_t nbytes); // utf8 size within n bytes
+intptr_t cstr_u8_to_pos(const cstr* self, intptr_t u8idx); // byte pos offset at utf8 codepoint index
+const char* cstr_u8_at(const cstr* self, intptr_t u8idx); // char* position at utf8 codepoint index
+csview cstr_u8_chr(const cstr* self, intptr_t u8idx); // get utf8 character as a csview
+void cstr_u8_replace_at(cstr* self, intptr_t bytepos, intptr_t u8len, csview repl); // replace u8len utf8 chars
+void cstr_u8_erase(cstr* self, intptr_t bytepos, intptr_t u8len); // erase u8len codepoints from pos
// iterate utf8 codepoints
-cstr_iter cstr_begin(const cstr* self);
-cstr_iter cstr_end(const cstr* self);
-void cstr_next(cstr_iter* it);
-cstr_iter cstr_advance(cstr_iter it, intptr_t n);
+cstr_iter cstr_begin(const cstr* self);
+cstr_iter cstr_end(const cstr* self);
+void cstr_next(cstr_iter* it);
+cstr_iter cstr_advance(cstr_iter it, intptr_t n);
// utf8 functions requires linking with src/utf8code.c symbols:
-bool cstr_valid_utf8(const cstr* self); // check if str is valid utf8
-cstr cstr_casefold_sv(csview sv); // returns new casefolded utf8 cstr
-
-cstr cstr_tolower(const char* str); // returns new lowercase utf8 cstr
-cstr cstr_tolower_sv(csview sv); // returns new lowercase utf8 cstr
-void cstr_lowercase(cstr* self); // transform cstr to lowercase utf8
-
-cstr cstr_toupper(const char* str); // returns new uppercase utf8 cstr
-cstr cstr_toupper_sv(csview sv); // returns new uppercase utf8 cstr
-void cstr_uppercase(cstr* self); // transform cstr to uppercase utf8
-
-int cstr_icmp(const cstr* s1, const cstr* s2); // utf8 case-insensitive comparison
-bool cstr_iequals(const cstr* self, const char* str); // "
-bool cstr_istarts_with(const cstr* self, const char* str); // "
-bool cstr_iends_with(const cstr* self, const char* str); // "
+bool cstr_valid_utf8(const cstr* self); // check if str is valid utf8
+cstr cstr_casefold_sv(csview sv); // returns new casefolded utf8 cstr
+
+cstr cstr_tolower(const char* str); // returns new lowercase utf8 cstr
+cstr cstr_tolower_sv(csview sv); // returns new lowercase utf8 cstr
+void cstr_lowercase(cstr* self); // transform cstr to lowercase utf8
+
+cstr cstr_toupper(const char* str); // returns new uppercase utf8 cstr
+cstr cstr_toupper_sv(csview sv); // returns new uppercase utf8 cstr
+void cstr_uppercase(cstr* self); // transform cstr to uppercase utf8
+
+int cstr_icmp(const cstr* s1, const cstr* s2); // utf8 case-insensitive comparison
+bool cstr_iequals(const cstr* self, const char* str); // "
+bool cstr_istarts_with(const cstr* self, const char* str); // "
+bool cstr_iends_with(const cstr* self, const char* str); // "
```
-Note that all methods with arguments `(..., const char* str, size_t n)`, `n` must be within the range of `str` length.
+Note that all methods with arguments `(..., const char* str, intptr_t n)`, `n` must be within the range of `str` length.
#### Helper methods:
```c
@@ -137,17 +136,17 @@ int cstr_cmp(const cstr* s1, const cstr* s2);
bool cstr_eq(const cstr* s1, const cstr* s2);
bool cstr_hash(const cstr* self);
-char* cstrnstrn(const char* str, const char* search, size_t slen, size_t nlen);
+char* cstrnstrn(const char* str, const char* search, intptr_t slen, intptr_t nlen);
```
## Types
-| Type name | Type definition | Used to represent... |
-|:----------------|:-------------------------------------------|:---------------------|
-| `cstr` | `struct { ... }` | The string type |
-| `cstr_value` | `char` | String element type |
-| `csview` | `struct { const char *str; size_t size; }` | String view type |
-| `cstr_buf` | `struct { char *data; size_t size, cap; }` | String buffer type |
+| Type name | Type definition | Used to represent... |
+|:----------------|:---------------------------------------------|:---------------------|
+| `cstr` | `struct { ... }` | The string type |
+| `cstr_value` | `char` | String element type |
+| `csview` | `struct { const char *str; intptr_t size; }` | String view type |
+| `cstr_buf` | `struct { char *data; intptr_t size, cap; }` | String buffer type |
## Constants and macros
@@ -163,7 +162,7 @@ char* cstrnstrn(const char* str, const char* search, size_t slen, size_t
int main() {
c_AUTO (cstr, s0, s1, full_path) {
s0 = cstr_lit("Initialization without using strlen().");
- printf("%s\nLength: %" c_ZU "\n\n", cstr_str(&s0), cstr_size(&s0));
+ printf("%s\nLength: %" c_ZI "\n\n", cstr_str(&s0), cstr_size(&s0));
s1 = cstr_lit("one-nine-three-seven-five.");
printf("%s\n", cstr_str(&s1));
@@ -174,7 +173,7 @@ int main() {
cstr_erase(&s1, 7, 5); // -nine
printf("%s\n", cstr_str(&s1));
- cstr_replace_ex(&s1, "seven", "four", 1);
+ cstr_replace(&s1, "seven", "four", 1);
printf("%s\n", cstr_str(&s1));
// reassign:
diff --git a/docs/csview_api.md b/docs/csview_api.md
index b5508ace..3971c6a6 100644
--- a/docs/csview_api.md
+++ b/docs/csview_api.md
@@ -26,61 +26,61 @@ 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, size_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, size_t n); // alias for c_SV(str, n)
+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)
-size_t csview_size(csview sv);
+intptr_t csview_size(csview sv);
bool csview_empty(csview sv);
void csview_clear(csview* self);
bool csview_equals(csview sv, csview sv2);
-size_t csview_find(csview sv, const char* str);
-size_t csview_find_sv(csview sv, csview find);
+intptr_t csview_find(csview sv, const char* str);
+intptr_t csview_find_sv(csview sv, csview find);
bool csview_contains(csview sv, const char* str);
bool csview_starts_with(csview sv, const char* str);
bool csview_ends_with(csview sv, const char* str);
-csview csview_substr_ex(csview sv, intptr_t pos, size_t n); // negative pos count from end
-csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2); // negative p1, p2 count from end
-csview csview_token(csview sv, const char* sep, size_t* start); // *start > sv.size after last token
+csview csview_substr_ex(csview sv, intptr_t pos, intptr_t n); // negative pos count from end
+csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2); // negative p1, p2 count from end
+csview csview_token(csview sv, const char* sep, intptr_t* start); // *start > sv.size after last token
```
#### UTF8 methods
```c
-size_t csview_u8_size(csview sv);
-csview csview_u8_substr(csview sv, size_t bytepos, size_t u8len);
-bool csview_valid_utf8(csview sv); // requires linking with src/utf8code.c
+intptr_t csview_u8_size(csview sv);
+csview csview_u8_substr(csview sv, intptr_t bytepos, intptr_t u8len);
+bool csview_valid_utf8(csview sv); // requires linking with src/utf8code.c
csview_iter csview_begin(const csview* self);
csview_iter csview_end(const csview* self);
-void csview_next(csview_iter* it); // utf8 codepoint step, not byte!
+void csview_next(csview_iter* it); // utf8 codepoint step, not byte!
csview_iter csview_advance(csview_iter it, intptr_t n);
-// from utf8.h
-size_t utf8_size(const char *s);
-size_t utf8_size_n(const char *s, size_t nbytes); // number of UTF8 codepoints within n bytes
-const char* utf8_at(const char *s, size_t index); // from UTF8 index to char* position
-size_t utf8_pos(const char* s, size_t index); // from UTF8 index to byte index position
-unsigned utf8_chr_size(const char* s); // UTF8 character size: 1-4
-// implemented in src/utf8code.c:
+ // from utf8.h
+intptr_t utf8_size(const char *s);
+intptr_t utf8_size_n(const char *s, intptr_t nbytes); // number of UTF8 codepoints within n bytes
+const char* utf8_at(const char *s, intptr_t index); // from UTF8 index to char* position
+intptr_t utf8_pos(const char* s, intptr_t index); // from UTF8 index to byte index position
+unsigned utf8_chr_size(const char* s); // UTF8 character size: 1-4
+ // implemented in src/utf8code.c:
bool utf8_valid(const char* s);
-bool utf8_valid_n(const char* s, size_t nbytes);
-uint32_t utf8_decode(utf8_decode_t *d, uint8_t byte); // decode next byte to utf8, return state.
-unsigned utf8_encode(char *out, uint32_t codepoint); // encode unicode cp into out buffer
-uint32_t utf8_peek(const char* s); // codepoint value of character at s
-uint32_t utf8_peek_off(const char* s, int offset); // codepoint value at utf8 pos (may be negative)
+bool utf8_valid_n(const char* s, intptr_t nbytes);
+uint32_t utf8_decode(utf8_decode_t *d, uint8_t byte); // decode next byte to utf8, return state.
+unsigned utf8_encode(char *out, uint32_t codepoint); // encode unicode cp into out buffer
+uint32_t utf8_peek(const char* s); // codepoint value of character at s
+uint32_t utf8_peek_off(const char* s, int offset); // codepoint value at utf8 pos (may be negative)
```
#### Extended cstr methods
```c
-csview cstr_substr(const cstr* self, size_t pos, size_t n);
-csview cstr_substr_ex(const cstr* s, intptr_t pos, size_t n); // negative pos count from end
-csview cstr_u8_substr(const cstr* self, size_t bytepos, size_t u8len);
+csview cstr_substr(const cstr* self, intptr_t pos, intptr_t n);
+csview cstr_substr_ex(const cstr* s, intptr_t pos, intptr_t n); // negative pos count from end
+csview cstr_u8_substr(const cstr* self, intptr_t bytepos, intptr_t u8len);
-csview cstr_slice(const cstr* self, size_t p1, size_t p2);
+csview cstr_slice(const cstr* self, intptr_t p1, intptr_t p2);
csview cstr_slice_ex(const cstr* s, intptr_t p, intptr_t q); // negative p or q count from end
```
#### Iterate tokens with *c_FORTOKEN*, *c_FORTOKEN_SV*
@@ -103,7 +103,7 @@ uint64_t csview_hash(const csview* x);
| Type name | Type definition | Used to represent... |
|:----------------|:-------------------------------------------|:-------------------------|
-| `csview` | `struct { const char *str; size_t size; }` | The string view type |
+| `csview` | `struct { const char *str; intptr_t size; }` | The string view type |
| `csview_value` | `char` | The string element type |
| `csview_iter` | `struct { csview_value *ref; }` | UTF8 iterator |
@@ -125,7 +125,7 @@ int main ()
// (quoting Alfred N. Whitehead)
csview sv1 = cstr_substr(&str1, 3, 5); // "think"
- size_t pos = cstr_find(&str1, "live"); // position of "live" in str1
+ intptr_t pos = cstr_find(&str1, "live"); // position of "live" in str1
csview sv2 = cstr_substr(&str1, pos, 4); // get "live"
csview sv3 = cstr_slice(&str1, -8, -1); // get "details"
printf("%.*s %.*s %.*s\n",
@@ -135,7 +135,7 @@ int main ()
cstr s3 = cstr_from_sv(cstr_substr(&s1, 0, 6)); // "Apples"
printf("%s %s\n", cstr_str(&s2), cstr_str(&s3));
- c_DROP(cstr, &str1, &s1, &s2, &s3);
+ c_drop(cstr, &str1, &s1, &s2, &s3);
}
```
Output:
diff --git a/docs/cvec_api.md b/docs/cvec_api.md
index 92629c8b..057caa7c 100644
--- a/docs/cvec_api.md
+++ b/docs/cvec_api.md
@@ -31,32 +31,32 @@ See the c++ class [std::vector](https://en.cppreference.com/w/cpp/container/vect
```c
cvec_X cvec_X_init(void);
-cvec_X cvec_X_with_size(size_t size, i_val null);
-cvec_X cvec_X_with_capacity(size_t size);
+cvec_X cvec_X_with_size(intptr_t size, i_val null);
+cvec_X cvec_X_with_capacity(intptr_t size);
cvec_X cvec_X_clone(cvec_X vec);
void cvec_X_clear(cvec_X* self);
void cvec_X_copy(cvec_X* self, const cvec_X* other);
cvec_X_iter cvec_X_copy_range(cvec_X* self, i_val* pos, const i_val* p1, const i_val* p2);
-bool cvec_X_reserve(cvec_X* self, size_t cap);
-bool cvec_X_resize(cvec_X* self, size_t size, i_val null);
-cvec_X_iter cvec_X_insert_uninit(cvec_X* self, i_val* pos, size_t n); // return pos iter
+bool cvec_X_reserve(cvec_X* self, intptr_t cap);
+bool cvec_X_resize(cvec_X* self, intptr_t size, i_val null);
+cvec_X_iter cvec_X_insert_uninit(cvec_X* self, i_val* pos, intptr_t n); // return pos iter
void cvec_X_shrink_to_fit(cvec_X* self);
-void cvec_X_drop(cvec_X* self); // destructor
+void cvec_X_drop(cvec_X* self); // destructor
bool cvec_X_empty(const cvec_X* self);
-size_t cvec_X_size(const cvec_X* self);
-size_t cvec_X_capacity(const cvec_X* self);
+intptr_t cvec_X_size(const cvec_X* self);
+intptr_t cvec_X_capacity(const cvec_X* self);
-const cvec_X_value* cvec_X_at(const cvec_X* self, size_t idx);
-const cvec_X_value* cvec_X_get(const cvec_X* self, i_valraw raw); // return NULL if not found
-cvec_X_value* cvec_X_at_mut(cvec_X* self, size_t idx);
-cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // find mutable value, return value ptr
+const cvec_X_value* cvec_X_at(const cvec_X* self, intptr_t idx);
+const cvec_X_value* cvec_X_get(const cvec_X* self, i_valraw raw); // return NULL if not found
+cvec_X_value* cvec_X_at_mut(cvec_X* self, intptr_t idx);
+cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // find mutable value, return value ptr
cvec_X_iter cvec_X_find(const cvec_X* self, i_valraw raw);
-cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); // return cvec_X_end() if not found
+cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); // return cvec_X_end() if not found
// On sorted vectors:
-cvec_X_iter cvec_X_binary_search(const cvec_X* self, i_valraw raw); // at elem == raw, else end
-cvec_X_iter cvec_X_lower_bound(const cvec_X* self, i_valraw raw); // at first elem >= raw, else end
+cvec_X_iter cvec_X_binary_search(const cvec_X* self, i_valraw raw); // at elem == raw, else end
+cvec_X_iter cvec_X_lower_bound(const cvec_X* self, i_valraw raw); // at first elem >= raw, else end
cvec_X_iter cvec_X_binary_search_in(cvec_X_iter i1, cvec_X_iter i2,
i_valraw raw, cvec_X_iter* lower_bound);
@@ -65,24 +65,24 @@ cvec_X_value* cvec_X_back(const cvec_X* self);
cvec_X_value* cvec_X_push(cvec_X* self, i_val value);
cvec_X_value* cvec_X_emplace(cvec_X* self, i_valraw raw);
-cvec_X_value* cvec_X_push_back(cvec_X* self, i_val value); // alias for push
-cvec_X_value* cvec_X_emplace_back(cvec_X* self, i_valraw raw); // alias for emplace
+cvec_X_value* cvec_X_push_back(cvec_X* self, i_val value); // alias for push
+cvec_X_value* cvec_X_emplace_back(cvec_X* self, i_valraw raw); // alias for emplace
void cvec_X_pop(cvec_X* self);
-void cvec_X_pop_back(cvec_X* self); // alias for pop
+void cvec_X_pop_back(cvec_X* self); // alias for pop
-cvec_X_iter cvec_X_insert(cvec_X* self, size_t idx, i_val value); // move value
-cvec_X_iter cvec_X_insert_n(cvec_X* self, size_t idx, const i_val[] arr, size_t n); // move n values
-cvec_X_iter cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value
+cvec_X_iter cvec_X_insert(cvec_X* self, intptr_t idx, i_val value); // move value
+cvec_X_iter cvec_X_insert_n(cvec_X* self, intptr_t idx, const i_val[] arr, intptr_t n); // move n values
+cvec_X_iter cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value
cvec_X_iter cvec_X_insert_range(cvec_X* self, i_val* pos,
const i_val* p1, const i_val* p2);
-cvec_X_iter cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); // clone values
+cvec_X_iter cvec_X_emplace_n(cvec_X* self, intptr_t idx, const i_valraw[] arr, intptr_t n); // clone values
cvec_X_iter cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw);
cvec_X_iter cvec_X_emplace_range(cvec_X* self, i_val* pos,
const i_valraw* p1, const i_valraw* p2);
-cvec_X_iter cvec_X_erase_n(cvec_X* self, size_t idx, size_t n);
+cvec_X_iter cvec_X_erase_n(cvec_X* self, intptr_t idx, intptr_t n);
cvec_X_iter cvec_X_erase_at(cvec_X* self, cvec_X_iter it);
cvec_X_iter cvec_X_erase_range(cvec_X* self, cvec_X_iter it1, cvec_X_iter it2);
cvec_X_iter cvec_X_erase_range_p(cvec_X* self, i_val* p1, i_val* p2);
@@ -94,7 +94,7 @@ void cvec_X_sort_range(cvec_X_iter i1, cvec_X_iter i2,
cvec_X_iter cvec_X_begin(const cvec_X* self);
cvec_X_iter cvec_X_end(const cvec_X* self);
void cvec_X_next(cvec_X_iter* iter);
-cvec_X_iter cvec_X_advance(cvec_X_iter it, intptr_t n);
+cvec_X_iter cvec_X_advance(cvec_X_iter it, size_t n);
cvec_X_raw cvec_X_value_toraw(cvec_X_value* pval);
cvec_X_value cvec_X_value_clone(cvec_X_value val);
@@ -222,6 +222,6 @@ int main(void) {
c_FOREACH (i, UVec, vec2)
printf("%s: %d\n", cstr_str(&i.ref->name), i.ref->id);
- c_DROP(UVec, &vec, &vec2); // cleanup
+ c_drop(UVec, &vec, &vec2); // cleanup
}
``` \ No newline at end of file