diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/carc_api.md | 32 | ||||
| -rw-r--r-- | docs/carray_api.md | 6 | ||||
| -rw-r--r-- | docs/cbox_api.md | 29 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 68 | ||||
| -rw-r--r-- | docs/cdeq_api.md | 24 | ||||
| -rw-r--r-- | docs/cmap_api.md | 4 | ||||
| -rw-r--r-- | docs/csmap_api.md | 4 | ||||
| -rw-r--r-- | docs/cstr_api.md | 56 | ||||
| -rw-r--r-- | docs/csview_api.md | 18 | ||||
| -rw-r--r-- | docs/cvec_api.md | 28 |
10 files changed, 143 insertions, 126 deletions
diff --git a/docs/carc_api.md b/docs/carc_api.md index 687e9547..d09b1839 100644 --- a/docs/carc_api.md +++ b/docs/carc_api.md @@ -32,25 +32,31 @@ See similar c++ class [std::shared_ptr](https://en.cppreference.com/w/cpp/memory ## Methods ```c carc_X carc_X_init(); // empty shared pointer -carc_X carc_X_from(i_valraw raw); // construct a new value in an carc from raw type. -carc_X carc_X_make(i_val val); // make a carc from constructed val object. Faster than from_ptr(). -carc_X carc_X_from_ptr(i_val* p); // create a carc from raw pointer. Takes ownership of p. +carc_X carc_X_new(i_valraw raw); // create an carc from raw type (available if i_valraw defined by user). +carc_X carc_X_from(i_val val); // create an carc from constructed val object. Faster than from_ptr(). +carc_X carc_X_from_ptr(i_val* p); // create an carc from raw pointer. Takes ownership of p. carc_X carc_X_clone(carc_X other); // return other with increased use count carc_X carc_X_move(carc_X* self); // transfer ownership to another carc. void carc_X_take(carc_X* self, carc_X other); // take ownership of other. -void carc_X_assign(carc_X* self, carc_X other); // copy shared (increase use count) +void carc_X_copy(carc_X* self, carc_X other); // shared assign (increase use count) void carc_X_drop(carc_X* self); // destruct (decrease use count, free at 0) -long carc_X_use_count(carc_X ptr); +long carc_X_use_count(const carc_X* self); void carc_X_reset(carc_X* self); void carc_X_reset_to(carc_X* self, i_val* p); // assign new carc from ptr. Takes ownership of p. -uint64_t carc_X_value_hash(const i_val* x); // hash value -int carc_X_value_cmp(const i_val* x, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp' - // is defined. Otherwise uses 'i_cmp' or default compare. -bool carc_X_value_eq(const i_val* x, const i_val* y); // carc_X_value_cmp == 0 +uint64_t carc_X_hash(const carc_X* x); // hash value +int carc_X_cmp(const carc_X* x, const carc_X* y); // compares pointer addresses if 'i_opt c_no_cmp' + // is defined. Otherwise uses 'i_cmp' or default cmp. +bool carc_X_eq(const carc_X* x, const carc_X* y); // carc_X_cmp() == 0 + +// functions on pointed to objects. + +uint64_t carc_X_value_hash(const i_val* x); +int carc_X_value_cmp(const i_val* x, const i_val* y); +bool carc_X_value_eq(const i_val* x, const i_val* y); ``` ## Types and constants @@ -96,18 +102,18 @@ int main() // POPULATE s1 with shared pointers to Map: Map *map; - map = Stack_push(&s1, Arc_make(Map_init()))->get; // push empty map to s1. + map = Stack_push(&s1, Arc_from(Map_init()))->get; // push empty map to s1. c_forarray (Map_raw, v, { {"Joey", 1990}, {"Mary", 1995}, {"Joanna", 1992}}) { Map_emplace(map, v->first, v->second); // populate it. } - map = Stack_push(&s1, Arc_make(Map_init()))->get; + map = Stack_push(&s1, Arc_from(Map_init()))->get; c_forarray (Map_raw, v, { {"Rosanna", 2001}, {"Brad", 1999}, {"Jack", 1980} }) { Map_emplace(map, v->first, v->second); } // POPULATE s2: - map = Stack_push(&s2, Arc_make(Map_init()))->get; + map = Stack_push(&s2, Arc_from(Map_init()))->get; c_forarray (Map_raw, v, { {"Steve", 1979}, {"Rick", 1974}, {"Tracy", 2003} }) { Map_emplace(map, v->first, v->second); } @@ -118,7 +124,7 @@ int main() // Deep-copy (does not share) a Map from s1 to s2. // s2 will contain two shared and two unshared maps. - map = Stack_push(&s2, Arc_make(Map_clone(*s1.data[1].get)))->get; + map = Stack_push(&s2, Arc_from(Map_clone(*s1.data[1].get)))->get; // Add one more element to the cloned map: Map_emplace_or_assign(map, "Cloned", 2022); diff --git a/docs/carray_api.md b/docs/carray_api.md index 579bf119..cede295e 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -91,8 +91,8 @@ int main() // Ex1 int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. - c_autovar (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), - carr3_f_drop(&arr3)) { + c_with (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -105,7 +105,7 @@ int main() // Ex2 int w = 256, h = 128; - c_autovar (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { + c_with (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { int n = 0; c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; diff --git a/docs/cbox_api.md b/docs/cbox_api.md index 1119d930..dc90fa8e 100644 --- a/docs/cbox_api.md +++ b/docs/cbox_api.md @@ -31,24 +31,31 @@ compare the pointer addresses when used. Additionally, `c_no_clone` or `i_is_fwd ## Methods ```c cbox_X cbox_X_init(); // return an empty cbox -cbox_X cbox_X_from(i_valraw raw); // construct a new boxed object from raw type, if defined. -cbox_X cbox_X_make(i_val val); // make a cbox from constructed val object. +cbox_X cbox_X_new(i_valraw raw); // create a cbox from raw type. Avail if i_valraw user defined. +cbox_X cbox_X_from(i_val val); // create a cbox from constructed val object. cbox_X cbox_X_from_ptr(i_val* p); // create a cbox from a pointer. Takes ownership of p. cbox_X cbox_X_clone(cbox_X other); // return deep copied clone cbox_X cbox_X_move(cbox_X* self); // transfer ownership to another cbox. void cbox_X_take(cbox_X* self, cbox_X other); // take ownership of other. -void cbox_X_assign(cbox_X* self, cbox_X other); // deep copy to self +void cbox_X_copy(cbox_X* self, cbox_X other); // deep copy to self void cbox_X_drop(cbox_X* self); // destruct the contained object and free's it. 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_value_hash(const i_val* p); // hash value -int cbox_X_value_cmp(const i_val* p, const i_val* y); // compares pointer addresses if 'i_opt c_no_cmp' - // is defined. Otherwise uses 'i_cmp' or default compare. -bool cbox_X_value_eq(const i_val* p, const i_val* y); // cbox_X_value_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 'i_opt c_no_cmp' + // 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. + +uint64_t cbox_X_value_hash(const i_val* x); +int cbox_X_value_cmp(const i_val* x, const i_val* y); +bool cbox_X_value_eq(const i_val* x, const i_val* y); ``` + ## Types and constants | Type name | Type definition | Used to represent... | @@ -68,7 +75,7 @@ void int_drop(int* x) { #define i_type IBox #define i_val int #define i_valdrop int_drop // optional func, just to display elements destroyed -#define i_valclone(x) x // must specify because i_valdrop was defined. +#define i_valclone(x) x // must specified when i_valdrop is defined. #include <stc/cbox.h> #define i_type ISet @@ -84,10 +91,8 @@ int main() c_auto (IVec, vec) // declare and init vec, call drop at scope exit c_auto (ISet, set) // similar { - c_forarray (IBox, v, { - IBox_make(2021), IBox_make(2012), - IBox_make(2022), IBox_make(2015), - }) IVec_push(&vec, *v); + c_forarray (int, v, {2021, 2012, 2022, 2015}) + IVec_emplace(&vec, *v); // same as: IVec_push(&vec, IBox_from(*v)); printf("vec:"); c_foreach (i, IVec, vec) diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index b4a90036..d37d4d04 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -2,38 +2,41 @@ The following macros are recommended to use, and they safe/have no side-effects. -### c_auto, c_autovar, c_autoscope, c_autodefer +### c_auto, c_with, c_scope, c_defer General ***defer*** mechanics for resource acquisition. These macros allows you to specify the freeing of the resources at the point where the acquisition takes place. The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. -| Usage | Description | -|:---------------------------------------|:-----------------------------------------------------| -| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_drop(&var))` | -| `c_autovar (Type var=init, end...)` | Declare `var`. Defer `end...` to end of block | -| `c_autoscope (init, end...)` | Execute `init`. Defer `end...` to end of block | -| `c_autodefer (end...)` | Defer `end...` to end of block | -| `c_breakauto` or `continue` | Break out of a `c_auto*`-block/scope without memleak | - -For multiple variables, use either multiple **c_autovar** in sequence, or declare variable outside -scope and use **c_autoscope**. Also, **c_auto** support up to 4 variables. +| Usage | Description | +|:---------------------------------------|:----------------------------------------------------------| +| `c_auto (Type, var...)` | Same as `c_with (Type var=Type_init(), Type_drop(&var))` | +| `c_with (Type var=init, drop)` | Declare `var`. Defer `drop...` to end of scope | +| `c_with (Type var=init, pred, drop)` | Adds a predicate in order to exit early if init failed | +| `c_scope (init, drop...)` | Execute `init` and defer `drop...` to end of scope | +| `c_defer (drop...)` | Defer `drop...` to end of scope | +| `continue` | Exit a `c_auto/c_with/c_scope...` without memory leaks | + +For multiple variables, use either multiple **c_with** in sequence, or declare variable outside +scope and use **c_scope**. For convenience, **c_auto** support up to 4 variables. ```c -c_autovar (uint8_t* buf = malloc(BUF_SIZE), free(buf)) -c_autovar (FILE* f = fopen(fname, "rb"), fclose(f)) +// `c_with` is similar to python `with`: it declares and can drop a variable after going out of scope. +c_with (uint8_t* buf = malloc(BUF_SIZE), free(buf)) +c_with (FILE* fp = fopen(fname, "rb"), fclose(fp)) { int n = 0; - if (f && buf) { - n = fread(buf, 1, BUF_SIZE, f); + if (fp && buf) { + n = fread(buf, 1, BUF_SIZE, fp); doSomething(buf, n); } } -c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) +c_with (cstr str = cstr_new("Hello"), cstr_drop(&str)) { - cstr_append(&s, " world"); - printf("%s\n", cstr_str(&s)); + cstr_append(&str, " world"); + printf("%s\n", cstr_str(&str)); } +// `c_auto` automatically initialize and destruct up to 4 variables, like `c_with`. c_auto (cstr, s1, s2) { cstr_append(&s1, "Hello"); @@ -45,14 +48,16 @@ c_auto (cstr, s1, s2) printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } -MyData data; -c_autoscope (mydata_init(&data), mydata_destroy(&data)) +// `c_scope` is like `c_with` but works with an already declared variable. +static pthread_mutex_t mut; +c_scope (pthread_mutex_lock(&mut), pthread_mutex_unlock(&mut)) { - printf("%s\n", cstr_str(&mydata.name)); + /* Do syncronized work. */ } +// `c_defer` executes the expressions when leaving scope. cstr s1 = cstr_new("Hello"), s2 = cstr_new("world"); -c_autodefer (cstr_drop(&s1), cstr_drop(&s2)) +c_defer (cstr_drop(&s1), cstr_drop(&s2)) { printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } @@ -70,16 +75,16 @@ cvec_str readFile(const char* name) { cvec_str vec = cvec_str_init(); // returned - c_autovar (FILE* fp = fopen(name, "r"), fclose(fp)) - c_autovar (cstr line = cstr_null, cstr_drop(&line)) - while (cstr_getline(&line, fp)) - cvec_str_emplace_back(&vec, cstr_str(&line)); + c_with (FILE* fp = fopen(name, "r"), fclose(fp)) + c_with (cstr line = cstr_null, cstr_drop(&line)) + while (cstr_getline(&line, fp)) + cvec_str_emplace_back(&vec, cstr_str(&line)); return vec; } int main() { - c_autovar (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) + c_with (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) c_foreach (i, cvec_str, x) printf("%s\n", cstr_str(i.ref)); } @@ -209,16 +214,15 @@ c_forrange (int, i, 30, 0, -5) printf(" %d", i); ### c_find_if, c_find_in Search linearily in containers using a predicate ``` -// NOTE: it.ref is NULL if not found, not cvec_i_end(&vec).ref -// This makes it easier to test. -cvec_i_iter it; +cvec_i_iter it, it1, it2; // Search vec for first value > 2: -c_find_if(cvec_i, vec, it, *it.ref > 2); +// NOTE: it.ref is NULL if not found +c_find_if(it, cvec_i, vec, *it.ref > 2); if (it.ref) printf("%d\n", *it.ref); // Search within a range: -c_find_in(csmap_str, it1, it2, it, cstr_contains(*it.ref, "hello")); +c_find_in(it, csmap_str, it1, it2, cstr_contains(it.ref, "hello")); if (it.ref) cmap_str_erase_at(&map, it); ``` diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 6826946c..6a47313d 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -29,6 +29,7 @@ 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); void cdeq_X_shrink_to_fit(cdeq_X* self); void cdeq_X_swap(cdeq_X* a, cdeq_X* b); @@ -42,7 +43,7 @@ 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 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); +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); @@ -57,22 +58,21 @@ 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() void cdeq_X_pop_back(cdeq_X* self); -cdeq_X_value* cdeq_X_insert(cdeq_X* self, size_t idx, i_val value); // move value -cdeq_X_value* cdeq_X_insert_n(cdeq_X* self, size_t idx, const i_val[] arr, size_t n); // move arr values -cdeq_X_value* cdeq_X_insert_at(cdeq_X* self, cdeq_X_iter it, i_val value); // move value -cdeq_X_value* cdeq_X_insert_range_p(cdeq_X* self, i_val* pos, - const i_val* p1, const i_val* p2); +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_range(cdeq_X* self, i_val* pos, + const i_val* p1, const i_val* p2); -cdeq_X_value* cdeq_X_emplace_n(cdeq_X* self, size_t idx, const i_valraw[] arr, size_t n); -cdeq_X_value* cdeq_X_emplace_at(cdeq_X* self, cdeq_X_iter it, i_valraw raw); -cdeq_X_value* cdeq_X_emplace_range(cdeq_X* self, cdeq_X_iter it, // will clone - cdeq_X_iter it1, cdeq_X_iter it2); -cdeq_X_value* cdeq_X_emplace_range_p(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_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_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); void cdeq_X_sort(cdeq_X* self); void cdeq_X_sort_range(cdeq_X_iter i1, cdeq_X_iter i2, diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 91c36def..792d6c8c 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -211,7 +211,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) + c_with (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) { cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); @@ -244,7 +244,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop(). + c_auto (cmap_iv, vecs) // shorthand for c_with with _init(), _drop(). { cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 3a1a5aa6..91abaae3 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -157,7 +157,7 @@ int main() { uint32_t col = 0xcc7744ff; csmap_id idnames = csmap_id_init(); - c_autodefer (csmap_id_drop(&idnames)) + c_defer (csmap_id_drop(&idnames)) { c_forarray (csmap_id_raw, v, { {100, "Red"}, {110, "Blue"} }) csmap_id_emplace(&idnames, v->first, v->second); @@ -238,7 +238,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // equivalent to: c_auto (csmap_iv, vecs) - c_autovar (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) + c_with (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) { csmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); csmap_iv_insert(&vecs, 2, (Vec3i){0, 100, 0}); diff --git a/docs/cstr_api.md b/docs/cstr_api.md index fffec64c..d4e292cd 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -30,16 +30,16 @@ 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 +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(cstr s); -size_t cstr_capacity(cstr s); -bool cstr_empty(cstr s); +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); @@ -57,7 +57,7 @@ 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); -char* cstr_append_uninit(cstr *self, size_t len); // append len uninitialized bytes +char* cstr_append_uninit(cstr* self, size_t len); // append len uninitialized bytes void cstr_insert(cstr* self, size_t pos, const char* ins); void cstr_insert_sv(cstr* self, size_t pos, csview ins); @@ -72,19 +72,21 @@ void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* rep 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(cstr s, const char* str); -bool cstr_equals_s(cstr s, cstr s2); -size_t cstr_find(cstr s, const char* search); -size_t cstr_find_at(cstr s, size_t pos, const char* search); // search from pos -bool cstr_contains(cstr s, const char* search); +bool cstr_equals(const cstr* self, const char* str); +bool cstr_equals_s(const cstr* self, cstr s); +bool cstr_equals_sv(const cstr* self, csview sv); -bool cstr_starts_with(cstr s, const char* str); -bool cstr_starts_with_sv(cstr s, csview sv); -bool cstr_starts_with_s(cstr s, 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_ends_with(cstr s, const char* str); -bool cstr_ends_with_sv(cstr s, csview sv); -bool cstr_ends_with_s(cstr s, cstr s); +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 @@ -92,12 +94,12 @@ bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does no #### UTF8 methods ```c -size_t cstr_u8_size(cstr s); // number of utf8 codepoints -size_t cstr_u8_size_n(cstr s, size_t nbytes); // utf8 size within n bytes -size_t cstr_u8_to_pos(cstr s, size_t u8idx); // byte pos offset at utf8 codepoint index +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 u8pos, size_t u8len, csview repl); // replace at utf8 indices +void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl); // replace u8len utf8 chars // iterate utf8 codepoints cstr_iter cstr_begin(const cstr* self); @@ -117,18 +119,18 @@ cstr cstr_toupper_sv(csview sv); // returns 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(cstr s, const char* str); // " -bool cstr_istarts_with(cstr s, const char* str); // " -bool cstr_iends_with(cstr s, const char* str); // " +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. #### Helper methods: ```c -int cstr_cmp(const cstr *s1, const cstr *s2); -bool cstr_eq(const cstr *s1, const cstr *s2); -bool cstr_hash(const cstr *s); +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* c_strnstrn(const char* str, const char* search, size_t slen, size_t nlen); ``` @@ -155,7 +157,7 @@ char* c_strnstrn(const char* str, const char* search, size_t slen, size_t int main() { cstr s0 = cstr_new("Initialization without using strlen()."); - printf("%s\nLength: %" PRIuMAX "\n\n", cstr_str(&s0), cstr_size(s0)); + printf("%s\nLength: %" PRIuMAX "\n\n", cstr_str(&s0), cstr_size(&s0)); cstr s1 = cstr_new("one-nine-three-seven-five."); printf("%s\n", cstr_str(&s1)); diff --git a/docs/csview_api.md b/docs/csview_api.md index 09f377d1..128a1c9d 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -92,11 +92,11 @@ uint64_t csview_hash(const csview* x); ## Types -| Type name | Type definition | Used to represent... | -|:----------------|:------------------------------------------|:-------------------------| -| `csview` | `struct { const char *str; size_t size }` | The string view type | -| `csview_value` | `char` | The string element type | -| `csview_iter` | `struct { csview_value *ref; }` | UTF8 iterator | +| Type name | Type definition | Used to represent... | +|:----------------|:-------------------------------------------|:-------------------------| +| `csview` | `struct { const char *str; size_t size; }` | The string view type | +| `csview_value` | `char` | The string element type | +| `csview_iter` | `struct { csview_value *ref; }` | UTF8 iterator | ## Constants and macros @@ -118,7 +118,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 + size_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("%" c_PRIsv "%" c_PRIsv "%" c_PRIsv "\n", @@ -146,11 +146,11 @@ int main() { c_auto (cstr, s1) { s1 = cstr_new("hell😀 w😀rld"); - cstr_u8_replace_at(&s1, 7, 1, c_sv("ø")); + cstr_u8_replace(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) - printf("%.*s,", c_ARGsv(i.chr)); + printf("%.*s,", c_ARGsv(i.u8.chr)); } } ``` @@ -199,7 +199,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_with (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } diff --git a/docs/cvec_api.md b/docs/cvec_api.md index a907c827..579f6eeb 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -34,9 +34,10 @@ 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_value* cvec_X_append_uninit(cvec_X* self, size_t n); // return start of uninit +cvec_X_iter cvec_X_insert_uninit(cvec_X* self, i_val* pos, size_t n); // return pos iter void cvec_X_shrink_to_fit(cvec_X* self); void cvec_X_swap(cvec_X* a, cvec_X* b); void cvec_X_drop(cvec_X* self); // destructor @@ -48,9 +49,9 @@ size_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); // get mutable value +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); +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 @@ -68,22 +69,21 @@ cvec_X_value* cvec_X_emplace_back(cvec_X* self, i_valraw raw); void cvec_X_pop(cvec_X* self); void cvec_X_pop_back(cvec_X* self); // alias for pop -cvec_X_value* cvec_X_insert(cvec_X* self, size_t idx, i_val value); // move value -cvec_X_value* cvec_X_insert_n(cvec_X* self, size_t idx, const i_val[] arr, size_t n); // move n values -cvec_X_value* cvec_X_insert_at(cvec_X* self, cvec_X_iter it, i_val value); // move value -cvec_X_value* cvec_X_insert_range_p(cvec_X* self, i_val* pos, - const i_val* p1, const i_val* p2); +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_range(cvec_X* self, i_val* pos, + const i_val* p1, const i_val* p2); -cvec_X_value* cvec_X_emplace_n(cvec_X* self, size_t idx, const i_valraw[] arr, size_t n); -cvec_X_value* cvec_X_emplace_at(cvec_X* self, cvec_X_iter it, i_valraw raw); -cvec_X_value* cvec_X_emplace_range(cvec_X* self, cvec_X_iter it, // will clone - cvec_X_iter it1, cvec_X_iter it2); -cvec_X_value* cvec_X_emplace_range_p(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_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_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); void cvec_X_sort(cvec_X* self); void cvec_X_sort_range(cvec_X_iter i1, cvec_X_iter i2, |
